(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){ "use strict"; var _jquery = _interopRequireDefault(require("jquery")); var _Modeler = _interopRequireDefault(require("bpmn-js/lib/Modeler")); var _bpmnJsPropertiesPanel = _interopRequireDefault(require("bpmn-js-properties-panel")); var _activiti = _interopRequireDefault(require("../resources/properties-panel/provider/activiti")); var _activiti2 = _interopRequireDefault(require("../resources/activiti.json")); var _customTranslate = _interopRequireDefault(require("../resources/customTranslate/customTranslate")); var _customControls = _interopRequireDefault(require("../resources/customControls")); var _tools = _interopRequireDefault(require("../resources/tools")); var _newDiagram = _interopRequireDefault(require("../resources/newDiagram.bpmn")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } //import propertiesPanelModule from '../resources/properties-panel'; const proHost = window.location.protocol + "//" + window.location.host; const href = window.location.href.split("bpmnjs")[0]; const key = href.split(window.location.host)[1]; const publicurl = proHost + key; // 添加翻译组件 var customTranslateModule = { translate: ['value', _customTranslate.default] }; var container = (0, _jquery.default)('#js-drop-zone'); var canvas = (0, _jquery.default)('#js-canvas'); var bpmnModeler = new _Modeler.default({ container: canvas, propertiesPanel: { parent: '#js-properties-panel' }, additionalModules: [_bpmnJsPropertiesPanel.default, _activiti.default, _customControls.default, customTranslateModule], moddleExtensions: { activiti: _activiti2.default } }); container.removeClass('with-diagram'); // 判断浏览器支持程度 if (!window.FileList || !window.FileReader) { window.alert('请使用谷歌、火狐、IE10+浏览器'); } else { _tools.default.registerFileDrop(container, _tools.default.createDiagram(_newDiagram.default, bpmnModeler, container)); } (0, _jquery.default)(function () { // 创建bpmn var param = _tools.default.getUrlParam(window.location.href); (0, _jquery.default)('.item').show(); if (param.type === 'updateBpmn') { //加载后台方法获取xml _jquery.default.ajax({ url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/processDefinition/getProcessDefineXMLByModelId', // url: 'http://localhost:8080/processDefinition/getDefinitionXML', type: 'GET', data: param, dataType: 'text', headers: { 'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'), }, success: function (result) { var newXmlData = result; _tools.default.createDiagram(newXmlData, bpmnModeler, container); }, error: function (err) { console.log(err); } }); } else if (param.type === 'lookBpmn') { //编辑bpmn (0, _jquery.default)('.item').hide(); (0, _jquery.default)('.download').show(); const Id = param.deploymentFileUUID || '6d4af2dc-bab0-11ea-b584-3cf011eaafca'; const Name = param.deploymentName || 'String.bpmn'; const instanceId = param.instanceId; (0, _jquery.default)('.djs-palette').hide(); (0, _jquery.default)('.properties-panel-parent').hide(); var param = { "deploymentId": Id, "resourceName": decodeURI(Name) }; if (instanceId) { var param1 = { instanceId }; _jquery.default.ajax({ url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/activitiHistory/gethighLine', // url: 'http://localhost:8080/activitiHistory/gethighLine', type: 'GET', data: param1, dataType: 'json', headers: { 'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'), }, success: function (result) { var ColorJson = _tools.default.getByColor(result.data); _jquery.default.ajax({ url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/processDefinition/getDefinitionXML', // url: 'http://localhost:8080/processDefinition/getDefinitionXML', type: 'GET', data: param, dataType: 'text', headers: { 'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'), }, success: function (result) { var newXmlData = result; _tools.default.createDiagram(newXmlData, bpmnModeler, container); setTimeout(function () { for (var i in ColorJson) { _tools.default.setColor(ColorJson[i], bpmnModeler); } }, 200); }, error: function (err) { console.log(err); } }); }, error: function (err) { console.log(err); } }); } else { //加载后台方法获取xml _jquery.default.ajax({ url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/processDefinition/getDefinitionXML', // url: 'http://localhost:8080/processDefinition/getDefinitionXML', type: 'GET', data: param, dataType: 'text', headers: { 'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'), }, success: function (result) { var newXmlData = result; _tools.default.createDiagram(newXmlData, bpmnModeler, container); }, error: function (err) { console.log(err); } }); } } else if (param.type === "historyBpmn") { // bpmn历史 (0, _jquery.default)('.item').hide(); (0, _jquery.default)('.download').show(); } // 点击新增 (0, _jquery.default)('#js-download-diagram').on("click", function () { _tools.default.syopen('alert'); }); // 点击取消 (0, _jquery.default)('.cancel').on("click", function () { _tools.default.syhide('alert'); }); // 点击确定 (0, _jquery.default)('#sure').on('click', function () { // const text=$("#deploymentName").val() const modelId = param.modelId; _tools.default.saveBpmn(bpmnModeler,modelId); }); // 点击下载 (0, _jquery.default)("#downloadBpmn").on("click", function () { _tools.default.downLoad(bpmnModeler); }); // 点击上传 (0, _jquery.default)("#uploadFile").on("change", function () { _tools.default.upload(bpmnModeler, container); }); }); },{"../resources/activiti.json":568,"../resources/customControls":571,"../resources/customTranslate/customTranslate":572,"../resources/newDiagram.bpmn":574,"../resources/properties-panel/provider/activiti":610,"../resources/tools":676,"bpmn-js-properties-panel":2,"bpmn-js/lib/Modeler":15,"jquery":348}],2:[function(require,module,exports){ module.exports = require('./lib'); },{"./lib":12}],3:[function(require,module,exports){ 'use strict'; var escapeHTML = require('./Utils').escapeHTML; var domify = require('min-dom').domify, domQuery = require('min-dom').query, domQueryAll = require('min-dom').queryAll, domRemove = require('min-dom').remove, domClasses = require('min-dom').classes, domClosest = require('min-dom').closest, domAttr = require('min-dom').attr, domDelegate = require('min-dom').delegate, domMatches = require('min-dom').matches; var forEach = require('lodash/forEach'), filter = require('lodash/filter'), get = require('lodash/get'), keys = require('lodash/keys'), isEmpty = require('lodash/isEmpty'), isArray = require('lodash/isArray'), xor = require('lodash/xor'), debounce = require('lodash/debounce'); var updateSelection = require('selection-update'); var scrollTabs = require('scroll-tabs').default; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var HIDE_CLASS = 'bpp-hidden'; var DEBOUNCE_DELAY = 300; function isToggle(node) { return node.type === 'checkbox' || node.type === 'radio'; } function isSelect(node) { return node.type === 'select-one'; } function isContentEditable(node) { return domAttr(node, 'contenteditable'); } function getPropertyPlaceholders(node) { var selector = 'input[name], textarea[name], [data-value], [contenteditable]'; var placeholders = domQueryAll(selector, node); if ((!placeholders || !placeholders.length) && domMatches(node, selector)) { placeholders = [ node ]; } return placeholders; } /** * Return all active form controls. * This excludes the invisible controls unless all is true * * @param {Element} node * @param {Boolean} [all=false] */ function getFormControls(node, all) { var controls = domQueryAll('input[name], textarea[name], select[name], [contenteditable]', node); if (!controls || !controls.length) { controls = domMatches(node, 'option') ? [ node ] : controls; } if (!all) { controls = filter(controls, function(node) { return !domClosest(node, '.' + HIDE_CLASS); }); } return controls; } function getFormControlValuesInScope(entryNode) { var values = {}; var controlNodes = getFormControls(entryNode); forEach(controlNodes, function(controlNode) { var value = controlNode.value; var name = domAttr(controlNode, 'name') || domAttr(controlNode, 'data-name'); // take toggle state into account for radio / checkboxes if (isToggle(controlNode)) { if (controlNode.checked) { if (!domAttr(controlNode, 'value')) { value = true; } else { value = controlNode.value; } } else { value = null; } } else if (isContentEditable(controlNode)) { value = controlNode.innerText; } if (value !== null) { // return the actual value // handle serialization in entry provider // (ie. if empty string should be serialized or not) values[name] = value; } }); return values; } /** * Extract input values from entry node * * @param {DOMElement} entryNode * @returns {Object} */ function getFormControlValues(entryNode) { var values; var listContainer = domQuery('[data-list-entry-container]', entryNode); if (listContainer) { values = []; var listNodes = listContainer.children || []; forEach(listNodes, function(listNode) { values.push(getFormControlValuesInScope(listNode)); }); } else { values = getFormControlValuesInScope(entryNode); } return values; } /** * Return true if the given form extracted value equals * to an old cached version. * * @param {Object} value * @param {Object} oldValue * @return {Boolean} */ function valueEqual(value, oldValue) { if (value && !oldValue) { return false; } var allKeys = keys(value).concat(keys(oldValue)); return allKeys.every(function(key) { return value[key] === oldValue[key]; }); } /** * Return true if the given form extracted value(s) * equal an old cached version. * * @param {Array<Object>|Object} values * @param {Array<Object>|Object} oldValues * @return {Boolean} */ function valuesEqual(values, oldValues) { if (isArray(values)) { if (values.length !== oldValues.length) { return false; } return values.every(function(v, idx) { return valueEqual(v, oldValues[idx]); }); } return valueEqual(values, oldValues); } /** * Return a mapping of { id: entry } for all entries in the given groups in the given tabs. * * @param {Object} tabs * @return {Object} */ function extractEntries(tabs) { return keyBy(flattenDeep(map(flattenDeep(map(tabs, 'groups')), 'entries')), 'id'); } /** * Return a mapping of { id: group } for all groups in the given tabs. * * @param {Object} tabs * @return {Object} */ function extractGroups(tabs) { return keyBy(flattenDeep(map(tabs, 'groups')), 'id'); } /** * A properties panel implementation. * * To use it provide a `propertiesProvider` component that knows * about which properties to display. * * Properties edit state / visibility can be intercepted * via a custom {@link PropertiesActivator}. * * @class * @constructor * * @param {Object} config * @param {EventBus} eventBus * @param {Modeling} modeling * @param {PropertiesProvider} propertiesProvider * @param {Canvas} canvas * @param {CommandStack} commandStack */ function PropertiesPanel(config, eventBus, modeling, propertiesProvider, commandStack, canvas) { this._eventBus = eventBus; this._modeling = modeling; this._commandStack = commandStack; this._canvas = canvas; this._propertiesProvider = propertiesProvider; this._init(config); } PropertiesPanel.$inject = [ 'config.propertiesPanel', 'eventBus', 'modeling', 'propertiesProvider', 'commandStack', 'canvas' ]; module.exports = PropertiesPanel; PropertiesPanel.prototype._init = function(config) { var canvas = this._canvas, eventBus = this._eventBus; var self = this; /** * Select the root element once it is added to the canvas */ eventBus.on('root.added', function(e) { var element = e.element; if (isImplicitRoot(element)) { return; } self.update(element); }); eventBus.on('selection.changed', function(e) { var newElement = e.newSelection[0]; var rootElement = canvas.getRootElement(); if (isImplicitRoot(rootElement)) { return; } self.update(newElement); }); // add / update tab-bar scrolling eventBus.on([ 'propertiesPanel.changed', 'propertiesPanel.resized' ], function(event) { var tabBarNode = domQuery('.bpp-properties-tab-bar', self._container); if (!tabBarNode) { return; } var scroller = scrollTabs.get(tabBarNode); if (!scroller) { // we did not initialize yet, do that // now and make sure we select the active // tab on scroll update scroller = scrollTabs(tabBarNode, { selectors: { tabsContainer: '.bpp-properties-tabs-links', tab: '.bpp-properties-tabs-links li', ignore: '.bpp-hidden', active: '.bpp-active' } }); scroller.on('scroll', function(newActiveNode, oldActiveNode, direction) { var linkNode = domQuery('[data-tab-target]', newActiveNode); var tabId = domAttr(linkNode, 'data-tab-target'); self.activateTab(tabId); }); } // react on tab changes and or tabContainer resize // and make sure the active tab is shown completely scroller.update(); }); eventBus.on('elements.changed', function(e) { var current = self._current; var element = current && current.element; if (element) { if (e.elements.indexOf(element) !== -1) { self.update(element); } } }); eventBus.on('elementTemplates.changed', function() { var current = self._current; var element = current && current.element; if (element) { self.update(element); } }); eventBus.on('diagram.destroy', function() { self.detach(); }); this._container = domify('<div class="bpp-properties-panel"></div>'); this._bindListeners(this._container); if (config && config.parent) { this.attachTo(config.parent); } }; PropertiesPanel.prototype.attachTo = function(parentNode) { if (!parentNode) { throw new Error('parentNode required'); } // ensure we detach from the // previous, old parent this.detach(); // unwrap jQuery if provided if (parentNode.get && parentNode.constructor.prototype.jquery) { parentNode = parentNode.get(0); } if (typeof parentNode === 'string') { parentNode = domQuery(parentNode); } var container = this._container; parentNode.appendChild(container); this._emit('attach'); }; PropertiesPanel.prototype.detach = function() { var container = this._container, parentNode = container.parentNode; if (!parentNode) { return; } this._emit('detach'); parentNode.removeChild(container); }; /** * Select the given tab within the properties panel. * * @param {Object|String} tab */ PropertiesPanel.prototype.activateTab = function(tab) { var tabId = typeof tab === 'string' ? tab : tab.id; var current = this._current; var panelNode = current.panel; var allTabNodes = domQueryAll('.bpp-properties-tab', panelNode), allTabLinkNodes = domQueryAll('.bpp-properties-tab-link', panelNode); forEach(allTabNodes, function(tabNode) { var currentTabId = domAttr(tabNode, 'data-tab'); if(currentTabId == 'general'){ domClasses(tabNode).toggle('bpp-active', tabId === currentTabId); } }); forEach(allTabLinkNodes, function(tabLinkNode) { var tabLink = domQuery('[data-tab-target]', tabLinkNode), currentTabId = domAttr(tabLink, 'data-tab-target'); domClasses(tabLinkNode).toggle('bpp-active', tabId === currentTabId); }); }; /** * Update the DOM representation of the properties panel */ PropertiesPanel.prototype.update = function(element) { var current = this._current; // no actual selection change var needsCreate = true; if (typeof element === 'undefined') { // use RootElement of BPMN diagram to generate properties panel if no element is selected element = this._canvas.getRootElement(); } var newTabs = this._propertiesProvider.getTabs(element); if (current && current.element === element) { // see if we can reuse the existing panel needsCreate = this._entriesChanged(current, newTabs); } if (needsCreate) { if (current) { // get active tab from the existing panel before remove it var activeTabNode = domQuery('.bpp-properties-tab.bpp-active', current.panel); var activeTabId; if (activeTabNode) { activeTabId = domAttr(activeTabNode, 'data-tab'); } // remove old panel domRemove(current.panel); } this._current = this._create(element, newTabs); // activate the saved active tab from the remove panel or the first tab (activeTabId) ? this.activateTab(activeTabId) : this.activateTab(this._current.tabs[0]); } if (this._current) { // make sure correct tab contents are visible this._updateActivation(this._current); } this._emit('changed'); }; /** * Returns true if one of two groups has different entries than the other. * * @param {Object} current * @param {Object} newTabs * @return {Boolean} */ PropertiesPanel.prototype._entriesChanged = function(current, newTabs) { var oldEntryIds = keys(current.entries), newEntryIds = keys(extractEntries(newTabs)); return !isEmpty(xor(oldEntryIds, newEntryIds)); }; PropertiesPanel.prototype._emit = function(event) { this._eventBus.fire('propertiesPanel.' + event, { panel: this, current: this._current }); }; PropertiesPanel.prototype._bindListeners = function(container) { var self = this; // handles a change for a given event var handleChange = function handleChange(event) { // see if we handle a change inside a [data-entry] element. // if not, drop out var inputNode = event.delegateTarget, entryNode = domClosest(inputNode, '[data-entry]'), entryId, entry; // change from outside a [data-entry] element, simply ignore if (!entryNode) { return; } entryId = domAttr(entryNode, 'data-entry'); entry = self.getEntry(entryId); var values = getFormControlValues(entryNode); if (event.type === 'change') { // - if the "data-on-change" attribute is present and a value is changed, // then the associated action is performed. // - if the associated action returns "true" then an update to the business // object is done // - if it does not return "true", then only the DOM content is updated var onChangeAction = domAttr(inputNode, 'data-on-change'); if (onChangeAction) { var isEntryDirty = self.executeAction(entry, entryNode, onChangeAction, event); if (!isEntryDirty) { return self.update(self._current.element); } } } self.applyChanges(entry, values, entryNode); self.updateState(entry, entryNode); }; // debounce update only elements that are target of key events, // i.e. INPUT and TEXTAREA. SELECTs will trigger an immediate update anyway. domDelegate.bind(container, 'input, textarea, [contenteditable]', 'input', debounce(handleChange, DEBOUNCE_DELAY)); domDelegate.bind(container, 'input, textarea, select, [contenteditable]', 'change', handleChange); // handle key events domDelegate.bind(container, 'select', 'keydown', function(e) { // DEL if (e.keyCode === 46) { e.stopPropagation(); e.preventDefault(); } }); domDelegate.bind(container, '[data-action]', 'click', function onClick(event) { // triggers on all inputs var inputNode = event.delegateTarget, entryNode = domClosest(inputNode, '[data-entry]'); var actionId = domAttr(inputNode, 'data-action'), entryId = domAttr(entryNode, 'data-entry'); var entry = self.getEntry(entryId); var isEntryDirty = self.executeAction(entry, entryNode, actionId, event); if (isEntryDirty) { var values = getFormControlValues(entryNode); self.applyChanges(entry, values, entryNode); } self.updateState(entry, entryNode); }); function handleInput(event, element) { // triggers on all inputs var inputNode = event.delegateTarget; var entryNode = domClosest(inputNode, '[data-entry]'); // only work on data entries if (!entryNode) { return; } var eventHandlerId = domAttr(inputNode, 'data-blur'), entryId = domAttr(entryNode, 'data-entry'); var entry = self.getEntry(entryId); var isEntryDirty = self.executeAction(entry, entryNode, eventHandlerId, event); if (isEntryDirty) { var values = getFormControlValues(entryNode); self.applyChanges(entry, values, entryNode); } self.updateState(entry, entryNode); } domDelegate.bind(container, '[data-blur]', 'blur', handleInput, true); // make tab links interactive domDelegate.bind(container, '.bpp-properties-tabs-links [data-tab-target]', 'click', function(event) { event.preventDefault(); var delegateTarget = event.delegateTarget; var tabId = domAttr(delegateTarget, 'data-tab-target'); // activate tab on link click self.activateTab(tabId); }); }; PropertiesPanel.prototype.updateState = function(entry, entryNode) { this.updateShow(entry, entryNode); this.updateDisable(entry, entryNode); }; /** * Update the visibility of the entry node in the DOM */ PropertiesPanel.prototype.updateShow = function(entry, node) { var current = this._current; if (!current) { return; } var showNodes = domQueryAll('[data-show]', node) || []; forEach(showNodes, function(showNode) { var expr = domAttr(showNode, 'data-show'); var fn = get(entry, expr); if (fn) { var scope = domClosest(showNode, '[data-scope]') || node; var shouldShow = fn(current.element, node, showNode, scope) || false; if (shouldShow) { domClasses(showNode).remove(HIDE_CLASS); } else { domClasses(showNode).add(HIDE_CLASS); } } }); }; /** * Evaluates a given function. If it returns true, then the * node is marked as "disabled". */ PropertiesPanel.prototype.updateDisable = function(entry, node) { var current = this._current; if (!current) { return; } var nodes = domQueryAll('[data-disable]', node) || []; forEach(nodes, function(currentNode) { var expr = domAttr(currentNode, 'data-disable'); var fn = get(entry, expr); if (fn) { var scope = domClosest(currentNode, '[data-scope]') || node; var shouldDisable = fn(current.element, node, currentNode, scope) || false; domAttr(currentNode, 'disabled', shouldDisable ? '' : null); } }); }; PropertiesPanel.prototype.executeAction = function(entry, entryNode, actionId, event) { var current = this._current; if (!current) { return; } var fn = get(entry, actionId); if (fn) { var scopeNode = domClosest(event.target, '[data-scope]') || entryNode; return fn.apply(entry, [ current.element, entryNode, event, scopeNode ]); } }; /** * Apply changes to the business object by executing a command */ PropertiesPanel.prototype.applyChanges = function(entry, values, containerElement) { var element = this._current.element; // ensure we only update the model if we got dirty changes if (valuesEqual(values, entry.oldValues)) { return; } var command = entry.set(element, values, containerElement); var commandToExecute; if (isArray(command)) { if (command.length) { commandToExecute = { cmd: 'properties-panel.multi-command-executor', context: flattenDeep(command) }; } } else { commandToExecute = command; } if (commandToExecute) { this._commandStack.execute(commandToExecute.cmd, commandToExecute.context || { element : element }); } else { this.update(element); } }; /** * apply validation errors in the DOM and show or remove an error message near the entry node. */ PropertiesPanel.prototype.applyValidationErrors = function(validationErrors, entryNode) { var valid = true; var controlNodes = getFormControls(entryNode, true); forEach(controlNodes, function(controlNode) { var name = domAttr(controlNode, 'name') || domAttr(controlNode, 'data-name'); var error = validationErrors && validationErrors[name]; var errorMessageNode = domQuery('.bpp-error-message', controlNode.parentNode); if (error) { valid = false; if (!errorMessageNode) { errorMessageNode = domify('<div></div>'); domClasses(errorMessageNode).add('bpp-error-message'); // insert errorMessageNode after controlNode controlNode.parentNode.insertBefore(errorMessageNode, controlNode.nextSibling); } errorMessageNode.textContent = error; domClasses(controlNode).add('invalid'); } else { domClasses(controlNode).remove('invalid'); if (errorMessageNode) { controlNode.parentNode.removeChild(errorMessageNode); } } }); return valid; }; /** * Check if the entry contains valid input */ PropertiesPanel.prototype.validate = function(entry, values, entryNode) { var self = this; var current = this._current; var valid = true; entryNode = entryNode || domQuery('[data-entry="' + entry.id + '"]', current.panel); if (values instanceof Array) { var listContainer = domQuery('[data-list-entry-container]', entryNode), listEntryNodes = listContainer.children || []; // create new elements for (var i = 0; i < values.length; i++) { var listValue = values[i]; if (entry.validateListItem) { var validationErrors = entry.validateListItem(current.element, listValue, entryNode, i), listEntryNode = listEntryNodes[i]; valid = self.applyValidationErrors(validationErrors, listEntryNode) && valid; } } } else { if (entry.validate) { this.validationErrors = entry.validate(current.element, values, entryNode); valid = self.applyValidationErrors(this.validationErrors, entryNode) && valid; } } return valid; }; PropertiesPanel.prototype.getEntry = function(id) { return this._current && this._current.entries[id]; }; var flattenDeep = require('lodash/flattenDeep'), keyBy = require('lodash/keyBy'), map = require('lodash/map'); PropertiesPanel.prototype._create = function(element, tabs) { if (!element) { return null; } var containerNode = this._container; var panelNode = this._createPanel(element, tabs); containerNode.appendChild(panelNode); var entries = extractEntries(tabs); var groups = extractGroups(tabs); return { tabs: tabs, groups: groups, entries: entries, element: element, panel: panelNode }; }; /** * Update variable parts of the entry node on element changes. * * @param {djs.model.Base} element * @param {EntryDescriptor} entry * @param {Object} values * @param {HTMLElement} entryNode * @param {Number} idx */ PropertiesPanel.prototype._bindTemplate = function(element, entry, values, entryNode, idx) { var eventBus = this._eventBus; function isPropertyEditable(entry, propertyName) { return eventBus.fire('propertiesPanel.isPropertyEditable', { entry: entry, propertyName: propertyName, element: element }); } var inputNodes = getPropertyPlaceholders(entryNode); forEach(inputNodes, function(node) { var name, newValue, editable; // we deal with an input element if ('value' in node || isContentEditable(node) === 'true') { name = domAttr(node, 'name') || domAttr(node, 'data-name'); newValue = values[name]; editable = isPropertyEditable(entry, name); if (editable && entry.editable) { editable = entry.editable(element, entryNode, node, name, newValue, idx); } domAttr(node, 'readonly', editable ? null : ''); domAttr(node, 'disabled', editable ? null : ''); // take full control over setting the value // and possibly updating the input in entry#setControlValue if (entry.setControlValue) { entry.setControlValue(element, entryNode, node, name, newValue, idx); } else if (isToggle(node)) { setToggleValue(node, newValue); } else if (isSelect(node)) { setSelectValue(node, newValue); } else { setInputValue(node, newValue); } } // we deal with some non-editable html element else { name = domAttr(node, 'data-value'); newValue = values[name]; if (entry.setControlValue) { entry.setControlValue(element, entryNode, node, name, newValue, idx); } else { setTextValue(node, newValue); } } }); }; // TODO(nikku): WTF freaking name? Change / clarify. PropertiesPanel.prototype._updateActivation = function(current) { var self = this; var eventBus = this._eventBus; var element = current.element; function isEntryVisible(entry) { return eventBus.fire('propertiesPanel.isEntryVisible', { entry: entry, element: element }); } function isGroupVisible(group, element, groupNode) { if (typeof group.enabled === 'function') { return group.enabled(element, groupNode); } else { return true; } } function isTabVisible(tab, element) { if (typeof tab.enabled === 'function') { return tab.enabled(element); } else { return true; } } function toggleVisible(node, visible) { domClasses(node).toggle(HIDE_CLASS, !visible); } // check whether the active tab is visible // if not: set the first tab as active tab function checkActiveTabVisibility(node, visible) { var isActive = domClasses(node).has('bpp-active'); if (!visible && isActive) { self.activateTab(current.tabs[0]); } } function updateLabel(element, selector, text) { var labelNode = domQuery(selector, element); if (!labelNode) { return; } labelNode.textContent = text; } var panelNode = current.panel; forEach(current.tabs, function(tab) { var tabNode = domQuery('[data-tab=' + tab.id + ']', panelNode); var tabLinkNode = domQuery('[data-tab-target=' + tab.id + ']', panelNode).parentNode; var tabVisible = false; forEach(tab.groups, function(group) { var groupVisible = false; var groupNode = domQuery('[data-group=' + group.id + ']', tabNode); forEach(group.entries, function(entry) { var entryNode = domQuery('[data-entry="' + entry.id + '"]', groupNode); var entryVisible = isEntryVisible(entry); groupVisible = groupVisible || entryVisible; toggleVisible(entryNode, entryVisible); var values = 'get' in entry ? entry.get(element, entryNode) : {}; if (values instanceof Array) { var listEntryContainer = domQuery('[data-list-entry-container]', entryNode); var existingElements = listEntryContainer.children || []; for (var i = 0; i < values.length; i++) { var listValue = values[i]; var listItemNode = existingElements[i]; if (!listItemNode) { listItemNode = domify(entry.createListEntryTemplate(listValue, i, listEntryContainer)); listEntryContainer.appendChild(listItemNode); } domAttr(listItemNode, 'data-index', i); self._bindTemplate(element, entry, listValue, listItemNode, i); } var entriesToRemove = existingElements.length - values.length; for (var j = 0; j < entriesToRemove; j++) { // remove orphaned element listEntryContainer.removeChild(listEntryContainer.lastChild); } } else { self._bindTemplate(element, entry, values, entryNode); } // update conditionally visible elements self.updateState(entry, entryNode); self.validate(entry, values, entryNode); // remember initial state for later dirty checking entry.oldValues = getFormControlValues(entryNode); }); if (typeof group.label === 'function') { updateLabel(groupNode, '.group-label', group.label(element, groupNode)); } groupVisible = groupVisible && isGroupVisible(group, element, groupNode); tabVisible = tabVisible || groupVisible; toggleVisible(groupNode, groupVisible); }); tabVisible = tabVisible && isTabVisible(tab, element); toggleVisible(tabNode, tabVisible); toggleVisible(tabLinkNode, tabVisible); checkActiveTabVisibility(tabNode, tabVisible); }); // inject elements id into header updateLabel(panelNode, '[data-label-id]', getBusinessObject(element).id || ''); }; PropertiesPanel.prototype._createPanel = function(element, tabs) { var self = this; var panelNode = domify('<div class="bpp-properties"></div>'), headerNode = domify('<div class="bpp-properties-header">' + '<div class="label" data-label-id></div>' + '<div class="search">' + '<input type="search" placeholder="Search for property" />' + '<button><span>Search</span></button>' + '</div>' + '</div>'), tabBarNode = domify('<div class="bpp-properties-tab-bar"></div>'), tabLinksNode = domify('<ul class="bpp-properties-tabs-links"></ul>'), tabContainerNode = domify('<div class="bpp-properties-tabs-container"></div>'); panelNode.appendChild(headerNode); forEach(tabs, function(tab, tabIndex) { if (!tab.id) { throw new Error('tab must have an id'); } var updateStype = '' if (tab.id != 'general') { updateStype = 'display:none' } var tabNode = domify('<div class="bpp-properties-tab" style="'+updateStype+'" data-tab="' + escapeHTML(tab.id) + '"></div>'), tabLinkNode = domify('<li class="bpp-properties-tab-link" style="'+updateStype+'"> ' + '<a href data-tab-target="' + escapeHTML(tab.id) + '">' + escapeHTML(tab.label) + '</a>' + '</li>'); var groups = tab.groups; forEach(groups, function(group) { if (!group.id) { throw new Error('group must have an id'); } var groupNode = domify('<div class="bpp-properties-group" data-group="' + escapeHTML(group.id) + '">' + '<span class="group-toggle"></span>' + '<span class="group-label">' + escapeHTML(group.label) + '</span>' + '</div>'); // TODO(nre): use event delegation to handle that... groupNode.querySelector('.group-toggle').addEventListener('click', function(evt) { domClasses(groupNode).toggle('group-closed'); evt.preventDefault(); evt.stopPropagation(); }); groupNode.addEventListener('click', function(evt) { if (!evt.defaultPrevented && domClasses(groupNode).has('group-closed')) { domClasses(groupNode).remove('group-closed'); } }); forEach(group.entries, function(entry) { if (!entry.id) { throw new Error('entry must have an id'); } var html = entry.html; if (typeof html === 'string') { html = domify(html); } // unwrap jquery if (html.get && html.constructor.prototype.jquery) { html = html.get(0); } var entryNode = domify('<div class="bpp-properties-entry" data-entry="' + escapeHTML(entry.id) + '"></div>'); forEach(entry.cssClasses || [], function(cssClass) { domClasses(entryNode).add(cssClass); }); entryNode.appendChild(html); groupNode.appendChild(entryNode); // update conditionally visible elements self.updateState(entry, entryNode); }); tabNode.appendChild(groupNode); }); tabLinksNode.appendChild(tabLinkNode); tabContainerNode.appendChild(tabNode); }); tabBarNode.appendChild(tabLinksNode); panelNode.appendChild(tabBarNode); panelNode.appendChild(tabContainerNode); return panelNode; }; function setInputValue(node, value) { var contentEditable = isContentEditable(node); var oldValue = contentEditable ? node.innerText : node.value; var selection; // prevents input fields from having the value 'undefined' if (value === undefined) { value = ''; } if (oldValue === value) { return; } // update selection on undo/redo if (document.activeElement === node) { selection = updateSelection(getSelection(node), oldValue, value); } if (contentEditable) { node.innerText = value; } else { node.value = value; } if (selection) { setSelection(node, selection); } } function setSelectValue(node, value) { if (value !== undefined) { node.value = value; } } function setToggleValue(node, value) { var nodeValue = node.value; node.checked = (value === nodeValue) || (!domAttr(node, 'value') && value); } function setTextValue(node, value) { node.textContent = value; } function getSelection(node) { return isContentEditable(node) ? getContentEditableSelection(node) : { start: node.selectionStart, end: node.selectionEnd }; } function getContentEditableSelection(node) { var selection = window.getSelection(); var focusNode = selection.focusNode, focusOffset = selection.focusOffset, anchorOffset = selection.anchorOffset; if (!focusNode) { throw new Error('not selected'); } // verify we have selection on the current element if (!node.contains(focusNode)) { throw new Error('not selected'); } return { start: Math.min(focusOffset, anchorOffset), end: Math.max(focusOffset, anchorOffset) }; } function setSelection(node, selection) { if (isContentEditable(node)) { setContentEditableSelection(node, selection); } else { node.selectionStart = selection.start; node.selectionEnd = selection.end; } } function setContentEditableSelection(node, selection) { var focusNode, domRange, domSelection; focusNode = node.firstChild || node, domRange = document.createRange(); domRange.setStart(focusNode, selection.start); domRange.setEnd(focusNode, selection.end); domSelection = window.getSelection(); domSelection.removeAllRanges(); domSelection.addRange(domRange); } function isImplicitRoot(element) { return element.id === '__implicitroot'; } },{"./Utils":4,"bpmn-js/lib/util/ModelUtil":141,"lodash/debounce":516,"lodash/filter":518,"lodash/flattenDeep":521,"lodash/forEach":522,"lodash/get":523,"lodash/isArray":527,"lodash/isEmpty":531,"lodash/keyBy":538,"lodash/keys":539,"lodash/map":540,"lodash/xor":554,"min-dom":556,"scroll-tabs":565,"selection-update":566}],4:[function(require,module,exports){ 'use strict'; var domQuery = require('min-dom').query, domClear = require('min-dom').clear, is = require('bpmn-js/lib/util/ModelUtil').is, forEach = require('lodash/forEach'), domify = require('min-dom').domify, Ids = require('ids').default; var SPACE_REGEX = /\s/; // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar var QNAME_REGEX = /^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i; // for ID validation as per BPMN Schema (QName - Namespace) var ID_REGEX = /^[a-z_][\w-.]*$/i; var PLACEHOLDER_REGEX = /\$\{([^}]*)\}/g; var HTML_ESCAPE_MAP = { '&': '&', '<': '<', '>': '>', '"': '"', '\'': ''' }; function selectedOption(selectBox) { if (selectBox.selectedIndex >= 0) { return selectBox.options[selectBox.selectedIndex].value; } } module.exports.selectedOption = selectedOption; function selectedType(elementSyntax, inputNode) { var typeSelect = domQuery(elementSyntax, inputNode); return selectedOption(typeSelect); } module.exports.selectedType = selectedType; /** * Retrieve the root element the document this * business object is contained in. * * @return {ModdleElement} */ function getRoot(businessObject) { var parent = businessObject; while (parent.$parent) { parent = parent.$parent; } return parent; } module.exports.getRoot = getRoot; /** * filters all elements in the list which have a given type. * removes a new list */ function filterElementsByType(objectList, type) { var list = objectList || []; var result = []; forEach(list, function(obj) { if (is(obj, type)) { result.push(obj); } }); return result; } module.exports.filterElementsByType = filterElementsByType; function findRootElementsByType(businessObject, referencedType) { var root = getRoot(businessObject); return filterElementsByType(root.rootElements, referencedType); } module.exports.findRootElementsByType = findRootElementsByType; function removeAllChildren(domElement) { while (domElement.firstChild) { domElement.removeChild(domElement.firstChild); } } module.exports.removeAllChildren = removeAllChildren; /** * adds an empty option to the list */ function addEmptyParameter(list) { return list.push({ 'label': '', 'value': '', 'name': '' }); } module.exports.addEmptyParameter = addEmptyParameter; /** * returns a list with all root elements for the given parameter 'referencedType' */ function refreshOptionsModel(businessObject, referencedType) { var model = []; var referableObjects = findRootElementsByType(businessObject, referencedType); forEach(referableObjects, function(obj) { model.push({ label: (obj.name || '') + ' (id='+obj.id+')', value: obj.id, name: obj.name }); }); return model; } module.exports.refreshOptionsModel = refreshOptionsModel; /** * fills the drop down with options */ function updateOptionsDropDown(domSelector, businessObject, referencedType, entryNode) { var options = refreshOptionsModel(businessObject, referencedType); addEmptyParameter(options); var selectBox = domQuery(domSelector, entryNode); domClear(selectBox); forEach(options, function(option) { var optionEntry = domify('<option value="' + escapeHTML(option.value) + '">' + escapeHTML(option.label) + '</option>'); selectBox.appendChild(optionEntry); }); return options; } module.exports.updateOptionsDropDown = updateOptionsDropDown; /** * checks whether the id value is valid * * @param {ModdleElement} bo * @param {String} idValue * @param {Function} translate * * @return {String} error message */ function isIdValid(bo, idValue, translate) { var assigned = bo.$model.ids.assigned(idValue); var idExists = assigned && assigned !== bo; if (!idValue || idExists) { return translate('Element must have an unique id.'); } return validateId(idValue, translate); } module.exports.isIdValid = isIdValid; function validateId(idValue, translate) { idValue = stripPlaceholders(idValue); if (containsSpace(idValue)) { return translate('Id must not contain spaces.'); } if (!ID_REGEX.test(idValue)) { if (QNAME_REGEX.test(idValue)) { return translate('Id must not contain prefix.'); } return translate('Id must be a valid QName.'); } } module.exports.validateId = validateId; function containsSpace(value) { return SPACE_REGEX.test(value); } module.exports.containsSpace = containsSpace; function stripPlaceholders(idValue) { // replace expression e.g. ${VERSION_TAG} // use only the content between ${} // for the REGEX check return idValue.replace(PLACEHOLDER_REGEX, '$1'); } /** * generate a semantic id with given prefix */ function nextId(prefix) { var ids = new Ids([32,32,1]); return ids.nextPrefixed(prefix); } module.exports.nextId = nextId; function triggerClickEvent(element) { var evt; var eventType = 'click'; if (document.createEvent) { try { // Chrome, Safari, Firefox evt = new MouseEvent((eventType), { view: window, bubbles: true, cancelable: true }); } catch (e) { // IE 11, PhantomJS (wat!) evt = document.createEvent('MouseEvent'); evt.initEvent((eventType), true, true); } return element.dispatchEvent(evt); } else { // Welcome IE evt = document.createEventObject(); return element.fireEvent('on' + eventType, evt); } } module.exports.triggerClickEvent = triggerClickEvent; function escapeHTML(str) { str = '' + str; return str && str.replace(/[&<>"']/g, function(match) { return HTML_ESCAPE_MAP[match]; }); } module.exports.escapeHTML = escapeHTML; },{"bpmn-js/lib/util/ModelUtil":141,"ids":346,"lodash/forEach":522,"min-dom":556}],5:[function(require,module,exports){ 'use strict'; var elementHelper = require('../helper/ElementHelper'); /** * A handler capable of creating a new element under a provided parent * and updating / creating a reference to it in one atomic action. * * @class * @constructor */ function CreateAndReferenceElementHandler(elementRegistry, bpmnFactory) { this._elementRegistry = elementRegistry; this._bpmnFactory = bpmnFactory; } CreateAndReferenceElementHandler.$inject = [ 'elementRegistry', 'bpmnFactory' ]; module.exports = CreateAndReferenceElementHandler; // api //////////////////// /** * Creates a new element under a provided parent and updates / creates a reference to it in * one atomic action. * * @method CreateAndReferenceElementHandler#execute * * @param {Object} context * @param {djs.model.Base} context.element which is the context for the reference * @param {moddle.referencingObject} context.referencingObject the object which creates the reference * @param {String} context.referenceProperty the property of the referencingObject which makes the reference * @param {moddle.newObject} context.newObject the new object to add * @param {moddle.newObjectContainer} context.newObjectContainer the container for the new object * * @returns {Array<djs.mode.Base>} the updated element */ CreateAndReferenceElementHandler.prototype.execute = function(context) { var referencingObject = ensureNotNull(context.referencingObject, 'referencingObject'), referenceProperty = ensureNotNull(context.referenceProperty, 'referenceProperty'), newObject = ensureNotNull(context.newObject, 'newObject'), newObjectContainer = ensureNotNull(context.newObjectContainer, 'newObjectContainer'), newObjectParent = ensureNotNull(context.newObjectParent, 'newObjectParent'), changed = [ context.element ]; // this will not change any diagram-js elements // create new object var referencedObject = elementHelper .createElement(newObject.type, newObject.properties, newObjectParent, this._bpmnFactory); context.referencedObject = referencedObject; // add to containing list newObjectContainer.push(referencedObject); // adjust reference attribute context.previousReference = referencingObject[referenceProperty]; referencingObject[referenceProperty] = referencedObject; context.changed = changed; // indicate changed on objects affected by the update return changed; }; /** * Reverts the update * * @method CreateAndReferenceElementHandler#revert * * @param {Object} context * * @returns {djs.mode.Base} the updated element */ CreateAndReferenceElementHandler.prototype.revert = function(context) { var referencingObject = context.referencingObject, referenceProperty = context.referenceProperty, previousReference = context.previousReference, referencedObject = context.referencedObject, newObjectContainer = context.newObjectContainer; // reset reference referencingObject.set(referenceProperty, previousReference); // remove new element newObjectContainer.splice(newObjectContainer.indexOf(referencedObject), 1); return context.changed; }; // helpers ////////////// function ensureNotNull(prop, name) { if (!prop) { throw new Error(name + ' required'); } return prop; } },{"../helper/ElementHelper":11}],6:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/forEach'); var elementHelper = require('../helper/ElementHelper'); /** * A handler that implements a BPMN 2.0 property update * for business objects which are not represented in the * diagram. * * This is useful in the context of the properties panel in * order to update child elements of elements visible in * the diagram. * * Example: perform an update of a specific event definition * of an intermediate event. * * @class * @constructor */ function CreateBusinessObjectListHandler(elementRegistry, bpmnFactory) { this._elementRegistry = elementRegistry; this._bpmnFactory = bpmnFactory; } CreateBusinessObjectListHandler.$inject = [ 'elementRegistry', 'bpmnFactory' ]; module.exports = CreateBusinessObjectListHandler; function ensureNotNull(prop, name) { if (!prop) { throw new Error(name + ' required'); } return prop; } function ensureList(prop, name) { if (!prop || Object.prototype.toString.call(prop) !== '[object Array]') { throw new Error(name + ' needs to be a list'); } return prop; } // api ///////////////////////////////////////////// /** * Creates a new element under a provided parent and updates / creates a reference to it in * one atomic action. * * @method CreateBusinessObjectListHandler#execute * * @param {Object} context * @param {djs.model.Base} context.element which is the context for the reference * @param {moddle.referencingObject} context.referencingObject the object which creates the reference * @param {String} context.referenceProperty the property of the referencingObject which makes the reference * @param {moddle.newObject} context.newObject the new object to add * @param {moddle.newObjectContainer} context.newObjectContainer the container for the new object * * @return {Array<djs.mode.Base>} the updated element */ CreateBusinessObjectListHandler.prototype.execute = function(context) { var currentObject = ensureNotNull(context.currentObject, 'currentObject'), propertyName = ensureNotNull(context.propertyName, 'propertyName'), newObjects = ensureList(context.newObjects, 'newObjects'), changed = [ context.element ]; // this will not change any diagram-js elements var childObjects = []; var self = this; // create new array of business objects forEach(newObjects, function(obj) { var element = elementHelper.createElement(obj.type, obj.properties, currentObject, self._bpmnFactory); childObjects.push(element); }); context.childObject = childObjects; // adjust array reference in the parent business object context.previousChilds = currentObject[propertyName]; currentObject[propertyName] = childObjects; context.changed = changed; // indicate changed on objects affected by the update return changed; }; /** * Reverts the update * * @method CreateBusinessObjectListHandler#revert * * @param {Object} context * * @return {djs.mode.Base} the updated element */ CreateBusinessObjectListHandler.prototype.revert = function(context) { var currentObject = context.currentObject, propertyName = context.propertyName, previousChilds = context.previousChilds; // remove new element currentObject.set(propertyName, previousChilds); return context.changed; }; },{"../helper/ElementHelper":11,"lodash/forEach":522}],7:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/forEach'); /** * A handler that combines and executes multiple commands. * * All updates are bundled on the command stack and executed in one step. * This also makes it possible to revert the changes in one step. * * Example use case: remove the camunda:formKey attribute and in addition * add all form fields needed for the camunda:formData property. * * @class * @constructor */ function MultiCommandHandler(commandStack) { this._commandStack = commandStack; } MultiCommandHandler.$inject = [ 'commandStack' ]; module.exports = MultiCommandHandler; MultiCommandHandler.prototype.preExecute = function(context) { var commandStack = this._commandStack; forEach(context, function(command) { commandStack.execute(command.cmd, command.context); }); }; },{"lodash/forEach":522}],8:[function(require,module,exports){ 'use strict'; var reduce = require('lodash/transform'), is = require('bpmn-js/lib/util/ModelUtil').is, keys = require('lodash/keys'), forEach = require('lodash/forEach'); /** * A handler that implements a BPMN 2.0 property update * for business objects which are not represented in the * diagram. * * This is useful in the context of the properties panel in * order to update child elements of elements visible in * the diagram. * * Example: perform an update of a specific event definition * of an intermediate event. * * @class * @constructor */ function UpdateBusinessObjectHandler(elementRegistry) { this._elementRegistry = elementRegistry; } UpdateBusinessObjectHandler.$inject = [ 'elementRegistry' ]; module.exports = UpdateBusinessObjectHandler; /** * returns the root element */ function getRoot(businessObject) { var parent = businessObject; while (parent.$parent) { parent = parent.$parent; } return parent; } function getProperties(businessObject, propertyNames) { return reduce(propertyNames, function(result, key) { result[key] = businessObject.get(key); return result; }, {}); } function setProperties(businessObject, properties) { forEach(properties, function(value, key) { businessObject.set(key, value); }); } // api ///////////////////////////////////////////// /** * Updates a business object with a list of new properties * * @method UpdateBusinessObjectHandler#execute * * @param {Object} context * @param {djs.model.Base} context.element the element which has a child business object updated * @param {moddle.businessObject} context.businessObject the businessObject to update * @param {Object} context.properties a list of properties to set on the businessObject * * @return {Array<djs.mode.Base>} the updated element */ UpdateBusinessObjectHandler.prototype.execute = function(context) { var element = context.element, businessObject = context.businessObject, rootElements = getRoot(businessObject).rootElements, referenceType = context.referenceType, referenceProperty = context.referenceProperty, changed = [ element ]; // this will not change any diagram-js elements if (!element) { throw new Error('element required'); } if (!businessObject) { throw new Error('businessObject required'); } var properties = context.properties, oldProperties = context.oldProperties || getProperties(businessObject, keys(properties)); // check if there the update needs an external element for reference if (typeof referenceType !== 'undefined' && typeof referenceProperty !== 'undefined') { forEach(rootElements, function(rootElement) { if (is(rootElement, referenceType)) { if (rootElement.id === properties[referenceProperty]) { properties[referenceProperty] = rootElement; } } }); } // update properties setProperties(businessObject, properties); // store old values context.oldProperties = oldProperties; context.changed = changed; // indicate changed on objects affected by the update return changed; }; /** * Reverts the update * * @method UpdateBusinessObjectHandler#revert * * @param {Object} context * * @return {djs.mode.Base} the updated element */ UpdateBusinessObjectHandler.prototype.revert = function(context) { var oldProperties = context.oldProperties, businessObject = context.businessObject; // update properties setProperties(businessObject, oldProperties); return context.changed; }; },{"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522,"lodash/keys":539,"lodash/transform":551}],9:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/forEach'); /** * A handler that implements a BPMN 2.0 property update * for business object lists which are not represented in the * diagram. * * This is useful in the context of the properties panel in * order to update child elements of elements visible in * the diagram. * * Example: perform an update of a specific event definition * of an intermediate event. * * @class * @constructor */ function UpdateBusinessObjectListHandler(elementRegistry, bpmnFactory) { this._elementRegistry = elementRegistry; this._bpmnFactory = bpmnFactory; } UpdateBusinessObjectListHandler.$inject = [ 'elementRegistry', 'bpmnFactory' ]; module.exports = UpdateBusinessObjectListHandler; function ensureNotNull(prop, name) { if (!prop) { throw new Error(name + 'required'); } return prop; } // api ///////////////////////////////////////////// /** * Updates a element under a provided parent. */ UpdateBusinessObjectListHandler.prototype.execute = function(context) { var currentObject = ensureNotNull(context.currentObject, 'currentObject'), propertyName = ensureNotNull(context.propertyName, 'propertyName'), updatedObjectList = context.updatedObjectList, objectsToRemove = context.objectsToRemove || [], objectsToAdd = context.objectsToAdd || [], changed = [ context.element], // this will not change any diagram-js elements referencePropertyName; if (context.referencePropertyName) { referencePropertyName = context.referencePropertyName; } var objectList = currentObject[propertyName]; // adjust array reference in the parent business object context.previousList = currentObject[propertyName]; if (updatedObjectList) { currentObject[propertyName] = updatedObjectList; } else { var listCopy = []; // remove all objects which should be removed forEach(objectList, function(object) { if (objectsToRemove.indexOf(object) == -1) { listCopy.push(object); } }); // add all objects which should be added listCopy = listCopy.concat(objectsToAdd); // set property to new list if (listCopy.length > 0 || !referencePropertyName) { // as long as there are elements in the list update the list currentObject[propertyName] = listCopy; } else if (referencePropertyName) { // remove the list when it is empty var parentObject = currentObject.$parent; parentObject.set(referencePropertyName, undefined); } } context.changed = changed; // indicate changed on objects affected by the update return changed; }; /** * Reverts the update * * @method CreateBusinessObjectListHandler#revert * * @param {Object} context * * @return {djs.mode.Base} the updated element */ UpdateBusinessObjectListHandler.prototype.revert = function(context) { var currentObject = context.currentObject, propertyName = context.propertyName, previousList = context.previousList, parentObject = currentObject.$parent; if (context.referencePropertyName) { parentObject.set(context.referencePropertyName, currentObject); } // remove new element currentObject.set(propertyName, previousList); return context.changed; }; },{"lodash/forEach":522}],10:[function(require,module,exports){ 'use strict'; var forEach = require('lodash/forEach'); var HANDLERS = { 'properties-panel.update-businessobject': require('./UpdateBusinessObjectHandler'), 'properties-panel.create-and-reference': require('./CreateAndReferenceHandler'), 'properties-panel.create-businessobject-list': require('./CreateBusinessObjectListHandler'), 'properties-panel.update-businessobject-list': require('./UpdateBusinessObjectListHandler'), 'properties-panel.multi-command-executor': require('./MultiCommandHandler') }; function CommandInitializer(eventBus, commandStack) { eventBus.on('diagram.init', function() { forEach(HANDLERS, function(handler, id) { commandStack.registerHandler(id, handler); }); }); } CommandInitializer.$inject = [ 'eventBus', 'commandStack' ]; module.exports = { __init__: [ CommandInitializer ] }; },{"./CreateAndReferenceHandler":5,"./CreateBusinessObjectListHandler":6,"./MultiCommandHandler":7,"./UpdateBusinessObjectHandler":8,"./UpdateBusinessObjectListHandler":9,"lodash/forEach":522}],11:[function(require,module,exports){ 'use strict'; var ElementHelper = {}; module.exports = ElementHelper; /** * Creates a new element and set the parent to it * * @method ElementHelper#createElement * * @param {String} elementType of the new element * @param {Object} properties of the new element in key-value pairs * @param {moddle.object} parent of the new element * @param {BpmnFactory} factory which creates the new element * * @returns {djs.model.Base} element which is created */ ElementHelper.createElement = function(elementType, properties, parent, factory) { var element = factory.create(elementType, properties); element.$parent = parent; return element; }; },{}],12:[function(require,module,exports){ module.exports = { __depends__: [ require('./cmd'), require('diagram-js/lib/i18n/translate').default ], __init__: [ 'propertiesPanel' ], propertiesPanel: [ 'type', require('./PropertiesPanel') ] }; },{"./PropertiesPanel":3,"./cmd":10,"diagram-js/lib/i18n/translate":337}],13:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BaseModeler; var _inherits = _interopRequireDefault(require("inherits")); var _ids = _interopRequireDefault(require("ids")); var _BaseViewer = _interopRequireDefault(require("./BaseViewer")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A base modeler for BPMN 2.0 diagrams. * * Have a look at {@link Modeler} for a bundle that includes actual features. * * @param {Object} [options] configuration options to pass to the viewer * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body. * @param {string|number} [options.width] the width of the viewer * @param {string|number} [options.height] the height of the viewer * @param {Object} [options.moddleExtensions] extension packages to provide * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules */ function BaseModeler(options) { _BaseViewer.default.call(this, options); // hook ID collection into the modeler this.on('import.parse.complete', function (event) { if (!event.error) { this._collectIds(event.definitions, event.elementsById); } }, this); this.on('diagram.destroy', function () { this.get('moddle').ids.clear(); }, this); } (0, _inherits.default)(BaseModeler, _BaseViewer.default); /** * Create a moddle instance, attaching ids to it. * * @param {Object} options */ BaseModeler.prototype._createModdle = function (options) { var moddle = _BaseViewer.default.prototype._createModdle.call(this, options); // attach ids to moddle to be able to track // and validated ids in the BPMN 2.0 XML document // tree moddle.ids = new _ids.default([32, 36, 1]); return moddle; }; /** * Collect ids processed during parsing of the * definitions object. * * @param {ModdleElement} definitions * @param {Context} context */ BaseModeler.prototype._collectIds = function (definitions, elementsById) { var moddle = definitions.$model, ids = moddle.ids, id; // remove references from previous import ids.clear(); for (id in elementsById) { ids.claim(id, elementsById[id]); } }; },{"./BaseViewer":14,"ids":346,"inherits":347}],14:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BaseViewer; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _tinySvg = require("tiny-svg"); var _diagramJs = _interopRequireDefault(require("diagram-js")); var _bpmnModdle = _interopRequireDefault(require("bpmn-moddle")); var _inherits = _interopRequireDefault(require("inherits")); var _Importer = require("./import/Importer"); var _CompatibilityUtil = require("./util/CompatibilityUtil"); var _PoweredByUtil = require("./util/PoweredByUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * The code in the <project-logo></project-logo> area * must not be changed. * * @see http://bpmn.io/license for more information. */ /** * A base viewer for BPMN 2.0 diagrams. * * Have a look at {@link Viewer}, {@link NavigatedViewer} or {@link Modeler} for * bundles that include actual features. * * @param {Object} [options] configuration options to pass to the viewer * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body. * @param {string|number} [options.width] the width of the viewer * @param {string|number} [options.height] the height of the viewer * @param {Object} [options.moddleExtensions] extension packages to provide * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules */ function BaseViewer(options) { options = (0, _minDash.assign)({}, DEFAULT_OPTIONS, options); this._moddle = this._createModdle(options); this._container = this._createContainer(options); /* <project-logo> */ addProjectLogo(this._container); /* </project-logo> */ this._init(this._container, this._moddle, options); } (0, _inherits.default)(BaseViewer, _diagramJs.default); /** * The importXML result. * * @typedef {Object} ImportXMLResult * * @property {Array<string>} warnings */ /** * The importXML error. * * @typedef {Error} ImportXMLError * * @property {Array<string>} warnings */ /** * Parse and render a BPMN 2.0 diagram. * * Once finished the viewer reports back the result to the * provided callback function with (err, warnings). * * ## Life-Cycle Events * * During import the viewer will fire life-cycle events: * * * import.parse.start (about to read model from xml) * * import.parse.complete (model read; may have worked or not) * * import.render.start (graphical import start) * * import.render.complete (graphical import finished) * * import.done (everything done) * * You can use these events to hook into the life-cycle. * * @param {string} xml the BPMN 2.0 xml * @param {ModdleElement<BPMNDiagram>|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered) * * Returns {Promise<ImportXMLResult, ImportXMLError>} */ BaseViewer.prototype.importXML = (0, _CompatibilityUtil.wrapForCompatibility)(function importXML(xml, bpmnDiagram) { var self = this; function ParseCompleteEvent(data) { var event = self.get('eventBus').createEvent(data); // TODO(nikku): remove with future bpmn-js version Object.defineProperty(event, 'context', { enumerable: true, get: function () { console.warn(new Error('import.parse.complete <context> is deprecated ' + 'and will be removed in future library versions')); return { warnings: data.warnings, references: data.references, elementsById: data.elementsById }; } }); return event; } return new Promise(function (resolve, reject) { // hook in pre-parse listeners + // allow xml manipulation xml = self._emit('import.parse.start', { xml: xml }) || xml; self._moddle.fromXML(xml, 'bpmn:Definitions').then(function (result) { var definitions = result.rootElement; var references = result.references; var parseWarnings = result.warnings; var elementsById = result.elementsById; // hook in post parse listeners + // allow definitions manipulation definitions = self._emit('import.parse.complete', ParseCompleteEvent({ error: null, definitions: definitions, elementsById: elementsById, references: references, warnings: parseWarnings })) || definitions; self.importDefinitions(definitions, bpmnDiagram).then(function (result) { var allWarnings = [].concat(parseWarnings, result.warnings || []); self._emit('import.done', { error: null, warnings: allWarnings }); return resolve({ warnings: allWarnings }); }).catch(function (err) { var allWarnings = [].concat(parseWarnings, err.warnings || []); self._emit('import.done', { error: err, warnings: allWarnings }); return reject(addWarningsToError(err, allWarnings)); }); }).catch(function (err) { self._emit('import.parse.complete', { error: err }); err = checkValidationError(err); self._emit('import.done', { error: err, warnings: err.warnings }); return reject(err); }); }); }); /** * The importDefinitions result. * * @typedef {Object} ImportDefinitionsResult * * @property {Array<string>} warnings */ /** * The importDefinitions error. * * @typedef {Error} ImportDefinitionsError * * @property {Array<string>} warnings */ /** * Import parsed definitions and render a BPMN 2.0 diagram. * * Once finished the viewer reports back the result to the * provided callback function with (err, warnings). * * ## Life-Cycle Events * * During import the viewer will fire life-cycle events: * * * import.render.start (graphical import start) * * import.render.complete (graphical import finished) * * You can use these events to hook into the life-cycle. * * @param {ModdleElement<Definitions>} definitions parsed BPMN 2.0 definitions * @param {ModdleElement<BPMNDiagram>|string} [bpmnDiagram] BPMN diagram or id of diagram to render (if not provided, the first one will be rendered) * * Returns {Promise<ImportDefinitionsResult, ImportDefinitionsError>} */ BaseViewer.prototype.importDefinitions = (0, _CompatibilityUtil.wrapForCompatibility)(function importDefinitions(definitions, bpmnDiagram) { var self = this; return new Promise(function (resolve, reject) { self._setDefinitions(definitions); self.open(bpmnDiagram).then(function (result) { var warnings = result.warnings; return resolve({ warnings: warnings }); }).catch(function (err) { return reject(err); }); }); }); /** * The open result. * * @typedef {Object} OpenResult * * @property {Array<string>} warnings */ /** * The open error. * * @typedef {Error} OpenError * * @property {Array<string>} warnings */ /** * Open diagram of previously imported XML. * * Once finished the viewer reports back the result to the * provided callback function with (err, warnings). * * ## Life-Cycle Events * * During switch the viewer will fire life-cycle events: * * * import.render.start (graphical import start) * * import.render.complete (graphical import finished) * * You can use these events to hook into the life-cycle. * * @param {string|ModdleElement<BPMNDiagram>} [bpmnDiagramOrId] id or the diagram to open * * Returns {Promise<OpenResult, OpenError>} */ BaseViewer.prototype.open = (0, _CompatibilityUtil.wrapForCompatibility)(function open(bpmnDiagramOrId) { var definitions = this._definitions; var bpmnDiagram = bpmnDiagramOrId; var self = this; return new Promise(function (resolve, reject) { if (!definitions) { var err1 = new Error('no XML imported'); return reject(addWarningsToError(err1, [])); } if (typeof bpmnDiagramOrId === 'string') { bpmnDiagram = findBPMNDiagram(definitions, bpmnDiagramOrId); if (!bpmnDiagram) { var err2 = new Error('BPMNDiagram <' + bpmnDiagramOrId + '> not found'); return reject(addWarningsToError(err2, [])); } } // clear existing rendered diagram // catch synchronous exceptions during #clear() try { self.clear(); } catch (error) { return reject(addWarningsToError(error, [])); } // perform graphical import (0, _Importer.importBpmnDiagram)(self, definitions, bpmnDiagram).then(function (result) { var warnings = result.warnings; return resolve({ warnings: warnings }); }).catch(function (err) { return reject(err); }); }); }); /** * The saveXML result. * * @typedef {Object} SaveXMLResult * * @property {string} xml */ /** * Export the currently displayed BPMN 2.0 diagram as * a BPMN 2.0 XML document. * * ## Life-Cycle Events * * During XML saving the viewer will fire life-cycle events: * * * saveXML.start (before serialization) * * saveXML.serialized (after xml generation) * * saveXML.done (everything done) * * You can use these events to hook into the life-cycle. * * @param {Object} [options] export options * @param {boolean} [options.format=false] output formatted XML * @param {boolean} [options.preamble=true] output preamble * * Returns {Promise<SaveXMLResult, Error>} */ BaseViewer.prototype.saveXML = (0, _CompatibilityUtil.wrapForCompatibility)(function saveXML(options) { options = options || {}; var self = this; var definitions = this._definitions; return new Promise(function (resolve, reject) { if (!definitions) { var err = new Error('no definitions loaded'); return reject(err); } // allow to fiddle around with definitions definitions = self._emit('saveXML.start', { definitions: definitions }) || definitions; self._moddle.toXML(definitions, options).then(function (result) { var xml = result.xml; try { xml = self._emit('saveXML.serialized', { error: null, xml: xml }) || xml; self._emit('saveXML.done', { error: null, xml: xml }); } catch (e) { console.error('error in saveXML life-cycle listener', e); } return resolve({ xml: xml }); }).catch(function (err) { return reject(err); }); }); }); /** * The saveSVG result. * * @typedef {Object} SaveSVGResult * * @property {string} svg */ /** * Export the currently displayed BPMN 2.0 diagram as * an SVG image. * * ## Life-Cycle Events * * During SVG saving the viewer will fire life-cycle events: * * * saveSVG.start (before serialization) * * saveSVG.done (everything done) * * You can use these events to hook into the life-cycle. * * @param {Object} [options] * * Returns {Promise<SaveSVGResult, Error>} */ BaseViewer.prototype.saveSVG = (0, _CompatibilityUtil.wrapForCompatibility)(function saveSVG(options) { options = options || {}; var self = this; return new Promise(function (resolve, reject) { self._emit('saveSVG.start'); var svg, err; try { var canvas = self.get('canvas'); var contentNode = canvas.getDefaultLayer(), defsNode = (0, _minDom.query)('defs', canvas._svg); var contents = (0, _tinySvg.innerSVG)(contentNode), defs = defsNode ? '<defs>' + (0, _tinySvg.innerSVG)(defsNode) + '</defs>' : ''; var bbox = contentNode.getBBox(); svg = '<?xml version="1.0" encoding="utf-8"?>\n' + '<!-- created with bpmn-js / http://bpmn.io -->\n' + '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' + '<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" ' + 'width="' + bbox.width + '" height="' + bbox.height + '" ' + 'viewBox="' + bbox.x + ' ' + bbox.y + ' ' + bbox.width + ' ' + bbox.height + '" version="1.1">' + defs + contents + '</svg>'; } catch (e) { err = e; } self._emit('saveSVG.done', { error: err, svg: svg }); if (!err) { return resolve({ svg: svg }); } return reject(err); }); }); /** * Get a named diagram service. * * @example * * var elementRegistry = viewer.get('elementRegistry'); * var startEventShape = elementRegistry.get('StartEvent_1'); * * @param {string} name * * @return {Object} diagram service instance * * @method BaseViewer#get */ /** * Invoke a function in the context of this viewer. * * @example * * viewer.invoke(function(elementRegistry) { * var startEventShape = elementRegistry.get('StartEvent_1'); * }); * * @param {Function} fn to be invoked * * @return {Object} the functions return value * * @method BaseViewer#invoke */ BaseViewer.prototype._setDefinitions = function (definitions) { this._definitions = definitions; }; BaseViewer.prototype.getModules = function () { return this._modules; }; /** * Remove all drawn elements from the viewer. * * After calling this method the viewer can still * be reused for opening another diagram. * * @method BaseViewer#clear */ BaseViewer.prototype.clear = function () { if (!this.getDefinitions()) { // no diagram to clear return; } // remove businessObject#di binding // // this is necessary, as we establish the bindings // in the BpmnTreeWalker (and assume none are given // on reimport) this.get('elementRegistry').forEach(function (element) { var bo = element.businessObject; if (bo && bo.di) { delete bo.di; } }); // remove drawn elements _diagramJs.default.prototype.clear.call(this); }; /** * Destroy the viewer instance and remove all its * remainders from the document tree. */ BaseViewer.prototype.destroy = function () { // diagram destroy _diagramJs.default.prototype.destroy.call(this); // dom detach (0, _minDom.remove)(this._container); }; /** * Register an event listener * * Remove a previously added listener via {@link #off(event, callback)}. * * @param {string} event * @param {number} [priority] * @param {Function} callback * @param {Object} [that] */ BaseViewer.prototype.on = function (event, priority, callback, target) { return this.get('eventBus').on(event, priority, callback, target); }; /** * De-register an event listener * * @param {string} event * @param {Function} callback */ BaseViewer.prototype.off = function (event, callback) { this.get('eventBus').off(event, callback); }; BaseViewer.prototype.attachTo = function (parentNode) { if (!parentNode) { throw new Error('parentNode required'); } // ensure we detach from the // previous, old parent this.detach(); // unwrap jQuery if provided if (parentNode.get && parentNode.constructor.prototype.jquery) { parentNode = parentNode.get(0); } if (typeof parentNode === 'string') { parentNode = (0, _minDom.query)(parentNode); } parentNode.appendChild(this._container); this._emit('attach', {}); this.get('canvas').resized(); }; BaseViewer.prototype.getDefinitions = function () { return this._definitions; }; BaseViewer.prototype.detach = function () { var container = this._container, parentNode = container.parentNode; if (!parentNode) { return; } this._emit('detach', {}); parentNode.removeChild(container); }; BaseViewer.prototype._init = function (container, moddle, options) { var baseModules = options.modules || this.getModules(), additionalModules = options.additionalModules || [], staticModules = [{ bpmnjs: ['value', this], moddle: ['value', moddle] }]; var diagramModules = [].concat(staticModules, baseModules, additionalModules); var diagramOptions = (0, _minDash.assign)((0, _minDash.omit)(options, ['additionalModules']), { canvas: (0, _minDash.assign)({}, options.canvas, { container: container }), modules: diagramModules }); // invoke diagram constructor _diagramJs.default.call(this, diagramOptions); if (options && options.container) { this.attachTo(options.container); } }; /** * Emit an event on the underlying {@link EventBus} * * @param {string} type * @param {Object} event * * @return {Object} event processing result (if any) */ BaseViewer.prototype._emit = function (type, event) { return this.get('eventBus').fire(type, event); }; BaseViewer.prototype._createContainer = function (options) { var container = (0, _minDom.domify)('<div class="bjs-container"></div>'); (0, _minDash.assign)(container.style, { width: ensureUnit(options.width), height: ensureUnit(options.height), position: options.position }); return container; }; BaseViewer.prototype._createModdle = function (options) { var moddleOptions = (0, _minDash.assign)({}, this._moddleExtensions, options.moddleExtensions); return new _bpmnModdle.default(moddleOptions); }; BaseViewer.prototype._modules = []; // helpers /////////////// function addWarningsToError(err, warningsAry) { err.warnings = warningsAry; return err; } function checkValidationError(err) { // check if we can help the user by indicating wrong BPMN 2.0 xml // (in case he or the exporting tool did not get that right) var pattern = /unparsable content <([^>]+)> detected([\s\S]*)$/; var match = pattern.exec(err.message); if (match) { err.message = 'unparsable content <' + match[1] + '> detected; ' + 'this may indicate an invalid BPMN 2.0 diagram file' + match[2]; } return err; } var DEFAULT_OPTIONS = { width: '100%', height: '100%', position: 'relative' }; /** * Ensure the passed argument is a proper unit (defaulting to px) */ function ensureUnit(val) { return val + ((0, _minDash.isNumber)(val) ? 'px' : ''); } /** * Find BPMNDiagram in definitions by ID * * @param {ModdleElement<Definitions>} definitions * @param {string} diagramId * * @return {ModdleElement<BPMNDiagram>|null} */ function findBPMNDiagram(definitions, diagramId) { if (!diagramId) { return null; } return (0, _minDash.find)(definitions.diagrams, function (element) { return element.id === diagramId; }) || null; } /* <project-logo> */ /** * Adds the project logo to the diagram container as * required by the bpmn.io license. * * @see http://bpmn.io/license * * @param {Element} container */ function addProjectLogo(container) { var img = _PoweredByUtil.BPMNIO_IMG; var linkMarkup = '<a href="http://bpmn.io" ' + 'target="_blank" ' + 'class="bjs-powered-by" ' + 'title="Powered by bpmn.io" ' + 'style="position: absolute; bottom: 15px; right: 15px; z-index: 100; ' + _PoweredByUtil.LINK_STYLES + '">' + img + '</a>'; var linkElement = (0, _minDom.domify)(linkMarkup); container.appendChild(linkElement); _minDom.event.bind(linkElement, 'click', function (event) { (0, _PoweredByUtil.open)(); event.preventDefault(); }); } /* </project-logo> */ },{"./import/Importer":135,"./util/CompatibilityUtil":138,"./util/PoweredByUtil":142,"bpmn-moddle":330,"diagram-js":143,"inherits":347,"min-dash":555,"min-dom":556,"tiny-svg":567}],15:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Modeler; var _inherits = _interopRequireDefault(require("inherits")); var _BaseModeler = _interopRequireDefault(require("./BaseModeler")); var _Viewer = _interopRequireDefault(require("./Viewer")); var _NavigatedViewer = _interopRequireDefault(require("./NavigatedViewer")); var _keyboardMove = _interopRequireDefault(require("diagram-js/lib/navigation/keyboard-move")); var _movecanvas = _interopRequireDefault(require("diagram-js/lib/navigation/movecanvas")); var _touch = _interopRequireDefault(require("diagram-js/lib/navigation/touch")); var _zoomscroll = _interopRequireDefault(require("diagram-js/lib/navigation/zoomscroll")); var _alignElements = _interopRequireDefault(require("diagram-js/lib/features/align-elements")); var _autoPlace = _interopRequireDefault(require("./features/auto-place")); var _autoResize = _interopRequireDefault(require("./features/auto-resize")); var _autoScroll = _interopRequireDefault(require("diagram-js/lib/features/auto-scroll")); var _bendpoints = _interopRequireDefault(require("diagram-js/lib/features/bendpoints")); var _connect = _interopRequireDefault(require("diagram-js/lib/features/connect")); var _connectionPreview = _interopRequireDefault(require("diagram-js/lib/features/connection-preview")); var _contextPad = _interopRequireDefault(require("./features/context-pad")); var _copyPaste = _interopRequireDefault(require("./features/copy-paste")); var _create = _interopRequireDefault(require("diagram-js/lib/features/create")); var _distributeElements = _interopRequireDefault(require("./features/distribute-elements")); var _editorActions = _interopRequireDefault(require("./features/editor-actions")); var _gridSnapping = _interopRequireDefault(require("./features/grid-snapping")); var _interactionEvents = _interopRequireDefault(require("./features/interaction-events")); var _keyboard = _interopRequireDefault(require("./features/keyboard")); var _keyboardMoveSelection = _interopRequireDefault(require("diagram-js/lib/features/keyboard-move-selection")); var _labelEditing = _interopRequireDefault(require("./features/label-editing")); var _modeling = _interopRequireDefault(require("./features/modeling")); var _move = _interopRequireDefault(require("diagram-js/lib/features/move")); var _palette = _interopRequireDefault(require("./features/palette")); var _replacePreview = _interopRequireDefault(require("./features/replace-preview")); var _resize = _interopRequireDefault(require("diagram-js/lib/features/resize")); var _snapping = _interopRequireDefault(require("./features/snapping")); var _search = _interopRequireDefault(require("./features/search")); var _CompatibilityUtil = require("./util/CompatibilityUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var initialDiagram = '<?xml version="1.0" encoding="UTF-8"?>' + '<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' + 'xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" ' + 'xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" ' + 'xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" ' + 'targetNamespace="http://bpmn.io/schema/bpmn" ' + 'id="Definitions_1">' + '<bpmn:process id="Process_1" isExecutable="false">' + '<bpmn:startEvent id="StartEvent_1"/>' + '</bpmn:process>' + '<bpmndi:BPMNDiagram id="BPMNDiagram_1">' + '<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">' + '<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">' + '<dc:Bounds height="36.0" width="36.0" x="173.0" y="102.0"/>' + '</bpmndi:BPMNShape>' + '</bpmndi:BPMNPlane>' + '</bpmndi:BPMNDiagram>' + '</bpmn:definitions>'; /** * A modeler for BPMN 2.0 diagrams. * * * ## Extending the Modeler * * In order to extend the viewer pass extension modules to bootstrap via the * `additionalModules` option. An extension module is an object that exposes * named services. * * The following example depicts the integration of a simple * logging component that integrates with interaction events: * * * ```javascript * * // logging component * function InteractionLogger(eventBus) { * eventBus.on('element.hover', function(event) { * console.log() * }) * } * * InteractionLogger.$inject = [ 'eventBus' ]; // minification save * * // extension module * var extensionModule = { * __init__: [ 'interactionLogger' ], * interactionLogger: [ 'type', InteractionLogger ] * }; * * // extend the viewer * var bpmnModeler = new Modeler({ additionalModules: [ extensionModule ] }); * bpmnModeler.importXML(...); * ``` * * * ## Customizing / Replacing Components * * You can replace individual diagram components by redefining them in override modules. * This works for all components, including those defined in the core. * * Pass in override modules via the `options.additionalModules` flag like this: * * ```javascript * function CustomContextPadProvider(contextPad) { * * contextPad.registerProvider(this); * * this.getContextPadEntries = function(element) { * // no entries, effectively disable the context pad * return {}; * }; * } * * CustomContextPadProvider.$inject = [ 'contextPad' ]; * * var overrideModule = { * contextPadProvider: [ 'type', CustomContextPadProvider ] * }; * * var bpmnModeler = new Modeler({ additionalModules: [ overrideModule ]}); * ``` * * @param {Object} [options] configuration options to pass to the viewer * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body. * @param {string|number} [options.width] the width of the viewer * @param {string|number} [options.height] the height of the viewer * @param {Object} [options.moddleExtensions] extension packages to provide * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules */ function Modeler(options) { _BaseModeler.default.call(this, options); } (0, _inherits.default)(Modeler, _BaseModeler.default); Modeler.Viewer = _Viewer.default; Modeler.NavigatedViewer = _NavigatedViewer.default; /** * The createDiagram result. * * @typedef {Object} CreateDiagramResult * * @property {Array<string>} warnings */ /** * The createDiagram error. * * @typedef {Error} CreateDiagramError * * @property {Array<string>} warnings */ /** * Create a new diagram to start modeling. * * Returns {Promise<CreateDiagramResult, CreateDiagramError>} */ Modeler.prototype.createDiagram = (0, _CompatibilityUtil.wrapForCompatibility)(function createDiagram() { return this.importXML(initialDiagram); }); Modeler.prototype._interactionModules = [// non-modeling components _keyboardMove.default, _movecanvas.default, _touch.default, _zoomscroll.default]; Modeler.prototype._modelingModules = [// modeling components _alignElements.default, _autoPlace.default, _autoScroll.default, _autoResize.default, _bendpoints.default, _connect.default, _connectionPreview.default, _contextPad.default, _copyPaste.default, _create.default, _distributeElements.default, _editorActions.default, _gridSnapping.default, _interactionEvents.default, _keyboard.default, _keyboardMoveSelection.default, _labelEditing.default, _modeling.default, _move.default, _palette.default, _replacePreview.default, _resize.default, _snapping.default, _search.default]; // modules the modeler is composed of // // - viewer modules // - interaction modules // - modeling modules Modeler.prototype._modules = [].concat(_Viewer.default.prototype._modules, Modeler.prototype._interactionModules, Modeler.prototype._modelingModules); },{"./BaseModeler":13,"./NavigatedViewer":16,"./Viewer":17,"./features/auto-place":26,"./features/auto-resize":29,"./features/context-pad":31,"./features/copy-paste":34,"./features/distribute-elements":38,"./features/editor-actions":40,"./features/grid-snapping":46,"./features/interaction-events":48,"./features/keyboard":50,"./features/label-editing":55,"./features/modeling":110,"./features/palette":116,"./features/replace-preview":121,"./features/search":128,"./features/snapping":132,"./util/CompatibilityUtil":138,"diagram-js/lib/features/align-elements":159,"diagram-js/lib/features/auto-scroll":169,"diagram-js/lib/features/bendpoints":176,"diagram-js/lib/features/connect":183,"diagram-js/lib/features/connection-preview":185,"diagram-js/lib/features/create":192,"diagram-js/lib/features/keyboard-move-selection":213,"diagram-js/lib/features/move":251,"diagram-js/lib/features/resize":269,"diagram-js/lib/navigation/keyboard-move":304,"diagram-js/lib/navigation/movecanvas":306,"diagram-js/lib/navigation/touch":307,"diagram-js/lib/navigation/zoomscroll":310,"inherits":347}],16:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = NavigatedViewer; var _inherits = _interopRequireDefault(require("inherits")); var _Viewer = _interopRequireDefault(require("./Viewer")); var _keyboardMove = _interopRequireDefault(require("diagram-js/lib/navigation/keyboard-move")); var _movecanvas = _interopRequireDefault(require("diagram-js/lib/navigation/movecanvas")); var _zoomscroll = _interopRequireDefault(require("diagram-js/lib/navigation/zoomscroll")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A viewer that includes mouse navigation facilities * * @param {Object} options */ function NavigatedViewer(options) { _Viewer.default.call(this, options); } (0, _inherits.default)(NavigatedViewer, _Viewer.default); NavigatedViewer.prototype._navigationModules = [_keyboardMove.default, _movecanvas.default, _zoomscroll.default]; NavigatedViewer.prototype._modules = [].concat(_Viewer.default.prototype._modules, NavigatedViewer.prototype._navigationModules); },{"./Viewer":17,"diagram-js/lib/navigation/keyboard-move":304,"diagram-js/lib/navigation/movecanvas":306,"diagram-js/lib/navigation/zoomscroll":310,"inherits":347}],17:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Viewer; var _inherits = _interopRequireDefault(require("inherits")); var _core = _interopRequireDefault(require("./core")); var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate")); var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection")); var _overlays = _interopRequireDefault(require("diagram-js/lib/features/overlays")); var _BaseViewer = _interopRequireDefault(require("./BaseViewer")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A viewer for BPMN 2.0 diagrams. * * Have a look at {@link NavigatedViewer} or {@link Modeler} for bundles that include * additional features. * * * ## Extending the Viewer * * In order to extend the viewer pass extension modules to bootstrap via the * `additionalModules` option. An extension module is an object that exposes * named services. * * The following example depicts the integration of a simple * logging component that integrates with interaction events: * * * ```javascript * * // logging component * function InteractionLogger(eventBus) { * eventBus.on('element.hover', function(event) { * console.log() * }) * } * * InteractionLogger.$inject = [ 'eventBus' ]; // minification save * * // extension module * var extensionModule = { * __init__: [ 'interactionLogger' ], * interactionLogger: [ 'type', InteractionLogger ] * }; * * // extend the viewer * var bpmnViewer = new Viewer({ additionalModules: [ extensionModule ] }); * bpmnViewer.importXML(...); * ``` * * @param {Object} [options] configuration options to pass to the viewer * @param {DOMElement} [options.container] the container to render the viewer in, defaults to body. * @param {string|number} [options.width] the width of the viewer * @param {string|number} [options.height] the height of the viewer * @param {Object} [options.moddleExtensions] extension packages to provide * @param {Array<didi.Module>} [options.modules] a list of modules to override the default modules * @param {Array<didi.Module>} [options.additionalModules] a list of modules to use with the default modules */ function Viewer(options) { _BaseViewer.default.call(this, options); } (0, _inherits.default)(Viewer, _BaseViewer.default); // modules the viewer is composed of Viewer.prototype._modules = [_core.default, _translate.default, _selection.default, _overlays.default]; // default moddle extensions the viewer is composed of Viewer.prototype._moddleExtensions = {}; },{"./BaseViewer":14,"./core":18,"diagram-js/lib/features/overlays":256,"diagram-js/lib/features/selection":278,"diagram-js/lib/i18n/translate":296,"inherits":347}],18:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _draw = _interopRequireDefault(require("../draw")); var _import = _interopRequireDefault(require("../import")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_draw.default, _import.default] }; exports.default = _default; },{"../draw":23,"../import":137}],19:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isTypedEvent = isTypedEvent; exports.isThrowEvent = isThrowEvent; exports.isCollection = isCollection; exports.getDi = getDi; exports.getSemantic = getSemantic; exports.getFillColor = getFillColor; exports.getStrokeColor = getStrokeColor; exports.getCirclePath = getCirclePath; exports.getRoundRectPath = getRoundRectPath; exports.getDiamondPath = getDiamondPath; exports.getRectPath = getRectPath; var _minDash = require("min-dash"); var _RenderUtil = require("diagram-js/lib/util/RenderUtil"); // element utils ////////////////////// /** * Checks if eventDefinition of the given element matches with semantic type. * * @return {boolean} true if element is of the given semantic type */ function isTypedEvent(event, eventDefinitionType, filter) { function matches(definition, filter) { return (0, _minDash.every)(filter, function (val, key) { // we want a == conversion here, to be able to catch // undefined == false and friends /* jshint -W116 */ return definition[key] == val; }); } return (0, _minDash.some)(event.eventDefinitions, function (definition) { return definition.$type === eventDefinitionType && matches(event, filter); }); } function isThrowEvent(event) { return event.$type === 'bpmn:IntermediateThrowEvent' || event.$type === 'bpmn:EndEvent'; } function isCollection(element) { var dataObject = element.dataObjectRef; return element.isCollection || dataObject && dataObject.isCollection; } function getDi(element) { return element.businessObject.di; } function getSemantic(element) { return element.businessObject; } // color access ////////////////////// function getFillColor(element, defaultColor) { return getDi(element).get('bioc:fill') || defaultColor || 'white'; } function getStrokeColor(element, defaultColor) { return getDi(element).get('bioc:stroke') || defaultColor || 'black'; } // cropping path customizations ////////////////////// function getCirclePath(shape) { var cx = shape.x + shape.width / 2, cy = shape.y + shape.height / 2, radius = shape.width / 2; var circlePath = [['M', cx, cy], ['m', 0, -radius], ['a', radius, radius, 0, 1, 1, 0, 2 * radius], ['a', radius, radius, 0, 1, 1, 0, -2 * radius], ['z']]; return (0, _RenderUtil.componentsToPath)(circlePath); } function getRoundRectPath(shape, borderRadius) { var x = shape.x, y = shape.y, width = shape.width, height = shape.height; var roundRectPath = [['M', x + borderRadius, y], ['l', width - borderRadius * 2, 0], ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, borderRadius], ['l', 0, height - borderRadius * 2], ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, borderRadius], ['l', borderRadius * 2 - width, 0], ['a', borderRadius, borderRadius, 0, 0, 1, -borderRadius, -borderRadius], ['l', 0, borderRadius * 2 - height], ['a', borderRadius, borderRadius, 0, 0, 1, borderRadius, -borderRadius], ['z']]; return (0, _RenderUtil.componentsToPath)(roundRectPath); } function getDiamondPath(shape) { var width = shape.width, height = shape.height, x = shape.x, y = shape.y, halfWidth = width / 2, halfHeight = height / 2; var diamondPath = [['M', x + halfWidth, y], ['l', halfWidth, halfHeight], ['l', -halfWidth, halfHeight], ['l', -halfWidth, -halfHeight], ['z']]; return (0, _RenderUtil.componentsToPath)(diamondPath); } function getRectPath(shape) { var x = shape.x, y = shape.y, width = shape.width, height = shape.height; var rectPath = [['M', x, y], ['l', width, 0], ['l', 0, height], ['l', -width, 0], ['z']]; return (0, _RenderUtil.componentsToPath)(rectPath); } },{"diagram-js/lib/util/RenderUtil":327,"min-dash":555}],20:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnRenderer; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _BaseRenderer = _interopRequireDefault(require("diagram-js/lib/draw/BaseRenderer")); var _DiUtil = require("../util/DiUtil"); var _LabelUtil = require("../features/label-editing/LabelUtil"); var _ModelUtil = require("../util/ModelUtil"); var _RenderUtil = require("diagram-js/lib/util/RenderUtil"); var _BpmnRenderUtil = require("./BpmnRenderUtil"); var _minDom = require("min-dom"); var _tinySvg = require("tiny-svg"); var _SvgTransformUtil = require("diagram-js/lib/util/SvgTransformUtil"); var _ids = _interopRequireDefault(require("ids")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var RENDERER_IDS = new _ids.default(); var TASK_BORDER_RADIUS = 10; var INNER_OUTER_DIST = 3; var DEFAULT_FILL_OPACITY = .95, HIGH_FILL_OPACITY = .35; function BpmnRenderer(config, eventBus, styles, pathMap, canvas, textRenderer, priority) { _BaseRenderer.default.call(this, eventBus, priority); var defaultFillColor = config && config.defaultFillColor, defaultStrokeColor = config && config.defaultStrokeColor; var rendererId = RENDERER_IDS.next(); var markers = {}; var computeStyle = styles.computeStyle; function addMarker(id, options) { var attrs = (0, _minDash.assign)({ fill: 'black', strokeWidth: 1, strokeLinecap: 'round', strokeDasharray: 'none' }, options.attrs); var ref = options.ref || { x: 0, y: 0 }; var scale = options.scale || 1; // fix for safari / chrome / firefox bug not correctly // resetting stroke dash array if (attrs.strokeDasharray === 'none') { attrs.strokeDasharray = [10000, 1]; } var marker = (0, _tinySvg.create)('marker'); (0, _tinySvg.attr)(options.element, attrs); (0, _tinySvg.append)(marker, options.element); (0, _tinySvg.attr)(marker, { id: id, viewBox: '0 0 20 20', refX: ref.x, refY: ref.y, markerWidth: 20 * scale, markerHeight: 20 * scale, orient: 'auto' }); var defs = (0, _minDom.query)('defs', canvas._svg); if (!defs) { defs = (0, _tinySvg.create)('defs'); (0, _tinySvg.append)(canvas._svg, defs); } (0, _tinySvg.append)(defs, marker); markers[id] = marker; } function colorEscape(str) { // only allow characters and numbers return str.replace(/[^0-9a-zA-z]+/g, '_'); } function marker(type, fill, stroke) { var id = type + '-' + colorEscape(fill) + '-' + colorEscape(stroke) + '-' + rendererId; if (!markers[id]) { createMarker(id, type, fill, stroke); } return 'url(#' + id + ')'; } function createMarker(id, type, fill, stroke) { if (type === 'sequenceflow-end') { var sequenceflowEnd = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(sequenceflowEnd, { d: 'M 1 5 L 11 10 L 1 15 Z' }); addMarker(id, { element: sequenceflowEnd, ref: { x: 11, y: 10 }, scale: 0.5, attrs: { fill: stroke, stroke: stroke } }); } if (type === 'messageflow-start') { var messageflowStart = (0, _tinySvg.create)('circle'); (0, _tinySvg.attr)(messageflowStart, { cx: 6, cy: 6, r: 3.5 }); addMarker(id, { element: messageflowStart, attrs: { fill: fill, stroke: stroke }, ref: { x: 6, y: 6 } }); } if (type === 'messageflow-end') { var messageflowEnd = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(messageflowEnd, { d: 'm 1 5 l 0 -3 l 7 3 l -7 3 z' }); addMarker(id, { element: messageflowEnd, attrs: { fill: fill, stroke: stroke, strokeLinecap: 'butt' }, ref: { x: 8.5, y: 5 } }); } if (type === 'association-start') { var associationStart = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(associationStart, { d: 'M 11 5 L 1 10 L 11 15' }); addMarker(id, { element: associationStart, attrs: { fill: 'none', stroke: stroke, strokeWidth: 1.5 }, ref: { x: 1, y: 10 }, scale: 0.5 }); } if (type === 'association-end') { var associationEnd = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(associationEnd, { d: 'M 1 5 L 11 10 L 1 15' }); addMarker(id, { element: associationEnd, attrs: { fill: 'none', stroke: stroke, strokeWidth: 1.5 }, ref: { x: 12, y: 10 }, scale: 0.5 }); } if (type === 'conditional-flow-marker') { var conditionalflowMarker = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(conditionalflowMarker, { d: 'M 0 10 L 8 6 L 16 10 L 8 14 Z' }); addMarker(id, { element: conditionalflowMarker, attrs: { fill: fill, stroke: stroke }, ref: { x: -1, y: 10 }, scale: 0.5 }); } if (type === 'conditional-default-flow-marker') { var conditionaldefaultflowMarker = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(conditionaldefaultflowMarker, { d: 'M 6 4 L 10 16' }); addMarker(id, { element: conditionaldefaultflowMarker, attrs: { stroke: stroke }, ref: { x: 0, y: 10 }, scale: 0.5 }); } } function drawCircle(parentGfx, width, height, offset, attrs) { if ((0, _minDash.isObject)(offset)) { attrs = offset; offset = 0; } offset = offset || 0; attrs = computeStyle(attrs, { stroke: 'black', strokeWidth: 2, fill: 'white' }); if (attrs.fill === 'none') { delete attrs.fillOpacity; } var cx = width / 2, cy = height / 2; var circle = (0, _tinySvg.create)('circle'); (0, _tinySvg.attr)(circle, { cx: cx, cy: cy, r: Math.round((width + height) / 4 - offset) }); (0, _tinySvg.attr)(circle, attrs); (0, _tinySvg.append)(parentGfx, circle); return circle; } function drawRect(parentGfx, width, height, r, offset, attrs) { if ((0, _minDash.isObject)(offset)) { attrs = offset; offset = 0; } offset = offset || 0; attrs = computeStyle(attrs, { stroke: 'black', strokeWidth: 2, fill: 'white' }); var rect = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(rect, { x: offset, y: offset, width: width - offset * 2, height: height - offset * 2, rx: r, ry: r }); (0, _tinySvg.attr)(rect, attrs); (0, _tinySvg.append)(parentGfx, rect); return rect; } function drawDiamond(parentGfx, width, height, attrs) { var x_2 = width / 2; var y_2 = height / 2; var points = [{ x: x_2, y: 0 }, { x: width, y: y_2 }, { x: x_2, y: height }, { x: 0, y: y_2 }]; var pointsString = points.map(function (point) { return point.x + ',' + point.y; }).join(' '); attrs = computeStyle(attrs, { stroke: 'black', strokeWidth: 2, fill: 'white' }); var polygon = (0, _tinySvg.create)('polygon'); (0, _tinySvg.attr)(polygon, { points: pointsString }); (0, _tinySvg.attr)(polygon, attrs); (0, _tinySvg.append)(parentGfx, polygon); return polygon; } function drawLine(parentGfx, waypoints, attrs) { attrs = computeStyle(attrs, ['no-fill'], { stroke: 'black', strokeWidth: 2, fill: 'none' }); var line = (0, _RenderUtil.createLine)(waypoints, attrs); (0, _tinySvg.append)(parentGfx, line); return line; } function drawPath(parentGfx, d, attrs) { attrs = computeStyle(attrs, ['no-fill'], { strokeWidth: 2, stroke: 'black' }); var path = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(path, { d: d }); (0, _tinySvg.attr)(path, attrs); (0, _tinySvg.append)(parentGfx, path); return path; } function drawMarker(type, parentGfx, path, attrs) { return drawPath(parentGfx, path, (0, _minDash.assign)({ 'data-marker': type }, attrs)); } function as(type) { return function (parentGfx, element) { return handlers[type](parentGfx, element); }; } function renderer(type) { return handlers[type]; } function renderEventContent(element, parentGfx) { var event = (0, _BpmnRenderUtil.getSemantic)(element); var isThrowing = (0, _BpmnRenderUtil.isThrowEvent)(event); if (event.eventDefinitions && event.eventDefinitions.length > 1) { if (event.parallelMultiple) { return renderer('bpmn:ParallelMultipleEventDefinition')(parentGfx, element, isThrowing); } else { return renderer('bpmn:MultipleEventDefinition')(parentGfx, element, isThrowing); } } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:MessageEventDefinition')) { return renderer('bpmn:MessageEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TimerEventDefinition')) { return renderer('bpmn:TimerEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:ConditionalEventDefinition')) { return renderer('bpmn:ConditionalEventDefinition')(parentGfx, element); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:SignalEventDefinition')) { return renderer('bpmn:SignalEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:EscalationEventDefinition')) { return renderer('bpmn:EscalationEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:LinkEventDefinition')) { return renderer('bpmn:LinkEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:ErrorEventDefinition')) { return renderer('bpmn:ErrorEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CancelEventDefinition')) { return renderer('bpmn:CancelEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:CompensateEventDefinition')) { return renderer('bpmn:CompensateEventDefinition')(parentGfx, element, isThrowing); } if ((0, _BpmnRenderUtil.isTypedEvent)(event, 'bpmn:TerminateEventDefinition')) { return renderer('bpmn:TerminateEventDefinition')(parentGfx, element, isThrowing); } return null; } function renderLabel(parentGfx, label, options) { options = (0, _minDash.assign)({ size: { width: 100 } }, options); var text = textRenderer.createText(label || '', options); (0, _tinySvg.classes)(text).add('djs-label'); (0, _tinySvg.append)(parentGfx, text); return text; } function renderEmbeddedLabel(parentGfx, element, align) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element); return renderLabel(parentGfx, semantic.name, { box: element, align: align, padding: 5, style: { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) } }); } function renderExternalLabel(parentGfx, element) { var box = { width: 90, height: 30, x: element.width / 2 + element.x, y: element.height / 2 + element.y }; return renderLabel(parentGfx, (0, _LabelUtil.getLabel)(element), { box: box, fitBox: true, style: (0, _minDash.assign)({}, textRenderer.getExternalStyle(), { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }) }); } function renderLaneLabel(parentGfx, text, element) { var textBox = renderLabel(parentGfx, text, { box: { height: 30, width: element.height }, align: 'center-middle', style: { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) } }); var top = -1 * element.height; (0, _SvgTransformUtil.transform)(textBox, 0, -top, 270); } function createPathFromConnection(connection) { var waypoints = connection.waypoints; var pathData = 'm ' + waypoints[0].x + ',' + waypoints[0].y; for (var i = 1; i < waypoints.length; i++) { pathData += 'L' + waypoints[i].x + ',' + waypoints[i].y + ' '; } return pathData; } var handlers = this.handlers = { 'bpmn:Event': function (parentGfx, element, attrs) { if (!('fillOpacity' in attrs)) { attrs.fillOpacity = DEFAULT_FILL_OPACITY; } return drawCircle(parentGfx, element.width, element.height, attrs); }, 'bpmn:StartEvent': function (parentGfx, element) { var attrs = { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var semantic = (0, _BpmnRenderUtil.getSemantic)(element); if (!semantic.isInterrupting) { attrs = { strokeDasharray: '6', strokeLinecap: 'round', fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; } var circle = renderer('bpmn:Event')(parentGfx, element, attrs); renderEventContent(element, parentGfx); return circle; }, 'bpmn:MessageEventDefinition': function (parentGfx, element, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_MESSAGE', { xScaleFactor: 0.9, yScaleFactor: 0.9, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.235, my: 0.315 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) : (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor); var stroke = isThrowing ? (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor) : (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); var messagePath = drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: stroke }); return messagePath; }, 'bpmn:TimerEventDefinition': function (parentGfx, element) { var circle = drawCircle(parentGfx, element.width, element.height, 0.2 * element.height, { strokeWidth: 2, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var pathData = pathMap.getScaledPath('EVENT_TIMER_WH', { xScaleFactor: 0.75, yScaleFactor: 0.75, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.5, my: 0.5 } }); drawPath(parentGfx, pathData, { strokeWidth: 2, strokeLinecap: 'square', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); for (var i = 0; i < 12; i++) { var linePathData = pathMap.getScaledPath('EVENT_TIMER_LINE', { xScaleFactor: 0.75, yScaleFactor: 0.75, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.5, my: 0.5 } }); var width = element.width / 2; var height = element.height / 2; drawPath(parentGfx, linePathData, { strokeWidth: 1, strokeLinecap: 'square', transform: 'rotate(' + i * 30 + ',' + height + ',' + width + ')', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); } return circle; }, 'bpmn:EscalationEventDefinition': function (parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_ESCALATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.5, my: 0.2 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:ConditionalEventDefinition': function (parentGfx, event) { var pathData = pathMap.getScaledPath('EVENT_CONDITIONAL', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.5, my: 0.222 } }); return drawPath(parentGfx, pathData, { strokeWidth: 1, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:LinkEventDefinition': function (parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_LINK', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.57, my: 0.263 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:ErrorEventDefinition': function (parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_ERROR', { xScaleFactor: 1.1, yScaleFactor: 1.1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.2, my: 0.722 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:CancelEventDefinition': function (parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_CANCEL_45', { xScaleFactor: 1.0, yScaleFactor: 1.0, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.638, my: -0.055 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; var path = drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); (0, _SvgTransformUtil.rotate)(path, 45); return path; }, 'bpmn:CompensateEventDefinition': function (parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_COMPENSATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.22, my: 0.5 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:SignalEventDefinition': function (parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_SIGNAL', { xScaleFactor: 0.9, yScaleFactor: 0.9, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.5, my: 0.2 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill, stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:MultipleEventDefinition': function (parentGfx, event, isThrowing) { var pathData = pathMap.getScaledPath('EVENT_MULTIPLE', { xScaleFactor: 1.1, yScaleFactor: 1.1, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.222, my: 0.36 } }); var fill = isThrowing ? (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) : 'none'; return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: fill }); }, 'bpmn:ParallelMultipleEventDefinition': function (parentGfx, event) { var pathData = pathMap.getScaledPath('EVENT_PARALLEL_MULTIPLE', { xScaleFactor: 1.2, yScaleFactor: 1.2, containerWidth: event.width, containerHeight: event.height, position: { mx: 0.458, my: 0.194 } }); return drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(event, defaultStrokeColor) }); }, 'bpmn:EndEvent': function (parentGfx, element) { var circle = renderer('bpmn:Event')(parentGfx, element, { strokeWidth: 4, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); renderEventContent(element, parentGfx, true); return circle; }, 'bpmn:TerminateEventDefinition': function (parentGfx, element) { var circle = drawCircle(parentGfx, element.width, element.height, 8, { strokeWidth: 4, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return circle; }, 'bpmn:IntermediateEvent': function (parentGfx, element) { var outer = renderer('bpmn:Event')(parentGfx, element, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); /* inner */ drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, 'none'), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); renderEventContent(element, parentGfx); return outer; }, 'bpmn:IntermediateCatchEvent': as('bpmn:IntermediateEvent'), 'bpmn:IntermediateThrowEvent': as('bpmn:IntermediateEvent'), 'bpmn:Activity': function (parentGfx, element, attrs) { attrs = attrs || {}; if (!('fillOpacity' in attrs)) { attrs.fillOpacity = DEFAULT_FILL_OPACITY; } return drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, attrs); }, 'bpmn:Task': function (parentGfx, element) { var attrs = { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var rect = renderer('bpmn:Activity')(parentGfx, element, attrs); renderEmbeddedLabel(parentGfx, element, 'center-middle'); attachTaskMarkers(parentGfx, element); return rect; }, 'bpmn:ServiceTask': function (parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var pathDataBG = pathMap.getScaledPath('TASK_TYPE_SERVICE', { abspos: { x: 12, y: 18 } }); /* service bg */ drawPath(parentGfx, pathDataBG, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var fillPathData = pathMap.getScaledPath('TASK_TYPE_SERVICE_FILL', { abspos: { x: 17.2, y: 18 } }); /* service fill */ drawPath(parentGfx, fillPathData, { strokeWidth: 0, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor) }); var pathData = pathMap.getScaledPath('TASK_TYPE_SERVICE', { abspos: { x: 17, y: 22 } }); /* service */ drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:UserTask': function (parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var x = 15; var y = 12; var pathData = pathMap.getScaledPath('TASK_TYPE_USER_1', { abspos: { x: x, y: y } }); /* user path */ drawPath(parentGfx, pathData, { strokeWidth: 0.5, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var pathData2 = pathMap.getScaledPath('TASK_TYPE_USER_2', { abspos: { x: x, y: y } }); /* user2 path */ drawPath(parentGfx, pathData2, { strokeWidth: 0.5, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var pathData3 = pathMap.getScaledPath('TASK_TYPE_USER_3', { abspos: { x: x, y: y } }); /* user3 path */ drawPath(parentGfx, pathData3, { strokeWidth: 0.5, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:ManualTask': function (parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var pathData = pathMap.getScaledPath('TASK_TYPE_MANUAL', { abspos: { x: 17, y: 15 } }); /* manual path */ drawPath(parentGfx, pathData, { strokeWidth: 0.5, // 0.25, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:SendTask': function (parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var pathData = pathMap.getScaledPath('TASK_TYPE_SEND', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: 21, containerHeight: 14, position: { mx: 0.285, my: 0.357 } }); /* send path */ drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor) }); return task; }, 'bpmn:ReceiveTask': function (parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element); var task = renderer('bpmn:Task')(parentGfx, element); var pathData; if (semantic.instantiate) { drawCircle(parentGfx, 28, 28, 20 * 0.22, { strokeWidth: 1 }); pathData = pathMap.getScaledPath('TASK_TYPE_INSTANTIATING_SEND', { abspos: { x: 7.77, y: 9.52 } }); } else { pathData = pathMap.getScaledPath('TASK_TYPE_SEND', { xScaleFactor: 0.9, yScaleFactor: 0.9, containerWidth: 21, containerHeight: 14, position: { mx: 0.3, my: 0.4 } }); } /* receive path */ drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:ScriptTask': function (parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var pathData = pathMap.getScaledPath('TASK_TYPE_SCRIPT', { abspos: { x: 15, y: 20 } }); /* script path */ drawPath(parentGfx, pathData, { strokeWidth: 1, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:BusinessRuleTask': function (parentGfx, element) { var task = renderer('bpmn:Task')(parentGfx, element); var headerPathData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_HEADER', { abspos: { x: 8, y: 8 } }); var businessHeaderPath = drawPath(parentGfx, headerPathData); (0, _tinySvg.attr)(businessHeaderPath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, '#aaaaaa'), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var headerData = pathMap.getScaledPath('TASK_TYPE_BUSINESS_RULE_MAIN', { abspos: { x: 8, y: 8 } }); var businessPath = drawPath(parentGfx, headerData); (0, _tinySvg.attr)(businessPath, { strokeWidth: 1, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return task; }, 'bpmn:SubProcess': function (parentGfx, element, attrs) { attrs = (0, _minDash.assign)({ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }, attrs); var rect = renderer('bpmn:Activity')(parentGfx, element, attrs); var expanded = (0, _DiUtil.isExpanded)(element); if ((0, _DiUtil.isEventSubProcess)(element)) { (0, _tinySvg.attr)(rect, { strokeDasharray: '1,2' }); } renderEmbeddedLabel(parentGfx, element, expanded ? 'center-top' : 'center-middle'); if (expanded) { attachTaskMarkers(parentGfx, element); } else { attachTaskMarkers(parentGfx, element, ['SubProcessMarker']); } return rect; }, 'bpmn:AdHocSubProcess': function (parentGfx, element) { return renderer('bpmn:SubProcess')(parentGfx, element); }, 'bpmn:Transaction': function (parentGfx, element) { var outer = renderer('bpmn:SubProcess')(parentGfx, element); var innerAttrs = styles.style(['no-fill', 'no-events'], { stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); /* inner path */ drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS - 2, INNER_OUTER_DIST, innerAttrs); return outer; }, 'bpmn:CallActivity': function (parentGfx, element) { return renderer('bpmn:SubProcess')(parentGfx, element, { strokeWidth: 5 }); }, 'bpmn:Participant': function (parentGfx, element) { var attrs = { fillOpacity: DEFAULT_FILL_OPACITY, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var lane = renderer('bpmn:Lane')(parentGfx, element, attrs); var expandedPool = (0, _DiUtil.isExpanded)(element); if (expandedPool) { drawLine(parentGfx, [{ x: 30, y: 0 }, { x: 30, y: element.height }], { stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var text = (0, _BpmnRenderUtil.getSemantic)(element).name; renderLaneLabel(parentGfx, text, element); } else { // Collapsed pool draw text inline var text2 = (0, _BpmnRenderUtil.getSemantic)(element).name; renderLabel(parentGfx, text2, { box: element, align: 'center-middle', style: { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) } }); } var participantMultiplicity = !!(0, _BpmnRenderUtil.getSemantic)(element).participantMultiplicity; if (participantMultiplicity) { renderer('ParticipantMultiplicityMarker')(parentGfx, element); } return lane; }, 'bpmn:Lane': function (parentGfx, element, attrs) { var rect = drawRect(parentGfx, element.width, element.height, 0, (0, _minDash.assign)({ fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), fillOpacity: HIGH_FILL_OPACITY, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }, attrs)); var semantic = (0, _BpmnRenderUtil.getSemantic)(element); if (semantic.$type === 'bpmn:Lane') { var text = semantic.name; renderLaneLabel(parentGfx, text, element); } return rect; }, 'bpmn:InclusiveGateway': function (parentGfx, element) { var diamond = renderer('bpmn:Gateway')(parentGfx, element); /* circle path */ drawCircle(parentGfx, element.width, element.height, element.height * 0.24, { strokeWidth: 2.5, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return diamond; }, 'bpmn:ExclusiveGateway': function (parentGfx, element) { var diamond = renderer('bpmn:Gateway')(parentGfx, element); var pathData = pathMap.getScaledPath('GATEWAY_EXCLUSIVE', { xScaleFactor: 0.4, yScaleFactor: 0.4, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.32, my: 0.3 } }); if ((0, _BpmnRenderUtil.getDi)(element).isMarkerVisible) { drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); } return diamond; }, 'bpmn:ComplexGateway': function (parentGfx, element) { var diamond = renderer('bpmn:Gateway')(parentGfx, element); var pathData = pathMap.getScaledPath('GATEWAY_COMPLEX', { xScaleFactor: 0.5, yScaleFactor: 0.5, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.46, my: 0.26 } }); /* complex path */ drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return diamond; }, 'bpmn:ParallelGateway': function (parentGfx, element) { var diamond = renderer('bpmn:Gateway')(parentGfx, element); var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', { xScaleFactor: 0.6, yScaleFactor: 0.6, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.46, my: 0.2 } }); /* parallel path */ drawPath(parentGfx, pathData, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return diamond; }, 'bpmn:EventBasedGateway': function (parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element); var diamond = renderer('bpmn:Gateway')(parentGfx, element); /* outer circle path */ drawCircle(parentGfx, element.width, element.height, element.height * 0.20, { strokeWidth: 1, fill: 'none', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var type = semantic.eventGatewayType; var instantiate = !!semantic.instantiate; function drawEvent() { var pathData = pathMap.getScaledPath('GATEWAY_EVENT_BASED', { xScaleFactor: 0.18, yScaleFactor: 0.18, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.36, my: 0.44 } }); var attrs = { strokeWidth: 2, fill: (0, _BpmnRenderUtil.getFillColor)(element, 'none'), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; /* event path */ drawPath(parentGfx, pathData, attrs); } if (type === 'Parallel') { var pathData = pathMap.getScaledPath('GATEWAY_PARALLEL', { xScaleFactor: 0.4, yScaleFactor: 0.4, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.474, my: 0.296 } }); var parallelPath = drawPath(parentGfx, pathData); (0, _tinySvg.attr)(parallelPath, { strokeWidth: 1, fill: 'none' }); } else if (type === 'Exclusive') { if (!instantiate) { var innerCircle = drawCircle(parentGfx, element.width, element.height, element.height * 0.26); (0, _tinySvg.attr)(innerCircle, { strokeWidth: 1, fill: 'none', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); } drawEvent(); } return diamond; }, 'bpmn:Gateway': function (parentGfx, element) { var attrs = { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), fillOpacity: DEFAULT_FILL_OPACITY, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; return drawDiamond(parentGfx, element.width, element.height, attrs); }, 'bpmn:SequenceFlow': function (parentGfx, element) { var pathData = createPathFromConnection(element); var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); var attrs = { strokeLinejoin: 'round', markerEnd: marker('sequenceflow-end', fill, stroke), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var path = drawPath(parentGfx, pathData, attrs); var sequenceFlow = (0, _BpmnRenderUtil.getSemantic)(element); var source; if (element.source) { source = element.source.businessObject; // conditional flow marker if (sequenceFlow.conditionExpression && source.$instanceOf('bpmn:Activity')) { (0, _tinySvg.attr)(path, { markerStart: marker('conditional-flow-marker', fill, stroke) }); } // default marker if (source.default && (source.$instanceOf('bpmn:Gateway') || source.$instanceOf('bpmn:Activity')) && source.default === sequenceFlow) { (0, _tinySvg.attr)(path, { markerStart: marker('conditional-default-flow-marker', fill, stroke) }); } } return path; }, 'bpmn:Association': function (parentGfx, element, attrs) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element); var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); attrs = (0, _minDash.assign)({ strokeDasharray: '0.5, 5', strokeLinecap: 'round', strokeLinejoin: 'round', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }, attrs || {}); if (semantic.associationDirection === 'One' || semantic.associationDirection === 'Both') { attrs.markerEnd = marker('association-end', fill, stroke); } if (semantic.associationDirection === 'Both') { attrs.markerStart = marker('association-start', fill, stroke); } return drawLine(parentGfx, element.waypoints, attrs); }, 'bpmn:DataInputAssociation': function (parentGfx, element) { var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); return renderer('bpmn:Association')(parentGfx, element, { markerEnd: marker('association-end', fill, stroke) }); }, 'bpmn:DataOutputAssociation': function (parentGfx, element) { var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); return renderer('bpmn:Association')(parentGfx, element, { markerEnd: marker('association-end', fill, stroke) }); }, 'bpmn:MessageFlow': function (parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element), di = (0, _BpmnRenderUtil.getDi)(element); var fill = (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke = (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor); var pathData = createPathFromConnection(element); var attrs = { markerEnd: marker('messageflow-end', fill, stroke), markerStart: marker('messageflow-start', fill, stroke), strokeDasharray: '10, 12', strokeLinecap: 'round', strokeLinejoin: 'round', strokeWidth: '1.5px', stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; var path = drawPath(parentGfx, pathData, attrs); if (semantic.messageRef) { var midPoint = path.getPointAtLength(path.getTotalLength() / 2); var markerPathData = pathMap.getScaledPath('MESSAGE_FLOW_MARKER', { abspos: { x: midPoint.x, y: midPoint.y } }); var messageAttrs = { strokeWidth: 1 }; if (di.messageVisibleKind === 'initiating') { messageAttrs.fill = 'white'; messageAttrs.stroke = 'black'; } else { messageAttrs.fill = '#888'; messageAttrs.stroke = 'white'; } drawPath(parentGfx, markerPathData, messageAttrs); } return path; }, 'bpmn:DataObject': function (parentGfx, element) { var pathData = pathMap.getScaledPath('DATA_OBJECT_PATH', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.474, my: 0.296 } }); var elementObject = drawPath(parentGfx, pathData, { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), fillOpacity: DEFAULT_FILL_OPACITY, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var semantic = (0, _BpmnRenderUtil.getSemantic)(element); if ((0, _BpmnRenderUtil.isCollection)(semantic)) { renderDataItemCollection(parentGfx, element); } return elementObject; }, 'bpmn:DataObjectReference': as('bpmn:DataObject'), 'bpmn:DataInput': function (parentGfx, element) { var arrowPathData = pathMap.getRawPath('DATA_ARROW'); // page var elementObject = renderer('bpmn:DataObject')(parentGfx, element); /* input arrow path */ drawPath(parentGfx, arrowPathData, { strokeWidth: 1 }); return elementObject; }, 'bpmn:DataOutput': function (parentGfx, element) { var arrowPathData = pathMap.getRawPath('DATA_ARROW'); // page var elementObject = renderer('bpmn:DataObject')(parentGfx, element); /* output arrow path */ drawPath(parentGfx, arrowPathData, { strokeWidth: 1, fill: 'black' }); return elementObject; }, 'bpmn:DataStoreReference': function (parentGfx, element) { var DATA_STORE_PATH = pathMap.getScaledPath('DATA_STORE', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0, my: 0.133 } }); var elementStore = drawPath(parentGfx, DATA_STORE_PATH, { strokeWidth: 2, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), fillOpacity: DEFAULT_FILL_OPACITY, stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); return elementStore; }, 'bpmn:BoundaryEvent': function (parentGfx, element) { var semantic = (0, _BpmnRenderUtil.getSemantic)(element), cancel = semantic.cancelActivity; var attrs = { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }; if (!cancel) { attrs.strokeDasharray = '6'; attrs.strokeLinecap = 'round'; } // apply fillOpacity var outerAttrs = (0, _minDash.assign)({}, attrs, { fillOpacity: 1 }); // apply no-fill var innerAttrs = (0, _minDash.assign)({}, attrs, { fill: 'none' }); var outer = renderer('bpmn:Event')(parentGfx, element, outerAttrs); /* inner path */ drawCircle(parentGfx, element.width, element.height, INNER_OUTER_DIST, innerAttrs); renderEventContent(element, parentGfx); return outer; }, 'bpmn:Group': function (parentGfx, element) { var group = drawRect(parentGfx, element.width, element.height, TASK_BORDER_RADIUS, { stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), strokeWidth: 1, strokeDasharray: '8,3,1,3', fill: 'none', pointerEvents: 'none' }); return group; }, 'label': function (parentGfx, element) { return renderExternalLabel(parentGfx, element); }, 'bpmn:TextAnnotation': function (parentGfx, element) { var style = { 'fill': 'none', 'stroke': 'none' }; var textElement = drawRect(parentGfx, element.width, element.height, 0, 0, style); var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.0, my: 0.0 } }); drawPath(parentGfx, textPathData, { stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); var text = (0, _BpmnRenderUtil.getSemantic)(element).text || ''; renderLabel(parentGfx, text, { box: element, align: 'left-top', padding: 5, style: { fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) } }); return textElement; }, 'ParticipantMultiplicityMarker': function (parentGfx, element) { var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: element.width / 2 / element.width, my: (element.height - 15) / element.height } }); drawMarker('participant-multiplicity', parentGfx, markerPath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'SubProcessMarker': function (parentGfx, element) { var markerRect = drawRect(parentGfx, 14, 14, 0, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); // Process marker is placed in the middle of the box // therefore fixed values can be used here (0, _SvgTransformUtil.translate)(markerRect, element.width / 2 - 7.5, element.height - 20); var markerPath = pathMap.getScaledPath('MARKER_SUB_PROCESS', { xScaleFactor: 1.5, yScaleFactor: 1.5, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 - 7.5) / element.width, my: (element.height - 20) / element.height } }); drawMarker('sub-process', parentGfx, markerPath, { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'ParallelMarker': function (parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_PARALLEL', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.parallel) / element.width, my: (element.height - 20) / element.height } }); drawMarker('parallel', parentGfx, markerPath, { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'SequentialMarker': function (parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_SEQUENTIAL', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.seq) / element.width, my: (element.height - 19) / element.height } }); drawMarker('sequential', parentGfx, markerPath, { fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'CompensationMarker': function (parentGfx, element, position) { var markerMath = pathMap.getScaledPath('MARKER_COMPENSATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.compensation) / element.width, my: (element.height - 13) / element.height } }); drawMarker('compensation', parentGfx, markerMath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); }, 'LoopMarker': function (parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_LOOP', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.loop) / element.width, my: (element.height - 7) / element.height } }); drawMarker('loop', parentGfx, markerPath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getFillColor)(element, defaultFillColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), strokeLinecap: 'round', strokeMiterlimit: 0.5 }); }, 'AdhocMarker': function (parentGfx, element, position) { var markerPath = pathMap.getScaledPath('MARKER_ADHOC', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: (element.width / 2 + position.adhoc) / element.width, my: (element.height - 15) / element.height } }); drawMarker('adhoc', parentGfx, markerPath, { strokeWidth: 1, fill: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor), stroke: (0, _BpmnRenderUtil.getStrokeColor)(element, defaultStrokeColor) }); } }; function attachTaskMarkers(parentGfx, element, taskMarkers) { var obj = (0, _BpmnRenderUtil.getSemantic)(element); var subprocess = taskMarkers && taskMarkers.indexOf('SubProcessMarker') !== -1; var position; if (subprocess) { position = { seq: -21, parallel: -22, compensation: -42, loop: -18, adhoc: 10 }; } else { position = { seq: -3, parallel: -6, compensation: -27, loop: 0, adhoc: 10 }; } (0, _minDash.forEach)(taskMarkers, function (marker) { renderer(marker)(parentGfx, element, position); }); if (obj.isForCompensation) { renderer('CompensationMarker')(parentGfx, element, position); } if (obj.$type === 'bpmn:AdHocSubProcess') { renderer('AdhocMarker')(parentGfx, element, position); } var loopCharacteristics = obj.loopCharacteristics, isSequential = loopCharacteristics && loopCharacteristics.isSequential; if (loopCharacteristics) { if (isSequential === undefined) { renderer('LoopMarker')(parentGfx, element, position); } if (isSequential === false) { renderer('ParallelMarker')(parentGfx, element, position); } if (isSequential === true) { renderer('SequentialMarker')(parentGfx, element, position); } } } function renderDataItemCollection(parentGfx, element) { var yPosition = (element.height - 16) / element.height; var pathData = pathMap.getScaledPath('DATA_OBJECT_COLLECTION_PATH', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.451, my: yPosition } }); /* collection path */ drawPath(parentGfx, pathData, { strokeWidth: 2 }); } // extension API, use at your own risk this._drawPath = drawPath; } (0, _inherits.default)(BpmnRenderer, _BaseRenderer.default); BpmnRenderer.$inject = ['config.bpmnRenderer', 'eventBus', 'styles', 'pathMap', 'canvas', 'textRenderer']; BpmnRenderer.prototype.canRender = function (element) { return (0, _ModelUtil.is)(element, 'bpmn:BaseElement'); }; BpmnRenderer.prototype.drawShape = function (parentGfx, element) { var type = element.type; var h = this.handlers[type]; /* jshint -W040 */ return h(parentGfx, element); }; BpmnRenderer.prototype.drawConnection = function (parentGfx, element) { var type = element.type; var h = this.handlers[type]; /* jshint -W040 */ return h(parentGfx, element); }; BpmnRenderer.prototype.getShapePath = function (element) { if ((0, _ModelUtil.is)(element, 'bpmn:Event')) { return (0, _BpmnRenderUtil.getCirclePath)(element); } if ((0, _ModelUtil.is)(element, 'bpmn:Activity')) { return (0, _BpmnRenderUtil.getRoundRectPath)(element, TASK_BORDER_RADIUS); } if ((0, _ModelUtil.is)(element, 'bpmn:Gateway')) { return (0, _BpmnRenderUtil.getDiamondPath)(element); } return (0, _BpmnRenderUtil.getRectPath)(element); }; },{"../features/label-editing/LabelUtil":53,"../util/DiUtil":139,"../util/ModelUtil":141,"./BpmnRenderUtil":19,"diagram-js/lib/draw/BaseRenderer":154,"diagram-js/lib/util/RenderUtil":327,"diagram-js/lib/util/SvgTransformUtil":328,"ids":346,"inherits":347,"min-dash":555,"min-dom":556,"tiny-svg":567}],21:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = PathMap; /** * Map containing SVG paths needed by BpmnRenderer. */ function PathMap() { /** * Contains a map of path elements * * <h1>Path definition</h1> * A parameterized path is defined like this: * <pre> * 'GATEWAY_PARALLEL': { * d: 'm {mx},{my} {e.x0},0 0,{e.x1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' + '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z', * height: 17.5, * width: 17.5, * heightElements: [2.5, 7.5], * widthElements: [2.5, 7.5] * } * </pre> * <p>It's important to specify a correct <b>height and width</b> for the path as the scaling * is based on the ratio between the specified height and width in this object and the * height and width that is set as scale target (Note x,y coordinates will be scaled with * individual ratios).</p> * <p>The '<b>heightElements</b>' and '<b>widthElements</b>' array must contain the values that will be scaled. * The scaling is based on the computed ratios. * Coordinates on the y axis should be in the <b>heightElement</b>'s array, they will be scaled using * the computed ratio coefficient. * In the parameterized path the scaled values can be accessed through the 'e' object in {} brackets. * <ul> * <li>The values for the y axis can be accessed in the path string using {e.y0}, {e.y1}, ....</li> * <li>The values for the x axis can be accessed in the path string using {e.x0}, {e.x1}, ....</li> * </ul> * The numbers x0, x1 respectively y0, y1, ... map to the corresponding array index. * </p> */ this.pathMap = { 'EVENT_MESSAGE': { d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}', height: 36, width: 36, heightElements: [6, 14], widthElements: [10.5, 21] }, 'EVENT_SIGNAL': { d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x1},0 Z', height: 36, width: 36, heightElements: [18], widthElements: [10, 20] }, 'EVENT_ESCALATION': { d: 'M {mx},{my} l {e.x0},{e.y0} l -{e.x0},-{e.y1} l -{e.x0},{e.y1} Z', height: 36, width: 36, heightElements: [20, 7], widthElements: [8] }, 'EVENT_CONDITIONAL': { d: 'M {e.x0},{e.y0} l {e.x1},0 l 0,{e.y2} l -{e.x1},0 Z ' + 'M {e.x2},{e.y3} l {e.x0},0 ' + 'M {e.x2},{e.y4} l {e.x0},0 ' + 'M {e.x2},{e.y5} l {e.x0},0 ' + 'M {e.x2},{e.y6} l {e.x0},0 ' + 'M {e.x2},{e.y7} l {e.x0},0 ' + 'M {e.x2},{e.y8} l {e.x0},0 ', height: 36, width: 36, heightElements: [8.5, 14.5, 18, 11.5, 14.5, 17.5, 20.5, 23.5, 26.5], widthElements: [10.5, 14.5, 12.5] }, 'EVENT_LINK': { d: 'm {mx},{my} 0,{e.y0} -{e.x1},0 0,{e.y1} {e.x1},0 0,{e.y0} {e.x0},-{e.y2} -{e.x0},-{e.y2} z', height: 36, width: 36, heightElements: [4.4375, 6.75, 7.8125], widthElements: [9.84375, 13.5] }, 'EVENT_ERROR': { d: 'm {mx},{my} {e.x0},-{e.y0} {e.x1},-{e.y1} {e.x2},{e.y2} {e.x3},-{e.y3} -{e.x4},{e.y4} -{e.x5},-{e.y5} z', height: 36, width: 36, heightElements: [0.023, 8.737, 8.151, 16.564, 10.591, 8.714], widthElements: [0.085, 6.672, 6.97, 4.273, 5.337, 6.636] }, 'EVENT_CANCEL_45': { d: 'm {mx},{my} -{e.x1},0 0,{e.x0} {e.x1},0 0,{e.y1} {e.x0},0 ' + '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z', height: 36, width: 36, heightElements: [4.75, 8.5], widthElements: [4.75, 8.5] }, 'EVENT_COMPENSATION': { d: 'm {mx},{my} {e.x0},-{e.y0} 0,{e.y1} z m {e.x1},-{e.y2} {e.x2},-{e.y3} 0,{e.y1} -{e.x2},-{e.y3} z', height: 36, width: 36, heightElements: [6.5, 13, 0.4, 6.1], widthElements: [9, 9.3, 8.7] }, 'EVENT_TIMER_WH': { d: 'M {mx},{my} l {e.x0},-{e.y0} m -{e.x0},{e.y0} l {e.x1},{e.y1} ', height: 36, width: 36, heightElements: [10, 2], widthElements: [3, 7] }, 'EVENT_TIMER_LINE': { d: 'M {mx},{my} ' + 'm {e.x0},{e.y0} l -{e.x1},{e.y1} ', height: 36, width: 36, heightElements: [10, 3], widthElements: [0, 0] }, 'EVENT_MULTIPLE': { d: 'm {mx},{my} {e.x1},-{e.y0} {e.x1},{e.y0} -{e.x0},{e.y1} -{e.x2},0 z', height: 36, width: 36, heightElements: [6.28099, 12.56199], widthElements: [3.1405, 9.42149, 12.56198] }, 'EVENT_PARALLEL_MULTIPLE': { d: 'm {mx},{my} {e.x0},0 0,{e.y1} {e.x1},0 0,{e.y0} -{e.x1},0 0,{e.y1} ' + '-{e.x0},0 0,-{e.y1} -{e.x1},0 0,-{e.y0} {e.x1},0 z', height: 36, width: 36, heightElements: [2.56228, 7.68683], widthElements: [2.56228, 7.68683] }, 'GATEWAY_EXCLUSIVE': { d: 'm {mx},{my} {e.x0},{e.y0} {e.x1},{e.y0} {e.x2},0 {e.x4},{e.y2} ' + '{e.x4},{e.y1} {e.x2},0 {e.x1},{e.y3} {e.x0},{e.y3} ' + '{e.x3},0 {e.x5},{e.y1} {e.x5},{e.y2} {e.x3},0 z', height: 17.5, width: 17.5, heightElements: [8.5, 6.5312, -6.5312, -8.5], widthElements: [6.5, -6.5, 3, -3, 5, -5] }, 'GATEWAY_PARALLEL': { d: 'm {mx},{my} 0,{e.y1} -{e.x1},0 0,{e.y0} {e.x1},0 0,{e.y1} {e.x0},0 ' + '0,-{e.y1} {e.x1},0 0,-{e.y0} -{e.x1},0 0,-{e.y1} -{e.x0},0 z', height: 30, width: 30, heightElements: [5, 12.5], widthElements: [5, 12.5] }, 'GATEWAY_EVENT_BASED': { d: 'm {mx},{my} {e.x0},{e.y0} {e.x0},{e.y1} {e.x1},{e.y2} {e.x2},0 z', height: 11, width: 11, heightElements: [-6, 6, 12, -12], widthElements: [9, -3, -12] }, 'GATEWAY_COMPLEX': { d: 'm {mx},{my} 0,{e.y0} -{e.x0},-{e.y1} -{e.x1},{e.y2} {e.x0},{e.y1} -{e.x2},0 0,{e.y3} ' + '{e.x2},0 -{e.x0},{e.y1} l {e.x1},{e.y2} {e.x0},-{e.y1} 0,{e.y0} {e.x3},0 0,-{e.y0} {e.x0},{e.y1} ' + '{e.x1},-{e.y2} -{e.x0},-{e.y1} {e.x2},0 0,-{e.y3} -{e.x2},0 {e.x0},-{e.y1} -{e.x1},-{e.y2} ' + '-{e.x0},{e.y1} 0,-{e.y0} -{e.x3},0 z', height: 17.125, width: 17.125, heightElements: [4.875, 3.4375, 2.125, 3], widthElements: [3.4375, 2.125, 4.875, 3] }, 'DATA_OBJECT_PATH': { d: 'm 0,0 {e.x1},0 {e.x0},{e.y0} 0,{e.y1} -{e.x2},0 0,-{e.y2} {e.x1},0 0,{e.y0} {e.x0},0', height: 61, width: 51, heightElements: [10, 50, 60], widthElements: [10, 40, 50, 60] }, 'DATA_OBJECT_COLLECTION_PATH': { d: 'm {mx}, {my} ' + 'm 0 15 l 0 -15 ' + 'm 4 15 l 0 -15 ' + 'm 4 15 l 0 -15 ', height: 61, width: 51, heightElements: [12], widthElements: [1, 6, 12, 15] }, 'DATA_ARROW': { d: 'm 5,9 9,0 0,-3 5,5 -5,5 0,-3 -9,0 z', height: 61, width: 51, heightElements: [], widthElements: [] }, 'DATA_STORE': { d: 'm {mx},{my} ' + 'l 0,{e.y2} ' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' + 'l 0,-{e.y2} ' + 'c -{e.x0},-{e.y1} -{e.x1},-{e.y1} -{e.x2},0' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0 ' + 'm -{e.x2},{e.y0}' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0' + 'm -{e.x2},{e.y0}' + 'c {e.x0},{e.y1} {e.x1},{e.y1} {e.x2},0', height: 61, width: 61, heightElements: [7, 10, 45], widthElements: [2, 58, 60] }, 'TEXT_ANNOTATION': { d: 'm {mx}, {my} m 10,0 l -10,0 l 0,{e.y0} l 10,0', height: 30, width: 10, heightElements: [30], widthElements: [10] }, 'MARKER_SUB_PROCESS': { d: 'm{mx},{my} m 7,2 l 0,10 m -5,-5 l 10,0', height: 10, width: 10, heightElements: [], widthElements: [] }, 'MARKER_PARALLEL': { d: 'm{mx},{my} m 3,2 l 0,10 m 3,-10 l 0,10 m 3,-10 l 0,10', height: 10, width: 10, heightElements: [], widthElements: [] }, 'MARKER_SEQUENTIAL': { d: 'm{mx},{my} m 0,3 l 10,0 m -10,3 l 10,0 m -10,3 l 10,0', height: 10, width: 10, heightElements: [], widthElements: [] }, 'MARKER_COMPENSATION': { d: 'm {mx},{my} 7,-5 0,10 z m 7.1,-0.3 6.9,-4.7 0,10 -6.9,-4.7 z', height: 10, width: 21, heightElements: [], widthElements: [] }, 'MARKER_LOOP': { d: 'm {mx},{my} c 3.526979,0 6.386161,-2.829858 6.386161,-6.320661 0,-3.490806 -2.859182,-6.320661 ' + '-6.386161,-6.320661 -3.526978,0 -6.38616,2.829855 -6.38616,6.320661 0,1.745402 ' + '0.714797,3.325567 1.870463,4.469381 0.577834,0.571908 1.265885,1.034728 2.029916,1.35457 ' + 'l -0.718163,-3.909793 m 0.718163,3.909793 -3.885211,0.802902', height: 13.9, width: 13.7, heightElements: [], widthElements: [] }, 'MARKER_ADHOC': { d: 'm {mx},{my} m 0.84461,2.64411 c 1.05533,-1.23780996 2.64337,-2.07882 4.29653,-1.97997996 2.05163,0.0805 ' + '3.85579,1.15803 5.76082,1.79107 1.06385,0.34139996 2.24454,0.1438 3.18759,-0.43767 0.61743,-0.33642 ' + '1.2775,-0.64078 1.7542,-1.17511 0,0.56023 0,1.12046 0,1.6807 -0.98706,0.96237996 -2.29792,1.62393996 ' + '-3.6918,1.66181996 -1.24459,0.0927 -2.46671,-0.2491 -3.59505,-0.74812 -1.35789,-0.55965 ' + '-2.75133,-1.33436996 -4.27027,-1.18121996 -1.37741,0.14601 -2.41842,1.13685996 -3.44288,1.96782996 z', height: 4, width: 15, heightElements: [], widthElements: [] }, 'TASK_TYPE_SEND': { d: 'm {mx},{my} l 0,{e.y1} l {e.x1},0 l 0,-{e.y1} z l {e.x0},{e.y0} l {e.x0},-{e.y0}', height: 14, width: 21, heightElements: [6, 14], widthElements: [10.5, 21] }, 'TASK_TYPE_SCRIPT': { d: 'm {mx},{my} c 9.966553,-6.27276 -8.000926,-7.91932 2.968968,-14.938 l -8.802728,0 ' + 'c -10.969894,7.01868 6.997585,8.66524 -2.968967,14.938 z ' + 'm -7,-12 l 5,0 ' + 'm -4.5,3 l 4.5,0 ' + 'm -3,3 l 5,0' + 'm -4,3 l 5,0', height: 15, width: 12.6, heightElements: [6, 14], widthElements: [10.5, 21] }, 'TASK_TYPE_USER_1': { d: 'm {mx},{my} c 0.909,-0.845 1.594,-2.049 1.594,-3.385 0,-2.554 -1.805,-4.62199999 ' + '-4.357,-4.62199999 -2.55199998,0 -4.28799998,2.06799999 -4.28799998,4.62199999 0,1.348 ' + '0.974,2.562 1.89599998,3.405 -0.52899998,0.187 -5.669,2.097 -5.794,4.7560005 v 6.718 ' + 'h 17 v -6.718 c 0,-2.2980005 -5.5279996,-4.5950005 -6.0509996,-4.7760005 z' + 'm -8,6 l 0,5.5 m 11,0 l 0,-5' }, 'TASK_TYPE_USER_2': { d: 'm {mx},{my} m 2.162,1.009 c 0,2.4470005 -2.158,4.4310005 -4.821,4.4310005 ' + '-2.66499998,0 -4.822,-1.981 -4.822,-4.4310005 ' }, 'TASK_TYPE_USER_3': { d: 'm {mx},{my} m -6.9,-3.80 c 0,0 2.25099998,-2.358 4.27399998,-1.177 2.024,1.181 4.221,1.537 ' + '4.124,0.965 -0.098,-0.57 -0.117,-3.79099999 -4.191,-4.13599999 -3.57499998,0.001 ' + '-4.20799998,3.36699999 -4.20699998,4.34799999 z' }, 'TASK_TYPE_MANUAL': { d: 'm {mx},{my} c 0.234,-0.01 5.604,0.008 8.029,0.004 0.808,0 1.271,-0.172 1.417,-0.752 0.227,-0.898 ' + '-0.334,-1.314 -1.338,-1.316 -2.467,-0.01 -7.886,-0.004 -8.108,-0.004 -0.014,-0.079 0.016,-0.533 0,-0.61 ' + '0.195,-0.042 8.507,0.006 9.616,0.002 0.877,-0.007 1.35,-0.438 1.353,-1.208 0.003,-0.768 -0.479,-1.09 ' + '-1.35,-1.091 -2.968,-0.002 -9.619,-0.013 -9.619,-0.013 v -0.591 c 0,0 5.052,-0.016 7.225,-0.016 ' + '0.888,-0.002 1.354,-0.416 1.351,-1.193 -0.006,-0.761 -0.492,-1.196 -1.361,-1.196 -3.473,-0.005 ' + '-10.86,-0.003 -11.0829995,-0.003 -0.022,-0.047 -0.045,-0.094 -0.069,-0.139 0.3939995,-0.319 ' + '2.0409995,-1.626 2.4149995,-2.017 0.469,-0.4870005 0.519,-1.1650005 0.162,-1.6040005 -0.414,-0.511 ' + '-0.973,-0.5 -1.48,-0.236 -1.4609995,0.764 -6.5999995,3.6430005 -7.7329995,4.2710005 -0.9,0.499 ' + '-1.516,1.253 -1.882,2.19 -0.37000002,0.95 -0.17,2.01 -0.166,2.979 0.004,0.718 -0.27300002,1.345 ' + '-0.055,2.063 0.629,2.087 2.425,3.312 4.859,3.318 4.6179995,0.014 9.2379995,-0.139 13.8569995,-0.158 ' + '0.755,-0.004 1.171,-0.301 1.182,-1.033 0.012,-0.754 -0.423,-0.969 -1.183,-0.973 -1.778,-0.01 ' + '-5.824,-0.004 -6.04,-0.004 10e-4,-0.084 0.003,-0.586 10e-4,-0.67 z' }, 'TASK_TYPE_INSTANTIATING_SEND': { d: 'm {mx},{my} l 0,8.4 l 12.6,0 l 0,-8.4 z l 6.3,3.6 l 6.3,-3.6' }, 'TASK_TYPE_SERVICE': { d: 'm {mx},{my} v -1.71335 c 0.352326,-0.0705 0.703932,-0.17838 1.047628,-0.32133 ' + '0.344416,-0.14465 0.665822,-0.32133 0.966377,-0.52145 l 1.19431,1.18005 1.567487,-1.57688 ' + '-1.195028,-1.18014 c 0.403376,-0.61394 0.683079,-1.29908 0.825447,-2.01824 l 1.622133,-0.01 ' + 'v -2.2196 l -1.636514,0.01 c -0.07333,-0.35153 -0.178319,-0.70024 -0.323564,-1.04372 ' + '-0.145244,-0.34406 -0.321407,-0.6644 -0.522735,-0.96217 l 1.131035,-1.13631 -1.583305,-1.56293 ' + '-1.129598,1.13589 c -0.614052,-0.40108 -1.302883,-0.68093 -2.022633,-0.82247 l 0.0093,-1.61852 ' + 'h -2.241173 l 0.0042,1.63124 c -0.353763,0.0736 -0.705369,0.17977 -1.049785,0.32371 -0.344415,0.14437 ' + '-0.665102,0.32092 -0.9635006,0.52046 l -1.1698628,-1.15823 -1.5667691,1.5792 1.1684265,1.15669 ' + 'c -0.4026573,0.61283 -0.68308,1.29797 -0.8247287,2.01713 l -1.6588041,0.003 v 2.22174 ' + 'l 1.6724648,-0.006 c 0.073327,0.35077 0.1797598,0.70243 0.3242851,1.04472 0.1452428,0.34448 ' + '0.3214064,0.6644 0.5227339,0.96066 l -1.1993431,1.19723 1.5840256,1.56011 1.1964668,-1.19348 ' + 'c 0.6140517,0.40346 1.3028827,0.68232 2.0233517,0.82331 l 7.19e-4,1.69892 h 2.226848 z ' + 'm 0.221462,-3.9957 c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' + '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' + '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z' }, 'TASK_TYPE_SERVICE_FILL': { d: 'm {mx},{my} c -1.788948,0.7502 -3.8576,-0.0928 -4.6097055,-1.87438 -0.7521065,-1.78321 ' + '0.090598,-3.84627 1.8802645,-4.59604 1.78823,-0.74936 3.856881,0.0929 4.608987,1.87437 ' + '0.752106,1.78165 -0.0906,3.84612 -1.879546,4.59605 z' }, 'TASK_TYPE_BUSINESS_RULE_HEADER': { d: 'm {mx},{my} 0,4 20,0 0,-4 z' }, 'TASK_TYPE_BUSINESS_RULE_MAIN': { d: 'm {mx},{my} 0,12 20,0 0,-12 z' + 'm 0,8 l 20,0 ' + 'm -13,-4 l 0,8' }, 'MESSAGE_FLOW_MARKER': { d: 'm {mx},{my} m -10.5 ,-7 l 0,14 l 21,0 l 0,-14 z l 10.5,6 l 10.5,-6' } }; this.getRawPath = function getRawPath(pathId) { return this.pathMap[pathId].d; }; /** * Scales the path to the given height and width. * <h1>Use case</h1> * <p>Use case is to scale the content of elements (event, gateways) based * on the element bounding box's size. * </p> * <h1>Why not transform</h1> * <p>Scaling a path with transform() will also scale the stroke and IE does not support * the option 'non-scaling-stroke' to prevent this. * Also there are use cases where only some parts of a path should be * scaled.</p> * * @param {string} pathId The ID of the path. * @param {Object} param <p> * Example param object scales the path to 60% size of the container (data.width, data.height). * <pre> * { * xScaleFactor: 0.6, * yScaleFactor:0.6, * containerWidth: data.width, * containerHeight: data.height, * position: { * mx: 0.46, * my: 0.2, * } * } * </pre> * <ul> * <li>targetpathwidth = xScaleFactor * containerWidth</li> * <li>targetpathheight = yScaleFactor * containerHeight</li> * <li>Position is used to set the starting coordinate of the path. M is computed: * <ul> * <li>position.x * containerWidth</li> * <li>position.y * containerHeight</li> * </ul> * Center of the container <pre> position: { * mx: 0.5, * my: 0.5, * }</pre> * Upper left corner of the container * <pre> position: { * mx: 0.0, * my: 0.0, * }</pre> * </li> * </ul> * </p> * */ this.getScaledPath = function getScaledPath(pathId, param) { var rawPath = this.pathMap[pathId]; // positioning // compute the start point of the path var mx, my; if (param.abspos) { mx = param.abspos.x; my = param.abspos.y; } else { mx = param.containerWidth * param.position.mx; my = param.containerHeight * param.position.my; } var coordinates = {}; // map for the scaled coordinates if (param.position) { // path var heightRatio = param.containerHeight / rawPath.height * param.yScaleFactor; var widthRatio = param.containerWidth / rawPath.width * param.xScaleFactor; // Apply height ratio for (var heightIndex = 0; heightIndex < rawPath.heightElements.length; heightIndex++) { coordinates['y' + heightIndex] = rawPath.heightElements[heightIndex] * heightRatio; } // Apply width ratio for (var widthIndex = 0; widthIndex < rawPath.widthElements.length; widthIndex++) { coordinates['x' + widthIndex] = rawPath.widthElements[widthIndex] * widthRatio; } } // Apply value to raw path var path = format(rawPath.d, { mx: mx, my: my, e: coordinates }); return path; }; } // helpers ////////////////////// // copied from https://github.com/adobe-webplatform/Snap.svg/blob/master/src/svg.js var tokenRegex = /\{([^}]+)\}/g, objNotationRegex = /(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g; // matches .xxxxx or ["xxxxx"] to run over object properties function replacer(all, key, obj) { var res = obj; key.replace(objNotationRegex, function (all, name, quote, quotedName, isFunc) { name = name || quotedName; if (res) { if (name in res) { res = res[name]; } typeof res == 'function' && isFunc && (res = res()); } }); res = (res == null || res == obj ? all : res) + ''; return res; } function format(str, obj) { return String(str).replace(tokenRegex, function (all, key) { return replacer(all, key, obj); }); } },{}],22:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TextRenderer; var _minDash = require("min-dash"); var _Text = _interopRequireDefault(require("diagram-js/lib/util/Text")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DEFAULT_FONT_SIZE = 12; var LINE_HEIGHT_RATIO = 1.2; var MIN_TEXT_ANNOTATION_HEIGHT = 30; function TextRenderer(config) { var defaultStyle = (0, _minDash.assign)({ fontFamily: 'Arial, sans-serif', fontSize: DEFAULT_FONT_SIZE, fontWeight: 'normal', lineHeight: LINE_HEIGHT_RATIO }, config && config.defaultStyle || {}); var fontSize = parseInt(defaultStyle.fontSize, 10) - 1; var externalStyle = (0, _minDash.assign)({}, defaultStyle, { fontSize: fontSize }, config && config.externalStyle || {}); var textUtil = new _Text.default({ style: defaultStyle }); /** * Get the new bounds of an externally rendered, * layouted label. * * @param {Bounds} bounds * @param {string} text * * @return {Bounds} */ this.getExternalLabelBounds = function (bounds, text) { var layoutedDimensions = textUtil.getDimensions(text, { box: { width: 90, height: 30, x: bounds.width / 2 + bounds.x, y: bounds.height / 2 + bounds.y }, style: externalStyle }); // resize label shape to fit label text return { x: Math.round(bounds.x + bounds.width / 2 - layoutedDimensions.width / 2), y: Math.round(bounds.y), width: Math.ceil(layoutedDimensions.width), height: Math.ceil(layoutedDimensions.height) }; }; /** * Get the new bounds of text annotation. * * @param {Bounds} bounds * @param {string} text * * @return {Bounds} */ this.getTextAnnotationBounds = function (bounds, text) { var layoutedDimensions = textUtil.getDimensions(text, { box: bounds, style: defaultStyle, align: 'left-top', padding: 5 }); return { x: bounds.x, y: bounds.y, width: bounds.width, height: Math.max(MIN_TEXT_ANNOTATION_HEIGHT, Math.round(layoutedDimensions.height)) }; }; /** * Create a layouted text element. * * @param {string} text * @param {Object} [options] * * @return {SVGElement} rendered text */ this.createText = function (text, options) { return textUtil.createText(text, options || {}); }; /** * Get default text style. */ this.getDefaultStyle = function () { return defaultStyle; }; /** * Get the external text style. */ this.getExternalStyle = function () { return externalStyle; }; } TextRenderer.$inject = ['config.textRenderer']; },{"diagram-js/lib/util/Text":329,"min-dash":555}],23:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnRenderer = _interopRequireDefault(require("./BpmnRenderer")); var _TextRenderer = _interopRequireDefault(require("./TextRenderer")); var _PathMap = _interopRequireDefault(require("./PathMap")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['bpmnRenderer'], bpmnRenderer: ['type', _BpmnRenderer.default], textRenderer: ['type', _TextRenderer.default], pathMap: ['type', _PathMap.default] }; exports.default = _default; },{"./BpmnRenderer":20,"./PathMap":21,"./TextRenderer":22}],24:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoPlace; var _BpmnAutoPlaceUtil = require("./BpmnAutoPlaceUtil"); /** * BPMN auto-place behavior. * * @param {EventBus} eventBus */ function AutoPlace(eventBus) { eventBus.on('autoPlace', function (context) { var shape = context.shape, source = context.source; return (0, _BpmnAutoPlaceUtil.getNewShapePosition)(source, shape); }); } AutoPlace.$inject = ['eventBus']; },{"./BpmnAutoPlaceUtil":25}],25:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNewShapePosition = getNewShapePosition; exports.getFlowNodePosition = getFlowNodePosition; exports.getTextAnnotationPosition = getTextAnnotationPosition; exports.getDataElementPosition = getDataElementPosition; var _ModelUtil = require("../../util/ModelUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _AutoPlaceUtil = require("diagram-js/lib/features/auto-place/AutoPlaceUtil"); /** * Find the new position for the target element to * connect to source. * * @param {djs.model.Shape} source * @param {djs.model.Shape} element * * @return {Point} */ function getNewShapePosition(source, element) { if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { return getTextAnnotationPosition(source, element); } if ((0, _ModelingUtil.isAny)(element, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) { return getDataElementPosition(source, element); } if ((0, _ModelUtil.is)(element, 'bpmn:FlowNode')) { return getFlowNodePosition(source, element); } } /** * Always try to place element right of source; * compute actual distance from previous nodes in flow. */ function getFlowNodePosition(source, element) { var sourceTrbl = (0, _LayoutUtil.asTRBL)(source); var sourceMid = (0, _LayoutUtil.getMid)(source); var horizontalDistance = (0, _AutoPlaceUtil.getConnectedDistance)(source, { filter: function (connection) { return (0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow'); } }); var margin = 30, minDistance = 80, orientation = 'left'; if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) { orientation = (0, _LayoutUtil.getOrientation)(source, source.host, -25); if (orientation.indexOf('top') !== -1) { margin *= -1; } } var position = { x: sourceTrbl.right + horizontalDistance + element.width / 2, y: sourceMid.y + getVerticalDistance(orientation, minDistance) }; var nextPositionDirection = { y: { margin: margin, minDistance: minDistance } }; return (0, _AutoPlaceUtil.findFreePosition)(source, element, position, (0, _AutoPlaceUtil.generateGetNextPosition)(nextPositionDirection)); } function getVerticalDistance(orientation, minDistance) { if (orientation.indexOf('top') != -1) { return -1 * minDistance; } else if (orientation.indexOf('bottom') != -1) { return minDistance; } else { return 0; } } /** * Always try to place text annotations top right of source. */ function getTextAnnotationPosition(source, element) { var sourceTrbl = (0, _LayoutUtil.asTRBL)(source); var position = { x: sourceTrbl.right + element.width / 2, y: sourceTrbl.top - 50 - element.height / 2 }; var nextPositionDirection = { y: { margin: -30, minDistance: 20 } }; return (0, _AutoPlaceUtil.findFreePosition)(source, element, position, (0, _AutoPlaceUtil.generateGetNextPosition)(nextPositionDirection)); } /** * Always put element bottom right of source. */ function getDataElementPosition(source, element) { var sourceTrbl = (0, _LayoutUtil.asTRBL)(source); var position = { x: sourceTrbl.right - 10 + element.width / 2, y: sourceTrbl.bottom + 40 + element.width / 2 }; var nextPositionDirection = { x: { margin: 30, minDistance: 30 } }; return (0, _AutoPlaceUtil.findFreePosition)(source, element, position, (0, _AutoPlaceUtil.generateGetNextPosition)(nextPositionDirection)); } },{"../../util/ModelUtil":141,"../modeling/util/ModelingUtil":112,"diagram-js/lib/features/auto-place/AutoPlaceUtil":164,"diagram-js/lib/layout/LayoutUtil":300}],26:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _autoPlace = _interopRequireDefault(require("diagram-js/lib/features/auto-place")); var _BpmnAutoPlace = _interopRequireDefault(require("./BpmnAutoPlace")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_autoPlace.default], __init__: ['bpmnAutoPlace'], bpmnAutoPlace: ['type', _BpmnAutoPlace.default] }; exports.default = _default; },{"./BpmnAutoPlace":24,"diagram-js/lib/features/auto-place":165}],27:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnAutoResize; var _AutoResize = _interopRequireDefault(require("diagram-js/lib/features/auto-resize/AutoResize")); var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Sub class of the AutoResize module which implements a BPMN * specific resize function. */ function BpmnAutoResize(injector) { injector.invoke(_AutoResize.default, this); } BpmnAutoResize.$inject = ['injector']; (0, _inherits.default)(BpmnAutoResize, _AutoResize.default); /** * Resize shapes and lanes. * * @param {djs.model.Shape} target * @param {Bounds} newBounds * @param {Object} hints */ BpmnAutoResize.prototype.resize = function (target, newBounds, hints) { if ((0, _ModelUtil.is)(target, 'bpmn:Participant')) { this._modeling.resizeLane(target, newBounds, null, hints); } else { this._modeling.resizeShape(target, newBounds, null, hints); } }; },{"../../util/ModelUtil":141,"diagram-js/lib/features/auto-resize/AutoResize":166,"inherits":347}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnAutoResizeProvider; var _ModelUtil = require("../../util/ModelUtil"); var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _AutoResizeProvider = _interopRequireDefault(require("diagram-js/lib/features/auto-resize/AutoResizeProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * This module is a provider for automatically resizing parent BPMN elements */ function BpmnAutoResizeProvider(eventBus, modeling) { _AutoResizeProvider.default.call(this, eventBus); this._modeling = modeling; } (0, _inherits.default)(BpmnAutoResizeProvider, _AutoResizeProvider.default); BpmnAutoResizeProvider.$inject = ['eventBus', 'modeling']; /** * Check if the given target can be expanded * * @param {djs.model.Shape} target * * @return {boolean} */ BpmnAutoResizeProvider.prototype.canResize = function (elements, target) { if (!(0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _ModelUtil.is)(target, 'bpmn:Lane') && !(0, _ModelUtil.is)(target, 'bpmn:SubProcess')) { return false; } var canResize = true; (0, _minDash.forEach)(elements, function (element) { if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || element.labelTarget) { canResize = false; return; } }); return canResize; }; },{"../../util/ModelUtil":141,"diagram-js/lib/features/auto-resize/AutoResizeProvider":167,"inherits":347,"min-dash":555}],29:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnAutoResize = _interopRequireDefault(require("./BpmnAutoResize")); var _BpmnAutoResizeProvider = _interopRequireDefault(require("./BpmnAutoResizeProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['bpmnAutoResize', 'bpmnAutoResizeProvider'], bpmnAutoResize: ['type', _BpmnAutoResize.default], bpmnAutoResizeProvider: ['type', _BpmnAutoResizeProvider.default] }; exports.default = _default; },{"./BpmnAutoResize":27,"./BpmnAutoResizeProvider":28}],30:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ContextPadProvider; var _minDash = require("min-dash"); var _ModelUtil = require("../../util/ModelUtil"); var _DiUtil = require("../../util/DiUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _LaneUtil = require("../modeling/util/LaneUtil"); var _Mouse = require("diagram-js/lib/util/Mouse"); /** * A provider for BPMN 2.0 elements context pad */ function ContextPadProvider(config, injector, eventBus, contextPad, modeling, elementFactory, connect, create, popupMenu, canvas, rules, translate) { config = config || {}; contextPad.registerProvider(this); this._contextPad = contextPad; this._modeling = modeling; this._elementFactory = elementFactory; this._connect = connect; this._create = create; this._popupMenu = popupMenu; this._canvas = canvas; this._rules = rules; this._translate = translate; if (config.autoPlace !== false) { this._autoPlace = injector.get('autoPlace', false); } eventBus.on('create.end', 250, function (event) { var context = event.context, shape = context.shape; if (!(0, _Mouse.hasPrimaryModifier)(event) || !contextPad.isOpen(shape)) { return; } var entries = contextPad.getEntries(shape); if (entries.replace) { entries.replace.action.click(event, shape); } }); } ContextPadProvider.$inject = ['config.contextPad', 'injector', 'eventBus', 'contextPad', 'modeling', 'elementFactory', 'connect', 'create', 'popupMenu', 'canvas', 'rules', 'translate']; ContextPadProvider.prototype.getContextPadEntries = function (element) { var contextPad = this._contextPad, modeling = this._modeling, elementFactory = this._elementFactory, connect = this._connect, create = this._create, popupMenu = this._popupMenu, canvas = this._canvas, rules = this._rules, autoPlace = this._autoPlace, translate = this._translate; var actions = {}; if (element.type === 'label') { return actions; } var businessObject = element.businessObject; function startConnect(event, element) { connect.start(event, element); } function removeElement(e) { modeling.removeElements([element]); } function getReplaceMenuPosition(element) { var Y_OFFSET = 5; var diagramContainer = canvas.getContainer(), pad = contextPad.getPad(element).html; var diagramRect = diagramContainer.getBoundingClientRect(), padRect = pad.getBoundingClientRect(); var top = padRect.top - diagramRect.top; var left = padRect.left - diagramRect.left; var pos = { x: left, y: top + padRect.height + Y_OFFSET }; return pos; } /** * Create an append action * * @param {string} type * @param {string} className * @param {string} [title] * @param {Object} [options] * * @return {Object} descriptor */ function appendAction(type, className, title, options) { if (typeof title !== 'string') { options = title; title = translate('Append {type}', { type: type.replace(/^bpmn:/, '') }); } function appendStart(event, element) { var shape = elementFactory.createShape((0, _minDash.assign)({ type: type }, options)); create.start(event, shape, { source: element }); } var append = autoPlace ? function (event, element) { var shape = elementFactory.createShape((0, _minDash.assign)({ type: type }, options)); autoPlace.append(element, shape); } : appendStart; return { group: 'model', className: className, title: title, action: { dragstart: appendStart, click: append } }; } function splitLaneHandler(count) { return function (event, element) { // actual split modeling.splitLane(element, count); // refresh context pad after split to // get rid of split icons contextPad.open(element, true); }; } if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:Lane', 'bpmn:Participant']) && (0, _DiUtil.isExpanded)(businessObject)) { var childLanes = (0, _LaneUtil.getChildLanes)(element); (0, _minDash.assign)(actions, { 'lane-insert-above': { group: 'lane-insert-above', className: 'bpmn-icon-lane-insert-above', title: translate('Add Lane above'), action: { click: function (event, element) { modeling.addLane(element, 'top'); } } } }); if (childLanes.length < 2) { if (element.height >= 120) { (0, _minDash.assign)(actions, { 'lane-divide-two': { group: 'lane-divide', className: 'bpmn-icon-lane-divide-two', title: translate('Divide into two Lanes'), action: { click: splitLaneHandler(2) } } }); } if (element.height >= 180) { (0, _minDash.assign)(actions, { 'lane-divide-three': { group: 'lane-divide', className: 'bpmn-icon-lane-divide-three', title: translate('Divide into three Lanes'), action: { click: splitLaneHandler(3) } } }); } } (0, _minDash.assign)(actions, { 'lane-insert-below': { group: 'lane-insert-below', className: 'bpmn-icon-lane-insert-below', title: translate('Add Lane below'), action: { click: function (event, element) { modeling.addLane(element, 'bottom'); } } } }); } if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowNode')) { if ((0, _ModelUtil.is)(businessObject, 'bpmn:EventBasedGateway')) { (0, _minDash.assign)(actions, { 'append.receive-task': appendAction('bpmn:ReceiveTask', 'bpmn-icon-receive-task', translate('Append ReceiveTask')), 'append.message-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-message', translate('Append MessageIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:MessageEventDefinition' }), 'append.timer-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-timer', translate('Append TimerIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:TimerEventDefinition' }), 'append.condition-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-condition', translate('Append ConditionIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:ConditionalEventDefinition' }), 'append.signal-intermediate-event': appendAction('bpmn:IntermediateCatchEvent', 'bpmn-icon-intermediate-event-catch-signal', translate('Append SignalIntermediateCatchEvent'), { eventDefinitionType: 'bpmn:SignalEventDefinition' }) }); } else if (isEventType(businessObject, 'bpmn:BoundaryEvent', 'bpmn:CompensateEventDefinition')) { (0, _minDash.assign)(actions, { 'append.compensation-activity': appendAction('bpmn:Task', 'bpmn-icon-task', translate('Append compensation activity'), { isForCompensation: true }) }); } else if (!(0, _ModelUtil.is)(businessObject, 'bpmn:EndEvent') && !businessObject.isForCompensation && !isEventType(businessObject, 'bpmn:IntermediateThrowEvent', 'bpmn:LinkEventDefinition') && !(0, _DiUtil.isEventSubProcess)(businessObject)) { (0, _minDash.assign)(actions, { 'append.end-event': appendAction('bpmn:EndEvent', 'bpmn-icon-end-event-none', translate('Append EndEvent')), 'append.gateway': appendAction('bpmn:ExclusiveGateway', 'bpmn-icon-gateway-none', translate('Append Gateway')), 'append.append-task': appendAction('bpmn:Task', 'bpmn-icon-task', translate('Append Task')), 'append.intermediate-event': appendAction('bpmn:IntermediateThrowEvent', 'bpmn-icon-intermediate-event-none', translate('Append Intermediate/Boundary Event')) }); } } if (!popupMenu.isEmpty(element, 'bpmn-replace')) { // Replace menu entry (0, _minDash.assign)(actions, { 'replace': { group: 'edit', className: 'bpmn-icon-screw-wrench', title: translate('Change type'), action: { click: function (event, element) { var position = (0, _minDash.assign)(getReplaceMenuPosition(element), { cursor: { x: event.x, y: event.y } }); popupMenu.open(element, 'bpmn-replace', position); } } } }); } if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:FlowNode', 'bpmn:InteractionNode', 'bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) { (0, _minDash.assign)(actions, { 'append.text-annotation': appendAction('bpmn:TextAnnotation', 'bpmn-icon-text-annotation'), 'connect': { group: 'connect', className: 'bpmn-icon-connection-multi', title: translate('Connect using ' + (businessObject.isForCompensation ? '' : 'Sequence/MessageFlow or ') + 'Association'), action: { click: startConnect, dragstart: startConnect } } }); } if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference'])) { (0, _minDash.assign)(actions, { 'connect': { group: 'connect', className: 'bpmn-icon-connection-multi', title: translate('Connect using DataInputAssociation'), action: { click: startConnect, dragstart: startConnect } } }); } if ((0, _ModelUtil.is)(businessObject, 'bpmn:Group')) { (0, _minDash.assign)(actions, { 'append.text-annotation': appendAction('bpmn:TextAnnotation', 'bpmn-icon-text-annotation') }); } // delete element entry, only show if allowed by rules var deleteAllowed = rules.allowed('elements.delete', { elements: [element] }); if ((0, _minDash.isArray)(deleteAllowed)) { // was the element returned as a deletion candidate? deleteAllowed = deleteAllowed[0] === element; } if (deleteAllowed) { (0, _minDash.assign)(actions, { 'delete': { group: 'edit', className: 'bpmn-icon-trash', title: translate('Remove'), action: { click: removeElement } } }); } return actions; }; // helpers ///////// function isEventType(eventBo, type, definition) { var isType = eventBo.$instanceOf(type); var isDefinition = false; var definitions = eventBo.eventDefinitions || []; (0, _minDash.forEach)(definitions, function (def) { if (def.$type === definition) { isDefinition = true; } }); return isType && isDefinition; } },{"../../util/DiUtil":139,"../../util/ModelUtil":141,"../modeling/util/LaneUtil":111,"../modeling/util/ModelingUtil":112,"diagram-js/lib/util/Mouse":323,"min-dash":555}],31:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _diagramJsDirectEditing = _interopRequireDefault(require("diagram-js-direct-editing")); var _contextPad = _interopRequireDefault(require("diagram-js/lib/features/context-pad")); var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection")); var _connect = _interopRequireDefault(require("diagram-js/lib/features/connect")); var _create = _interopRequireDefault(require("diagram-js/lib/features/create")); var _popupMenu = _interopRequireDefault(require("../popup-menu")); var _ContextPadProvider = _interopRequireDefault(require("./ContextPadProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_diagramJsDirectEditing.default, _contextPad.default, _selection.default, _connect.default, _create.default, _popupMenu.default], __init__: ['contextPadProvider'], contextPadProvider: ['type', _ContextPadProvider.default] }; exports.default = _default; },{"../popup-menu":118,"./ContextPadProvider":30,"diagram-js-direct-editing":332,"diagram-js/lib/features/connect":183,"diagram-js/lib/features/context-pad":187,"diagram-js/lib/features/create":192,"diagram-js/lib/features/selection":278}],32:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnCopyPaste; var _ModelUtil = require("../../util/ModelUtil"); var _minDash = require("min-dash"); function copyProperties(source, target, properties) { if (!(0, _minDash.isArray)(properties)) { properties = [properties]; } (0, _minDash.forEach)(properties, function (property) { if (!(0, _minDash.isUndefined)(source[property])) { target[property] = source[property]; } }); } function removeProperties(element, properties) { if (!(0, _minDash.isArray)(properties)) { properties = [properties]; } (0, _minDash.forEach)(properties, function (property) { if (element[property]) { delete element[property]; } }); } var LOW_PRIORITY = 750; function BpmnCopyPaste(bpmnFactory, eventBus, moddleCopy) { eventBus.on('copyPaste.copyElement', LOW_PRIORITY, function (context) { var descriptor = context.descriptor, element = context.element; var businessObject = descriptor.oldBusinessObject = (0, _ModelUtil.getBusinessObject)(element); descriptor.type = element.type; copyProperties(businessObject, descriptor, 'name'); descriptor.di = {}; // fill and stroke will be set to DI copyProperties(businessObject.di, descriptor.di, ['fill', 'stroke']); copyProperties(businessObject.di, descriptor, 'isExpanded'); if (isLabel(descriptor)) { return descriptor; } // default sequence flow if (businessObject.default) { descriptor.default = businessObject.default.id; } }); eventBus.on('moddleCopy.canCopyProperty', function (context) { var parent = context.parent, property = context.property, propertyName = context.propertyName, bpmnProcess; if (propertyName === 'processRef' && (0, _ModelUtil.is)(parent, 'bpmn:Participant') && (0, _ModelUtil.is)(property, 'bpmn:Process')) { bpmnProcess = bpmnFactory.create('bpmn:Process'); // return copy of process return moddleCopy.copyElement(property, bpmnProcess); } }); var references; function resolveReferences(descriptor, cache) { var businessObject = (0, _ModelUtil.getBusinessObject)(descriptor); // default sequence flows if (descriptor.default) { // relationship cannot be resolved immediately references[descriptor.default] = { element: businessObject, property: 'default' }; } // boundary events if (descriptor.host) { // relationship can be resolved immediately (0, _ModelUtil.getBusinessObject)(descriptor).attachedToRef = (0, _ModelUtil.getBusinessObject)(cache[descriptor.host]); } references = (0, _minDash.omit)(references, (0, _minDash.reduce)(references, function (array, reference, key) { var element = reference.element, property = reference.property; if (key === descriptor.id) { element[property] = businessObject; array.push(descriptor.id); } return array; }, [])); } eventBus.on('copyPaste.pasteElements', function () { references = {}; }); eventBus.on('copyPaste.pasteElement', function (context) { var cache = context.cache, descriptor = context.descriptor, oldBusinessObject = descriptor.oldBusinessObject, newBusinessObject; // do NOT copy business object if external label if (isLabel(descriptor)) { descriptor.businessObject = (0, _ModelUtil.getBusinessObject)(cache[descriptor.labelTarget]); return; } newBusinessObject = bpmnFactory.create(oldBusinessObject.$type); descriptor.businessObject = moddleCopy.copyElement(oldBusinessObject, newBusinessObject); // resolve references e.g. default sequence flow resolveReferences(descriptor, cache); copyProperties(descriptor, newBusinessObject, ['isExpanded', 'name']); removeProperties(descriptor, 'oldBusinessObject'); }); } BpmnCopyPaste.$inject = ['bpmnFactory', 'eventBus', 'moddleCopy']; // helpers ////////// function isLabel(element) { return !!element.labelTarget; } },{"../../util/ModelUtil":141,"min-dash":555}],33:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ModdleCopy; exports.getPropertyNames = getPropertyNames; var _minDash = require("min-dash"); var DISALLOWED_PROPERTIES = ['artifacts', 'dataInputAssociations', 'dataOutputAssociations', 'default', 'flowElements', 'lanes', 'incoming', 'outgoing']; /** * @typedef {Function} <moddleCopy.canCopyProperties> listener * * @param {Object} context * @param {Array<string>} context.propertyNames * @param {ModdleElement} context.sourceElement * @param {ModdleElement} context.targetElement * * @returns {Array<string>|boolean} - Return properties to be copied or false to disallow * copying. */ /** * @typedef {Function} <moddleCopy.canCopyProperty> listener * * @param {Object} context * @param {ModdleElement} context.parent * @param {*} context.property * @param {string} context.propertyName * * @returns {*|boolean} - Return copied property or false to disallow * copying. */ /** * @typedef {Function} <moddleCopy.canSetCopiedProperty> listener * * @param {Object} context * @param {ModdleElement} context.parent * @param {*} context.property * @param {string} context.propertyName * * @returns {boolean} - Return false to disallow * setting copied property. */ /** * Utility for copying model properties from source element to target element. * * @param {EventBus} eventBus * @param {BpmnFactory} bpmnFactory * @param {BpmnModdle} moddle */ function ModdleCopy(eventBus, bpmnFactory, moddle) { this._bpmnFactory = bpmnFactory; this._eventBus = eventBus; this._moddle = moddle; // copy extension elements last eventBus.on('moddleCopy.canCopyProperties', function (context) { var propertyNames = context.propertyNames; if (!propertyNames || !propertyNames.length) { return; } return (0, _minDash.sortBy)(propertyNames, function (propertyName) { return propertyName === 'extensionElements'; }); }); // default check whether property can be copied eventBus.on('moddleCopy.canCopyProperty', function (context) { var parent = context.parent, parentDescriptor = (0, _minDash.isObject)(parent) && parent.$descriptor, propertyName = context.propertyName; if (propertyName && DISALLOWED_PROPERTIES.indexOf(propertyName) !== -1) { // disallow copying property return false; } if (propertyName && parentDescriptor && !(0, _minDash.find)(parentDescriptor.properties, (0, _minDash.matchPattern)({ name: propertyName }))) { // disallow copying property return false; } }); // do NOT allow to copy empty extension elements eventBus.on('moddleCopy.canSetCopiedProperty', function (context) { var property = context.property; if (is(property, 'bpmn:ExtensionElements') && (!property.values || !property.values.length)) { // disallow setting copied property return false; } }); } ModdleCopy.$inject = ['eventBus', 'bpmnFactory', 'moddle']; /** * Copy model properties of source element to target element. * * @param {ModdleElement} sourceElement * @param {ModdleElement} targetElement * @param {Array<string>} [propertyNames] * * @param {ModdleElement} */ ModdleCopy.prototype.copyElement = function (sourceElement, targetElement, propertyNames) { var self = this; if (propertyNames && !(0, _minDash.isArray)(propertyNames)) { propertyNames = [propertyNames]; } propertyNames = propertyNames || getPropertyNames(sourceElement.$descriptor); var canCopyProperties = this._eventBus.fire('moddleCopy.canCopyProperties', { propertyNames: propertyNames, sourceElement: sourceElement, targetElement: targetElement }); if (canCopyProperties === false) { return targetElement; } if ((0, _minDash.isArray)(canCopyProperties)) { propertyNames = canCopyProperties; } // copy properties (0, _minDash.forEach)(propertyNames, function (propertyName) { var sourceProperty; if ((0, _minDash.has)(sourceElement, propertyName)) { sourceProperty = sourceElement.get(propertyName); } var copiedProperty = self.copyProperty(sourceProperty, targetElement, propertyName); var canSetProperty = self._eventBus.fire('moddleCopy.canSetCopiedProperty', { parent: targetElement, property: copiedProperty, propertyName: propertyName }); if (canSetProperty === false) { return; } if ((0, _minDash.isDefined)(copiedProperty)) { targetElement.set(propertyName, copiedProperty); } }); return targetElement; }; /** * Copy model property. * * @param {*} property * @param {ModdleElement} parent * @param {string} propertyName * * @returns {*} */ ModdleCopy.prototype.copyProperty = function (property, parent, propertyName) { var self = this; // allow others to copy property var copiedProperty = this._eventBus.fire('moddleCopy.canCopyProperty', { parent: parent, property: property, propertyName: propertyName }); // return if copying is NOT allowed if (copiedProperty === false) { return; } if (copiedProperty) { if ((0, _minDash.isObject)(copiedProperty) && copiedProperty.$type && !copiedProperty.$parent) { copiedProperty.$parent = parent; } return copiedProperty; } var propertyDescriptor = this._moddle.getPropertyDescriptor(parent, propertyName); // do NOT copy Ids and references if (propertyDescriptor.isId || propertyDescriptor.isReference) { return; } // copy arrays if ((0, _minDash.isArray)(property)) { return (0, _minDash.reduce)(property, function (childProperties, childProperty) { // recursion copiedProperty = self.copyProperty(childProperty, parent, propertyName); // copying might NOT be allowed if (copiedProperty) { copiedProperty.$parent = parent; return childProperties.concat(copiedProperty); } return childProperties; }, []); } // copy model elements if ((0, _minDash.isObject)(property) && property.$type) { if (this._moddle.getElementDescriptor(property).isGeneric) { return; } copiedProperty = self._bpmnFactory.create(property.$type); copiedProperty.$parent = parent; // recursion copiedProperty = self.copyElement(property, copiedProperty); return copiedProperty; } // copy primitive properties return property; }; // helpers ////////// function getPropertyNames(descriptor, keepDefaultProperties) { return (0, _minDash.reduce)(descriptor.properties, function (properties, property) { if (keepDefaultProperties && property.default) { return properties; } return properties.concat(property.name); }, []); } function is(element, type) { return element && typeof element.$instanceOf === 'function' && element.$instanceOf(type); } },{"min-dash":555}],34:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _copyPaste = _interopRequireDefault(require("diagram-js/lib/features/copy-paste")); var _BpmnCopyPaste = _interopRequireDefault(require("./BpmnCopyPaste")); var _ModdleCopy = _interopRequireDefault(require("./ModdleCopy")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_copyPaste.default], __init__: ['bpmnCopyPaste', 'moddleCopy'], bpmnCopyPaste: ['type', _BpmnCopyPaste.default], moddleCopy: ['type', _ModdleCopy.default] }; exports.default = _default; },{"./BpmnCopyPaste":32,"./ModdleCopy":33,"diagram-js/lib/features/copy-paste":189}],35:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnDiOrdering; var _BpmnRenderUtil = require("../../draw/BpmnRenderUtil"); var _ModelUtil = require("../../util/ModelUtil"); var _minDash = require("min-dash"); var _Elements = require("diagram-js/lib/util/Elements"); var HIGH_PRIORITY = 2000; function BpmnDiOrdering(eventBus, canvas) { eventBus.on('saveXML.start', HIGH_PRIORITY, orderDi); function orderDi() { var root = canvas.getRootElement(), rootDi = (0, _ModelUtil.getBusinessObject)(root).di, elements, diElements; elements = (0, _Elements.selfAndAllChildren)([root], false); // only bpmndi:Shape and bpmndi:Edge can be direct children of bpmndi:Plane elements = (0, _minDash.filter)(elements, function (element) { return element !== root && !element.labelTarget; }); diElements = (0, _minDash.map)(elements, _BpmnRenderUtil.getDi); rootDi.set('planeElement', diElements); } } BpmnDiOrdering.$inject = ['eventBus', 'canvas']; },{"../../draw/BpmnRenderUtil":19,"../../util/ModelUtil":141,"diagram-js/lib/util/Elements":315,"min-dash":555}],36:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnDiOrdering = _interopRequireDefault(require("../di-ordering/BpmnDiOrdering")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['bpmnDiOrdering'], bpmnDiOrdering: ['type', _BpmnDiOrdering.default] }; exports.default = _default; },{"../di-ordering/BpmnDiOrdering":35}],37:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnDistributeElements; var _minDash = require("min-dash"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); /** * Registers element exclude filters for elements that * currently do not support distribution. */ function BpmnDistributeElements(distributeElements) { distributeElements.registerFilter(function (elements) { return (0, _minDash.filter)(elements, function (element) { var cannotDistribute = (0, _ModelingUtil.isAny)(element, ['bpmn:Association', 'bpmn:BoundaryEvent', 'bpmn:DataInputAssociation', 'bpmn:DataOutputAssociation', 'bpmn:Lane', 'bpmn:MessageFlow', 'bpmn:Participant', 'bpmn:SequenceFlow', 'bpmn:TextAnnotation']); return !(element.labelTarget || cannotDistribute); }); }); } BpmnDistributeElements.$inject = ['distributeElements']; },{"../modeling/util/ModelingUtil":112,"min-dash":555}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _distributeElements = _interopRequireDefault(require("diagram-js/lib/features/distribute-elements")); var _BpmnDistributeElements = _interopRequireDefault(require("./BpmnDistributeElements")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_distributeElements.default], __init__: ['bpmnDistributeElements'], bpmnDistributeElements: ['type', _BpmnDistributeElements.default] }; exports.default = _default; },{"./BpmnDistributeElements":37,"diagram-js/lib/features/distribute-elements":194}],39:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnEditorActions; var _inherits = _interopRequireDefault(require("inherits")); var _EditorActions = _interopRequireDefault(require("diagram-js/lib/features/editor-actions/EditorActions")); var _minDash = require("min-dash"); var _ModelUtil = require("../../util/ModelUtil"); var _Elements = require("diagram-js/lib/util/Elements"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Registers and executes BPMN specific editor actions. * * @param {Injector} injector */ function BpmnEditorActions(injector) { injector.invoke(_EditorActions.default, this); } (0, _inherits.default)(BpmnEditorActions, _EditorActions.default); BpmnEditorActions.$inject = ['injector']; /** * Register default actions. * * @param {Injector} injector */ BpmnEditorActions.prototype._registerDefaultActions = function (injector) { // (0) invoke super method _EditorActions.default.prototype._registerDefaultActions.call(this, injector); // (1) retrieve optional components to integrate with var canvas = injector.get('canvas', false); var elementRegistry = injector.get('elementRegistry', false); var selection = injector.get('selection', false); var spaceTool = injector.get('spaceTool', false); var lassoTool = injector.get('lassoTool', false); var handTool = injector.get('handTool', false); var globalConnect = injector.get('globalConnect', false); var distributeElements = injector.get('distributeElements', false); var alignElements = injector.get('alignElements', false); var directEditing = injector.get('directEditing', false); var searchPad = injector.get('searchPad', false); var modeling = injector.get('modeling', false); // (2) check components and register actions if (canvas && elementRegistry && selection) { this._registerAction('selectElements', function () { // select all elements except for the invisible // root element var rootElement = canvas.getRootElement(); var elements = elementRegistry.filter(function (element) { return element !== rootElement; }); selection.select(elements); return elements; }); } if (spaceTool) { this._registerAction('spaceTool', function () { spaceTool.toggle(); }); } if (lassoTool) { this._registerAction('lassoTool', function () { lassoTool.toggle(); }); } if (handTool) { this._registerAction('handTool', function () { handTool.toggle(); }); } if (globalConnect) { this._registerAction('globalConnectTool', function () { globalConnect.toggle(); }); } if (selection && distributeElements) { this._registerAction('distributeElements', function (opts) { var currentSelection = selection.get(), type = opts.type; if (currentSelection.length) { distributeElements.trigger(currentSelection, type); } }); } if (selection && alignElements) { this._registerAction('alignElements', function (opts) { var currentSelection = selection.get(), aligneableElements = [], type = opts.type; if (currentSelection.length) { aligneableElements = (0, _minDash.filter)(currentSelection, function (element) { return !(0, _ModelUtil.is)(element, 'bpmn:Lane'); }); alignElements.trigger(aligneableElements, type); } }); } if (selection && modeling) { this._registerAction('setColor', function (opts) { var currentSelection = selection.get(); if (currentSelection.length) { modeling.setColor(currentSelection, opts); } }); } if (selection && directEditing) { this._registerAction('directEditing', function () { var currentSelection = selection.get(); if (currentSelection.length) { directEditing.activate(currentSelection[0]); } }); } if (searchPad) { this._registerAction('find', function () { searchPad.toggle(); }); } if (canvas && modeling) { this._registerAction('moveToOrigin', function () { var rootElement = canvas.getRootElement(), boundingBox, elements; if ((0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) { elements = elementRegistry.filter(function (element) { return (0, _ModelUtil.is)(element.parent, 'bpmn:Collaboration'); }); } else { elements = elementRegistry.filter(function (element) { return element !== rootElement && !(0, _ModelUtil.is)(element.parent, 'bpmn:SubProcess'); }); } boundingBox = (0, _Elements.getBBox)(elements); modeling.moveElements(elements, { x: -boundingBox.x, y: -boundingBox.y }, rootElement); }); } }; },{"../../util/ModelUtil":141,"diagram-js/lib/features/editor-actions/EditorActions":198,"diagram-js/lib/util/Elements":315,"inherits":347,"min-dash":555}],40:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _editorActions = _interopRequireDefault(require("diagram-js/lib/features/editor-actions")); var _BpmnEditorActions = _interopRequireDefault(require("./BpmnEditorActions")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_editorActions.default], editorActions: ['type', _BpmnEditorActions.default] }; exports.default = _default; },{"./BpmnEditorActions":39,"diagram-js/lib/features/editor-actions":199}],41:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnGridSnapping; var _ModelingUtil = require("../modeling/util/ModelingUtil"); function BpmnGridSnapping(eventBus) { eventBus.on(['create.init', 'shape.move.init'], function (event) { var context = event.context, shape = event.shape; if ((0, _ModelingUtil.isAny)(shape, ['bpmn:Participant', 'bpmn:SubProcess', 'bpmn:TextAnnotation'])) { if (!context.gridSnappingContext) { context.gridSnappingContext = {}; } context.gridSnappingContext.snapLocation = 'top-left'; } }); } BpmnGridSnapping.$inject = ['eventBus']; },{"../modeling/util/ModelingUtil":112}],42:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoPlaceBehavior; var _BpmnAutoPlaceUtil = require("../../auto-place/BpmnAutoPlaceUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _ModelUtil = require("../../../util/ModelUtil"); var HIGH_PRIORITY = 2000; function AutoPlaceBehavior(eventBus, gridSnapping) { eventBus.on('autoPlace', HIGH_PRIORITY, function (context) { var source = context.source, sourceMid = (0, _LayoutUtil.getMid)(source), shape = context.shape; var position = (0, _BpmnAutoPlaceUtil.getNewShapePosition)(source, shape); ['x', 'y'].forEach(function (axis) { var options = {}; // do not snap if x/y equal if (position[axis] === sourceMid[axis]) { return; } if (position[axis] > sourceMid[axis]) { options.min = position[axis]; } else { options.max = position[axis]; } if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) { if (isHorizontal(axis)) { options.offset = -shape.width / 2; } else { options.offset = -shape.height / 2; } } position[axis] = gridSnapping.snapValue(position[axis], options); }); // must be returned to be considered by auto place return position; }); } AutoPlaceBehavior.$inject = ['eventBus', 'gridSnapping']; // helpers ////////// function isHorizontal(axis) { return axis === 'x'; } },{"../../../util/ModelUtil":141,"../../auto-place/BpmnAutoPlaceUtil":25,"diagram-js/lib/layout/LayoutUtil":300}],43:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateParticipantBehavior; var _ModelUtil = require("../../../util/ModelUtil"); var HIGHER_PRIORITY = 1750; function CreateParticipantBehavior(canvas, eventBus, gridSnapping) { eventBus.on(['create.start', 'shape.move.start'], HIGHER_PRIORITY, function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(); if (!(0, _ModelUtil.is)(shape, 'bpmn:Participant') || !(0, _ModelUtil.is)(rootElement, 'bpmn:Process') || !rootElement.children.length) { return; } var createConstraints = context.createConstraints; if (!createConstraints) { return; } shape.width = gridSnapping.snapValue(shape.width, { min: shape.width }); shape.height = gridSnapping.snapValue(shape.height, { min: shape.height }); }); } CreateParticipantBehavior.$inject = ['canvas', 'eventBus', 'gridSnapping']; },{"../../../util/ModelUtil":141}],44:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LayoutConnectionBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _Geometry = require("diagram-js/lib/util/Geometry"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGH_PRIORITY = 3000; /** * Snaps connections with Manhattan layout. */ function LayoutConnectionBehavior(eventBus, gridSnapping, modeling) { _CommandInterceptor.default.call(this, eventBus); this._gridSnapping = gridSnapping; var self = this; this.postExecuted(['connection.create', 'connection.layout'], HIGH_PRIORITY, function (event) { var context = event.context, connection = context.connection, hints = context.hints || {}, waypoints = connection.waypoints; if (hints.connectionStart || hints.connectionEnd || hints.createElementsBehavior === false) { return; } if (!hasMiddleSegments(waypoints)) { return; } modeling.updateWaypoints(connection, self.snapMiddleSegments(waypoints)); }); } LayoutConnectionBehavior.$inject = ['eventBus', 'gridSnapping', 'modeling']; (0, _inherits.default)(LayoutConnectionBehavior, _CommandInterceptor.default); /** * Snap middle segments of a given connection. * * @param {Array<Point>} waypoints * * @returns {Array<Point>} */ LayoutConnectionBehavior.prototype.snapMiddleSegments = function (waypoints) { var gridSnapping = this._gridSnapping, snapped; waypoints = waypoints.slice(); for (var i = 1; i < waypoints.length - 2; i++) { snapped = snapSegment(gridSnapping, waypoints[i], waypoints[i + 1]); waypoints[i] = snapped[0]; waypoints[i + 1] = snapped[1]; } return waypoints; }; // helpers ////////// /** * Check whether a connection has a middle segments. * * @param {Array} waypoints * * @returns {boolean} */ function hasMiddleSegments(waypoints) { return waypoints.length > 3; } /** * Check whether an alignment is horizontal. * * @param {string} aligned * * @returns {boolean} */ function horizontallyAligned(aligned) { return aligned === 'h'; } /** * Check whether an alignment is vertical. * * @param {string} aligned * * @returns {boolean} */ function verticallyAligned(aligned) { return aligned === 'v'; } /** * Get middle segments from a given connection. * * @param {Array} waypoints * * @returns {Array} */ function snapSegment(gridSnapping, segmentStart, segmentEnd) { var aligned = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd); var snapped = {}; if (horizontallyAligned(aligned)) { // snap horizontally snapped.y = gridSnapping.snapValue(segmentStart.y); } if (verticallyAligned(aligned)) { // snap vertically snapped.x = gridSnapping.snapValue(segmentStart.x); } if ('x' in snapped || 'y' in snapped) { segmentStart = (0, _minDash.assign)({}, segmentStart, snapped); segmentEnd = (0, _minDash.assign)({}, segmentEnd, snapped); } return [segmentStart, segmentEnd]; } },{"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Geometry":318,"inherits":347,"min-dash":555}],45:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _AutoPlaceBehavior = _interopRequireDefault(require("./AutoPlaceBehavior")); var _CreateParticipantBehavior = _interopRequireDefault(require("./CreateParticipantBehavior")); var _LayoutConnectionBehavior = _interopRequireDefault(require("./LayoutConnectionBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['gridSnappingAutoPlaceBehavior', 'gridSnappingCreateParticipantBehavior', 'gridSnappingLayoutConnectionBehavior'], gridSnappingAutoPlaceBehavior: ['type', _AutoPlaceBehavior.default], gridSnappingCreateParticipantBehavior: ['type', _CreateParticipantBehavior.default], gridSnappingLayoutConnectionBehavior: ['type', _LayoutConnectionBehavior.default] }; exports.default = _default; },{"./AutoPlaceBehavior":42,"./CreateParticipantBehavior":43,"./LayoutConnectionBehavior":44}],46:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnGridSnapping = _interopRequireDefault(require("./BpmnGridSnapping")); var _gridSnapping = _interopRequireDefault(require("diagram-js/lib/features/grid-snapping")); var _behavior = _interopRequireDefault(require("./behavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_gridSnapping.default, _behavior.default], __init__: ['bpmnGridSnapping'], bpmnGridSnapping: ['type', _BpmnGridSnapping.default] }; exports.default = _default; },{"./BpmnGridSnapping":41,"./behavior":45,"diagram-js/lib/features/grid-snapping":207}],47:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnInteractionEvents; var _ModelUtil = require("../../util/ModelUtil"); var _DiUtil = require("../../util/DiUtil"); var LABEL_WIDTH = 30, LABEL_HEIGHT = 30; /** * BPMN-specific hit zones and interaction fixes. * * @param {EventBus} eventBus * @param {InteractionEvents} interactionEvents */ function BpmnInteractionEvents(eventBus, interactionEvents) { this._interactionEvents = interactionEvents; var self = this; eventBus.on(['interactionEvents.createHit', 'interactionEvents.updateHit'], function (context) { var element = context.element, gfx = context.gfx; if ((0, _ModelUtil.is)(element, 'bpmn:Lane')) { return self.createParticipantHit(element, gfx); } else if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) { if ((0, _DiUtil.isExpanded)(element)) { return self.createParticipantHit(element, gfx); } else { return self.createDefaultHit(element, gfx); } } else if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess')) { if ((0, _DiUtil.isExpanded)(element)) { return self.createSubProcessHit(element, gfx); } else { return self.createDefaultHit(element, gfx); } } }); } BpmnInteractionEvents.$inject = ['eventBus', 'interactionEvents']; BpmnInteractionEvents.prototype.createDefaultHit = function (element, gfx) { this._interactionEvents.removeHits(gfx); this._interactionEvents.createDefaultHit(element, gfx); // indicate that we created a hit return true; }; BpmnInteractionEvents.prototype.createParticipantHit = function (element, gfx) { // remove existing hits this._interactionEvents.removeHits(gfx); // add outline hit this._interactionEvents.createBoxHit(gfx, 'click-stroke', { width: element.width, height: element.height }); // add label hit this._interactionEvents.createBoxHit(gfx, 'all', { width: LABEL_WIDTH, height: element.height }); // indicate that we created a hit return true; }; BpmnInteractionEvents.prototype.createSubProcessHit = function (element, gfx) { // remove existing hits this._interactionEvents.removeHits(gfx); // add outline hit this._interactionEvents.createBoxHit(gfx, 'click-stroke', { width: element.width, height: element.height }); // add label hit this._interactionEvents.createBoxHit(gfx, 'all', { width: element.width, height: LABEL_HEIGHT }); // indicate that we created a hit return true; }; },{"../../util/DiUtil":139,"../../util/ModelUtil":141}],48:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnInteractionEvents = _interopRequireDefault(require("./BpmnInteractionEvents")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['bpmnInteractionEvents'], bpmnInteractionEvents: ['type', _BpmnInteractionEvents.default] }; exports.default = _default; },{"./BpmnInteractionEvents":47}],49:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnKeyboardBindings; var _inherits = _interopRequireDefault(require("inherits")); var _KeyboardBindings = _interopRequireDefault(require("diagram-js/lib/features/keyboard/KeyboardBindings")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN 2.0 specific keyboard bindings. * * @param {Injector} injector */ function BpmnKeyboardBindings(injector) { injector.invoke(_KeyboardBindings.default, this); } (0, _inherits.default)(BpmnKeyboardBindings, _KeyboardBindings.default); BpmnKeyboardBindings.$inject = ['injector']; /** * Register available keyboard bindings. * * @param {Keyboard} keyboard * @param {EditorActions} editorActions */ BpmnKeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) { // inherit default bindings _KeyboardBindings.default.prototype.registerBindings.call(this, keyboard, editorActions); /** * Add keyboard binding if respective editor action * is registered. * * @param {string} action name * @param {Function} fn that implements the key binding */ function addListener(action, fn) { if (editorActions.isRegistered(action)) { keyboard.addListener(fn); } } // select all elements // CTRL + A addListener('selectElements', function (context) { var event = context.keyEvent; if (keyboard.isKey(['a', 'A'], event) && keyboard.isCmd(event)) { editorActions.trigger('selectElements'); return true; } }); // search labels // CTRL + F addListener('find', function (context) { var event = context.keyEvent; if (keyboard.isKey(['f', 'F'], event) && keyboard.isCmd(event)) { editorActions.trigger('find'); return true; } }); // activate space tool // S addListener('spaceTool', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['s', 'S'], event)) { editorActions.trigger('spaceTool'); return true; } }); // activate lasso tool // L addListener('lassoTool', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['l', 'L'], event)) { editorActions.trigger('lassoTool'); return true; } }); // activate hand tool // H addListener('handTool', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['h', 'H'], event)) { editorActions.trigger('handTool'); return true; } }); // activate global connect tool // C addListener('globalConnectTool', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['c', 'C'], event)) { editorActions.trigger('globalConnectTool'); return true; } }); // activate direct editing // E addListener('directEditing', function (context) { var event = context.keyEvent; if (keyboard.hasModifier(event)) { return; } if (keyboard.isKey(['e', 'E'], event)) { editorActions.trigger('directEditing'); return true; } }); }; },{"diagram-js/lib/features/keyboard/KeyboardBindings":215,"inherits":347}],50:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _keyboard = _interopRequireDefault(require("diagram-js/lib/features/keyboard")); var _BpmnKeyboardBindings = _interopRequireDefault(require("./BpmnKeyboardBindings")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_keyboard.default], __init__: ['keyboardBindings'], keyboardBindings: ['type', _BpmnKeyboardBindings.default] }; exports.default = _default; },{"./BpmnKeyboardBindings":49,"diagram-js/lib/features/keyboard":217}],51:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelEditingPreview; var _tinySvg = require("tiny-svg"); var _ModelUtil = require("../../util/ModelUtil"); var _SvgTransformUtil = require("diagram-js/lib/util/SvgTransformUtil"); var MARKER_HIDDEN = 'djs-element-hidden', MARKER_LABEL_HIDDEN = 'djs-label-hidden'; function LabelEditingPreview(eventBus, canvas, elementRegistry, pathMap) { var self = this; var defaultLayer = canvas.getDefaultLayer(); var element, absoluteElementBBox, gfx; eventBus.on('directEditing.activate', function (context) { var activeProvider = context.active; element = activeProvider.element.label || activeProvider.element; // text annotation if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { absoluteElementBBox = canvas.getAbsoluteBBox(element); gfx = (0, _tinySvg.create)('g'); var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: element.height, position: { mx: 0.0, my: 0.0 } }); var path = self.path = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(path, { d: textPathData, strokeWidth: 2, stroke: getStrokeColor(element) }); (0, _tinySvg.append)(gfx, path); (0, _tinySvg.append)(defaultLayer, gfx); (0, _SvgTransformUtil.translate)(gfx, element.x, element.y); } if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation') || element.labelTarget) { canvas.addMarker(element, MARKER_HIDDEN); } else if ((0, _ModelUtil.is)(element, 'bpmn:Task') || (0, _ModelUtil.is)(element, 'bpmn:CallActivity') || (0, _ModelUtil.is)(element, 'bpmn:SubProcess') || (0, _ModelUtil.is)(element, 'bpmn:Participant')) { canvas.addMarker(element, MARKER_LABEL_HIDDEN); } }); eventBus.on('directEditing.resize', function (context) { // text annotation if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { var height = context.height, dy = context.dy; var newElementHeight = Math.max(element.height / absoluteElementBBox.height * (height + dy), 0); var textPathData = pathMap.getScaledPath('TEXT_ANNOTATION', { xScaleFactor: 1, yScaleFactor: 1, containerWidth: element.width, containerHeight: newElementHeight, position: { mx: 0.0, my: 0.0 } }); (0, _tinySvg.attr)(self.path, { d: textPathData }); } }); eventBus.on(['directEditing.complete', 'directEditing.cancel'], function (context) { var activeProvider = context.active; if (activeProvider) { canvas.removeMarker(activeProvider.element.label || activeProvider.element, MARKER_HIDDEN); canvas.removeMarker(element, MARKER_LABEL_HIDDEN); } element = undefined; absoluteElementBBox = undefined; if (gfx) { (0, _tinySvg.remove)(gfx); gfx = undefined; } }); } LabelEditingPreview.$inject = ['eventBus', 'canvas', 'elementRegistry', 'pathMap']; // helpers /////////////////// function getStrokeColor(element, defaultColor) { var bo = (0, _ModelUtil.getBusinessObject)(element); return bo.di.get('stroke') || defaultColor || 'black'; } },{"../../util/ModelUtil":141,"diagram-js/lib/util/SvgTransformUtil":328,"tiny-svg":567}],52:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelEditingProvider; var _minDash = require("min-dash"); var _LabelUtil = require("./LabelUtil"); var _ModelUtil = require("../../util/ModelUtil"); var _CategoryUtil = require("../modeling/behavior/util/CategoryUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _DiUtil = require("../../util/DiUtil"); var _LabelUtil2 = require("../../util/LabelUtil"); function LabelEditingProvider(eventBus, bpmnFactory, canvas, directEditing, modeling, resizeHandles, textRenderer) { this._bpmnFactory = bpmnFactory; this._canvas = canvas; this._modeling = modeling; this._textRenderer = textRenderer; directEditing.registerProvider(this); // listen to dblclick on non-root elements eventBus.on('element.dblclick', function (event) { activateDirectEdit(event.element, true); }); // complete on followup canvas operation eventBus.on(['autoPlace.start', 'canvas.viewbox.changing', 'drag.init', 'element.mousedown', 'popupMenu.open'], function (event) { if (directEditing.isActive()) { directEditing.complete(); } }); // cancel on command stack changes eventBus.on(['commandStack.changed'], function (e) { if (directEditing.isActive()) { directEditing.cancel(); } }); eventBus.on('directEditing.activate', function (event) { resizeHandles.removeResizers(); }); eventBus.on('create.end', 500, function (event) { var context = event.context, element = context.shape, canExecute = event.context.canExecute, isTouch = event.isTouch; // TODO(nikku): we need to find a way to support the // direct editing on mobile devices; right now this will // break for desworkflowediting on mobile devices // as it breaks the user interaction workflow // TODO(nre): we should temporarily focus the edited element // here and release the focused viewport after the direct edit // operation is finished if (isTouch) { return; } if (!canExecute) { return; } if (context.hints && context.hints.createElementsBehavior === false) { return; } activateDirectEdit(element); }); eventBus.on('autoPlace.end', 500, function (event) { activateDirectEdit(event.shape); }); function activateDirectEdit(element, force) { if (force || (0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:TextAnnotation', 'bpmn:Group']) || isCollapsedSubProcess(element)) { directEditing.activate(element); } } } LabelEditingProvider.$inject = ['eventBus', 'bpmnFactory', 'canvas', 'directEditing', 'modeling', 'resizeHandles', 'textRenderer']; /** * Activate direct editing for activities and text annotations. * * @param {djs.model.Base} element * * @return {Object} an object with properties bounds (position and size), text and options */ LabelEditingProvider.prototype.activate = function (element) { // text var text = (0, _LabelUtil.getLabel)(element); if (text === undefined) { return; } var context = { text: text }; // bounds var bounds = this.getEditingBBox(element); (0, _minDash.assign)(context, bounds); var options = {}; // tasks if ((0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:Participant', 'bpmn:Lane', 'bpmn:CallActivity']) || isCollapsedSubProcess(element)) { (0, _minDash.assign)(options, { centerVertically: true }); } // external labels if ((0, _LabelUtil2.isLabelExternal)(element)) { (0, _minDash.assign)(options, { autoResize: true }); } // text annotations if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { (0, _minDash.assign)(options, { resizable: true, autoResize: true }); } (0, _minDash.assign)(context, { options: options }); return context; }; /** * Get the editing bounding box based on the element's size and position * * @param {djs.model.Base} element * * @return {Object} an object containing information about position * and size (fixed or minimum and/or maximum) */ LabelEditingProvider.prototype.getEditingBBox = function (element) { var canvas = this._canvas; var target = element.label || element; var bbox = canvas.getAbsoluteBBox(target); var mid = { x: bbox.x + bbox.width / 2, y: bbox.y + bbox.height / 2 }; // default position var bounds = { x: bbox.x, y: bbox.y }; var zoom = canvas.zoom(); var defaultStyle = this._textRenderer.getDefaultStyle(), externalStyle = this._textRenderer.getExternalStyle(); // take zoom into account var externalFontSize = externalStyle.fontSize * zoom, externalLineHeight = externalStyle.lineHeight, defaultFontSize = defaultStyle.fontSize * zoom, defaultLineHeight = defaultStyle.lineHeight; var style = { fontFamily: this._textRenderer.getDefaultStyle().fontFamily, fontWeight: this._textRenderer.getDefaultStyle().fontWeight }; // adjust for expanded pools AND lanes if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || isExpandedPool(element)) { (0, _minDash.assign)(bounds, { width: bbox.height, height: 30 * zoom, x: bbox.x - bbox.height / 2 + 15 * zoom, y: mid.y - 30 * zoom / 2 }); (0, _minDash.assign)(style, { fontSize: defaultFontSize + 'px', lineHeight: defaultLineHeight, paddingTop: 7 * zoom + 'px', paddingBottom: 7 * zoom + 'px', paddingLeft: 5 * zoom + 'px', paddingRight: 5 * zoom + 'px', transform: 'rotate(-90deg)' }); } // internal labels for tasks and collapsed call activities, // sub processes and participants if ((0, _ModelingUtil.isAny)(element, ['bpmn:Task', 'bpmn:CallActivity']) || isCollapsedPool(element) || isCollapsedSubProcess(element)) { (0, _minDash.assign)(bounds, { width: bbox.width, height: bbox.height }); (0, _minDash.assign)(style, { fontSize: defaultFontSize + 'px', lineHeight: defaultLineHeight, paddingTop: 7 * zoom + 'px', paddingBottom: 7 * zoom + 'px', paddingLeft: 5 * zoom + 'px', paddingRight: 5 * zoom + 'px' }); } // internal labels for expanded sub processes if (isExpandedSubProcess(element)) { (0, _minDash.assign)(bounds, { width: bbox.width, x: bbox.x }); (0, _minDash.assign)(style, { fontSize: defaultFontSize + 'px', lineHeight: defaultLineHeight, paddingTop: 7 * zoom + 'px', paddingBottom: 7 * zoom + 'px', paddingLeft: 5 * zoom + 'px', paddingRight: 5 * zoom + 'px' }); } var width = 90 * zoom, paddingTop = 7 * zoom, paddingBottom = 4 * zoom; // external labels for events, data elements, gateways, groups and connections if (target.labelTarget) { (0, _minDash.assign)(bounds, { width: width, height: bbox.height + paddingTop + paddingBottom, x: mid.x - width / 2, y: bbox.y - paddingTop }); (0, _minDash.assign)(style, { fontSize: externalFontSize + 'px', lineHeight: externalLineHeight, paddingTop: paddingTop + 'px', paddingBottom: paddingBottom + 'px' }); } // external label not yet created if ((0, _LabelUtil2.isLabelExternal)(target) && !(0, _LabelUtil2.hasExternalLabel)(target) && !(0, _LabelUtil2.isLabel)(target)) { var externalLabelMid = (0, _LabelUtil2.getExternalLabelMid)(element); var absoluteBBox = canvas.getAbsoluteBBox({ x: externalLabelMid.x, y: externalLabelMid.y, width: 0, height: 0 }); var height = externalFontSize + paddingTop + paddingBottom; (0, _minDash.assign)(bounds, { width: width, height: height, x: absoluteBBox.x - width / 2, y: absoluteBBox.y - height / 2 }); (0, _minDash.assign)(style, { fontSize: externalFontSize + 'px', lineHeight: externalLineHeight, paddingTop: paddingTop + 'px', paddingBottom: paddingBottom + 'px' }); } // text annotations if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { (0, _minDash.assign)(bounds, { width: bbox.width, height: bbox.height, minWidth: 30 * zoom, minHeight: 10 * zoom }); (0, _minDash.assign)(style, { textAlign: 'left', paddingTop: 5 * zoom + 'px', paddingBottom: 7 * zoom + 'px', paddingLeft: 7 * zoom + 'px', paddingRight: 5 * zoom + 'px', fontSize: defaultFontSize + 'px', lineHeight: defaultLineHeight }); } return { bounds: bounds, style: style }; }; LabelEditingProvider.prototype.update = function (element, newLabel, activeContextText, bounds) { var newBounds, bbox; if ((0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { bbox = this._canvas.getAbsoluteBBox(element); newBounds = { x: element.x, y: element.y, width: element.width / bbox.width * bounds.width, height: element.height / bbox.height * bounds.height }; } if ((0, _ModelUtil.is)(element, 'bpmn:Group')) { var businessObject = (0, _ModelUtil.getBusinessObject)(element); // initialize categoryValue if not existing if (!businessObject.categoryValueRef) { var rootElement = this._canvas.getRootElement(), definitions = (0, _ModelUtil.getBusinessObject)(rootElement).$parent; var categoryValue = (0, _CategoryUtil.createCategoryValue)(definitions, this._bpmnFactory); (0, _ModelUtil.getBusinessObject)(element).categoryValueRef = categoryValue; } } if (isEmptyText(newLabel)) { newLabel = null; } this._modeling.updateLabel(element, newLabel, newBounds); }; // helpers ////////////////////// function isCollapsedSubProcess(element) { return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && !(0, _DiUtil.isExpanded)(element); } function isExpandedSubProcess(element) { return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element); } function isCollapsedPool(element) { return (0, _ModelUtil.is)(element, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(element); } function isExpandedPool(element) { return (0, _ModelUtil.is)(element, 'bpmn:Participant') && (0, _DiUtil.isExpanded)(element); } function isEmptyText(label) { return !label || !label.trim(); } },{"../../util/DiUtil":139,"../../util/LabelUtil":140,"../../util/ModelUtil":141,"../modeling/behavior/util/CategoryUtil":95,"../modeling/util/ModelingUtil":112,"./LabelUtil":53,"min-dash":555}],53:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getLabel = getLabel; exports.setLabel = setLabel; var _ModelUtil = require("../../util/ModelUtil"); function getLabelAttr(semantic) { if ((0, _ModelUtil.is)(semantic, 'bpmn:FlowElement') || (0, _ModelUtil.is)(semantic, 'bpmn:Participant') || (0, _ModelUtil.is)(semantic, 'bpmn:Lane') || (0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:MessageFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:DataInput') || (0, _ModelUtil.is)(semantic, 'bpmn:DataOutput')) { return 'name'; } if ((0, _ModelUtil.is)(semantic, 'bpmn:TextAnnotation')) { return 'text'; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Group')) { return 'categoryValueRef'; } } function getCategoryValue(semantic) { var categoryValueRef = semantic['categoryValueRef']; if (!categoryValueRef) { return ''; } return categoryValueRef.value || ''; } function getLabel(element) { var semantic = element.businessObject, attr = getLabelAttr(semantic); if (attr) { if (attr === 'categoryValueRef') { return getCategoryValue(semantic); } return semantic[attr] || ''; } } function setLabel(element, text, isExternal) { var semantic = element.businessObject, attr = getLabelAttr(semantic); if (attr) { if (attr === 'categoryValueRef') { semantic['categoryValueRef'].value = text; } else { semantic[attr] = text; } } return element; } },{"../../util/ModelUtil":141}],54:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateLabelHandler; var _LabelUtil = require("../LabelUtil"); var _LabelUtil2 = require("../../../util/LabelUtil"); var _ModelUtil = require("../../../util/ModelUtil"); var NULL_DIMENSIONS = { width: 0, height: 0 }; /** * A handler that updates the text of a BPMN element. */ function UpdateLabelHandler(modeling, textRenderer) { /** * Set the label and return the changed elements. * * Element parameter can be label itself or connection (i.e. sequence flow). * * @param {djs.model.Base} element * @param {string} text */ function setText(element, text) { // external label if present var label = element.label || element; var labelTarget = element.labelTarget || element; (0, _LabelUtil.setLabel)(label, text, labelTarget !== label); return [label, labelTarget]; } function preExecute(ctx) { var element = ctx.element, businessObject = element.businessObject, newLabel = ctx.newLabel; if (!(0, _LabelUtil2.isLabel)(element) && (0, _LabelUtil2.isLabelExternal)(element) && !(0, _LabelUtil2.hasExternalLabel)(element) && !isEmptyText(newLabel)) { // create label var paddingTop = 7; var labelCenter = (0, _LabelUtil2.getExternalLabelMid)(element); labelCenter = { x: labelCenter.x, y: labelCenter.y + paddingTop }; modeling.createLabel(element, labelCenter, { id: businessObject.id + '_label', businessObject: businessObject }); } } function execute(ctx) { ctx.oldLabel = (0, _LabelUtil.getLabel)(ctx.element); return setText(ctx.element, ctx.newLabel); } function revert(ctx) { return setText(ctx.element, ctx.oldLabel); } function postExecute(ctx) { var element = ctx.element, label = element.label || element, newLabel = ctx.newLabel, newBounds = ctx.newBounds, hints = ctx.hints || {}; // ignore internal labels for elements except text annotations if (!(0, _LabelUtil2.isLabel)(label) && !(0, _ModelUtil.is)(label, 'bpmn:TextAnnotation')) { return; } if ((0, _LabelUtil2.isLabel)(label) && isEmptyText(newLabel)) { if (hints.removeShape !== false) { modeling.removeShape(label, { unsetLabel: false }); } return; } var text = (0, _LabelUtil.getLabel)(label); // resize element based on label _or_ pre-defined bounds if (typeof newBounds === 'undefined') { newBounds = textRenderer.getExternalLabelBounds(label, text); } // setting newBounds to false or _null_ will // disable the postExecute resize operation if (newBounds) { modeling.resizeShape(label, newBounds, NULL_DIMENSIONS); } } // API this.preExecute = preExecute; this.execute = execute; this.revert = revert; this.postExecute = postExecute; } UpdateLabelHandler.$inject = ['modeling', 'textRenderer']; // helpers /////////////////////// function isEmptyText(label) { return !label || !label.trim(); } },{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"../LabelUtil":53}],55:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _changeSupport = _interopRequireDefault(require("diagram-js/lib/features/change-support")); var _resize = _interopRequireDefault(require("diagram-js/lib/features/resize")); var _diagramJsDirectEditing = _interopRequireDefault(require("diagram-js-direct-editing")); var _LabelEditingProvider = _interopRequireDefault(require("./LabelEditingProvider")); var _LabelEditingPreview = _interopRequireDefault(require("./LabelEditingPreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_changeSupport.default, _resize.default, _diagramJsDirectEditing.default], __init__: ['labelEditingProvider', 'labelEditingPreview'], labelEditingProvider: ['type', _LabelEditingProvider.default], labelEditingPreview: ['type', _LabelEditingPreview.default] }; exports.default = _default; },{"./LabelEditingPreview":51,"./LabelEditingProvider":52,"diagram-js-direct-editing":332,"diagram-js/lib/features/change-support":178,"diagram-js/lib/features/resize":269}],56:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnFactory; var _minDash = require("min-dash"); var _ModelingUtil = require("./util/ModelingUtil"); var _ModelUtil = require("../../util/ModelUtil"); function BpmnFactory(moddle) { this._model = moddle; } BpmnFactory.$inject = ['moddle']; BpmnFactory.prototype._needsId = function (element) { return (0, _ModelingUtil.isAny)(element, ['bpmn:RootElement', 'bpmn:FlowElement', 'bpmn:MessageFlow', 'bpmn:DataAssociation', 'bpmn:Artifact', 'bpmn:Participant', 'bpmn:Lane', 'bpmn:LaneSet', 'bpmn:Process', 'bpmn:Collaboration', 'bpmndi:BPMNShape', 'bpmndi:BPMNEdge', 'bpmndi:BPMNDiagram', 'bpmndi:BPMNPlane', 'bpmn:Property', 'bpmn:CategoryValue']); }; BpmnFactory.prototype._ensureId = function (element) { // generate semantic ids for elements // bpmn:SequenceFlow -> SequenceFlow_ID var prefix; if ((0, _ModelUtil.is)(element, 'bpmn:Activity')) { prefix = 'Activity'; } else if ((0, _ModelUtil.is)(element, 'bpmn:Event')) { prefix = 'Event'; } else if ((0, _ModelUtil.is)(element, 'bpmn:Gateway')) { prefix = 'Gateway'; } else if ((0, _ModelingUtil.isAny)(element, ['bpmn:SequenceFlow', 'bpmn:MessageFlow'])) { prefix = 'Flow'; } else { prefix = (element.$type || '').replace(/^[^:]*:/g, ''); } prefix += '_'; if (!element.id && this._needsId(element)) { element.id = this._model.ids.nextPrefixed(prefix, element); } }; BpmnFactory.prototype.create = function (type, attrs) { var element = this._model.create(type, attrs || {}); this._ensureId(element); return element; }; BpmnFactory.prototype.createDiLabel = function () { return this.create('bpmndi:BPMNLabel', { bounds: this.createDiBounds() }); }; BpmnFactory.prototype.createDiShape = function (semantic, bounds, attrs) { return this.create('bpmndi:BPMNShape', (0, _minDash.assign)({ bpmnElement: semantic, bounds: this.createDiBounds(bounds) }, attrs)); }; BpmnFactory.prototype.createDiBounds = function (bounds) { return this.create('dc:Bounds', bounds); }; BpmnFactory.prototype.createDiWaypoints = function (waypoints) { var self = this; return (0, _minDash.map)(waypoints, function (pos) { return self.createDiWaypoint(pos); }); }; BpmnFactory.prototype.createDiWaypoint = function (point) { return this.create('dc:Point', (0, _minDash.pick)(point, ['x', 'y'])); }; BpmnFactory.prototype.createDiEdge = function (semantic, waypoints, attrs) { return this.create('bpmndi:BPMNEdge', (0, _minDash.assign)({ bpmnElement: semantic }, attrs)); }; BpmnFactory.prototype.createDiPlane = function (semantic) { return this.create('bpmndi:BPMNPlane', { bpmnElement: semantic }); }; },{"../../util/ModelUtil":141,"./util/ModelingUtil":112,"min-dash":555}],57:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnLayouter; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _BaseLayouter = _interopRequireDefault(require("diagram-js/lib/layout/BaseLayouter")); var _ManhattanLayout = require("diagram-js/lib/layout/ManhattanLayout"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _DiUtil = require("../../util/DiUtil"); var _ModelUtil = require("../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var ATTACH_ORIENTATION_PADDING = -10, BOUNDARY_TO_HOST_THRESHOLD = 40; var oppositeOrientationMapping = { 'top': 'bottom', 'top-right': 'bottom-left', 'top-left': 'bottom-right', 'right': 'left', 'bottom': 'top', 'bottom-right': 'top-left', 'bottom-left': 'top-right', 'left': 'right' }; var orientationDirectionMapping = { top: 't', right: 'r', bottom: 'b', left: 'l' }; function BpmnLayouter() {} (0, _inherits.default)(BpmnLayouter, _BaseLayouter.default); BpmnLayouter.prototype.layoutConnection = function (connection, hints) { if (!hints) { hints = {}; } var source = hints.source || connection.source, target = hints.target || connection.target, waypoints = hints.waypoints || connection.waypoints, connectionStart = hints.connectionStart, connectionEnd = hints.connectionEnd; var manhattanOptions, updatedWaypoints; if (!connectionStart) { connectionStart = getConnectionDocking(waypoints && waypoints[0], source); } if (!connectionEnd) { connectionEnd = getConnectionDocking(waypoints && waypoints[waypoints.length - 1], target); } // TODO(nikku): support vertical modeling // and invert preferredLayouts accordingly if ((0, _ModelUtil.is)(connection, 'bpmn:Association') || (0, _ModelUtil.is)(connection, 'bpmn:DataAssociation')) { if (waypoints && !isCompensationAssociation(source, target)) { return [].concat([connectionStart], waypoints.slice(1, -1), [connectionEnd]); } } if ((0, _ModelUtil.is)(connection, 'bpmn:MessageFlow')) { manhattanOptions = getMessageFlowManhattanOptions(source, target); } else if ((0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow') || isCompensationAssociation(source, target)) { // layout all connection between flow elements h:h, except for // (1) outgoing of boundary events -> layout based on attach orientation and target orientation // (2) incoming/outgoing of gateways -> v:h for outgoing, h:v for incoming // (3) loops if (source === target) { manhattanOptions = { preferredLayouts: getLoopPreferredLayout(source, connection) }; } else if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent')) { manhattanOptions = { preferredLayouts: getBoundaryEventPreferredLayouts(source, target, connectionEnd) }; } else if (isExpandedSubProcess(source) || isExpandedSubProcess(target)) { manhattanOptions = getSubProcessManhattanOptions(source); } else if ((0, _ModelUtil.is)(source, 'bpmn:Gateway')) { manhattanOptions = { preferredLayouts: ['v:h'] }; } else if ((0, _ModelUtil.is)(target, 'bpmn:Gateway')) { manhattanOptions = { preferredLayouts: ['h:v'] }; } else { manhattanOptions = { preferredLayouts: ['h:h'] }; } } if (manhattanOptions) { manhattanOptions = (0, _minDash.assign)(manhattanOptions, hints); updatedWaypoints = (0, _ManhattanLayout.withoutRedundantPoints)((0, _ManhattanLayout.repairConnection)(source, target, connectionStart, connectionEnd, waypoints, manhattanOptions)); } return updatedWaypoints || [connectionStart, connectionEnd]; }; // helpers ////////// function getAttachOrientation(attachedElement) { var hostElement = attachedElement.host; return (0, _LayoutUtil.getOrientation)((0, _LayoutUtil.getMid)(attachedElement), hostElement, ATTACH_ORIENTATION_PADDING); } function getMessageFlowManhattanOptions(source, target) { return { preferredLayouts: ['straight', 'v:v'], preserveDocking: getMessageFlowPreserveDocking(source, target) }; } function getMessageFlowPreserveDocking(source, target) { // (1) docking element connected to participant has precedence if ((0, _ModelUtil.is)(target, 'bpmn:Participant')) { return 'source'; } if ((0, _ModelUtil.is)(source, 'bpmn:Participant')) { return 'target'; } // (2) docking element connected to expanded sub-process has precedence if (isExpandedSubProcess(target)) { return 'source'; } if (isExpandedSubProcess(source)) { return 'target'; } // (3) docking event has precedence if ((0, _ModelUtil.is)(target, 'bpmn:Event')) { return 'target'; } if ((0, _ModelUtil.is)(source, 'bpmn:Event')) { return 'source'; } return null; } function getSubProcessManhattanOptions(source) { return { preferredLayouts: ['straight', 'h:h'], preserveDocking: getSubProcessPreserveDocking(source) }; } function getSubProcessPreserveDocking(source) { return isExpandedSubProcess(source) ? 'target' : 'source'; } function getConnectionDocking(point, shape) { return point ? point.original || point : (0, _LayoutUtil.getMid)(shape); } function isCompensationAssociation(source, target) { return (0, _ModelUtil.is)(target, 'bpmn:Activity') && (0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent') && target.businessObject.isForCompensation; } function isExpandedSubProcess(element) { return (0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element); } function isSame(a, b) { return a === b; } function isAnyOrientation(orientation, orientations) { return orientations.indexOf(orientation) !== -1; } function getHorizontalOrientation(orientation) { var matches = /right|left/.exec(orientation); return matches && matches[0]; } function getVerticalOrientation(orientation) { var matches = /top|bottom/.exec(orientation); return matches && matches[0]; } function isOppositeOrientation(a, b) { return oppositeOrientationMapping[a] === b; } function isOppositeHorizontalOrientation(a, b) { var horizontalOrientation = getHorizontalOrientation(a); var oppositeHorizontalOrientation = oppositeOrientationMapping[horizontalOrientation]; return b.indexOf(oppositeHorizontalOrientation) !== -1; } function isOppositeVerticalOrientation(a, b) { var verticalOrientation = getVerticalOrientation(a); var oppositeVerticalOrientation = oppositeOrientationMapping[verticalOrientation]; return b.indexOf(oppositeVerticalOrientation) !== -1; } function isHorizontalOrientation(orientation) { return orientation === 'right' || orientation === 'left'; } function getLoopPreferredLayout(source, connection) { var waypoints = connection.waypoints; var orientation = waypoints && waypoints.length && (0, _LayoutUtil.getOrientation)(waypoints[0], source); if (orientation === 'top') { return ['t:r']; } else if (orientation === 'right') { return ['r:b']; } else if (orientation === 'left') { return ['l:t']; } return ['b:l']; } function getBoundaryEventPreferredLayouts(source, target, end) { var sourceMid = (0, _LayoutUtil.getMid)(source), targetMid = (0, _LayoutUtil.getMid)(target), attachOrientation = getAttachOrientation(source), sourceLayout, targetLayout; var isLoop = isSame(source.host, target); var attachedToSide = isAnyOrientation(attachOrientation, ['top', 'right', 'bottom', 'left']); var targetOrientation = (0, _LayoutUtil.getOrientation)(targetMid, sourceMid, { x: source.width / 2 + target.width / 2, y: source.height / 2 + target.height / 2 }); if (isLoop) { return getBoundaryEventLoopLayout(attachOrientation, attachedToSide, source, target, end); } // source layout sourceLayout = getBoundaryEventSourceLayout(attachOrientation, targetOrientation, attachedToSide); // target layout targetLayout = getBoundaryEventTargetLayout(attachOrientation, targetOrientation, attachedToSide); return [sourceLayout + ':' + targetLayout]; } function getBoundaryEventLoopLayout(attachOrientation, attachedToSide, source, target, end) { var orientation = attachedToSide ? attachOrientation : getVerticalOrientation(attachOrientation), sourceLayout = orientationDirectionMapping[orientation], targetLayout; if (attachedToSide) { if (isHorizontalOrientation(attachOrientation)) { targetLayout = shouldConnectToSameSide('y', source, target, end) ? 'h' : 'b'; } else { targetLayout = shouldConnectToSameSide('x', source, target, end) ? 'v' : 'l'; } } else { targetLayout = 'v'; } return [sourceLayout + ':' + targetLayout]; } function shouldConnectToSameSide(axis, source, target, end) { var threshold = BOUNDARY_TO_HOST_THRESHOLD; return !(areCloseOnAxis(axis, end, target, threshold) || areCloseOnAxis(axis, end, { x: target.x + target.width, y: target.y + target.height }, threshold) || areCloseOnAxis(axis, end, (0, _LayoutUtil.getMid)(source), threshold)); } function areCloseOnAxis(axis, a, b, threshold) { return Math.abs(a[axis] - b[axis]) < threshold; } function getBoundaryEventSourceLayout(attachOrientation, targetOrientation, attachedToSide) { // attached to either top, right, bottom or left side if (attachedToSide) { return orientationDirectionMapping[attachOrientation]; } // attached to either top-right, top-left, bottom-right or bottom-left corner // same vertical or opposite horizontal orientation if (isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) || isOppositeOrientation(getHorizontalOrientation(attachOrientation), getHorizontalOrientation(targetOrientation))) { return orientationDirectionMapping[getVerticalOrientation(attachOrientation)]; } // fallback return orientationDirectionMapping[getHorizontalOrientation(attachOrientation)]; } function getBoundaryEventTargetLayout(attachOrientation, targetOrientation, attachedToSide) { // attached to either top, right, bottom or left side if (attachedToSide) { if (isHorizontalOrientation(attachOrientation)) { // orientation is right or left // opposite horizontal orientation or same orientation if (isOppositeHorizontalOrientation(attachOrientation, targetOrientation) || isSame(attachOrientation, targetOrientation)) { return 'h'; } // fallback return 'v'; } else { // orientation is top or bottom // opposite vertical orientation or same orientation if (isOppositeVerticalOrientation(attachOrientation, targetOrientation) || isSame(attachOrientation, targetOrientation)) { return 'v'; } // fallback return 'h'; } } // attached to either top-right, top-left, bottom-right or bottom-left corner // orientation is right, left // or same vertical orientation but also right or left if (isHorizontalOrientation(targetOrientation) || isSame(getVerticalOrientation(attachOrientation), getVerticalOrientation(targetOrientation)) && getHorizontalOrientation(targetOrientation)) { return 'h'; } else { return 'v'; } } },{"../../util/DiUtil":139,"../../util/ModelUtil":141,"diagram-js/lib/layout/BaseLayouter":298,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/layout/ManhattanLayout":301,"inherits":347,"min-dash":555}],58:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnUpdater; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _Collections = require("diagram-js/lib/util/Collections"); var _model = require("diagram-js/lib/model"); var _ModelUtil = require("../../util/ModelUtil"); var _ModelingUtil = require("./util/ModelingUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A handler responsible for updating the underlying BPMN 2.0 XML + DI * once changes on the diagram happen */ function BpmnUpdater(eventBus, bpmnFactory, connectionDocking, translate) { _CommandInterceptor.default.call(this, eventBus); this._bpmnFactory = bpmnFactory; this._translate = translate; var self = this; // connection cropping ////////////////////// // crop connection ends during create/update function cropConnection(e) { var context = e.context, hints = context.hints || {}, connection; if (!context.cropped && hints.createElementsBehavior !== false) { connection = context.connection; connection.waypoints = connectionDocking.getCroppedWaypoints(connection); context.cropped = true; } } this.executed(['connection.layout', 'connection.create'], cropConnection); this.reverted(['connection.layout'], function (e) { delete e.context.cropped; }); // BPMN + DI update ////////////////////// // update parent function updateParent(e) { var context = e.context; self.updateParent(context.shape || context.connection, context.oldParent); } function reverseUpdateParent(e) { var context = e.context; var element = context.shape || context.connection, // oldParent is the (old) new parent, because we are undoing oldParent = context.parent || context.newParent; self.updateParent(element, oldParent); } this.executed(['shape.move', 'shape.create', 'shape.delete', 'connection.create', 'connection.move', 'connection.delete'], ifBpmn(updateParent)); this.reverted(['shape.move', 'shape.create', 'shape.delete', 'connection.create', 'connection.move', 'connection.delete'], ifBpmn(reverseUpdateParent)); /* * ## Updating Parent * * When morphing a Process into a Collaboration or vice-versa, * make sure that both the *semantic* and *di* parent of each element * is updated. * */ function updateRoot(event) { var context = event.context, oldRoot = context.oldRoot, children = oldRoot.children; (0, _minDash.forEach)(children, function (child) { if ((0, _ModelUtil.is)(child, 'bpmn:BaseElement')) { self.updateParent(child); } }); } this.executed(['canvas.updateRoot'], updateRoot); this.reverted(['canvas.updateRoot'], updateRoot); // update bounds function updateBounds(e) { var shape = e.context.shape; if (!(0, _ModelUtil.is)(shape, 'bpmn:BaseElement')) { return; } self.updateBounds(shape); } this.executed(['shape.move', 'shape.create', 'shape.resize'], ifBpmn(function (event) { // exclude labels because they're handled separately during shape.changed if (event.context.shape.type === 'label') { return; } updateBounds(event); })); this.reverted(['shape.move', 'shape.create', 'shape.resize'], ifBpmn(function (event) { // exclude labels because they're handled separately during shape.changed if (event.context.shape.type === 'label') { return; } updateBounds(event); })); // Handle labels separately. This is necessary, because the label bounds have to be updated // every time its shape changes, not only on move, create and resize. eventBus.on('shape.changed', function (event) { if (event.element.type === 'label') { updateBounds({ context: { shape: event.element } }); } }); // attach / detach connection function updateConnection(e) { self.updateConnection(e.context); } this.executed(['connection.create', 'connection.move', 'connection.delete', 'connection.reconnect'], ifBpmn(updateConnection)); this.reverted(['connection.create', 'connection.move', 'connection.delete', 'connection.reconnect'], ifBpmn(updateConnection)); // update waypoints function updateConnectionWaypoints(e) { self.updateConnectionWaypoints(e.context.connection); } this.executed(['connection.layout', 'connection.move', 'connection.updateWaypoints'], ifBpmn(updateConnectionWaypoints)); this.reverted(['connection.layout', 'connection.move', 'connection.updateWaypoints'], ifBpmn(updateConnectionWaypoints)); // update conditional/default flows this.executed('connection.reconnect', ifBpmn(function (event) { var context = event.context, connection = context.connection, oldSource = context.oldSource, newSource = context.newSource, connectionBo = (0, _ModelUtil.getBusinessObject)(connection), oldSourceBo = (0, _ModelUtil.getBusinessObject)(oldSource), newSourceBo = (0, _ModelUtil.getBusinessObject)(newSource); // remove condition from connection on reconnect to new source // if new source can NOT have condional sequence flow if (connectionBo.conditionExpression && !(0, _ModelingUtil.isAny)(newSourceBo, ['bpmn:Activity', 'bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway'])) { context.oldConditionExpression = connectionBo.conditionExpression; delete connectionBo.conditionExpression; } // remove default from old source flow on reconnect to new source // if source changed if (oldSource !== newSource && oldSourceBo.default === connectionBo) { context.oldDefault = oldSourceBo.default; delete oldSourceBo.default; } })); this.reverted('connection.reconnect', ifBpmn(function (event) { var context = event.context, connection = context.connection, oldSource = context.oldSource, newSource = context.newSource, connectionBo = (0, _ModelUtil.getBusinessObject)(connection), oldSourceBo = (0, _ModelUtil.getBusinessObject)(oldSource), newSourceBo = (0, _ModelUtil.getBusinessObject)(newSource); // add condition to connection on revert reconnect to new source if (context.oldConditionExpression) { connectionBo.conditionExpression = context.oldConditionExpression; } // add default to old source on revert reconnect to new source if (context.oldDefault) { oldSourceBo.default = context.oldDefault; delete newSourceBo.default; } })); // update attachments function updateAttachment(e) { self.updateAttachment(e.context); } this.executed(['element.updateAttachment'], ifBpmn(updateAttachment)); this.reverted(['element.updateAttachment'], ifBpmn(updateAttachment)); } (0, _inherits.default)(BpmnUpdater, _CommandInterceptor.default); BpmnUpdater.$inject = ['eventBus', 'bpmnFactory', 'connectionDocking', 'translate']; // implementation ////////////////////// BpmnUpdater.prototype.updateAttachment = function (context) { var shape = context.shape, businessObject = shape.businessObject, host = shape.host; businessObject.attachedToRef = host && host.businessObject; }; BpmnUpdater.prototype.updateParent = function (element, oldParent) { // do not update BPMN 2.0 label parent if (element instanceof _model.Label) { return; } // data stores in collaborations are handled separately by DataStoreBehavior if ((0, _ModelUtil.is)(element, 'bpmn:DataStoreReference') && element.parent && (0, _ModelUtil.is)(element.parent, 'bpmn:Collaboration')) { return; } var parentShape = element.parent; var businessObject = element.businessObject, parentBusinessObject = parentShape && parentShape.businessObject, parentDi = parentBusinessObject && parentBusinessObject.di; if ((0, _ModelUtil.is)(element, 'bpmn:FlowNode')) { this.updateFlowNodeRefs(businessObject, parentBusinessObject, oldParent && oldParent.businessObject); } if ((0, _ModelUtil.is)(element, 'bpmn:DataOutputAssociation')) { if (element.source) { parentBusinessObject = element.source.businessObject; } else { parentBusinessObject = null; } } if ((0, _ModelUtil.is)(element, 'bpmn:DataInputAssociation')) { if (element.target) { parentBusinessObject = element.target.businessObject; } else { parentBusinessObject = null; } } this.updateSemanticParent(businessObject, parentBusinessObject); if ((0, _ModelUtil.is)(element, 'bpmn:DataObjectReference') && businessObject.dataObjectRef) { this.updateSemanticParent(businessObject.dataObjectRef, parentBusinessObject); } this.updateDiParent(businessObject.di, parentDi); }; BpmnUpdater.prototype.updateBounds = function (shape) { var di = shape.businessObject.di; var target = shape instanceof _model.Label ? this._getLabel(di) : di; var bounds = target.bounds; if (!bounds) { bounds = this._bpmnFactory.createDiBounds(); target.set('bounds', bounds); } (0, _minDash.assign)(bounds, { x: shape.x, y: shape.y, width: shape.width, height: shape.height }); }; BpmnUpdater.prototype.updateFlowNodeRefs = function (businessObject, newContainment, oldContainment) { if (oldContainment === newContainment) { return; } var oldRefs, newRefs; if ((0, _ModelUtil.is)(oldContainment, 'bpmn:Lane')) { oldRefs = oldContainment.get('flowNodeRef'); (0, _Collections.remove)(oldRefs, businessObject); } if ((0, _ModelUtil.is)(newContainment, 'bpmn:Lane')) { newRefs = newContainment.get('flowNodeRef'); (0, _Collections.add)(newRefs, businessObject); } }; // update existing sourceElement and targetElement di information BpmnUpdater.prototype.updateDiConnection = function (di, newSource, newTarget) { if (di.sourceElement && di.sourceElement.bpmnElement !== newSource) { di.sourceElement = newSource && newSource.di; } if (di.targetElement && di.targetElement.bpmnElement !== newTarget) { di.targetElement = newTarget && newTarget.di; } }; BpmnUpdater.prototype.updateDiParent = function (di, parentDi) { if (parentDi && !(0, _ModelUtil.is)(parentDi, 'bpmndi:BPMNPlane')) { parentDi = parentDi.$parent; } if (di.$parent === parentDi) { return; } var planeElements = (parentDi || di.$parent).get('planeElement'); if (parentDi) { planeElements.push(di); di.$parent = parentDi; } else { (0, _Collections.remove)(planeElements, di); di.$parent = null; } }; function getDefinitions(element) { while (element && !(0, _ModelUtil.is)(element, 'bpmn:Definitions')) { element = element.$parent; } return element; } BpmnUpdater.prototype.getLaneSet = function (container) { var laneSet, laneSets; // bpmn:Lane if ((0, _ModelUtil.is)(container, 'bpmn:Lane')) { laneSet = container.childLaneSet; if (!laneSet) { laneSet = this._bpmnFactory.create('bpmn:LaneSet'); container.childLaneSet = laneSet; laneSet.$parent = container; } return laneSet; } // bpmn:Participant if ((0, _ModelUtil.is)(container, 'bpmn:Participant')) { container = container.processRef; } // bpmn:FlowElementsContainer laneSets = container.get('laneSets'); laneSet = laneSets[0]; if (!laneSet) { laneSet = this._bpmnFactory.create('bpmn:LaneSet'); laneSet.$parent = container; laneSets.push(laneSet); } return laneSet; }; BpmnUpdater.prototype.updateSemanticParent = function (businessObject, newParent, visualParent) { var containment, translate = this._translate; if (businessObject.$parent === newParent) { return; } if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInput') || (0, _ModelUtil.is)(businessObject, 'bpmn:DataOutput')) { if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant') && 'processRef' in newParent) { newParent = newParent.processRef; } // already in correct ioSpecification if ('ioSpecification' in newParent && newParent.ioSpecification === businessObject.$parent) { return; } } if ((0, _ModelUtil.is)(businessObject, 'bpmn:Lane')) { if (newParent) { newParent = this.getLaneSet(newParent); } containment = 'lanes'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowElement')) { if (newParent) { if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant')) { newParent = newParent.processRef; } else if ((0, _ModelUtil.is)(newParent, 'bpmn:Lane')) { do { // unwrap Lane -> LaneSet -> (Lane | FlowElementsContainer) newParent = newParent.$parent.$parent; } while ((0, _ModelUtil.is)(newParent, 'bpmn:Lane')); } } containment = 'flowElements'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:Artifact')) { while (newParent && !(0, _ModelUtil.is)(newParent, 'bpmn:Process') && !(0, _ModelUtil.is)(newParent, 'bpmn:SubProcess') && !(0, _ModelUtil.is)(newParent, 'bpmn:Collaboration')) { if ((0, _ModelUtil.is)(newParent, 'bpmn:Participant')) { newParent = newParent.processRef; break; } else { newParent = newParent.$parent; } } containment = 'artifacts'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:MessageFlow')) { containment = 'messageFlows'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:Participant')) { containment = 'participants'; // make sure the participants process is properly attached / detached // from the XML document var process = businessObject.processRef, definitions; if (process) { definitions = getDefinitions(businessObject.$parent || newParent); if (businessObject.$parent) { (0, _Collections.remove)(definitions.get('rootElements'), process); process.$parent = null; } if (newParent) { (0, _Collections.add)(definitions.get('rootElements'), process); process.$parent = definitions; } } } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataOutputAssociation')) { containment = 'dataOutputAssociations'; } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInputAssociation')) { containment = 'dataInputAssociations'; } if (!containment) { throw new Error(translate('no parent for {element} in {parent}', { element: businessObject.id, parent: newParent.id })); } var children; if (businessObject.$parent) { // remove from old parent children = businessObject.$parent.get(containment); (0, _Collections.remove)(children, businessObject); } if (!newParent) { businessObject.$parent = null; } else { // add to new parent children = newParent.get(containment); children.push(businessObject); businessObject.$parent = newParent; } if (visualParent) { var diChildren = visualParent.get(containment); (0, _Collections.remove)(children, businessObject); if (newParent) { if (!diChildren) { diChildren = []; newParent.set(containment, diChildren); } diChildren.push(businessObject); } } }; BpmnUpdater.prototype.updateConnectionWaypoints = function (connection) { connection.businessObject.di.set('waypoint', this._bpmnFactory.createDiWaypoints(connection.waypoints)); }; BpmnUpdater.prototype.updateConnection = function (context) { var connection = context.connection, businessObject = (0, _ModelUtil.getBusinessObject)(connection), newSource = (0, _ModelUtil.getBusinessObject)(connection.source), newTarget = (0, _ModelUtil.getBusinessObject)(connection.target), visualParent; if (!(0, _ModelUtil.is)(businessObject, 'bpmn:DataAssociation')) { var inverseSet = (0, _ModelUtil.is)(businessObject, 'bpmn:SequenceFlow'); if (businessObject.sourceRef !== newSource) { if (inverseSet) { (0, _Collections.remove)(businessObject.sourceRef && businessObject.sourceRef.get('outgoing'), businessObject); if (newSource && newSource.get('outgoing')) { newSource.get('outgoing').push(businessObject); } } businessObject.sourceRef = newSource; } if (businessObject.targetRef !== newTarget) { if (inverseSet) { (0, _Collections.remove)(businessObject.targetRef && businessObject.targetRef.get('incoming'), businessObject); if (newTarget && newTarget.get('incoming')) { newTarget.get('incoming').push(businessObject); } } businessObject.targetRef = newTarget; } } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataInputAssociation')) { // handle obnoxious isMsome sourceRef businessObject.get('sourceRef')[0] = newSource; visualParent = context.parent || context.newParent || newTarget; this.updateSemanticParent(businessObject, newTarget, visualParent); } else if ((0, _ModelUtil.is)(businessObject, 'bpmn:DataOutputAssociation')) { visualParent = context.parent || context.newParent || newSource; this.updateSemanticParent(businessObject, newSource, visualParent); // targetRef = new target businessObject.targetRef = newTarget; } this.updateConnectionWaypoints(connection); this.updateDiConnection(businessObject.di, newSource, newTarget); }; // helpers ////////////////////// BpmnUpdater.prototype._getLabel = function (di) { if (!di.label) { di.label = this._bpmnFactory.createDiLabel(); } return di.label; }; /** * Make sure the event listener is only called * if the touched element is a BPMN element. * * @param {Function} fn * @return {Function} guarded function */ function ifBpmn(fn) { return function (event) { var context = event.context, element = context.shape || context.connection; if ((0, _ModelUtil.is)(element, 'bpmn:BaseElement')) { fn(event); } }; } },{"../../util/ModelUtil":141,"./util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/model":302,"diagram-js/lib/util/Collections":313,"inherits":347,"min-dash":555}],59:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ElementFactory; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../util/ModelUtil"); var _DiUtil = require("../../util/DiUtil"); var _ElementFactory = _interopRequireDefault(require("diagram-js/lib/core/ElementFactory")); var _LabelUtil = require("../../util/LabelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A bpmn-aware factory for diagram-js shapes */ function ElementFactory(bpmnFactory, moddle, translate) { _ElementFactory.default.call(this); this._bpmnFactory = bpmnFactory; this._moddle = moddle; this._translate = translate; } (0, _inherits.default)(ElementFactory, _ElementFactory.default); ElementFactory.$inject = ['bpmnFactory', 'moddle', 'translate']; ElementFactory.prototype.baseCreate = _ElementFactory.default.prototype.create; ElementFactory.prototype.create = function (elementType, attrs) { // no special magic for labels, // we assume their businessObjects have already been created // and wired via attrs if (elementType === 'label') { return this.baseCreate(elementType, (0, _minDash.assign)({ type: 'label' }, _LabelUtil.DEFAULT_LABEL_SIZE, attrs)); } return this.createBpmnElement(elementType, attrs); }; ElementFactory.prototype.createBpmnElement = function (elementType, attrs) { var size, translate = this._translate; attrs = attrs || {}; var businessObject = attrs.businessObject; if (!businessObject) { if (!attrs.type) { throw new Error(translate('no shape type specified')); } businessObject = this._bpmnFactory.create(attrs.type); } if (!businessObject.di) { if (elementType === 'root') { businessObject.di = this._bpmnFactory.createDiPlane(businessObject, [], { id: businessObject.id + '_di' }); } else if (elementType === 'connection') { businessObject.di = this._bpmnFactory.createDiEdge(businessObject, [], { id: businessObject.id + '_di' }); } else { businessObject.di = this._bpmnFactory.createDiShape(businessObject, {}, { id: businessObject.id + '_di' }); } } if ((0, _ModelUtil.is)(businessObject, 'bpmn:Group')) { attrs = (0, _minDash.assign)({ isFrame: true }, attrs); } if (attrs.di) { (0, _minDash.assign)(businessObject.di, attrs.di); delete attrs.di; } applyAttributes(businessObject, attrs, ['processRef', 'isInterrupting', 'associationDirection', 'isForCompensation']); if (attrs.isExpanded) { applyAttribute(businessObject.di, attrs, 'isExpanded'); } if ((0, _ModelUtil.is)(businessObject, 'bpmn:ExclusiveGateway')) { businessObject.di.isMarkerVisible = true; } var eventDefinitions, newEventDefinition; if (attrs.eventDefinitionType) { eventDefinitions = businessObject.get('eventDefinitions') || []; newEventDefinition = this._bpmnFactory.create(attrs.eventDefinitionType, attrs.eventDefinitionAttrs); if (attrs.eventDefinitionType === 'bpmn:ConditionalEventDefinition') { newEventDefinition.condition = this._bpmnFactory.create('bpmn:FormalExpression'); } eventDefinitions.push(newEventDefinition); newEventDefinition.$parent = businessObject; businessObject.eventDefinitions = eventDefinitions; delete attrs.eventDefinitionType; } size = this._getDefaultSize(businessObject); attrs = (0, _minDash.assign)({ businessObject: businessObject, id: businessObject.id }, size, attrs); return this.baseCreate(elementType, attrs); }; ElementFactory.prototype._getDefaultSize = function (semantic) { if ((0, _ModelUtil.is)(semantic, 'bpmn:SubProcess')) { if ((0, _DiUtil.isExpanded)(semantic)) { return { width: 350, height: 200 }; } else { return { width: 100, height: 80 }; } } if ((0, _ModelUtil.is)(semantic, 'bpmn:Task')) { return { width: 100, height: 80 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Gateway')) { return { width: 50, height: 50 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Event')) { return { width: 36, height: 36 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Participant')) { if ((0, _DiUtil.isExpanded)(semantic)) { return { width: 600, height: 250 }; } else { return { width: 400, height: 60 }; } } if ((0, _ModelUtil.is)(semantic, 'bpmn:Lane')) { return { width: 400, height: 100 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:DataObjectReference')) { return { width: 36, height: 50 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference')) { return { width: 50, height: 50 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:TextAnnotation')) { return { width: 100, height: 30 }; } if ((0, _ModelUtil.is)(semantic, 'bpmn:Group')) { return { width: 300, height: 300 }; } return { width: 100, height: 80 }; }; /** * Create participant. * * @param {boolean|Object} [attrs] attrs * * @returns {djs.model.Shape} */ ElementFactory.prototype.createParticipantShape = function (attrs) { if (!(0, _minDash.isObject)(attrs)) { attrs = { isExpanded: attrs }; } attrs = (0, _minDash.assign)({ type: 'bpmn:Participant' }, attrs || {}); // participants are expanded by default if (attrs.isExpanded !== false) { attrs.processRef = this._bpmnFactory.create('bpmn:Process'); } return this.createShape(attrs); }; // helpers ////////////////////// /** * Apply attributes from a map to the given element, * remove attribute from the map on application. * * @param {Base} element * @param {Object} attrs (in/out map of attributes) * @param {Array<string>} attributeNames name of attributes to apply */ function applyAttributes(element, attrs, attributeNames) { (0, _minDash.forEach)(attributeNames, function (property) { if (attrs[property] !== undefined) { applyAttribute(element, attrs, property); } }); } /** * Apply named property to element and drain it from the attrs * collection. * * @param {Base} element * @param {Object} attrs (in/out map of attributes) * @param {string} attributeName to apply */ function applyAttribute(element, attrs, attributeName) { element[attributeName] = attrs[attributeName]; delete attrs[attributeName]; } },{"../../util/DiUtil":139,"../../util/LabelUtil":140,"../../util/ModelUtil":141,"diagram-js/lib/core/ElementFactory":149,"inherits":347,"min-dash":555}],60:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Modeling; var _inherits = _interopRequireDefault(require("inherits")); var _Modeling = _interopRequireDefault(require("diagram-js/lib/features/modeling/Modeling")); var _UpdatePropertiesHandler = _interopRequireDefault(require("./cmd/UpdatePropertiesHandler")); var _UpdateCanvasRootHandler = _interopRequireDefault(require("./cmd/UpdateCanvasRootHandler")); var _AddLaneHandler = _interopRequireDefault(require("./cmd/AddLaneHandler")); var _SplitLaneHandler = _interopRequireDefault(require("./cmd/SplitLaneHandler")); var _ResizeLaneHandler = _interopRequireDefault(require("./cmd/ResizeLaneHandler")); var _UpdateFlowNodeRefsHandler = _interopRequireDefault(require("./cmd/UpdateFlowNodeRefsHandler")); var _IdClaimHandler = _interopRequireDefault(require("./cmd/IdClaimHandler")); var _SetColorHandler = _interopRequireDefault(require("./cmd/SetColorHandler")); var _UpdateLabelHandler = _interopRequireDefault(require("../label-editing/cmd/UpdateLabelHandler")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN 2.0 modeling features activator * * @param {EventBus} eventBus * @param {ElementFactory} elementFactory * @param {CommandStack} commandStack * @param {BpmnRules} bpmnRules */ function Modeling(eventBus, elementFactory, commandStack, bpmnRules) { _Modeling.default.call(this, eventBus, elementFactory, commandStack); this._bpmnRules = bpmnRules; } (0, _inherits.default)(Modeling, _Modeling.default); Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack', 'bpmnRules']; Modeling.prototype.getHandlers = function () { var handlers = _Modeling.default.prototype.getHandlers.call(this); handlers['element.updateProperties'] = _UpdatePropertiesHandler.default; handlers['canvas.updateRoot'] = _UpdateCanvasRootHandler.default; handlers['lane.add'] = _AddLaneHandler.default; handlers['lane.resize'] = _ResizeLaneHandler.default; handlers['lane.split'] = _SplitLaneHandler.default; handlers['lane.updateRefs'] = _UpdateFlowNodeRefsHandler.default; handlers['id.updateClaim'] = _IdClaimHandler.default; handlers['element.setColor'] = _SetColorHandler.default; handlers['element.updateLabel'] = _UpdateLabelHandler.default; return handlers; }; Modeling.prototype.updateLabel = function (element, newLabel, newBounds, hints) { this._commandStack.execute('element.updateLabel', { element: element, newLabel: newLabel, newBounds: newBounds, hints: hints || {} }); }; Modeling.prototype.connect = function (source, target, attrs, hints) { var bpmnRules = this._bpmnRules; if (!attrs) { attrs = bpmnRules.canConnect(source, target); } if (!attrs) { return; } return this.createConnection(source, target, attrs, source.parent, hints); }; Modeling.prototype.updateProperties = function (element, properties) { this._commandStack.execute('element.updateProperties', { element: element, properties: properties }); }; Modeling.prototype.resizeLane = function (laneShape, newBounds, balanced) { this._commandStack.execute('lane.resize', { shape: laneShape, newBounds: newBounds, balanced: balanced }); }; Modeling.prototype.addLane = function (targetLaneShape, location) { var context = { shape: targetLaneShape, location: location }; this._commandStack.execute('lane.add', context); return context.newLane; }; Modeling.prototype.splitLane = function (targetLane, count) { this._commandStack.execute('lane.split', { shape: targetLane, count: count }); }; /** * Transform the current diagram into a collaboration. * * @return {djs.model.Root} the new root element */ Modeling.prototype.makeCollaboration = function () { var collaborationElement = this._create('root', { type: 'bpmn:Collaboration' }); var context = { newRoot: collaborationElement }; this._commandStack.execute('canvas.updateRoot', context); return collaborationElement; }; Modeling.prototype.updateLaneRefs = function (flowNodeShapes, laneShapes) { this._commandStack.execute('lane.updateRefs', { flowNodeShapes: flowNodeShapes, laneShapes: laneShapes }); }; /** * Transform the current diagram into a process. * * @return {djs.model.Root} the new root element */ Modeling.prototype.makeProcess = function () { var processElement = this._create('root', { type: 'bpmn:Process' }); var context = { newRoot: processElement }; this._commandStack.execute('canvas.updateRoot', context); }; Modeling.prototype.claimId = function (id, moddleElement) { this._commandStack.execute('id.updateClaim', { id: id, element: moddleElement, claiming: true }); }; Modeling.prototype.unclaimId = function (id, moddleElement) { this._commandStack.execute('id.updateClaim', { id: id, element: moddleElement }); }; Modeling.prototype.setColor = function (elements, colors) { if (!elements.length) { elements = [elements]; } this._commandStack.execute('element.setColor', { elements: elements, colors: colors }); }; },{"../label-editing/cmd/UpdateLabelHandler":54,"./cmd/AddLaneHandler":101,"./cmd/IdClaimHandler":102,"./cmd/ResizeLaneHandler":103,"./cmd/SetColorHandler":104,"./cmd/SplitLaneHandler":105,"./cmd/UpdateCanvasRootHandler":106,"./cmd/UpdateFlowNodeRefsHandler":107,"./cmd/UpdatePropertiesHandler":108,"diagram-js/lib/features/modeling/Modeling":222,"inherits":347}],61:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AdaptiveLabelPositioningBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _Math = require("diagram-js/lib/util/Math"); var _LabelUtil = require("../../../util/LabelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var ALIGNMENTS = ['top', 'bottom', 'left', 'right']; var ELEMENT_LABEL_DISTANCE = 10; /** * A component that makes sure that external labels are added * together with respective elements and properly updated (DI wise) * during move. * * @param {EventBus} eventBus * @param {Modeling} modeling */ function AdaptiveLabelPositioningBehavior(eventBus, modeling) { _CommandInterceptor.default.call(this, eventBus); this.postExecuted(['connection.create', 'connection.layout', 'connection.updateWaypoints'], function (event) { var context = event.context, connection = context.connection, source = connection.source, target = connection.target, hints = context.hints || {}; if (hints.createElementsBehavior !== false) { checkLabelAdjustment(source); checkLabelAdjustment(target); } }); this.postExecuted(['label.create'], function (event) { var context = event.context, shape = context.shape, hints = context.hints || {}; if (hints.createElementsBehavior !== false) { checkLabelAdjustment(shape.labelTarget); } }); this.postExecuted(['elements.create'], function (event) { var context = event.context, elements = context.elements, hints = context.hints || {}; if (hints.createElementsBehavior !== false) { elements.forEach(function (element) { checkLabelAdjustment(element); }); } }); function checkLabelAdjustment(element) { // skip non-existing labels if (!(0, _LabelUtil.hasExternalLabel)(element)) { return; } var optimalPosition = getOptimalPosition(element); // no optimal position found if (!optimalPosition) { return; } adjustLabelPosition(element, optimalPosition); } function adjustLabelPosition(element, orientation) { var elementMid = (0, _LayoutUtil.getMid)(element), label = element.label, labelMid = (0, _LayoutUtil.getMid)(label); // ignore labels that are being created if (!label.parent) { return; } var elementTrbl = (0, _LayoutUtil.asTRBL)(element); var newLabelMid; switch (orientation) { case 'top': newLabelMid = { x: elementMid.x, y: elementTrbl.top - ELEMENT_LABEL_DISTANCE - label.height / 2 }; break; case 'left': newLabelMid = { x: elementTrbl.left - ELEMENT_LABEL_DISTANCE - label.width / 2, y: elementMid.y }; break; case 'bottom': newLabelMid = { x: elementMid.x, y: elementTrbl.bottom + ELEMENT_LABEL_DISTANCE + label.height / 2 }; break; case 'right': newLabelMid = { x: elementTrbl.right + ELEMENT_LABEL_DISTANCE + label.width / 2, y: elementMid.y }; break; } var delta = (0, _Math.substract)(newLabelMid, labelMid); modeling.moveShape(label, delta); } } (0, _inherits.default)(AdaptiveLabelPositioningBehavior, _CommandInterceptor.default); AdaptiveLabelPositioningBehavior.$inject = ['eventBus', 'modeling']; // helpers ////////////////////// /** * Return alignments which are taken by a boundary's host element * * @param {Shape} element * * @return {Array<string>} */ function getTakenHostAlignments(element) { var hostElement = element.host, elementMid = (0, _LayoutUtil.getMid)(element), hostOrientation = (0, _LayoutUtil.getOrientation)(elementMid, hostElement); var freeAlignments; // check whether there is a multi-orientation, e.g. 'top-left' if (hostOrientation.indexOf('-') >= 0) { freeAlignments = hostOrientation.split('-'); } else { freeAlignments = [hostOrientation]; } var takenAlignments = ALIGNMENTS.filter(function (alignment) { return freeAlignments.indexOf(alignment) === -1; }); return takenAlignments; } /** * Return alignments which are taken by related connections * * @param {Shape} element * * @return {Array<string>} */ function getTakenConnectionAlignments(element) { var elementMid = (0, _LayoutUtil.getMid)(element); var takenAlignments = [].concat(element.incoming.map(function (c) { return c.waypoints[c.waypoints.length - 2]; }), element.outgoing.map(function (c) { return c.waypoints[1]; })).map(function (point) { return getApproximateOrientation(elementMid, point); }); return takenAlignments; } /** * Return the optimal label position around an element * or _undefined_, if none was found. * * @param {Shape} element * * @return {string} positioning identifier */ function getOptimalPosition(element) { var labelMid = (0, _LayoutUtil.getMid)(element.label); var elementMid = (0, _LayoutUtil.getMid)(element); var labelOrientation = getApproximateOrientation(elementMid, labelMid); if (!isAligned(labelOrientation)) { return; } var takenAlignments = getTakenConnectionAlignments(element); if (element.host) { var takenHostAlignments = getTakenHostAlignments(element); takenAlignments = takenAlignments.concat(takenHostAlignments); } var freeAlignments = ALIGNMENTS.filter(function (alignment) { return takenAlignments.indexOf(alignment) === -1; }); // NOTHING TO DO; label already aligned a.O.K. if (freeAlignments.indexOf(labelOrientation) !== -1) { return; } return freeAlignments[0]; } function getApproximateOrientation(p0, p1) { return (0, _LayoutUtil.getOrientation)(p1, p0, 5); } function isAligned(orientation) { return ALIGNMENTS.indexOf(orientation) !== -1; } },{"../../../util/LabelUtil":140,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Math":322,"inherits":347}],62:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AppendBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function AppendBehavior(eventBus, elementFactory, bpmnRules) { _CommandInterceptor.default.call(this, eventBus); // assign correct shape position unless already set this.preExecute('shape.append', function (context) { var source = context.source, shape = context.shape; if (!context.position) { if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) { context.position = { x: source.x + source.width / 2 + 75, y: source.y - 50 - shape.height / 2 }; } else { context.position = { x: source.x + source.width + 80 + shape.width / 2, y: source.y + source.height / 2 }; } } }, true); } (0, _inherits.default)(AppendBehavior, _CommandInterceptor.default); AppendBehavior.$inject = ['eventBus', 'elementFactory', 'bpmnRules']; },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],63:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AssociationBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function AssociationBehavior(injector, modeling) { injector.invoke(_CommandInterceptor.default, this); this.postExecute('shape.move', function (context) { var newParent = context.newParent, shape = context.shape; var associations = (0, _minDash.filter)(shape.incoming.concat(shape.outgoing), function (connection) { return (0, _ModelUtil.is)(connection, 'bpmn:Association'); }); (0, _minDash.forEach)(associations, function (association) { modeling.moveConnection(association, { x: 0, y: 0 }, newParent); }); }, true); } (0, _inherits.default)(AssociationBehavior, _CommandInterceptor.default); AssociationBehavior.$inject = ['injector', 'modeling']; },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],64:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AttachEventBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); var _LabelUtil = require("../../../util/LabelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; /** * Replace intermediate event with boundary event when creating or moving results in attached event. */ function AttachEventBehavior(bpmnReplace, injector) { injector.invoke(_CommandInterceptor.default, this); this._bpmnReplace = bpmnReplace; var self = this; this.postExecuted('elements.create', LOW_PRIORITY, function (context) { var elements = context.elements; elements = elements.filter(function (shape) { var host = shape.host; return shouldReplace(shape, host); }); if (elements.length !== 1) { return; } elements.map(function (element) { return elements.indexOf(element); }).forEach(function (index) { var host = elements[index]; context.elements[index] = self.replaceShape(elements[index], host); }); }, true); this.preExecute('elements.move', LOW_PRIORITY, function (context) { var shapes = context.shapes, host = context.newHost; if (shapes.length !== 1) { return; } var shape = shapes[0]; if (shouldReplace(shape, host)) { context.shapes = [self.replaceShape(shape, host)]; } }, true); } AttachEventBehavior.$inject = ['bpmnReplace', 'injector']; (0, _inherits.default)(AttachEventBehavior, _CommandInterceptor.default); AttachEventBehavior.prototype.replaceShape = function (shape, host) { var eventDefinition = getEventDefinition(shape); var boundaryEvent = { type: 'bpmn:BoundaryEvent', host: host }; if (eventDefinition) { boundaryEvent.eventDefinitionType = eventDefinition.$type; } return this._bpmnReplace.replaceElement(shape, boundaryEvent, { layoutConnection: false }); }; // helpers ////////// function getEventDefinition(element) { var businessObject = (0, _ModelUtil.getBusinessObject)(element), eventDefinitions = businessObject.eventDefinitions; return eventDefinitions && eventDefinitions[0]; } function shouldReplace(shape, host) { return !(0, _LabelUtil.isLabel)(shape) && (0, _ModelingUtil.isAny)(shape, ['bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent']) && !!host; } },{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],65:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BoundaryEventBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific boundary event behavior */ function BoundaryEventBehavior(eventBus, modeling) { _CommandInterceptor.default.call(this, eventBus); function getBoundaryEvents(element) { return (0, _minDash.filter)(element.attachers, function (attacher) { return (0, _ModelUtil.is)(attacher, 'bpmn:BoundaryEvent'); }); } // remove after connecting to event-based gateway this.postExecute('connection.create', function (event) { var source = event.context.source, target = event.context.target, boundaryEvents = getBoundaryEvents(target); if ((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && (0, _ModelUtil.is)(target, 'bpmn:ReceiveTask') && boundaryEvents.length > 0) { modeling.removeElements(boundaryEvents); } }); // remove after replacing connected gateway with event-based gateway this.postExecute('connection.reconnect', function (event) { var oldSource = event.context.oldSource, newSource = event.context.newSource; if ((0, _ModelUtil.is)(oldSource, 'bpmn:Gateway') && (0, _ModelUtil.is)(newSource, 'bpmn:EventBasedGateway')) { (0, _minDash.forEach)(newSource.outgoing, function (connection) { var target = connection.target, attachedboundaryEvents = getBoundaryEvents(target); if ((0, _ModelUtil.is)(target, 'bpmn:ReceiveTask') && attachedboundaryEvents.length > 0) { modeling.removeElements(attachedboundaryEvents); } }); } }); } BoundaryEventBehavior.$inject = ['eventBus', 'modeling']; (0, _inherits.default)(BoundaryEventBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],66:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelingUtil = require("../util/ModelingUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function CreateBehavior(injector) { injector.invoke(_CommandInterceptor.default, this); this.preExecute('shape.create', 1500, function (event) { var context = event.context, parent = context.parent, shape = context.shape; if ((0, _ModelUtil.is)(parent, 'bpmn:Lane') && !(0, _ModelUtil.is)(shape, 'bpmn:Lane')) { context.parent = (0, _ModelingUtil.getParent)(parent, 'bpmn:Participant'); } }); } CreateBehavior.$inject = ['injector']; (0, _inherits.default)(CreateBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],67:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateDataObjectBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific create data object behavior */ function CreateDataObjectBehavior(eventBus, bpmnFactory, moddle) { _CommandInterceptor.default.call(this, eventBus); this.preExecute('shape.create', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:DataObjectReference') && shape.type !== 'label') { // create a DataObject every time a DataObjectReference is created var dataObject = bpmnFactory.create('bpmn:DataObject'); // set the reference to the DataObject shape.businessObject.dataObjectRef = dataObject; } }); } CreateDataObjectBehavior.$inject = ['eventBus', 'bpmnFactory', 'moddle']; (0, _inherits.default)(CreateDataObjectBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],68:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateParticipantBehavior; exports.PARTICIPANT_BORDER_WIDTH = void 0; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _LabelUtil = require("../../../util/LabelUtil"); var _Elements = require("diagram-js/lib/util/Elements"); var _minDash = require("min-dash"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HORIZONTAL_PARTICIPANT_PADDING = 20, VERTICAL_PARTICIPANT_PADDING = 20; var PARTICIPANT_BORDER_WIDTH = 30; exports.PARTICIPANT_BORDER_WIDTH = PARTICIPANT_BORDER_WIDTH; var HIGH_PRIORITY = 2000; /** * BPMN-specific behavior for creating participants. */ function CreateParticipantBehavior(canvas, eventBus, modeling) { _CommandInterceptor.default.call(this, eventBus); // fit participant eventBus.on(['create.start', 'shape.move.start'], HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(); if (!(0, _ModelUtil.is)(shape, 'bpmn:Participant') || !(0, _ModelUtil.is)(rootElement, 'bpmn:Process') || !rootElement.children.length) { return; } // ignore connections, groups and labels var children = rootElement.children.filter(function (element) { return !(0, _ModelUtil.is)(element, 'bpmn:Group') && !(0, _LabelUtil.isLabel)(element) && !isConnection(element); }); // ensure for available children to calculate bounds if (!children.length) { return; } var childrenBBox = (0, _Elements.getBBox)(children); var participantBounds = getParticipantBounds(shape, childrenBBox); // assign width and height (0, _minDash.assign)(shape, participantBounds); // assign create constraints context.createConstraints = getParticipantCreateConstraints(shape, childrenBBox); }); // force hovering process when creating first participant eventBus.on('create.start', HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(), rootElementGfx = canvas.getGraphics(rootElement); function ensureHoveringProcess(event) { event.element = rootElement; event.gfx = rootElementGfx; } if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(rootElement, 'bpmn:Process')) { eventBus.on('element.hover', HIGH_PRIORITY, ensureHoveringProcess); eventBus.once('create.cleanup', function () { eventBus.off('element.hover', ensureHoveringProcess); }); } }); function ensureCollaboration(context) { var parent = context.parent, collaboration; var rootElement = canvas.getRootElement(); if ((0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) { collaboration = rootElement; } else { // update root element by making collaboration collaboration = modeling.makeCollaboration(); // re-use process when creating first participant context.process = parent; } context.parent = collaboration; } // turn process into collaboration before adding participant this.preExecute('shape.create', function (context) { var parent = context.parent, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _ModelUtil.is)(parent, 'bpmn:Process')) { ensureCollaboration(context); } }, true); this.execute('shape.create', function (context) { var process = context.process, shape = context.shape; if (process) { context.oldProcessRef = shape.businessObject.processRef; // re-use process when creating first participant shape.businessObject.processRef = process.businessObject; } }, true); this.revert('shape.create', function (context) { var process = context.process, shape = context.shape; if (process) { // re-use process when creating first participant shape.businessObject.processRef = context.oldProcessRef; } }, true); this.postExecute('shape.create', function (context) { var process = context.process, shape = context.shape; if (process) { // move children from process to participant var processChildren = process.children.slice(); modeling.moveElements(processChildren, { x: 0, y: 0 }, shape); } }, true); // turn process into collaboration when creating participants this.preExecute('elements.create', HIGH_PRIORITY, function (context) { var elements = context.elements, parent = context.parent, participant; var hasParticipants = findParticipant(elements); if (hasParticipants && (0, _ModelUtil.is)(parent, 'bpmn:Process')) { ensureCollaboration(context); participant = findParticipant(elements); context.oldProcessRef = participant.businessObject.processRef; // re-use process when creating first participant participant.businessObject.processRef = parent.businessObject; } }, true); this.revert('elements.create', function (context) { var elements = context.elements, process = context.process, participant; if (process) { participant = findParticipant(elements); // re-use process when creating first participant participant.businessObject.processRef = context.oldProcessRef; } }, true); this.postExecute('elements.create', function (context) { var elements = context.elements, process = context.process, participant; if (process) { participant = findParticipant(elements); // move children from process to first participant var processChildren = process.children.slice(); modeling.moveElements(processChildren, { x: 0, y: 0 }, participant); } }, true); } CreateParticipantBehavior.$inject = ['canvas', 'eventBus', 'modeling']; (0, _inherits.default)(CreateParticipantBehavior, _CommandInterceptor.default); // helpers ////////// function getParticipantBounds(shape, childrenBBox) { childrenBBox = { width: childrenBBox.width + HORIZONTAL_PARTICIPANT_PADDING * 2 + PARTICIPANT_BORDER_WIDTH, height: childrenBBox.height + VERTICAL_PARTICIPANT_PADDING * 2 }; var width = Math.max(shape.width, childrenBBox.width), height = Math.max(shape.height, childrenBBox.height); return { x: -width / 2, y: -height / 2, width: width, height: height }; } function getParticipantCreateConstraints(shape, childrenBBox) { childrenBBox = (0, _LayoutUtil.asTRBL)(childrenBBox); return { bottom: childrenBBox.top + shape.height / 2 - VERTICAL_PARTICIPANT_PADDING, left: childrenBBox.right - shape.width / 2 + HORIZONTAL_PARTICIPANT_PADDING, top: childrenBBox.bottom - shape.height / 2 + VERTICAL_PARTICIPANT_PADDING, right: childrenBBox.left + shape.width / 2 - HORIZONTAL_PARTICIPANT_PADDING - PARTICIPANT_BORDER_WIDTH }; } function isConnection(element) { return !!element.waypoints; } function findParticipant(elements) { return (0, _minDash.find)(elements, function (element) { return (0, _ModelUtil.is)(element, 'bpmn:Participant'); }); } },{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Elements":315,"inherits":347,"min-dash":555}],69:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DataInputAssociationBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _Collections = require("diagram-js/lib/util/Collections"); var _minDash = require("min-dash"); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var TARGET_REF_PLACEHOLDER_NAME = '__targetRef_placeholder'; /** * This behavior makes sure we always set a fake * DataInputAssociation#targetRef as demanded by the BPMN 2.0 * XSD schema. * * The reference is set to a bpmn:Property{ name: '__targetRef_placeholder' } * which is created on the fly and cleaned up afterwards if not needed * anymore. * * @param {EventBus} eventBus * @param {BpmnFactory} bpmnFactory */ function DataInputAssociationBehavior(eventBus, bpmnFactory) { _CommandInterceptor.default.call(this, eventBus); this.executed(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnect'], ifDataInputAssociation(fixTargetRef)); this.reverted(['connection.create', 'connection.delete', 'connection.move', 'connection.reconnect'], ifDataInputAssociation(fixTargetRef)); function usesTargetRef(element, targetRef, removedConnection) { var inputAssociations = element.get('dataInputAssociations'); return (0, _minDash.find)(inputAssociations, function (association) { return association !== removedConnection && association.targetRef === targetRef; }); } function getTargetRef(element, create) { var properties = element.get('properties'); var targetRefProp = (0, _minDash.find)(properties, function (p) { return p.name === TARGET_REF_PLACEHOLDER_NAME; }); if (!targetRefProp && create) { targetRefProp = bpmnFactory.create('bpmn:Property', { name: TARGET_REF_PLACEHOLDER_NAME }); (0, _Collections.add)(properties, targetRefProp); } return targetRefProp; } function cleanupTargetRef(element, connection) { var targetRefProp = getTargetRef(element); if (!targetRefProp) { return; } if (!usesTargetRef(element, targetRefProp, connection)) { (0, _Collections.remove)(element.get('properties'), targetRefProp); } } /** * Make sure targetRef is set to a valid property or * `null` if the connection is detached. * * @param {Event} event */ function fixTargetRef(event) { var context = event.context, connection = context.connection, connectionBo = connection.businessObject, target = connection.target, targetBo = target && target.businessObject, newTarget = context.newTarget, newTargetBo = newTarget && newTarget.businessObject, oldTarget = context.oldTarget || context.target, oldTargetBo = oldTarget && oldTarget.businessObject; var dataAssociation = connection.businessObject, targetRefProp; if (oldTargetBo && oldTargetBo !== targetBo) { cleanupTargetRef(oldTargetBo, connectionBo); } if (newTargetBo && newTargetBo !== targetBo) { cleanupTargetRef(newTargetBo, connectionBo); } if (targetBo) { targetRefProp = getTargetRef(targetBo, true); dataAssociation.targetRef = targetRefProp; } else { dataAssociation.targetRef = null; } } } DataInputAssociationBehavior.$inject = ['eventBus', 'bpmnFactory']; (0, _inherits.default)(DataInputAssociationBehavior, _CommandInterceptor.default); /** * Only call the given function when the event * touches a bpmn:DataInputAssociation. * * @param {Function} fn * @return {Function} */ function ifDataInputAssociation(fn) { return function (event) { var context = event.context, connection = context.connection; if ((0, _ModelUtil.is)(connection, 'bpmn:DataInputAssociation')) { return fn(event); } }; } },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Collections":313,"inherits":347,"min-dash":555}],70:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DataStoreBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); var _UpdateSemanticParentHandler = _interopRequireDefault(require("../cmd/UpdateSemanticParentHandler")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific data store behavior */ function DataStoreBehavior(canvas, commandStack, elementRegistry, eventBus) { _CommandInterceptor.default.call(this, eventBus); commandStack.registerHandler('dataStore.updateContainment', _UpdateSemanticParentHandler.default); function getFirstParticipant() { return elementRegistry.filter(function (element) { return (0, _ModelUtil.is)(element, 'bpmn:Participant'); })[0]; } function getDataStores(element) { return element.children.filter(function (child) { return (0, _ModelUtil.is)(child, 'bpmn:DataStoreReference') && !child.labelTarget; }); } function updateDataStoreParent(dataStore, newDataStoreParent) { var dataStoreBo = dataStore.businessObject || dataStore; newDataStoreParent = newDataStoreParent || getFirstParticipant(); if (newDataStoreParent) { var newDataStoreParentBo = newDataStoreParent.businessObject || newDataStoreParent; commandStack.execute('dataStore.updateContainment', { dataStoreBo: dataStoreBo, newSemanticParent: newDataStoreParentBo.processRef || newDataStoreParentBo, newDiParent: newDataStoreParentBo.di }); } } // disable auto-resize for data stores this.preExecute('shape.create', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label') { if (!context.hints) { context.hints = {}; } // prevent auto resizing context.hints.autoResize = false; } }); // disable auto-resize for data stores this.preExecute('elements.move', function (event) { var context = event.context, shapes = context.shapes; var dataStoreReferences = shapes.filter(function (shape) { return (0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference'); }); if (dataStoreReferences.length) { if (!context.hints) { context.hints = {}; } // prevent auto resizing for data store references context.hints.autoResize = shapes.filter(function (shape) { return !(0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference'); }); } }); // update parent on data store created this.postExecute('shape.create', function (event) { var context = event.context, shape = context.shape, parent = shape.parent; if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label' && (0, _ModelUtil.is)(parent, 'bpmn:Collaboration')) { updateDataStoreParent(shape); } }); // update parent on data store moved this.postExecute('shape.move', function (event) { var context = event.context, shape = context.shape, oldParent = context.oldParent, parent = shape.parent; if ((0, _ModelUtil.is)(oldParent, 'bpmn:Collaboration')) { // do nothing if not necessary return; } if ((0, _ModelUtil.is)(shape, 'bpmn:DataStoreReference') && shape.type !== 'label' && (0, _ModelUtil.is)(parent, 'bpmn:Collaboration')) { var participant = (0, _ModelUtil.is)(oldParent, 'bpmn:Participant') ? oldParent : getAncestor(oldParent, 'bpmn:Participant'); updateDataStoreParent(shape, participant); } }); // update data store parents on participant or subprocess deleted this.postExecute('shape.delete', function (event) { var context = event.context, shape = context.shape, rootElement = canvas.getRootElement(); if ((0, _ModelingUtil.isAny)(shape, ['bpmn:Participant', 'bpmn:SubProcess']) && (0, _ModelUtil.is)(rootElement, 'bpmn:Collaboration')) { getDataStores(rootElement).filter(function (dataStore) { return isDescendant(dataStore, shape); }).forEach(function (dataStore) { updateDataStoreParent(dataStore); }); } }); // update data store parents on collaboration -> process this.postExecute('canvas.updateRoot', function (event) { var context = event.context, oldRoot = context.oldRoot, newRoot = context.newRoot; var dataStores = getDataStores(oldRoot); dataStores.forEach(function (dataStore) { if ((0, _ModelUtil.is)(newRoot, 'bpmn:Process')) { updateDataStoreParent(dataStore, newRoot); } }); }); } DataStoreBehavior.$inject = ['canvas', 'commandStack', 'elementRegistry', 'eventBus']; (0, _inherits.default)(DataStoreBehavior, _CommandInterceptor.default); // helpers ////////// function isDescendant(descendant, ancestor) { var descendantBo = descendant.businessObject || descendant, ancestorBo = ancestor.businessObject || ancestor; while (descendantBo.$parent) { if (descendantBo.$parent === ancestorBo.processRef || ancestorBo) { return true; } descendantBo = descendantBo.$parent; } return false; } function getAncestor(element, type) { while (element.parent) { if ((0, _ModelUtil.is)(element.parent, type)) { return element.parent; } element = element.parent; } } },{"../../../util/ModelUtil":141,"../cmd/UpdateSemanticParentHandler":109,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],71:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteLaneBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _LaneUtil = require("../util/LaneUtil"); var _Elements = require("diagram-js/lib/util/Elements"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; /** * BPMN specific delete lane behavior */ function DeleteLaneBehavior(eventBus, modeling, spaceTool) { _CommandInterceptor.default.call(this, eventBus); function compensateLaneDelete(shape, oldParent) { var siblings = (0, _LaneUtil.getChildLanes)(oldParent); var topAffected = []; var bottomAffected = []; (0, _Elements.eachElement)(siblings, function (element) { if (element.y > shape.y) { bottomAffected.push(element); } else { topAffected.push(element); } return element.children; }); if (!siblings.length) { return; } var offset; if (bottomAffected.length && topAffected.length) { offset = shape.height / 2; } else { offset = shape.height; } var topAdjustments, bottomAdjustments; if (topAffected.length) { topAdjustments = spaceTool.calculateAdjustments(topAffected, 'y', offset, shape.y - 10); spaceTool.makeSpace(topAdjustments.movingShapes, topAdjustments.resizingShapes, { x: 0, y: offset }, 's'); } if (bottomAffected.length) { bottomAdjustments = spaceTool.calculateAdjustments(bottomAffected, 'y', -offset, shape.y + shape.height + 10); spaceTool.makeSpace(bottomAdjustments.movingShapes, bottomAdjustments.resizingShapes, { x: 0, y: -offset }, 'n'); } } /** * Adjust sizes of other lanes after lane deletion */ this.postExecuted('shape.delete', LOW_PRIORITY, function (event) { var context = event.context, hints = context.hints, shape = context.shape, oldParent = context.oldParent; // only compensate lane deletes if (!(0, _ModelUtil.is)(shape, 'bpmn:Lane')) { return; } // compensate root deletes only if (hints && hints.nested) { return; } compensateLaneDelete(shape, oldParent); }); } DeleteLaneBehavior.$inject = ['eventBus', 'modeling', 'spaceTool']; (0, _inherits.default)(DeleteLaneBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Elements":315,"inherits":347}],72:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DetachEventBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _LabelUtil = require("../../../util/LabelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; /** * Replace boundary event with intermediate event when creating or moving results in detached event. */ function DetachEventBehavior(bpmnReplace, injector) { injector.invoke(_CommandInterceptor.default, this); this._bpmnReplace = bpmnReplace; var self = this; this.postExecuted('elements.create', LOW_PRIORITY, function (context) { var elements = context.elements; elements.filter(function (shape) { var host = shape.host; return shouldReplace(shape, host); }).map(function (shape) { return elements.indexOf(shape); }).forEach(function (index) { context.elements[index] = self.replaceShape(elements[index]); }); }, true); this.preExecute('elements.move', LOW_PRIORITY, function (context) { var shapes = context.shapes, newHost = context.newHost; shapes.forEach(function (shape, index) { var host = shape.host; if (shouldReplace(shape, includes(shapes, host) ? host : newHost)) { shapes[index] = self.replaceShape(shape); } }); }, true); } DetachEventBehavior.$inject = ['bpmnReplace', 'injector']; (0, _inherits.default)(DetachEventBehavior, _CommandInterceptor.default); DetachEventBehavior.prototype.replaceShape = function (shape) { var eventDefinition = getEventDefinition(shape), intermediateEvent; if (eventDefinition) { intermediateEvent = { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: eventDefinition.$type }; } else { intermediateEvent = { type: 'bpmn:IntermediateThrowEvent' }; } return this._bpmnReplace.replaceElement(shape, intermediateEvent, { layoutConnection: false }); }; // helpers ////////// function getEventDefinition(element) { var businessObject = (0, _ModelUtil.getBusinessObject)(element), eventDefinitions = businessObject.eventDefinitions; return eventDefinitions && eventDefinitions[0]; } function shouldReplace(shape, host) { return !(0, _LabelUtil.isLabel)(shape) && (0, _ModelUtil.is)(shape, 'bpmn:BoundaryEvent') && !host; } function includes(array, item) { return array.indexOf(item) !== -1; } },{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],73:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DropOnFlowBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _LineIntersection = require("diagram-js/lib/util/LineIntersection"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function DropOnFlowBehavior(eventBus, bpmnRules, modeling) { _CommandInterceptor.default.call(this, eventBus); /** * Reconnect start / end of a connection after * dropping an element on a flow. */ function insertShape(shape, targetFlow, positionOrBounds) { var waypoints = targetFlow.waypoints, waypointsBefore, waypointsAfter, dockingPoint, source, target, incomingConnection, outgoingConnection, oldOutgoing = shape.outgoing.slice(), oldIncoming = shape.incoming.slice(); var mid; if ((0, _minDash.isNumber)(positionOrBounds.width)) { mid = (0, _LayoutUtil.getMid)(positionOrBounds); } else { mid = positionOrBounds; } var intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, mid); if (intersection) { waypointsBefore = waypoints.slice(0, intersection.index); waypointsAfter = waypoints.slice(intersection.index + (intersection.bendpoint ? 1 : 0)); // due to inaccuracy intersection might have been found if (!waypointsBefore.length || !waypointsAfter.length) { return; } dockingPoint = intersection.bendpoint ? waypoints[intersection.index] : mid; // if last waypointBefore is inside shape's bounds, ignore docking point if (!isPointInsideBBox(shape, waypointsBefore[waypointsBefore.length - 1])) { waypointsBefore.push(copy(dockingPoint)); } // if first waypointAfter is inside shape's bounds, ignore docking point if (!isPointInsideBBox(shape, waypointsAfter[0])) { waypointsAfter.unshift(copy(dockingPoint)); } } source = targetFlow.source; target = targetFlow.target; if (bpmnRules.canConnect(source, shape, targetFlow)) { // reconnect source -> inserted shape modeling.reconnectEnd(targetFlow, shape, waypointsBefore || mid); incomingConnection = targetFlow; } if (bpmnRules.canConnect(shape, target, targetFlow)) { if (!incomingConnection) { // reconnect inserted shape -> end modeling.reconnectStart(targetFlow, shape, waypointsAfter || mid); outgoingConnection = targetFlow; } else { outgoingConnection = modeling.connect(shape, target, { type: targetFlow.type, waypoints: waypointsAfter }); } } var duplicateConnections = [].concat(incomingConnection && (0, _minDash.filter)(oldIncoming, function (connection) { return connection.source === incomingConnection.source; }) || [], outgoingConnection && (0, _minDash.filter)(oldOutgoing, function (connection) { return connection.target === outgoingConnection.target; }) || []); if (duplicateConnections.length) { modeling.removeElements(duplicateConnections); } } this.preExecute('elements.move', function (context) { var newParent = context.newParent, shapes = context.shapes, delta = context.delta, shape = shapes[0]; if (!shape || !newParent) { return; } // if the new parent is a connection, // change it to the new parent's parent if (newParent && newParent.waypoints) { context.newParent = newParent = newParent.parent; } var shapeMid = (0, _LayoutUtil.getMid)(shape); var newShapeMid = { x: shapeMid.x + delta.x, y: shapeMid.y + delta.y }; // find a connection which intersects with the // element's mid point var connection = (0, _minDash.find)(newParent.children, function (element) { var canInsert = bpmnRules.canInsert(shapes, element); return canInsert && (0, _LineIntersection.getApproxIntersection)(element.waypoints, newShapeMid); }); if (connection) { context.targetFlow = connection; context.position = newShapeMid; } }, true); this.postExecuted('elements.move', function (context) { var shapes = context.shapes, targetFlow = context.targetFlow, position = context.position; if (targetFlow) { insertShape(shapes[0], targetFlow, position); } }, true); this.preExecute('shape.create', function (context) { var parent = context.parent, shape = context.shape; if (bpmnRules.canInsert(shape, parent)) { context.targetFlow = parent; context.parent = parent.parent; } }, true); this.postExecuted('shape.create', function (context) { var shape = context.shape, targetFlow = context.targetFlow, positionOrBounds = context.position; if (targetFlow) { insertShape(shape, targetFlow, positionOrBounds); } }, true); } (0, _inherits.default)(DropOnFlowBehavior, _CommandInterceptor.default); DropOnFlowBehavior.$inject = ['eventBus', 'bpmnRules', 'modeling']; // helpers ///////////////////// function isPointInsideBBox(bbox, point) { var x = point.x, y = point.y; return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height; } function copy(obj) { return (0, _minDash.assign)({}, obj); } },{"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/LineIntersection":321,"inherits":347,"min-dash":555}],74:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = EventBasedGatewayBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function EventBasedGatewayBehavior(eventBus, modeling) { _CommandInterceptor.default.call(this, eventBus); /** * Remove existing sequence flows of event-based target before connecting * from event-based gateway. */ this.preExecuted('connection.create', function (event) { var context = event.context, source = context.source, target = context.target, existingIncomingConnections = target.incoming.slice(); if (context.hints && context.hints.createElementsBehavior === false) { return; } if ((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && target.incoming.length) { existingIncomingConnections.filter(isSequenceFlow).forEach(function (sequenceFlow) { modeling.removeConnection(sequenceFlow); }); } }); /** * After replacing shape with event-based gateway, remove incoming sequence * flows of event-based targets which do not belong to event-based gateway * source. */ this.preExecuted('shape.replace', function (event) { var newShape = event.context.newShape, newShapeTargets, newShapeTargetsIncomingSequenceFlows; if (!(0, _ModelUtil.is)(newShape, 'bpmn:EventBasedGateway')) { return; } newShapeTargets = newShape.outgoing.filter(isSequenceFlow).map(function (sequenceFlow) { return sequenceFlow.target; }); newShapeTargetsIncomingSequenceFlows = newShapeTargets.reduce(function (sequenceFlows, target) { var incomingSequenceFlows = target.incoming.filter(isSequenceFlow); return sequenceFlows.concat(incomingSequenceFlows); }, []); newShapeTargetsIncomingSequenceFlows.forEach(function (sequenceFlow) { if (sequenceFlow.source !== newShape) { modeling.removeConnection(sequenceFlow); } }); }); } EventBasedGatewayBehavior.$inject = ['eventBus', 'modeling']; (0, _inherits.default)(EventBasedGatewayBehavior, _CommandInterceptor.default); // helpers ////////////////////// function isSequenceFlow(connection) { return (0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow'); } },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],75:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = FixHoverBehavior; var _LaneUtil = require("../util/LaneUtil"); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); var HIGH_PRIORITY = 1500; var HIGHEST_PRIORITY = 2000; /** * Correct hover targets in certain situations to improve diagram interaction. * * @param {ElementRegistry} elementRegistry * @param {EventBus} eventBus * @param {Canvas} canvas */ function FixHoverBehavior(elementRegistry, eventBus, canvas) { eventBus.on(['create.hover', 'create.move', 'create.end', 'shape.move.hover', 'shape.move.move', 'shape.move.end'], HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape || event.shape, hover = event.hover; // ensure elements are not dropped onto a bpmn:Lane but onto // the underlying bpmn:Participant if ((0, _ModelUtil.is)(hover, 'bpmn:Lane') && !(0, _ModelingUtil.isAny)(shape, ['bpmn:Lane', 'bpmn:Participant'])) { event.hover = (0, _LaneUtil.getLanesRoot)(hover); event.hoverGfx = elementRegistry.getGraphics(event.hover); } var rootElement = canvas.getRootElement(); // ensure bpmn:Group and label elements are dropped // always onto the root if (hover !== rootElement && (shape.labelTarget || (0, _ModelUtil.is)(shape, 'bpmn:Group'))) { event.hover = rootElement; event.hoverGfx = elementRegistry.getGraphics(event.hover); } }); eventBus.on(['connect.hover', 'connect.out', 'connect.end', 'connect.cleanup', 'global-connect.hover', 'global-connect.out', 'global-connect.end', 'global-connect.cleanup'], HIGH_PRIORITY, function (event) { var hover = event.hover; // ensure connections start/end on bpmn:Participant, // not the underlying bpmn:Lane if ((0, _ModelUtil.is)(hover, 'bpmn:Lane')) { event.hover = (0, _LaneUtil.getLanesRoot)(hover) || hover; event.hoverGfx = elementRegistry.getGraphics(event.hover); } }); eventBus.on(['bendpoint.move.hover'], HIGH_PRIORITY, function (event) { var context = event.context, hover = event.hover, type = context.type; // ensure reconnect start/end on bpmn:Participant, // not the underlying bpmn:Lane if ((0, _ModelUtil.is)(hover, 'bpmn:Lane') && /reconnect/.test(type)) { event.hover = (0, _LaneUtil.getLanesRoot)(hover) || hover; event.hoverGfx = elementRegistry.getGraphics(event.hover); } }); eventBus.on(['connect.start'], HIGH_PRIORITY, function (event) { var context = event.context, start = context.start; // ensure connect start on bpmn:Participant, // not the underlying bpmn:Lane if ((0, _ModelUtil.is)(start, 'bpmn:Lane')) { context.start = (0, _LaneUtil.getLanesRoot)(start) || start; } }); // allow movement of participants from lanes eventBus.on('shape.move.start', HIGHEST_PRIORITY, function (event) { var shape = event.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) { event.shape = (0, _LaneUtil.getLanesRoot)(shape) || shape; } }); } FixHoverBehavior.$inject = ['elementRegistry', 'eventBus', 'canvas']; },{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"../util/ModelingUtil":112}],76:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = GroupBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _Collections = require("diagram-js/lib/util/Collections"); var _ModelUtil = require("../../../util/ModelUtil"); var _CategoryUtil = require("./util/CategoryUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGH_PRIORITY = 2000; /** * BPMN specific Group behavior */ function GroupBehavior(bpmnFactory, canvas, elementRegistry, eventBus, injector, moddleCopy) { injector.invoke(_CommandInterceptor.default, this); /** * Gets process definitions * * @return {ModdleElement} definitions */ function getDefinitions() { var rootElement = canvas.getRootElement(), businessObject = (0, _ModelUtil.getBusinessObject)(rootElement); return businessObject.$parent; } /** * Removes a referenced category value for a given group shape * * @param {djs.model.Shape} shape */ function removeReferencedCategoryValue(shape) { var businessObject = (0, _ModelUtil.getBusinessObject)(shape), categoryValue = businessObject.categoryValueRef; if (!categoryValue) { return; } var category = categoryValue.$parent; if (!categoryValue) { return; } (0, _Collections.remove)(category.categoryValue, categoryValue); // cleanup category if it is empty if (category && !category.categoryValue.length) { removeCategory(category); } } /** * Removes a given category from the definitions * * @param {ModdleElement} category */ function removeCategory(category) { var definitions = getDefinitions(); (0, _Collections.remove)(definitions.get('rootElements'), category); } /** * Returns all group element in the current registry * * @return {Array<djs.model.shape>} a list of group shapes */ function getGroupElements() { return elementRegistry.filter(function (e) { return (0, _ModelUtil.is)(e, 'bpmn:Group'); }); } /** * Returns true if given categoryValue is referenced in one of the given elements * * @param {Array<djs.model.shape>} elements * @param {ModdleElement} categoryValue * @return {boolean} */ function isReferenced(elements, categoryValue) { return elements.some(function (e) { var businessObject = (0, _ModelUtil.getBusinessObject)(e); return businessObject.categoryValueRef && businessObject.categoryValueRef === categoryValue; }); } /** * remove referenced category + value when group was deleted */ this.executed('shape.delete', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Group')) { var businessObject = (0, _ModelUtil.getBusinessObject)(shape), categoryValueRef = businessObject.categoryValueRef, groupElements = getGroupElements(); if (!isReferenced(groupElements, categoryValueRef)) { removeReferencedCategoryValue(shape); } } }); /** * re-attach removed category */ this.reverted('shape.delete', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Group')) { var businessObject = (0, _ModelUtil.getBusinessObject)(shape), categoryValueRef = businessObject.categoryValueRef, definitions = getDefinitions(), category = categoryValueRef ? categoryValueRef.$parent : null; (0, _Collections.add)(category.get('categoryValue'), categoryValueRef); (0, _Collections.add)(definitions.get('rootElements'), category); } }); /** * create new category + value when group was created */ this.execute('shape.create', function (event) { var context = event.context, shape = context.shape, businessObject = (0, _ModelUtil.getBusinessObject)(shape); if ((0, _ModelUtil.is)(businessObject, 'bpmn:Group') && !businessObject.categoryValueRef) { var definitions = getDefinitions(), categoryValue = (0, _CategoryUtil.createCategoryValue)(definitions, bpmnFactory); // link the reference to the Group businessObject.categoryValueRef = categoryValue; } }); this.revert('shape.create', function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Group')) { removeReferencedCategoryValue(shape); delete (0, _ModelUtil.getBusinessObject)(shape).categoryValueRef; } }); // copy bpmn:CategoryValue when copying element eventBus.on('moddleCopy.canCopyProperty', HIGH_PRIORITY, function (context) { var property = context.property, categoryValue; if ((0, _ModelUtil.is)(property, 'bpmn:CategoryValue')) { categoryValue = (0, _CategoryUtil.createCategoryValue)(getDefinitions(), bpmnFactory); // return copy of category return moddleCopy.copyElement(property, categoryValue); } }); } GroupBehavior.$inject = ['bpmnFactory', 'canvas', 'elementRegistry', 'eventBus', 'injector', 'moddleCopy']; (0, _inherits.default)(GroupBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"./util/CategoryUtil":95,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Collections":313,"inherits":347}],77:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ImportDockingFix; var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _LineIntersect = _interopRequireDefault(require("./util/LineIntersect")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Fix broken dockings after DI imports. * * @param {EventBus} eventBus */ function ImportDockingFix(eventBus) { function adjustDocking(startPoint, nextPoint, elementMid) { var elementTop = { x: elementMid.x, y: elementMid.y - 50 }; var elementLeft = { x: elementMid.x - 50, y: elementMid.y }; var verticalIntersect = (0, _LineIntersect.default)(startPoint, nextPoint, elementMid, elementTop), horizontalIntersect = (0, _LineIntersect.default)(startPoint, nextPoint, elementMid, elementLeft); // original is horizontal or vertical center cross intersection var centerIntersect; if (verticalIntersect && horizontalIntersect) { if (getDistance(verticalIntersect, elementMid) > getDistance(horizontalIntersect, elementMid)) { centerIntersect = horizontalIntersect; } else { centerIntersect = verticalIntersect; } } else { centerIntersect = verticalIntersect || horizontalIntersect; } startPoint.original = centerIntersect; } function fixDockings(connection) { var waypoints = connection.waypoints; adjustDocking(waypoints[0], waypoints[1], (0, _LayoutUtil.getMid)(connection.source)); adjustDocking(waypoints[waypoints.length - 1], waypoints[waypoints.length - 2], (0, _LayoutUtil.getMid)(connection.target)); } eventBus.on('bpmnElement.added', function (e) { var element = e.element; if (element.waypoints) { fixDockings(element); } }); } ImportDockingFix.$inject = ['eventBus']; // helpers ////////////////////// function getDistance(p1, p2) { return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); } },{"./util/LineIntersect":99,"diagram-js/lib/layout/LayoutUtil":300}],78:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = IsHorizontalFix; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A component that makes sure that each created or updated * Pool and Lane is assigned an isHorizontal property set to true. * * @param {EventBus} eventBus */ function IsHorizontalFix(eventBus) { _CommandInterceptor.default.call(this, eventBus); var elementTypesToUpdate = ['bpmn:Participant', 'bpmn:Lane']; this.executed(['shape.move', 'shape.create', 'shape.resize'], function (event) { var bo = (0, _ModelUtil.getBusinessObject)(event.context.shape); if ((0, _ModelingUtil.isAny)(bo, elementTypesToUpdate) && !bo.di.get('isHorizontal')) { // set attribute directly to avoid modeling#updateProperty side effects bo.di.set('isHorizontal', true); } }); } IsHorizontalFix.$inject = ['eventBus']; (0, _inherits.default)(IsHorizontalFix, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],79:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelBehavior; exports.getReferencePointDelta = getReferencePointDelta; exports.getReferencePoint = getReferencePoint; exports.asEdges = asEdges; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _LabelUtil = require("../../../util/LabelUtil"); var _LabelUtil2 = require("../../label-editing/LabelUtil"); var _LabelLayoutUtil = require("./util/LabelLayoutUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _AttachUtil = require("diagram-js/lib/util/AttachUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _PositionUtil = require("diagram-js/lib/util/PositionUtil"); var _GeometricUtil = require("./util/GeometricUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DEFAULT_LABEL_DIMENSIONS = { width: 90, height: 20 }; var NAME_PROPERTY = 'name'; var TEXT_PROPERTY = 'text'; /** * A component that makes sure that external labels are added * together with respective elements and properly updated (DI wise) * during move. * * @param {EventBus} eventBus * @param {Modeling} modeling * @param {BpmnFactory} bpmnFactory * @param {TextRenderer} textRenderer */ function LabelBehavior(eventBus, modeling, bpmnFactory, textRenderer) { _CommandInterceptor.default.call(this, eventBus); // update label if name property was updated this.postExecute('element.updateProperties', function (e) { var context = e.context, element = context.element, properties = context.properties; if (NAME_PROPERTY in properties) { modeling.updateLabel(element, properties[NAME_PROPERTY]); } if (TEXT_PROPERTY in properties && (0, _ModelUtil.is)(element, 'bpmn:TextAnnotation')) { var newBounds = textRenderer.getTextAnnotationBounds({ x: element.x, y: element.y, width: element.width, height: element.height }, properties[TEXT_PROPERTY] || ''); modeling.updateLabel(element, properties.text, newBounds); } }); // create label shape after shape/connection was created this.postExecute(['shape.create', 'connection.create'], function (e) { var context = e.context, hints = context.hints || {}; if (hints.createElementsBehavior === false) { return; } var element = context.shape || context.connection, businessObject = element.businessObject; if ((0, _LabelUtil.isLabel)(element) || !(0, _LabelUtil.isLabelExternal)(element)) { return; } // only create label if attribute available if (!(0, _LabelUtil2.getLabel)(element)) { return; } var labelCenter = (0, _LabelUtil.getExternalLabelMid)(element); // we don't care about x and y var labelDimensions = textRenderer.getExternalLabelBounds(DEFAULT_LABEL_DIMENSIONS, (0, _LabelUtil2.getLabel)(element)); modeling.createLabel(element, labelCenter, { id: businessObject.id + '_label', businessObject: businessObject, width: labelDimensions.width, height: labelDimensions.height }); }); // update label after label shape was deleted this.postExecute('shape.delete', function (event) { var context = event.context, labelTarget = context.labelTarget, hints = context.hints || {}; // check if label if (labelTarget && hints.unsetLabel !== false) { modeling.updateLabel(labelTarget, null, null, { removeShape: false }); } }); // update di information on label creation this.postExecute(['label.create'], function (event) { var context = event.context, element = context.shape, businessObject, di; // we want to trigger on real labels only if (!element.labelTarget) { return; } // we want to trigger on BPMN elements only if (!(0, _ModelUtil.is)(element.labelTarget || element, 'bpmn:BaseElement')) { return; } businessObject = element.businessObject, di = businessObject.di; if (!di.label) { di.label = bpmnFactory.create('bpmndi:BPMNLabel', { bounds: bpmnFactory.create('dc:Bounds') }); } (0, _minDash.assign)(di.label.bounds, { x: element.x, y: element.y, width: element.width, height: element.height }); }); function getVisibleLabelAdjustment(event) { var context = event.context, connection = context.connection, label = connection.label, hints = (0, _minDash.assign)({}, context.hints), newWaypoints = context.newWaypoints || connection.waypoints, oldWaypoints = context.oldWaypoints; if (typeof hints.startChanged === 'undefined') { hints.startChanged = !!hints.connectionStart; } if (typeof hints.endChanged === 'undefined') { hints.endChanged = !!hints.connectionEnd; } return (0, _LabelLayoutUtil.getLabelAdjustment)(label, newWaypoints, oldWaypoints, hints); } this.postExecute(['connection.layout', 'connection.updateWaypoints'], function (event) { var context = event.context, hints = context.hints || {}; if (hints.labelBehavior === false) { return; } var connection = context.connection, label = connection.label, labelAdjustment; // handle missing label as well as the case // that the label parent does not exist (yet), // because it is being pasted / created via multi element create // // Cf. https://github.com/bpmn-io/bpmn-js/pull/1227 if (!label || !label.parent) { return; } labelAdjustment = getVisibleLabelAdjustment(event); modeling.moveShape(label, labelAdjustment); }); // keep label position on shape replace this.postExecute(['shape.replace'], function (event) { var context = event.context, newShape = context.newShape, oldShape = context.oldShape; var businessObject = (0, _ModelUtil.getBusinessObject)(newShape); if (businessObject && (0, _LabelUtil.isLabelExternal)(businessObject) && oldShape.label && newShape.label) { newShape.label.x = oldShape.label.x; newShape.label.y = oldShape.label.y; } }); // move external label after resizing this.postExecute('shape.resize', function (event) { var context = event.context, shape = context.shape, newBounds = context.newBounds, oldBounds = context.oldBounds; if ((0, _LabelUtil.hasExternalLabel)(shape)) { var label = shape.label, labelMid = (0, _LayoutUtil.getMid)(label), edges = asEdges(oldBounds); // get nearest border point to label as reference point var referencePoint = getReferencePoint(labelMid, edges); var delta = getReferencePointDelta(referencePoint, oldBounds, newBounds); modeling.moveShape(label, delta); } }); } (0, _inherits.default)(LabelBehavior, _CommandInterceptor.default); LabelBehavior.$inject = ['eventBus', 'modeling', 'bpmnFactory', 'textRenderer']; // helpers ////////////////////// /** * Calculates a reference point delta relative to a new position * of a certain element's bounds * * @param {Point} point * @param {Bounds} oldBounds * @param {Bounds} newBounds * * @return {Delta} delta */ function getReferencePointDelta(referencePoint, oldBounds, newBounds) { var newReferencePoint = (0, _AttachUtil.getNewAttachPoint)(referencePoint, oldBounds, newBounds); return (0, _LayoutUtil.roundPoint)((0, _PositionUtil.delta)(newReferencePoint, referencePoint)); } /** * Generates the nearest point (reference point) for a given point * onto given set of lines * * @param {Array<Point, Point>} lines * @param {Point} point * * @param {Point} */ function getReferencePoint(point, lines) { if (!lines.length) { return; } var nearestLine = getNearestLine(point, lines); return (0, _GeometricUtil.perpendicularFoot)(point, nearestLine); } /** * Convert the given bounds to a lines array containing all edges * * @param {Bounds|Point} bounds * * @return Array<Point> */ function asEdges(bounds) { return [[// top { x: bounds.x, y: bounds.y }, { x: bounds.x + (bounds.width || 0), y: bounds.y }], [// right { x: bounds.x + (bounds.width || 0), y: bounds.y }, { x: bounds.x + (bounds.width || 0), y: bounds.y + (bounds.height || 0) }], [// bottom { x: bounds.x, y: bounds.y + (bounds.height || 0) }, { x: bounds.x + (bounds.width || 0), y: bounds.y + (bounds.height || 0) }], [// left { x: bounds.x, y: bounds.y }, { x: bounds.x, y: bounds.y + (bounds.height || 0) }]]; } /** * Returns the nearest line for a given point by distance * @param {Point} point * @param Array<Point> lines * * @return Array<Point> */ function getNearestLine(point, lines) { var distances = lines.map(function (l) { return { line: l, distance: (0, _GeometricUtil.getDistancePointLine)(point, l) }; }); var sorted = (0, _minDash.sortBy)(distances, 'distance'); return sorted[0].line; } },{"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"../../label-editing/LabelUtil":53,"./util/GeometricUtil":96,"./util/LabelLayoutUtil":97,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/AttachUtil":311,"diagram-js/lib/util/PositionUtil":325,"inherits":347,"min-dash":555}],80:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ModelingFeedback; var _ModelUtil = require("../../../util/ModelUtil"); var COLLAB_ERR_MSG = 'flow elements must be children of pools/participants', PROCESS_ERR_MSG = 'participants cannot be pasted onto a non-empty process diagram'; function ModelingFeedback(eventBus, tooltips, translate) { function showError(position, message, timeout) { tooltips.add({ position: { x: position.x + 5, y: position.y + 5 }, type: 'error', timeout: timeout || 2000, html: '<div>' + message + '</div>' }); } eventBus.on(['shape.move.rejected', 'create.rejected'], function (event) { var context = event.context, shape = context.shape, target = context.target; if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration') && (0, _ModelUtil.is)(shape, 'bpmn:FlowNode')) { showError(event, translate(COLLAB_ERR_MSG)); } }); eventBus.on(['elements.paste.rejected'], function (event) { var context = event.context, position = context.position, target = context.target; if ((0, _ModelUtil.is)(target, 'bpmn:Collaboration')) { showError(position, translate(COLLAB_ERR_MSG)); } if ((0, _ModelUtil.is)(target, 'bpmn:Process')) { showError(position, translate(PROCESS_ERR_MSG), 3000); } }); } ModelingFeedback.$inject = ['eventBus', 'tooltips', 'translate']; },{"../../../util/ModelUtil":141}],81:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RemoveElementBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../../util/ModelUtil"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _LineIntersect = _interopRequireDefault(require("./util/LineIntersect")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function RemoveElementBehavior(eventBus, bpmnRules, modeling) { _CommandInterceptor.default.call(this, eventBus); /** * Combine sequence flows when deleting an element * if there is one incoming and one outgoing * sequence flow */ this.preExecute('shape.delete', function (e) { var shape = e.context.shape; // only handle [a] -> [shape] -> [b] patterns if (shape.incoming.length !== 1 || shape.outgoing.length !== 1) { return; } var inConnection = shape.incoming[0], outConnection = shape.outgoing[0]; // only handle sequence flows if (!(0, _ModelUtil.is)(inConnection, 'bpmn:SequenceFlow') || !(0, _ModelUtil.is)(outConnection, 'bpmn:SequenceFlow')) { return; } if (bpmnRules.canConnect(inConnection.source, outConnection.target, inConnection)) { // compute new, combined waypoints var newWaypoints = getNewWaypoints(inConnection.waypoints, outConnection.waypoints); modeling.reconnectEnd(inConnection, outConnection.target, newWaypoints); } }); } (0, _inherits.default)(RemoveElementBehavior, _CommandInterceptor.default); RemoveElementBehavior.$inject = ['eventBus', 'bpmnRules', 'modeling']; // helpers ////////////////////// function getDocking(point) { return point.original || point; } function getNewWaypoints(inWaypoints, outWaypoints) { var intersection = (0, _LineIntersect.default)(getDocking(inWaypoints[inWaypoints.length - 2]), getDocking(inWaypoints[inWaypoints.length - 1]), getDocking(outWaypoints[1]), getDocking(outWaypoints[0])); if (intersection) { return [].concat(inWaypoints.slice(0, inWaypoints.length - 1), [intersection], outWaypoints.slice(1)); } else { return [getDocking(inWaypoints[0]), getDocking(outWaypoints[outWaypoints.length - 1])]; } } },{"../../../util/ModelUtil":141,"./util/LineIntersect":99,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],82:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RemoveParticipantBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific remove behavior */ function RemoveParticipantBehavior(eventBus, modeling) { _CommandInterceptor.default.call(this, eventBus); /** * morph collaboration diagram into process diagram * after the last participant has been removed */ this.preExecute('shape.delete', function (context) { var shape = context.shape, parent = shape.parent; // activate the behavior if the shape to be removed // is a participant if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { context.collaborationRoot = parent; } }, true); this.postExecute('shape.delete', function (context) { var collaborationRoot = context.collaborationRoot; if (collaborationRoot && !collaborationRoot.businessObject.participants.length) { // replace empty collaboration with process diagram modeling.makeProcess(); } }, true); } RemoveParticipantBehavior.$inject = ['eventBus', 'modeling']; (0, _inherits.default)(RemoveParticipantBehavior, _CommandInterceptor.default); },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],83:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceConnectionBehavior; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function ReplaceConnectionBehavior(eventBus, modeling, bpmnRules, injector) { _CommandInterceptor.default.call(this, eventBus); var dragging = injector.get('dragging', false); function fixConnection(connection) { var source = connection.source, target = connection.target, parent = connection.parent; // do not do anything if connection // is already deleted (may happen due to other // behaviors plugged-in before) if (!parent) { return; } var replacementType, remove; /** * Check if incoming or outgoing connections * can stay or could be substituted with an * appropriate replacement. * * This holds true for SequenceFlow <> MessageFlow. */ if ((0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow')) { if (!bpmnRules.canConnectSequenceFlow(source, target)) { remove = true; } if (bpmnRules.canConnectMessageFlow(source, target)) { replacementType = 'bpmn:MessageFlow'; } } // transform message flows into sequence flows, if possible if ((0, _ModelUtil.is)(connection, 'bpmn:MessageFlow')) { if (!bpmnRules.canConnectMessageFlow(source, target)) { remove = true; } if (bpmnRules.canConnectSequenceFlow(source, target)) { replacementType = 'bpmn:SequenceFlow'; } } if ((0, _ModelUtil.is)(connection, 'bpmn:Association') && !bpmnRules.canConnectAssociation(source, target)) { remove = true; } // remove invalid connection, // unless it has been removed already if (remove) { modeling.removeConnection(connection); } // replace SequenceFlow <> MessageFlow if (replacementType) { modeling.connect(source, target, { type: replacementType, waypoints: connection.waypoints.slice() }); } } function replaceReconnectedConnection(event) { var context = event.context, connection = context.connection, source = context.newSource || connection.source, target = context.newTarget || connection.target, allowed, replacement; allowed = bpmnRules.canConnect(source, target); if (!allowed || allowed.type === connection.type) { return; } replacement = modeling.connect(source, target, { type: allowed.type, waypoints: connection.waypoints.slice() }); // remove old connection modeling.removeConnection(connection); // replace connection in context to reconnect end/start context.connection = replacement; if (dragging) { cleanDraggingSelection(connection, replacement); } } // monkey-patch selection saved in dragging in order to re-select it when operation is finished function cleanDraggingSelection(oldConnection, newConnection) { var context = dragging.context(), previousSelection = context && context.payload.previousSelection, index; // do nothing if not dragging or no selection was present if (!previousSelection || !previousSelection.length) { return; } index = previousSelection.indexOf(oldConnection); if (index === -1) { return; } previousSelection.splice(index, 1, newConnection); } // lifecycle hooks this.postExecuted('elements.move', function (context) { var closure = context.closure, allConnections = closure.allConnections; (0, _minDash.forEach)(allConnections, fixConnection); }, true); this.preExecute('connection.reconnect', replaceReconnectedConnection); this.postExecuted('element.updateProperties', function (event) { var context = event.context, properties = context.properties, element = context.element, businessObject = element.businessObject, connection; // remove condition on change to default if (properties.default) { connection = (0, _minDash.find)(element.outgoing, (0, _minDash.matchPattern)({ id: element.businessObject.default.id })); if (connection) { modeling.updateProperties(connection, { conditionExpression: undefined }); } } // remove default from source on change to conditional if (properties.conditionExpression && businessObject.sourceRef.default === businessObject) { modeling.updateProperties(element.source, { default: undefined }); } }); } (0, _inherits.default)(ReplaceConnectionBehavior, _CommandInterceptor.default); ReplaceConnectionBehavior.$inject = ['eventBus', 'modeling', 'bpmnRules', 'injector']; },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],84:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceElementBehaviour; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _DiUtil = require("../../../util/DiUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN-specific replace behavior. */ function ReplaceElementBehaviour(bpmnReplace, bpmnRules, elementRegistry, injector, modeling, selection) { injector.invoke(_CommandInterceptor.default, this); this._bpmnReplace = bpmnReplace; this._elementRegistry = elementRegistry; this._selection = selection; // replace elements on move this.postExecuted(['elements.move'], 500, function (event) { var context = event.context, target = context.newParent, newHost = context.newHost, elements = []; (0, _minDash.forEach)(context.closure.topLevel, function (topLevelElements) { if ((0, _DiUtil.isEventSubProcess)(topLevelElements)) { elements = elements.concat(topLevelElements.children); } else { elements = elements.concat(topLevelElements); } }); // set target to host if attaching if (elements.length === 1 && newHost) { target = newHost; } var canReplace = bpmnRules.canReplace(elements, target); if (canReplace) { this.replaceElements(elements, canReplace.replacements, newHost); } }, this); // update attachments on host replace this.postExecute(['shape.replace'], 1500, function (e) { var context = e.context, oldShape = context.oldShape, newShape = context.newShape, attachers = oldShape.attachers, canReplace; if (attachers && attachers.length) { canReplace = bpmnRules.canReplace(attachers, newShape); this.replaceElements(attachers, canReplace.replacements); } }, this); // keep ID on shape replace this.postExecuted(['shape.replace'], 1500, function (e) { var context = e.context, oldShape = context.oldShape, newShape = context.newShape; modeling.unclaimId(oldShape.businessObject.id, oldShape.businessObject); modeling.updateProperties(newShape, { id: oldShape.id }); }); } (0, _inherits.default)(ReplaceElementBehaviour, _CommandInterceptor.default); ReplaceElementBehaviour.prototype.replaceElements = function (elements, newElements) { var elementRegistry = this._elementRegistry, bpmnReplace = this._bpmnReplace, selection = this._selection; (0, _minDash.forEach)(newElements, function (replacement) { var newElement = { type: replacement.newElementType }; var oldElement = elementRegistry.get(replacement.oldElementId); var idx = elements.indexOf(oldElement); elements[idx] = bpmnReplace.replaceElement(oldElement, newElement, { select: false }); }); if (newElements) { selection.select(elements); } }; ReplaceElementBehaviour.$inject = ['bpmnReplace', 'bpmnRules', 'elementRegistry', 'injector', 'modeling', 'selection']; },{"../../../util/DiUtil":139,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555}],85:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeBehavior; exports.TEXT_ANNOTATION_MIN_DIMENSIONS = exports.SUB_PROCESS_MIN_DIMENSIONS = exports.PARTICIPANT_MIN_DIMENSIONS = exports.LANE_MIN_DIMENSIONS = void 0; var _ModelUtil = require("../../../util/ModelUtil"); var _DiUtil = require("../../../util/DiUtil"); var _ResizeUtil = require("./util/ResizeUtil"); var HIGH_PRIORITY = 1500; var LANE_MIN_DIMENSIONS = { width: 300, height: 60 }; exports.LANE_MIN_DIMENSIONS = LANE_MIN_DIMENSIONS; var PARTICIPANT_MIN_DIMENSIONS = { width: 300, height: 150 }; exports.PARTICIPANT_MIN_DIMENSIONS = PARTICIPANT_MIN_DIMENSIONS; var SUB_PROCESS_MIN_DIMENSIONS = { width: 140, height: 120 }; exports.SUB_PROCESS_MIN_DIMENSIONS = SUB_PROCESS_MIN_DIMENSIONS; var TEXT_ANNOTATION_MIN_DIMENSIONS = { width: 50, height: 30 }; /** * Set minimum bounds/resize constraints on resize. * * @param {EventBus} eventBus */ exports.TEXT_ANNOTATION_MIN_DIMENSIONS = TEXT_ANNOTATION_MIN_DIMENSIONS; function ResizeBehavior(eventBus) { eventBus.on('resize.start', HIGH_PRIORITY, function (event) { var context = event.context, shape = context.shape, direction = context.direction, balanced = context.balanced; if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) { context.resizeConstraints = (0, _ResizeUtil.getParticipantResizeConstraints)(shape, direction, balanced); } if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { context.minDimensions = PARTICIPANT_MIN_DIMENSIONS; } if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(shape)) { context.minDimensions = SUB_PROCESS_MIN_DIMENSIONS; } if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) { context.minDimensions = TEXT_ANNOTATION_MIN_DIMENSIONS; } }); } ResizeBehavior.$inject = ['eventBus']; },{"../../../util/DiUtil":139,"../../../util/ModelUtil":141,"./util/ResizeUtil":100}],86:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeLaneBehavior; var _ModelUtil = require("../../../util/ModelUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _Mouse = require("diagram-js/lib/util/Mouse"); var SLIGHTLY_HIGHER_PRIORITY = 1001; /** * Invoke {@link Modeling#resizeLane} instead of * {@link Modeling#resizeShape} when resizing a Lane * or Participant shape. */ function ResizeLaneBehavior(eventBus, modeling) { eventBus.on('resize.start', SLIGHTLY_HIGHER_PRIORITY + 500, function (event) { var context = event.context, shape = context.shape; if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) { // should we resize the opposite lane(s) in // order to compensate for the resize operation? context.balanced = !(0, _Mouse.hasPrimaryModifier)(event); } }); /** * Intercept resize end and call resize lane function instead. */ eventBus.on('resize.end', SLIGHTLY_HIGHER_PRIORITY, function (event) { var context = event.context, shape = context.shape, canExecute = context.canExecute, newBounds = context.newBounds; if ((0, _ModelUtil.is)(shape, 'bpmn:Lane') || (0, _ModelUtil.is)(shape, 'bpmn:Participant')) { if (canExecute) { // ensure we have actual pixel values for new bounds // (important when zoom level was > 1 during move) newBounds = (0, _LayoutUtil.roundBounds)(newBounds); // perform the actual resize modeling.resizeLane(shape, newBounds, context.balanced); } // stop propagation return false; } }); } ResizeLaneBehavior.$inject = ['eventBus', 'modeling']; },{"../../../util/ModelUtil":141,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Mouse":323}],87:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RootElementReferenceBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _minDash = require("min-dash"); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _Collections = require("diagram-js/lib/util/Collections"); var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("../util/ModelingUtil"); var _DiUtil = require("../../../util/DiUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; /** * Add referenced root elements (error, escalation, message, signal) if they don't exist. * Copy referenced root elements on copy & paste. */ function RootElementReferenceBehavior(bpmnjs, eventBus, injector, moddleCopy, bpmnFactory) { injector.invoke(_CommandInterceptor.default, this); function canHaveRootElementReference(element) { return (0, _ModelingUtil.isAny)(element, ['bpmn:ReceiveTask', 'bpmn:SendTask']) || hasAnyEventDefinition(element, ['bpmn:ErrorEventDefinition', 'bpmn:EscalationEventDefinition', 'bpmn:MessageEventDefinition', 'bpmn:SignalEventDefinition']); } function hasRootElement(rootElement) { var definitions = bpmnjs.getDefinitions(), rootElements = definitions.get('rootElements'); return !!(0, _minDash.find)(rootElements, (0, _minDash.matchPattern)({ id: rootElement.id })); } function getRootElementReferencePropertyName(eventDefinition) { if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:ErrorEventDefinition')) { return 'errorRef'; } else if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:EscalationEventDefinition')) { return 'escalationRef'; } else if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:MessageEventDefinition')) { return 'messageRef'; } else if ((0, _ModelUtil.is)(eventDefinition, 'bpmn:SignalEventDefinition')) { return 'signalRef'; } } function getRootElement(businessObject) { if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:ReceiveTask', 'bpmn:SendTask'])) { return businessObject.get('messageRef'); } var eventDefinitions = businessObject.get('eventDefinitions'), eventDefinition = eventDefinitions[0]; return eventDefinition.get(getRootElementReferencePropertyName(eventDefinition)); } function setRootElement(businessObject, rootElement) { if ((0, _ModelingUtil.isAny)(businessObject, ['bpmn:ReceiveTask', 'bpmn:SendTask'])) { return businessObject.set('messageRef', rootElement); } var eventDefinitions = businessObject.get('eventDefinitions'), eventDefinition = eventDefinitions[0]; return eventDefinition.set(getRootElementReferencePropertyName(eventDefinition), rootElement); } // create shape this.executed('shape.create', function (context) { var shape = context.shape; if (!canHaveRootElementReference(shape)) { return; } var businessObject = (0, _ModelUtil.getBusinessObject)(shape), rootElement = getRootElement(businessObject), rootElements; if (rootElement && !hasRootElement(rootElement)) { rootElements = bpmnjs.getDefinitions().get('rootElements'); // add root element (0, _Collections.add)(rootElements, rootElement); context.addedRootElement = rootElement; } }, true); this.reverted('shape.create', function (context) { var addedRootElement = context.addedRootElement; if (!addedRootElement) { return; } var rootElements = bpmnjs.getDefinitions().get('rootElements'); // remove root element (0, _Collections.remove)(rootElements, addedRootElement); }, true); eventBus.on('copyPaste.copyElement', function (context) { var descriptor = context.descriptor, element = context.element; if (!canHaveRootElementReference(element)) { return; } var businessObject = (0, _ModelUtil.getBusinessObject)(element), rootElement = getRootElement(businessObject); if (rootElement) { descriptor.referencedRootElement = rootElement; } }); eventBus.on('copyPaste.pasteElement', LOW_PRIORITY, function (context) { var descriptor = context.descriptor, businessObject = descriptor.businessObject; if (!canHaveRootElementReference(businessObject)) { return; } var referencedRootElement = descriptor.referencedRootElement; if (!referencedRootElement) { return; } if (!hasRootElement(referencedRootElement)) { referencedRootElement = moddleCopy.copyElement(referencedRootElement, bpmnFactory.create(referencedRootElement.$type)); } setRootElement(businessObject, referencedRootElement); }); } RootElementReferenceBehavior.$inject = ['bpmnjs', 'eventBus', 'injector', 'moddleCopy', 'bpmnFactory']; (0, _inherits.default)(RootElementReferenceBehavior, _CommandInterceptor.default); // helpers ////////// function hasAnyEventDefinition(element, types) { if (!(0, _minDash.isArray)(types)) { types = [types]; } return (0, _minDash.some)(types, function (type) { return (0, _DiUtil.hasEventDefinition)(element, type); }); } },{"../../../util/DiUtil":139,"../../../util/ModelUtil":141,"../util/ModelingUtil":112,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/util/Collections":313,"inherits":347,"min-dash":555}],88:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceToolBehavior; var _minDash = require("min-dash"); var _ModelUtil = require("../../../util/ModelUtil"); var _DiUtil = require("../../../util/DiUtil"); var _ResizeBehavior = require("./ResizeBehavior"); var _LaneUtil = require("../util/LaneUtil"); var max = Math.max; function SpaceToolBehavior(eventBus) { eventBus.on('spaceTool.getMinDimensions', function (context) { var shapes = context.shapes, axis = context.axis, start = context.start, minDimensions = {}; (0, _minDash.forEach)(shapes, function (shape) { var id = shape.id; if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { if (isHorizontal(axis)) { minDimensions[id] = _ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS; } else { minDimensions[id] = { width: _ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS.width, height: getParticipantMinHeight(shape, start) }; } } if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(shape)) { minDimensions[id] = _ResizeBehavior.SUB_PROCESS_MIN_DIMENSIONS; } if ((0, _ModelUtil.is)(shape, 'bpmn:TextAnnotation')) { minDimensions[id] = _ResizeBehavior.TEXT_ANNOTATION_MIN_DIMENSIONS; } }); return minDimensions; }); } SpaceToolBehavior.$inject = ['eventBus']; // helpers ////////// function isHorizontal(axis) { return axis === 'x'; } /** * Get minimum height for participant taking lanes into account. * * @param {<djs.model.Shape>} participant * @param {number} start * * @returns {Object} */ function getParticipantMinHeight(participant, start) { var lanesMinHeight; if (!hasChildLanes(participant)) { return _ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS.height; } lanesMinHeight = getLanesMinHeight(participant, start); return max(_ResizeBehavior.PARTICIPANT_MIN_DIMENSIONS.height, lanesMinHeight); } function hasChildLanes(element) { return !!(0, _LaneUtil.getChildLanes)(element).length; } function getLanesMinHeight(participant, resizeStart) { var lanes = (0, _LaneUtil.getChildLanes)(participant), resizedLane; // find the nested lane which is currently resized resizedLane = findResizedLane(lanes, resizeStart); // resized lane cannot shrink below the minimum height // but remaining lanes' dimensions are kept intact return participant.height - resizedLane.height + _ResizeBehavior.LANE_MIN_DIMENSIONS.height; } /** * Find nested lane which is currently resized. * * @param {Array<djs.model.Shape>} lanes * @param {number} resizeStart */ function findResizedLane(lanes, resizeStart) { var i, lane, childLanes; for (i = 0; i < lanes.length; i++) { lane = lanes[i]; // resizing current lane or a lane nested if (resizeStart >= lane.y && resizeStart <= lane.y + lane.height) { childLanes = (0, _LaneUtil.getChildLanes)(lane); // a nested lane is resized if (childLanes.length) { return findResizedLane(childLanes, resizeStart); } // current lane is the resized one return lane; } } } },{"../../../util/DiUtil":139,"../../../util/ModelUtil":141,"../util/LaneUtil":111,"./ResizeBehavior":85,"min-dash":555}],89:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SubProcessStartEventBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _DiUtil = require("../../../util/DiUtil.js"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Add start event replacing element with expanded sub process. * * @param {Injector} injector * @param {Modeling} modeling */ function SubProcessStartEventBehavior(injector, modeling) { injector.invoke(_CommandInterceptor.default, this); this.postExecuted('shape.replace', function (event) { var oldShape = event.context.oldShape, newShape = event.context.newShape; if (!(0, _ModelUtil.is)(newShape, 'bpmn:SubProcess') || !(0, _ModelUtil.is)(oldShape, 'bpmn:Task') || !(0, _DiUtil.isExpanded)(newShape)) { return; } var position = getStartEventPosition(newShape); modeling.createShape({ type: 'bpmn:StartEvent' }, position, newShape); }); } SubProcessStartEventBehavior.$inject = ['injector', 'modeling']; (0, _inherits.default)(SubProcessStartEventBehavior, _CommandInterceptor.default); // helpers ////////// function getStartEventPosition(shape) { return { x: shape.x + shape.width / 6, y: shape.y + shape.height / 2 }; } },{"../../../util/DiUtil.js":139,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],90:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ToggleElementCollapseBehaviour; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _ResizeUtil = require("diagram-js/lib/features/resize/ResizeUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500; function ToggleElementCollapseBehaviour(eventBus, elementFactory, modeling, resize) { _CommandInterceptor.default.call(this, eventBus); function hideEmptyLabels(children) { if (children.length) { children.forEach(function (child) { if (child.type === 'label' && !child.businessObject.name) { child.hidden = true; } }); } } function expandedBounds(shape, defaultSize) { var children = shape.children, newBounds = defaultSize, visibleElements, visibleBBox; visibleElements = filterVisible(children).concat([shape]); visibleBBox = (0, _ResizeUtil.computeChildrenBBox)(visibleElements); if (visibleBBox) { // center to visibleBBox with max(defaultSize, childrenBounds) newBounds.width = Math.max(visibleBBox.width, newBounds.width); newBounds.height = Math.max(visibleBBox.height, newBounds.height); newBounds.x = visibleBBox.x + (visibleBBox.width - newBounds.width) / 2; newBounds.y = visibleBBox.y + (visibleBBox.height - newBounds.height) / 2; } else { // center to collapsed shape with defaultSize newBounds.x = shape.x + (shape.width - newBounds.width) / 2; newBounds.y = shape.y + (shape.height - newBounds.height) / 2; } return newBounds; } function collapsedBounds(shape, defaultSize) { return { x: shape.x + (shape.width - defaultSize.width) / 2, y: shape.y + (shape.height - defaultSize.height) / 2, width: defaultSize.width, height: defaultSize.height }; } this.executed(['shape.toggleCollapse'], LOW_PRIORITY, function (e) { var context = e.context, shape = context.shape; if (!(0, _ModelUtil.is)(shape, 'bpmn:SubProcess')) { return; } if (!shape.collapsed) { // all children got made visible through djs, hide empty labels hideEmptyLabels(shape.children); // remove collapsed marker (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = true; } else { // place collapsed marker (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = false; } }); this.reverted(['shape.toggleCollapse'], LOW_PRIORITY, function (e) { var context = e.context; var shape = context.shape; // revert removing/placing collapsed marker if (!shape.collapsed) { (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = true; } else { (0, _ModelUtil.getBusinessObject)(shape).di.isExpanded = false; } }); this.postExecuted(['shape.toggleCollapse'], LOW_PRIORITY, function (e) { var shape = e.context.shape, defaultSize = elementFactory._getDefaultSize(shape), newBounds; if (shape.collapsed) { // resize to default size of collapsed shapes newBounds = collapsedBounds(shape, defaultSize); } else { // resize to bounds of max(visible children, defaultSize) newBounds = expandedBounds(shape, defaultSize); } modeling.resizeShape(shape, newBounds, null, { autoResize: shape.collapsed ? false : 'nwse' }); }); } (0, _inherits.default)(ToggleElementCollapseBehaviour, _CommandInterceptor.default); ToggleElementCollapseBehaviour.$inject = ['eventBus', 'elementFactory', 'modeling']; // helpers ////////////////////// function filterVisible(elements) { return elements.filter(function (e) { return !e.hidden; }); } },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"diagram-js/lib/features/resize/ResizeUtil":268,"inherits":347}],91:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UnclaimIdBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); var _DiUtil = require("../../../util/DiUtil"); var _LabelUtil = require("../../../util/LabelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Unclaims model IDs on element deletion. * * @param {Canvas} canvas * @param {Injector} injector * @param {Moddle} moddle * @param {Modeling} modeling */ function UnclaimIdBehavior(canvas, injector, moddle, modeling) { injector.invoke(_CommandInterceptor.default, this); this.preExecute('shape.delete', function (event) { var context = event.context, shape = context.shape, shapeBo = shape.businessObject; if ((0, _LabelUtil.isLabel)(shape)) { return; } if ((0, _ModelUtil.is)(shape, 'bpmn:Participant') && (0, _DiUtil.isExpanded)(shape)) { moddle.ids.unclaim(shapeBo.processRef.id); } modeling.unclaimId(shapeBo.id, shapeBo); }); this.preExecute('connection.delete', function (event) { var context = event.context, connection = context.connection, connectionBo = connection.businessObject; modeling.unclaimId(connectionBo.id, connectionBo); }); this.preExecute('canvas.updateRoot', function () { var rootElement = canvas.getRootElement(), rootElementBo = rootElement.businessObject; moddle.ids.unclaim(rootElementBo.id); }); } (0, _inherits.default)(UnclaimIdBehavior, _CommandInterceptor.default); UnclaimIdBehavior.$inject = ['canvas', 'injector', 'moddle', 'modeling']; },{"../../../util/DiUtil":139,"../../../util/LabelUtil":140,"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],92:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteSequenceFlowBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A behavior that unsets the Default property of * sequence flow source on element delete, if the * removed element is the Gateway or Task's default flow. * * @param {EventBus} eventBus * @param {Modeling} modeling */ function DeleteSequenceFlowBehavior(eventBus, modeling) { _CommandInterceptor.default.call(this, eventBus); this.preExecute('connection.delete', function (event) { var context = event.context, connection = context.connection, source = connection.source; if (isDefaultFlow(connection, source)) { modeling.updateProperties(source, { 'default': null }); } }); } (0, _inherits.default)(DeleteSequenceFlowBehavior, _CommandInterceptor.default); DeleteSequenceFlowBehavior.$inject = ['eventBus', 'modeling']; // helpers ////////////////////// function isDefaultFlow(connection, source) { if (!(0, _ModelUtil.is)(connection, 'bpmn:SequenceFlow')) { return false; } var sourceBo = (0, _ModelUtil.getBusinessObject)(source), sequenceFlow = (0, _ModelUtil.getBusinessObject)(connection); return sourceBo.get('default') === sequenceFlow; } },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],93:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateFlowNodeRefsBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _ModelUtil = require("../../../util/ModelUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 500, HIGH_PRIORITY = 5000; /** * BPMN specific delete lane behavior */ function UpdateFlowNodeRefsBehavior(eventBus, modeling, translate) { _CommandInterceptor.default.call(this, eventBus); /** * Ok, this is it: * * We have to update the Lane#flowNodeRefs _and_ * FlowNode#lanes with every FlowNode move/resize and * Lane move/resize. * * We want to group that stuff to recompute containments * as efficient as possible. * * Yea! */ // the update context var context; function initContext() { context = context || new UpdateContext(); context.enter(); return context; } function getContext() { if (!context) { throw new Error(translate('out of bounds release')); } return context; } function releaseContext() { if (!context) { throw new Error(translate('out of bounds release')); } var triggerUpdate = context.leave(); if (triggerUpdate) { modeling.updateLaneRefs(context.flowNodes, context.lanes); context = null; } return triggerUpdate; } var laneRefUpdateEvents = ['spaceTool', 'lane.add', 'lane.resize', 'lane.split', 'elements.create', 'elements.delete', 'elements.move', 'shape.create', 'shape.delete', 'shape.move', 'shape.resize']; // listen to a lot of stuff to group lane updates this.preExecute(laneRefUpdateEvents, HIGH_PRIORITY, function (event) { initContext(); }); this.postExecuted(laneRefUpdateEvents, LOW_PRIORITY, function (event) { releaseContext(); }); // Mark flow nodes + lanes that need an update this.preExecute(['shape.create', 'shape.move', 'shape.delete', 'shape.resize'], function (event) { var context = event.context, shape = context.shape; var updateContext = getContext(); // no need to update labels if (shape.labelTarget) { return; } if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) { updateContext.addLane(shape); } if ((0, _ModelUtil.is)(shape, 'bpmn:FlowNode')) { updateContext.addFlowNode(shape); } }); } UpdateFlowNodeRefsBehavior.$inject = ['eventBus', 'modeling', 'translate']; (0, _inherits.default)(UpdateFlowNodeRefsBehavior, _CommandInterceptor.default); function UpdateContext() { this.flowNodes = []; this.lanes = []; this.counter = 0; this.addLane = function (lane) { this.lanes.push(lane); }; this.addFlowNode = function (flowNode) { this.flowNodes.push(flowNode); }; this.enter = function () { this.counter++; }; this.leave = function () { this.counter--; return !this.counter; }; } },{"../../../util/ModelUtil":141,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347}],94:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _AdaptiveLabelPositioningBehavior = _interopRequireDefault(require("./AdaptiveLabelPositioningBehavior")); var _AppendBehavior = _interopRequireDefault(require("./AppendBehavior")); var _AssociationBehavior = _interopRequireDefault(require("./AssociationBehavior")); var _AttachEventBehavior = _interopRequireDefault(require("./AttachEventBehavior")); var _BoundaryEventBehavior = _interopRequireDefault(require("./BoundaryEventBehavior")); var _RootElementReferenceBehavior = _interopRequireDefault(require("./RootElementReferenceBehavior")); var _CreateBehavior = _interopRequireDefault(require("./CreateBehavior")); var _FixHoverBehavior = _interopRequireDefault(require("./FixHoverBehavior")); var _CreateDataObjectBehavior = _interopRequireDefault(require("./CreateDataObjectBehavior")); var _CreateParticipantBehavior = _interopRequireDefault(require("./CreateParticipantBehavior")); var _DataInputAssociationBehavior = _interopRequireDefault(require("./DataInputAssociationBehavior")); var _DataStoreBehavior = _interopRequireDefault(require("./DataStoreBehavior")); var _DeleteLaneBehavior = _interopRequireDefault(require("./DeleteLaneBehavior")); var _DetachEventBehavior = _interopRequireDefault(require("./DetachEventBehavior")); var _DropOnFlowBehavior = _interopRequireDefault(require("./DropOnFlowBehavior")); var _EventBasedGatewayBehavior = _interopRequireDefault(require("./EventBasedGatewayBehavior")); var _GroupBehavior = _interopRequireDefault(require("./GroupBehavior")); var _ImportDockingFix = _interopRequireDefault(require("./ImportDockingFix")); var _IsHorizontalFix = _interopRequireDefault(require("./IsHorizontalFix")); var _LabelBehavior = _interopRequireDefault(require("./LabelBehavior")); var _ModelingFeedback = _interopRequireDefault(require("./ModelingFeedback")); var _ReplaceConnectionBehavior = _interopRequireDefault(require("./ReplaceConnectionBehavior")); var _RemoveParticipantBehavior = _interopRequireDefault(require("./RemoveParticipantBehavior")); var _ReplaceElementBehaviour = _interopRequireDefault(require("./ReplaceElementBehaviour")); var _ResizeBehavior = _interopRequireDefault(require("./ResizeBehavior")); var _ResizeLaneBehavior = _interopRequireDefault(require("./ResizeLaneBehavior")); var _RemoveElementBehavior = _interopRequireDefault(require("./RemoveElementBehavior")); var _SpaceToolBehavior = _interopRequireDefault(require("./SpaceToolBehavior")); var _SubProcessStartEventBehavior = _interopRequireDefault(require("./SubProcessStartEventBehavior")); var _ToggleElementCollapseBehaviour = _interopRequireDefault(require("./ToggleElementCollapseBehaviour")); var _UnclaimIdBehavior = _interopRequireDefault(require("./UnclaimIdBehavior")); var _UpdateFlowNodeRefsBehavior = _interopRequireDefault(require("./UpdateFlowNodeRefsBehavior")); var _UnsetDefaultFlowBehavior = _interopRequireDefault(require("./UnsetDefaultFlowBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['adaptiveLabelPositioningBehavior', 'appendBehavior', 'associationBehavior', 'attachEventBehavior', 'boundaryEventBehavior', 'rootElementReferenceBehavior', 'createBehavior', 'fixHoverBehavior', 'createDataObjectBehavior', 'createParticipantBehavior', 'dataStoreBehavior', 'dataInputAssociationBehavior', 'deleteLaneBehavior', 'detachEventBehavior', 'dropOnFlowBehavior', 'eventBasedGatewayBehavior', 'groupBehavior', 'importDockingFix', 'isHorizontalFix', 'labelBehavior', 'modelingFeedback', 'removeElementBehavior', 'removeParticipantBehavior', 'replaceConnectionBehavior', 'replaceElementBehaviour', 'resizeBehavior', 'resizeLaneBehavior', 'toggleElementCollapseBehaviour', 'spaceToolBehavior', 'subProcessStartEventBehavior', 'unclaimIdBehavior', 'unsetDefaultFlowBehavior', 'updateFlowNodeRefsBehavior'], adaptiveLabelPositioningBehavior: ['type', _AdaptiveLabelPositioningBehavior.default], appendBehavior: ['type', _AppendBehavior.default], associationBehavior: ['type', _AssociationBehavior.default], attachEventBehavior: ['type', _AttachEventBehavior.default], boundaryEventBehavior: ['type', _BoundaryEventBehavior.default], rootElementReferenceBehavior: ['type', _RootElementReferenceBehavior.default], createBehavior: ['type', _CreateBehavior.default], fixHoverBehavior: ['type', _FixHoverBehavior.default], createDataObjectBehavior: ['type', _CreateDataObjectBehavior.default], createParticipantBehavior: ['type', _CreateParticipantBehavior.default], dataInputAssociationBehavior: ['type', _DataInputAssociationBehavior.default], dataStoreBehavior: ['type', _DataStoreBehavior.default], deleteLaneBehavior: ['type', _DeleteLaneBehavior.default], detachEventBehavior: ['type', _DetachEventBehavior.default], dropOnFlowBehavior: ['type', _DropOnFlowBehavior.default], eventBasedGatewayBehavior: ['type', _EventBasedGatewayBehavior.default], groupBehavior: ['type', _GroupBehavior.default], importDockingFix: ['type', _ImportDockingFix.default], isHorizontalFix: ['type', _IsHorizontalFix.default], labelBehavior: ['type', _LabelBehavior.default], modelingFeedback: ['type', _ModelingFeedback.default], replaceConnectionBehavior: ['type', _ReplaceConnectionBehavior.default], removeParticipantBehavior: ['type', _RemoveParticipantBehavior.default], replaceElementBehaviour: ['type', _ReplaceElementBehaviour.default], resizeBehavior: ['type', _ResizeBehavior.default], resizeLaneBehavior: ['type', _ResizeLaneBehavior.default], removeElementBehavior: ['type', _RemoveElementBehavior.default], toggleElementCollapseBehaviour: ['type', _ToggleElementCollapseBehaviour.default], spaceToolBehavior: ['type', _SpaceToolBehavior.default], subProcessStartEventBehavior: ['type', _SubProcessStartEventBehavior.default], unclaimIdBehavior: ['type', _UnclaimIdBehavior.default], updateFlowNodeRefsBehavior: ['type', _UpdateFlowNodeRefsBehavior.default], unsetDefaultFlowBehavior: ['type', _UnsetDefaultFlowBehavior.default] }; exports.default = _default; },{"./AdaptiveLabelPositioningBehavior":61,"./AppendBehavior":62,"./AssociationBehavior":63,"./AttachEventBehavior":64,"./BoundaryEventBehavior":65,"./CreateBehavior":66,"./CreateDataObjectBehavior":67,"./CreateParticipantBehavior":68,"./DataInputAssociationBehavior":69,"./DataStoreBehavior":70,"./DeleteLaneBehavior":71,"./DetachEventBehavior":72,"./DropOnFlowBehavior":73,"./EventBasedGatewayBehavior":74,"./FixHoverBehavior":75,"./GroupBehavior":76,"./ImportDockingFix":77,"./IsHorizontalFix":78,"./LabelBehavior":79,"./ModelingFeedback":80,"./RemoveElementBehavior":81,"./RemoveParticipantBehavior":82,"./ReplaceConnectionBehavior":83,"./ReplaceElementBehaviour":84,"./ResizeBehavior":85,"./ResizeLaneBehavior":86,"./RootElementReferenceBehavior":87,"./SpaceToolBehavior":88,"./SubProcessStartEventBehavior":89,"./ToggleElementCollapseBehaviour":90,"./UnclaimIdBehavior":91,"./UnsetDefaultFlowBehavior":92,"./UpdateFlowNodeRefsBehavior":93}],95:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCategoryValue = createCategoryValue; var _Collections = require("diagram-js/lib/util/Collections"); var _ModelUtil = require("../../../../util/ModelUtil"); /** * Creates a new bpmn:CategoryValue inside a new bpmn:Category * * @param {ModdleElement} definitions * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} categoryValue. */ function createCategoryValue(definitions, bpmnFactory) { var categoryValue = bpmnFactory.create('bpmn:CategoryValue'), category = bpmnFactory.create('bpmn:Category', { categoryValue: [categoryValue] }); // add to correct place (0, _Collections.add)(definitions.get('rootElements'), category); (0, _ModelUtil.getBusinessObject)(category).$parent = definitions; (0, _ModelUtil.getBusinessObject)(categoryValue).$parent = category; return categoryValue; } },{"../../../../util/ModelUtil":141,"diagram-js/lib/util/Collections":313}],96:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.vectorLength = vectorLength; exports.getAngle = getAngle; exports.rotateVector = rotateVector; exports.perpendicularFoot = perpendicularFoot; exports.getDistancePointLine = getDistancePointLine; exports.getDistancePointPoint = getDistancePointPoint; /** * Returns the length of a vector * * @param {Vector} * @return {Float} */ function vectorLength(v) { return Math.sqrt(Math.pow(v.x, 2) + Math.pow(v.y, 2)); } /** * Calculates the angle between a line a the yAxis * * @param {Array} * @return {Float} */ function getAngle(line) { // return value is between 0, 180 and -180, -0 // @janstuemmel: maybe replace return a/b with b/a return Math.atan((line[1].y - line[0].y) / (line[1].x - line[0].x)); } /** * Rotates a vector by a given angle * * @param {Vector} * @param {Float} Angle in radians * @return {Vector} */ function rotateVector(vector, angle) { return !angle ? vector : { x: Math.cos(angle) * vector.x - Math.sin(angle) * vector.y, y: Math.sin(angle) * vector.x + Math.cos(angle) * vector.y }; } /** * Solves a 2D equation system * a + r*b = c, where a,b,c are 2D vectors * * @param {Vector} * @param {Vector} * @param {Vector} * @return {Float} */ function solveLambaSystem(a, b, c) { // the 2d system var system = [{ n: a[0] - c[0], lambda: b[0] }, { n: a[1] - c[1], lambda: b[1] }]; // solve var n = system[0].n * b[0] + system[1].n * b[1], l = system[0].lambda * b[0] + system[1].lambda * b[1]; return -n / l; } /** * Position of perpendicular foot * * @param {Point} * @param [ {Point}, {Point} ] line defined through two points * @return {Point} the perpendicular foot position */ function perpendicularFoot(point, line) { var a = line[0], b = line[1]; // relative position of b from a var bd = { x: b.x - a.x, y: b.y - a.y }; // solve equation system to the parametrized vectors param real value var r = solveLambaSystem([a.x, a.y], [bd.x, bd.y], [point.x, point.y]); return { x: a.x + r * bd.x, y: a.y + r * bd.y }; } /** * Calculates the distance between a point and a line * * @param {Point} * @param [ {Point}, {Point} ] line defined through two points * @return {Float} distance */ function getDistancePointLine(point, line) { var pfPoint = perpendicularFoot(point, line); // distance vector var connectionVector = { x: pfPoint.x - point.x, y: pfPoint.y - point.y }; return vectorLength(connectionVector); } /** * Calculates the distance between two points * * @param {Point} * @param {Point} * @return {Float} distance */ function getDistancePointPoint(point1, point2) { return vectorLength({ x: point1.x - point2.x, y: point1.y - point2.y }); } },{}],97:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findNewLabelLineStartIndex = findNewLabelLineStartIndex; exports.getLabelAdjustment = getLabelAdjustment; var _GeometricUtil = require("./GeometricUtil"); var _LineAttachmentUtil = require("./LineAttachmentUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); function findNewLabelLineStartIndex(oldWaypoints, newWaypoints, attachment, hints) { var index = attachment.segmentIndex; var offset = newWaypoints.length - oldWaypoints.length; // segmentMove happened if (hints.segmentMove) { var oldSegmentStartIndex = hints.segmentMove.segmentStartIndex, newSegmentStartIndex = hints.segmentMove.newSegmentStartIndex; // if label was on moved segment return new segment index if (index === oldSegmentStartIndex) { return newSegmentStartIndex; } // label is after new segment index if (index >= newSegmentStartIndex) { return index + offset < newSegmentStartIndex ? newSegmentStartIndex : index + offset; } // if label is before new segment index return index; } // bendpointMove happened if (hints.bendpointMove) { var insert = hints.bendpointMove.insert, bendpointIndex = hints.bendpointMove.bendpointIndex, newIndex; // waypoints length didnt change if (offset === 0) { return index; } // label behind new/removed bendpoint if (index >= bendpointIndex) { newIndex = insert ? index + 1 : index - 1; } // label before new/removed bendpoint if (index < bendpointIndex) { newIndex = index; // decide label should take right or left segment if (insert && attachment.type !== 'bendpoint' && bendpointIndex - 1 === index) { var rel = relativePositionMidWaypoint(newWaypoints, bendpointIndex); if (rel < attachment.relativeLocation) { newIndex++; } } } return newIndex; } // start/end changed if (offset === 0) { return index; } if (hints.connectionStart) { return index === 0 ? 0 : null; } if (hints.connectionEnd) { return index === oldWaypoints.length - 2 ? newWaypoints.length - 2 : null; } // if nothing fits, return null return null; } /** * Calculate the required adjustment (move delta) for the given label * after the connection waypoints got updated. * * @param {djs.model.Label} label * @param {Array<Point>} newWaypoints * @param {Array<Point>} oldWaypoints * @param {Object} hints * * @return {Point} delta */ function getLabelAdjustment(label, newWaypoints, oldWaypoints, hints) { var x = 0, y = 0; var labelPosition = getLabelMid(label); // get closest attachment var attachment = (0, _LineAttachmentUtil.getAttachment)(labelPosition, oldWaypoints), oldLabelLineIndex = attachment.segmentIndex, newLabelLineIndex = findNewLabelLineStartIndex(oldWaypoints, newWaypoints, attachment, hints); if (newLabelLineIndex === null) { return { x: x, y: y }; } // should never happen // TODO(@janstuemmel): throw an error here when connectionSegmentMove is refactored if (newLabelLineIndex < 0 || newLabelLineIndex > newWaypoints.length - 2) { return { x: x, y: y }; } var oldLabelLine = getLine(oldWaypoints, oldLabelLineIndex), newLabelLine = getLine(newWaypoints, newLabelLineIndex), oldFoot = attachment.position; var relativeFootPosition = getRelativeFootPosition(oldLabelLine, oldFoot), angleDelta = getAngleDelta(oldLabelLine, newLabelLine); // special rule if label on bendpoint if (attachment.type === 'bendpoint') { var offset = newWaypoints.length - oldWaypoints.length, oldBendpointIndex = attachment.bendpointIndex, oldBendpoint = oldWaypoints[oldBendpointIndex]; // bendpoint position hasn't changed, return same position if (newWaypoints.indexOf(oldBendpoint) !== -1) { return { x: x, y: y }; } // new bendpoint and old bendpoint have same index, then just return the offset if (offset === 0) { var newBendpoint = newWaypoints[oldBendpointIndex]; return { x: newBendpoint.x - attachment.position.x, y: newBendpoint.y - attachment.position.y }; } // if bendpoints get removed if (offset < 0 && oldBendpointIndex !== 0 && oldBendpointIndex < oldWaypoints.length - 1) { relativeFootPosition = relativePositionMidWaypoint(oldWaypoints, oldBendpointIndex); } } var newFoot = { x: (newLabelLine[1].x - newLabelLine[0].x) * relativeFootPosition + newLabelLine[0].x, y: (newLabelLine[1].y - newLabelLine[0].y) * relativeFootPosition + newLabelLine[0].y }; // the rotated vector to label var newLabelVector = (0, _GeometricUtil.rotateVector)({ x: labelPosition.x - oldFoot.x, y: labelPosition.y - oldFoot.y }, angleDelta); // the new relative position x = newFoot.x + newLabelVector.x - labelPosition.x; y = newFoot.y + newLabelVector.y - labelPosition.y; return (0, _LayoutUtil.roundPoint)({ x: x, y: y }); } // HELPERS ////////////////////// function relativePositionMidWaypoint(waypoints, idx) { var distanceSegment1 = (0, _GeometricUtil.getDistancePointPoint)(waypoints[idx - 1], waypoints[idx]), distanceSegment2 = (0, _GeometricUtil.getDistancePointPoint)(waypoints[idx], waypoints[idx + 1]); var relativePosition = distanceSegment1 / (distanceSegment1 + distanceSegment2); return relativePosition; } function getLabelMid(label) { return { x: label.x + label.width / 2, y: label.y + label.height / 2 }; } function getAngleDelta(l1, l2) { var a1 = (0, _GeometricUtil.getAngle)(l1), a2 = (0, _GeometricUtil.getAngle)(l2); return a2 - a1; } function getLine(waypoints, idx) { return [waypoints[idx], waypoints[idx + 1]]; } function getRelativeFootPosition(line, foot) { var length = (0, _GeometricUtil.getDistancePointPoint)(line[0], line[1]), lengthToFoot = (0, _GeometricUtil.getDistancePointPoint)(line[0], foot); return length === 0 ? 0 : lengthToFoot / length; } },{"./GeometricUtil":96,"./LineAttachmentUtil":98,"diagram-js/lib/layout/LayoutUtil":300}],98:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getAttachment = getAttachment; var sqrt = Math.sqrt, min = Math.min, max = Math.max, abs = Math.abs; /** * Calculate the square (power to two) of a number. * * @param {number} n * * @return {number} */ function sq(n) { return Math.pow(n, 2); } /** * Get distance between two points. * * @param {Point} p1 * @param {Point} p2 * * @return {number} */ function getDistance(p1, p2) { return sqrt(sq(p1.x - p2.x) + sq(p1.y - p2.y)); } /** * Return the attachment of the given point on the specified line. * * The attachment is either a bendpoint (attached to the given point) * or segment (attached to a location on a line segment) attachment: * * ```javascript * var pointAttachment = { * type: 'bendpoint', * bendpointIndex: 3, * position: { x: 10, y: 10 } // the attach point on the line * }; * * var segmentAttachment = { * type: 'segment', * segmentIndex: 2, * relativeLocation: 0.31, // attach point location between 0 (at start) and 1 (at end) * position: { x: 10, y: 10 } // the attach point on the line * }; * ``` * * @param {Point} point * @param {Array<Point>} line * * @return {Object} attachment */ function getAttachment(point, line) { var idx = 0, segmentStart, segmentEnd, segmentStartDistance, segmentEndDistance, attachmentPosition, minDistance, intersections, attachment, attachmentDistance, closestAttachmentDistance, closestAttachment; for (idx = 0; idx < line.length - 1; idx++) { segmentStart = line[idx]; segmentEnd = line[idx + 1]; if (pointsEqual(segmentStart, segmentEnd)) { intersections = [segmentStart]; } else { segmentStartDistance = getDistance(point, segmentStart); segmentEndDistance = getDistance(point, segmentEnd); minDistance = min(segmentStartDistance, segmentEndDistance); intersections = getCircleSegmentIntersections(segmentStart, segmentEnd, point, minDistance); } if (intersections.length < 1) { throw new Error('expected between [1, 2] circle -> line intersections'); } // one intersection -> bendpoint attachment if (intersections.length === 1) { attachment = { type: 'bendpoint', position: intersections[0], segmentIndex: idx, bendpointIndex: pointsEqual(segmentStart, intersections[0]) ? idx : idx + 1 }; } // two intersections -> segment attachment if (intersections.length === 2) { attachmentPosition = mid(intersections[0], intersections[1]); attachment = { type: 'segment', position: attachmentPosition, segmentIndex: idx, relativeLocation: getDistance(segmentStart, attachmentPosition) / getDistance(segmentStart, segmentEnd) }; } attachmentDistance = getDistance(attachment.position, point); if (!closestAttachment || closestAttachmentDistance > attachmentDistance) { closestAttachment = attachment; closestAttachmentDistance = attachmentDistance; } } return closestAttachment; } /** * Gets the intersection between a circle and a line segment. * * @param {Point} s1 segment start * @param {Point} s2 segment end * @param {Point} cc circle center * @param {number} cr circle radius * * @return {Array<Point>} intersections */ function getCircleSegmentIntersections(s1, s2, cc, cr) { var baX = s2.x - s1.x; var baY = s2.y - s1.y; var caX = cc.x - s1.x; var caY = cc.y - s1.y; var a = baX * baX + baY * baY; var bBy2 = baX * caX + baY * caY; var c = caX * caX + caY * caY - cr * cr; var pBy2 = bBy2 / a; var q = c / a; var disc = pBy2 * pBy2 - q; // check against negative value to work around // negative, very close to zero results (-4e-15) // being produced in some environments if (disc < 0 && disc > -0.000001) { disc = 0; } if (disc < 0) { return []; } // if disc == 0 ... dealt with later var tmpSqrt = sqrt(disc); var abScalingFactor1 = -pBy2 + tmpSqrt; var abScalingFactor2 = -pBy2 - tmpSqrt; var i1 = { x: s1.x - baX * abScalingFactor1, y: s1.y - baY * abScalingFactor1 }; if (disc === 0) { // abScalingFactor1 == abScalingFactor2 return [i1]; } var i2 = { x: s1.x - baX * abScalingFactor2, y: s1.y - baY * abScalingFactor2 }; // return only points on line segment return [i1, i2].filter(function (p) { return isPointInSegment(p, s1, s2); }); } function isPointInSegment(p, segmentStart, segmentEnd) { return fenced(p.x, segmentStart.x, segmentEnd.x) && fenced(p.y, segmentStart.y, segmentEnd.y); } function fenced(n, rangeStart, rangeEnd) { // use matching threshold to work around // precision errors in intersection computation return n >= min(rangeStart, rangeEnd) - EQUAL_THRESHOLD && n <= max(rangeStart, rangeEnd) + EQUAL_THRESHOLD; } /** * Calculate mid of two points. * * @param {Point} p1 * @param {Point} p2 * * @return {Point} */ function mid(p1, p2) { return { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 }; } var EQUAL_THRESHOLD = 0.1; function pointsEqual(p1, p2) { return abs(p1.x - p2.x) <= EQUAL_THRESHOLD && abs(p1.y - p2.y) <= EQUAL_THRESHOLD; } },{}],99:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = lineIntersect; /** * Returns the intersection between two line segments a and b. * * @param {Point} l1s * @param {Point} l1e * @param {Point} l2s * @param {Point} l2e * * @return {Point} */ function lineIntersect(l1s, l1e, l2s, l2e) { // if the lines intersect, the result contains the x and y of the // intersection (treating the lines as infinite) and booleans for // whether line segment 1 or line segment 2 contain the point var denominator, a, b, c, numerator; denominator = (l2e.y - l2s.y) * (l1e.x - l1s.x) - (l2e.x - l2s.x) * (l1e.y - l1s.y); if (denominator == 0) { return null; } a = l1s.y - l2s.y; b = l1s.x - l2s.x; numerator = (l2e.x - l2s.x) * a - (l2e.y - l2s.y) * b; c = numerator / denominator; // if we cast these lines infinitely in // both directions, they intersect here return { x: Math.round(l1s.x + c * (l1e.x - l1s.x)), y: Math.round(l1s.y + c * (l1e.y - l1s.y)) }; } },{}],100:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getParticipantResizeConstraints = getParticipantResizeConstraints; var _ModelUtil = require("../../../../util/ModelUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _LaneUtil = require("../../../modeling/util/LaneUtil"); var _ResizeBehavior = require("../ResizeBehavior"); var abs = Math.abs, min = Math.min, max = Math.max; function addToTrbl(trbl, attr, value, choice) { var current = trbl[attr]; // make sure to set the value if it does not exist // or apply the correct value by comparing against // choice(value, currentValue) trbl[attr] = current === undefined ? value : choice(value, current); } function addMin(trbl, attr, value) { return addToTrbl(trbl, attr, value, min); } function addMax(trbl, attr, value) { return addToTrbl(trbl, attr, value, max); } var LANE_RIGHT_PADDING = 20, LANE_LEFT_PADDING = 50, LANE_TOP_PADDING = 20, LANE_BOTTOM_PADDING = 20; function getParticipantResizeConstraints(laneShape, resizeDirection, balanced) { var lanesRoot = (0, _LaneUtil.getLanesRoot)(laneShape); var isFirst = true, isLast = true; // max top/bottom size for lanes var allLanes = (0, _LaneUtil.collectLanes)(lanesRoot, [lanesRoot]); var laneTrbl = (0, _LayoutUtil.asTRBL)(laneShape); var maxTrbl = {}, minTrbl = {}; if (/e/.test(resizeDirection)) { minTrbl.right = laneTrbl.left + _ResizeBehavior.LANE_MIN_DIMENSIONS.width; } else if (/w/.test(resizeDirection)) { minTrbl.left = laneTrbl.right - _ResizeBehavior.LANE_MIN_DIMENSIONS.width; } allLanes.forEach(function (other) { var otherTrbl = (0, _LayoutUtil.asTRBL)(other); if (/n/.test(resizeDirection)) { if (otherTrbl.top < laneTrbl.top - 10) { isFirst = false; } // max top size (based on next element) if (balanced && abs(laneTrbl.top - otherTrbl.bottom) < 10) { addMax(maxTrbl, 'top', otherTrbl.top + _ResizeBehavior.LANE_MIN_DIMENSIONS.height); } // min top size (based on self or nested element) if (abs(laneTrbl.top - otherTrbl.top) < 5) { addMin(minTrbl, 'top', otherTrbl.bottom - _ResizeBehavior.LANE_MIN_DIMENSIONS.height); } } if (/s/.test(resizeDirection)) { if (otherTrbl.bottom > laneTrbl.bottom + 10) { isLast = false; } // max bottom size (based on previous element) if (balanced && abs(laneTrbl.bottom - otherTrbl.top) < 10) { addMin(maxTrbl, 'bottom', otherTrbl.bottom - _ResizeBehavior.LANE_MIN_DIMENSIONS.height); } // min bottom size (based on self or nested element) if (abs(laneTrbl.bottom - otherTrbl.bottom) < 5) { addMax(minTrbl, 'bottom', otherTrbl.top + _ResizeBehavior.LANE_MIN_DIMENSIONS.height); } } }); // max top/bottom/left/right size based on flow nodes var flowElements = lanesRoot.children.filter(function (s) { return !s.hidden && !s.waypoints && ((0, _ModelUtil.is)(s, 'bpmn:FlowElement') || (0, _ModelUtil.is)(s, 'bpmn:Artifact')); }); flowElements.forEach(function (flowElement) { var flowElementTrbl = (0, _LayoutUtil.asTRBL)(flowElement); if (isFirst && /n/.test(resizeDirection)) { addMin(minTrbl, 'top', flowElementTrbl.top - LANE_TOP_PADDING); } if (/e/.test(resizeDirection)) { addMax(minTrbl, 'right', flowElementTrbl.right + LANE_RIGHT_PADDING); } if (isLast && /s/.test(resizeDirection)) { addMax(minTrbl, 'bottom', flowElementTrbl.bottom + LANE_BOTTOM_PADDING); } if (/w/.test(resizeDirection)) { addMin(minTrbl, 'left', flowElementTrbl.left - LANE_LEFT_PADDING); } }); return { min: minTrbl, max: maxTrbl }; } },{"../../../../util/ModelUtil":141,"../../../modeling/util/LaneUtil":111,"../ResizeBehavior":85,"diagram-js/lib/layout/LayoutUtil":300}],101:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AddLaneHandler; var _minDash = require("min-dash"); var _Elements = require("diagram-js/lib/util/Elements"); var _LaneUtil = require("../util/LaneUtil"); /** * A handler that allows us to add a new lane * above or below an existing one. * * @param {Modeling} modeling * @param {SpaceTool} spaceTool */ function AddLaneHandler(modeling, spaceTool) { this._modeling = modeling; this._spaceTool = spaceTool; } AddLaneHandler.$inject = ['modeling', 'spaceTool']; AddLaneHandler.prototype.preExecute = function (context) { var spaceTool = this._spaceTool, modeling = this._modeling; var shape = context.shape, location = context.location; var lanesRoot = (0, _LaneUtil.getLanesRoot)(shape); var isRoot = lanesRoot === shape, laneParent = isRoot ? shape : shape.parent; var existingChildLanes = (0, _LaneUtil.getChildLanes)(laneParent); // (0) add a lane if we currently got none and are adding to root if (!existingChildLanes.length) { modeling.createShape({ type: 'bpmn:Lane' }, { x: shape.x + _LaneUtil.LANE_INDENTATION, y: shape.y, width: shape.width - _LaneUtil.LANE_INDENTATION, height: shape.height }, laneParent); } // (1) collect affected elements to create necessary space var allAffected = []; (0, _Elements.eachElement)(lanesRoot, function (element) { allAffected.push(element); // handle element labels in the diagram root if (element.label) { allAffected.push(element.label); } if (element === shape) { return []; } return (0, _minDash.filter)(element.children, function (c) { return c !== shape; }); }); var offset = location === 'top' ? -120 : 120, lanePosition = location === 'top' ? shape.y : shape.y + shape.height, spacePos = lanePosition + (location === 'top' ? 10 : -10), direction = location === 'top' ? 'n' : 's'; var adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos); spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: 0, y: offset }, direction, spacePos); // (2) create new lane at open space context.newLane = modeling.createShape({ type: 'bpmn:Lane' }, { x: shape.x + (isRoot ? _LaneUtil.LANE_INDENTATION : 0), y: lanePosition - (location === 'top' ? 120 : 0), width: shape.width - (isRoot ? _LaneUtil.LANE_INDENTATION : 0), height: 120 }, laneParent); }; },{"../util/LaneUtil":111,"diagram-js/lib/util/Elements":315,"min-dash":555}],102:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = IdClaimHandler; function IdClaimHandler(moddle) { this._moddle = moddle; } IdClaimHandler.$inject = ['moddle']; IdClaimHandler.prototype.execute = function (context) { var ids = this._moddle.ids, id = context.id, element = context.element, claiming = context.claiming; if (claiming) { ids.claim(id, element); } else { ids.unclaim(id); } }; /** * Command revert implementation. */ IdClaimHandler.prototype.revert = function (context) { var ids = this._moddle.ids, id = context.id, element = context.element, claiming = context.claiming; if (claiming) { ids.unclaim(id); } else { ids.claim(id, element); } }; },{}],103:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeLaneHandler; var _ModelUtil = require("../../../util/ModelUtil"); var _LaneUtil = require("../util/LaneUtil"); var _Elements = require("diagram-js/lib/util/Elements"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _ResizeUtil = require("diagram-js/lib/features/resize/ResizeUtil"); /** * A handler that resizes a lane. * * @param {Modeling} modeling */ function ResizeLaneHandler(modeling, spaceTool) { this._modeling = modeling; this._spaceTool = spaceTool; } ResizeLaneHandler.$inject = ['modeling', 'spaceTool']; ResizeLaneHandler.prototype.preExecute = function (context) { var shape = context.shape, newBounds = context.newBounds, balanced = context.balanced; if (balanced !== false) { this.resizeBalanced(shape, newBounds); } else { this.resizeSpace(shape, newBounds); } }; /** * Resize balanced, adjusting next / previous lane sizes. * * @param {djs.model.Shape} shape * @param {Bounds} newBounds */ ResizeLaneHandler.prototype.resizeBalanced = function (shape, newBounds) { var modeling = this._modeling; var resizeNeeded = (0, _LaneUtil.computeLanesResize)(shape, newBounds); // resize the lane modeling.resizeShape(shape, newBounds); // resize other lanes as needed resizeNeeded.forEach(function (r) { modeling.resizeShape(r.shape, r.newBounds); }); }; /** * Resize, making actual space and moving below / above elements. * * @param {djs.model.Shape} shape * @param {Bounds} newBounds */ ResizeLaneHandler.prototype.resizeSpace = function (shape, newBounds) { var spaceTool = this._spaceTool; var shapeTrbl = (0, _LayoutUtil.asTRBL)(shape), newTrbl = (0, _LayoutUtil.asTRBL)(newBounds); var trblDiff = (0, _ResizeUtil.substractTRBL)(newTrbl, shapeTrbl); var lanesRoot = (0, _LaneUtil.getLanesRoot)(shape); var allAffected = [], allLanes = []; (0, _Elements.eachElement)(lanesRoot, function (element) { allAffected.push(element); if ((0, _ModelUtil.is)(element, 'bpmn:Lane') || (0, _ModelUtil.is)(element, 'bpmn:Participant')) { allLanes.push(element); } return element.children; }); var change, spacePos, direction, offset, adjustments; if (trblDiff.bottom || trblDiff.top) { change = trblDiff.bottom || trblDiff.top; spacePos = shape.y + (trblDiff.bottom ? shape.height : 0) + (trblDiff.bottom ? -10 : 10); direction = trblDiff.bottom ? 's' : 'n'; offset = trblDiff.top > 0 || trblDiff.bottom < 0 ? -change : change; adjustments = spaceTool.calculateAdjustments(allAffected, 'y', offset, spacePos); spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: 0, y: change }, direction); } if (trblDiff.left || trblDiff.right) { change = trblDiff.right || trblDiff.left; spacePos = shape.x + (trblDiff.right ? shape.width : 0) + (trblDiff.right ? -10 : 100); direction = trblDiff.right ? 'e' : 'w'; offset = trblDiff.left > 0 || trblDiff.right < 0 ? -change : change; adjustments = spaceTool.calculateAdjustments(allLanes, 'x', offset, spacePos); spaceTool.makeSpace(adjustments.movingShapes, adjustments.resizingShapes, { x: change, y: 0 }, direction); } }; },{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"diagram-js/lib/features/resize/ResizeUtil":268,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Elements":315}],104:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SetColorHandler; var _minDash = require("min-dash"); var DEFAULT_COLORS = { fill: undefined, stroke: undefined }; function SetColorHandler(commandStack) { this._commandStack = commandStack; } SetColorHandler.$inject = ['commandStack']; SetColorHandler.prototype.postExecute = function (context) { var elements = context.elements, colors = context.colors || DEFAULT_COLORS; var self = this; var di = {}; if ('fill' in colors) { (0, _minDash.assign)(di, { fill: colors.fill }); } if ('stroke' in colors) { (0, _minDash.assign)(di, { stroke: colors.stroke }); } (0, _minDash.forEach)(elements, function (element) { self._commandStack.execute('element.updateProperties', { element: element, properties: { di: di } }); }); }; },{"min-dash":555}],105:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SplitLaneHandler; var _LaneUtil = require("../util/LaneUtil"); /** * A handler that splits a lane into a number of sub-lanes, * creating new sub lanes, if necessary. * * @param {Modeling} modeling */ function SplitLaneHandler(modeling, translate) { this._modeling = modeling; this._translate = translate; } SplitLaneHandler.$inject = ['modeling', 'translate']; SplitLaneHandler.prototype.preExecute = function (context) { var modeling = this._modeling, translate = this._translate; var shape = context.shape, newLanesCount = context.count; var childLanes = (0, _LaneUtil.getChildLanes)(shape), existingLanesCount = childLanes.length; if (existingLanesCount > newLanesCount) { throw new Error(translate('more than {count} child lanes', { count: newLanesCount })); } var newLanesHeight = Math.round(shape.height / newLanesCount); // Iterate from top to bottom in child lane order, // resizing existing lanes and creating new ones // so that they split the parent proportionally. // // Due to rounding related errors, the bottom lane // needs to take up all the remaining space. var laneY, laneHeight, laneBounds, newLaneAttrs, idx; for (idx = 0; idx < newLanesCount; idx++) { laneY = shape.y + idx * newLanesHeight; // if bottom lane if (idx === newLanesCount - 1) { laneHeight = shape.height - newLanesHeight * idx; } else { laneHeight = newLanesHeight; } laneBounds = { x: shape.x + _LaneUtil.LANE_INDENTATION, y: laneY, width: shape.width - _LaneUtil.LANE_INDENTATION, height: laneHeight }; if (idx < existingLanesCount) { // resize existing lane modeling.resizeShape(childLanes[idx], laneBounds); } else { // create a new lane at position newLaneAttrs = { type: 'bpmn:Lane' }; modeling.createShape(newLaneAttrs, laneBounds, shape); } } }; },{"../util/LaneUtil":111}],106:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateCanvasRootHandler; var _Collections = require("diagram-js/lib/util/Collections"); function UpdateCanvasRootHandler(canvas, modeling) { this._canvas = canvas; this._modeling = modeling; } UpdateCanvasRootHandler.$inject = ['canvas', 'modeling']; UpdateCanvasRootHandler.prototype.execute = function (context) { var canvas = this._canvas; var newRoot = context.newRoot, newRootBusinessObject = newRoot.businessObject, oldRoot = canvas.getRootElement(), oldRootBusinessObject = oldRoot.businessObject, bpmnDefinitions = oldRootBusinessObject.$parent, diPlane = oldRootBusinessObject.di; // (1) replace process old <> new root canvas.setRootElement(newRoot, true); // (2) update root elements (0, _Collections.add)(bpmnDefinitions.rootElements, newRootBusinessObject); newRootBusinessObject.$parent = bpmnDefinitions; (0, _Collections.remove)(bpmnDefinitions.rootElements, oldRootBusinessObject); oldRootBusinessObject.$parent = null; // (3) wire di oldRootBusinessObject.di = null; diPlane.bpmnElement = newRootBusinessObject; newRootBusinessObject.di = diPlane; context.oldRoot = oldRoot; // TODO(nikku): return changed elements? // return [ newRoot, oldRoot ]; }; UpdateCanvasRootHandler.prototype.revert = function (context) { var canvas = this._canvas; var newRoot = context.newRoot, newRootBusinessObject = newRoot.businessObject, oldRoot = context.oldRoot, oldRootBusinessObject = oldRoot.businessObject, bpmnDefinitions = newRootBusinessObject.$parent, diPlane = newRootBusinessObject.di; // (1) replace process old <> new root canvas.setRootElement(oldRoot, true); // (2) update root elements (0, _Collections.remove)(bpmnDefinitions.rootElements, newRootBusinessObject); newRootBusinessObject.$parent = null; (0, _Collections.add)(bpmnDefinitions.rootElements, oldRootBusinessObject); oldRootBusinessObject.$parent = bpmnDefinitions; // (3) wire di newRootBusinessObject.di = null; diPlane.bpmnElement = oldRootBusinessObject; oldRootBusinessObject.di = diPlane; // TODO(nikku): return changed elements? // return [ newRoot, oldRoot ]; }; },{"diagram-js/lib/util/Collections":313}],107:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateFlowNodeRefsHandler; var _LaneUtil = require("../util/LaneUtil"); var _ModelUtil = require("../../../util/ModelUtil"); var _Collections = require("diagram-js/lib/util/Collections"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var FLOW_NODE_REFS_ATTR = 'flowNodeRef', LANES_ATTR = 'lanes'; /** * A handler that updates lane refs on changed elements */ function UpdateFlowNodeRefsHandler(elementRegistry) { this._elementRegistry = elementRegistry; } UpdateFlowNodeRefsHandler.$inject = ['elementRegistry']; UpdateFlowNodeRefsHandler.prototype.computeUpdates = function (flowNodeShapes, laneShapes) { var handledNodes = []; var updates = []; var participantCache = {}; var allFlowNodeShapes = []; function isInLaneShape(element, laneShape) { var laneTrbl = (0, _LayoutUtil.asTRBL)(laneShape); var elementMid = { x: element.x + element.width / 2, y: element.y + element.height / 2 }; return elementMid.x > laneTrbl.left && elementMid.x < laneTrbl.right && elementMid.y > laneTrbl.top && elementMid.y < laneTrbl.bottom; } function addFlowNodeShape(flowNodeShape) { if (handledNodes.indexOf(flowNodeShape) === -1) { allFlowNodeShapes.push(flowNodeShape); handledNodes.push(flowNodeShape); } } function getAllLaneShapes(flowNodeShape) { var root = (0, _LaneUtil.getLanesRoot)(flowNodeShape); if (!participantCache[root.id]) { participantCache[root.id] = (0, _LaneUtil.collectLanes)(root); } return participantCache[root.id]; } function getNewLanes(flowNodeShape) { if (!flowNodeShape.parent) { return []; } var allLaneShapes = getAllLaneShapes(flowNodeShape); return allLaneShapes.filter(function (l) { return isInLaneShape(flowNodeShape, l); }).map(function (shape) { return shape.businessObject; }); } laneShapes.forEach(function (laneShape) { var root = (0, _LaneUtil.getLanesRoot)(laneShape); if (!root || handledNodes.indexOf(root) !== -1) { return; } var children = root.children.filter(function (c) { return (0, _ModelUtil.is)(c, 'bpmn:FlowNode'); }); children.forEach(addFlowNodeShape); handledNodes.push(root); }); flowNodeShapes.forEach(addFlowNodeShape); allFlowNodeShapes.forEach(function (flowNodeShape) { var flowNode = flowNodeShape.businessObject; var lanes = flowNode.get(LANES_ATTR), remove = lanes.slice(), add = getNewLanes(flowNodeShape); updates.push({ flowNode: flowNode, remove: remove, add: add }); }); laneShapes.forEach(function (laneShape) { var lane = laneShape.businessObject; // lane got removed XX-) if (!laneShape.parent) { lane.get(FLOW_NODE_REFS_ATTR).forEach(function (flowNode) { updates.push({ flowNode: flowNode, remove: [lane], add: [] }); }); } }); return updates; }; UpdateFlowNodeRefsHandler.prototype.execute = function (context) { var updates = context.updates; if (!updates) { updates = context.updates = this.computeUpdates(context.flowNodeShapes, context.laneShapes); } updates.forEach(function (update) { var flowNode = update.flowNode, lanes = flowNode.get(LANES_ATTR); // unwire old update.remove.forEach(function (oldLane) { (0, _Collections.remove)(lanes, oldLane); (0, _Collections.remove)(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode); }); // wire new update.add.forEach(function (newLane) { (0, _Collections.add)(lanes, newLane); (0, _Collections.add)(newLane.get(FLOW_NODE_REFS_ATTR), flowNode); }); }); // TODO(nikku): return changed elements // return [ ... ]; }; UpdateFlowNodeRefsHandler.prototype.revert = function (context) { var updates = context.updates; updates.forEach(function (update) { var flowNode = update.flowNode, lanes = flowNode.get(LANES_ATTR); // unwire new update.add.forEach(function (newLane) { (0, _Collections.remove)(lanes, newLane); (0, _Collections.remove)(newLane.get(FLOW_NODE_REFS_ATTR), flowNode); }); // wire old update.remove.forEach(function (oldLane) { (0, _Collections.add)(lanes, oldLane); (0, _Collections.add)(oldLane.get(FLOW_NODE_REFS_ATTR), flowNode); }); }); // TODO(nikku): return changed elements // return [ ... ]; }; },{"../../../util/ModelUtil":141,"../util/LaneUtil":111,"diagram-js/lib/layout/LayoutUtil":300,"diagram-js/lib/util/Collections":313}],108:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdatePropertiesHandler; var _minDash = require("min-dash"); var _ModelUtil = require("../../../util/ModelUtil"); var DEFAULT_FLOW = 'default', ID = 'id', DI = 'di'; var NULL_DIMENSIONS = { width: 0, height: 0 }; /** * A handler that implements a BPMN 2.0 property update. * * This should be used to set simple properties on elements with * an underlying BPMN business object. * * Use respective diagram-js provided handlers if you would * like to perform automated modeling. */ function UpdatePropertiesHandler(elementRegistry, moddle, translate, modeling, textRenderer) { this._elementRegistry = elementRegistry; this._moddle = moddle; this._translate = translate; this._modeling = modeling; this._textRenderer = textRenderer; } UpdatePropertiesHandler.$inject = ['elementRegistry', 'moddle', 'translate', 'modeling', 'textRenderer']; // api ////////////////////// /** * Updates a BPMN element with a list of new properties * * @param {Object} context * @param {djs.model.Base} context.element the element to update * @param {Object} context.properties a list of properties to set on the element's * businessObject (the BPMN model element) * * @return {Array<djs.model.Base>} the updated element */ UpdatePropertiesHandler.prototype.execute = function (context) { var element = context.element, changed = [element], translate = this._translate; if (!element) { throw new Error(translate('element required')); } var elementRegistry = this._elementRegistry, ids = this._moddle.ids; var businessObject = element.businessObject, properties = unwrapBusinessObjects(context.properties), oldProperties = context.oldProperties || getProperties(businessObject, properties); if (isIdChange(properties, businessObject)) { ids.unclaim(businessObject[ID]); elementRegistry.updateId(element, properties[ID]); ids.claim(properties[ID], businessObject); } // correctly indicate visual changes on default flow updates if (DEFAULT_FLOW in properties) { if (properties[DEFAULT_FLOW]) { changed.push(elementRegistry.get(properties[DEFAULT_FLOW].id)); } if (businessObject[DEFAULT_FLOW]) { changed.push(elementRegistry.get(businessObject[DEFAULT_FLOW].id)); } } // update properties setProperties(businessObject, properties); // store old values context.oldProperties = oldProperties; context.changed = changed; // indicate changed on objects affected by the update return changed; }; UpdatePropertiesHandler.prototype.postExecute = function (context) { var element = context.element, label = element.label; var text = label && (0, _ModelUtil.getBusinessObject)(label).name; if (!text) { return; } // get layouted text bounds and resize external // external label accordingly var newLabelBounds = this._textRenderer.getExternalLabelBounds(label, text); this._modeling.resizeShape(label, newLabelBounds, NULL_DIMENSIONS); }; /** * Reverts the update on a BPMN elements properties. * * @param {Object} context * * @return {djs.model.Base} the updated element */ UpdatePropertiesHandler.prototype.revert = function (context) { var element = context.element, properties = context.properties, oldProperties = context.oldProperties, businessObject = element.businessObject, elementRegistry = this._elementRegistry, ids = this._moddle.ids; // update properties setProperties(businessObject, oldProperties); if (isIdChange(properties, businessObject)) { ids.unclaim(properties[ID]); elementRegistry.updateId(element, oldProperties[ID]); ids.claim(oldProperties[ID], businessObject); } return context.changed; }; function isIdChange(properties, businessObject) { return ID in properties && properties[ID] !== businessObject[ID]; } function getProperties(businessObject, properties) { var propertyNames = (0, _minDash.keys)(properties); return (0, _minDash.reduce)(propertyNames, function (result, key) { // handle DI separately if (key !== DI) { result[key] = businessObject.get(key); } else { result[key] = getDiProperties(businessObject.di, (0, _minDash.keys)(properties.di)); } return result; }, {}); } function getDiProperties(di, propertyNames) { return (0, _minDash.reduce)(propertyNames, function (result, key) { result[key] = di.get(key); return result; }, {}); } function setProperties(businessObject, properties) { (0, _minDash.forEach)(properties, function (value, key) { if (key !== DI) { businessObject.set(key, value); } else { // only update, if businessObject.di exists if (businessObject.di) { setDiProperties(businessObject.di, value); } } }); } function setDiProperties(di, properties) { (0, _minDash.forEach)(properties, function (value, key) { di.set(key, value); }); } var referencePropertyNames = ['default']; /** * Make sure we unwrap the actual business object * behind diagram element that may have been * passed as arguments. * * @param {Object} properties * * @return {Object} unwrappedProps */ function unwrapBusinessObjects(properties) { var unwrappedProps = (0, _minDash.assign)({}, properties); referencePropertyNames.forEach(function (name) { if (name in properties) { unwrappedProps[name] = (0, _ModelUtil.getBusinessObject)(unwrappedProps[name]); } }); return unwrappedProps; } },{"../../../util/ModelUtil":141,"min-dash":555}],109:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateSemanticParentHandler; function UpdateSemanticParentHandler(bpmnUpdater) { this._bpmnUpdater = bpmnUpdater; } UpdateSemanticParentHandler.$inject = ['bpmnUpdater']; UpdateSemanticParentHandler.prototype.execute = function (context) { var dataStoreBo = context.dataStoreBo, newSemanticParent = context.newSemanticParent, newDiParent = context.newDiParent; context.oldSemanticParent = dataStoreBo.$parent; context.oldDiParent = dataStoreBo.di.$parent; // update semantic parent this._bpmnUpdater.updateSemanticParent(dataStoreBo, newSemanticParent); // update DI parent this._bpmnUpdater.updateDiParent(dataStoreBo.di, newDiParent); }; UpdateSemanticParentHandler.prototype.revert = function (context) { var dataStoreBo = context.dataStoreBo, oldSemanticParent = context.oldSemanticParent, oldDiParent = context.oldDiParent; // update semantic parent this._bpmnUpdater.updateSemanticParent(dataStoreBo, oldSemanticParent); // update DI parent this._bpmnUpdater.updateDiParent(dataStoreBo.di, oldDiParent); }; },{}],110:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _behavior = _interopRequireDefault(require("./behavior")); var _rules = _interopRequireDefault(require("../rules")); var _diOrdering = _interopRequireDefault(require("../di-ordering")); var _ordering = _interopRequireDefault(require("../ordering")); var _replace = _interopRequireDefault(require("../replace")); var _command = _interopRequireDefault(require("diagram-js/lib/command")); var _tooltips = _interopRequireDefault(require("diagram-js/lib/features/tooltips")); var _labelSupport = _interopRequireDefault(require("diagram-js/lib/features/label-support")); var _attachSupport = _interopRequireDefault(require("diagram-js/lib/features/attach-support")); var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection")); var _changeSupport = _interopRequireDefault(require("diagram-js/lib/features/change-support")); var _spaceTool = _interopRequireDefault(require("diagram-js/lib/features/space-tool")); var _BpmnFactory = _interopRequireDefault(require("./BpmnFactory")); var _BpmnUpdater = _interopRequireDefault(require("./BpmnUpdater")); var _ElementFactory = _interopRequireDefault(require("./ElementFactory")); var _Modeling = _interopRequireDefault(require("./Modeling")); var _BpmnLayouter = _interopRequireDefault(require("./BpmnLayouter")); var _CroppingConnectionDocking = _interopRequireDefault(require("diagram-js/lib/layout/CroppingConnectionDocking")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['modeling', 'bpmnUpdater'], __depends__: [_behavior.default, _rules.default, _diOrdering.default, _ordering.default, _replace.default, _command.default, _tooltips.default, _labelSupport.default, _attachSupport.default, _selection.default, _changeSupport.default, _spaceTool.default], bpmnFactory: ['type', _BpmnFactory.default], bpmnUpdater: ['type', _BpmnUpdater.default], elementFactory: ['type', _ElementFactory.default], modeling: ['type', _Modeling.default], layouter: ['type', _BpmnLayouter.default], connectionDocking: ['type', _CroppingConnectionDocking.default] }; exports.default = _default; },{"../di-ordering":36,"../ordering":114,"../replace":124,"../rules":126,"./BpmnFactory":56,"./BpmnLayouter":57,"./BpmnUpdater":58,"./ElementFactory":59,"./Modeling":60,"./behavior":94,"diagram-js/lib/command":147,"diagram-js/lib/features/attach-support":161,"diagram-js/lib/features/change-support":178,"diagram-js/lib/features/label-support":219,"diagram-js/lib/features/selection":278,"diagram-js/lib/features/space-tool":288,"diagram-js/lib/features/tooltips":292,"diagram-js/lib/layout/CroppingConnectionDocking":299}],111:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.collectLanes = collectLanes; exports.getChildLanes = getChildLanes; exports.getLanesRoot = getLanesRoot; exports.computeLanesResize = computeLanesResize; exports.LANE_INDENTATION = void 0; var _ModelUtil = require("../../../util/ModelUtil"); var _ModelingUtil = require("./ModelingUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _ResizeUtil = require("diagram-js/lib/features/resize/ResizeUtil"); var abs = Math.abs; function getTRBLResize(oldBounds, newBounds) { return (0, _ResizeUtil.substractTRBL)((0, _LayoutUtil.asTRBL)(newBounds), (0, _LayoutUtil.asTRBL)(oldBounds)); } var LANE_PARENTS = ['bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess']; var LANE_INDENTATION = 30; /** * Collect all lane shapes in the given paren * * @param {djs.model.Shape} shape * @param {Array<djs.model.Base>} [collectedShapes] * * @return {Array<djs.model.Base>} */ exports.LANE_INDENTATION = LANE_INDENTATION; function collectLanes(shape, collectedShapes) { collectedShapes = collectedShapes || []; shape.children.filter(function (s) { if ((0, _ModelUtil.is)(s, 'bpmn:Lane')) { collectLanes(s, collectedShapes); collectedShapes.push(s); } }); return collectedShapes; } /** * Return the lane children of the given element. * * @param {djs.model.Shape} shape * * @return {Array<djs.model.Shape>} */ function getChildLanes(shape) { return shape.children.filter(function (c) { return (0, _ModelUtil.is)(c, 'bpmn:Lane'); }); } /** * Return the root element containing the given lane shape * * @param {djs.model.Shape} shape * * @return {djs.model.Shape} */ function getLanesRoot(shape) { return (0, _ModelingUtil.getParent)(shape, LANE_PARENTS) || shape; } /** * Compute the required resize operations for lanes * adjacent to the given shape, assuming it will be * resized to the given new bounds. * * @param {djs.model.Shape} shape * @param {Bounds} newBounds * * @return {Array<Object>} */ function computeLanesResize(shape, newBounds) { var rootElement = getLanesRoot(shape); var initialShapes = (0, _ModelUtil.is)(rootElement, 'bpmn:Process') ? [] : [rootElement]; var allLanes = collectLanes(rootElement, initialShapes), shapeTrbl = (0, _LayoutUtil.asTRBL)(shape), shapeNewTrbl = (0, _LayoutUtil.asTRBL)(newBounds), trblResize = getTRBLResize(shape, newBounds), resizeNeeded = []; allLanes.forEach(function (other) { if (other === shape) { return; } var topResize = 0, rightResize = trblResize.right, bottomResize = 0, leftResize = trblResize.left; var otherTrbl = (0, _LayoutUtil.asTRBL)(other); if (trblResize.top) { if (abs(otherTrbl.bottom - shapeTrbl.top) < 10) { bottomResize = shapeNewTrbl.top - otherTrbl.bottom; } if (abs(otherTrbl.top - shapeTrbl.top) < 5) { topResize = shapeNewTrbl.top - otherTrbl.top; } } if (trblResize.bottom) { if (abs(otherTrbl.top - shapeTrbl.bottom) < 10) { topResize = shapeNewTrbl.bottom - otherTrbl.top; } if (abs(otherTrbl.bottom - shapeTrbl.bottom) < 5) { bottomResize = shapeNewTrbl.bottom - otherTrbl.bottom; } } if (topResize || rightResize || bottomResize || leftResize) { resizeNeeded.push({ shape: other, newBounds: (0, _ResizeUtil.resizeTRBL)(other, { top: topResize, right: rightResize, bottom: bottomResize, left: leftResize }) }); } }); return resizeNeeded; } },{"../../../util/ModelUtil":141,"./ModelingUtil":112,"diagram-js/lib/features/resize/ResizeUtil":268,"diagram-js/lib/layout/LayoutUtil":300}],112:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isAny = isAny; exports.getParent = getParent; var _minDash = require("min-dash"); var _ModelUtil = require("../../../util/ModelUtil"); /** * Return true if element has any of the given types. * * @param {djs.model.Base} element * @param {Array<string>} types * * @return {boolean} */ function isAny(element, types) { return (0, _minDash.some)(types, function (t) { return (0, _ModelUtil.is)(element, t); }); } /** * Return the parent of the element with any of the given types. * * @param {djs.model.Base} element * @param {string|Array<string>} anyType * * @return {djs.model.Base} */ function getParent(element, anyType) { if (typeof anyType === 'string') { anyType = [anyType]; } while (element = element.parent) { if (isAny(element, anyType)) { return element; } } return null; } },{"../../../util/ModelUtil":141,"min-dash":555}],113:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnOrderingProvider; var _inherits = _interopRequireDefault(require("inherits")); var _OrderingProvider = _interopRequireDefault(require("diagram-js/lib/features/ordering/OrderingProvider")); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * a simple ordering provider that makes sure: * * (0) labels and groups are rendered always on top * (1) elements are ordered by a {level} property */ function BpmnOrderingProvider(eventBus, canvas, translate) { _OrderingProvider.default.call(this, eventBus); var orders = [{ type: 'bpmn:SubProcess', order: { level: 6 } }, { type: 'bpmn:SequenceFlow', order: { level: 3, containers: ['bpmn:Participant', 'bpmn:FlowElementsContainer'] } }, // handle DataAssociation(s) like message flows and render them always on top { type: 'bpmn:DataAssociation', order: { level: 9, containers: ['bpmn:Collaboration', 'bpmn:Process'] } }, { type: 'bpmn:MessageFlow', order: { level: 9, containers: ['bpmn:Collaboration'] } }, { type: 'bpmn:Association', order: { level: 6, containers: ['bpmn:Participant', 'bpmn:FlowElementsContainer', 'bpmn:Collaboration'] } }, { type: 'bpmn:BoundaryEvent', order: { level: 8 } }, { type: 'bpmn:Group', order: { level: 10, containers: ['bpmn:Collaboration', 'bpmn:Process'] } }, { type: 'bpmn:FlowElement', order: { level: 5 } }, { type: 'bpmn:Participant', order: { level: -2 } }, { type: 'bpmn:Lane', order: { level: -1 } }]; function computeOrder(element) { if (element.labelTarget) { return { level: 10 }; } var entry = (0, _minDash.find)(orders, function (o) { return (0, _ModelingUtil.isAny)(element, [o.type]); }); return entry && entry.order || { level: 1 }; } function getOrder(element) { var order = element.order; if (!order) { element.order = order = computeOrder(element); } return order; } function findActualParent(element, newParent, containers) { var actualParent = newParent; while (actualParent) { if ((0, _ModelingUtil.isAny)(actualParent, containers)) { break; } actualParent = actualParent.parent; } if (!actualParent) { throw new Error(translate('no parent for {element} in {parent}', { element: element.id, parent: newParent.id })); } return actualParent; } this.getOrdering = function (element, newParent) { // render labels always on top if (element.labelTarget) { return { parent: canvas.getRootElement(), index: -1 }; } var elementOrder = getOrder(element); if (elementOrder.containers) { newParent = findActualParent(element, newParent, elementOrder.containers); } var currentIndex = newParent.children.indexOf(element); var insertIndex = (0, _minDash.findIndex)(newParent.children, function (child) { // do not compare with labels, they are created // in the wrong order (right after elements) during import and // mess up the positioning. if (!element.labelTarget && child.labelTarget) { return false; } return elementOrder.level < getOrder(child).level; }); // if the element is already in the child list at // a smaller index, we need to adjust the insert index. // this takes into account that the element is being removed // before being re-inserted if (insertIndex !== -1) { if (currentIndex !== -1 && currentIndex < insertIndex) { insertIndex -= 1; } } return { index: insertIndex, parent: newParent }; }; } BpmnOrderingProvider.$inject = ['eventBus', 'canvas', 'translate']; (0, _inherits.default)(BpmnOrderingProvider, _OrderingProvider.default); },{"../modeling/util/ModelingUtil":112,"diagram-js/lib/features/ordering/OrderingProvider":252,"inherits":347,"min-dash":555}],114:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate")); var _BpmnOrderingProvider = _interopRequireDefault(require("./BpmnOrderingProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_translate.default], __init__: ['bpmnOrderingProvider'], bpmnOrderingProvider: ['type', _BpmnOrderingProvider.default] }; exports.default = _default; },{"./BpmnOrderingProvider":113,"diagram-js/lib/i18n/translate":296}],115:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = PaletteProvider; var _minDash = require("min-dash"); /** * A palette provider for BPMN 2.0 elements. */ function PaletteProvider(palette, create, elementFactory, spaceTool, lassoTool, handTool, globalConnect, translate) { this._palette = palette; this._create = create; this._elementFactory = elementFactory; this._spaceTool = spaceTool; this._lassoTool = lassoTool; this._handTool = handTool; this._globalConnect = globalConnect; this._translate = translate; palette.registerProvider(this); } PaletteProvider.$inject = ['palette', 'create', 'elementFactory', 'spaceTool', 'lassoTool', 'handTool', 'globalConnect', 'translate']; PaletteProvider.prototype.getPaletteEntries = function (element) { var actions = {}, create = this._create, elementFactory = this._elementFactory, spaceTool = this._spaceTool, lassoTool = this._lassoTool, handTool = this._handTool, globalConnect = this._globalConnect, translate = this._translate; function createAction(type, group, className, title, options) { function createListener(event) { var shape = elementFactory.createShape((0, _minDash.assign)({ type: type }, options)); if (options) { shape.businessObject.di.isExpanded = options.isExpanded; } create.start(event, shape); } var shortType = type.replace(/^bpmn:/, ''); return { group: group, className: className, title: title || translate('Create {type}', { type: shortType }), action: { dragstart: createListener, click: createListener } }; } function createSubprocess(event) { var subProcess = elementFactory.createShape({ type: 'bpmn:SubProcess', x: 0, y: 0, isExpanded: true }); var startEvent = elementFactory.createShape({ type: 'bpmn:StartEvent', x: 40, y: 82, parent: subProcess }); create.start(event, [subProcess, startEvent], { hints: { autoSelect: [startEvent] } }); } function createParticipant(event) { create.start(event, elementFactory.createParticipantShape()); } (0, _minDash.assign)(actions, { 'hand-tool': { group: 'tools', className: 'bpmn-icon-hand-tool', title: translate('Activate the hand tool'), action: { click: function (event) { handTool.activateHand(event); } } }, 'lasso-tool': { group: 'tools', className: 'bpmn-icon-lasso-tool', title: translate('Activate the lasso tool'), action: { click: function (event) { lassoTool.activateSelection(event); } } }, 'space-tool': { group: 'tools', className: 'bpmn-icon-space-tool', title: translate('Activate the create/remove space tool'), action: { click: function (event) { spaceTool.activateSelection(event); } } }, 'global-connect-tool': { group: 'tools', className: 'bpmn-icon-connection-multi', title: translate('Activate the global connect tool'), action: { click: function (event) { globalConnect.toggle(event); } } }, 'tool-separator': { group: 'tools', separator: true }, 'create.start-event': createAction('bpmn:StartEvent', 'event', 'bpmn-icon-start-event-none', translate('Create StartEvent')), 'create.intermediate-event': createAction('bpmn:IntermediateThrowEvent', 'event', 'bpmn-icon-intermediate-event-none', translate('Create Intermediate/Boundary Event')), 'create.end-event': createAction('bpmn:EndEvent', 'event', 'bpmn-icon-end-event-none', translate('Create EndEvent')), 'create.exclusive-gateway': createAction('bpmn:ExclusiveGateway', 'gateway', 'bpmn-icon-gateway-none', translate('Create Gateway')), 'create.task': createAction('bpmn:Task', 'activity', 'bpmn-icon-task', translate('Create Task')), 'create.data-object': createAction('bpmn:DataObjectReference', 'data-object', 'bpmn-icon-data-object', translate('Create DataObjectReference')), 'create.data-store': createAction('bpmn:DataStoreReference', 'data-store', 'bpmn-icon-data-store', translate('Create DataStoreReference')), 'create.subprocess-expanded': { group: 'activity', className: 'bpmn-icon-subprocess-expanded', title: translate('Create expanded SubProcess'), action: { dragstart: createSubprocess, click: createSubprocess } }, 'create.participant-expanded': { group: 'collaboration', className: 'bpmn-icon-participant', title: translate('Create Pool/Participant'), action: { dragstart: createParticipant, click: createParticipant } }, 'create.group': createAction('bpmn:Group', 'artifact', 'bpmn-icon-group', translate('Create Group')) }); return actions; }; },{"min-dash":555}],116:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _palette = _interopRequireDefault(require("diagram-js/lib/features/palette")); var _create = _interopRequireDefault(require("diagram-js/lib/features/create")); var _spaceTool = _interopRequireDefault(require("diagram-js/lib/features/space-tool")); var _lassoTool = _interopRequireDefault(require("diagram-js/lib/features/lasso-tool")); var _handTool = _interopRequireDefault(require("diagram-js/lib/features/hand-tool")); var _globalConnect = _interopRequireDefault(require("diagram-js/lib/features/global-connect")); var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate")); var _PaletteProvider = _interopRequireDefault(require("./PaletteProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_palette.default, _create.default, _spaceTool.default, _lassoTool.default, _handTool.default, _globalConnect.default, _translate.default], __init__: ['paletteProvider'], paletteProvider: ['type', _PaletteProvider.default] }; exports.default = _default; },{"./PaletteProvider":115,"diagram-js/lib/features/create":192,"diagram-js/lib/features/global-connect":201,"diagram-js/lib/features/hand-tool":209,"diagram-js/lib/features/lasso-tool":221,"diagram-js/lib/features/palette":258,"diagram-js/lib/features/space-tool":288,"diagram-js/lib/i18n/translate":296}],117:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceMenuProvider; var _ModelUtil = require("../../util/ModelUtil"); var _DiUtil = require("../../util/DiUtil"); var _TypeUtil = require("./util/TypeUtil"); var _minDash = require("min-dash"); var replaceOptions = _interopRequireWildcard(require("../replace/ReplaceOptions")); function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /** * This module is an element agnostic replace menu provider for the popup menu. */ function ReplaceMenuProvider(popupMenu, modeling, moddle, bpmnReplace, rules, translate) { this._popupMenu = popupMenu; this._modeling = modeling; this._moddle = moddle; this._bpmnReplace = bpmnReplace; this._rules = rules; this._translate = translate; this.register(); } ReplaceMenuProvider.$inject = ['popupMenu', 'modeling', 'moddle', 'bpmnReplace', 'rules', 'translate']; /** * Register replace menu provider in the popup menu */ ReplaceMenuProvider.prototype.register = function () { this._popupMenu.registerProvider('bpmn-replace', this); }; /** * Get all entries from replaceOptions for the given element and apply filters * on them. Get for example only elements, which are different from the current one. * * @param {djs.model.Base} element * * @return {Array<Object>} a list of menu entry items */ ReplaceMenuProvider.prototype.getEntries = function (element) { var businessObject = element.businessObject; var rules = this._rules; var entries; if (!rules.allowed('shape.replace', { element: element })) { return []; } var differentType = (0, _TypeUtil.isDifferentType)(element); // start events outside sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && !(0, _ModelUtil.is)(businessObject.$parent, 'bpmn:SubProcess')) { entries = (0, _minDash.filter)(replaceOptions.START_EVENT, differentType); return this._createEntries(element, entries); } // expanded/collapsed pools if ((0, _ModelUtil.is)(businessObject, 'bpmn:Participant')) { entries = (0, _minDash.filter)(replaceOptions.PARTICIPANT, function (entry) { return (0, _DiUtil.isExpanded)(businessObject) !== entry.target.isExpanded; }); return this._createEntries(element, entries); } // start events inside event sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && (0, _DiUtil.isEventSubProcess)(businessObject.$parent)) { entries = (0, _minDash.filter)(replaceOptions.EVENT_SUB_PROCESS_START_EVENT, function (entry) { var target = entry.target; var isInterrupting = target.isInterrupting !== false; var isInterruptingEqual = (0, _ModelUtil.getBusinessObject)(element).isInterrupting === isInterrupting; // filters elements which types and event definition are equal but have have different interrupting types return differentType(entry) || !differentType(entry) && !isInterruptingEqual; }); return this._createEntries(element, entries); } // start events inside sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:StartEvent') && !(0, _DiUtil.isEventSubProcess)(businessObject.$parent) && (0, _ModelUtil.is)(businessObject.$parent, 'bpmn:SubProcess')) { entries = (0, _minDash.filter)(replaceOptions.START_EVENT_SUB_PROCESS, differentType); return this._createEntries(element, entries); } // end events if ((0, _ModelUtil.is)(businessObject, 'bpmn:EndEvent')) { entries = (0, _minDash.filter)(replaceOptions.END_EVENT, function (entry) { var target = entry.target; // hide cancel end events outside transactions if (target.eventDefinitionType == 'bpmn:CancelEventDefinition' && !(0, _ModelUtil.is)(businessObject.$parent, 'bpmn:Transaction')) { return false; } return differentType(entry); }); return this._createEntries(element, entries); } // boundary events if ((0, _ModelUtil.is)(businessObject, 'bpmn:BoundaryEvent')) { entries = (0, _minDash.filter)(replaceOptions.BOUNDARY_EVENT, function (entry) { var target = entry.target; if (target.eventDefinition == 'bpmn:CancelEventDefinition' && !(0, _ModelUtil.is)(businessObject.attachedToRef, 'bpmn:Transaction')) { return false; } var cancelActivity = target.cancelActivity !== false; var isCancelActivityEqual = businessObject.cancelActivity == cancelActivity; return differentType(entry) || !differentType(entry) && !isCancelActivityEqual; }); return this._createEntries(element, entries); } // intermediate events if ((0, _ModelUtil.is)(businessObject, 'bpmn:IntermediateCatchEvent') || (0, _ModelUtil.is)(businessObject, 'bpmn:IntermediateThrowEvent')) { entries = (0, _minDash.filter)(replaceOptions.INTERMEDIATE_EVENT, differentType); return this._createEntries(element, entries); } // gateways if ((0, _ModelUtil.is)(businessObject, 'bpmn:Gateway')) { entries = (0, _minDash.filter)(replaceOptions.GATEWAY, differentType); return this._createEntries(element, entries); } // transactions if ((0, _ModelUtil.is)(businessObject, 'bpmn:Transaction')) { entries = (0, _minDash.filter)(replaceOptions.TRANSACTION, differentType); return this._createEntries(element, entries); } // expanded event sub processes if ((0, _DiUtil.isEventSubProcess)(businessObject) && (0, _DiUtil.isExpanded)(businessObject)) { entries = (0, _minDash.filter)(replaceOptions.EVENT_SUB_PROCESS, differentType); return this._createEntries(element, entries); } // expanded sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(businessObject)) { entries = (0, _minDash.filter)(replaceOptions.SUBPROCESS_EXPANDED, differentType); return this._createEntries(element, entries); } // collapsed ad hoc sub processes if ((0, _ModelUtil.is)(businessObject, 'bpmn:AdHocSubProcess') && !(0, _DiUtil.isExpanded)(businessObject)) { entries = (0, _minDash.filter)(replaceOptions.TASK, function (entry) { var target = entry.target; var isTargetSubProcess = target.type === 'bpmn:SubProcess'; var isTargetExpanded = target.isExpanded === true; return (0, _TypeUtil.isDifferentType)(element, target) && (!isTargetSubProcess || isTargetExpanded); }); return this._createEntries(element, entries); } // sequence flows if ((0, _ModelUtil.is)(businessObject, 'bpmn:SequenceFlow')) { return this._createSequenceFlowEntries(element, replaceOptions.SEQUENCE_FLOW); } // flow nodes if ((0, _ModelUtil.is)(businessObject, 'bpmn:FlowNode')) { entries = (0, _minDash.filter)(replaceOptions.TASK, differentType); // collapsed SubProcess can not be replaced with itself if ((0, _ModelUtil.is)(businessObject, 'bpmn:SubProcess') && !(0, _DiUtil.isExpanded)(businessObject)) { entries = (0, _minDash.filter)(entries, function (entry) { return entry.label !== 'Sub Process (collapsed)'; }); } return this._createEntries(element, entries); } return []; }; /** * Get a list of header items for the given element. This includes buttons * for multi instance markers and for the ad hoc marker. * * @param {djs.model.Base} element * * @return {Array<Object>} a list of menu entry items */ ReplaceMenuProvider.prototype.getHeaderEntries = function (element) { var headerEntries = []; if ((0, _ModelUtil.is)(element, 'bpmn:Activity') && !(0, _DiUtil.isEventSubProcess)(element)) { headerEntries = headerEntries.concat(this._getLoopEntries(element)); } if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess') && !(0, _ModelUtil.is)(element, 'bpmn:Transaction') && !(0, _DiUtil.isEventSubProcess)(element)) { headerEntries.push(this._getAdHocEntry(element)); } return headerEntries; }; /** * Creates an array of menu entry objects for a given element and filters the replaceOptions * according to a filter function. * * @param {djs.model.Base} element * @param {Object} replaceOptions * * @return {Array<Object>} a list of menu items */ ReplaceMenuProvider.prototype._createEntries = function (element, replaceOptions) { var menuEntries = []; var self = this; (0, _minDash.forEach)(replaceOptions, function (definition) { var entry = self._createMenuEntry(definition, element); menuEntries.push(entry); }); return menuEntries; }; /** * Creates an array of menu entry objects for a given sequence flow. * * @param {djs.model.Base} element * @param {Object} replaceOptions * @return {Array<Object>} a list of menu items */ ReplaceMenuProvider.prototype._createSequenceFlowEntries = function (element, replaceOptions) { var businessObject = (0, _ModelUtil.getBusinessObject)(element); var menuEntries = []; var modeling = this._modeling, moddle = this._moddle; var self = this; (0, _minDash.forEach)(replaceOptions, function (entry) { switch (entry.actionName) { case 'replace-with-default-flow': if (businessObject.sourceRef.default !== businessObject && ((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ComplexGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity'))) { menuEntries.push(self._createMenuEntry(entry, element, function () { modeling.updateProperties(element.source, { default: businessObject }); })); } break; case 'replace-with-conditional-flow': if (!businessObject.conditionExpression && (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity')) { menuEntries.push(self._createMenuEntry(entry, element, function () { var conditionExpression = moddle.create('bpmn:FormalExpression', { body: '' }); modeling.updateProperties(element, { conditionExpression: conditionExpression }); })); } break; default: // default flows if ((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity') && businessObject.conditionExpression) { return menuEntries.push(self._createMenuEntry(entry, element, function () { modeling.updateProperties(element, { conditionExpression: undefined }); })); } // conditional flows if (((0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ExclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:InclusiveGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:ComplexGateway') || (0, _ModelUtil.is)(businessObject.sourceRef, 'bpmn:Activity')) && businessObject.sourceRef.default === businessObject) { return menuEntries.push(self._createMenuEntry(entry, element, function () { modeling.updateProperties(element.source, { default: undefined }); })); } } }); return menuEntries; }; /** * Creates and returns a single menu entry item. * * @param {Object} definition a single replace options definition object * @param {djs.model.Base} element * @param {Function} [action] an action callback function which gets called when * the menu entry is being triggered. * * @return {Object} menu entry item */ ReplaceMenuProvider.prototype._createMenuEntry = function (definition, element, action) { var translate = this._translate; var replaceElement = this._bpmnReplace.replaceElement; var replaceAction = function () { return replaceElement(element, definition.target); }; action = action || replaceAction; var menuEntry = { label: translate(definition.label), className: definition.className, id: definition.actionName, action: action }; return menuEntry; }; /** * Get a list of menu items containing buttons for multi instance markers * * @param {djs.model.Base} element * * @return {Array<Object>} a list of menu items */ ReplaceMenuProvider.prototype._getLoopEntries = function (element) { var self = this; var translate = this._translate; function toggleLoopEntry(event, entry) { var loopCharacteristics; if (entry.active) { loopCharacteristics = undefined; } else { loopCharacteristics = self._moddle.create(entry.options.loopCharacteristics); if (entry.options.isSequential) { loopCharacteristics.isSequential = entry.options.isSequential; } } self._modeling.updateProperties(element, { loopCharacteristics: loopCharacteristics }); } var businessObject = (0, _ModelUtil.getBusinessObject)(element), loopCharacteristics = businessObject.loopCharacteristics; var isSequential, isLoop, isParallel; if (loopCharacteristics) { isSequential = loopCharacteristics.isSequential; isLoop = loopCharacteristics.isSequential === undefined; isParallel = loopCharacteristics.isSequential !== undefined && !loopCharacteristics.isSequential; } var loopEntries = [{ id: 'toggle-parallel-mi', className: 'bpmn-icon-parallel-mi-marker', title: translate('Parallel Multi Instance'), active: isParallel, action: toggleLoopEntry, options: { loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics', isSequential: false } }, { id: 'toggle-sequential-mi', className: 'bpmn-icon-sequential-mi-marker', title: translate('Sequential Multi Instance'), active: isSequential, action: toggleLoopEntry, options: { loopCharacteristics: 'bpmn:MultiInstanceLoopCharacteristics', isSequential: true } }, { id: 'toggle-loop', className: 'bpmn-icon-loop-marker', title: translate('Loop'), active: isLoop, action: toggleLoopEntry, options: { loopCharacteristics: 'bpmn:StandardLoopCharacteristics' } }]; return loopEntries; }; /** * Get the menu items containing a button for the ad hoc marker * * @param {djs.model.Base} element * * @return {Object} a menu item */ ReplaceMenuProvider.prototype._getAdHocEntry = function (element) { var translate = this._translate; var businessObject = (0, _ModelUtil.getBusinessObject)(element); var isAdHoc = (0, _ModelUtil.is)(businessObject, 'bpmn:AdHocSubProcess'); var replaceElement = this._bpmnReplace.replaceElement; var adHocEntry = { id: 'toggle-adhoc', className: 'bpmn-icon-ad-hoc-marker', title: translate('Ad-hoc'), active: isAdHoc, action: function (event, entry) { if (isAdHoc) { return replaceElement(element, { type: 'bpmn:SubProcess' }, { autoResize: false, layoutConnection: false }); } else { return replaceElement(element, { type: 'bpmn:AdHocSubProcess' }, { autoResize: false, layoutConnection: false }); } } }; return adHocEntry; }; },{"../../util/DiUtil":139,"../../util/ModelUtil":141,"../replace/ReplaceOptions":123,"./util/TypeUtil":119,"min-dash":555}],118:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _popupMenu = _interopRequireDefault(require("diagram-js/lib/features/popup-menu")); var _replace = _interopRequireDefault(require("../replace")); var _ReplaceMenuProvider = _interopRequireDefault(require("./ReplaceMenuProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_popupMenu.default, _replace.default], __init__: ['replaceMenuProvider'], replaceMenuProvider: ['type', _ReplaceMenuProvider.default] }; exports.default = _default; },{"../replace":124,"./ReplaceMenuProvider":117,"diagram-js/lib/features/popup-menu":260}],119:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isDifferentType = isDifferentType; var _ModelUtil = require("../../../util/ModelUtil"); var _DiUtil = require("../../../util/DiUtil"); /** * Returns true, if an element is from a different type * than a target definition. Takes into account the type, * event definition type and triggeredByEvent property. * * @param {djs.model.Base} element * * @return {boolean} */ function isDifferentType(element) { return function (entry) { var target = entry.target; var businessObject = (0, _ModelUtil.getBusinessObject)(element), eventDefinition = businessObject.eventDefinitions && businessObject.eventDefinitions[0]; var isTypeEqual = businessObject.$type === target.type; var isEventDefinitionEqual = (eventDefinition && eventDefinition.$type) === target.eventDefinitionType; var isTriggeredByEventEqual = businessObject.triggeredByEvent === target.triggeredByEvent; var isExpandedEqual = target.isExpanded === undefined || target.isExpanded === (0, _DiUtil.isExpanded)(businessObject); return !isTypeEqual || !isEventDefinitionEqual || !isTriggeredByEventEqual || !isExpandedEqual; }; } },{"../../../util/DiUtil":139,"../../../util/ModelUtil":141}],120:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnReplacePreview; var _CommandInterceptor = _interopRequireDefault(require("diagram-js/lib/command/CommandInterceptor")); var _inherits = _interopRequireDefault(require("inherits")); var _css = _interopRequireDefault(require("css.escape")); var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _tinySvg = require("tiny-svg"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 250; function BpmnReplacePreview(eventBus, elementRegistry, elementFactory, canvas, previewSupport) { _CommandInterceptor.default.call(this, eventBus); /** * Replace the visuals of all elements in the context which can be replaced * * @param {Object} context */ function replaceVisual(context) { var replacements = context.canExecute.replacements; (0, _minDash.forEach)(replacements, function (replacement) { var id = replacement.oldElementId; var newElement = { type: replacement.newElementType }; // if the visual of the element is already replaced if (context.visualReplacements[id]) { return; } var element = elementRegistry.get(id); (0, _minDash.assign)(newElement, { x: element.x, y: element.y }); // create a temporary shape var tempShape = elementFactory.createShape(newElement); canvas.addShape(tempShape, element.parent); // select the original SVG element related to the element and hide it var gfx = (0, _minDom.query)('[data-element-id="' + (0, _css.default)(element.id) + '"]', context.dragGroup); if (gfx) { (0, _tinySvg.attr)(gfx, { display: 'none' }); } // clone the gfx of the temporary shape and add it to the drag group var dragger = previewSupport.addDragger(tempShape, context.dragGroup); context.visualReplacements[id] = dragger; canvas.removeShape(tempShape); }); } /** * Restore the original visuals of the previously replaced elements * * @param {Object} context */ function restoreVisual(context) { var visualReplacements = context.visualReplacements; (0, _minDash.forEach)(visualReplacements, function (dragger, id) { var originalGfx = (0, _minDom.query)('[data-element-id="' + (0, _css.default)(id) + '"]', context.dragGroup); if (originalGfx) { (0, _tinySvg.attr)(originalGfx, { display: 'inline' }); } dragger.remove(); if (visualReplacements[id]) { delete visualReplacements[id]; } }); } eventBus.on('shape.move.move', LOW_PRIORITY, function (event) { var context = event.context, canExecute = context.canExecute; if (!context.visualReplacements) { context.visualReplacements = {}; } if (canExecute && canExecute.replacements) { replaceVisual(context); } else { restoreVisual(context); } }); } BpmnReplacePreview.$inject = ['eventBus', 'elementRegistry', 'elementFactory', 'canvas', 'previewSupport']; (0, _inherits.default)(BpmnReplacePreview, _CommandInterceptor.default); },{"css.escape":331,"diagram-js/lib/command/CommandInterceptor":145,"inherits":347,"min-dash":555,"min-dom":556,"tiny-svg":567}],121:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _previewSupport = _interopRequireDefault(require("diagram-js/lib/features/preview-support")); var _BpmnReplacePreview = _interopRequireDefault(require("./BpmnReplacePreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_previewSupport.default], __init__: ['bpmnReplacePreview'], bpmnReplacePreview: ['type', _BpmnReplacePreview.default] }; exports.default = _default; },{"./BpmnReplacePreview":120,"diagram-js/lib/features/preview-support":262}],122:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnReplace; var _minDash = require("min-dash"); var _ModelUtil = require("../../util/ModelUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _DiUtil = require("../../util/DiUtil"); var _ModdleCopy = require("../copy-paste/ModdleCopy"); function copyProperties(source, target, properties) { if (!(0, _minDash.isArray)(properties)) { properties = [properties]; } (0, _minDash.forEach)(properties, function (property) { if (!(0, _minDash.isUndefined)(source[property])) { target[property] = source[property]; } }); } var CUSTOM_PROPERTIES = ['cancelActivity', 'instantiate', 'eventGatewayType', 'triggeredByEvent', 'isInterrupting']; function toggeling(element, target) { var oldCollapsed = element && (0, _minDash.has)(element, 'collapsed') ? element.collapsed : !(0, _DiUtil.isExpanded)(element); var targetCollapsed; if (target && ((0, _minDash.has)(target, 'collapsed') || (0, _minDash.has)(target, 'isExpanded'))) { // property is explicitly set so use it targetCollapsed = (0, _minDash.has)(target, 'collapsed') ? target.collapsed : !target.isExpanded; } else { // keep old state targetCollapsed = oldCollapsed; } if (oldCollapsed !== targetCollapsed) { element.collapsed = oldCollapsed; return true; } return false; } /** * This module takes care of replacing BPMN elements */ function BpmnReplace(bpmnFactory, elementFactory, moddleCopy, modeling, replace, selection) { /** * Prepares a new business object for the replacement element * and triggers the replace operation. * * @param {djs.model.Base} element * @param {Object} target * @param {Object} [hints] * * @return {djs.model.Base} the newly created element */ function replaceElement(element, target, hints) { hints = hints || {}; var type = target.type, oldBusinessObject = element.businessObject; if (isSubProcess(oldBusinessObject)) { if (type === 'bpmn:SubProcess') { if (toggeling(element, target)) { // expanding or collapsing process modeling.toggleCollapse(element); return element; } } } var newBusinessObject = bpmnFactory.create(type); var newElement = { type: type, businessObject: newBusinessObject }; var elementProps = (0, _ModdleCopy.getPropertyNames)(oldBusinessObject.$descriptor), newElementProps = (0, _ModdleCopy.getPropertyNames)(newBusinessObject.$descriptor, true), copyProps = intersection(elementProps, newElementProps); // initialize special properties defined in target definition (0, _minDash.assign)(newBusinessObject, (0, _minDash.pick)(target, CUSTOM_PROPERTIES)); var properties = (0, _minDash.filter)(copyProps, function (propertyName) { // copying event definitions, unless we replace if (propertyName === 'eventDefinitions') { return hasEventDefinition(element, target.eventDefinitionType); } // retain loop characteristics if the target element // is not an event sub process if (propertyName === 'loopCharacteristics') { return !(0, _DiUtil.isEventSubProcess)(newBusinessObject); } // so the applied properties from 'target' don't get lost if (newBusinessObject.hasOwnProperty(propertyName)) { return false; } if (propertyName === 'processRef' && target.isExpanded === false) { return false; } if (propertyName === 'triggeredByEvent') { return false; } return true; }); newBusinessObject = moddleCopy.copyElement(oldBusinessObject, newBusinessObject, properties); // initialize custom BPMN extensions if (target.eventDefinitionType) { // only initialize with new eventDefinition // if we did not set an event definition yet, // i.e. because we copied it if (!hasEventDefinition(newBusinessObject, target.eventDefinitionType)) { newElement.eventDefinitionType = target.eventDefinitionType; newElement.eventDefinitionAttrs = target.eventDefinitionAttrs; } } if ((0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Activity')) { if (isSubProcess(oldBusinessObject)) { // no toggeling, so keep old state newElement.isExpanded = (0, _DiUtil.isExpanded)(oldBusinessObject); } // else if property is explicitly set, use it else if (target && (0, _minDash.has)(target, 'isExpanded')) { newElement.isExpanded = target.isExpanded; } // TODO: need also to respect min/max Size // copy size, from an expanded subprocess to an expanded alternative subprocess // except bpmn:Task, because Task is always expanded if ((0, _DiUtil.isExpanded)(oldBusinessObject) && !(0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Task') && newElement.isExpanded) { newElement.width = element.width; newElement.height = element.height; } } // remove children if not expanding sub process if (isSubProcess(oldBusinessObject) && !isSubProcess(newBusinessObject)) { hints.moveChildren = false; } // transform collapsed/expanded pools if ((0, _ModelUtil.is)(oldBusinessObject, 'bpmn:Participant')) { // create expanded pool if (target.isExpanded === true) { newBusinessObject.processRef = bpmnFactory.create('bpmn:Process'); } else { // remove children when transforming to collapsed pool hints.moveChildren = false; } // apply same width and default height newElement.width = element.width; newElement.height = elementFactory._getDefaultSize(newBusinessObject).height; } newBusinessObject.name = oldBusinessObject.name; // retain default flow's reference between inclusive <-> exclusive gateways and activities if ((0, _ModelingUtil.isAny)(oldBusinessObject, ['bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:Activity']) && (0, _ModelingUtil.isAny)(newBusinessObject, ['bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:Activity'])) { newBusinessObject.default = oldBusinessObject.default; } if (target.host && !(0, _ModelUtil.is)(oldBusinessObject, 'bpmn:BoundaryEvent') && (0, _ModelUtil.is)(newBusinessObject, 'bpmn:BoundaryEvent')) { newElement.host = target.host; } newElement.di = {}; // fill and stroke will be set to DI copyProperties(oldBusinessObject.di, newElement.di, ['fill', 'stroke']); newElement = replace.replaceElement(element, newElement, hints); if (hints.select !== false) { selection.select(newElement); } return newElement; } this.replaceElement = replaceElement; } BpmnReplace.$inject = ['bpmnFactory', 'elementFactory', 'moddleCopy', 'modeling', 'replace', 'selection']; function isSubProcess(bo) { return (0, _ModelUtil.is)(bo, 'bpmn:SubProcess'); } function hasEventDefinition(element, type) { var bo = (0, _ModelUtil.getBusinessObject)(element); return type && bo.get('eventDefinitions').some(function (definition) { return (0, _ModelUtil.is)(definition, type); }); } /** * Compute intersection between two arrays. */ function intersection(a1, a2) { return a1.filter(function (el) { return a2.indexOf(el) !== -1; }); } },{"../../util/DiUtil":139,"../../util/ModelUtil":141,"../copy-paste/ModdleCopy":33,"../modeling/util/ModelingUtil":112,"min-dash":555}],123:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PARTICIPANT = exports.SEQUENCE_FLOW = exports.EVENT_SUB_PROCESS_START_EVENT = exports.BOUNDARY_EVENT = exports.TASK = exports.EVENT_SUB_PROCESS = exports.TRANSACTION = exports.SUBPROCESS_EXPANDED = exports.GATEWAY = exports.END_EVENT = exports.INTERMEDIATE_EVENT = exports.START_EVENT_SUB_PROCESS = exports.START_EVENT = void 0; var START_EVENT = [{ label: 'Start Event', actionName: 'replace-with-none-start', className: 'bpmn-icon-start-event-none', target: { type: 'bpmn:StartEvent' } }, { label: 'Intermediate Throw Event', actionName: 'replace-with-none-intermediate-throwing', className: 'bpmn-icon-intermediate-event-none', target: { type: 'bpmn:IntermediateThrowEvent' } }, { label: 'End Event', actionName: 'replace-with-none-end', className: 'bpmn-icon-end-event-none', target: { type: 'bpmn:EndEvent' } }, { label: 'Message Start Event', actionName: 'replace-with-message-start', className: 'bpmn-icon-start-event-message', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Timer Start Event', actionName: 'replace-with-timer-start', className: 'bpmn-icon-start-event-timer', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:TimerEventDefinition' } }, { label: 'Conditional Start Event', actionName: 'replace-with-conditional-start', className: 'bpmn-icon-start-event-condition', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition' } }, { label: 'Signal Start Event', actionName: 'replace-with-signal-start', className: 'bpmn-icon-start-event-signal', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }]; exports.START_EVENT = START_EVENT; var START_EVENT_SUB_PROCESS = [{ label: 'Start Event', actionName: 'replace-with-none-start', className: 'bpmn-icon-start-event-none', target: { type: 'bpmn:StartEvent' } }, { label: 'Intermediate Throw Event', actionName: 'replace-with-none-intermediate-throwing', className: 'bpmn-icon-intermediate-event-none', target: { type: 'bpmn:IntermediateThrowEvent' } }, { label: 'End Event', actionName: 'replace-with-none-end', className: 'bpmn-icon-end-event-none', target: { type: 'bpmn:EndEvent' } }]; exports.START_EVENT_SUB_PROCESS = START_EVENT_SUB_PROCESS; var INTERMEDIATE_EVENT = [{ label: 'Start Event', actionName: 'replace-with-none-start', className: 'bpmn-icon-start-event-none', target: { type: 'bpmn:StartEvent' } }, { label: 'Intermediate Throw Event', actionName: 'replace-with-none-intermediate-throw', className: 'bpmn-icon-intermediate-event-none', target: { type: 'bpmn:IntermediateThrowEvent' } }, { label: 'End Event', actionName: 'replace-with-none-end', className: 'bpmn-icon-end-event-none', target: { type: 'bpmn:EndEvent' } }, { label: 'Message Intermediate Catch Event', actionName: 'replace-with-message-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-message', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Message Intermediate Throw Event', actionName: 'replace-with-message-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-message', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Timer Intermediate Catch Event', actionName: 'replace-with-timer-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-timer', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:TimerEventDefinition' } }, { label: 'Escalation Intermediate Throw Event', actionName: 'replace-with-escalation-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-escalation', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition' } }, { label: 'Conditional Intermediate Catch Event', actionName: 'replace-with-conditional-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-condition', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition' } }, { label: 'Link Intermediate Catch Event', actionName: 'replace-with-link-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-link', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:LinkEventDefinition', eventDefinitionAttrs: { name: '' } } }, { label: 'Link Intermediate Throw Event', actionName: 'replace-with-link-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-link', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:LinkEventDefinition', eventDefinitionAttrs: { name: '' } } }, { label: 'Compensation Intermediate Throw Event', actionName: 'replace-with-compensation-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-compensation', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:CompensateEventDefinition' } }, { label: 'Signal Intermediate Catch Event', actionName: 'replace-with-signal-intermediate-catch', className: 'bpmn-icon-intermediate-event-catch-signal', target: { type: 'bpmn:IntermediateCatchEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }, { label: 'Signal Intermediate Throw Event', actionName: 'replace-with-signal-intermediate-throw', className: 'bpmn-icon-intermediate-event-throw-signal', target: { type: 'bpmn:IntermediateThrowEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }]; exports.INTERMEDIATE_EVENT = INTERMEDIATE_EVENT; var END_EVENT = [{ label: 'Start Event', actionName: 'replace-with-none-start', className: 'bpmn-icon-start-event-none', target: { type: 'bpmn:StartEvent' } }, { label: 'Intermediate Throw Event', actionName: 'replace-with-none-intermediate-throw', className: 'bpmn-icon-intermediate-event-none', target: { type: 'bpmn:IntermediateThrowEvent' } }, { label: 'End Event', actionName: 'replace-with-none-end', className: 'bpmn-icon-end-event-none', target: { type: 'bpmn:EndEvent' } }, { label: 'Message End Event', actionName: 'replace-with-message-end', className: 'bpmn-icon-end-event-message', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Escalation End Event', actionName: 'replace-with-escalation-end', className: 'bpmn-icon-end-event-escalation', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition' } }, { label: 'Error End Event', actionName: 'replace-with-error-end', className: 'bpmn-icon-end-event-error', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:ErrorEventDefinition' } }, { label: 'Cancel End Event', actionName: 'replace-with-cancel-end', className: 'bpmn-icon-end-event-cancel', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:CancelEventDefinition' } }, { label: 'Compensation End Event', actionName: 'replace-with-compensation-end', className: 'bpmn-icon-end-event-compensation', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:CompensateEventDefinition' } }, { label: 'Signal End Event', actionName: 'replace-with-signal-end', className: 'bpmn-icon-end-event-signal', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }, { label: 'Terminate End Event', actionName: 'replace-with-terminate-end', className: 'bpmn-icon-end-event-terminate', target: { type: 'bpmn:EndEvent', eventDefinitionType: 'bpmn:TerminateEventDefinition' } }]; exports.END_EVENT = END_EVENT; var GATEWAY = [{ label: 'Exclusive Gateway', actionName: 'replace-with-exclusive-gateway', className: 'bpmn-icon-gateway-xor', target: { type: 'bpmn:ExclusiveGateway' } }, { label: 'Parallel Gateway', actionName: 'replace-with-parallel-gateway', className: 'bpmn-icon-gateway-parallel', target: { type: 'bpmn:ParallelGateway' } }, { label: 'Inclusive Gateway', actionName: 'replace-with-inclusive-gateway', className: 'bpmn-icon-gateway-or', target: { type: 'bpmn:InclusiveGateway' } }, { label: 'Complex Gateway', actionName: 'replace-with-complex-gateway', className: 'bpmn-icon-gateway-complex', target: { type: 'bpmn:ComplexGateway' } }, { label: 'Event based Gateway', actionName: 'replace-with-event-based-gateway', className: 'bpmn-icon-gateway-eventbased', target: { type: 'bpmn:EventBasedGateway', instantiate: false, eventGatewayType: 'Exclusive' } } // Gateways deactivated until https://github.com/bpmn-io/bpmn-js/issues/194 // { // label: 'Event based instantiating Gateway', // actionName: 'replace-with-exclusive-event-based-gateway', // className: 'bpmn-icon-exclusive-event-based', // target: { // type: 'bpmn:EventBasedGateway' // }, // options: { // businessObject: { instantiate: true, eventGatewayType: 'Exclusive' } // } // }, // { // label: 'Parallel Event based instantiating Gateway', // actionName: 'replace-with-parallel-event-based-instantiate-gateway', // className: 'bpmn-icon-parallel-event-based-instantiate-gateway', // target: { // type: 'bpmn:EventBasedGateway' // }, // options: { // businessObject: { instantiate: true, eventGatewayType: 'Parallel' } // } // } ]; exports.GATEWAY = GATEWAY; var SUBPROCESS_EXPANDED = [{ label: 'Transaction', actionName: 'replace-with-transaction', className: 'bpmn-icon-transaction', target: { type: 'bpmn:Transaction', isExpanded: true } }, { label: 'Event Sub Process', actionName: 'replace-with-event-subprocess', className: 'bpmn-icon-event-subprocess-expanded', target: { type: 'bpmn:SubProcess', triggeredByEvent: true, isExpanded: true } }, { label: 'Sub Process (collapsed)', actionName: 'replace-with-collapsed-subprocess', className: 'bpmn-icon-subprocess-collapsed', target: { type: 'bpmn:SubProcess', isExpanded: false } }]; exports.SUBPROCESS_EXPANDED = SUBPROCESS_EXPANDED; var TRANSACTION = [{ label: 'Sub Process', actionName: 'replace-with-subprocess', className: 'bpmn-icon-subprocess-expanded', target: { type: 'bpmn:SubProcess', isExpanded: true } }, { label: 'Event Sub Process', actionName: 'replace-with-event-subprocess', className: 'bpmn-icon-event-subprocess-expanded', target: { type: 'bpmn:SubProcess', triggeredByEvent: true, isExpanded: true } }]; exports.TRANSACTION = TRANSACTION; var EVENT_SUB_PROCESS = [{ label: 'Sub Process', actionName: 'replace-with-subprocess', className: 'bpmn-icon-subprocess-expanded', target: { type: 'bpmn:SubProcess', isExpanded: true } }, { label: 'Transaction', actionName: 'replace-with-transaction', className: 'bpmn-icon-transaction', target: { type: 'bpmn:Transaction', isExpanded: true } }]; exports.EVENT_SUB_PROCESS = EVENT_SUB_PROCESS; var TASK = [{ label: 'Task', actionName: 'replace-with-task', className: 'bpmn-icon-task', target: { type: 'bpmn:Task' } }, { label: 'Send Task', actionName: 'replace-with-send-task', className: 'bpmn-icon-send', target: { type: 'bpmn:SendTask' } }, { label: 'Receive Task', actionName: 'replace-with-receive-task', className: 'bpmn-icon-receive', target: { type: 'bpmn:ReceiveTask' } }, { label: 'User Task', actionName: 'replace-with-user-task', className: 'bpmn-icon-user', target: { type: 'bpmn:UserTask' } }, { label: 'Manual Task', actionName: 'replace-with-manual-task', className: 'bpmn-icon-manual', target: { type: 'bpmn:ManualTask' } }, { label: 'Business Rule Task', actionName: 'replace-with-rule-task', className: 'bpmn-icon-business-rule', target: { type: 'bpmn:BusinessRuleTask' } }, { label: 'Service Task', actionName: 'replace-with-service-task', className: 'bpmn-icon-service', target: { type: 'bpmn:ServiceTask' } }, { label: 'Script Task', actionName: 'replace-with-script-task', className: 'bpmn-icon-script', target: { type: 'bpmn:ScriptTask' } }, { label: 'Call Activity', actionName: 'replace-with-call-activity', className: 'bpmn-icon-call-activity', target: { type: 'bpmn:CallActivity' } }, { label: 'Sub Process (collapsed)', actionName: 'replace-with-collapsed-subprocess', className: 'bpmn-icon-subprocess-collapsed', target: { type: 'bpmn:SubProcess', isExpanded: false } }, { label: 'Sub Process (expanded)', actionName: 'replace-with-expanded-subprocess', className: 'bpmn-icon-subprocess-expanded', target: { type: 'bpmn:SubProcess', isExpanded: true } }]; exports.TASK = TASK; var BOUNDARY_EVENT = [{ label: 'Message Boundary Event', actionName: 'replace-with-message-boundary', className: 'bpmn-icon-intermediate-event-catch-message', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Timer Boundary Event', actionName: 'replace-with-timer-boundary', className: 'bpmn-icon-intermediate-event-catch-timer', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:TimerEventDefinition' } }, { label: 'Escalation Boundary Event', actionName: 'replace-with-escalation-boundary', className: 'bpmn-icon-intermediate-event-catch-escalation', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition' } }, { label: 'Conditional Boundary Event', actionName: 'replace-with-conditional-boundary', className: 'bpmn-icon-intermediate-event-catch-condition', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition' } }, { label: 'Error Boundary Event', actionName: 'replace-with-error-boundary', className: 'bpmn-icon-intermediate-event-catch-error', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:ErrorEventDefinition' } }, { label: 'Cancel Boundary Event', actionName: 'replace-with-cancel-boundary', className: 'bpmn-icon-intermediate-event-catch-cancel', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:CancelEventDefinition' } }, { label: 'Signal Boundary Event', actionName: 'replace-with-signal-boundary', className: 'bpmn-icon-intermediate-event-catch-signal', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }, { label: 'Compensation Boundary Event', actionName: 'replace-with-compensation-boundary', className: 'bpmn-icon-intermediate-event-catch-compensation', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:CompensateEventDefinition' } }, { label: 'Message Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-message-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-message', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:MessageEventDefinition', cancelActivity: false } }, { label: 'Timer Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-timer-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-timer', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:TimerEventDefinition', cancelActivity: false } }, { label: 'Escalation Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-escalation-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-escalation', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition', cancelActivity: false } }, { label: 'Conditional Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-conditional-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-condition', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition', cancelActivity: false } }, { label: 'Signal Boundary Event (non-interrupting)', actionName: 'replace-with-non-interrupting-signal-boundary', className: 'bpmn-icon-intermediate-event-catch-non-interrupting-signal', target: { type: 'bpmn:BoundaryEvent', eventDefinitionType: 'bpmn:SignalEventDefinition', cancelActivity: false } }]; exports.BOUNDARY_EVENT = BOUNDARY_EVENT; var EVENT_SUB_PROCESS_START_EVENT = [{ label: 'Message Start Event', actionName: 'replace-with-message-start', className: 'bpmn-icon-start-event-message', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:MessageEventDefinition' } }, { label: 'Timer Start Event', actionName: 'replace-with-timer-start', className: 'bpmn-icon-start-event-timer', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:TimerEventDefinition' } }, { label: 'Conditional Start Event', actionName: 'replace-with-conditional-start', className: 'bpmn-icon-start-event-condition', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition' } }, { label: 'Signal Start Event', actionName: 'replace-with-signal-start', className: 'bpmn-icon-start-event-signal', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:SignalEventDefinition' } }, { label: 'Error Start Event', actionName: 'replace-with-error-start', className: 'bpmn-icon-start-event-error', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:ErrorEventDefinition' } }, { label: 'Escalation Start Event', actionName: 'replace-with-escalation-start', className: 'bpmn-icon-start-event-escalation', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition' } }, { label: 'Compensation Start Event', actionName: 'replace-with-compensation-start', className: 'bpmn-icon-start-event-compensation', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:CompensateEventDefinition' } }, { label: 'Message Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-message-start', className: 'bpmn-icon-start-event-non-interrupting-message', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:MessageEventDefinition', isInterrupting: false } }, { label: 'Timer Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-timer-start', className: 'bpmn-icon-start-event-non-interrupting-timer', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:TimerEventDefinition', isInterrupting: false } }, { label: 'Conditional Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-conditional-start', className: 'bpmn-icon-start-event-non-interrupting-condition', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:ConditionalEventDefinition', isInterrupting: false } }, { label: 'Signal Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-signal-start', className: 'bpmn-icon-start-event-non-interrupting-signal', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:SignalEventDefinition', isInterrupting: false } }, { label: 'Escalation Start Event (non-interrupting)', actionName: 'replace-with-non-interrupting-escalation-start', className: 'bpmn-icon-start-event-non-interrupting-escalation', target: { type: 'bpmn:StartEvent', eventDefinitionType: 'bpmn:EscalationEventDefinition', isInterrupting: false } }]; exports.EVENT_SUB_PROCESS_START_EVENT = EVENT_SUB_PROCESS_START_EVENT; var SEQUENCE_FLOW = [{ label: 'Sequence Flow', actionName: 'replace-with-sequence-flow', className: 'bpmn-icon-connection' }, { label: 'Default Flow', actionName: 'replace-with-default-flow', className: 'bpmn-icon-default-flow' }, { label: 'Conditional Flow', actionName: 'replace-with-conditional-flow', className: 'bpmn-icon-conditional-flow' }]; exports.SEQUENCE_FLOW = SEQUENCE_FLOW; var PARTICIPANT = [{ label: 'Expanded Pool', actionName: 'replace-with-expanded-pool', className: 'bpmn-icon-participant', target: { type: 'bpmn:Participant', isExpanded: true } }, { label: 'Collapsed Pool', actionName: 'replace-with-collapsed-pool', // TODO(@janstuemmel): maybe design new icon className: 'bpmn-icon-lane', target: { type: 'bpmn:Participant', isExpanded: false } }]; exports.PARTICIPANT = PARTICIPANT; },{}],124:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _copyPaste = _interopRequireDefault(require("../copy-paste")); var _replace = _interopRequireDefault(require("diagram-js/lib/features/replace")); var _selection = _interopRequireDefault(require("diagram-js/lib/features/selection")); var _BpmnReplace = _interopRequireDefault(require("./BpmnReplace")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_copyPaste.default, _replace.default, _selection.default], bpmnReplace: ['type', _BpmnReplace.default] }; exports.default = _default; },{"../copy-paste":34,"./BpmnReplace":122,"diagram-js/lib/features/replace":264,"diagram-js/lib/features/selection":278}],125:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnRules; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _ModelUtil = require("../../util/ModelUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _LabelUtil = require("../../util/LabelUtil"); var _DiUtil = require("../../util/DiUtil"); var _RuleProvider = _interopRequireDefault(require("diagram-js/lib/features/rules/RuleProvider")); var _BpmnSnappingUtil = require("../snapping/BpmnSnappingUtil"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * BPMN specific modeling rule */ function BpmnRules(eventBus) { _RuleProvider.default.call(this, eventBus); } (0, _inherits.default)(BpmnRules, _RuleProvider.default); BpmnRules.$inject = ['eventBus']; BpmnRules.prototype.init = function () { this.addRule('connection.start', function (context) { var source = context.source; return canStartConnection(source); }); this.addRule('connection.create', function (context) { var source = context.source, target = context.target, hints = context.hints || {}, targetParent = hints.targetParent, targetAttach = hints.targetAttach; // don't allow incoming connections on // newly created boundary events // to boundary events if (targetAttach) { return false; } // temporarily set target parent for scoping // checks to work if (targetParent) { target.parent = targetParent; } try { return canConnect(source, target); } finally { // unset temporary target parent if (targetParent) { target.parent = null; } } }); this.addRule('connection.reconnect', function (context) { var connection = context.connection, source = context.source, target = context.target; return canConnect(source, target, connection); }); this.addRule('connection.updateWaypoints', function (context) { return { type: context.connection.type }; }); this.addRule('shape.resize', function (context) { var shape = context.shape, newBounds = context.newBounds; return canResize(shape, newBounds); }); this.addRule('elements.create', function (context) { var elements = context.elements, position = context.position, target = context.target; return (0, _minDash.every)(elements, function (element) { if (isConnection(element)) { return canConnect(element.source, element.target, element); } if (element.host) { return canAttach(element, element.host, null, position); } return canCreate(element, target, null, position); }); }); this.addRule('elements.move', function (context) { var target = context.target, shapes = context.shapes, position = context.position; return canAttach(shapes, target, null, position) || canReplace(shapes, target, position) || canMove(shapes, target, position) || canInsert(shapes, target, position); }); this.addRule('shape.create', function (context) { return canCreate(context.shape, context.target, context.source, context.position); }); this.addRule('shape.attach', function (context) { return canAttach(context.shape, context.target, null, context.position); }); this.addRule('element.copy', function (context) { var element = context.element, elements = context.elements; return canCopy(elements, element); }); }; BpmnRules.prototype.canConnectMessageFlow = canConnectMessageFlow; BpmnRules.prototype.canConnectSequenceFlow = canConnectSequenceFlow; BpmnRules.prototype.canConnectDataAssociation = canConnectDataAssociation; BpmnRules.prototype.canConnectAssociation = canConnectAssociation; BpmnRules.prototype.canMove = canMove; BpmnRules.prototype.canAttach = canAttach; BpmnRules.prototype.canReplace = canReplace; BpmnRules.prototype.canDrop = canDrop; BpmnRules.prototype.canInsert = canInsert; BpmnRules.prototype.canCreate = canCreate; BpmnRules.prototype.canConnect = canConnect; BpmnRules.prototype.canResize = canResize; BpmnRules.prototype.canCopy = canCopy; /** * Utility functions for rule checking */ /** * Checks if given element can be used for starting connection. * * @param {Element} source * @return {boolean} */ function canStartConnection(element) { if (nonExistingOrLabel(element)) { return null; } return (0, _ModelingUtil.isAny)(element, ['bpmn:FlowNode', 'bpmn:InteractionNode', 'bpmn:DataObjectReference', 'bpmn:DataStoreReference', 'bpmn:Group']); } function nonExistingOrLabel(element) { return !element || (0, _LabelUtil.isLabel)(element); } function isSame(a, b) { return a === b; } function getOrganizationalParent(element) { do { if ((0, _ModelUtil.is)(element, 'bpmn:Process')) { return (0, _ModelUtil.getBusinessObject)(element); } if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) { return (0, _ModelUtil.getBusinessObject)(element).processRef || (0, _ModelUtil.getBusinessObject)(element); } } while (element = element.parent); } function isTextAnnotation(element) { return (0, _ModelUtil.is)(element, 'bpmn:TextAnnotation'); } function isGroup(element) { return (0, _ModelUtil.is)(element, 'bpmn:Group') && !element.labelTarget; } function isCompensationBoundary(element) { return (0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && hasEventDefinition(element, 'bpmn:CompensateEventDefinition'); } function isForCompensation(e) { return (0, _ModelUtil.getBusinessObject)(e).isForCompensation; } function isSameOrganization(a, b) { var parentA = getOrganizationalParent(a), parentB = getOrganizationalParent(b); return parentA === parentB; } function isMessageFlowSource(element) { return (0, _ModelUtil.is)(element, 'bpmn:InteractionNode') && !(0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && (!(0, _ModelUtil.is)(element, 'bpmn:Event') || (0, _ModelUtil.is)(element, 'bpmn:ThrowEvent') && hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition')); } function isMessageFlowTarget(element) { return (0, _ModelUtil.is)(element, 'bpmn:InteractionNode') && !isForCompensation(element) && (!(0, _ModelUtil.is)(element, 'bpmn:Event') || (0, _ModelUtil.is)(element, 'bpmn:CatchEvent') && hasEventDefinitionOrNone(element, 'bpmn:MessageEventDefinition')) && !((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !hasEventDefinition(element, 'bpmn:MessageEventDefinition')); } function getScopeParent(element) { var parent = element; while (parent = parent.parent) { if ((0, _ModelUtil.is)(parent, 'bpmn:FlowElementsContainer')) { return (0, _ModelUtil.getBusinessObject)(parent); } if ((0, _ModelUtil.is)(parent, 'bpmn:Participant')) { return (0, _ModelUtil.getBusinessObject)(parent).processRef; } } return null; } function isSameScope(a, b) { var scopeParentA = getScopeParent(a), scopeParentB = getScopeParent(b); return scopeParentA === scopeParentB; } function hasEventDefinition(element, eventDefinition) { var bo = (0, _ModelUtil.getBusinessObject)(element); return !!(0, _minDash.find)(bo.eventDefinitions || [], function (definition) { return (0, _ModelUtil.is)(definition, eventDefinition); }); } function hasEventDefinitionOrNone(element, eventDefinition) { var bo = (0, _ModelUtil.getBusinessObject)(element); return (bo.eventDefinitions || []).every(function (definition) { return (0, _ModelUtil.is)(definition, eventDefinition); }); } function isSequenceFlowSource(element) { return (0, _ModelUtil.is)(element, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(element, 'bpmn:EndEvent') && !(0, _DiUtil.isEventSubProcess)(element) && !((0, _ModelUtil.is)(element, 'bpmn:IntermediateThrowEvent') && hasEventDefinition(element, 'bpmn:LinkEventDefinition')) && !isCompensationBoundary(element) && !isForCompensation(element); } function isSequenceFlowTarget(element) { return (0, _ModelUtil.is)(element, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(element, 'bpmn:StartEvent') && !(0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !(0, _DiUtil.isEventSubProcess)(element) && !((0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && hasEventDefinition(element, 'bpmn:LinkEventDefinition')) && !isForCompensation(element); } function isEventBasedTarget(element) { return (0, _ModelUtil.is)(element, 'bpmn:ReceiveTask') || (0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && (hasEventDefinition(element, 'bpmn:MessageEventDefinition') || hasEventDefinition(element, 'bpmn:TimerEventDefinition') || hasEventDefinition(element, 'bpmn:ConditionalEventDefinition') || hasEventDefinition(element, 'bpmn:SignalEventDefinition')); } function isConnection(element) { return element.waypoints; } function getParents(element) { var parents = []; while (element) { element = element.parent; if (element) { parents.push(element); } } return parents; } function isParent(possibleParent, element) { var allParents = getParents(element); return allParents.indexOf(possibleParent) !== -1; } function canConnect(source, target, connection) { if (nonExistingOrLabel(source) || nonExistingOrLabel(target)) { return null; } if (!(0, _ModelUtil.is)(connection, 'bpmn:DataAssociation')) { if (canConnectMessageFlow(source, target)) { return { type: 'bpmn:MessageFlow' }; } if (canConnectSequenceFlow(source, target)) { return { type: 'bpmn:SequenceFlow' }; } } var connectDataAssociation = canConnectDataAssociation(source, target); if (connectDataAssociation) { return connectDataAssociation; } if (isCompensationBoundary(source) && isForCompensation(target)) { return { type: 'bpmn:Association', associationDirection: 'One' }; } if (canConnectAssociation(source, target)) { return { type: 'bpmn:Association' }; } return false; } /** * Can an element be dropped into the target element * * @return {boolean} */ function canDrop(element, target, position) { // can move labels and groups everywhere if ((0, _LabelUtil.isLabel)(element) || isGroup(element)) { return true; } // disallow to create elements on collapsed pools if ((0, _ModelUtil.is)(target, 'bpmn:Participant') && !(0, _DiUtil.isExpanded)(target)) { return false; } // allow to create new participants on // existing collaboration and process diagrams if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) { return (0, _ModelUtil.is)(target, 'bpmn:Process') || (0, _ModelUtil.is)(target, 'bpmn:Collaboration'); } // allow moving DataInput / DataOutput within its original container only if ((0, _ModelingUtil.isAny)(element, ['bpmn:DataInput', 'bpmn:DataOutput'])) { if (element.parent) { return target === element.parent; } } // allow creating lanes on participants and other lanes only if ((0, _ModelUtil.is)(element, 'bpmn:Lane')) { return (0, _ModelUtil.is)(target, 'bpmn:Participant') || (0, _ModelUtil.is)(target, 'bpmn:Lane'); } // disallow dropping boundary events which cannot replace with intermediate event if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && !isDroppableBoundaryEvent(element)) { return false; } // drop flow elements onto flow element containers // and participants if ((0, _ModelUtil.is)(element, 'bpmn:FlowElement') && !(0, _ModelUtil.is)(element, 'bpmn:DataStoreReference')) { if ((0, _ModelUtil.is)(target, 'bpmn:FlowElementsContainer')) { return (0, _DiUtil.isExpanded)(target); } return (0, _ModelingUtil.isAny)(target, ['bpmn:Participant', 'bpmn:Lane']); } // account for the fact that data associations are always // rendered and moved to top (Process or Collaboration level) // // artifacts may be placed wherever, too if ((0, _ModelingUtil.isAny)(element, ['bpmn:Artifact', 'bpmn:DataAssociation', 'bpmn:DataStoreReference'])) { return (0, _ModelingUtil.isAny)(target, ['bpmn:Collaboration', 'bpmn:Lane', 'bpmn:Participant', 'bpmn:Process', 'bpmn:SubProcess']); } if ((0, _ModelUtil.is)(element, 'bpmn:MessageFlow')) { return (0, _ModelUtil.is)(target, 'bpmn:Collaboration') || element.source.parent == target || element.target.parent == target; } return false; } function isDroppableBoundaryEvent(event) { return (0, _ModelUtil.getBusinessObject)(event).cancelActivity && (hasNoEventDefinition(event) || hasCommonBoundaryIntermediateEventDefinition(event)); } function isBoundaryEvent(element) { return !(0, _LabelUtil.isLabel)(element) && (0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent'); } function isLane(element) { return (0, _ModelUtil.is)(element, 'bpmn:Lane'); } /** * We treat IntermediateThrowEvents as boundary events during create, * this must be reflected in the rules. */ function isBoundaryCandidate(element) { if (isBoundaryEvent(element)) { return true; } if ((0, _ModelUtil.is)(element, 'bpmn:IntermediateThrowEvent') && hasNoEventDefinition(element)) { return true; } return (0, _ModelUtil.is)(element, 'bpmn:IntermediateCatchEvent') && hasCommonBoundaryIntermediateEventDefinition(element); } function hasNoEventDefinition(element) { var bo = (0, _ModelUtil.getBusinessObject)(element); return bo && !(bo.eventDefinitions && bo.eventDefinitions.length); } function hasCommonBoundaryIntermediateEventDefinition(element) { return hasOneOfEventDefinitions(element, ['bpmn:MessageEventDefinition', 'bpmn:TimerEventDefinition', 'bpmn:SignalEventDefinition', 'bpmn:ConditionalEventDefinition']); } function hasOneOfEventDefinitions(element, eventDefinitions) { return eventDefinitions.some(function (definition) { return hasEventDefinition(element, definition); }); } function isReceiveTaskAfterEventBasedGateway(element) { return (0, _ModelUtil.is)(element, 'bpmn:ReceiveTask') && (0, _minDash.find)(element.incoming, function (incoming) { return (0, _ModelUtil.is)(incoming.source, 'bpmn:EventBasedGateway'); }); } function canAttach(elements, target, source, position) { if (!Array.isArray(elements)) { elements = [elements]; } // only (re-)attach one element at a time if (elements.length !== 1) { return false; } var element = elements[0]; // do not attach labels if ((0, _LabelUtil.isLabel)(element)) { return false; } // only handle boundary events if (!isBoundaryCandidate(element)) { return false; } // disallow drop on event sub processes if ((0, _DiUtil.isEventSubProcess)(target)) { return false; } // only allow drop on non compensation activities if (!(0, _ModelUtil.is)(target, 'bpmn:Activity') || isForCompensation(target)) { return false; } // only attach to subprocess border if (position && !(0, _BpmnSnappingUtil.getBoundaryAttachment)(position, target)) { return false; } // do not attach on receive tasks after event based gateways if (isReceiveTaskAfterEventBasedGateway(target)) { return false; } return 'attach'; } /** * Defines how to replace elements for a given target. * * Returns an array containing all elements which will be replaced. * * @example * * [{ id: 'IntermediateEvent_2', * type: 'bpmn:StartEvent' * }, * { id: 'IntermediateEvent_5', * type: 'bpmn:EndEvent' * }] * * @param {Array} elements * @param {Object} target * * @return {Object} an object containing all elements which have to be replaced */ function canReplace(elements, target, position) { if (!target) { return false; } var canExecute = { replacements: [] }; (0, _minDash.forEach)(elements, function (element) { if (!(0, _DiUtil.isEventSubProcess)(target)) { if ((0, _ModelUtil.is)(element, 'bpmn:StartEvent') && element.type !== 'label' && canDrop(element, target)) { // replace a non-interrupting start event by a blank interrupting start event // when the target is not an event sub process if (!(0, _DiUtil.isInterrupting)(element)) { canExecute.replacements.push({ oldElementId: element.id, newElementType: 'bpmn:StartEvent' }); } // replace an error/escalation/compensate start event by a blank interrupting start event // when the target is not an event sub process if ((0, _DiUtil.hasErrorEventDefinition)(element) || (0, _DiUtil.hasEscalationEventDefinition)(element) || (0, _DiUtil.hasCompensateEventDefinition)(element)) { canExecute.replacements.push({ oldElementId: element.id, newElementType: 'bpmn:StartEvent' }); } // replace a typed start event by a blank interrupting start event // when the target is a sub process but not an event sub process if (hasOneOfEventDefinitions(element, ['bpmn:MessageEventDefinition', 'bpmn:TimerEventDefinition', 'bpmn:SignalEventDefinition', 'bpmn:ConditionalEventDefinition']) && (0, _ModelUtil.is)(target, 'bpmn:SubProcess')) { canExecute.replacements.push({ oldElementId: element.id, newElementType: 'bpmn:StartEvent' }); } } } if (!(0, _ModelUtil.is)(target, 'bpmn:Transaction')) { if (hasEventDefinition(element, 'bpmn:CancelEventDefinition') && element.type !== 'label') { if ((0, _ModelUtil.is)(element, 'bpmn:EndEvent') && canDrop(element, target)) { canExecute.replacements.push({ oldElementId: element.id, newElementType: 'bpmn:EndEvent' }); } if ((0, _ModelUtil.is)(element, 'bpmn:BoundaryEvent') && canAttach(element, target, null, position)) { canExecute.replacements.push({ oldElementId: element.id, newElementType: 'bpmn:BoundaryEvent' }); } } } }); return canExecute.replacements.length ? canExecute : false; } function canMove(elements, target) { // do not move selection containing lanes if ((0, _minDash.some)(elements, isLane)) { return false; } // allow default move check to start move operation if (!target) { return true; } return elements.every(function (element) { return canDrop(element, target); }); } function canCreate(shape, target, source, position) { if (!target) { return false; } if ((0, _LabelUtil.isLabel)(shape) || isGroup(shape)) { return true; } if (isSame(source, target)) { return false; } // ensure we do not drop the element // into source if (source && isParent(source, target)) { return false; } return canDrop(shape, target, position) || canInsert(shape, target, position); } function canResize(shape, newBounds) { if ((0, _ModelUtil.is)(shape, 'bpmn:SubProcess')) { return (0, _DiUtil.isExpanded)(shape) && (!newBounds || newBounds.width >= 100 && newBounds.height >= 80); } if ((0, _ModelUtil.is)(shape, 'bpmn:Lane')) { return !newBounds || newBounds.width >= 130 && newBounds.height >= 60; } if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { return !newBounds || newBounds.width >= 250 && newBounds.height >= 50; } if (isTextAnnotation(shape)) { return true; } if (isGroup(shape)) { return true; } return false; } /** * Check, whether one side of the relationship * is a text annotation. */ function isOneTextAnnotation(source, target) { var sourceTextAnnotation = isTextAnnotation(source), targetTextAnnotation = isTextAnnotation(target); return (sourceTextAnnotation || targetTextAnnotation) && sourceTextAnnotation !== targetTextAnnotation; } function canConnectAssociation(source, target) { // do not connect connections if (isConnection(source) || isConnection(target)) { return false; } // compensation boundary events are exception if (isCompensationBoundary(source) && isForCompensation(target)) { return true; } // don't connect parent <-> child if (isParent(target, source) || isParent(source, target)) { return false; } // allow connection of associations between <!TextAnnotation> and <TextAnnotation> if (isOneTextAnnotation(source, target)) { return true; } // can connect associations where we can connect // data associations, too (!) return !!canConnectDataAssociation(source, target); } function canConnectMessageFlow(source, target) { // during connect user might move mouse out of canvas // https://github.com/bpmn-io/bpmn-js/issues/1033 if (getRootElement(source) && !getRootElement(target)) { return false; } return isMessageFlowSource(source) && isMessageFlowTarget(target) && !isSameOrganization(source, target); } function canConnectSequenceFlow(source, target) { if (isEventBasedTarget(target) && target.incoming.length > 0 && areOutgoingEventBasedGatewayConnections(target.incoming) && !(0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway')) { return false; } return isSequenceFlowSource(source) && isSequenceFlowTarget(target) && isSameScope(source, target) && !((0, _ModelUtil.is)(source, 'bpmn:EventBasedGateway') && !isEventBasedTarget(target)); } function canConnectDataAssociation(source, target) { if ((0, _ModelingUtil.isAny)(source, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference']) && (0, _ModelingUtil.isAny)(target, ['bpmn:Activity', 'bpmn:ThrowEvent'])) { return { type: 'bpmn:DataInputAssociation' }; } if ((0, _ModelingUtil.isAny)(target, ['bpmn:DataObjectReference', 'bpmn:DataStoreReference']) && (0, _ModelingUtil.isAny)(source, ['bpmn:Activity', 'bpmn:CatchEvent'])) { return { type: 'bpmn:DataOutputAssociation' }; } return false; } function canInsert(shape, flow, position) { if (!flow) { return false; } if (Array.isArray(shape)) { if (shape.length !== 1) { return false; } shape = shape[0]; } if (flow.source === shape || flow.target === shape) { return false; } // return true if we can drop on the // underlying flow parent // // at this point we are not really able to talk // about connection rules (yet) return (0, _ModelingUtil.isAny)(flow, ['bpmn:SequenceFlow', 'bpmn:MessageFlow']) && !(0, _LabelUtil.isLabel)(flow) && (0, _ModelUtil.is)(shape, 'bpmn:FlowNode') && !(0, _ModelUtil.is)(shape, 'bpmn:BoundaryEvent') && canDrop(shape, flow.parent, position); } function includes(elements, element) { return elements && element && elements.indexOf(element) !== -1; } function canCopy(elements, element) { if ((0, _LabelUtil.isLabel)(element)) { return true; } if ((0, _ModelUtil.is)(element, 'bpmn:Lane') && !includes(elements, element.parent)) { return false; } return true; } function isOutgoingEventBasedGatewayConnection(connection) { if (connection && connection.source) { return (0, _ModelUtil.is)(connection.source, 'bpmn:EventBasedGateway'); } } function areOutgoingEventBasedGatewayConnections(connections) { connections = connections || []; return connections.some(isOutgoingEventBasedGatewayConnection); } function getRootElement(element) { return (0, _ModelingUtil.getParent)(element, 'bpmn:Process') || (0, _ModelingUtil.getParent)(element, 'bpmn:Collaboration'); } },{"../../util/DiUtil":139,"../../util/LabelUtil":140,"../../util/ModelUtil":141,"../modeling/util/ModelingUtil":112,"../snapping/BpmnSnappingUtil":131,"diagram-js/lib/features/rules/RuleProvider":270,"inherits":347,"min-dash":555}],126:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _rules = _interopRequireDefault(require("diagram-js/lib/features/rules")); var _BpmnRules = _interopRequireDefault(require("./BpmnRules")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_rules.default], __init__: ['bpmnRules'], bpmnRules: ['type', _BpmnRules.default] }; exports.default = _default; },{"./BpmnRules":125,"diagram-js/lib/features/rules":272}],127:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnSearchProvider; var _minDash = require("min-dash"); var _LabelUtil = require("../label-editing/LabelUtil"); /** * Provides ability to search through BPMN elements */ function BpmnSearchProvider(elementRegistry, searchPad, canvas) { this._elementRegistry = elementRegistry; this._canvas = canvas; searchPad.registerProvider(this); } BpmnSearchProvider.$inject = ['elementRegistry', 'searchPad', 'canvas']; /** * Finds all elements that match given pattern * * <Result> : * { * primaryTokens: <Array<Token>>, * secondaryTokens: <Array<Token>>, * element: <Element> * } * * <Token> : * { * normal|matched: <string> * } * * @param {string} pattern * @return {Array<Result>} */ BpmnSearchProvider.prototype.find = function (pattern) { var rootElement = this._canvas.getRootElement(); var elements = this._elementRegistry.filter(function (element) { if (element.labelTarget) { return false; } return true; }); // do not include root element elements = (0, _minDash.filter)(elements, function (element) { return element !== rootElement; }); elements = (0, _minDash.map)(elements, function (element) { return { primaryTokens: matchAndSplit((0, _LabelUtil.getLabel)(element), pattern), secondaryTokens: matchAndSplit(element.id, pattern), element: element }; }); // exclude non-matched elements elements = (0, _minDash.filter)(elements, function (element) { return hasMatched(element.primaryTokens) || hasMatched(element.secondaryTokens); }); elements = (0, _minDash.sortBy)(elements, function (element) { return (0, _LabelUtil.getLabel)(element.element) + element.element.id; }); return elements; }; function hasMatched(tokens) { var matched = (0, _minDash.filter)(tokens, function (t) { return !!t.matched; }); return matched.length > 0; } function matchAndSplit(text, pattern) { var tokens = [], originalText = text; if (!text) { return tokens; } text = text.toLowerCase(); pattern = pattern.toLowerCase(); var i = text.indexOf(pattern); if (i > -1) { if (i !== 0) { tokens.push({ normal: originalText.substr(0, i) }); } tokens.push({ matched: originalText.substr(i, pattern.length) }); if (pattern.length + i < text.length) { tokens.push({ normal: originalText.substr(pattern.length + i, text.length) }); } } else { tokens.push({ normal: originalText }); } return tokens; } },{"../label-editing/LabelUtil":53,"min-dash":555}],128:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _searchPad = _interopRequireDefault(require("diagram-js/lib/features/search-pad")); var _BpmnSearchProvider = _interopRequireDefault(require("./BpmnSearchProvider")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_searchPad.default], __init__: ['bpmnSearch'], bpmnSearch: ['type', _BpmnSearchProvider.default] }; exports.default = _default; },{"./BpmnSearchProvider":127,"diagram-js/lib/features/search-pad":274}],129:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnConnectSnapping; var _SnapUtil = require("diagram-js/lib/features/snapping/SnapUtil"); var _KeyboardUtil = require("diagram-js/lib/features/keyboard/KeyboardUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _ModelUtil = require("../../util/ModelUtil"); var _ModelingUtil = require("../modeling/util/ModelingUtil"); var _minDash = require("min-dash"); var HIGHER_PRIORITY = 1250; var BOUNDARY_TO_HOST_THRESHOLD = 40; var TARGET_BOUNDS_PADDING = 20, TASK_BOUNDS_PADDING = 10; var TARGET_CENTER_PADDING = 20; var AXES = ['x', 'y']; var abs = Math.abs; /** * Snap during connect. * * @param {EventBus} eventBus */ function BpmnConnectSnapping(eventBus) { eventBus.on(['connect.hover', 'connect.move', 'connect.end'], HIGHER_PRIORITY, function (event) { var context = event.context, canExecute = context.canExecute, start = context.start, hover = context.hover, source = context.source, target = context.target; // do NOT snap on CMD if (event.originalEvent && (0, _KeyboardUtil.isCmd)(event.originalEvent)) { return; } if (!context.initialConnectionStart) { context.initialConnectionStart = context.connectionStart; } // snap hover if (canExecute && hover) { snapToShape(event, hover, getTargetBoundsPadding(hover)); } if (hover && isAnyType(canExecute, ['bpmn:Association', 'bpmn:DataInputAssociation', 'bpmn:DataOutputAssociation', 'bpmn:SequenceFlow'])) { context.connectionStart = (0, _SnapUtil.mid)(start); // snap hover if ((0, _ModelingUtil.isAny)(hover, ['bpmn:Event', 'bpmn:Gateway'])) { snapToPosition(event, (0, _SnapUtil.mid)(hover)); } // snap hover if ((0, _ModelingUtil.isAny)(hover, ['bpmn:Task', 'bpmn:SubProcess'])) { snapToTargetMid(event, hover); } // snap source and target if ((0, _ModelUtil.is)(source, 'bpmn:BoundaryEvent') && target === source.host) { snapBoundaryEventLoop(event); } } else if (isType(canExecute, 'bpmn:MessageFlow')) { if ((0, _ModelUtil.is)(start, 'bpmn:Event')) { // snap start context.connectionStart = (0, _SnapUtil.mid)(start); } if ((0, _ModelUtil.is)(hover, 'bpmn:Event')) { // snap hover snapToPosition(event, (0, _SnapUtil.mid)(hover)); } } else { // un-snap source context.connectionStart = context.initialConnectionStart; } }); } BpmnConnectSnapping.$inject = ['eventBus']; // helpers ////////// // snap to target if event in target function snapToShape(event, target, padding) { AXES.forEach(function (axis) { var dimensionForAxis = getDimensionForAxis(axis, target); if (event[axis] < target[axis] + padding) { (0, _SnapUtil.setSnapped)(event, axis, target[axis] + padding); } else if (event[axis] > target[axis] + dimensionForAxis - padding) { (0, _SnapUtil.setSnapped)(event, axis, target[axis] + dimensionForAxis - padding); } }); } // snap to target mid if event in target mid function snapToTargetMid(event, target) { var targetMid = (0, _SnapUtil.mid)(target); AXES.forEach(function (axis) { if (isMid(event, target, axis)) { (0, _SnapUtil.setSnapped)(event, axis, targetMid[axis]); } }); } // snap to prevent loop overlapping boundary event function snapBoundaryEventLoop(event) { var context = event.context, source = context.source, target = context.target; if (isReverse(context)) { return; } var sourceMid = (0, _SnapUtil.mid)(source), orientation = (0, _LayoutUtil.getOrientation)(sourceMid, target, -10), axes = []; if (/top|bottom/.test(orientation)) { axes.push('x'); } if (/left|right/.test(orientation)) { axes.push('y'); } axes.forEach(function (axis) { var coordinate = event[axis], newCoordinate; if (abs(coordinate - sourceMid[axis]) < BOUNDARY_TO_HOST_THRESHOLD) { if (coordinate > sourceMid[axis]) { newCoordinate = sourceMid[axis] + BOUNDARY_TO_HOST_THRESHOLD; } else { newCoordinate = sourceMid[axis] - BOUNDARY_TO_HOST_THRESHOLD; } (0, _SnapUtil.setSnapped)(event, axis, newCoordinate); } }); } function snapToPosition(event, position) { (0, _SnapUtil.setSnapped)(event, 'x', position.x); (0, _SnapUtil.setSnapped)(event, 'y', position.y); } function isType(attrs, type) { return attrs && attrs.type === type; } function isAnyType(attrs, types) { return (0, _minDash.some)(types, function (type) { return isType(attrs, type); }); } function getDimensionForAxis(axis, element) { return axis === 'x' ? element.width : element.height; } function getTargetBoundsPadding(target) { if ((0, _ModelUtil.is)(target, 'bpmn:Task')) { return TASK_BOUNDS_PADDING; } else { return TARGET_BOUNDS_PADDING; } } function isMid(event, target, axis) { return event[axis] > target[axis] + TARGET_CENTER_PADDING && event[axis] < target[axis] + getDimensionForAxis(axis, target) - TARGET_CENTER_PADDING; } function isReverse(context) { var hover = context.hover, source = context.source; return hover && source && hover === source; } },{"../../util/ModelUtil":141,"../modeling/util/ModelingUtil":112,"diagram-js/lib/features/keyboard/KeyboardUtil":216,"diagram-js/lib/features/snapping/SnapUtil":282,"diagram-js/lib/layout/LayoutUtil":300,"min-dash":555}],130:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnCreateMoveSnapping; var _inherits = _interopRequireDefault(require("inherits")); var _CreateMoveSnapping = _interopRequireDefault(require("diagram-js/lib/features/snapping/CreateMoveSnapping")); var _SnapUtil = require("diagram-js/lib/features/snapping/SnapUtil"); var _DiUtil = require("../../util/DiUtil"); var _ModelUtil = require("../../util/ModelUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _BpmnSnappingUtil = require("./BpmnSnappingUtil"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGH_PRIORITY = 1500; /** * Snap during create and move. * * @param {EventBus} eventBus * @param {Injector} injector */ function BpmnCreateMoveSnapping(eventBus, injector) { injector.invoke(_CreateMoveSnapping.default, this); // creating first participant eventBus.on(['create.move', 'create.end'], HIGH_PRIORITY, setSnappedIfConstrained); // snap boundary events eventBus.on(['create.move', 'create.end', 'shape.move.move', 'shape.move.end'], HIGH_PRIORITY, function (event) { var context = event.context, canExecute = context.canExecute, target = context.target; var canAttach = canExecute && (canExecute === 'attach' || canExecute.attach); if (canAttach && !(0, _SnapUtil.isSnapped)(event)) { snapBoundaryEvent(event, target); } }); } (0, _inherits.default)(BpmnCreateMoveSnapping, _CreateMoveSnapping.default); BpmnCreateMoveSnapping.$inject = ['eventBus', 'injector']; BpmnCreateMoveSnapping.prototype.initSnap = function (event) { var snapContext = _CreateMoveSnapping.default.prototype.initSnap.call(this, event); var shape = event.shape; var isMove = !!this._elementRegistry.get(shape.id); // snap to docking points (0, _minDash.forEach)(shape.outgoing, function (connection) { var docking = connection.waypoints[0]; docking = docking.original || docking; snapContext.setSnapOrigin(connection.id + '-docking', getDockingSnapOrigin(docking, isMove, event)); }); (0, _minDash.forEach)(shape.incoming, function (connection) { var docking = connection.waypoints[connection.waypoints.length - 1]; docking = docking.original || docking; snapContext.setSnapOrigin(connection.id + '-docking', getDockingSnapOrigin(docking, isMove, event)); }); if ((0, _ModelUtil.is)(shape, 'bpmn:Participant')) { // snap to borders with higher priority snapContext.setSnapLocations(['top-left', 'bottom-right', 'mid']); } return snapContext; }; BpmnCreateMoveSnapping.prototype.addSnapTargetPoints = function (snapPoints, shape, target) { _CreateMoveSnapping.default.prototype.addSnapTargetPoints.call(this, snapPoints, shape, target); var snapTargets = this.getSnapTargets(shape, target); (0, _minDash.forEach)(snapTargets, function (snapTarget) { // handle TRBL alignment // // * with container elements // * with text annotations if (isContainer(snapTarget) || areAll([shape, snapTarget], 'bpmn:TextAnnotation')) { snapPoints.add('top-left', (0, _SnapUtil.topLeft)(snapTarget)); snapPoints.add('bottom-right', (0, _SnapUtil.bottomRight)(snapTarget)); } }); var elementRegistry = this._elementRegistry; // snap to docking points if not create mode (0, _minDash.forEach)(shape.incoming, function (connection) { if (elementRegistry.get(shape.id)) { if (!includes(snapTargets, connection.source)) { snapPoints.add('mid', (0, _LayoutUtil.getMid)(connection.source)); } var docking = connection.waypoints[0]; snapPoints.add(connection.id + '-docking', docking.original || docking); } }); (0, _minDash.forEach)(shape.outgoing, function (connection) { if (elementRegistry.get(shape.id)) { if (!includes(snapTargets, connection.target)) { snapPoints.add('mid', (0, _LayoutUtil.getMid)(connection.target)); } var docking = connection.waypoints[connection.waypoints.length - 1]; snapPoints.add(connection.id + '-docking', docking.original || docking); } }); // add sequence flow parents as snap targets if ((0, _ModelUtil.is)(target, 'bpmn:SequenceFlow')) { snapPoints = this.addSnapTargetPoints(snapPoints, shape, target.parent); } return snapPoints; }; BpmnCreateMoveSnapping.prototype.getSnapTargets = function (shape, target) { return _CreateMoveSnapping.default.prototype.getSnapTargets.call(this, shape, target).filter(function (snapTarget) { // do not snap to lanes return !(0, _ModelUtil.is)(snapTarget, 'bpmn:Lane'); }); }; // helpers ////////// function snapBoundaryEvent(event, target) { var targetTRBL = (0, _LayoutUtil.asTRBL)(target); var direction = (0, _BpmnSnappingUtil.getBoundaryAttachment)(event, target); var context = event.context, shape = context.shape; var offset; if (shape.parent) { offset = { x: 0, y: 0 }; } else { offset = (0, _LayoutUtil.getMid)(shape); } if (/top/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.top - offset.y); } else if (/bottom/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'y', targetTRBL.bottom - offset.y); } if (/left/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.left - offset.x); } else if (/right/.test(direction)) { (0, _SnapUtil.setSnapped)(event, 'x', targetTRBL.right - offset.x); } } function areAll(elements, type) { return elements.every(function (el) { return (0, _ModelUtil.is)(el, type); }); } function isContainer(element) { if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess') && (0, _DiUtil.isExpanded)(element)) { return true; } return (0, _ModelUtil.is)(element, 'bpmn:Participant'); } function setSnappedIfConstrained(event) { var context = event.context, createConstraints = context.createConstraints; if (!createConstraints) { return; } var top = createConstraints.top, right = createConstraints.right, bottom = createConstraints.bottom, left = createConstraints.left; if (left && left >= event.x || right && right <= event.x) { (0, _SnapUtil.setSnapped)(event, 'x', event.x); } if (top && top >= event.y || bottom && bottom <= event.y) { (0, _SnapUtil.setSnapped)(event, 'y', event.y); } } function includes(array, value) { return array.indexOf(value) !== -1; } function getDockingSnapOrigin(docking, isMove, event) { return isMove ? { x: docking.x - event.x, y: docking.y - event.y } : { x: docking.x, y: docking.y }; } },{"../../util/DiUtil":139,"../../util/ModelUtil":141,"./BpmnSnappingUtil":131,"diagram-js/lib/features/snapping/CreateMoveSnapping":279,"diagram-js/lib/features/snapping/SnapUtil":282,"diagram-js/lib/layout/LayoutUtil":300,"inherits":347,"min-dash":555}],131:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getBoundaryAttachment = getBoundaryAttachment; var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); function getBoundaryAttachment(position, targetBounds) { var orientation = (0, _LayoutUtil.getOrientation)(position, targetBounds, -15); if (orientation !== 'intersect') { return orientation; } else { return null; } } },{"diagram-js/lib/layout/LayoutUtil":300}],132:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _BpmnConnectSnapping = _interopRequireDefault(require("./BpmnConnectSnapping")); var _BpmnCreateMoveSnapping = _interopRequireDefault(require("./BpmnCreateMoveSnapping")); var _snapping = _interopRequireDefault(require("diagram-js/lib/features/snapping")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_snapping.default], __init__: ['connectSnapping', 'createMoveSnapping'], connectSnapping: ['type', _BpmnConnectSnapping.default], createMoveSnapping: ['type', _BpmnCreateMoveSnapping.default] }; exports.default = _default; },{"./BpmnConnectSnapping":129,"./BpmnCreateMoveSnapping":130,"diagram-js/lib/features/snapping":284}],133:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnImporter; var _minDash = require("min-dash"); var _ModelUtil = require("../util/ModelUtil"); var _LabelUtil = require("../util/LabelUtil"); var _LayoutUtil = require("diagram-js/lib/layout/LayoutUtil"); var _DiUtil = require("../util/DiUtil"); var _LabelUtil2 = require("../features/label-editing/LabelUtil"); var _Util = require("./Util"); function elementData(semantic, attrs) { return (0, _minDash.assign)({ id: semantic.id, type: semantic.$type, businessObject: semantic }, attrs); } function getWaypoints(bo, source, target) { var waypoints = bo.di.waypoint; if (!waypoints || waypoints.length < 2) { return [(0, _LayoutUtil.getMid)(source), (0, _LayoutUtil.getMid)(target)]; } return waypoints.map(function (p) { return { x: p.x, y: p.y }; }); } function notYetDrawn(translate, semantic, refSemantic, property) { return new Error(translate('element {element} referenced by {referenced}#{property} not yet drawn', { element: (0, _Util.elementToString)(refSemantic), referenced: (0, _Util.elementToString)(semantic), property: property })); } /** * An importer that adds bpmn elements to the canvas * * @param {EventBus} eventBus * @param {Canvas} canvas * @param {ElementFactory} elementFactory * @param {ElementRegistry} elementRegistry * @param {Function} translate * @param {TextRenderer} textRenderer */ function BpmnImporter(eventBus, canvas, elementFactory, elementRegistry, translate, textRenderer) { this._eventBus = eventBus; this._canvas = canvas; this._elementFactory = elementFactory; this._elementRegistry = elementRegistry; this._translate = translate; this._textRenderer = textRenderer; } BpmnImporter.$inject = ['eventBus', 'canvas', 'elementFactory', 'elementRegistry', 'translate', 'textRenderer']; /** * Add bpmn element (semantic) to the canvas onto the * specified parent shape. */ BpmnImporter.prototype.add = function (semantic, parentElement) { var di = semantic.di, element, translate = this._translate, hidden; var parentIndex; // ROOT ELEMENT // handle the special case that we deal with a // invisible root element (process or collaboration) if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNPlane')) { // add a virtual element (not being drawn) element = this._elementFactory.createRoot(elementData(semantic)); this._canvas.setRootElement(element); } // SHAPE else if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNShape')) { var collapsed = !(0, _DiUtil.isExpanded)(semantic), isFrame = isFrameElement(semantic); hidden = parentElement && (parentElement.hidden || parentElement.collapsed); var bounds = semantic.di.bounds; element = this._elementFactory.createShape(elementData(semantic, { collapsed: collapsed, hidden: hidden, x: Math.round(bounds.x), y: Math.round(bounds.y), width: Math.round(bounds.width), height: Math.round(bounds.height), isFrame: isFrame })); if ((0, _ModelUtil.is)(semantic, 'bpmn:BoundaryEvent')) { this._attachBoundary(semantic, element); } // insert lanes behind other flow nodes (cf. #727) if ((0, _ModelUtil.is)(semantic, 'bpmn:Lane')) { parentIndex = 0; } if ((0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference')) { // check whether data store is inside our outside of its semantic parent if (!isPointInsideBBox(parentElement, (0, _LayoutUtil.getMid)(bounds))) { parentElement = this._canvas.getRootElement(); } } this._canvas.addShape(element, parentElement, parentIndex); } // CONNECTION else if ((0, _ModelUtil.is)(di, 'bpmndi:BPMNEdge')) { var source = this._getSource(semantic), target = this._getTarget(semantic); hidden = parentElement && (parentElement.hidden || parentElement.collapsed); element = this._elementFactory.createConnection(elementData(semantic, { hidden: hidden, source: source, target: target, waypoints: getWaypoints(semantic, source, target) })); if ((0, _ModelUtil.is)(semantic, 'bpmn:DataAssociation')) { // render always on top; this ensures DataAssociations // are rendered correctly across different "hacks" people // love to model such as cross participant / sub process // associations parentElement = null; } // insert sequence flows behind other flow nodes (cf. #727) if ((0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow')) { parentIndex = 0; } this._canvas.addConnection(element, parentElement, parentIndex); } else { throw new Error(translate('unknown di {di} for element {semantic}', { di: (0, _Util.elementToString)(di), semantic: (0, _Util.elementToString)(semantic) })); } // (optional) LABEL if ((0, _LabelUtil.isLabelExternal)(semantic) && (0, _LabelUtil2.getLabel)(element)) { this.addLabel(semantic, element); } this._eventBus.fire('bpmnElement.added', { element: element }); return element; }; /** * Attach the boundary element to the given host * * @param {ModdleElement} boundarySemantic * @param {djs.model.Base} boundaryElement */ BpmnImporter.prototype._attachBoundary = function (boundarySemantic, boundaryElement) { var translate = this._translate; var hostSemantic = boundarySemantic.attachedToRef; if (!hostSemantic) { throw new Error(translate('missing {semantic}#attachedToRef', { semantic: (0, _Util.elementToString)(boundarySemantic) })); } var host = this._elementRegistry.get(hostSemantic.id), attachers = host && host.attachers; if (!host) { throw notYetDrawn(translate, boundarySemantic, hostSemantic, 'attachedToRef'); } // wire element.host <> host.attachers boundaryElement.host = host; if (!attachers) { host.attachers = attachers = []; } if (attachers.indexOf(boundaryElement) === -1) { attachers.push(boundaryElement); } }; /** * add label for an element */ BpmnImporter.prototype.addLabel = function (semantic, element) { var bounds, text, label; bounds = (0, _LabelUtil.getExternalLabelBounds)(semantic, element); text = (0, _LabelUtil2.getLabel)(element); if (text) { // get corrected bounds from actual layouted text bounds = this._textRenderer.getExternalLabelBounds(bounds, text); } label = this._elementFactory.createLabel(elementData(semantic, { id: semantic.id + '_label', labelTarget: element, type: 'label', hidden: element.hidden || !(0, _LabelUtil2.getLabel)(element), x: Math.round(bounds.x), y: Math.round(bounds.y), width: Math.round(bounds.width), height: Math.round(bounds.height) })); return this._canvas.addShape(label, element.parent); }; /** * Return the drawn connection end based on the given side. * * @throws {Error} if the end is not yet drawn */ BpmnImporter.prototype._getEnd = function (semantic, side) { var element, refSemantic, type = semantic.$type, translate = this._translate; refSemantic = semantic[side + 'Ref']; // handle mysterious isMany DataAssociation#sourceRef if (side === 'source' && type === 'bpmn:DataInputAssociation') { refSemantic = refSemantic && refSemantic[0]; } // fix source / target for DataInputAssociation / DataOutputAssociation if (side === 'source' && type === 'bpmn:DataOutputAssociation' || side === 'target' && type === 'bpmn:DataInputAssociation') { refSemantic = semantic.$parent; } element = refSemantic && this._getElement(refSemantic); if (element) { return element; } if (refSemantic) { throw notYetDrawn(translate, semantic, refSemantic, side + 'Ref'); } else { throw new Error(translate('{semantic}#{side} Ref not specified', { semantic: (0, _Util.elementToString)(semantic), side: side })); } }; BpmnImporter.prototype._getSource = function (semantic) { return this._getEnd(semantic, 'source'); }; BpmnImporter.prototype._getTarget = function (semantic) { return this._getEnd(semantic, 'target'); }; BpmnImporter.prototype._getElement = function (semantic) { return this._elementRegistry.get(semantic.id); }; // helpers //////////////////// function isPointInsideBBox(bbox, point) { var x = point.x, y = point.y; return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height; } function isFrameElement(semantic) { return (0, _ModelUtil.is)(semantic, 'bpmn:Group'); } },{"../features/label-editing/LabelUtil":53,"../util/DiUtil":139,"../util/LabelUtil":140,"../util/ModelUtil":141,"./Util":136,"diagram-js/lib/layout/LayoutUtil":300,"min-dash":555}],134:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BpmnTreeWalker; var _minDash = require("min-dash"); var _objectRefs = _interopRequireDefault(require("object-refs")); var _Util = require("./Util"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var diRefs = new _objectRefs.default({ name: 'bpmnElement', enumerable: true }, { name: 'di', configurable: true }); /** * Returns true if an element has the given meta-model type * * @param {ModdleElement} element * @param {string} type * * @return {boolean} */ function is(element, type) { return element.$instanceOf(type); } /** * Find a suitable display candidate for definitions where the DI does not * correctly specify one. */ function findDisplayCandidate(definitions) { return (0, _minDash.find)(definitions.rootElements, function (e) { return is(e, 'bpmn:Process') || is(e, 'bpmn:Collaboration'); }); } function BpmnTreeWalker(handler, translate) { // list of containers already walked var handledElements = {}; // list of elements to handle deferred to ensure // prerequisites are drawn var deferred = []; // Helpers ////////////////////// function contextual(fn, ctx) { return function (e) { fn(e, ctx); }; } function handled(element) { handledElements[element.id] = element; } function isHandled(element) { return handledElements[element.id]; } function visit(element, ctx) { var gfx = element.gfx; // avoid multiple rendering of elements if (gfx) { throw new Error(translate('already rendered {element}', { element: (0, _Util.elementToString)(element) })); } // call handler return handler.element(element, ctx); } function visitRoot(element, diagram) { return handler.root(element, diagram); } function visitIfDi(element, ctx) { try { var gfx = element.di && visit(element, ctx); handled(element); return gfx; } catch (e) { logError(e.message, { element: element, error: e }); console.error(translate('failed to import {element}', { element: (0, _Util.elementToString)(element) })); console.error(e); } } function logError(message, context) { handler.error(message, context); } // DI handling ////////////////////// function registerDi(di) { var bpmnElement = di.bpmnElement; if (bpmnElement) { if (bpmnElement.di) { logError(translate('multiple DI elements defined for {element}', { element: (0, _Util.elementToString)(bpmnElement) }), { element: bpmnElement }); } else { diRefs.bind(bpmnElement, 'di'); bpmnElement.di = di; } } else { logError(translate('no bpmnElement referenced in {element}', { element: (0, _Util.elementToString)(di) }), { element: di }); } } function handleDiagram(diagram) { handlePlane(diagram.plane); } function handlePlane(plane) { registerDi(plane); (0, _minDash.forEach)(plane.planeElement, handlePlaneElement); } function handlePlaneElement(planeElement) { registerDi(planeElement); } // Semantic handling ////////////////////// /** * Handle definitions and return the rendered diagram (if any) * * @param {ModdleElement} definitions to walk and import * @param {ModdleElement} [diagram] specific diagram to import and display * * @throws {Error} if no diagram to display could be found */ function handleDefinitions(definitions, diagram) { // make sure we walk the correct bpmnElement var diagrams = definitions.diagrams; if (diagram && diagrams.indexOf(diagram) === -1) { throw new Error(translate('diagram not part of bpmn:Definitions')); } if (!diagram && diagrams && diagrams.length) { diagram = diagrams[0]; } // no diagram -> nothing to import if (!diagram) { throw new Error(translate('no diagram to display')); } // load DI from selected diagram only handleDiagram(diagram); var plane = diagram.plane; if (!plane) { throw new Error(translate('no plane for {element}', { element: (0, _Util.elementToString)(diagram) })); } var rootElement = plane.bpmnElement; // ensure we default to a suitable display candidate (process or collaboration), // even if non is specified in DI if (!rootElement) { rootElement = findDisplayCandidate(definitions); if (!rootElement) { throw new Error(translate('no process or collaboration to display')); } else { logError(translate('correcting missing bpmnElement on {plane} to {rootElement}', { plane: (0, _Util.elementToString)(plane), rootElement: (0, _Util.elementToString)(rootElement) })); // correct DI on the fly plane.bpmnElement = rootElement; registerDi(plane); } } var ctx = visitRoot(rootElement, plane); if (is(rootElement, 'bpmn:Process')) { handleProcess(rootElement, ctx); } else if (is(rootElement, 'bpmn:Collaboration')) { handleCollaboration(rootElement, ctx); // force drawing of everything not yet drawn that is part of the target DI handleUnhandledProcesses(definitions.rootElements, ctx); } else { throw new Error(translate('unsupported bpmnElement for {plane}: {rootElement}', { plane: (0, _Util.elementToString)(plane), rootElement: (0, _Util.elementToString)(rootElement) })); } // handle all deferred elements handleDeferred(deferred); } function handleDeferred() { var fn; // drain deferred until empty while (deferred.length) { fn = deferred.shift(); fn(); } } function handleProcess(process, context) { handleFlowElementsContainer(process, context); handleIoSpecification(process.ioSpecification, context); handleArtifacts(process.artifacts, context); // log process handled handled(process); } function handleUnhandledProcesses(rootElements, ctx) { // walk through all processes that have not yet been drawn and draw them // if they contain lanes with DI information. // we do this to pass the free-floating lane test cases in the MIWG test suite var processes = (0, _minDash.filter)(rootElements, function (e) { return !isHandled(e) && is(e, 'bpmn:Process') && e.laneSets; }); processes.forEach(contextual(handleProcess, ctx)); } function handleMessageFlow(messageFlow, context) { visitIfDi(messageFlow, context); } function handleMessageFlows(messageFlows, context) { (0, _minDash.forEach)(messageFlows, contextual(handleMessageFlow, context)); } function handleDataAssociation(association, context) { visitIfDi(association, context); } function handleDataInput(dataInput, context) { visitIfDi(dataInput, context); } function handleDataOutput(dataOutput, context) { visitIfDi(dataOutput, context); } function handleArtifact(artifact, context) { // bpmn:TextAnnotation // bpmn:Group // bpmn:Association visitIfDi(artifact, context); } function handleArtifacts(artifacts, context) { (0, _minDash.forEach)(artifacts, function (e) { if (is(e, 'bpmn:Association')) { deferred.push(function () { handleArtifact(e, context); }); } else { handleArtifact(e, context); } }); } function handleIoSpecification(ioSpecification, context) { if (!ioSpecification) { return; } (0, _minDash.forEach)(ioSpecification.dataInputs, contextual(handleDataInput, context)); (0, _minDash.forEach)(ioSpecification.dataOutputs, contextual(handleDataOutput, context)); } function handleSubProcess(subProcess, context) { handleFlowElementsContainer(subProcess, context); handleArtifacts(subProcess.artifacts, context); } function handleFlowNode(flowNode, context) { var childCtx = visitIfDi(flowNode, context); if (is(flowNode, 'bpmn:SubProcess')) { handleSubProcess(flowNode, childCtx || context); } if (is(flowNode, 'bpmn:Activity')) { handleIoSpecification(flowNode.ioSpecification, context); } // defer handling of associations // affected types: // // * bpmn:Activity // * bpmn:ThrowEvent // * bpmn:CatchEvent // deferred.push(function () { (0, _minDash.forEach)(flowNode.dataInputAssociations, contextual(handleDataAssociation, context)); (0, _minDash.forEach)(flowNode.dataOutputAssociations, contextual(handleDataAssociation, context)); }); } function handleSequenceFlow(sequenceFlow, context) { visitIfDi(sequenceFlow, context); } function handleDataElement(dataObject, context) { visitIfDi(dataObject, context); } function handleLane(lane, context) { deferred.push(function () { var newContext = visitIfDi(lane, context); if (lane.childLaneSet) { handleLaneSet(lane.childLaneSet, newContext || context); } wireFlowNodeRefs(lane); }); } function handleLaneSet(laneSet, context) { (0, _minDash.forEach)(laneSet.lanes, contextual(handleLane, context)); } function handleLaneSets(laneSets, context) { (0, _minDash.forEach)(laneSets, contextual(handleLaneSet, context)); } function handleFlowElementsContainer(container, context) { handleFlowElements(container.flowElements, context); if (container.laneSets) { handleLaneSets(container.laneSets, context); } } function handleFlowElements(flowElements, context) { (0, _minDash.forEach)(flowElements, function (e) { if (is(e, 'bpmn:SequenceFlow')) { deferred.push(function () { handleSequenceFlow(e, context); }); } else if (is(e, 'bpmn:BoundaryEvent')) { deferred.unshift(function () { handleFlowNode(e, context); }); } else if (is(e, 'bpmn:FlowNode')) { handleFlowNode(e, context); } else if (is(e, 'bpmn:DataObject')) {// SKIP (assume correct referencing via DataObjectReference) } else if (is(e, 'bpmn:DataStoreReference')) { handleDataElement(e, context); } else if (is(e, 'bpmn:DataObjectReference')) { handleDataElement(e, context); } else { logError(translate('unrecognized flowElement {element} in context {context}', { element: (0, _Util.elementToString)(e), context: context ? (0, _Util.elementToString)(context.businessObject) : 'null' }), { element: e, context: context }); } }); } function handleParticipant(participant, context) { var newCtx = visitIfDi(participant, context); var process = participant.processRef; if (process) { handleProcess(process, newCtx || context); } } function handleCollaboration(collaboration) { (0, _minDash.forEach)(collaboration.participants, contextual(handleParticipant)); handleArtifacts(collaboration.artifacts); // handle message flows latest in the process deferred.push(function () { handleMessageFlows(collaboration.messageFlows); }); } function wireFlowNodeRefs(lane) { // wire the virtual flowNodeRefs <-> relationship (0, _minDash.forEach)(lane.flowNodeRef, function (flowNode) { var lanes = flowNode.get('lanes'); if (lanes) { lanes.push(lane); } }); } // API ////////////////////// return { handleDeferred: handleDeferred, handleDefinitions: handleDefinitions, handleSubProcess: handleSubProcess, registerDi: registerDi }; } },{"./Util":136,"min-dash":555,"object-refs":560}],135:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.importBpmnDiagram = importBpmnDiagram; var _BpmnTreeWalker = _interopRequireDefault(require("./BpmnTreeWalker")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * The importBpmnDiagram result. * * @typedef {Object} ImportBPMNDiagramResult * * @property {Array<string>} warnings */ /** * The importBpmnDiagram error. * * @typedef {Error} ImportBPMNDiagramError * * @property {Array<string>} warnings */ /** * Import the definitions into a diagram. * * Errors and warnings are reported through the specified callback. * * @param {djs.Diagram} diagram * @param {ModdleElement<Definitions>} definitions * @param {ModdleElement<BPMNDiagram>} [bpmnDiagram] the diagram to be rendered * (if not provided, the first one will be rendered) * * Returns {Promise<ImportBPMNDiagramResult, ImportBPMNDiagramError>} */ function importBpmnDiagram(diagram, definitions, bpmnDiagram) { var importer, eventBus, translate; var error, warnings = []; /** * Walk the diagram semantically, importing (=drawing) * all elements you encounter. * * @param {ModdleElement<Definitions>} definitions * @param {ModdleElement<BPMNDiagram>} bpmnDiagram */ function render(definitions, bpmnDiagram) { var visitor = { root: function (element) { return importer.add(element); }, element: function (element, parentShape) { return importer.add(element, parentShape); }, error: function (message, context) { warnings.push({ message: message, context: context }); } }; var walker = new _BpmnTreeWalker.default(visitor, translate); // traverse BPMN 2.0 document model, // starting at definitions walker.handleDefinitions(definitions, bpmnDiagram); } return new Promise(function (resolve, reject) { try { importer = diagram.get('bpmnImporter'); eventBus = diagram.get('eventBus'); translate = diagram.get('translate'); eventBus.fire('import.render.start', { definitions: definitions }); render(definitions, bpmnDiagram); eventBus.fire('import.render.complete', { error: error, warnings: warnings }); return resolve({ warnings: warnings }); } catch (e) { e.warnings = warnings; return reject(e); } }); } },{"./BpmnTreeWalker":134}],136:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.elementToString = elementToString; function elementToString(e) { if (!e) { return '<null>'; } return '<' + e.$type + (e.id ? ' id="' + e.id : '') + '" />'; } },{}],137:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _translate = _interopRequireDefault(require("diagram-js/lib/i18n/translate")); var _BpmnImporter = _interopRequireDefault(require("./BpmnImporter")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_translate.default], bpmnImporter: ['type', _BpmnImporter.default] }; exports.default = _default; },{"./BpmnImporter":133,"diagram-js/lib/i18n/translate":296}],138:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.wrapForCompatibility = wrapForCompatibility; var _minDash = require("min-dash"); // TODO(nikku): remove with future bpmn-js version /** * Wraps APIs to check: * * 1) If a callback is passed -> Warn users about callback deprecation. * 2) If Promise class is implemented in current environment. * * @private */ function wrapForCompatibility(api) { return function () { if (!window.Promise) { throw new Error('Promises is not supported in this environment. Please polyfill Promise.'); } var argLen = arguments.length; if (argLen >= 1 && (0, _minDash.isFunction)(arguments[argLen - 1])) { var callback = arguments[argLen - 1]; console.warn(new Error('Passing callbacks to ' + api.name + ' is deprecated and will be removed in a future major release. ' + 'Please switch to promises: https://bpmn.io/l/moving-to-promises.html')); var argsWithoutCallback = Array.prototype.slice.call(arguments, 0, -1); api.apply(this, argsWithoutCallback).then(function (result) { var firstKey = Object.keys(result)[0]; // The APIs we are wrapping all resolve a single item depending on the API. // For instance, importXML resolves { warnings } and saveXML returns { xml }. // That's why we can call the callback with the first item of result. return callback(null, result[firstKey]); // Passing a second paramter instead of catch because we don't want to // catch errors thrown by callback(). }, function (err) { return callback(err, err.warnings); }); } else { return api.apply(this, arguments); } }; } },{"min-dash":555}],139:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isExpanded = isExpanded; exports.isInterrupting = isInterrupting; exports.isEventSubProcess = isEventSubProcess; exports.hasEventDefinition = hasEventDefinition; exports.hasErrorEventDefinition = hasErrorEventDefinition; exports.hasEscalationEventDefinition = hasEscalationEventDefinition; exports.hasCompensateEventDefinition = hasCompensateEventDefinition; var _ModelUtil = require("./ModelUtil"); var _minDash = require("min-dash"); function isExpanded(element) { if ((0, _ModelUtil.is)(element, 'bpmn:CallActivity')) { return false; } if ((0, _ModelUtil.is)(element, 'bpmn:SubProcess')) { return !!(0, _ModelUtil.getBusinessObject)(element).di.isExpanded; } if ((0, _ModelUtil.is)(element, 'bpmn:Participant')) { return !!(0, _ModelUtil.getBusinessObject)(element).processRef; } return true; } function isInterrupting(element) { return element && (0, _ModelUtil.getBusinessObject)(element).isInterrupting !== false; } function isEventSubProcess(element) { return element && !!(0, _ModelUtil.getBusinessObject)(element).triggeredByEvent; } function hasEventDefinition(element, eventType) { var bo = (0, _ModelUtil.getBusinessObject)(element), hasEventDefinition = false; if (bo.eventDefinitions) { (0, _minDash.forEach)(bo.eventDefinitions, function (event) { if ((0, _ModelUtil.is)(event, eventType)) { hasEventDefinition = true; } }); } return hasEventDefinition; } function hasErrorEventDefinition(element) { return hasEventDefinition(element, 'bpmn:ErrorEventDefinition'); } function hasEscalationEventDefinition(element) { return hasEventDefinition(element, 'bpmn:EscalationEventDefinition'); } function hasCompensateEventDefinition(element) { return hasEventDefinition(element, 'bpmn:CompensateEventDefinition'); } },{"./ModelUtil":141,"min-dash":555}],140:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isLabelExternal = isLabelExternal; exports.hasExternalLabel = hasExternalLabel; exports.getFlowLabelPosition = getFlowLabelPosition; exports.getWaypointsMid = getWaypointsMid; exports.getExternalLabelMid = getExternalLabelMid; exports.getExternalLabelBounds = getExternalLabelBounds; exports.isLabel = isLabel; exports.FLOW_LABEL_INDENT = exports.DEFAULT_LABEL_SIZE = void 0; var _minDash = require("min-dash"); var _ModelUtil = require("./ModelUtil"); var DEFAULT_LABEL_SIZE = { width: 90, height: 20 }; exports.DEFAULT_LABEL_SIZE = DEFAULT_LABEL_SIZE; var FLOW_LABEL_INDENT = 15; /** * Returns true if the given semantic has an external label * * @param {BpmnElement} semantic * @return {boolean} true if has label */ exports.FLOW_LABEL_INDENT = FLOW_LABEL_INDENT; function isLabelExternal(semantic) { return (0, _ModelUtil.is)(semantic, 'bpmn:Event') || (0, _ModelUtil.is)(semantic, 'bpmn:Gateway') || (0, _ModelUtil.is)(semantic, 'bpmn:DataStoreReference') || (0, _ModelUtil.is)(semantic, 'bpmn:DataObjectReference') || (0, _ModelUtil.is)(semantic, 'bpmn:DataInput') || (0, _ModelUtil.is)(semantic, 'bpmn:DataOutput') || (0, _ModelUtil.is)(semantic, 'bpmn:SequenceFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:MessageFlow') || (0, _ModelUtil.is)(semantic, 'bpmn:Group'); } /** * Returns true if the given element has an external label * * @param {djs.model.shape} element * @return {boolean} true if has label */ function hasExternalLabel(element) { return isLabel(element.label); } /** * Get the position for sequence flow labels * * @param {Array<Point>} waypoints * @return {Point} the label position */ function getFlowLabelPosition(waypoints) { // get the waypoints mid var mid = waypoints.length / 2 - 1; var first = waypoints[Math.floor(mid)]; var second = waypoints[Math.ceil(mid + 0.01)]; // get position var position = getWaypointsMid(waypoints); // calculate angle var angle = Math.atan((second.y - first.y) / (second.x - first.x)); var x = position.x, y = position.y; if (Math.abs(angle) < Math.PI / 2) { y -= FLOW_LABEL_INDENT; } else { x += FLOW_LABEL_INDENT; } return { x: x, y: y }; } /** * Get the middle of a number of waypoints * * @param {Array<Point>} waypoints * @return {Point} the mid point */ function getWaypointsMid(waypoints) { var mid = waypoints.length / 2 - 1; var first = waypoints[Math.floor(mid)]; var second = waypoints[Math.ceil(mid + 0.01)]; return { x: first.x + (second.x - first.x) / 2, y: first.y + (second.y - first.y) / 2 }; } function getExternalLabelMid(element) { if (element.waypoints) { return getFlowLabelPosition(element.waypoints); } else if ((0, _ModelUtil.is)(element, 'bpmn:Group')) { return { x: element.x + element.width / 2, y: element.y + DEFAULT_LABEL_SIZE.height / 2 }; } else { return { x: element.x + element.width / 2, y: element.y + element.height + DEFAULT_LABEL_SIZE.height / 2 }; } } /** * Returns the bounds of an elements label, parsed from the elements DI or * generated from its bounds. * * @param {BpmnElement} semantic * @param {djs.model.Base} element */ function getExternalLabelBounds(semantic, element) { var mid, size, bounds, di = semantic.di, label = di.label; if (label && label.bounds) { bounds = label.bounds; size = { width: Math.max(DEFAULT_LABEL_SIZE.width, bounds.width), height: bounds.height }; mid = { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 }; } else { mid = getExternalLabelMid(element); size = DEFAULT_LABEL_SIZE; } return (0, _minDash.assign)({ x: mid.x - size.width / 2, y: mid.y - size.height / 2 }, size); } function isLabel(element) { return element && !!element.labelTarget; } },{"./ModelUtil":141,"min-dash":555}],141:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.is = is; exports.getBusinessObject = getBusinessObject; /** * Is an element of the given BPMN type? * * @param {djs.model.Base|ModdleElement} element * @param {string} type * * @return {boolean} */ function is(element, type) { var bo = getBusinessObject(element); return bo && typeof bo.$instanceOf === 'function' && bo.$instanceOf(type); } /** * Return the business object for a given element. * * @param {djs.model.Base|ModdleElement} element * * @return {ModdleElement} */ function getBusinessObject(element) { return element && element.businessObject || element; } },{}],142:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.open = open; exports.LINK_STYLES = exports.BPMNIO_IMG = void 0; var _minDom = require("min-dom"); /** * This file must not be changed or exchanged. * * @see http://bpmn.io/license for more information. */ // inlined ../../resources/logo.svg var BPMNIO_LOGO_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14.02 5.57" width="53" height="21" style="vertical-align:middle"><path fill="currentColor" d="M1.88.92v.14c0 .41-.13.68-.4.8.33.14.46.44.46.86v.33c0 .61-.33.95-.95.95H0V0h.95c.65 0 .93.3.93.92zM.63.57v1.06h.24c.24 0 .38-.1.38-.43V.98c0-.28-.1-.4-.32-.4zm0 1.63v1.22h.36c.2 0 .32-.1.32-.39v-.35c0-.37-.12-.48-.4-.48H.63zM4.18.99v.52c0 .64-.31.98-.94.98h-.3V4h-.62V0h.92c.63 0 .94.35.94.99zM2.94.57v1.35h.3c.2 0 .3-.09.3-.37v-.6c0-.29-.1-.38-.3-.38h-.3zm2.89 2.27L6.25 0h.88v4h-.6V1.12L6.1 3.99h-.6l-.46-2.82v2.82h-.55V0h.87zM8.14 1.1V4h-.56V0h.79L9 2.4V0h.56v4h-.64zm2.49 2.29v.6h-.6v-.6zM12.12 1c0-.63.33-1 .95-1 .61 0 .95.37.95 1v2.04c0 .64-.34 1-.95 1-.62 0-.95-.37-.95-1zm.62 2.08c0 .28.13.39.33.39s.32-.1.32-.4V.98c0-.29-.12-.4-.32-.4s-.33.11-.33.4z"/><path fill="currentColor" d="M0 4.53h14.02v1.04H0zM11.08 0h.63v.62h-.63zm.63 4V1h-.63v2.98z"/></svg>'; var BPMNIO_IMG = BPMNIO_LOGO_SVG; exports.BPMNIO_IMG = BPMNIO_IMG; function css(attrs) { return attrs.join(';'); } var LINK_STYLES = css(['color: #404040']); exports.LINK_STYLES = LINK_STYLES; var LIGHTBOX_STYLES = css(['z-index: 1001', 'position: fixed', 'top: 0', 'left: 0', 'right: 0', 'bottom: 0']); var BACKDROP_STYLES = css(['width: 100%', 'height: 100%', 'background: rgba(40,40,40,0.2)']); var NOTICE_STYLES = css(['position: absolute', 'left: 50%', 'top: 40%', 'transform: translate(-50%)', 'width: 260px', 'padding: 10px', 'background: white', 'box-shadow: 0 1px 4px rgba(0,0,0,0.3)', 'font-family: Helvetica, Arial, sans-serif', 'font-size: 14px', 'display: flex', 'line-height: 1.3']); var LIGHTBOX_MARKUP = '<div class="bjs-powered-by-lightbox" style="' + LIGHTBOX_STYLES + '">' + '<div class="backdrop" style="' + BACKDROP_STYLES + '"></div>' + '<div class="notice" style="' + NOTICE_STYLES + '">' + '<a href="https://bpmn.io" target="_blank" rel="noopener" style="margin: 15px 20px 15px 10px; align-self: center;' + LINK_STYLES + '">' + BPMNIO_IMG + '</a>' + '<span>' + 'Web-based tooling for BPMN, DMN and CMMN diagrams ' + 'powered by <a href="https://bpmn.io" target="_blank" rel="noopener">bpmn.io</a>.' + '</span>' + '</div>' + '</div>'; var lightbox; function open() { if (!lightbox) { lightbox = (0, _minDom.domify)(LIGHTBOX_MARKUP); _minDom.delegate.bind(lightbox, '.backdrop', 'click', function (event) { document.body.removeChild(lightbox); }); } document.body.appendChild(lightbox); } },{"min-dom":556}],143:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "default", { enumerable: true, get: function () { return _Diagram.default; } }); var _Diagram = _interopRequireDefault(require("./lib/Diagram")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } },{"./lib/Diagram":144}],144:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Diagram; var _didi = require("didi"); var _core = _interopRequireDefault(require("./core")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Bootstrap an injector from a list of modules, instantiating a number of default components * * @ignore * @param {Array<didi.Module>} bootstrapModules * * @return {didi.Injector} a injector to use to access the components */ function bootstrap(bootstrapModules) { var modules = [], components = []; function hasModule(m) { return modules.indexOf(m) >= 0; } function addModule(m) { modules.push(m); } function visit(m) { if (hasModule(m)) { return; } (m.__depends__ || []).forEach(visit); if (hasModule(m)) { return; } addModule(m); (m.__init__ || []).forEach(function (c) { components.push(c); }); } bootstrapModules.forEach(visit); var injector = new _didi.Injector(modules); components.forEach(function (c) { try { // eagerly resolve component (fn or string) injector[typeof c === 'string' ? 'get' : 'invoke'](c); } catch (e) { console.error('Failed to instantiate component'); console.error(e.stack); throw e; } }); return injector; } /** * Creates an injector from passed options. * * @ignore * @param {Object} options * @return {didi.Injector} */ function createInjector(options) { options = options || {}; var configModule = { 'config': ['value', options] }; var modules = [configModule, _core.default].concat(options.modules || []); return bootstrap(modules); } /** * The main diagram-js entry point that bootstraps the diagram with the given * configuration. * * To register extensions with the diagram, pass them as Array<didi.Module> to the constructor. * * @class djs.Diagram * @memberOf djs * @constructor * * @example * * <caption>Creating a plug-in that logs whenever a shape is added to the canvas.</caption> * * // plug-in implemenentation * function MyLoggingPlugin(eventBus) { * eventBus.on('shape.added', function(event) { * console.log('shape ', event.shape, ' was added to the diagram'); * }); * } * * // export as module * export default { * __init__: [ 'myLoggingPlugin' ], * myLoggingPlugin: [ 'type', MyLoggingPlugin ] * }; * * * // instantiate the diagram with the new plug-in * * import MyLoggingModule from 'path-to-my-logging-plugin'; * * var diagram = new Diagram({ * modules: [ * MyLoggingModule * ] * }); * * diagram.invoke([ 'canvas', function(canvas) { * // add shape to drawing canvas * canvas.addShape({ x: 10, y: 10 }); * }); * * // 'shape ... was added to the diagram' logged to console * * @param {Object} options * @param {Array<didi.Module>} [options.modules] external modules to instantiate with the diagram * @param {didi.Injector} [injector] an (optional) injector to bootstrap the diagram with */ function Diagram(options, injector) { // create injector unless explicitly specified this.injector = injector = injector || createInjector(options); // API /** * Resolves a diagram service * * @method Diagram#get * * @param {string} name the name of the diagram service to be retrieved * @param {boolean} [strict=true] if false, resolve missing services to null */ this.get = injector.get; /** * Executes a function into which diagram services are injected * * @method Diagram#invoke * * @param {Function|Object[]} fn the function to resolve * @param {Object} locals a number of locals to use to resolve certain dependencies */ this.invoke = injector.invoke; // init // indicate via event /** * An event indicating that all plug-ins are loaded. * * Use this event to fire other events to interested plug-ins * * @memberOf Diagram * * @event diagram.init * * @example * * eventBus.on('diagram.init', function() { * eventBus.fire('my-custom-event', { foo: 'BAR' }); * }); * * @type {Object} */ this.get('eventBus').fire('diagram.init'); } /** * Destroys the diagram * * @method Diagram#destroy */ Diagram.prototype.destroy = function () { this.get('eventBus').fire('diagram.destroy'); }; /** * Clear the diagram, removing all contents. */ Diagram.prototype.clear = function () { this.get('eventBus').fire('diagram.clear'); }; },{"./core":153,"didi":344}],145:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CommandInterceptor; var _minDash = require("min-dash"); var DEFAULT_PRIORITY = 1000; /** * A utility that can be used to plug-in into the command execution for * extension and/or validation. * * @param {EventBus} eventBus * * @example * * import inherits from 'inherits'; * * import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor'; * * function CommandLogger(eventBus) { * CommandInterceptor.call(this, eventBus); * * this.preExecute(function(event) { * console.log('command pre-execute', event); * }); * } * * inherits(CommandLogger, CommandInterceptor); * */ function CommandInterceptor(eventBus) { this._eventBus = eventBus; } CommandInterceptor.$inject = ['eventBus']; function unwrapEvent(fn, that) { return function (event) { return fn.call(that || null, event.context, event.command, event); }; } /** * Register an interceptor for a command execution * * @param {string|Array<string>} [events] list of commands to register on * @param {string} [hook] command hook, i.e. preExecute, executed to listen on * @param {number} [priority] the priority on which to hook into the execution * @param {Function} handlerFn interceptor to be invoked with (event) * @param {boolean} unwrap if true, unwrap the event and pass (context, command, event) to the * listener instead * @param {Object} [that] Pass context (`this`) to the handler function */ CommandInterceptor.prototype.on = function (events, hook, priority, handlerFn, unwrap, that) { if ((0, _minDash.isFunction)(hook) || (0, _minDash.isNumber)(hook)) { that = unwrap; unwrap = handlerFn; handlerFn = priority; priority = hook; hook = null; } if ((0, _minDash.isFunction)(priority)) { that = unwrap; unwrap = handlerFn; handlerFn = priority; priority = DEFAULT_PRIORITY; } if ((0, _minDash.isObject)(unwrap)) { that = unwrap; unwrap = false; } if (!(0, _minDash.isFunction)(handlerFn)) { throw new Error('handlerFn must be a function'); } if (!(0, _minDash.isArray)(events)) { events = [events]; } var eventBus = this._eventBus; (0, _minDash.forEach)(events, function (event) { // concat commandStack(.event)?(.hook)? var fullEvent = ['commandStack', event, hook].filter(function (e) { return e; }).join('.'); eventBus.on(fullEvent, priority, unwrap ? unwrapEvent(handlerFn, that) : handlerFn, that); }); }; var hooks = ['canExecute', 'preExecute', 'preExecuted', 'execute', 'executed', 'postExecute', 'postExecuted', 'revert', 'reverted']; /* * Install hook shortcuts * * This will generate the CommandInterceptor#(preExecute|...|reverted) methods * which will in term forward to CommandInterceptor#on. */ (0, _minDash.forEach)(hooks, function (hook) { /** * {canExecute|preExecute|preExecuted|execute|executed|postExecute|postExecuted|revert|reverted} * * A named hook for plugging into the command execution * * @param {string|Array<string>} [events] list of commands to register on * @param {number} [priority] the priority on which to hook into the execution * @param {Function} handlerFn interceptor to be invoked with (event) * @param {boolean} [unwrap=false] if true, unwrap the event and pass (context, command, event) to the * listener instead * @param {Object} [that] Pass context (`this`) to the handler function */ CommandInterceptor.prototype[hook] = function (events, priority, handlerFn, unwrap, that) { if ((0, _minDash.isFunction)(events) || (0, _minDash.isNumber)(events)) { that = unwrap; unwrap = handlerFn; handlerFn = priority; priority = events; events = null; } this.on(events, hook, priority, handlerFn, unwrap, that); }; }); },{"min-dash":555}],146:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CommandStack; var _minDash = require("min-dash"); /** * A service that offers un- and redoable execution of commands. * * The command stack is responsible for executing modeling actions * in a un- and redoable manner. To do this it delegates the actual * command execution to {@link CommandHandler}s. * * Command handlers provide {@link CommandHandler#execute(ctx)} and * {@link CommandHandler#revert(ctx)} methods to un- and redo a command * identified by a command context. * * * ## Life-Cycle events * * In the process the command stack fires a number of life-cycle events * that other components to participate in the command execution. * * * preExecute * * preExecuted * * execute * * executed * * postExecute * * postExecuted * * revert * * reverted * * A special event is used for validating, whether a command can be * performed prior to its execution. * * * canExecute * * Each of the events is fired as `commandStack.{eventName}` and * `commandStack.{commandName}.{eventName}`, respectively. This gives * components fine grained control on where to hook into. * * The event object fired transports `command`, the name of the * command and `context`, the command context. * * * ## Creating Command Handlers * * Command handlers should provide the {@link CommandHandler#execute(ctx)} * and {@link CommandHandler#revert(ctx)} methods to implement * redoing and undoing of a command. * * A command handler _must_ ensure undo is performed properly in order * not to break the undo chain. It must also return the shapes that * got changed during the `execute` and `revert` operations. * * Command handlers may execute other modeling operations (and thus * commands) in their `preExecute` and `postExecute` phases. The command * stack will properly group all commands together into a logical unit * that may be re- and undone atomically. * * Command handlers must not execute other commands from within their * core implementation (`execute`, `revert`). * * * ## Change Tracking * * During the execution of the CommandStack it will keep track of all * elements that have been touched during the command's execution. * * At the end of the CommandStack execution it will notify interested * components via an 'elements.changed' event with all the dirty * elements. * * The event can be picked up by components that are interested in the fact * that elements have been changed. One use case for this is updating * their graphical representation after moving / resizing or deletion. * * @see CommandHandler * * @param {EventBus} eventBus * @param {Injector} injector */ function CommandStack(eventBus, injector) { /** * A map of all registered command handlers. * * @type {Object} */ this._handlerMap = {}; /** * A stack containing all re/undoable actions on the diagram * * @type {Array<Object>} */ this._stack = []; /** * The current index on the stack * * @type {number} */ this._stackIdx = -1; /** * Current active commandStack execution * * @type {Object} */ this._currentExecution = { actions: [], dirty: [] }; this._injector = injector; this._eventBus = eventBus; this._uid = 1; eventBus.on(['diagram.destroy', 'diagram.clear'], function () { this.clear(false); }, this); } CommandStack.$inject = ['eventBus', 'injector']; /** * Execute a command * * @param {string} command the command to execute * @param {Object} context the environment to execute the command in */ CommandStack.prototype.execute = function (command, context) { if (!command) { throw new Error('command required'); } var action = { command: command, context: context }; this._pushAction(action); this._internalExecute(action); this._popAction(action); }; /** * Ask whether a given command can be executed. * * Implementors may hook into the mechanism on two ways: * * * in event listeners: * * Users may prevent the execution via an event listener. * It must prevent the default action for `commandStack.(<command>.)canExecute` events. * * * in command handlers: * * If the method {@link CommandHandler#canExecute} is implemented in a handler * it will be called to figure out whether the execution is allowed. * * @param {string} command the command to execute * @param {Object} context the environment to execute the command in * * @return {boolean} true if the command can be executed */ CommandStack.prototype.canExecute = function (command, context) { var action = { command: command, context: context }; var handler = this._getHandler(command); var result = this._fire(command, 'canExecute', action); // handler#canExecute will only be called if no listener // decided on a result already if (result === undefined) { if (!handler) { return false; } if (handler.canExecute) { result = handler.canExecute(context); } } return result; }; /** * Clear the command stack, erasing all undo / redo history */ CommandStack.prototype.clear = function (emit) { this._stack.length = 0; this._stackIdx = -1; if (emit !== false) { this._fire('changed'); } }; /** * Undo last command(s) */ CommandStack.prototype.undo = function () { var action = this._getUndoAction(), next; if (action) { this._pushAction(action); while (action) { this._internalUndo(action); next = this._getUndoAction(); if (!next || next.id !== action.id) { break; } action = next; } this._popAction(); } }; /** * Redo last command(s) */ CommandStack.prototype.redo = function () { var action = this._getRedoAction(), next; if (action) { this._pushAction(action); while (action) { this._internalExecute(action, true); next = this._getRedoAction(); if (!next || next.id !== action.id) { break; } action = next; } this._popAction(); } }; /** * Register a handler instance with the command stack * * @param {string} command * @param {CommandHandler} handler */ CommandStack.prototype.register = function (command, handler) { this._setHandler(command, handler); }; /** * Register a handler type with the command stack * by instantiating it and injecting its dependencies. * * @param {string} command * @param {Function} a constructor for a {@link CommandHandler} */ CommandStack.prototype.registerHandler = function (command, handlerCls) { if (!command || !handlerCls) { throw new Error('command and handlerCls must be defined'); } var handler = this._injector.instantiate(handlerCls); this.register(command, handler); }; CommandStack.prototype.canUndo = function () { return !!this._getUndoAction(); }; CommandStack.prototype.canRedo = function () { return !!this._getRedoAction(); }; // stack access ////////////////////// CommandStack.prototype._getRedoAction = function () { return this._stack[this._stackIdx + 1]; }; CommandStack.prototype._getUndoAction = function () { return this._stack[this._stackIdx]; }; // internal functionality ////////////////////// CommandStack.prototype._internalUndo = function (action) { var self = this; var command = action.command, context = action.context; var handler = this._getHandler(command); // guard against illegal nested command stack invocations this._atomicDo(function () { self._fire(command, 'revert', action); if (handler.revert) { self._markDirty(handler.revert(context)); } self._revertedAction(action); self._fire(command, 'reverted', action); }); }; CommandStack.prototype._fire = function (command, qualifier, event) { if (arguments.length < 3) { event = qualifier; qualifier = null; } var names = qualifier ? [command + '.' + qualifier, qualifier] : [command], i, name, result; event = this._eventBus.createEvent(event); for (i = 0; name = names[i]; i++) { result = this._eventBus.fire('commandStack.' + name, event); if (event.cancelBubble) { break; } } return result; }; CommandStack.prototype._createId = function () { return this._uid++; }; CommandStack.prototype._atomicDo = function (fn) { var execution = this._currentExecution; execution.atomic = true; try { fn(); } finally { execution.atomic = false; } }; CommandStack.prototype._internalExecute = function (action, redo) { var self = this; var command = action.command, context = action.context; var handler = this._getHandler(command); if (!handler) { throw new Error('no command handler registered for <' + command + '>'); } this._pushAction(action); if (!redo) { this._fire(command, 'preExecute', action); if (handler.preExecute) { handler.preExecute(context); } this._fire(command, 'preExecuted', action); } // guard against illegal nested command stack invocations this._atomicDo(function () { self._fire(command, 'execute', action); if (handler.execute) { // actual execute + mark return results as dirty self._markDirty(handler.execute(context)); } // log to stack self._executedAction(action, redo); self._fire(command, 'executed', action); }); if (!redo) { this._fire(command, 'postExecute', action); if (handler.postExecute) { handler.postExecute(context); } this._fire(command, 'postExecuted', action); } this._popAction(action); }; CommandStack.prototype._pushAction = function (action) { var execution = this._currentExecution, actions = execution.actions; var baseAction = actions[0]; if (execution.atomic) { throw new Error('illegal invocation in <execute> or <revert> phase (action: ' + action.command + ')'); } if (!action.id) { action.id = baseAction && baseAction.id || this._createId(); } actions.push(action); }; CommandStack.prototype._popAction = function () { var execution = this._currentExecution, actions = execution.actions, dirty = execution.dirty; actions.pop(); if (!actions.length) { this._eventBus.fire('elements.changed', { elements: (0, _minDash.uniqueBy)('id', dirty.reverse()) }); dirty.length = 0; this._fire('changed'); } }; CommandStack.prototype._markDirty = function (elements) { var execution = this._currentExecution; if (!elements) { return; } elements = (0, _minDash.isArray)(elements) ? elements : [elements]; execution.dirty = execution.dirty.concat(elements); }; CommandStack.prototype._executedAction = function (action, redo) { var stackIdx = ++this._stackIdx; if (!redo) { this._stack.splice(stackIdx, this._stack.length, action); } }; CommandStack.prototype._revertedAction = function (action) { this._stackIdx--; }; CommandStack.prototype._getHandler = function (command) { return this._handlerMap[command]; }; CommandStack.prototype._setHandler = function (command, handler) { if (!command || !handler) { throw new Error('command and handler required'); } if (this._handlerMap[command]) { throw new Error('overriding handler for command <' + command + '>'); } this._handlerMap[command] = handler; }; },{"min-dash":555}],147:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _CommandStack = _interopRequireDefault(require("./CommandStack")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { commandStack: ['type', _CommandStack.default] }; exports.default = _default; },{"./CommandStack":146}],148:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Canvas; var _minDash = require("min-dash"); var _Collections = require("../util/Collections"); var _Elements = require("../util/Elements"); var _tinySvg = require("tiny-svg"); function round(number, resolution) { return Math.round(number * resolution) / resolution; } function ensurePx(number) { return (0, _minDash.isNumber)(number) ? number + 'px' : number; } /** * Creates a HTML container element for a SVG element with * the given configuration * * @param {Object} options * @return {HTMLElement} the container element */ function createContainer(options) { options = (0, _minDash.assign)({}, { width: '100%', height: '100%' }, options); var container = options.container || document.body; // create a <div> around the svg element with the respective size // this way we can always get the correct container size // (this is impossible for <svg> elements at the moment) var parent = document.createElement('div'); parent.setAttribute('class', 'djs-container'); (0, _minDash.assign)(parent.style, { position: 'relative', overflow: 'hidden', width: ensurePx(options.width), height: ensurePx(options.height) }); container.appendChild(parent); return parent; } function createGroup(parent, cls, childIndex) { var group = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(group).add(cls); var index = childIndex !== undefined ? childIndex : parent.childNodes.length - 1; // must ensure second argument is node or _null_ // cf. https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore parent.insertBefore(group, parent.childNodes[index] || null); return group; } var BASE_LAYER = 'base'; var REQUIRED_MODEL_ATTRS = { shape: ['x', 'y', 'width', 'height'], connection: ['waypoints'] }; /** * The main drawing canvas. * * @class * @constructor * * @emits Canvas#canvas.init * * @param {Object} config * @param {EventBus} eventBus * @param {GraphicsFactory} graphicsFactory * @param {ElementRegistry} elementRegistry */ function Canvas(config, eventBus, graphicsFactory, elementRegistry) { this._eventBus = eventBus; this._elementRegistry = elementRegistry; this._graphicsFactory = graphicsFactory; this._init(config || {}); } Canvas.$inject = ['config.canvas', 'eventBus', 'graphicsFactory', 'elementRegistry']; Canvas.prototype._init = function (config) { var eventBus = this._eventBus; // Creates a <svg> element that is wrapped into a <div>. // This way we are always able to correctly figure out the size of the svg element // by querying the parent node. // // (It is not possible to get the size of a svg element cross browser @ 2014-04-01) // // <div class="djs-container" style="width: {desired-width}, height: {desired-height}"> // <svg width="100%" height="100%"> // ... // </svg> // </div> // html container var container = this._container = createContainer(config); var svg = this._svg = (0, _tinySvg.create)('svg'); (0, _tinySvg.attr)(svg, { width: '100%', height: '100%' }); (0, _tinySvg.append)(container, svg); var viewport = this._viewport = createGroup(svg, 'viewport'); this._layers = {}; // debounce canvas.viewbox.changed events // for smoother diagram interaction if (config.deferUpdate !== false) { this._viewboxChanged = (0, _minDash.debounce)((0, _minDash.bind)(this._viewboxChanged, this), 300); } eventBus.on('diagram.init', function () { /** * An event indicating that the canvas is ready to be drawn on. * * @memberOf Canvas * * @event canvas.init * * @type {Object} * @property {SVGElement} svg the created svg element * @property {SVGElement} viewport the direct parent of diagram elements and shapes */ eventBus.fire('canvas.init', { svg: svg, viewport: viewport }); }, this); // reset viewbox on shape changes to // recompute the viewbox eventBus.on(['shape.added', 'connection.added', 'shape.removed', 'connection.removed', 'elements.changed'], function () { delete this._cachedViewbox; }, this); eventBus.on('diagram.destroy', 500, this._destroy, this); eventBus.on('diagram.clear', 500, this._clear, this); }; Canvas.prototype._destroy = function (emit) { this._eventBus.fire('canvas.destroy', { svg: this._svg, viewport: this._viewport }); var parent = this._container.parentNode; if (parent) { parent.removeChild(this._container); } delete this._svg; delete this._container; delete this._layers; delete this._rootElement; delete this._viewport; }; Canvas.prototype._clear = function () { var self = this; var allElements = this._elementRegistry.getAll(); // remove all elements allElements.forEach(function (element) { var type = (0, _Elements.getType)(element); if (type === 'root') { self.setRootElement(null, true); } else { self._removeElement(element, type); } }); // force recomputation of view box delete this._cachedViewbox; }; /** * Returns the default layer on which * all elements are drawn. * * @returns {SVGElement} */ Canvas.prototype.getDefaultLayer = function () { return this.getLayer(BASE_LAYER, 0); }; /** * Returns a layer that is used to draw elements * or annotations on it. * * Non-existing layers retrieved through this method * will be created. During creation, the optional index * may be used to create layers below or above existing layers. * A layer with a certain index is always created above all * existing layers with the same index. * * @param {string} name * @param {number} index * * @returns {SVGElement} */ Canvas.prototype.getLayer = function (name, index) { if (!name) { throw new Error('must specify a name'); } var layer = this._layers[name]; if (!layer) { layer = this._layers[name] = this._createLayer(name, index); } // throw an error if layer creation / retrival is // requested on different index if (typeof index !== 'undefined' && layer.index !== index) { throw new Error('layer <' + name + '> already created at index <' + index + '>'); } return layer.group; }; /** * Creates a given layer and returns it. * * @param {string} name * @param {number} [index=0] * * @return {Object} layer descriptor with { index, group: SVGGroup } */ Canvas.prototype._createLayer = function (name, index) { if (!index) { index = 0; } var childIndex = (0, _minDash.reduce)(this._layers, function (childIndex, layer) { if (index >= layer.index) { childIndex++; } return childIndex; }, 0); return { group: createGroup(this._viewport, 'layer-' + name, childIndex), index: index }; }; /** * Returns the html element that encloses the * drawing canvas. * * @return {DOMNode} */ Canvas.prototype.getContainer = function () { return this._container; }; // markers ////////////////////// Canvas.prototype._updateMarker = function (element, marker, add) { var container; if (!element.id) { element = this._elementRegistry.get(element); } // we need to access all container = this._elementRegistry._elements[element.id]; if (!container) { return; } (0, _minDash.forEach)([container.gfx, container.secondaryGfx], function (gfx) { if (gfx) { // invoke either addClass or removeClass based on mode if (add) { (0, _tinySvg.classes)(gfx).add(marker); } else { (0, _tinySvg.classes)(gfx).remove(marker); } } }); /** * An event indicating that a marker has been updated for an element * * @event element.marker.update * @type {Object} * @property {djs.model.Element} element the shape * @property {Object} gfx the graphical representation of the shape * @property {string} marker * @property {boolean} add true if the marker was added, false if it got removed */ this._eventBus.fire('element.marker.update', { element: element, gfx: container.gfx, marker: marker, add: !!add }); }; /** * Adds a marker to an element (basically a css class). * * Fires the element.marker.update event, making it possible to * integrate extension into the marker life-cycle, too. * * @example * canvas.addMarker('foo', 'some-marker'); * * var fooGfx = canvas.getGraphics('foo'); * * fooGfx; // <g class="... some-marker"> ... </g> * * @param {string|djs.model.Base} element * @param {string} marker */ Canvas.prototype.addMarker = function (element, marker) { this._updateMarker(element, marker, true); }; /** * Remove a marker from an element. * * Fires the element.marker.update event, making it possible to * integrate extension into the marker life-cycle, too. * * @param {string|djs.model.Base} element * @param {string} marker */ Canvas.prototype.removeMarker = function (element, marker) { this._updateMarker(element, marker, false); }; /** * Check the existence of a marker on element. * * @param {string|djs.model.Base} element * @param {string} marker */ Canvas.prototype.hasMarker = function (element, marker) { if (!element.id) { element = this._elementRegistry.get(element); } var gfx = this.getGraphics(element); return (0, _tinySvg.classes)(gfx).has(marker); }; /** * Toggles a marker on an element. * * Fires the element.marker.update event, making it possible to * integrate extension into the marker life-cycle, too. * * @param {string|djs.model.Base} element * @param {string} marker */ Canvas.prototype.toggleMarker = function (element, marker) { if (this.hasMarker(element, marker)) { this.removeMarker(element, marker); } else { this.addMarker(element, marker); } }; Canvas.prototype.getRootElement = function () { if (!this._rootElement) { this.setRootElement({ id: '__implicitroot', children: [] }); } return this._rootElement; }; // root element handling ////////////////////// /** * Sets a given element as the new root element for the canvas * and returns the new root element. * * @param {Object|djs.model.Root} element * @param {boolean} [override] whether to override the current root element, if any * * @return {Object|djs.model.Root} new root element */ Canvas.prototype.setRootElement = function (element, override) { if (element) { this._ensureValid('root', element); } var currentRoot = this._rootElement, elementRegistry = this._elementRegistry, eventBus = this._eventBus; if (currentRoot) { if (!override) { throw new Error('rootElement already set, need to specify override'); } // simulate element remove event sequence eventBus.fire('root.remove', { element: currentRoot }); eventBus.fire('root.removed', { element: currentRoot }); elementRegistry.remove(currentRoot); } if (element) { var gfx = this.getDefaultLayer(); // resemble element add event sequence eventBus.fire('root.add', { element: element }); elementRegistry.add(element, gfx, this._svg); eventBus.fire('root.added', { element: element, gfx: gfx }); } this._rootElement = element; return element; }; // add functionality ////////////////////// Canvas.prototype._ensureValid = function (type, element) { if (!element.id) { throw new Error('element must have an id'); } if (this._elementRegistry.get(element.id)) { throw new Error('element with id ' + element.id + ' already exists'); } var requiredAttrs = REQUIRED_MODEL_ATTRS[type]; var valid = (0, _minDash.every)(requiredAttrs, function (attr) { return typeof element[attr] !== 'undefined'; }); if (!valid) { throw new Error('must supply { ' + requiredAttrs.join(', ') + ' } with ' + type); } }; Canvas.prototype._setParent = function (element, parent, parentIndex) { (0, _Collections.add)(parent.children, element, parentIndex); element.parent = parent; }; /** * Adds an element to the canvas. * * This wires the parent <-> child relationship between the element and * a explicitly specified parent or an implicit root element. * * During add it emits the events * * * <{type}.add> (element, parent) * * <{type}.added> (element, gfx) * * Extensions may hook into these events to perform their magic. * * @param {string} type * @param {Object|djs.model.Base} element * @param {Object|djs.model.Base} [parent] * @param {number} [parentIndex] * * @return {Object|djs.model.Base} the added element */ Canvas.prototype._addElement = function (type, element, parent, parentIndex) { parent = parent || this.getRootElement(); var eventBus = this._eventBus, graphicsFactory = this._graphicsFactory; this._ensureValid(type, element); eventBus.fire(type + '.add', { element: element, parent: parent }); this._setParent(element, parent, parentIndex); // create graphics var gfx = graphicsFactory.create(type, element, parentIndex); this._elementRegistry.add(element, gfx); // update its visual graphicsFactory.update(type, element, gfx); eventBus.fire(type + '.added', { element: element, gfx: gfx }); return element; }; /** * Adds a shape to the canvas * * @param {Object|djs.model.Shape} shape to add to the diagram * @param {djs.model.Base} [parent] * @param {number} [parentIndex] * * @return {djs.model.Shape} the added shape */ Canvas.prototype.addShape = function (shape, parent, parentIndex) { return this._addElement('shape', shape, parent, parentIndex); }; /** * Adds a connection to the canvas * * @param {Object|djs.model.Connection} connection to add to the diagram * @param {djs.model.Base} [parent] * @param {number} [parentIndex] * * @return {djs.model.Connection} the added connection */ Canvas.prototype.addConnection = function (connection, parent, parentIndex) { return this._addElement('connection', connection, parent, parentIndex); }; /** * Internal remove element */ Canvas.prototype._removeElement = function (element, type) { var elementRegistry = this._elementRegistry, graphicsFactory = this._graphicsFactory, eventBus = this._eventBus; element = elementRegistry.get(element.id || element); if (!element) { // element was removed already return; } eventBus.fire(type + '.remove', { element: element }); graphicsFactory.remove(element); // unset parent <-> child relationship (0, _Collections.remove)(element.parent && element.parent.children, element); element.parent = null; eventBus.fire(type + '.removed', { element: element }); elementRegistry.remove(element); return element; }; /** * Removes a shape from the canvas * * @param {string|djs.model.Shape} shape or shape id to be removed * * @return {djs.model.Shape} the removed shape */ Canvas.prototype.removeShape = function (shape) { /** * An event indicating that a shape is about to be removed from the canvas. * * @memberOf Canvas * * @event shape.remove * @type {Object} * @property {djs.model.Shape} element the shape descriptor * @property {Object} gfx the graphical representation of the shape */ /** * An event indicating that a shape has been removed from the canvas. * * @memberOf Canvas * * @event shape.removed * @type {Object} * @property {djs.model.Shape} element the shape descriptor * @property {Object} gfx the graphical representation of the shape */ return this._removeElement(shape, 'shape'); }; /** * Removes a connection from the canvas * * @param {string|djs.model.Connection} connection or connection id to be removed * * @return {djs.model.Connection} the removed connection */ Canvas.prototype.removeConnection = function (connection) { /** * An event indicating that a connection is about to be removed from the canvas. * * @memberOf Canvas * * @event connection.remove * @type {Object} * @property {djs.model.Connection} element the connection descriptor * @property {Object} gfx the graphical representation of the connection */ /** * An event indicating that a connection has been removed from the canvas. * * @memberOf Canvas * * @event connection.removed * @type {Object} * @property {djs.model.Connection} element the connection descriptor * @property {Object} gfx the graphical representation of the connection */ return this._removeElement(connection, 'connection'); }; /** * Return the graphical object underlaying a certain diagram element * * @param {string|djs.model.Base} element descriptor of the element * @param {boolean} [secondary=false] whether to return the secondary connected element * * @return {SVGElement} */ Canvas.prototype.getGraphics = function (element, secondary) { return this._elementRegistry.getGraphics(element, secondary); }; /** * Perform a viewbox update via a given change function. * * @param {Function} changeFn */ Canvas.prototype._changeViewbox = function (changeFn) { // notify others of the upcoming viewbox change this._eventBus.fire('canvas.viewbox.changing'); // perform actual change changeFn.apply(this); // reset the cached viewbox so that // a new get operation on viewbox or zoom // triggers a viewbox re-computation this._cachedViewbox = null; // notify others of the change; this step // may or may not be debounced this._viewboxChanged(); }; Canvas.prototype._viewboxChanged = function () { this._eventBus.fire('canvas.viewbox.changed', { viewbox: this.viewbox() }); }; /** * Gets or sets the view box of the canvas, i.e. the * area that is currently displayed. * * The getter may return a cached viewbox (if it is currently * changing). To force a recomputation, pass `false` as the first argument. * * @example * * canvas.viewbox({ x: 100, y: 100, width: 500, height: 500 }) * * // sets the visible area of the diagram to (100|100) -> (600|100) * // and and scales it according to the diagram width * * var viewbox = canvas.viewbox(); // pass `false` to force recomputing the box. * * console.log(viewbox); * // { * // inner: Dimensions, * // outer: Dimensions, * // scale, * // x, y, * // width, height * // } * * // if the current diagram is zoomed and scrolled, you may reset it to the * // default zoom via this method, too: * * var zoomedAndScrolledViewbox = canvas.viewbox(); * * canvas.viewbox({ * x: 0, * y: 0, * width: zoomedAndScrolledViewbox.outer.width, * height: zoomedAndScrolledViewbox.outer.height * }); * * @param {Object} [box] the new view box to set * @param {number} box.x the top left X coordinate of the canvas visible in view box * @param {number} box.y the top left Y coordinate of the canvas visible in view box * @param {number} box.width the visible width * @param {number} box.height * * @return {Object} the current view box */ Canvas.prototype.viewbox = function (box) { if (box === undefined && this._cachedViewbox) { return this._cachedViewbox; } var viewport = this._viewport, innerBox, outerBox = this.getSize(), matrix, transform, scale, x, y; if (!box) { // compute the inner box based on the // diagrams default layer. This allows us to exclude // external components, such as overlays innerBox = this.getDefaultLayer().getBBox(); transform = (0, _tinySvg.transform)(viewport); matrix = transform ? transform.matrix : (0, _tinySvg.createMatrix)(); scale = round(matrix.a, 1000); x = round(-matrix.e || 0, 1000); y = round(-matrix.f || 0, 1000); box = this._cachedViewbox = { x: x ? x / scale : 0, y: y ? y / scale : 0, width: outerBox.width / scale, height: outerBox.height / scale, scale: scale, inner: { width: innerBox.width, height: innerBox.height, x: innerBox.x, y: innerBox.y }, outer: outerBox }; return box; } else { this._changeViewbox(function () { scale = Math.min(outerBox.width / box.width, outerBox.height / box.height); var matrix = this._svg.createSVGMatrix().scale(scale).translate(-box.x, -box.y); (0, _tinySvg.transform)(viewport, matrix); }); } return box; }; /** * Gets or sets the scroll of the canvas. * * @param {Object} [delta] the new scroll to apply. * * @param {number} [delta.dx] * @param {number} [delta.dy] */ Canvas.prototype.scroll = function (delta) { var node = this._viewport; var matrix = node.getCTM(); if (delta) { this._changeViewbox(function () { delta = (0, _minDash.assign)({ dx: 0, dy: 0 }, delta || {}); matrix = this._svg.createSVGMatrix().translate(delta.dx, delta.dy).multiply(matrix); setCTM(node, matrix); }); } return { x: matrix.e, y: matrix.f }; }; /** * Gets or sets the current zoom of the canvas, optionally zooming * to the specified position. * * The getter may return a cached zoom level. Call it with `false` as * the first argument to force recomputation of the current level. * * @param {string|number} [newScale] the new zoom level, either a number, i.e. 0.9, * or `fit-viewport` to adjust the size to fit the current viewport * @param {string|Point} [center] the reference point { x: .., y: ..} to zoom to, 'auto' to zoom into mid or null * * @return {number} the current scale */ Canvas.prototype.zoom = function (newScale, center) { if (!newScale) { return this.viewbox(newScale).scale; } if (newScale === 'fit-viewport') { return this._fitViewport(center); } var outer, matrix; this._changeViewbox(function () { if (typeof center !== 'object') { outer = this.viewbox().outer; center = { x: outer.width / 2, y: outer.height / 2 }; } matrix = this._setZoom(newScale, center); }); return round(matrix.a, 1000); }; function setCTM(node, m) { var mstr = 'matrix(' + m.a + ',' + m.b + ',' + m.c + ',' + m.d + ',' + m.e + ',' + m.f + ')'; node.setAttribute('transform', mstr); } Canvas.prototype._fitViewport = function (center) { var vbox = this.viewbox(), outer = vbox.outer, inner = vbox.inner, newScale, newViewbox; // display the complete diagram without zooming in. // instead of relying on internal zoom, we perform a // hard reset on the canvas viewbox to realize this // // if diagram does not need to be zoomed in, we focus it around // the diagram origin instead if (inner.x >= 0 && inner.y >= 0 && inner.x + inner.width <= outer.width && inner.y + inner.height <= outer.height && !center) { newViewbox = { x: 0, y: 0, width: Math.max(inner.width + inner.x, outer.width), height: Math.max(inner.height + inner.y, outer.height) }; } else { newScale = Math.min(1, outer.width / inner.width, outer.height / inner.height); newViewbox = { x: inner.x + (center ? inner.width / 2 - outer.width / newScale / 2 : 0), y: inner.y + (center ? inner.height / 2 - outer.height / newScale / 2 : 0), width: outer.width / newScale, height: outer.height / newScale }; } this.viewbox(newViewbox); return this.viewbox(false).scale; }; Canvas.prototype._setZoom = function (scale, center) { var svg = this._svg, viewport = this._viewport; var matrix = svg.createSVGMatrix(); var point = svg.createSVGPoint(); var centerPoint, originalPoint, currentMatrix, scaleMatrix, newMatrix; currentMatrix = viewport.getCTM(); var currentScale = currentMatrix.a; if (center) { centerPoint = (0, _minDash.assign)(point, center); // revert applied viewport transformations originalPoint = centerPoint.matrixTransform(currentMatrix.inverse()); // create scale matrix scaleMatrix = matrix.translate(originalPoint.x, originalPoint.y).scale(1 / currentScale * scale).translate(-originalPoint.x, -originalPoint.y); newMatrix = currentMatrix.multiply(scaleMatrix); } else { newMatrix = matrix.scale(scale); } setCTM(this._viewport, newMatrix); return newMatrix; }; /** * Returns the size of the canvas * * @return {Dimensions} */ Canvas.prototype.getSize = function () { return { width: this._container.clientWidth, height: this._container.clientHeight }; }; /** * Return the absolute bounding box for the given element * * The absolute bounding box may be used to display overlays in the * callers (browser) coordinate system rather than the zoomed in/out * canvas coordinates. * * @param {ElementDescriptor} element * @return {Bounds} the absolute bounding box */ Canvas.prototype.getAbsoluteBBox = function (element) { var vbox = this.viewbox(); var bbox; // connection // use svg bbox if (element.waypoints) { var gfx = this.getGraphics(element); bbox = gfx.getBBox(); } // shapes // use data else { bbox = element; } var x = bbox.x * vbox.scale - vbox.x * vbox.scale; var y = bbox.y * vbox.scale - vbox.y * vbox.scale; var width = bbox.width * vbox.scale; var height = bbox.height * vbox.scale; return { x: x, y: y, width: width, height: height }; }; /** * Fires an event in order other modules can react to the * canvas resizing */ Canvas.prototype.resized = function () { // force recomputation of view box delete this._cachedViewbox; this._eventBus.fire('canvas.resized'); }; },{"../util/Collections":313,"../util/Elements":315,"min-dash":555,"tiny-svg":567}],149:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ElementFactory; var _model = require("../model"); var _minDash = require("min-dash"); /** * A factory for diagram-js shapes */ function ElementFactory() { this._uid = 12; } ElementFactory.prototype.createRoot = function (attrs) { return this.create('root', attrs); }; ElementFactory.prototype.createLabel = function (attrs) { return this.create('label', attrs); }; ElementFactory.prototype.createShape = function (attrs) { return this.create('shape', attrs); }; ElementFactory.prototype.createConnection = function (attrs) { return this.create('connection', attrs); }; /** * Create a model element with the given type and * a number of pre-set attributes. * * @param {string} type * @param {Object} attrs * @return {djs.model.Base} the newly created model instance */ ElementFactory.prototype.create = function (type, attrs) { attrs = (0, _minDash.assign)({}, attrs || {}); if (!attrs.id) { attrs.id = type + '_' + this._uid++; } return (0, _model.create)(type, attrs); }; },{"../model":302,"min-dash":555}],150:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ElementRegistry; var _tinySvg = require("tiny-svg"); var ELEMENT_ID = 'data-element-id'; /** * @class * * A registry that keeps track of all shapes in the diagram. */ function ElementRegistry(eventBus) { this._elements = {}; this._eventBus = eventBus; } ElementRegistry.$inject = ['eventBus']; /** * Register a pair of (element, gfx, (secondaryGfx)). * * @param {djs.model.Base} element * @param {SVGElement} gfx * @param {SVGElement} [secondaryGfx] optional other element to register, too */ ElementRegistry.prototype.add = function (element, gfx, secondaryGfx) { var id = element.id; this._validateId(id); // associate dom node with element (0, _tinySvg.attr)(gfx, ELEMENT_ID, id); if (secondaryGfx) { (0, _tinySvg.attr)(secondaryGfx, ELEMENT_ID, id); } this._elements[id] = { element: element, gfx: gfx, secondaryGfx: secondaryGfx }; }; /** * Removes an element from the registry. * * @param {djs.model.Base} element */ ElementRegistry.prototype.remove = function (element) { var elements = this._elements, id = element.id || element, container = id && elements[id]; if (container) { // unset element id on gfx (0, _tinySvg.attr)(container.gfx, ELEMENT_ID, ''); if (container.secondaryGfx) { (0, _tinySvg.attr)(container.secondaryGfx, ELEMENT_ID, ''); } delete elements[id]; } }; /** * Update the id of an element * * @param {djs.model.Base} element * @param {string} newId */ ElementRegistry.prototype.updateId = function (element, newId) { this._validateId(newId); if (typeof element === 'string') { element = this.get(element); } this._eventBus.fire('element.updateId', { element: element, newId: newId }); var gfx = this.getGraphics(element), secondaryGfx = this.getGraphics(element, true); this.remove(element); element.id = newId; this.add(element, gfx, secondaryGfx); }; /** * Return the model element for a given id or graphics. * * @example * * elementRegistry.get('SomeElementId_1'); * elementRegistry.get(gfx); * * * @param {string|SVGElement} filter for selecting the element * * @return {djs.model.Base} */ ElementRegistry.prototype.get = function (filter) { var id; if (typeof filter === 'string') { id = filter; } else { id = filter && (0, _tinySvg.attr)(filter, ELEMENT_ID); } var container = this._elements[id]; return container && container.element; }; /** * Return all elements that match a given filter function. * * @param {Function} fn * * @return {Array<djs.model.Base>} */ ElementRegistry.prototype.filter = function (fn) { var filtered = []; this.forEach(function (element, gfx) { if (fn(element, gfx)) { filtered.push(element); } }); return filtered; }; /** * Return the first element that satisfies the provided testing function. * * @param {Function} fn * * @return {djs.model.Base} */ ElementRegistry.prototype.find = function (fn) { var map = this._elements, keys = Object.keys(map); for (var i = 0; i < keys.length; i++) { var id = keys[i], container = map[id], element = container.element, gfx = container.gfx; if (fn(element, gfx)) { return element; } } }; /** * Return all rendered model elements. * * @return {Array<djs.model.Base>} */ ElementRegistry.prototype.getAll = function () { return this.filter(function (e) { return e; }); }; /** * Iterate over all diagram elements. * * @param {Function} fn */ ElementRegistry.prototype.forEach = function (fn) { var map = this._elements; Object.keys(map).forEach(function (id) { var container = map[id], element = container.element, gfx = container.gfx; return fn(element, gfx); }); }; /** * Return the graphical representation of an element or its id. * * @example * elementRegistry.getGraphics('SomeElementId_1'); * elementRegistry.getGraphics(rootElement); // <g ...> * * elementRegistry.getGraphics(rootElement, true); // <svg ...> * * * @param {string|djs.model.Base} filter * @param {boolean} [secondary=false] whether to return the secondary connected element * * @return {SVGElement} */ ElementRegistry.prototype.getGraphics = function (filter, secondary) { var id = filter.id || filter; var container = this._elements[id]; return container && (secondary ? container.secondaryGfx : container.gfx); }; /** * Validate the suitability of the given id and signals a problem * with an exception. * * @param {string} id * * @throws {Error} if id is empty or already assigned */ ElementRegistry.prototype._validateId = function (id) { if (!id) { throw new Error('element must have an id'); } if (this._elements[id]) { throw new Error('element with id ' + id + ' already added'); } }; },{"tiny-svg":567}],151:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = EventBus; var _minDash = require("min-dash"); var FN_REF = '__fn'; var DEFAULT_PRIORITY = 1000; var slice = Array.prototype.slice; /** * A general purpose event bus. * * This component is used to communicate across a diagram instance. * Other parts of a diagram can use it to listen to and broadcast events. * * * ## Registering for Events * * The event bus provides the {@link EventBus#on} and {@link EventBus#once} * methods to register for events. {@link EventBus#off} can be used to * remove event registrations. Listeners receive an instance of {@link Event} * as the first argument. It allows them to hook into the event execution. * * ```javascript * * // listen for event * eventBus.on('foo', function(event) { * * // access event type * event.type; // 'foo' * * // stop propagation to other listeners * event.stopPropagation(); * * // prevent event default * event.preventDefault(); * }); * * // listen for event with custom payload * eventBus.on('bar', function(event, payload) { * console.log(payload); * }); * * // listen for event returning value * eventBus.on('foobar', function(event) { * * // stop event propagation + prevent default * return false; * * // stop event propagation + return custom result * return { * complex: 'listening result' * }; * }); * * * // listen with custom priority (default=1000, higher is better) * eventBus.on('priorityfoo', 1500, function(event) { * console.log('invoked first!'); * }); * * * // listen for event and pass the context (`this`) * eventBus.on('foobar', function(event) { * this.foo(); * }, this); * ``` * * * ## Emitting Events * * Events can be emitted via the event bus using {@link EventBus#fire}. * * ```javascript * * // false indicates that the default action * // was prevented by listeners * if (eventBus.fire('foo') === false) { * console.log('default has been prevented!'); * }; * * * // custom args + return value listener * eventBus.on('sum', function(event, a, b) { * return a + b; * }); * * // you can pass custom arguments + retrieve result values. * var sum = eventBus.fire('sum', 1, 2); * console.log(sum); // 3 * ``` */ function EventBus() { this._listeners = {}; // cleanup on destroy on lowest priority to allow // message passing until the bitter end this.on('diagram.destroy', 1, this._destroy, this); } /** * Register an event listener for events with the given name. * * The callback will be invoked with `event, ...additionalArguments` * that have been passed to {@link EventBus#fire}. * * Returning false from a listener will prevent the events default action * (if any is specified). To stop an event from being processed further in * other listeners execute {@link Event#stopPropagation}. * * Returning anything but `undefined` from a listener will stop the listener propagation. * * @param {string|Array<string>} events * @param {number} [priority=1000] the priority in which this listener is called, larger is higher * @param {Function} callback * @param {Object} [that] Pass context (`this`) to the callback */ EventBus.prototype.on = function (events, priority, callback, that) { events = (0, _minDash.isArray)(events) ? events : [events]; if ((0, _minDash.isFunction)(priority)) { that = callback; callback = priority; priority = DEFAULT_PRIORITY; } if (!(0, _minDash.isNumber)(priority)) { throw new Error('priority must be a number'); } var actualCallback = callback; if (that) { actualCallback = (0, _minDash.bind)(callback, that); // make sure we remember and are able to remove // bound callbacks via {@link #off} using the original // callback actualCallback[FN_REF] = callback[FN_REF] || callback; } var self = this; events.forEach(function (e) { self._addListener(e, { priority: priority, callback: actualCallback, next: null }); }); }; /** * Register an event listener that is executed only once. * * @param {string} event the event name to register for * @param {number} [priority=1000] the priority in which this listener is called, larger is higher * @param {Function} callback the callback to execute * @param {Object} [that] Pass context (`this`) to the callback */ EventBus.prototype.once = function (event, priority, callback, that) { var self = this; if ((0, _minDash.isFunction)(priority)) { that = callback; callback = priority; priority = DEFAULT_PRIORITY; } if (!(0, _minDash.isNumber)(priority)) { throw new Error('priority must be a number'); } function wrappedCallback() { var result = callback.apply(that, arguments); self.off(event, wrappedCallback); return result; } // make sure we remember and are able to remove // bound callbacks via {@link #off} using the original // callback wrappedCallback[FN_REF] = callback; this.on(event, priority, wrappedCallback); }; /** * Removes event listeners by event and callback. * * If no callback is given, all listeners for a given event name are being removed. * * @param {string|Array<string>} events * @param {Function} [callback] */ EventBus.prototype.off = function (events, callback) { events = (0, _minDash.isArray)(events) ? events : [events]; var self = this; events.forEach(function (event) { self._removeListener(event, callback); }); }; /** * Create an EventBus event. * * @param {Object} data * * @return {Object} event, recognized by the eventBus */ EventBus.prototype.createEvent = function (data) { var event = new InternalEvent(); event.init(data); return event; }; /** * Fires a named event. * * @example * * // fire event by name * events.fire('foo'); * * // fire event object with nested type * var event = { type: 'foo' }; * events.fire(event); * * // fire event with explicit type * var event = { x: 10, y: 20 }; * events.fire('element.moved', event); * * // pass additional arguments to the event * events.on('foo', function(event, bar) { * alert(bar); * }); * * events.fire({ type: 'foo' }, 'I am bar!'); * * @param {string} [name] the optional event name * @param {Object} [event] the event object * @param {...Object} additional arguments to be passed to the callback functions * * @return {boolean} the events return value, if specified or false if the * default action was prevented by listeners */ EventBus.prototype.fire = function (type, data) { var event, firstListener, returnValue, args; args = slice.call(arguments); if (typeof type === 'object') { data = type; type = data.type; } if (!type) { throw new Error('no event type specified'); } firstListener = this._listeners[type]; if (!firstListener) { return; } // we make sure we fire instances of our home made // events here. We wrap them only once, though if (data instanceof InternalEvent) { // we are fine, we alread have an event event = data; } else { event = this.createEvent(data); } // ensure we pass the event as the first parameter args[0] = event; // original event type (in case we delegate) var originalType = event.type; // update event type before delegation if (type !== originalType) { event.type = type; } try { returnValue = this._invokeListeners(event, args, firstListener); } finally { // reset event type after delegation if (type !== originalType) { event.type = originalType; } } // set the return value to false if the event default // got prevented and no other return value exists if (returnValue === undefined && event.defaultPrevented) { returnValue = false; } return returnValue; }; EventBus.prototype.handleError = function (error) { return this.fire('error', { error: error }) === false; }; EventBus.prototype._destroy = function () { this._listeners = {}; }; EventBus.prototype._invokeListeners = function (event, args, listener) { var returnValue; while (listener) { // handle stopped propagation if (event.cancelBubble) { break; } returnValue = this._invokeListener(event, args, listener); listener = listener.next; } return returnValue; }; EventBus.prototype._invokeListener = function (event, args, listener) { var returnValue; try { // returning false prevents the default action returnValue = invokeFunction(listener.callback, args); // stop propagation on return value if (returnValue !== undefined) { event.returnValue = returnValue; event.stopPropagation(); } // prevent default on return false if (returnValue === false) { event.preventDefault(); } } catch (e) { if (!this.handleError(e)) { console.error('unhandled error in event listener'); console.error(e.stack); throw e; } } return returnValue; }; /* * Add new listener with a certain priority to the list * of listeners (for the given event). * * The semantics of listener registration / listener execution are * first register, first serve: New listeners will always be inserted * after existing listeners with the same priority. * * Example: Inserting two listeners with priority 1000 and 1300 * * * before: [ 1500, 1500, 1000, 1000 ] * * after: [ 1500, 1500, (new=1300), 1000, 1000, (new=1000) ] * * @param {string} event * @param {Object} listener { priority, callback } */ EventBus.prototype._addListener = function (event, newListener) { var listener = this._getListeners(event), previousListener; // no prior listeners if (!listener) { this._setListeners(event, newListener); return; } // ensure we order listeners by priority from // 0 (high) to n > 0 (low) while (listener) { if (listener.priority < newListener.priority) { newListener.next = listener; if (previousListener) { previousListener.next = newListener; } else { this._setListeners(event, newListener); } return; } previousListener = listener; listener = listener.next; } // add new listener to back previousListener.next = newListener; }; EventBus.prototype._getListeners = function (name) { return this._listeners[name]; }; EventBus.prototype._setListeners = function (name, listener) { this._listeners[name] = listener; }; EventBus.prototype._removeListener = function (event, callback) { var listener = this._getListeners(event), nextListener, previousListener, listenerCallback; if (!callback) { // clear listeners this._setListeners(event, null); return; } while (listener) { nextListener = listener.next; listenerCallback = listener.callback; if (listenerCallback === callback || listenerCallback[FN_REF] === callback) { if (previousListener) { previousListener.next = nextListener; } else { // new first listener this._setListeners(event, nextListener); } } previousListener = listener; listener = nextListener; } }; /** * A event that is emitted via the event bus. */ function InternalEvent() {} InternalEvent.prototype.stopPropagation = function () { this.cancelBubble = true; }; InternalEvent.prototype.preventDefault = function () { this.defaultPrevented = true; }; InternalEvent.prototype.init = function (data) { (0, _minDash.assign)(this, data || {}); }; /** * Invoke function. Be fast... * * @param {Function} fn * @param {Array<Object>} args * * @return {Any} */ function invokeFunction(fn, args) { return fn.apply(null, args); } },{"min-dash":555}],152:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = GraphicsFactory; var _minDash = require("min-dash"); var _GraphicsUtil = require("../util/GraphicsUtil"); var _SvgTransformUtil = require("../util/SvgTransformUtil"); var _minDom = require("min-dom"); var _tinySvg = require("tiny-svg"); var _Elements = require("../util/Elements"); /** * A factory that creates graphical elements * * @param {EventBus} eventBus * @param {ElementRegistry} elementRegistry */ function GraphicsFactory(eventBus, elementRegistry) { this._eventBus = eventBus; this._elementRegistry = elementRegistry; } GraphicsFactory.$inject = ['eventBus', 'elementRegistry']; GraphicsFactory.prototype._getChildrenContainer = function (element) { var gfx = this._elementRegistry.getGraphics(element); var childrenGfx; // root element if (!element.parent) { childrenGfx = gfx; } else { childrenGfx = (0, _GraphicsUtil.getChildren)(gfx); if (!childrenGfx) { childrenGfx = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(childrenGfx).add('djs-children'); (0, _tinySvg.append)(gfx.parentNode, childrenGfx); } } return childrenGfx; }; /** * Clears the graphical representation of the element and returns the * cleared visual (the <g class="djs-visual" /> element). */ GraphicsFactory.prototype._clear = function (gfx) { var visual = (0, _GraphicsUtil.getVisual)(gfx); (0, _minDom.clear)(visual); return visual; }; /** * Creates a gfx container for shapes and connections * * The layout is as follows: * * <g class="djs-group"> * * <!-- the gfx --> * <g class="djs-element djs-(shape|connection|frame)"> * <g class="djs-visual"> * <!-- the renderer draws in here --> * </g> * * <!-- extensions (overlays, click box, ...) goes here * </g> * * <!-- the gfx child nodes --> * <g class="djs-children"></g> * </g> * * @param {string} type the type of the element, i.e. shape | connection * @param {SVGElement} [childrenGfx] * @param {number} [parentIndex] position to create container in parent * @param {boolean} [isFrame] is frame element * * @return {SVGElement} */ GraphicsFactory.prototype._createContainer = function (type, childrenGfx, parentIndex, isFrame) { var outerGfx = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(outerGfx).add('djs-group'); // insert node at position if (typeof parentIndex !== 'undefined') { prependTo(outerGfx, childrenGfx, childrenGfx.childNodes[parentIndex]); } else { (0, _tinySvg.append)(childrenGfx, outerGfx); } var gfx = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(gfx).add('djs-element'); (0, _tinySvg.classes)(gfx).add('djs-' + type); if (isFrame) { (0, _tinySvg.classes)(gfx).add('djs-frame'); } (0, _tinySvg.append)(outerGfx, gfx); // create visual var visual = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(visual).add('djs-visual'); (0, _tinySvg.append)(gfx, visual); return gfx; }; GraphicsFactory.prototype.create = function (type, element, parentIndex) { var childrenGfx = this._getChildrenContainer(element.parent); return this._createContainer(type, childrenGfx, parentIndex, (0, _Elements.isFrameElement)(element)); }; GraphicsFactory.prototype.updateContainments = function (elements) { var self = this, elementRegistry = this._elementRegistry, parents; parents = (0, _minDash.reduce)(elements, function (map, e) { if (e.parent) { map[e.parent.id] = e.parent; } return map; }, {}); // update all parents of changed and reorganized their children // in the correct order (as indicated in our model) (0, _minDash.forEach)(parents, function (parent) { var children = parent.children; if (!children) { return; } var childrenGfx = self._getChildrenContainer(parent); (0, _minDash.forEach)(children.slice().reverse(), function (child) { var childGfx = elementRegistry.getGraphics(child); prependTo(childGfx.parentNode, childrenGfx); }); }); }; GraphicsFactory.prototype.drawShape = function (visual, element) { var eventBus = this._eventBus; return eventBus.fire('render.shape', { gfx: visual, element: element }); }; GraphicsFactory.prototype.getShapePath = function (element) { var eventBus = this._eventBus; return eventBus.fire('render.getShapePath', element); }; GraphicsFactory.prototype.drawConnection = function (visual, element) { var eventBus = this._eventBus; return eventBus.fire('render.connection', { gfx: visual, element: element }); }; GraphicsFactory.prototype.getConnectionPath = function (waypoints) { var eventBus = this._eventBus; return eventBus.fire('render.getConnectionPath', waypoints); }; GraphicsFactory.prototype.update = function (type, element, gfx) { // do NOT update root element if (!element.parent) { return; } var visual = this._clear(gfx); // redraw if (type === 'shape') { this.drawShape(visual, element); // update positioning (0, _SvgTransformUtil.translate)(gfx, element.x, element.y); } else if (type === 'connection') { this.drawConnection(visual, element); } else { throw new Error('unknown type: ' + type); } if (element.hidden) { (0, _tinySvg.attr)(gfx, 'display', 'none'); } else { (0, _tinySvg.attr)(gfx, 'display', 'block'); } }; GraphicsFactory.prototype.remove = function (element) { var gfx = this._elementRegistry.getGraphics(element); // remove (0, _tinySvg.remove)(gfx.parentNode); }; // helpers ////////// function prependTo(newNode, parentNode, siblingNode) { var node = siblingNode || parentNode.firstChild; // do not prepend node to itself to prevent IE from crashing // https://github.com/bpmn-io/bpmn-js/issues/746 if (newNode === node) { return; } parentNode.insertBefore(newNode, node); } },{"../util/Elements":315,"../util/GraphicsUtil":319,"../util/SvgTransformUtil":328,"min-dash":555,"min-dom":556,"tiny-svg":567}],153:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _draw = _interopRequireDefault(require("../draw")); var _Canvas = _interopRequireDefault(require("./Canvas")); var _ElementRegistry = _interopRequireDefault(require("./ElementRegistry")); var _ElementFactory = _interopRequireDefault(require("./ElementFactory")); var _EventBus = _interopRequireDefault(require("./EventBus")); var _GraphicsFactory = _interopRequireDefault(require("./GraphicsFactory")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_draw.default], __init__: ['canvas'], canvas: ['type', _Canvas.default], elementRegistry: ['type', _ElementRegistry.default], elementFactory: ['type', _ElementFactory.default], eventBus: ['type', _EventBus.default], graphicsFactory: ['type', _GraphicsFactory.default] }; exports.default = _default; },{"../draw":157,"./Canvas":148,"./ElementFactory":149,"./ElementRegistry":150,"./EventBus":151,"./GraphicsFactory":152}],154:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BaseRenderer; var DEFAULT_RENDER_PRIORITY = 1000; /** * The base implementation of shape and connection renderers. * * @param {EventBus} eventBus * @param {number} [renderPriority=1000] */ function BaseRenderer(eventBus, renderPriority) { var self = this; renderPriority = renderPriority || DEFAULT_RENDER_PRIORITY; eventBus.on(['render.shape', 'render.connection'], renderPriority, function (evt, context) { var type = evt.type, element = context.element, visuals = context.gfx; if (self.canRender(element)) { if (type === 'render.shape') { return self.drawShape(visuals, element); } else { return self.drawConnection(visuals, element); } } }); eventBus.on(['render.getShapePath', 'render.getConnectionPath'], renderPriority, function (evt, element) { if (self.canRender(element)) { if (evt.type === 'render.getShapePath') { return self.getShapePath(element); } else { return self.getConnectionPath(element); } } }); } /** * Should check whether *this* renderer can render * the element/connection. * * @param {element} element * * @returns {boolean} */ BaseRenderer.prototype.canRender = function () {}; /** * Provides the shape's snap svg element to be drawn on the `canvas`. * * @param {djs.Graphics} visuals * @param {Shape} shape * * @returns {Snap.svg} [returns a Snap.svg paper element ] */ BaseRenderer.prototype.drawShape = function () {}; /** * Provides the shape's snap svg element to be drawn on the `canvas`. * * @param {djs.Graphics} visuals * @param {Connection} connection * * @returns {Snap.svg} [returns a Snap.svg paper element ] */ BaseRenderer.prototype.drawConnection = function () {}; /** * Gets the SVG path of a shape that represents it's visual bounds. * * @param {Shape} shape * * @return {string} svg path */ BaseRenderer.prototype.getShapePath = function () {}; /** * Gets the SVG path of a connection that represents it's visual bounds. * * @param {Connection} connection * * @return {string} svg path */ BaseRenderer.prototype.getConnectionPath = function () {}; },{}],155:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DefaultRenderer; var _inherits = _interopRequireDefault(require("inherits")); var _BaseRenderer = _interopRequireDefault(require("./BaseRenderer")); var _RenderUtil = require("../util/RenderUtil"); var _tinySvg = require("tiny-svg"); var _Elements = require("../util/Elements"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // apply default renderer with lowest possible priority // so that it only kicks in if noone else could render var DEFAULT_RENDER_PRIORITY = 1; /** * The default renderer used for shapes and connections. * * @param {EventBus} eventBus * @param {Styles} styles */ function DefaultRenderer(eventBus, styles) { // _BaseRenderer.default.call(this, eventBus, DEFAULT_RENDER_PRIORITY); this.CONNECTION_STYLE = styles.style(['no-fill'], { strokeWidth: 5, stroke: 'fuchsia' }); this.SHAPE_STYLE = styles.style({ fill: 'white', stroke: 'fuchsia', strokeWidth: 2 }); this.FRAME_STYLE = styles.style(['no-fill'], { stroke: 'fuchsia', strokeDasharray: 4, strokeWidth: 2 }); } (0, _inherits.default)(DefaultRenderer, _BaseRenderer.default); DefaultRenderer.prototype.canRender = function () { return true; }; DefaultRenderer.prototype.drawShape = function drawShape(visuals, element) { var rect = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(rect, { x: 0, y: 0, width: element.width || 0, height: element.height || 0 }); if ((0, _Elements.isFrameElement)(element)) { (0, _tinySvg.attr)(rect, this.FRAME_STYLE); } else { (0, _tinySvg.attr)(rect, this.SHAPE_STYLE); } (0, _tinySvg.append)(visuals, rect); return rect; }; DefaultRenderer.prototype.drawConnection = function drawConnection(visuals, connection) { var line = (0, _RenderUtil.createLine)(connection.waypoints, this.CONNECTION_STYLE); (0, _tinySvg.append)(visuals, line); return line; }; DefaultRenderer.prototype.getShapePath = function getShapePath(shape) { var x = shape.x, y = shape.y, width = shape.width, height = shape.height; var shapePath = [['M', x, y], ['l', width, 0], ['l', 0, height], ['l', -width, 0], ['z']]; return (0, _RenderUtil.componentsToPath)(shapePath); }; DefaultRenderer.prototype.getConnectionPath = function getConnectionPath(connection) { var waypoints = connection.waypoints; var idx, point, connectionPath = []; for (idx = 0; point = waypoints[idx]; idx++) { // take invisible docking into account // when creating the path point = point.original || point; connectionPath.push([idx === 0 ? 'M' : 'L', point.x, point.y]); } return (0, _RenderUtil.componentsToPath)(connectionPath); }; DefaultRenderer.$inject = ['eventBus', 'styles']; },{"../util/Elements":315,"../util/RenderUtil":327,"./BaseRenderer":154,"inherits":347,"tiny-svg":567}],156:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Styles; var _minDash = require("min-dash"); /** * A component that manages shape styles */ function Styles() { var defaultTraits = { 'no-fill': { fill: 'none' }, 'no-border': { strokeOpacity: 0.0 }, 'no-events': { pointerEvents: 'none' } }; var self = this; /** * Builds a style definition from a className, a list of traits and an object of additional attributes. * * @param {string} className * @param {Array<string>} traits * @param {Object} additionalAttrs * * @return {Object} the style defintion */ this.cls = function (className, traits, additionalAttrs) { var attrs = this.style(traits, additionalAttrs); return (0, _minDash.assign)(attrs, { 'class': className }); }; /** * Builds a style definition from a list of traits and an object of additional attributes. * * @param {Array<string>} traits * @param {Object} additionalAttrs * * @return {Object} the style defintion */ this.style = function (traits, additionalAttrs) { if (!(0, _minDash.isArray)(traits) && !additionalAttrs) { additionalAttrs = traits; traits = []; } var attrs = (0, _minDash.reduce)(traits, function (attrs, t) { return (0, _minDash.assign)(attrs, defaultTraits[t] || {}); }, {}); return additionalAttrs ? (0, _minDash.assign)(attrs, additionalAttrs) : attrs; }; this.computeStyle = function (custom, traits, defaultStyles) { if (!(0, _minDash.isArray)(traits)) { defaultStyles = traits; traits = []; } return self.style(traits || [], (0, _minDash.assign)({}, defaultStyles, custom || {})); }; } },{"min-dash":555}],157:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _DefaultRenderer = _interopRequireDefault(require("./DefaultRenderer")); var _Styles = _interopRequireDefault(require("./Styles")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['defaultRenderer'], defaultRenderer: ['type', _DefaultRenderer.default], styles: ['type', _Styles.default] }; exports.default = _default; },{"./DefaultRenderer":155,"./Styles":156}],158:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AlignElements; var _minDash = require("min-dash"); function last(arr) { return arr && arr[arr.length - 1]; } function sortTopOrMiddle(element) { return element.y; } function sortLeftOrCenter(element) { return element.x; } /** * Sorting functions for different types of alignment * * @type {Object} * * @return {Function} */ var ALIGNMENT_SORTING = { left: sortLeftOrCenter, center: sortLeftOrCenter, right: function (element) { return element.x + element.width; }, top: sortTopOrMiddle, middle: sortTopOrMiddle, bottom: function (element) { return element.y + element.height; } }; function AlignElements(modeling) { this._modeling = modeling; } AlignElements.$inject = ['modeling']; /** * Get the relevant "axis" and "dimension" related to the current type of alignment * * @param {string} type left|right|center|top|bottom|middle * * @return {Object} { axis, dimension } */ AlignElements.prototype._getOrientationDetails = function (type) { var vertical = ['top', 'bottom', 'middle'], axis = 'x', dimension = 'width'; if (vertical.indexOf(type) !== -1) { axis = 'y'; dimension = 'height'; } return { axis: axis, dimension: dimension }; }; AlignElements.prototype._isType = function (type, types) { return types.indexOf(type) !== -1; }; /** * Get a point on the relevant axis where elements should align to * * @param {string} type left|right|center|top|bottom|middle * @param {Array} sortedElements * * @return {Object} */ AlignElements.prototype._alignmentPosition = function (type, sortedElements) { var orientation = this._getOrientationDetails(type), axis = orientation.axis, dimension = orientation.dimension, alignment = {}, centers = {}, hasSharedCenters = false, centeredElements, firstElement, lastElement; function getMiddleOrTop(first, last) { return Math.round((first[axis] + last[axis] + last[dimension]) / 2); } if (this._isType(type, ['left', 'top'])) { alignment[type] = sortedElements[0][axis]; } else if (this._isType(type, ['right', 'bottom'])) { lastElement = last(sortedElements); alignment[type] = lastElement[axis] + lastElement[dimension]; } else if (this._isType(type, ['center', 'middle'])) { // check if there is a center shared by more than one shape // if not, just take the middle of the range (0, _minDash.forEach)(sortedElements, function (element) { var center = element[axis] + Math.round(element[dimension] / 2); if (centers[center]) { centers[center].elements.push(element); } else { centers[center] = { elements: [element], center: center }; } }); centeredElements = (0, _minDash.sortBy)(centers, function (center) { if (center.elements.length > 1) { hasSharedCenters = true; } return center.elements.length; }); if (hasSharedCenters) { alignment[type] = last(centeredElements).center; return alignment; } firstElement = sortedElements[0]; sortedElements = (0, _minDash.sortBy)(sortedElements, function (element) { return element[axis] + element[dimension]; }); lastElement = last(sortedElements); alignment[type] = getMiddleOrTop(firstElement, lastElement); } return alignment; }; /** * Executes the alignment of a selection of elements * * @param {Array} elements [description] * @param {string} type left|right|center|top|bottom|middle */ AlignElements.prototype.trigger = function (elements, type) { var modeling = this._modeling; var filteredElements = (0, _minDash.filter)(elements, function (element) { return !(element.waypoints || element.host || element.labelTarget); }); var sortFn = ALIGNMENT_SORTING[type]; var sortedElements = (0, _minDash.sortBy)(filteredElements, sortFn); var alignment = this._alignmentPosition(type, sortedElements); modeling.alignElements(sortedElements, alignment); }; },{"min-dash":555}],159:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _AlignElements = _interopRequireDefault(require("./AlignElements")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['alignElements'], alignElements: ['type', _AlignElements.default] }; exports.default = _default; },{"./AlignElements":158}],160:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AttachSupport; var _minDash = require("min-dash"); var _Removal = require("../../util/Removal"); var _AttachUtil = require("../../util/AttachUtil"); var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 251, HIGH_PRIORITY = 1401; var MARKER_ATTACH = 'attach-ok'; /** * Adds the notion of attached elements to the modeler. * * Optionally depends on `diagram-js/lib/features/move` to render * the attached elements during move preview. * * Optionally depends on `diagram-js/lib/features/label-support` * to render attached labels during move preview. * * @param {didi.Injector} injector * @param {EventBus} eventBus * @param {Canvas} canvas * @param {Rules} rules * @param {Modeling} modeling */ function AttachSupport(injector, eventBus, canvas, rules, modeling) { _CommandInterceptor.default.call(this, eventBus); var movePreview = injector.get('movePreview', false); // remove all the attached elements from the shapes to be validated // add all the attached shapes to the overall list of moved shapes eventBus.on('shape.move.start', HIGH_PRIORITY, function (e) { var context = e.context, shapes = context.shapes, validatedShapes = context.validatedShapes; context.shapes = addAttached(shapes); context.validatedShapes = removeAttached(validatedShapes); }); // add attachers to the visual's group movePreview && eventBus.on('shape.move.start', LOW_PRIORITY, function (e) { var context = e.context, shapes = context.shapes, attachers = getAttachers(shapes); (0, _minDash.forEach)(attachers, function (attacher) { movePreview.makeDraggable(context, attacher, true); (0, _minDash.forEach)(attacher.labels, function (label) { movePreview.makeDraggable(context, label, true); }); }); }); // add attach-ok marker to current host movePreview && eventBus.on('shape.move.start', function (event) { var context = event.context, shapes = context.shapes; if (shapes.length !== 1) { return; } var shape = shapes[0]; var host = shape.host; if (host) { canvas.addMarker(host, MARKER_ATTACH); eventBus.once(['shape.move.out', 'shape.move.cleanup'], function () { canvas.removeMarker(host, MARKER_ATTACH); }); } }); // add all attachers to move closure this.preExecuted('elements.move', HIGH_PRIORITY, function (e) { var context = e.context, closure = context.closure, shapes = context.shapes, attachers = getAttachers(shapes); (0, _minDash.forEach)(attachers, function (attacher) { closure.add(attacher, closure.topLevel[attacher.host.id]); }); }); // perform the attaching after shapes are done moving this.postExecuted('elements.move', function (e) { var context = e.context, shapes = context.shapes, newHost = context.newHost, attachers; // only single elements can be attached // multiply elements can be detached if (newHost && shapes.length !== 1) { return; } if (newHost) { attachers = shapes; } else { // find attachers moved without host attachers = (0, _minDash.filter)(shapes, function (shape) { var host = shape.host; return isAttacher(shape) && !includes(shapes, host); }); } (0, _minDash.forEach)(attachers, function (attacher) { modeling.updateAttachment(attacher, newHost); }); }); // ensure invalid attachment connections are removed this.postExecuted('elements.move', function (e) { var shapes = e.context.shapes; (0, _minDash.forEach)(shapes, function (shape) { (0, _minDash.forEach)(shape.attachers, function (attacher) { // remove invalid outgoing connections (0, _minDash.forEach)(attacher.outgoing.slice(), function (connection) { var allowed = rules.allowed('connection.reconnect', { connection: connection, source: connection.source, target: connection.target }); if (!allowed) { modeling.removeConnection(connection); } }); // remove invalid incoming connections (0, _minDash.forEach)(attacher.incoming.slice(), function (connection) { var allowed = rules.allowed('connection.reconnect', { connection: connection, source: connection.source, target: connection.target }); if (!allowed) { modeling.removeConnection(connection); } }); }); }); }); this.postExecute('shape.create', function (e) { var context = e.context, shape = context.shape, host = context.host; if (host) { modeling.updateAttachment(shape, host); } }); // update attachments if the host is replaced this.postExecute('shape.replace', function (e) { var context = e.context, oldShape = context.oldShape, newShape = context.newShape; // move the attachers to the new host (0, _Removal.saveClear)(oldShape.attachers, function (attacher) { var allowed = rules.allowed('elements.move', { target: newShape, shapes: [attacher] }); if (allowed === 'attach') { modeling.updateAttachment(attacher, newShape); } else { modeling.removeShape(attacher); } }); // move attachers if new host has different size if (newShape.attachers.length) { (0, _minDash.forEach)(newShape.attachers, function (attacher) { var delta = (0, _AttachUtil.getNewAttachShapeDelta)(attacher, oldShape, newShape); modeling.moveShape(attacher, delta, attacher.parent); }); } }); // move shape on host resize this.postExecute('shape.resize', function (event) { var context = event.context, shape = context.shape, oldBounds = context.oldBounds, newBounds = context.newBounds, attachers = shape.attachers, hints = context.hints || {}; if (hints.attachSupport === false) { return; } (0, _minDash.forEach)(attachers, function (attacher) { var delta = (0, _AttachUtil.getNewAttachShapeDelta)(attacher, oldBounds, newBounds); modeling.moveShape(attacher, delta, attacher.parent); (0, _minDash.forEach)(attacher.labels, function (label) { modeling.moveShape(label, delta, label.parent); }); }); }); // remove attachments this.preExecute('shape.delete', function (event) { var shape = event.context.shape; (0, _Removal.saveClear)(shape.attachers, function (attacher) { modeling.removeShape(attacher); }); if (shape.host) { modeling.updateAttachment(shape, null); } }); } (0, _inherits.default)(AttachSupport, _CommandInterceptor.default); AttachSupport.$inject = ['injector', 'eventBus', 'canvas', 'rules', 'modeling']; /** * Return attachers of the given shapes * * @param {Array<djs.model.Base>} shapes * @return {Array<djs.model.Base>} */ function getAttachers(shapes) { return (0, _minDash.flatten)((0, _minDash.map)(shapes, function (s) { return s.attachers || []; })); } /** * Return a combined list of elements and * attachers. * * @param {Array<djs.model.Base>} elements * @return {Array<djs.model.Base>} filtered */ function addAttached(elements) { var attachers = getAttachers(elements); return (0, _minDash.unionBy)('id', elements, attachers); } /** * Return a filtered list of elements that do not * contain attached elements with hosts being part * of the selection. * * @param {Array<djs.model.Base>} elements * * @return {Array<djs.model.Base>} filtered */ function removeAttached(elements) { var ids = (0, _minDash.groupBy)(elements, 'id'); return (0, _minDash.filter)(elements, function (element) { while (element) { // host in selection if (element.host && ids[element.host.id]) { return false; } element = element.parent; } return true; }); } function isAttacher(shape) { return !!shape.host; } function includes(array, item) { return array.indexOf(item) !== -1; } },{"../../command/CommandInterceptor":145,"../../util/AttachUtil":311,"../../util/Removal":326,"inherits":347,"min-dash":555}],161:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _rules = _interopRequireDefault(require("../rules")); var _AttachSupport = _interopRequireDefault(require("./AttachSupport")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_rules.default], __init__: ['attachSupport'], attachSupport: ['type', _AttachSupport.default] }; exports.default = _default; },{"../rules":272,"./AttachSupport":160}],162:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoPlace; var _LayoutUtil = require("../../layout/LayoutUtil"); var _AutoPlaceUtil = require("./AutoPlaceUtil"); var LOW_PRIORITY = 100; /** * A service that places elements connected to existing ones * to an appropriate position in an _automated_ fashion. * * @param {EventBus} eventBus * @param {Modeling} modeling */ function AutoPlace(eventBus, modeling) { eventBus.on('autoPlace', LOW_PRIORITY, function (context) { var shape = context.shape, source = context.source; return getNewShapePosition(source, shape); }); /** * Append shape to source at appropriate position. * * @param {djs.model.Shape} source * @param {djs.model.Shape} shape * * @return {djs.model.Shape} appended shape */ this.append = function (source, shape, hints) { eventBus.fire('autoPlace.start', { source: source, shape: shape }); // allow others to provide the position var position = eventBus.fire('autoPlace', { source: source, shape: shape }); var newShape = modeling.appendShape(source, shape, position, source.parent, hints); eventBus.fire('autoPlace.end', { source: source, shape: newShape }); return newShape; }; } AutoPlace.$inject = ['eventBus', 'modeling']; // helpers ////////// /** * Find the new position for the target element to * connect to source. * * @param {djs.model.Shape} source * @param {djs.model.Shape} element * @param {Object} [hints] * @param {Object} [hints.defaultDistance] * * @returns {Point} */ function getNewShapePosition(source, element, hints) { if (!hints) { hints = {}; } var distance = hints.defaultDistance || _AutoPlaceUtil.DEFAULT_DISTANCE; var sourceMid = (0, _LayoutUtil.getMid)(source), sourceTrbl = (0, _LayoutUtil.asTRBL)(source); // simply put element right next to source return { x: sourceTrbl.right + distance + element.width / 2, y: sourceMid.y }; } },{"../../layout/LayoutUtil":300,"./AutoPlaceUtil":164}],163:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoPlaceSelectionBehavior; /** * Select element after auto placement. * * @param {EventBus} eventBus * @param {Selection} selection */ function AutoPlaceSelectionBehavior(eventBus, selection) { eventBus.on('autoPlace.end', 500, function (e) { selection.select(e.shape); }); } AutoPlaceSelectionBehavior.$inject = ['eventBus', 'selection']; },{}],164:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findFreePosition = findFreePosition; exports.generateGetNextPosition = generateGetNextPosition; exports.getConnectedAtPosition = getConnectedAtPosition; exports.getConnectedDistance = getConnectedDistance; exports.DEFAULT_DISTANCE = void 0; var _LayoutUtil = require("../../layout/LayoutUtil"); var _minDash = require("min-dash"); // padding to detect element placement var PLACEMENT_DETECTION_PAD = 10; var DEFAULT_DISTANCE = 50; exports.DEFAULT_DISTANCE = DEFAULT_DISTANCE; var DEFAULT_MAX_DISTANCE = 250; /** * Get free position starting from given position. * * @param {djs.model.Shape} source * @param {djs.model.Shape} element * @param {Point} position * @param {Function} getNextPosition * * @return {Point} */ function findFreePosition(source, element, position, getNextPosition) { var connectedAtPosition; while (connectedAtPosition = getConnectedAtPosition(source, position, element)) { position = getNextPosition(element, position, connectedAtPosition); } return position; } /** * Returns function that returns next position. * * @param {Object} nextPositionDirection * @param {Object} [nextPositionDirection.x] * @param {Object} [nextPositionDirection.y] * * @returns {Function} */ function generateGetNextPosition(nextPositionDirection) { return function (element, previousPosition, connectedAtPosition) { var nextPosition = { x: previousPosition.x, y: previousPosition.y }; ['x', 'y'].forEach(function (axis) { var nextPositionDirectionForAxis = nextPositionDirection[axis]; if (!nextPositionDirectionForAxis) { return; } var dimension = axis === 'x' ? 'width' : 'height'; var margin = nextPositionDirectionForAxis.margin, minDistance = nextPositionDirectionForAxis.minDistance; if (margin < 0) { nextPosition[axis] = Math.min(connectedAtPosition[axis] + margin - element[dimension] / 2, previousPosition[axis] - minDistance + margin); } else { nextPosition[axis] = Math.max(connectedAtPosition[axis] + connectedAtPosition[dimension] + margin + element[dimension] / 2, previousPosition[axis] + minDistance + margin); } }); return nextPosition; }; } /** * Return target at given position, if defined. * * This takes connected elements from host and attachers * into account, too. */ function getConnectedAtPosition(source, position, element) { var bounds = { x: position.x - element.width / 2, y: position.y - element.height / 2, width: element.width, height: element.height }; var closure = getAutoPlaceClosure(source, element); return (0, _minDash.find)(closure, function (target) { if (target === element) { return false; } var orientation = (0, _LayoutUtil.getOrientation)(target, bounds, PLACEMENT_DETECTION_PAD); return orientation === 'intersect'; }); } /** * Compute optimal distance between source and target based on existing connections to and from source. * Assumes left-to-right and top-to-down modeling. * * @param {djs.model.Shape} source * @param {Object} [hints] * @param {number} [hints.defaultDistance] * @param {string} [hints.direction] * @param {Function} [hints.filter] * @param {Function} [hints.getWeight] * @param {number} [hints.maxDistance] * @param {string} [hints.reference] * * @return {number} */ function getConnectedDistance(source, hints) { if (!hints) { hints = {}; } // targets > sources by default function getDefaultWeight(connection) { return connection.source === source ? 1 : -1; } var defaultDistance = hints.defaultDistance || DEFAULT_DISTANCE, direction = hints.direction || 'e', filter = hints.filter, getWeight = hints.getWeight || getDefaultWeight, maxDistance = hints.maxDistance || DEFAULT_MAX_DISTANCE, reference = hints.reference || 'start'; if (!filter) { filter = noneFilter; } function getDistance(a, b) { if (direction === 'n') { if (reference === 'start') { return (0, _LayoutUtil.asTRBL)(a).top - (0, _LayoutUtil.asTRBL)(b).bottom; } else if (reference === 'center') { return (0, _LayoutUtil.asTRBL)(a).top - (0, _LayoutUtil.getMid)(b).y; } else { return (0, _LayoutUtil.asTRBL)(a).top - (0, _LayoutUtil.asTRBL)(b).top; } } else if (direction === 'w') { if (reference === 'start') { return (0, _LayoutUtil.asTRBL)(a).left - (0, _LayoutUtil.asTRBL)(b).right; } else if (reference === 'center') { return (0, _LayoutUtil.asTRBL)(a).left - (0, _LayoutUtil.getMid)(b).x; } else { return (0, _LayoutUtil.asTRBL)(a).left - (0, _LayoutUtil.asTRBL)(b).left; } } else if (direction === 's') { if (reference === 'start') { return (0, _LayoutUtil.asTRBL)(b).top - (0, _LayoutUtil.asTRBL)(a).bottom; } else if (reference === 'center') { return (0, _LayoutUtil.getMid)(b).y - (0, _LayoutUtil.asTRBL)(a).bottom; } else { return (0, _LayoutUtil.asTRBL)(b).bottom - (0, _LayoutUtil.asTRBL)(a).bottom; } } else { if (reference === 'start') { return (0, _LayoutUtil.asTRBL)(b).left - (0, _LayoutUtil.asTRBL)(a).right; } else if (reference === 'center') { return (0, _LayoutUtil.getMid)(b).x - (0, _LayoutUtil.asTRBL)(a).right; } else { return (0, _LayoutUtil.asTRBL)(b).right - (0, _LayoutUtil.asTRBL)(a).right; } } } var sourcesDistances = source.incoming.filter(filter).map(function (connection) { var weight = getWeight(connection); var distance = weight < 0 ? getDistance(connection.source, source) : getDistance(source, connection.source); return { id: connection.source.id, distance: distance, weight: weight }; }); var targetsDistances = source.outgoing.filter(filter).map(function (connection) { var weight = getWeight(connection); var distance = weight > 0 ? getDistance(source, connection.target) : getDistance(connection.target, source); return { id: connection.target.id, distance: distance, weight: weight }; }); var distances = sourcesDistances.concat(targetsDistances).reduce(function (accumulator, currentValue) { accumulator[currentValue.id + '__weight_' + currentValue.weight] = currentValue; return accumulator; }, {}); var distancesGrouped = (0, _minDash.reduce)(distances, function (accumulator, currentValue) { var distance = currentValue.distance, weight = currentValue.weight; if (distance < 0 || distance > maxDistance) { return accumulator; } if (!accumulator[String(distance)]) { accumulator[String(distance)] = 0; } accumulator[String(distance)] += 1 * weight; if (!accumulator.distance || accumulator[accumulator.distance] < accumulator[String(distance)]) { accumulator.distance = distance; } return accumulator; }, {}); return distancesGrouped.distance || defaultDistance; } /** * Returns all connected elements around the given source. * * This includes: * * - connected elements * - host connected elements * - attachers connected elements * * @param {djs.model.Shape} source * * @return {Array<djs.model.Shape>} */ function getAutoPlaceClosure(source) { var allConnected = getConnected(source); if (source.host) { allConnected = allConnected.concat(getConnected(source.host)); } if (source.attachers) { allConnected = allConnected.concat(source.attachers.reduce(function (shapes, attacher) { return shapes.concat(getConnected(attacher)); }, [])); } return allConnected; } function getConnected(element) { return getTargets(element).concat(getSources(element)); } function getSources(shape) { return shape.incoming.map(function (connection) { return connection.source; }); } function getTargets(shape) { return shape.outgoing.map(function (connection) { return connection.target; }); } function noneFilter() { return true; } },{"../../layout/LayoutUtil":300,"min-dash":555}],165:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _AutoPlace = _interopRequireDefault(require("./AutoPlace")); var _AutoPlaceSelectionBehavior = _interopRequireDefault(require("./AutoPlaceSelectionBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['autoPlaceSelectionBehavior'], autoPlace: ['type', _AutoPlace.default], autoPlaceSelectionBehavior: ['type', _AutoPlaceSelectionBehavior.default] }; exports.default = _default; },{"./AutoPlace":162,"./AutoPlaceSelectionBehavior":163}],166:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoResize; var _inherits = _interopRequireDefault(require("inherits")); var _Elements = require("../../util/Elements"); var _LayoutUtil = require("../../layout/LayoutUtil"); var _minDash = require("min-dash"); var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * An auto resize component that takes care of expanding a parent element * if child elements are created or moved close the parents edge. * * @param {EventBus} eventBus * @param {ElementRegistry} elementRegistry * @param {Modeling} modeling * @param {Rules} rules */ function AutoResize(eventBus, elementRegistry, modeling, rules) { _CommandInterceptor.default.call(this, eventBus); this._elementRegistry = elementRegistry; this._modeling = modeling; this._rules = rules; var self = this; this.postExecuted(['shape.create'], function (event) { var context = event.context, hints = context.hints || {}, shape = context.shape, parent = context.parent || context.newParent; if (hints.autoResize === false) { return; } self._expand([shape], parent); }); this.postExecuted(['elements.move'], function (event) { var context = event.context, elements = (0, _minDash.flatten)((0, _minDash.values)(context.closure.topLevel)), hints = context.hints; var autoResize = hints ? hints.autoResize : true; if (autoResize === false) { return; } var expandings = (0, _minDash.groupBy)(elements, function (element) { return element.parent.id; }); (0, _minDash.forEach)(expandings, function (elements, parentId) { // optionally filter elements to be considered when resizing if ((0, _minDash.isArray)(autoResize)) { elements = elements.filter(function (element) { return (0, _minDash.find)(autoResize, (0, _minDash.matchPattern)({ id: element.id })); }); } self._expand(elements, parentId); }); }); this.postExecuted(['shape.toggleCollapse'], function (event) { var context = event.context, hints = context.hints, shape = context.shape; if (hints && hints.autoResize === false) { return; } if (shape.collapsed) { return; } self._expand(shape.children || [], shape); }); this.postExecuted(['shape.resize'], function (event) { var context = event.context, hints = context.hints, shape = context.shape, parent = shape.parent; if (hints && hints.autoResize === false) { return; } if (parent) { self._expand([shape], parent); } }); } AutoResize.$inject = ['eventBus', 'elementRegistry', 'modeling', 'rules']; (0, _inherits.default)(AutoResize, _CommandInterceptor.default); /** * Calculate the new bounds of the target shape, given * a number of elements have been moved or added into the parent. * * This method considers the current size, the added elements as well as * the provided padding for the new bounds. * * @param {Array<djs.model.Shape>} elements * @param {djs.model.Shape} target */ AutoResize.prototype._getOptimalBounds = function (elements, target) { var offset = this.getOffset(target), padding = this.getPadding(target); var elementsTrbl = (0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(elements)), targetTrbl = (0, _LayoutUtil.asTRBL)(target); var newTrbl = {}; if (elementsTrbl.top - targetTrbl.top < padding.top) { newTrbl.top = elementsTrbl.top - offset.top; } if (elementsTrbl.left - targetTrbl.left < padding.left) { newTrbl.left = elementsTrbl.left - offset.left; } if (targetTrbl.right - elementsTrbl.right < padding.right) { newTrbl.right = elementsTrbl.right + offset.right; } if (targetTrbl.bottom - elementsTrbl.bottom < padding.bottom) { newTrbl.bottom = elementsTrbl.bottom + offset.bottom; } return (0, _LayoutUtil.asBounds)((0, _minDash.assign)({}, targetTrbl, newTrbl)); }; /** * Expand the target shape respecting rules, offset and padding * * @param {Array<djs.model.Shape>} elements * @param {djs.model.Shape|string} target|targetId */ AutoResize.prototype._expand = function (elements, target) { if (typeof target === 'string') { target = this._elementRegistry.get(target); } var allowed = this._rules.allowed('element.autoResize', { elements: elements, target: target }); if (!allowed) { return; } // calculate the new bounds var newBounds = this._getOptimalBounds(elements, target); if (!boundsChanged(newBounds, target)) { return; } var resizeDirections = getResizeDirections((0, _minDash.pick)(target, ['x', 'y', 'width', 'height']), newBounds); // resize the parent shape this.resize(target, newBounds, { autoResize: resizeDirections }); var parent = target.parent; // recursively expand parent elements if (parent) { this._expand([target], parent); } }; /** * Get the amount to expand the given shape in each direction. * * @param {djs.model.Shape} shape * * @return {TRBL} */ AutoResize.prototype.getOffset = function (shape) { return { top: 60, bottom: 60, left: 100, right: 100 }; }; /** * Get the activation threshold for each side for which * resize triggers. * * @param {djs.model.Shape} shape * * @return {TRBL} */ AutoResize.prototype.getPadding = function (shape) { return { top: 2, bottom: 2, left: 15, right: 15 }; }; /** * Perform the actual resize operation. * * @param {djs.model.Shape} shape * @param {Bounds} newBounds * @param {Object} [hints] * @param {string} [hints.autoResize] */ AutoResize.prototype.resize = function (shape, newBounds, hints) { this._modeling.resizeShape(shape, newBounds, null, hints); }; function boundsChanged(newBounds, oldBounds) { return newBounds.x !== oldBounds.x || newBounds.y !== oldBounds.y || newBounds.width !== oldBounds.width || newBounds.height !== oldBounds.height; } /** * Get directions of resize as {n|w|s|e} e.g. "nw". * * @param {Bounds} oldBounds * @param {Bounds} newBounds * * @returns {string} Resize directions as {n|w|s|e}. */ function getResizeDirections(oldBounds, newBounds) { var directions = ''; oldBounds = (0, _LayoutUtil.asTRBL)(oldBounds); newBounds = (0, _LayoutUtil.asTRBL)(newBounds); if (oldBounds.top > newBounds.top) { directions = directions.concat('n'); } if (oldBounds.right < newBounds.right) { directions = directions.concat('w'); } if (oldBounds.bottom < newBounds.bottom) { directions = directions.concat('s'); } if (oldBounds.left > newBounds.left) { directions = directions.concat('e'); } return directions; } },{"../../command/CommandInterceptor":145,"../../layout/LayoutUtil":300,"../../util/Elements":315,"inherits":347,"min-dash":555}],167:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoResizeProvider; var _RuleProvider = _interopRequireDefault(require("../rules/RuleProvider")); var _inherits = _interopRequireDefault(require("inherits")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * This is a base rule provider for the element.autoResize rule. */ function AutoResizeProvider(eventBus) { _RuleProvider.default.call(this, eventBus); var self = this; this.addRule('element.autoResize', function (context) { return self.canResize(context.elements, context.target); }); } AutoResizeProvider.$inject = ['eventBus']; (0, _inherits.default)(AutoResizeProvider, _RuleProvider.default); /** * Needs to be implemented by sub classes to allow actual auto resize * * @param {Array<djs.model.Shape>} elements * @param {djs.model.Shape} target * * @return {boolean} */ AutoResizeProvider.prototype.canResize = function (elements, target) { return false; }; },{"../rules/RuleProvider":270,"inherits":347}],168:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AutoScroll; var _minDash = require("min-dash"); var _Event = require("../../util/Event"); /** * Initiates canvas scrolling if current cursor point is close to a border. * Cancelled when current point moves back inside the scrolling borders * or cancelled manually. * * Default options : * scrollThresholdIn: [ 20, 20, 20, 20 ], * scrollThresholdOut: [ 0, 0, 0, 0 ], * scrollRepeatTimeout: 15, * scrollStep: 10 * * Threshold order: * [ left, top, right, bottom ] */ function AutoScroll(config, eventBus, canvas) { this._canvas = canvas; this._opts = (0, _minDash.assign)({ scrollThresholdIn: [20, 20, 20, 20], scrollThresholdOut: [0, 0, 0, 0], scrollRepeatTimeout: 15, scrollStep: 10 }, config); var self = this; eventBus.on('drag.move', function (e) { var point = self._toBorderPoint(e); self.startScroll(point); }); eventBus.on(['drag.cleanup'], function () { self.stopScroll(); }); } AutoScroll.$inject = ['config.autoScroll', 'eventBus', 'canvas']; /** * Starts scrolling loop. * Point is given in global scale in canvas container box plane. * * @param {Object} point { x: X, y: Y } */ AutoScroll.prototype.startScroll = function (point) { var canvas = this._canvas; var opts = this._opts; var self = this; var clientRect = canvas.getContainer().getBoundingClientRect(); var diff = [point.x, point.y, clientRect.width - point.x, clientRect.height - point.y]; this.stopScroll(); var dx = 0, dy = 0; for (var i = 0; i < 4; i++) { if (between(diff[i], opts.scrollThresholdOut[i], opts.scrollThresholdIn[i])) { if (i === 0) { dx = opts.scrollStep; } else if (i == 1) { dy = opts.scrollStep; } else if (i == 2) { dx = -opts.scrollStep; } else if (i == 3) { dy = -opts.scrollStep; } } } if (dx !== 0 || dy !== 0) { canvas.scroll({ dx: dx, dy: dy }); this._scrolling = setTimeout(function () { self.startScroll(point); }, opts.scrollRepeatTimeout); } }; function between(val, start, end) { if (start < val && val < end) { return true; } return false; } /** * Stops scrolling loop. */ AutoScroll.prototype.stopScroll = function () { clearTimeout(this._scrolling); }; /** * Overrides defaults options. * * @param {Object} options */ AutoScroll.prototype.setOptions = function (options) { this._opts = (0, _minDash.assign)({}, this._opts, options); }; /** * Converts event to a point in canvas container plane in global scale. * * @param {Event} event * @return {Point} */ AutoScroll.prototype._toBorderPoint = function (event) { var clientRect = this._canvas._container.getBoundingClientRect(); var globalPosition = (0, _Event.toPoint)(event.originalEvent); return { x: globalPosition.x - clientRect.left, y: globalPosition.y - clientRect.top }; }; },{"../../util/Event":317,"min-dash":555}],169:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _AutoScroll = _interopRequireDefault(require("./AutoScroll")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_dragging.default], __init__: ['autoScroll'], autoScroll: ['type', _AutoScroll.default] }; exports.default = _default; },{"../dragging":197,"./AutoScroll":168}],170:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BendpointMove; exports.isReverse = isReverse; var _LayoutUtil = require("../../layout/LayoutUtil"); var round = Math.round; var RECONNECT_START = 'reconnectStart', RECONNECT_END = 'reconnectEnd', UPDATE_WAYPOINTS = 'updateWaypoints'; /** * Move bendpoints through drag and drop to add/remove bendpoints or reconnect connection. */ function BendpointMove(injector, eventBus, canvas, dragging, rules, modeling) { this._injector = injector; this.start = function (event, connection, bendpointIndex, insert) { var gfx = canvas.getGraphics(connection), source = connection.source, target = connection.target, waypoints = connection.waypoints, type; if (!insert && bendpointIndex === 0) { type = RECONNECT_START; } else if (!insert && bendpointIndex === waypoints.length - 1) { type = RECONNECT_END; } else { type = UPDATE_WAYPOINTS; } var command = type === UPDATE_WAYPOINTS ? 'connection.updateWaypoints' : 'connection.reconnect'; var allowed = rules.allowed(command, { connection: connection, source: source, target: target }); if (allowed === false) { allowed = rules.allowed(command, { connection: connection, source: target, target: source }); } if (allowed === false) { return; } dragging.init(event, 'bendpoint.move', { data: { connection: connection, connectionGfx: gfx, context: { allowed: allowed, bendpointIndex: bendpointIndex, connection: connection, source: source, target: target, insert: insert, type: type } } }); }; eventBus.on('bendpoint.move.hover', function (event) { var context = event.context, connection = context.connection, source = connection.source, target = connection.target, hover = event.hover, type = context.type; // cache hover state context.hover = hover; var allowed; if (!hover) { return; } var command = type === UPDATE_WAYPOINTS ? 'connection.updateWaypoints' : 'connection.reconnect'; allowed = context.allowed = rules.allowed(command, { connection: connection, source: type === RECONNECT_START ? hover : source, target: type === RECONNECT_END ? hover : target }); if (allowed) { context.source = type === RECONNECT_START ? hover : source; context.target = type === RECONNECT_END ? hover : target; return; } if (allowed === false) { allowed = context.allowed = rules.allowed(command, { connection: connection, source: type === RECONNECT_END ? hover : target, target: type === RECONNECT_START ? hover : source }); } if (allowed) { context.source = type === RECONNECT_END ? hover : target; context.target = type === RECONNECT_START ? hover : source; } }); eventBus.on(['bendpoint.move.out', 'bendpoint.move.cleanup'], function (event) { var context = event.context; context.hover = null; context.source = null; context.target = null; context.allowed = false; }); eventBus.on('bendpoint.move.end', function (event) { var context = event.context, allowed = context.allowed, bendpointIndex = context.bendpointIndex, connection = context.connection, insert = context.insert, newWaypoints = connection.waypoints.slice(), source = context.source, target = context.target, type = context.type, hints = context.hints || {}; // ensure integer values (important if zoom level was > 1 during move) var docking = { x: round(event.x), y: round(event.y) }; if (!allowed) { return false; } if (type === UPDATE_WAYPOINTS) { if (insert) { // insert new bendpoint newWaypoints.splice(bendpointIndex, 0, docking); } else { // swap previous waypoint with moved one newWaypoints[bendpointIndex] = docking; } // pass hints about actual moved bendpoint // useful for connection/label layout hints.bendpointMove = { insert: insert, bendpointIndex: bendpointIndex }; newWaypoints = this.cropWaypoints(connection, newWaypoints); modeling.updateWaypoints(connection, (0, _LayoutUtil.filterRedundantWaypoints)(newWaypoints), hints); } else { if (type === RECONNECT_START) { hints.docking = 'source'; if (isReverse(context)) { hints.docking = 'target'; hints.newWaypoints = newWaypoints.reverse(); } } else if (type === RECONNECT_END) { hints.docking = 'target'; if (isReverse(context)) { hints.docking = 'source'; hints.newWaypoints = newWaypoints.reverse(); } } modeling.reconnect(connection, source, target, docking, hints); } }, this); } BendpointMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'rules', 'modeling']; BendpointMove.prototype.cropWaypoints = function (connection, newWaypoints) { var connectionDocking = this._injector.get('connectionDocking', false); if (!connectionDocking) { return newWaypoints; } var waypoints = connection.waypoints; connection.waypoints = newWaypoints; connection.waypoints = connectionDocking.getCroppedWaypoints(connection); newWaypoints = connection.waypoints; connection.waypoints = waypoints; return newWaypoints; }; // helpers ////////// function isReverse(context) { var hover = context.hover, source = context.source, target = context.target, type = context.type; if (type === RECONNECT_START) { return hover && target && hover === target && source !== target; } if (type === RECONNECT_END) { return hover && source && hover === source && source !== target; } } },{"../../layout/LayoutUtil":300}],171:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BendpointMovePreview; var _tinySvg = require("tiny-svg"); var _BendpointUtil = require("./BendpointUtil"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var _BendpointMove = require("./BendpointMove"); var RECONNECT_START = 'reconnectStart', RECONNECT_END = 'reconnectEnd', UPDATE_WAYPOINTS = 'updateWaypoints'; var MARKER_OK = 'connect-ok', MARKER_NOT_OK = 'connect-not-ok', MARKER_CONNECT_HOVER = 'connect-hover', MARKER_CONNECT_UPDATING = 'djs-updating', MARKER_ELEMENT_HIDDEN = 'djs-element-hidden'; var HIGH_PRIORITY = 1100; /** * Preview connection while moving bendpoints. */ function BendpointMovePreview(bendpointMove, injector, eventBus, canvas) { this._injector = injector; var connectionPreview = injector.get('connectionPreview', false); eventBus.on('bendpoint.move.start', function (event) { var context = event.context, bendpointIndex = context.bendpointIndex, connection = context.connection, insert = context.insert, waypoints = connection.waypoints, newWaypoints = waypoints.slice(); context.waypoints = waypoints; if (insert) { // insert placeholder for new bendpoint newWaypoints.splice(bendpointIndex, 0, { x: event.x, y: event.y }); } connection.waypoints = newWaypoints; // add dragger gfx var draggerGfx = context.draggerGfx = (0, _BendpointUtil.addBendpoint)(canvas.getLayer('overlays')); (0, _tinySvg.classes)(draggerGfx).add('djs-dragging'); canvas.addMarker(connection, MARKER_ELEMENT_HIDDEN); canvas.addMarker(connection, MARKER_CONNECT_UPDATING); }); eventBus.on('bendpoint.move.hover', function (event) { var context = event.context, allowed = context.allowed, hover = context.hover, type = context.type; if (hover) { canvas.addMarker(hover, MARKER_CONNECT_HOVER); if (type === UPDATE_WAYPOINTS) { return; } if (allowed) { canvas.removeMarker(hover, MARKER_NOT_OK); canvas.addMarker(hover, MARKER_OK); } else if (allowed === false) { canvas.removeMarker(hover, MARKER_OK); canvas.addMarker(hover, MARKER_NOT_OK); } } }); eventBus.on(['bendpoint.move.out', 'bendpoint.move.cleanup'], HIGH_PRIORITY, function (event) { var context = event.context, hover = context.hover, target = context.target; if (hover) { canvas.removeMarker(hover, MARKER_CONNECT_HOVER); canvas.removeMarker(hover, target ? MARKER_OK : MARKER_NOT_OK); } }); eventBus.on('bendpoint.move.move', function (event) { var context = event.context, allowed = context.allowed, bendpointIndex = context.bendpointIndex, draggerGfx = context.draggerGfx, hover = context.hover, type = context.type, connection = context.connection, source = connection.source, target = connection.target, newWaypoints = connection.waypoints.slice(), bendpoint = { x: event.x, y: event.y }, hints = context.hints || {}, drawPreviewHints = {}; if (connectionPreview) { if (hints.connectionStart) { drawPreviewHints.connectionStart = hints.connectionStart; } if (hints.connectionEnd) { drawPreviewHints.connectionEnd = hints.connectionEnd; } if (type === RECONNECT_START) { if ((0, _BendpointMove.isReverse)(context)) { drawPreviewHints.connectionEnd = drawPreviewHints.connectionEnd || bendpoint; drawPreviewHints.source = target; drawPreviewHints.target = hover || source; newWaypoints = newWaypoints.reverse(); } else { drawPreviewHints.connectionStart = drawPreviewHints.connectionStart || bendpoint; drawPreviewHints.source = hover || source; drawPreviewHints.target = target; } } else if (type === RECONNECT_END) { if ((0, _BendpointMove.isReverse)(context)) { drawPreviewHints.connectionStart = drawPreviewHints.connectionStart || bendpoint; drawPreviewHints.source = hover || target; drawPreviewHints.target = source; newWaypoints = newWaypoints.reverse(); } else { drawPreviewHints.connectionEnd = drawPreviewHints.connectionEnd || bendpoint; drawPreviewHints.source = source; drawPreviewHints.target = hover || target; } } else { drawPreviewHints.noCropping = true; drawPreviewHints.noLayout = true; newWaypoints[bendpointIndex] = bendpoint; } if (type === UPDATE_WAYPOINTS) { newWaypoints = bendpointMove.cropWaypoints(connection, newWaypoints); } drawPreviewHints.waypoints = newWaypoints; connectionPreview.drawPreview(context, allowed, drawPreviewHints); } (0, _SvgTransformUtil.translate)(draggerGfx, event.x, event.y); }, this); eventBus.on(['bendpoint.move.end', 'bendpoint.move.cancel'], HIGH_PRIORITY, function (event) { var context = event.context, connection = context.connection, draggerGfx = context.draggerGfx, hover = context.hover, target = context.target, waypoints = context.waypoints; connection.waypoints = waypoints; // remove dragger gfx (0, _tinySvg.remove)(draggerGfx); canvas.removeMarker(connection, MARKER_CONNECT_UPDATING); canvas.removeMarker(connection, MARKER_ELEMENT_HIDDEN); if (hover) { canvas.removeMarker(hover, MARKER_OK); canvas.removeMarker(hover, target ? MARKER_OK : MARKER_NOT_OK); } if (connectionPreview) { connectionPreview.cleanUp(context); } }); } BendpointMovePreview.$inject = ['bendpointMove', 'injector', 'eventBus', 'canvas']; },{"../../util/SvgTransformUtil":328,"./BendpointMove":170,"./BendpointUtil":173,"tiny-svg":567}],172:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BendpointSnapping; var _minDash = require("min-dash"); var _SnapUtil = require("../snapping/SnapUtil"); var abs = Math.abs, round = Math.round; var TOLERANCE = 10; function BendpointSnapping(eventBus) { function snapTo(values, value) { if ((0, _minDash.isArray)(values)) { var i = values.length; while (i--) if (abs(values[i] - value) <= TOLERANCE) { return values[i]; } } else { values = +values; var rem = value % values; if (rem < TOLERANCE) { return value - rem; } if (rem > values - TOLERANCE) { return value - rem + values; } } return value; } function mid(element) { if (element.width) { return { x: round(element.width / 2 + element.x), y: round(element.height / 2 + element.y) }; } } // connection segment snapping ////////////////////// function getConnectionSegmentSnaps(context) { var snapPoints = context.snapPoints, connection = context.connection, waypoints = connection.waypoints, segmentStart = context.segmentStart, segmentStartIndex = context.segmentStartIndex, segmentEnd = context.segmentEnd, segmentEndIndex = context.segmentEndIndex, axis = context.axis; if (snapPoints) { return snapPoints; } var referenceWaypoints = [waypoints[segmentStartIndex - 1], segmentStart, segmentEnd, waypoints[segmentEndIndex + 1]]; if (segmentStartIndex < 2) { referenceWaypoints.unshift(mid(connection.source)); } if (segmentEndIndex > waypoints.length - 3) { referenceWaypoints.unshift(mid(connection.target)); } context.snapPoints = snapPoints = { horizontal: [], vertical: [] }; (0, _minDash.forEach)(referenceWaypoints, function (p) { // we snap on existing bendpoints only, // not placeholders that are inserted during add if (p) { p = p.original || p; if (axis === 'y') { snapPoints.horizontal.push(p.y); } if (axis === 'x') { snapPoints.vertical.push(p.x); } } }); return snapPoints; } eventBus.on('connectionSegment.move.move', 1500, function (event) { var context = event.context, snapPoints = getConnectionSegmentSnaps(context), x = event.x, y = event.y, sx, sy; if (!snapPoints) { return; } // snap sx = snapTo(snapPoints.vertical, x); sy = snapTo(snapPoints.horizontal, y); // correction x/y var cx = x - sx, cy = y - sy; // update delta (0, _minDash.assign)(event, { dx: event.dx - cx, dy: event.dy - cy, x: sx, y: sy }); // only set snapped if actually snapped if (cx || snapPoints.vertical.indexOf(x) !== -1) { (0, _SnapUtil.setSnapped)(event, 'x', sx); } if (cy || snapPoints.horizontal.indexOf(y) !== -1) { (0, _SnapUtil.setSnapped)(event, 'y', sy); } }); // bendpoint snapping ////////////////////// function getBendpointSnaps(context) { var snapPoints = context.snapPoints, waypoints = context.connection.waypoints, bendpointIndex = context.bendpointIndex; if (snapPoints) { return snapPoints; } var referenceWaypoints = [waypoints[bendpointIndex - 1], waypoints[bendpointIndex + 1]]; context.snapPoints = snapPoints = { horizontal: [], vertical: [] }; (0, _minDash.forEach)(referenceWaypoints, function (p) { // we snap on existing bendpoints only, // not placeholders that are inserted during add if (p) { p = p.original || p; snapPoints.horizontal.push(p.y); snapPoints.vertical.push(p.x); } }); return snapPoints; } eventBus.on(['bendpoint.move.move', 'bendpoint.move.end'], 1500, function (event) { var context = event.context, snapPoints = getBendpointSnaps(context), hover = context.hover, hoverMid = hover && mid(hover), x = event.x, y = event.y, sx, sy; if (!snapPoints) { return; } // snap to hover mid sx = snapTo(hoverMid ? snapPoints.vertical.concat([hoverMid.x]) : snapPoints.vertical, x); sy = snapTo(hoverMid ? snapPoints.horizontal.concat([hoverMid.y]) : snapPoints.horizontal, y); // correction x/y var cx = x - sx, cy = y - sy; // update delta (0, _minDash.assign)(event, { dx: event.dx - cx, dy: event.dy - cy, x: event.x - cx, y: event.y - cy }); // only set snapped if actually snapped if (cx || snapPoints.vertical.indexOf(x) !== -1) { (0, _SnapUtil.setSnapped)(event, 'x', sx); } if (cy || snapPoints.horizontal.indexOf(y) !== -1) { (0, _SnapUtil.setSnapped)(event, 'y', sy); } }); } BendpointSnapping.$inject = ['eventBus']; },{"../snapping/SnapUtil":282,"min-dash":555}],173:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.toCanvasCoordinates = toCanvasCoordinates; exports.getConnectionIntersection = getConnectionIntersection; exports.addBendpoint = addBendpoint; exports.addSegmentDragger = addSegmentDragger; exports.calculateSegmentMoveRegion = calculateSegmentMoveRegion; exports.SEGMENT_DRAGGER_CLS = exports.BENDPOINT_CLS = void 0; var _Event = require("../../util/Event"); var _Geometry = require("../../util/Geometry"); var _tinySvg = require("tiny-svg"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var _LineIntersection = require("../../util/LineIntersection"); var BENDPOINT_CLS = 'djs-bendpoint'; exports.BENDPOINT_CLS = BENDPOINT_CLS; var SEGMENT_DRAGGER_CLS = 'djs-segment-dragger'; exports.SEGMENT_DRAGGER_CLS = SEGMENT_DRAGGER_CLS; function toCanvasCoordinates(canvas, event) { var position = (0, _Event.toPoint)(event), clientRect = canvas._container.getBoundingClientRect(), offset; // canvas relative position offset = { x: clientRect.left, y: clientRect.top }; // update actual event payload with canvas relative measures var viewbox = canvas.viewbox(); return { x: viewbox.x + (position.x - offset.x) / viewbox.scale, y: viewbox.y + (position.y - offset.y) / viewbox.scale }; } function getConnectionIntersection(canvas, waypoints, event) { var localPosition = toCanvasCoordinates(canvas, event), intersection = (0, _LineIntersection.getApproxIntersection)(waypoints, localPosition); return intersection; } function addBendpoint(parentGfx, cls) { var groupGfx = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(groupGfx).add(BENDPOINT_CLS); (0, _tinySvg.append)(parentGfx, groupGfx); var visual = (0, _tinySvg.create)('circle'); (0, _tinySvg.attr)(visual, { cx: 0, cy: 0, r: 4 }); (0, _tinySvg.classes)(visual).add('djs-visual'); (0, _tinySvg.append)(groupGfx, visual); var hit = (0, _tinySvg.create)('circle'); (0, _tinySvg.attr)(hit, { cx: 0, cy: 0, r: 10 }); (0, _tinySvg.classes)(hit).add('djs-hit'); (0, _tinySvg.append)(groupGfx, hit); if (cls) { (0, _tinySvg.classes)(groupGfx).add(cls); } return groupGfx; } function createParallelDragger(parentGfx, segmentStart, segmentEnd, alignment) { var draggerGfx = (0, _tinySvg.create)('g'); (0, _tinySvg.append)(parentGfx, draggerGfx); var width = 14, height = 3, padding = 11, hitWidth = calculateHitWidth(segmentStart, segmentEnd, alignment), hitHeight = height + padding; var visual = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(visual, { x: -width / 2, y: -height / 2, width: width, height: height }); (0, _tinySvg.classes)(visual).add('djs-visual'); (0, _tinySvg.append)(draggerGfx, visual); var hit = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(hit, { x: -hitWidth / 2, y: -hitHeight / 2, width: hitWidth, height: hitHeight }); (0, _tinySvg.classes)(hit).add('djs-hit'); (0, _tinySvg.append)(draggerGfx, hit); (0, _SvgTransformUtil.rotate)(draggerGfx, alignment === 'v' ? 90 : 0, 0, 0); return draggerGfx; } function addSegmentDragger(parentGfx, segmentStart, segmentEnd) { var groupGfx = (0, _tinySvg.create)('g'), mid = (0, _Geometry.getMidPoint)(segmentStart, segmentEnd), alignment = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd); (0, _tinySvg.append)(parentGfx, groupGfx); createParallelDragger(groupGfx, segmentStart, segmentEnd, alignment); (0, _tinySvg.classes)(groupGfx).add(SEGMENT_DRAGGER_CLS); (0, _tinySvg.classes)(groupGfx).add(alignment === 'h' ? 'horizontal' : 'vertical'); (0, _SvgTransformUtil.translate)(groupGfx, mid.x, mid.y); return groupGfx; } /** * Calculates region for segment move which is 2/3 of the full segment length * @param {number} segmentLength * * @return {number} */ function calculateSegmentMoveRegion(segmentLength) { return Math.abs(Math.round(segmentLength * 2 / 3)); } // helper ////////// function calculateHitWidth(segmentStart, segmentEnd, alignment) { var segmentLengthXAxis = segmentEnd.x - segmentStart.x, segmentLengthYAxis = segmentEnd.y - segmentStart.y; return alignment === 'h' ? calculateSegmentMoveRegion(segmentLengthXAxis) : calculateSegmentMoveRegion(segmentLengthYAxis); } },{"../../util/Event":317,"../../util/Geometry":318,"../../util/LineIntersection":321,"../../util/SvgTransformUtil":328,"tiny-svg":567}],174:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Bendpoints; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _BendpointUtil = require("./BendpointUtil"); var _EscapeUtil = require("../../util/EscapeUtil"); var _Geometry = require("../../util/Geometry"); var _tinySvg = require("tiny-svg"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); /** * A service that adds editable bendpoints to connections. */ function Bendpoints(eventBus, canvas, interactionEvents, bendpointMove, connectionSegmentMove) { /** * Returns true if intersection point is inside middle region of segment, adjusted by * optional threshold */ function isIntersectionMiddle(intersection, waypoints, treshold) { var idx = intersection.index, p = intersection.point, p0, p1, mid, aligned, xDelta, yDelta; if (idx <= 0 || intersection.bendpoint) { return false; } p0 = waypoints[idx - 1]; p1 = waypoints[idx]; mid = (0, _Geometry.getMidPoint)(p0, p1), aligned = (0, _Geometry.pointsAligned)(p0, p1); xDelta = Math.abs(p.x - mid.x); yDelta = Math.abs(p.y - mid.y); return aligned && xDelta <= treshold && yDelta <= treshold; } /** * Calculates the threshold from a connection's middle which fits the two-third-region */ function calculateIntersectionThreshold(connection, intersection) { var waypoints = connection.waypoints, relevantSegment, alignment, segmentLength, threshold; if (intersection.index <= 0 || intersection.bendpoint) { return null; } // segment relative to connection intersection relevantSegment = { start: waypoints[intersection.index - 1], end: waypoints[intersection.index] }; alignment = (0, _Geometry.pointsAligned)(relevantSegment.start, relevantSegment.end); if (!alignment) { return null; } if (alignment === 'h') { segmentLength = relevantSegment.end.x - relevantSegment.start.x; } else { segmentLength = relevantSegment.end.y - relevantSegment.start.y; } // calculate threshold relative to 2/3 of segment length threshold = (0, _BendpointUtil.calculateSegmentMoveRegion)(segmentLength) / 2; return threshold; } function activateBendpointMove(event, connection) { var waypoints = connection.waypoints, intersection = (0, _BendpointUtil.getConnectionIntersection)(canvas, waypoints, event), threshold; if (!intersection) { return; } threshold = calculateIntersectionThreshold(connection, intersection); if (isIntersectionMiddle(intersection, waypoints, threshold)) { connectionSegmentMove.start(event, connection, intersection.index); } else { bendpointMove.start(event, connection, intersection.index, !intersection.bendpoint); } // we've handled the event return true; } function bindInteractionEvents(node, eventName, element) { _minDom.event.bind(node, eventName, function (event) { interactionEvents.triggerMouseEvent(eventName, event, element); event.stopPropagation(); }); } function getBendpointsContainer(element, create) { var layer = canvas.getLayer('overlays'), gfx = (0, _minDom.query)('.djs-bendpoints[data-element-id="' + (0, _EscapeUtil.escapeCSS)(element.id) + '"]', layer); if (!gfx && create) { gfx = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(gfx, { 'data-element-id': element.id }); (0, _tinySvg.classes)(gfx).add('djs-bendpoints'); (0, _tinySvg.append)(layer, gfx); bindInteractionEvents(gfx, 'mousedown', element); bindInteractionEvents(gfx, 'click', element); bindInteractionEvents(gfx, 'dblclick', element); } return gfx; } function getSegmentDragger(idx, parentGfx) { return (0, _minDom.query)('.djs-segment-dragger[data-segment-idx="' + idx + '"]', parentGfx); } function createBendpoints(gfx, connection) { connection.waypoints.forEach(function (p, idx) { var bendpoint = (0, _BendpointUtil.addBendpoint)(gfx); (0, _tinySvg.append)(gfx, bendpoint); (0, _SvgTransformUtil.translate)(bendpoint, p.x, p.y); }); // add floating bendpoint (0, _BendpointUtil.addBendpoint)(gfx, 'floating'); } function createSegmentDraggers(gfx, connection) { var waypoints = connection.waypoints; var segmentStart, segmentEnd, segmentDraggerGfx; for (var i = 1; i < waypoints.length; i++) { segmentStart = waypoints[i - 1]; segmentEnd = waypoints[i]; if ((0, _Geometry.pointsAligned)(segmentStart, segmentEnd)) { segmentDraggerGfx = (0, _BendpointUtil.addSegmentDragger)(gfx, segmentStart, segmentEnd); (0, _tinySvg.attr)(segmentDraggerGfx, { 'data-segment-idx': i }); bindInteractionEvents(segmentDraggerGfx, 'mousemove', connection); } } } function clearBendpoints(gfx) { (0, _minDash.forEach)((0, _minDom.queryAll)('.' + _BendpointUtil.BENDPOINT_CLS, gfx), function (node) { (0, _tinySvg.remove)(node); }); } function clearSegmentDraggers(gfx) { (0, _minDash.forEach)((0, _minDom.queryAll)('.' + _BendpointUtil.SEGMENT_DRAGGER_CLS, gfx), function (node) { (0, _tinySvg.remove)(node); }); } function addHandles(connection) { var gfx = getBendpointsContainer(connection); if (!gfx) { gfx = getBendpointsContainer(connection, true); createBendpoints(gfx, connection); createSegmentDraggers(gfx, connection); } return gfx; } function updateHandles(connection) { var gfx = getBendpointsContainer(connection); if (gfx) { clearSegmentDraggers(gfx); clearBendpoints(gfx); createSegmentDraggers(gfx, connection); createBendpoints(gfx, connection); } } function updateFloatingBendpointPosition(parentGfx, intersection) { var floating = (0, _minDom.query)('.floating', parentGfx), point = intersection.point; if (!floating) { return; } (0, _SvgTransformUtil.translate)(floating, point.x, point.y); } function updateSegmentDraggerPosition(parentGfx, intersection, waypoints) { var draggerGfx = getSegmentDragger(intersection.index, parentGfx), segmentStart = waypoints[intersection.index - 1], segmentEnd = waypoints[intersection.index], point = intersection.point, mid = (0, _Geometry.getMidPoint)(segmentStart, segmentEnd), alignment = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd), draggerVisual, relativePosition; if (!draggerGfx) { return; } draggerVisual = getDraggerVisual(draggerGfx); relativePosition = { x: point.x - mid.x, y: point.y - mid.y }; if (alignment === 'v') { // rotate position relativePosition = { x: relativePosition.y, y: relativePosition.x }; } (0, _SvgTransformUtil.translate)(draggerVisual, relativePosition.x, relativePosition.y); } eventBus.on('connection.changed', function (event) { updateHandles(event.element); }); eventBus.on('connection.remove', function (event) { var gfx = getBendpointsContainer(event.element); if (gfx) { (0, _tinySvg.remove)(gfx); } }); eventBus.on('element.marker.update', function (event) { var element = event.element, bendpointsGfx; if (!element.waypoints) { return; } bendpointsGfx = addHandles(element); if (event.add) { (0, _tinySvg.classes)(bendpointsGfx).add(event.marker); } else { (0, _tinySvg.classes)(bendpointsGfx).remove(event.marker); } }); eventBus.on('element.mousemove', function (event) { var element = event.element, waypoints = element.waypoints, bendpointsGfx, intersection; if (waypoints) { bendpointsGfx = getBendpointsContainer(element, true); intersection = (0, _BendpointUtil.getConnectionIntersection)(canvas, waypoints, event.originalEvent); if (!intersection) { return; } updateFloatingBendpointPosition(bendpointsGfx, intersection); if (!intersection.bendpoint) { updateSegmentDraggerPosition(bendpointsGfx, intersection, waypoints); } } }); eventBus.on('element.mousedown', function (event) { var originalEvent = event.originalEvent, element = event.element; if (!element.waypoints) { return; } return activateBendpointMove(originalEvent, element); }); eventBus.on('selection.changed', function (event) { var newSelection = event.newSelection, primary = newSelection[0]; if (primary && primary.waypoints) { addHandles(primary); } }); eventBus.on('element.hover', function (event) { var element = event.element; if (element.waypoints) { addHandles(element); interactionEvents.registerEvent(event.gfx, 'mousemove', 'element.mousemove'); } }); eventBus.on('element.out', function (event) { interactionEvents.unregisterEvent(event.gfx, 'mousemove', 'element.mousemove'); }); // update bendpoint container data attribute on element ID change eventBus.on('element.updateId', function (context) { var element = context.element, newId = context.newId; if (element.waypoints) { var bendpointContainer = getBendpointsContainer(element); if (bendpointContainer) { (0, _tinySvg.attr)(bendpointContainer, { 'data-element-id': newId }); } } }); // API this.addHandles = addHandles; this.updateHandles = updateHandles; this.getBendpointsContainer = getBendpointsContainer; this.getSegmentDragger = getSegmentDragger; } Bendpoints.$inject = ['eventBus', 'canvas', 'interactionEvents', 'bendpointMove', 'connectionSegmentMove']; // helper ///////////// function getDraggerVisual(draggerGfx) { return (0, _minDom.query)('.djs-visual', draggerGfx); } },{"../../util/EscapeUtil":316,"../../util/Geometry":318,"../../util/SvgTransformUtil":328,"./BendpointUtil":173,"min-dash":555,"min-dom":556,"tiny-svg":567}],175:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ConnectionSegmentMove; var _Geometry = require("../../util/Geometry"); var _BendpointUtil = require("./BendpointUtil"); var _LayoutUtil = require("../../layout/LayoutUtil"); var _tinySvg = require("tiny-svg"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var MARKER_CONNECT_HOVER = 'connect-hover', MARKER_CONNECT_UPDATING = 'djs-updating'; function axisAdd(point, axis, delta) { return axisSet(point, axis, point[axis] + delta); } function axisSet(point, axis, value) { return { x: axis === 'x' ? value : point.x, y: axis === 'y' ? value : point.y }; } function axisFenced(position, segmentStart, segmentEnd, axis) { var maxValue = Math.max(segmentStart[axis], segmentEnd[axis]), minValue = Math.min(segmentStart[axis], segmentEnd[axis]); var padding = 20; var fencedValue = Math.min(Math.max(minValue + padding, position[axis]), maxValue - padding); return axisSet(segmentStart, axis, fencedValue); } function flipAxis(axis) { return axis === 'x' ? 'y' : 'x'; } /** * Get the docking point on the given element. * * Compute a reasonable docking, if non exists. * * @param {Point} point * @param {djs.model.Shape} referenceElement * @param {string} moveAxis (x|y) * * @return {Point} */ function getDocking(point, referenceElement, moveAxis) { var referenceMid, inverseAxis; if (point.original) { return point.original; } else { referenceMid = (0, _LayoutUtil.getMid)(referenceElement); inverseAxis = flipAxis(moveAxis); return axisSet(point, inverseAxis, referenceMid[inverseAxis]); } } /** * A component that implements moving of bendpoints */ function ConnectionSegmentMove(injector, eventBus, canvas, dragging, graphicsFactory, modeling) { // optional connection docking integration var connectionDocking = injector.get('connectionDocking', false); // API this.start = function (event, connection, idx) { var context, gfx = canvas.getGraphics(connection), segmentStartIndex = idx - 1, segmentEndIndex = idx, waypoints = connection.waypoints, segmentStart = waypoints[segmentStartIndex], segmentEnd = waypoints[segmentEndIndex], intersection = (0, _BendpointUtil.getConnectionIntersection)(canvas, waypoints, event), direction, axis, dragPosition; direction = (0, _Geometry.pointsAligned)(segmentStart, segmentEnd); // do not move diagonal connection if (!direction) { return; } // the axis where we are going to move things axis = direction === 'v' ? 'x' : 'y'; if (segmentStartIndex === 0) { segmentStart = getDocking(segmentStart, connection.source, axis); } if (segmentEndIndex === waypoints.length - 1) { segmentEnd = getDocking(segmentEnd, connection.target, axis); } if (intersection) { dragPosition = intersection.point; } else { // set to segment center as default dragPosition = { x: (segmentStart.x + segmentEnd.x) / 2, y: (segmentStart.y + segmentEnd.y) / 2 }; } context = { connection: connection, segmentStartIndex: segmentStartIndex, segmentEndIndex: segmentEndIndex, segmentStart: segmentStart, segmentEnd: segmentEnd, axis: axis, dragPosition: dragPosition }; dragging.init(event, dragPosition, 'connectionSegment.move', { cursor: axis === 'x' ? 'resize-ew' : 'resize-ns', data: { connection: connection, connectionGfx: gfx, context: context } }); }; /** * Crop connection if connection cropping is provided. * * @param {Connection} connection * @param {Array<Point>} newWaypoints * * @return {Array<Point>} cropped connection waypoints */ function cropConnection(connection, newWaypoints) { // crop connection, if docking service is provided only if (!connectionDocking) { return newWaypoints; } var oldWaypoints = connection.waypoints, croppedWaypoints; // temporary set new waypoints connection.waypoints = newWaypoints; croppedWaypoints = connectionDocking.getCroppedWaypoints(connection); // restore old waypoints connection.waypoints = oldWaypoints; return croppedWaypoints; } // DRAGGING IMPLEMENTATION function redrawConnection(data) { graphicsFactory.update('connection', data.connection, data.connectionGfx); } function updateDragger(context, segmentOffset, event) { var newWaypoints = context.newWaypoints, segmentStartIndex = context.segmentStartIndex + segmentOffset, segmentStart = newWaypoints[segmentStartIndex], segmentEndIndex = context.segmentEndIndex + segmentOffset, segmentEnd = newWaypoints[segmentEndIndex], axis = flipAxis(context.axis); // make sure the dragger does not move // outside the connection var draggerPosition = axisFenced(event, segmentStart, segmentEnd, axis); // update dragger (0, _SvgTransformUtil.translate)(context.draggerGfx, draggerPosition.x, draggerPosition.y); } /** * Filter waypoints for redundant ones (i.e. on the same axis). * Returns the filtered waypoints and the offset related to the segment move. * * @param {Array<Point>} waypoints * @param {Integer} segmentStartIndex of moved segment start * * @return {Object} { filteredWaypoints, segmentOffset } */ function filterRedundantWaypoints(waypoints, segmentStartIndex) { var segmentOffset = 0; var filteredWaypoints = waypoints.filter(function (r, idx) { if ((0, _Geometry.pointsOnLine)(waypoints[idx - 1], waypoints[idx + 1], r)) { // remove point and increment offset segmentOffset = idx <= segmentStartIndex ? segmentOffset - 1 : segmentOffset; return false; } // dont remove point return true; }); return { waypoints: filteredWaypoints, segmentOffset: segmentOffset }; } eventBus.on('connectionSegment.move.start', function (event) { var context = event.context, connection = event.connection, layer = canvas.getLayer('overlays'); context.originalWaypoints = connection.waypoints.slice(); // add dragger gfx context.draggerGfx = (0, _BendpointUtil.addSegmentDragger)(layer, context.segmentStart, context.segmentEnd); (0, _tinySvg.classes)(context.draggerGfx).add('djs-dragging'); canvas.addMarker(connection, MARKER_CONNECT_UPDATING); }); eventBus.on('connectionSegment.move.move', function (event) { var context = event.context, connection = context.connection, segmentStartIndex = context.segmentStartIndex, segmentEndIndex = context.segmentEndIndex, segmentStart = context.segmentStart, segmentEnd = context.segmentEnd, axis = context.axis; var newWaypoints = context.originalWaypoints.slice(), newSegmentStart = axisAdd(segmentStart, axis, event['d' + axis]), newSegmentEnd = axisAdd(segmentEnd, axis, event['d' + axis]); // original waypoint count and added / removed // from start waypoint delta. We use the later // to retrieve the updated segmentStartIndex / segmentEndIndex var waypointCount = newWaypoints.length, segmentOffset = 0; // move segment start / end by axis delta newWaypoints[segmentStartIndex] = newSegmentStart; newWaypoints[segmentEndIndex] = newSegmentEnd; var sourceToSegmentOrientation, targetToSegmentOrientation; // handle first segment if (segmentStartIndex < 2) { sourceToSegmentOrientation = (0, _LayoutUtil.getOrientation)(connection.source, newSegmentStart); // first bendpoint, remove first segment if intersecting if (segmentStartIndex === 1) { if (sourceToSegmentOrientation === 'intersect') { newWaypoints.shift(); newWaypoints[0] = newSegmentStart; segmentOffset--; } } // docking point, add segment if not intersecting anymore else { if (sourceToSegmentOrientation !== 'intersect') { newWaypoints.unshift(segmentStart); segmentOffset++; } } } // handle last segment if (segmentEndIndex > waypointCount - 3) { targetToSegmentOrientation = (0, _LayoutUtil.getOrientation)(connection.target, newSegmentEnd); // last bendpoint, remove last segment if intersecting if (segmentEndIndex === waypointCount - 2) { if (targetToSegmentOrientation === 'intersect') { newWaypoints.pop(); newWaypoints[newWaypoints.length - 1] = newSegmentEnd; } } // last bendpoint, remove last segment if intersecting else { if (targetToSegmentOrientation !== 'intersect') { newWaypoints.push(segmentEnd); } } } // update connection waypoints context.newWaypoints = connection.waypoints = cropConnection(connection, newWaypoints); // update dragger position updateDragger(context, segmentOffset, event); // save segmentOffset in context context.newSegmentStartIndex = segmentStartIndex + segmentOffset; // redraw connection redrawConnection(event); }); eventBus.on('connectionSegment.move.hover', function (event) { event.context.hover = event.hover; canvas.addMarker(event.hover, MARKER_CONNECT_HOVER); }); eventBus.on(['connectionSegment.move.out', 'connectionSegment.move.cleanup'], function (event) { // remove connect marker // if it was added var hover = event.context.hover; if (hover) { canvas.removeMarker(hover, MARKER_CONNECT_HOVER); } }); eventBus.on('connectionSegment.move.cleanup', function (event) { var context = event.context, connection = context.connection; // remove dragger gfx if (context.draggerGfx) { (0, _tinySvg.remove)(context.draggerGfx); } canvas.removeMarker(connection, MARKER_CONNECT_UPDATING); }); eventBus.on(['connectionSegment.move.cancel', 'connectionSegment.move.end'], function (event) { var context = event.context, connection = context.connection; connection.waypoints = context.originalWaypoints; redrawConnection(event); }); eventBus.on('connectionSegment.move.end', function (event) { var context = event.context, connection = context.connection, newWaypoints = context.newWaypoints, newSegmentStartIndex = context.newSegmentStartIndex; // ensure we have actual pixel values bendpoint // coordinates (important when zoom level was > 1 during move) newWaypoints = newWaypoints.map(function (p) { return { original: p.original, x: Math.round(p.x), y: Math.round(p.y) }; }); // apply filter redunant waypoints var filtered = filterRedundantWaypoints(newWaypoints, newSegmentStartIndex); // get filtered waypoints var filteredWaypoints = filtered.waypoints, croppedWaypoints = cropConnection(connection, filteredWaypoints), segmentOffset = filtered.segmentOffset; var hints = { segmentMove: { segmentStartIndex: context.segmentStartIndex, newSegmentStartIndex: newSegmentStartIndex + segmentOffset } }; modeling.updateWaypoints(connection, croppedWaypoints, hints); }); } ConnectionSegmentMove.$inject = ['injector', 'eventBus', 'canvas', 'dragging', 'graphicsFactory', 'modeling']; },{"../../layout/LayoutUtil":300,"../../util/Geometry":318,"../../util/SvgTransformUtil":328,"./BendpointUtil":173,"tiny-svg":567}],176:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _rules = _interopRequireDefault(require("../rules")); var _Bendpoints = _interopRequireDefault(require("./Bendpoints")); var _BendpointMove = _interopRequireDefault(require("./BendpointMove")); var _BendpointMovePreview = _interopRequireDefault(require("./BendpointMovePreview")); var _ConnectionSegmentMove = _interopRequireDefault(require("./ConnectionSegmentMove")); var _BendpointSnapping = _interopRequireDefault(require("./BendpointSnapping")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_dragging.default, _rules.default], __init__: ['bendpoints', 'bendpointSnapping', 'bendpointMovePreview'], bendpoints: ['type', _Bendpoints.default], bendpointMove: ['type', _BendpointMove.default], bendpointMovePreview: ['type', _BendpointMovePreview.default], connectionSegmentMove: ['type', _ConnectionSegmentMove.default], bendpointSnapping: ['type', _BendpointSnapping.default] }; exports.default = _default; },{"../dragging":197,"../rules":272,"./BendpointMove":170,"./BendpointMovePreview":171,"./BendpointSnapping":172,"./Bendpoints":174,"./ConnectionSegmentMove":175}],177:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ChangeSupport; var _Elements = require("../../util/Elements"); /** * Adds change support to the diagram, including * * <ul> * <li>redrawing shapes and connections on change</li> * </ul> * * @param {EventBus} eventBus * @param {Canvas} canvas * @param {ElementRegistry} elementRegistry * @param {GraphicsFactory} graphicsFactory */ function ChangeSupport(eventBus, canvas, elementRegistry, graphicsFactory) { // redraw shapes / connections on change eventBus.on('element.changed', function (event) { var element = event.element; // element might have been deleted and replaced by new element with same ID // thus check for parent of element except for root element if (element.parent || element === canvas.getRootElement()) { event.gfx = elementRegistry.getGraphics(element); } // shape + gfx may have been deleted if (!event.gfx) { return; } eventBus.fire((0, _Elements.getType)(element) + '.changed', event); }); eventBus.on('elements.changed', function (event) { var elements = event.elements; elements.forEach(function (e) { eventBus.fire('element.changed', { element: e }); }); graphicsFactory.updateContainments(elements); }); eventBus.on('shape.changed', function (event) { graphicsFactory.update('shape', event.element, event.gfx); }); eventBus.on('connection.changed', function (event) { graphicsFactory.update('connection', event.element, event.gfx); }); } ChangeSupport.$inject = ['eventBus', 'canvas', 'elementRegistry', 'graphicsFactory']; },{"../../util/Elements":315}],178:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ChangeSupport = _interopRequireDefault(require("./ChangeSupport")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['changeSupport'], changeSupport: ['type', _ChangeSupport.default] }; exports.default = _default; },{"./ChangeSupport":177}],179:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Clipboard; /** * A clip board stub */ function Clipboard() {} Clipboard.prototype.get = function () { return this._data; }; Clipboard.prototype.set = function (data) { this._data = data; }; Clipboard.prototype.clear = function () { var data = this._data; delete this._data; return data; }; Clipboard.prototype.isEmpty = function () { return !this._data; }; },{}],180:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Clipboard = _interopRequireDefault(require("./Clipboard")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { clipboard: ['type', _Clipboard.default] }; exports.default = _default; },{"./Clipboard":179}],181:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Connect; exports.isReverse = isReverse; var _LayoutUtil = require("../../layout/LayoutUtil"); var _minDash = require("min-dash"); function Connect(eventBus, dragging, modeling, rules) { // rules function canConnect(source, target) { return rules.allowed('connection.create', { source: source, target: target }); } function canConnectReverse(source, target) { return canConnect(target, source); } // event handlers eventBus.on('connect.hover', function (event) { var context = event.context, start = context.start, hover = event.hover, canExecute; // cache hover state context.hover = hover; canExecute = context.canExecute = canConnect(start, hover); // ignore hover if ((0, _minDash.isNil)(canExecute)) { return; } if (canExecute !== false) { context.source = start; context.target = hover; return; } canExecute = context.canExecute = canConnectReverse(start, hover); // ignore hover if ((0, _minDash.isNil)(canExecute)) { return; } if (canExecute !== false) { context.source = hover; context.target = start; } }); eventBus.on(['connect.out', 'connect.cleanup'], function (event) { var context = event.context; context.hover = null; context.source = null; context.target = null; context.canExecute = false; }); eventBus.on('connect.end', function (event) { var context = event.context, canExecute = context.canExecute, connectionStart = context.connectionStart, connectionEnd = { x: event.x, y: event.y }, source = context.source, target = context.target; if (!canExecute) { return false; } var attrs = null, hints = { connectionStart: isReverse(context) ? connectionEnd : connectionStart, connectionEnd: isReverse(context) ? connectionStart : connectionEnd }; if ((0, _minDash.isObject)(canExecute)) { attrs = canExecute; } modeling.connect(source, target, attrs, hints); }); // API /** * Start connect operation. * * @param {DOMEvent} event * @param {djs.model.Base} start * @param {Point} [connectionStart] * @param {boolean} [autoActivate=false] */ this.start = function (event, start, connectionStart, autoActivate) { if (!(0, _minDash.isObject)(connectionStart)) { autoActivate = connectionStart; connectionStart = (0, _LayoutUtil.getMid)(start); } dragging.init(event, 'connect', { autoActivate: autoActivate, data: { shape: start, context: { start: start, connectionStart: connectionStart } } }); }; } Connect.$inject = ['eventBus', 'dragging', 'modeling', 'rules']; // helpers ////////// function isReverse(context) { var hover = context.hover, source = context.source, target = context.target; return hover && source && hover === source && source !== target; } },{"../../layout/LayoutUtil":300,"min-dash":555}],182:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ConnectPreview; var _Connect = require("./Connect"); var HIGH_PRIORITY = 1100, LOW_PRIORITY = 900; var MARKER_OK = 'connect-ok', MARKER_NOT_OK = 'connect-not-ok'; /** * Shows connection preview during connect. * * @param {didi.Injector} injector * @param {EventBus} eventBus * @param {Canvas} canvas */ function ConnectPreview(injector, eventBus, canvas) { var connectionPreview = injector.get('connectionPreview', false); connectionPreview && eventBus.on('connect.move', function (event) { var context = event.context, canConnect = context.canExecute, hover = context.hover, source = context.source, start = context.start, startPosition = context.startPosition, connectionStart = context.connectionStart, connectionEnd = context.connectionEnd, target = context.target; if (!connectionStart) { connectionStart = (0, _Connect.isReverse)(context) ? { x: event.x, y: event.y } : startPosition; } if (!connectionEnd) { connectionEnd = (0, _Connect.isReverse)(context) ? startPosition : { x: event.x, y: event.y }; } connectionPreview.drawPreview(context, canConnect, { source: source || start, target: target || hover, connectionStart: connectionStart, connectionEnd: connectionEnd }); }); eventBus.on('connect.hover', LOW_PRIORITY, function (event) { var context = event.context, hover = event.hover, canExecute = context.canExecute; // ignore hover if (canExecute === null) { return; } canvas.addMarker(hover, canExecute ? MARKER_OK : MARKER_NOT_OK); }); eventBus.on(['connect.out', 'connect.cleanup'], HIGH_PRIORITY, function (event) { var hover = event.hover; if (hover) { canvas.removeMarker(hover, MARKER_OK); canvas.removeMarker(hover, MARKER_NOT_OK); } }); connectionPreview && eventBus.on('connect.cleanup', function (event) { connectionPreview.cleanUp(event.context); }); } ConnectPreview.$inject = ['injector', 'eventBus', 'canvas']; },{"./Connect":181}],183:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _selection = _interopRequireDefault(require("../selection")); var _rules = _interopRequireDefault(require("../rules")); var _dragging = _interopRequireDefault(require("../dragging")); var _Connect = _interopRequireDefault(require("./Connect")); var _ConnectPreview = _interopRequireDefault(require("./ConnectPreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_selection.default, _rules.default, _dragging.default], __init__: ['connectPreview'], connect: ['type', _Connect.default], connectPreview: ['type', _ConnectPreview.default] }; exports.default = _default; },{"../dragging":197,"../rules":272,"../selection":278,"./Connect":181,"./ConnectPreview":182}],184:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ConnectionPreview; var _tinySvg = require("tiny-svg"); var _minDash = require("min-dash"); var _LayoutUtil = require("../../layout/LayoutUtil"); var MARKER_CONNECTION_PREVIEW = 'djs-connection-preview'; /** * Draws connection preview. Optionally, this can use layouter and connection docking to draw * better looking previews. * * @param {didi.Injector} injector * @param {Canvas} canvas * @param {GraphicsFactory} graphicsFactory * @param {ElementFactory} elementFactory */ function ConnectionPreview(injector, canvas, graphicsFactory, elementFactory) { this._canvas = canvas; this._graphicsFactory = graphicsFactory; this._elementFactory = elementFactory; // optional components this._connectionDocking = injector.get('connectionDocking', false); this._layouter = injector.get('layouter', false); } ConnectionPreview.$inject = ['injector', 'canvas', 'graphicsFactory', 'elementFactory']; /** * Draw connection preview. * * Provide at least one of <source, connectionStart> and <target, connectionEnd> to create a preview. * In the clean up stage, call `connectionPreview#cleanUp` with the context to remove preview. * * @param {Object} context * @param {Object|boolean} canConnect * @param {Object} hints * @param {djs.model.shape} [hints.source] source element * @param {djs.model.shape} [hints.target] target element * @param {Point} [hints.connectionStart] connection preview start * @param {Point} [hints.connectionEnd] connection preview end * @param {Array<Point>} [hints.waypoints] provided waypoints for preview * @param {boolean} [hints.noLayout] true if preview should not be laid out * @param {boolean} [hints.noCropping] true if preview should not be cropped * @param {boolean} [hints.noNoop] true if simple connection should not be drawn */ ConnectionPreview.prototype.drawPreview = function (context, canConnect, hints) { hints = hints || {}; var connectionPreviewGfx = context.connectionPreviewGfx, getConnection = context.getConnection, source = hints.source, target = hints.target, waypoints = hints.waypoints, connectionStart = hints.connectionStart, connectionEnd = hints.connectionEnd, noLayout = hints.noLayout, noCropping = hints.noCropping, noNoop = hints.noNoop, connection; var self = this; if (!connectionPreviewGfx) { connectionPreviewGfx = context.connectionPreviewGfx = this.createConnectionPreviewGfx(); } (0, _tinySvg.clear)(connectionPreviewGfx); if (!getConnection) { getConnection = context.getConnection = cacheReturnValues(function (canConnect, source, target) { return self.getConnection(canConnect, source, target); }); } if (canConnect) { connection = getConnection(canConnect, source, target); } if (!connection) { !noNoop && this.drawNoopPreview(connectionPreviewGfx, hints); return; } connection.waypoints = waypoints || []; // optional layout if (this._layouter && !noLayout) { connection.waypoints = this._layouter.layoutConnection(connection, { source: source, target: target, connectionStart: connectionStart, connectionEnd: connectionEnd, waypoints: hints.waypoints || connection.waypoints }); } // fallback if no waypoints were provided nor created with layouter if (!connection.waypoints || !connection.waypoints.length) { connection.waypoints = [source ? (0, _LayoutUtil.getMid)(source) : connectionStart, target ? (0, _LayoutUtil.getMid)(target) : connectionEnd]; } // optional cropping if (this._connectionDocking && (source || target) && !noCropping) { connection.waypoints = this._connectionDocking.getCroppedWaypoints(connection, source, target); } this._graphicsFactory.drawConnection(connectionPreviewGfx, connection); }; /** * Draw simple connection between source and target or provided points. * * @param {SVGElement} connectionPreviewGfx container for the connection * @param {Object} hints * @param {djs.model.shape} [hints.source] source element * @param {djs.model.shape} [hints.target] target element * @param {Point} [hints.connectionStart] required if source is not provided * @param {Point} [hints.connectionEnd] required if target is not provided */ ConnectionPreview.prototype.drawNoopPreview = function (connectionPreviewGfx, hints) { var source = hints.source, target = hints.target, start = hints.connectionStart || (0, _LayoutUtil.getMid)(source), end = hints.connectionEnd || (0, _LayoutUtil.getMid)(target); var waypoints = this.cropWaypoints(start, end, source, target); var connection = this.createNoopConnection(waypoints[0], waypoints[1]); (0, _tinySvg.append)(connectionPreviewGfx, connection); }; /** * Return cropped waypoints. * * @param {Point} start * @param {Point} end * @param {djs.model.shape} source * @param {djs.model.shape} target * * @returns {Array} */ ConnectionPreview.prototype.cropWaypoints = function (start, end, source, target) { var graphicsFactory = this._graphicsFactory, sourcePath = source && graphicsFactory.getShapePath(source), targetPath = target && graphicsFactory.getShapePath(target), connectionPath = graphicsFactory.getConnectionPath({ waypoints: [start, end] }); start = source && (0, _LayoutUtil.getElementLineIntersection)(sourcePath, connectionPath, true) || start; end = target && (0, _LayoutUtil.getElementLineIntersection)(targetPath, connectionPath, false) || end; return [start, end]; }; /** * Remove connection preview container if it exists. * * @param {Object} [context] * @param {SVGElement} [context.connectionPreviewGfx] preview container */ ConnectionPreview.prototype.cleanUp = function (context) { if (context && context.connectionPreviewGfx) { (0, _tinySvg.remove)(context.connectionPreviewGfx); } }; /** * Get connection that connects source and target. * * @param {Object|boolean} canConnect * * @returns {djs.model.connection} */ ConnectionPreview.prototype.getConnection = function (canConnect) { var attrs = ensureConnectionAttrs(canConnect); return this._elementFactory.createConnection(attrs); }; /** * Add and return preview graphics. * * @returns {SVGElement} */ ConnectionPreview.prototype.createConnectionPreviewGfx = function () { var gfx = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(gfx, { pointerEvents: 'none' }); (0, _tinySvg.classes)(gfx).add(MARKER_CONNECTION_PREVIEW); (0, _tinySvg.append)(this._canvas.getDefaultLayer(), gfx); return gfx; }; /** * Create and return simple connection. * * @param {Point} start * @param {Point} end * * @returns {SVGElement} */ ConnectionPreview.prototype.createNoopConnection = function (start, end) { var connection = (0, _tinySvg.create)('polyline'); (0, _tinySvg.attr)(connection, { 'stroke': '#333', 'strokeDasharray': [1], 'strokeWidth': 2, 'pointer-events': 'none' }); (0, _tinySvg.attr)(connection, { 'points': [start.x, start.y, end.x, end.y] }); return connection; }; // helpers ////////// /** * Returns function that returns cached return values referenced by stringified first argument. * * @param {Function} fn * * @return {Function} */ function cacheReturnValues(fn) { var returnValues = {}; /** * Return cached return value referenced by stringified first argument. * * @returns {*} */ return function (firstArgument) { var key = JSON.stringify(firstArgument); var returnValue = returnValues[key]; if (!returnValue) { returnValue = returnValues[key] = fn.apply(null, arguments); } return returnValue; }; } /** * Ensure connection attributes is object. * * @param {Object|boolean} canConnect * * @returns {Object} */ function ensureConnectionAttrs(canConnect) { if ((0, _minDash.isObject)(canConnect)) { return canConnect; } else { return {}; } } },{"../../layout/LayoutUtil":300,"min-dash":555,"tiny-svg":567}],185:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ConnectionPreview = _interopRequireDefault(require("./ConnectionPreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['connectionPreview'], connectionPreview: ['type', _ConnectionPreview.default] }; exports.default = _default; },{"./ConnectionPreview":184}],186:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ContextPad; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var entrySelector = '.entry'; var DEFAULT_PRIORITY = 1000; /** * A context pad that displays element specific, contextual actions next * to a diagram element. * * @param {Object} config * @param {boolean|Object} [config.scale={ min: 1.0, max: 1.5 }] * @param {number} [config.scale.min] * @param {number} [config.scale.max] * @param {EventBus} eventBus * @param {Overlays} overlays */ function ContextPad(config, eventBus, overlays) { this._eventBus = eventBus; this._overlays = overlays; var scale = (0, _minDash.isDefined)(config && config.scale) ? config.scale : { min: 1, max: 1.5 }; this._overlaysConfig = { position: { right: -9, top: -6 }, scale: scale }; this._current = null; this._init(); } ContextPad.$inject = ['config.contextPad', 'eventBus', 'overlays']; /** * Registers events needed for interaction with other components */ ContextPad.prototype._init = function () { var eventBus = this._eventBus; var self = this; eventBus.on('selection.changed', function (e) { var selection = e.newSelection; if (selection.length === 1) { self.open(selection[0]); } else { self.close(); } }); eventBus.on('elements.delete', function (event) { var elements = event.elements; (0, _minDash.forEach)(elements, function (e) { if (self.isOpen(e)) { self.close(); } }); }); eventBus.on('element.changed', function (event) { var element = event.element, current = self._current; // force reopen if element for which we are currently opened changed if (current && current.element === element) { self.open(element, true); } }); }; /** * Register a provider with the context pad * * @param {number} [priority=1000] * @param {ContextPadProvider} provider * * @example * const contextPadProvider = { * getContextPadEntries: function(element) { * return function(entries) { * return { * ...entries, * 'entry-1': { * label: 'My Entry', * action: function() { alert("I have been clicked!"); } * } * }; * } * } * }; * * contextPad.registerProvider(800, contextPadProvider); */ ContextPad.prototype.registerProvider = function (priority, provider) { if (!provider) { provider = priority; priority = DEFAULT_PRIORITY; } this._eventBus.on('contextPad.getProviders', priority, function (event) { event.providers.push(provider); }); }; /** * Returns the context pad entries for a given element * * @param {djs.element.Base} element * * @return {Array<ContextPadEntryDescriptor>} list of entries */ ContextPad.prototype.getEntries = function (element) { var providers = this._getProviders(); var entries = {}; // loop through all providers and their entries. // group entries by id so that overriding an entry is possible (0, _minDash.forEach)(providers, function (provider) { var entriesOrUpdater = provider.getContextPadEntries(element); if ((0, _minDash.isFunction)(entriesOrUpdater)) { entries = entriesOrUpdater(entries); } else { (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) { entries[id] = entry; }); } }); return entries; }; /** * Trigger an action available on the opened context pad * * @param {string} action * @param {Event} event * @param {boolean} [autoActivate=false] */ ContextPad.prototype.trigger = function (action, event, autoActivate) { var element = this._current.element, entries = this._current.entries, entry, handler, originalEvent, button = event.delegateTarget || event.target; if (!button) { return event.preventDefault(); } entry = entries[(0, _minDom.attr)(button, 'data-action')]; handler = entry.action; originalEvent = event.originalEvent || event; // simple action (via callback function) if ((0, _minDash.isFunction)(handler)) { if (action === 'click') { return handler(originalEvent, element, autoActivate); } } else { if (handler[action]) { return handler[action](originalEvent, element, autoActivate); } } // silence other actions event.preventDefault(); }; /** * Open the context pad for the given element * * @param {djs.model.Base} element * @param {boolean} force if true, force reopening the context pad */ ContextPad.prototype.open = function (element, force) { if (!force && this.isOpen(element)) { return; } this.close(); this._updateAndOpen(element); }; ContextPad.prototype._getProviders = function (id) { var event = this._eventBus.createEvent({ type: 'contextPad.getProviders', providers: [] }); this._eventBus.fire(event); return event.providers; }; ContextPad.prototype._updateAndOpen = function (element) { var entries = this.getEntries(element), pad = this.getPad(element), html = pad.html; (0, _minDash.forEach)(entries, function (entry, id) { var grouping = entry.group || 'default', control = (0, _minDom.domify)(entry.html || '<div class="entry" draggable="true"></div>'), container; (0, _minDom.attr)(control, 'data-action', id); container = (0, _minDom.query)('[data-group=' + grouping + ']', html); if (!container) { container = (0, _minDom.domify)('<div class="group" data-group="' + grouping + '"></div>'); html.appendChild(container); } container.appendChild(control); if (entry.className) { addClasses(control, entry.className); } if (entry.title) { (0, _minDom.attr)(control, 'title', entry.title); } if (entry.imageUrl) { control.appendChild((0, _minDom.domify)('<img src="' + entry.imageUrl + '">')); } }); (0, _minDom.classes)(html).add('open'); this._current = { element: element, pad: pad, entries: entries }; this._eventBus.fire('contextPad.open', { current: this._current }); }; ContextPad.prototype.getPad = function (element) { if (this.isOpen()) { return this._current.pad; } var self = this; var overlays = this._overlays; var html = (0, _minDom.domify)('<div class="djs-context-pad"></div>'); var overlaysConfig = (0, _minDash.assign)({ html: html }, this._overlaysConfig); _minDom.delegate.bind(html, entrySelector, 'click', function (event) { self.trigger('click', event); }); _minDom.delegate.bind(html, entrySelector, 'dragstart', function (event) { self.trigger('dragstart', event); }); // stop propagation of mouse events _minDom.event.bind(html, 'mousedown', function (event) { event.stopPropagation(); }); this._overlayId = overlays.add(element, 'context-pad', overlaysConfig); var pad = overlays.get(this._overlayId); this._eventBus.fire('contextPad.create', { element: element, pad: pad }); return pad; }; /** * Close the context pad */ ContextPad.prototype.close = function () { if (!this.isOpen()) { return; } this._overlays.remove(this._overlayId); this._overlayId = null; this._eventBus.fire('contextPad.close', { current: this._current }); this._current = null; }; /** * Check if pad is open. If element is given, will check * if pad is opened with given element. * * @param {Element} element * @return {boolean} */ ContextPad.prototype.isOpen = function (element) { return !!this._current && (!element ? true : this._current.element === element); }; // helpers ////////////////////// function addClasses(element, classNames) { var classes = (0, _minDom.classes)(element); var actualClassNames = (0, _minDash.isArray)(classNames) ? classNames : classNames.split(/\s+/g); actualClassNames.forEach(function (cls) { classes.add(cls); }); } },{"min-dash":555,"min-dom":556}],187:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("../interaction-events")); var _overlays = _interopRequireDefault(require("../overlays")); var _ContextPad = _interopRequireDefault(require("./ContextPad")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_interactionEvents.default, _overlays.default], contextPad: ['type', _ContextPad.default] }; exports.default = _default; },{"../interaction-events":211,"../overlays":256,"./ContextPad":186}],188:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CopyPaste; var _minDash = require("min-dash"); var _Elements = require("../../util/Elements"); /** * @typedef {Function} <copyPaste.canCopyElements> listener * * @param {Object} context * @param {Array<djs.model.Base>} context.elements * * @returns {Array<djs.model.Base>|boolean} - Return elements to be copied or false to disallow * copying. */ /** * @typedef {Function} <copyPaste.copyElement> listener * * @param {Object} context * @param {Object} context.descriptor * @param {djs.model.Base} context.element * @param {Array<djs.model.Base>} context.elements */ /** * @typedef {Function} <copyPaste.elementsCopied> listener * * @param {Object} context * @param {Object} context.elements * @param {Object} context.tree */ /** * @typedef {Function} <copyPaste.pasteElement> listener * * @param {Object} context * @param {Object} context.cache - Already created elements. * @param {Object} context.descriptor */ /** * @typedef {Function} <copyPaste.pasteElements> listener * * @param {Object} context * @param {Object} context.hints - Add hints before pasting. */ /** * Copy and paste elements. * * @param {Canvas} canvas * @param {Create} create * @param {Clipboard} clipboard * @param {ElementFactory} elementFactory * @param {EventBus} eventBus * @param {Modeling} modeling * @param {Mouse} mouse * @param {Rules} rules */ function CopyPaste(canvas, create, clipboard, elementFactory, eventBus, modeling, mouse, rules) { this._canvas = canvas; this._create = create; this._clipboard = clipboard; this._elementFactory = elementFactory; this._eventBus = eventBus; this._modeling = modeling; this._mouse = mouse; this._rules = rules; eventBus.on('copyPaste.copyElement', function (context) { var descriptor = context.descriptor, element = context.element, elements = context.elements; // default priority (priority = 1) descriptor.priority = 1; descriptor.id = element.id; var parentCopied = (0, _minDash.find)(elements, function (e) { return e === element.parent; }); // do NOT reference parent if parent wasn't copied if (parentCopied) { descriptor.parent = element.parent.id; } // attachers (priority = 2) if (isAttacher(element)) { descriptor.priority = 2; descriptor.host = element.host.id; } // connections (priority = 3) if (isConnection(element)) { descriptor.priority = 3; descriptor.source = element.source.id; descriptor.target = element.target.id; descriptor.waypoints = copyWaypoints(element); } // labels (priority = 4) if (isLabel(element)) { descriptor.priority = 4; descriptor.labelTarget = element.labelTarget.id; } (0, _minDash.forEach)(['x', 'y', 'width', 'height'], function (property) { if ((0, _minDash.isNumber)(element[property])) { descriptor[property] = element[property]; } }); descriptor.hidden = element.hidden; descriptor.collapsed = element.collapsed; }); eventBus.on('copyPaste.pasteElements', function (context) { var hints = context.hints; (0, _minDash.assign)(hints, { createElementsBehavior: false }); }); } CopyPaste.$inject = ['canvas', 'create', 'clipboard', 'elementFactory', 'eventBus', 'modeling', 'mouse', 'rules']; /** * Copy elements. * * @param {Array<djs.model.Base>} elements * * @returns {Object} */ CopyPaste.prototype.copy = function (elements) { var allowed, tree; if (!(0, _minDash.isArray)(elements)) { elements = elements ? [elements] : []; } allowed = this._eventBus.fire('copyPaste.canCopyElements', { elements: elements }); if (allowed === false) { tree = {}; } else { tree = this.createTree((0, _minDash.isArray)(allowed) ? allowed : elements); } // we set an empty tree, selection of elements // to copy was empty. this._clipboard.set(tree); this._eventBus.fire('copyPaste.elementsCopied', { elements: elements, tree: tree }); return tree; }; /** * Paste elements. * * @param {Object} [context] * @param {djs.model.base} [context.element] - Parent. * @param {Point} [context.point] - Position. * @param {Object} [context.hints] - Hints. */ CopyPaste.prototype.paste = function (context) { var tree = this._clipboard.get(); if (this._clipboard.isEmpty()) { return; } var hints = context && context.hints || {}; this._eventBus.fire('copyPaste.pasteElements', { hints: hints }); var elements = this._createElements(tree); // paste directly if (context && context.element && context.point) { return this._paste(elements, context.element, context.point, hints); } this._create.start(this._mouse.getLastMoveEvent(), elements, { hints: hints || {} }); }; /** * Paste elements directly. * * @param {Array<djs.model.Base>} elements * @param {djs.model.base} target * @param {Point} position * @param {Object} [hints] */ CopyPaste.prototype._paste = function (elements, target, position, hints) { // make sure each element has x and y (0, _minDash.forEach)(elements, function (element) { if (!(0, _minDash.isNumber)(element.x)) { element.x = 0; } if (!(0, _minDash.isNumber)(element.y)) { element.y = 0; } }); var bbox = (0, _Elements.getBBox)(elements); // center elements around cursor (0, _minDash.forEach)(elements, function (element) { if (isConnection(element)) { element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint) { return { x: waypoint.x - bbox.x - bbox.width / 2, y: waypoint.y - bbox.y - bbox.height / 2 }; }); } (0, _minDash.assign)(element, { x: element.x - bbox.x - bbox.width / 2, y: element.y - bbox.y - bbox.height / 2 }); }); return this._modeling.createElements(elements, position, target, (0, _minDash.assign)({}, hints)); }; /** * Create elements from tree. */ CopyPaste.prototype._createElements = function (tree) { var self = this; var eventBus = this._eventBus; var cache = {}; var elements = []; (0, _minDash.forEach)(tree, function (branch, depth) { depth = parseInt(depth, 10); // sort by priority branch = (0, _minDash.sortBy)(branch, 'priority'); (0, _minDash.forEach)(branch, function (descriptor) { // remove priority var attrs = (0, _minDash.assign)({}, (0, _minDash.omit)(descriptor, ['priority'])); if (cache[descriptor.parent]) { attrs.parent = cache[descriptor.parent]; } else { delete attrs.parent; } eventBus.fire('copyPaste.pasteElement', { cache: cache, descriptor: attrs }); var element; if (isConnection(attrs)) { attrs.source = cache[descriptor.source]; attrs.target = cache[descriptor.target]; element = cache[descriptor.id] = self.createConnection(attrs); elements.push(element); return; } if (isLabel(attrs)) { attrs.labelTarget = cache[attrs.labelTarget]; element = cache[descriptor.id] = self.createLabel(attrs); elements.push(element); return; } if (attrs.host) { attrs.host = cache[attrs.host]; } element = cache[descriptor.id] = self.createShape(attrs); elements.push(element); }); }); return elements; }; CopyPaste.prototype.createConnection = function (attrs) { var connection = this._elementFactory.createConnection((0, _minDash.omit)(attrs, ['id'])); return connection; }; CopyPaste.prototype.createLabel = function (attrs) { var label = this._elementFactory.createLabel((0, _minDash.omit)(attrs, ['id'])); return label; }; CopyPaste.prototype.createShape = function (attrs) { var shape = this._elementFactory.createShape((0, _minDash.omit)(attrs, ['id'])); return shape; }; /** * Check wether element has relations to other elements e.g. attachers, labels and connections. * * @param {Object} element * @param {Array<djs.model.Base>} elements * * @returns {boolean} */ CopyPaste.prototype.hasRelations = function (element, elements) { var labelTarget, source, target; if (isConnection(element)) { source = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.source.id })); target = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.target.id })); if (!source || !target) { return false; } } if (isLabel(element)) { labelTarget = (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.labelTarget.id })); if (!labelTarget) { return false; } } return true; }; /** * Create a tree-like structure from elements. * * @example * tree: { * 0: [ * { id: 'Shape_1', priority: 1, ... }, * { id: 'Shape_2', priority: 1, ... }, * { id: 'Connection_1', source: 'Shape_1', target: 'Shape_2', priority: 3, ... }, * ... * ], * 1: [ * { id: 'Shape_3', parent: 'Shape1', priority: 1, ... }, * ... * ] * }; * * @param {Array<djs.model.base>} elements * * @return {Object} */ CopyPaste.prototype.createTree = function (elements) { var rules = this._rules, self = this; var tree = {}, elementsData = []; var parents = (0, _Elements.getParents)(elements); function canCopy(element, elements) { return rules.allowed('element.copy', { element: element, elements: elements }); } function addElementData(element, depth) { // (1) check wether element has already been added var foundElementData = (0, _minDash.find)(elementsData, function (elementsData) { return element === elementsData.element; }); // (2) add element if not already added if (!foundElementData) { elementsData.push({ element: element, depth: depth }); return; } // (3) update depth if (foundElementData.depth < depth) { elementsData = removeElementData(foundElementData, elementsData); elementsData.push({ element: foundElementData.element, depth: depth }); } } function removeElementData(elementData, elementsData) { var index = elementsData.indexOf(elementData); if (index !== -1) { elementsData.splice(index, 1); } return elementsData; } // (1) add elements (0, _Elements.eachElement)(parents, function (element, _index, depth) { // do NOT add external labels directly if (isLabel(element)) { return; } // always copy external labels (0, _minDash.forEach)(element.labels, function (label) { addElementData(label, depth); }); function addRelatedElements(elements) { elements && elements.length && (0, _minDash.forEach)(elements, function (element) { // add external labels (0, _minDash.forEach)(element.labels, function (label) { addElementData(label, depth); }); addElementData(element, depth); }); } (0, _minDash.forEach)([element.attachers, element.incoming, element.outgoing], addRelatedElements); addElementData(element, depth); return element.children; }); elements = (0, _minDash.map)(elementsData, function (elementData) { return elementData.element; }); // (2) copy elements elementsData = (0, _minDash.map)(elementsData, function (elementData) { elementData.descriptor = {}; self._eventBus.fire('copyPaste.copyElement', { descriptor: elementData.descriptor, element: elementData.element, elements: elements }); return elementData; }); // (3) sort elements by priority elementsData = (0, _minDash.sortBy)(elementsData, function (elementData) { return elementData.descriptor.priority; }); elements = (0, _minDash.map)(elementsData, function (elementData) { return elementData.element; }); // (4) create tree (0, _minDash.forEach)(elementsData, function (elementData) { var depth = elementData.depth; if (!self.hasRelations(elementData.element, elements)) { removeElement(elementData.element, elements); return; } if (!canCopy(elementData.element, elements)) { removeElement(elementData.element, elements); return; } if (!tree[depth]) { tree[depth] = []; } tree[depth].push(elementData.descriptor); }); return tree; }; // helpers ////////// function isAttacher(element) { return !!element.host; } function isConnection(element) { return !!element.waypoints; } function isLabel(element) { return !!element.labelTarget; } function copyWaypoints(element) { return (0, _minDash.map)(element.waypoints, function (waypoint) { waypoint = copyWaypoint(waypoint); if (waypoint.original) { waypoint.original = copyWaypoint(waypoint.original); } return waypoint; }); } function copyWaypoint(waypoint) { return (0, _minDash.assign)({}, waypoint); } function removeElement(element, elements) { var index = elements.indexOf(element); if (index === -1) { return elements; } return elements.splice(index, 1); } },{"../../util/Elements":315,"min-dash":555}],189:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _clipboard = _interopRequireDefault(require("../clipboard")); var _create = _interopRequireDefault(require("../create")); var _mouse = _interopRequireDefault(require("../mouse")); var _rules = _interopRequireDefault(require("../rules")); var _CopyPaste = _interopRequireDefault(require("./CopyPaste")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_clipboard.default, _create.default, _mouse.default, _rules.default], __init__: ['copyPaste'], copyPaste: ['type', _CopyPaste.default] }; exports.default = _default; },{"../clipboard":180,"../create":192,"../mouse":248,"../rules":272,"./CopyPaste":188}],190:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Create; var _minDash = require("min-dash"); var _Elements = require("../../util/Elements"); var MARKER_OK = 'drop-ok', MARKER_NOT_OK = 'drop-not-ok', MARKER_ATTACH = 'attach-ok', MARKER_NEW_PARENT = 'new-parent'; var PREFIX = 'create'; var HIGH_PRIORITY = 2000; /** * Create new elements through drag and drop. * * @param {Canvas} canvas * @param {Dragging} dragging * @param {EventBus} eventBus * @param {Modeling} modeling * @param {Rules} rules */ function Create(canvas, dragging, eventBus, modeling, rules) { // rules ////////// /** * Check wether elements can be created. * * @param {Array<djs.model.Base>} elements * @param {djs.model.Base} target * @param {Point} position * @param {djs.model.Base} [source] * * @returns {boolean|null|Object} */ function canCreate(elements, target, position, source, hints) { if (!target) { return false; } // ignore child elements and external labels elements = (0, _minDash.filter)(elements, function (element) { var labelTarget = element.labelTarget; return !element.parent && !(isLabel(element) && elements.indexOf(labelTarget) !== -1); }); var shape = (0, _minDash.find)(elements, function (element) { return !isConnection(element); }); var attach = false, connect = false, create = false; // (1) attaching single shapes if (isSingleShape(elements)) { attach = rules.allowed('shape.attach', { position: position, shape: shape, target: target }); } if (!attach) { // (2) creating elements if (isSingleShape(elements)) { create = rules.allowed('shape.create', { position: position, shape: shape, source: source, target: target }); } else { create = rules.allowed('elements.create', { elements: elements, position: position, target: target }); } } var connectionTarget = hints.connectionTarget; // (3) appending single shapes if (create || attach) { if (shape && source) { connect = rules.allowed('connection.create', { source: connectionTarget === source ? shape : source, target: connectionTarget === source ? source : shape, hints: { targetParent: target, targetAttach: attach } }); } return { attach: attach, connect: connect }; } // ignore wether or not elements can be created if (create === null || attach === null) { return null; } return false; } function setMarker(element, marker) { [MARKER_ATTACH, MARKER_OK, MARKER_NOT_OK, MARKER_NEW_PARENT].forEach(function (m) { if (m === marker) { canvas.addMarker(element, m); } else { canvas.removeMarker(element, m); } }); } // event handling ////////// eventBus.on(['create.move', 'create.hover'], function (event) { var context = event.context, elements = context.elements, hover = event.hover, source = context.source, hints = context.hints || {}; if (!hover) { context.canExecute = false; context.target = null; return; } ensureConstraints(event); var position = { x: event.x, y: event.y }; var canExecute = context.canExecute = hover && canCreate(elements, hover, position, source, hints); if (hover && canExecute !== null) { context.target = hover; if (canExecute && canExecute.attach) { setMarker(hover, MARKER_ATTACH); } else { setMarker(hover, canExecute ? MARKER_NEW_PARENT : MARKER_NOT_OK); } } }); eventBus.on(['create.end', 'create.out', 'create.cleanup'], function (event) { var hover = event.hover; if (hover) { setMarker(hover, null); } }); eventBus.on('create.end', function (event) { var context = event.context, source = context.source, shape = context.shape, elements = context.elements, target = context.target, canExecute = context.canExecute, attach = canExecute && canExecute.attach, connect = canExecute && canExecute.connect, hints = context.hints || {}; if (canExecute === false || !target) { return false; } ensureConstraints(event); var position = { x: event.x, y: event.y }; if (connect) { shape = modeling.appendShape(source, shape, position, target, { attach: attach, connection: connect === true ? {} : connect, connectionTarget: hints.connectionTarget }); } else { elements = modeling.createElements(elements, position, target, (0, _minDash.assign)({}, hints, { attach: attach })); // update shape shape = (0, _minDash.find)(elements, function (element) { return !isConnection(element); }); } // update elements and shape (0, _minDash.assign)(context, { elements: elements, shape: shape }); (0, _minDash.assign)(event, { elements: elements, shape: shape }); }); function cancel() { var context = dragging.context(); if (context && context.prefix === PREFIX) { dragging.cancel(); } } // cancel on <elements.changed> that is not result of <drag.end> eventBus.on('create.init', function () { eventBus.on('elements.changed', cancel); eventBus.once(['create.cancel', 'create.end'], HIGH_PRIORITY, function () { eventBus.off('elements.changed', cancel); }); }); // API ////////// this.start = function (event, elements, context) { if (!(0, _minDash.isArray)(elements)) { elements = [elements]; } var shape = (0, _minDash.find)(elements, function (element) { return !isConnection(element); }); if (!shape) { // at least one shape is required return; } context = (0, _minDash.assign)({ elements: elements, hints: {}, shape: shape }, context || {}); // make sure each element has x and y (0, _minDash.forEach)(elements, function (element) { if (!(0, _minDash.isNumber)(element.x)) { element.x = 0; } if (!(0, _minDash.isNumber)(element.y)) { element.y = 0; } }); var bbox = (0, _Elements.getBBox)(elements); // center elements around cursor (0, _minDash.forEach)(elements, function (element) { if (isConnection(element)) { element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint) { return { x: waypoint.x - bbox.x - bbox.width / 2, y: waypoint.y - bbox.y - bbox.height / 2 }; }); } (0, _minDash.assign)(element, { x: element.x - bbox.x - bbox.width / 2, y: element.y - bbox.y - bbox.height / 2 }); }); dragging.init(event, PREFIX, { cursor: 'grabbing', autoActivate: true, data: { shape: shape, elements: elements, context: context } }); }; } Create.$inject = ['canvas', 'dragging', 'eventBus', 'modeling', 'rules']; // helpers ////////// function ensureConstraints(event) { var context = event.context, createConstraints = context.createConstraints; if (!createConstraints) { return; } if (createConstraints.left) { event.x = Math.max(event.x, createConstraints.left); } if (createConstraints.right) { event.x = Math.min(event.x, createConstraints.right); } if (createConstraints.top) { event.y = Math.max(event.y, createConstraints.top); } if (createConstraints.bottom) { event.y = Math.min(event.y, createConstraints.bottom); } } function isConnection(element) { return !!element.waypoints; } function isSingleShape(elements) { return elements && elements.length === 1 && !isConnection(elements[0]); } function isLabel(element) { return !!element.labelTarget; } },{"../../util/Elements":315,"min-dash":555}],191:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreatePreview; var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var _GraphicsUtil = require("../../util/GraphicsUtil"); var _tinySvg = require("tiny-svg"); var LOW_PRIORITY = 750; function CreatePreview(canvas, eventBus, graphicsFactory, previewSupport, styles) { function createDragGroup(elements) { var dragGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events'])); var childrenGfx = (0, _tinySvg.create)('g'); elements.forEach(function (element) { // create graphics var gfx; if (element.hidden) { return; } if (element.waypoints) { gfx = graphicsFactory._createContainer('connection', childrenGfx); graphicsFactory.drawConnection((0, _GraphicsUtil.getVisual)(gfx), element); } else { gfx = graphicsFactory._createContainer('shape', childrenGfx); graphicsFactory.drawShape((0, _GraphicsUtil.getVisual)(gfx), element); (0, _SvgTransformUtil.translate)(gfx, element.x, element.y); } // add preview previewSupport.addDragger(element, dragGroup, gfx); }); return dragGroup; } eventBus.on('create.move', LOW_PRIORITY, function (event) { var hover = event.hover, context = event.context, elements = context.elements, dragGroup = context.dragGroup; // lazily create previews if (!dragGroup) { dragGroup = context.dragGroup = createDragGroup(elements); } var defaultLayer; if (hover) { if (!dragGroup.parentNode) { defaultLayer = canvas.getDefaultLayer(); (0, _tinySvg.append)(defaultLayer, dragGroup); } (0, _SvgTransformUtil.translate)(dragGroup, event.x, event.y); } else { (0, _tinySvg.remove)(dragGroup); } }); eventBus.on('create.cleanup', function (event) { var context = event.context, dragGroup = context.dragGroup; if (dragGroup) { (0, _tinySvg.remove)(dragGroup); } }); } CreatePreview.$inject = ['canvas', 'eventBus', 'graphicsFactory', 'previewSupport', 'styles']; },{"../../util/GraphicsUtil":319,"../../util/SvgTransformUtil":328,"tiny-svg":567}],192:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _previewSupport = _interopRequireDefault(require("../preview-support")); var _rules = _interopRequireDefault(require("../rules")); var _selection = _interopRequireDefault(require("../selection")); var _Create = _interopRequireDefault(require("./Create")); var _CreatePreview = _interopRequireDefault(require("./CreatePreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_dragging.default, _previewSupport.default, _rules.default, _selection.default], __init__: ['create', 'createPreview'], create: ['type', _Create.default], createPreview: ['type', _CreatePreview.default] }; exports.default = _default; },{"../dragging":197,"../preview-support":262,"../rules":272,"../selection":278,"./Create":190,"./CreatePreview":191}],193:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DistributeElements; var _minDash = require("min-dash"); var AXIS_DIMENSIONS = { horizontal: ['x', 'width'], vertical: ['y', 'height'] }; var THRESHOLD = 5; /** * Groups and filters elements and then trigger even distribution. */ function DistributeElements(modeling) { this._modeling = modeling; this._filters = []; // register filter for filtering big elements this.registerFilter(function (elements, axis, dimension) { var elementsSize = 0, numOfShapes = 0, avgDimension; (0, _minDash.forEach)(elements, function (element) { if (element.waypoints || element.labelTarget) { return; } elementsSize += element[dimension]; numOfShapes += 1; }); avgDimension = Math.round(elementsSize / numOfShapes); return (0, _minDash.filter)(elements, function (element) { return element[dimension] < avgDimension + 50; }); }); } DistributeElements.$inject = ['modeling']; /** * Registers filter functions that allow external parties to filter * out certain elements. * * @param {Function} filterFn */ DistributeElements.prototype.registerFilter = function (filterFn) { if (typeof filterFn !== 'function') { throw new Error('the filter has to be a function'); } this._filters.push(filterFn); }; /** * Distributes the elements with a given orientation * * @param {Array} elements [description] * @param {string} orientation [description] */ DistributeElements.prototype.trigger = function (elements, orientation) { var modeling = this._modeling; var groups, distributableElements; if (elements.length < 3) { return; } this._setOrientation(orientation); distributableElements = this._filterElements(elements); groups = this._createGroups(distributableElements); // nothing to distribute if (groups.length <= 2) { return; } modeling.distributeElements(groups, this._axis, this._dimension); return groups; }; /** * Filters the elements with provided filters by external parties * * @param {Array[Elements]} elements * * @return {Array[Elements]} */ DistributeElements.prototype._filterElements = function (elements) { var filters = this._filters, axis = this._axis, dimension = this._dimension, distributableElements = [].concat(elements); if (!filters.length) { return elements; } (0, _minDash.forEach)(filters, function (filterFn) { distributableElements = filterFn(distributableElements, axis, dimension); }); return distributableElements; }; /** * Create range (min, max) groups. Also tries to group elements * together that share the same range. * * @example * var distributableElements = [ * { * range: { * min: 100, * max: 200 * }, * elements: [ { id: 'shape1', .. }] * } * ] * * @param {Array} elements * * @return {Array[Objects]} */ DistributeElements.prototype._createGroups = function (elements) { var rangeGroups = [], self = this, axis = this._axis, dimension = this._dimension; if (!axis) { throw new Error('must have a defined "axis" and "dimension"'); } // sort by 'left->right' or 'top->bottom' var sortedElements = (0, _minDash.sortBy)(elements, axis); (0, _minDash.forEach)(sortedElements, function (element, idx) { var elementRange = self._findRange(element, axis, dimension), range; var previous = rangeGroups[rangeGroups.length - 1]; if (previous && self._hasIntersection(previous.range, elementRange)) { rangeGroups[rangeGroups.length - 1].elements.push(element); } else { range = { range: elementRange, elements: [element] }; rangeGroups.push(range); } }); return rangeGroups; }; /** * Maps a direction to the according axis and dimension * * @param {string} direction 'horizontal' or 'vertical' */ DistributeElements.prototype._setOrientation = function (direction) { var orientation = AXIS_DIMENSIONS[direction]; this._axis = orientation[0]; this._dimension = orientation[1]; }; /** * Checks if the two ranges intercept each other * * @param {Object} rangeA {min, max} * @param {Object} rangeB {min, max} * * @return {boolean} */ DistributeElements.prototype._hasIntersection = function (rangeA, rangeB) { return Math.max(rangeA.min, rangeA.max) >= Math.min(rangeB.min, rangeB.max) && Math.min(rangeA.min, rangeA.max) <= Math.max(rangeB.min, rangeB.max); }; /** * Returns the min and max values for an element * * @param {[type]} element [description] * @param {[type]} axis [description] * @param {[type]} dimension [description] * * @return {[type]} [description] */ DistributeElements.prototype._findRange = function (element) { var axis = element[this._axis], dimension = element[this._dimension]; return { min: axis + THRESHOLD, max: axis + dimension - THRESHOLD }; }; },{"min-dash":555}],194:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _DistributeElements = _interopRequireDefault(require("./DistributeElements")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['distributeElements'], distributeElements: ['type', _DistributeElements.default] }; exports.default = _default; },{"./DistributeElements":193}],195:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Dragging; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _Event = require("../../util/Event"); var _Cursor = require("../../util/Cursor"); var _ClickTrap = require("../../util/ClickTrap"); var _PositionUtil = require("../../util/PositionUtil"); /* global TouchEvent */ var round = Math.round; var DRAG_ACTIVE_CLS = 'djs-drag-active'; function preventDefault(event) { event.preventDefault(); } function isTouchEvent(event) { // check for TouchEvent being available first // (i.e. not available on desktop Firefox) return typeof TouchEvent !== 'undefined' && event instanceof TouchEvent; } function getLength(point) { return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2)); } /** * A helper that fires canvas localized drag events and realizes * the general "drag-and-drop" look and feel. * * Calling {@link Dragging#activate} activates dragging on a canvas. * * It provides the following: * * * emits life cycle events, namespaced with a prefix assigned * during dragging activation * * sets and restores the cursor * * sets and restores the selection if elements still exist * * ensures there can be only one drag operation active at a time * * Dragging may be canceled manually by calling {@link Dragging#cancel} * or by pressing ESC. * * * ## Life-cycle events * * Dragging can be in three different states, off, initialized * and active. * * (1) off: no dragging operation is in progress * (2) initialized: a new drag operation got initialized but not yet * started (i.e. because of no initial move) * (3) started: dragging is in progress * * Eventually dragging will be off again after a drag operation has * been ended or canceled via user click or ESC key press. * * To indicate transitions between these states dragging emits generic * life-cycle events with the `drag.` prefix _and_ events namespaced * to a prefix choosen by a user during drag initialization. * * The following events are emitted (appropriately prefixed) via * the {@link EventBus}. * * * `init` * * `start` * * `move` * * `end` * * `ended` (dragging already in off state) * * `cancel` (only if previously started) * * `canceled` (dragging already in off state, only if previously started) * * `cleanup` * * * @example * * function MyDragComponent(eventBus, dragging) { * * eventBus.on('mydrag.start', function(event) { * console.log('yes, we start dragging'); * }); * * eventBus.on('mydrag.move', function(event) { * console.log('canvas local coordinates', event.x, event.y, event.dx, event.dy); * * // local drag data is passed with the event * event.context.foo; // "BAR" * * // the original mouse event, too * event.originalEvent; // MouseEvent(...) * }); * * eventBus.on('element.click', function(event) { * dragging.init(event, 'mydrag', { * cursor: 'grabbing', * data: { * context: { * foo: "BAR" * } * } * }); * }); * } */ function Dragging(eventBus, canvas, selection, elementRegistry) { var defaultOptions = { threshold: 5, trapClick: true }; // the currently active drag operation // dragging is active as soon as this context exists. // // it is visually _active_ only when a context.active flag is set to true. var context; /* convert a global event into local coordinates */ function toLocalPoint(globalPosition) { var viewbox = canvas.viewbox(); var clientRect = canvas._container.getBoundingClientRect(); return { x: viewbox.x + (globalPosition.x - clientRect.left) / viewbox.scale, y: viewbox.y + (globalPosition.y - clientRect.top) / viewbox.scale }; } // helpers function fire(type, dragContext) { dragContext = dragContext || context; var event = eventBus.createEvent((0, _minDash.assign)({}, dragContext.payload, dragContext.data, { isTouch: dragContext.isTouch })); // default integration if (eventBus.fire('drag.' + type, event) === false) { return false; } return eventBus.fire(dragContext.prefix + '.' + type, event); } function restoreSelection(previousSelection) { var existingSelection = previousSelection.filter(function (element) { return elementRegistry.get(element.id); }); existingSelection.length && selection.select(existingSelection); } // event listeners function move(event, activate) { var payload = context.payload, displacement = context.displacement; var globalStart = context.globalStart, globalCurrent = (0, _Event.toPoint)(event), globalDelta = (0, _PositionUtil.delta)(globalCurrent, globalStart); var localStart = context.localStart, localCurrent = toLocalPoint(globalCurrent), localDelta = (0, _PositionUtil.delta)(localCurrent, localStart); // activate context explicitly or once threshold is reached if (!context.active && (activate || getLength(globalDelta) > context.threshold)) { // fire start event with original // starting coordinates (0, _minDash.assign)(payload, { x: round(localStart.x + displacement.x), y: round(localStart.y + displacement.y), dx: 0, dy: 0 }, { originalEvent: event }); if (false === fire('start')) { return cancel(); } context.active = true; // unset selection and remember old selection // the previous (old) selection will always passed // with the event via the event.previousSelection property if (!context.keepSelection) { payload.previousSelection = selection.get(); selection.select(null); } // allow custom cursor if (context.cursor) { (0, _Cursor.set)(context.cursor); } // indicate dragging via marker on root element canvas.addMarker(canvas.getRootElement(), DRAG_ACTIVE_CLS); } (0, _Event.stopPropagation)(event); if (context.active) { // update payload with actual coordinates (0, _minDash.assign)(payload, { x: round(localCurrent.x + displacement.x), y: round(localCurrent.y + displacement.y), dx: round(localDelta.x), dy: round(localDelta.y) }, { originalEvent: event }); // emit move event fire('move'); } } function end(event) { var previousContext, returnValue = true; if (context.active) { if (event) { context.payload.originalEvent = event; // suppress original event (click, ...) // because we just ended a drag operation (0, _Event.stopPropagation)(event); } // implementations may stop restoring the // original state (selections, ...) by preventing the // end events default action returnValue = fire('end'); } if (returnValue === false) { fire('rejected'); } previousContext = cleanup(returnValue !== true); // last event to be fired when all drag operations are done // at this point in time no drag operation is in progress anymore fire('ended', previousContext); } // cancel active drag operation if the user presses // the ESC key on the keyboard function checkCancel(event) { if (event.which === 27) { preventDefault(event); cancel(); } } // prevent ghost click that might occur after a finished // drag and drop session function trapClickAndEnd(event) { var untrap; // trap the click in case we are part of an active // drag operation. This will effectively prevent // the ghost click that cannot be canceled otherwise. if (context.active) { untrap = (0, _ClickTrap.install)(eventBus); // remove trap after minimal delay setTimeout(untrap, 400); // prevent default action (click) preventDefault(event); } end(event); } function trapTouch(event) { move(event); } // update the drag events hover (djs.model.Base) and hoverGfx (Snap<SVGElement>) // properties during hover and out and fire {prefix}.hover and {prefix}.out properties // respectively function hover(event) { var payload = context.payload; payload.hoverGfx = event.gfx; payload.hover = event.element; fire('hover'); } function out(event) { fire('out'); var payload = context.payload; payload.hoverGfx = null; payload.hover = null; } // life-cycle methods function cancel(restore) { var previousContext; if (!context) { return; } var wasActive = context.active; if (wasActive) { fire('cancel'); } previousContext = cleanup(restore); if (wasActive) { // last event to be fired when all drag operations are done // at this point in time no drag operation is in progress anymore fire('canceled', previousContext); } } function cleanup(restore) { var previousContext, endDrag; fire('cleanup'); // reset cursor (0, _Cursor.unset)(); if (context.trapClick) { endDrag = trapClickAndEnd; } else { endDrag = end; } // reset dom listeners _minDom.event.unbind(document, 'mousemove', move); _minDom.event.unbind(document, 'dragstart', preventDefault); _minDom.event.unbind(document, 'selectstart', preventDefault); _minDom.event.unbind(document, 'mousedown', endDrag, true); _minDom.event.unbind(document, 'mouseup', endDrag, true); _minDom.event.unbind(document, 'keyup', checkCancel); _minDom.event.unbind(document, 'touchstart', trapTouch, true); _minDom.event.unbind(document, 'touchcancel', cancel, true); _minDom.event.unbind(document, 'touchmove', move, true); _minDom.event.unbind(document, 'touchend', end, true); eventBus.off('element.hover', hover); eventBus.off('element.out', out); // remove drag marker on root element canvas.removeMarker(canvas.getRootElement(), DRAG_ACTIVE_CLS); // restore selection, unless it has changed var previousSelection = context.payload.previousSelection; if (restore !== false && previousSelection && !selection.get().length) { restoreSelection(previousSelection); } previousContext = context; context = null; return previousContext; } /** * Initialize a drag operation. * * If `localPosition` is given, drag events will be emitted * relative to it. * * @param {MouseEvent|TouchEvent} [event] * @param {Point} [localPosition] actual diagram local position this drag operation should start at * @param {string} prefix * @param {Object} [options] */ function init(event, relativeTo, prefix, options) { // only one drag operation may be active, at a time if (context) { cancel(false); } if (typeof relativeTo === 'string') { options = prefix; prefix = relativeTo; relativeTo = null; } options = (0, _minDash.assign)({}, defaultOptions, options || {}); var data = options.data || {}, originalEvent, globalStart, localStart, endDrag, isTouch; if (options.trapClick) { endDrag = trapClickAndEnd; } else { endDrag = end; } if (event) { originalEvent = (0, _Event.getOriginal)(event) || event; globalStart = (0, _Event.toPoint)(event); (0, _Event.stopPropagation)(event); // prevent default browser dragging behavior if (originalEvent.type === 'dragstart') { preventDefault(originalEvent); } } else { originalEvent = null; globalStart = { x: 0, y: 0 }; } localStart = toLocalPoint(globalStart); if (!relativeTo) { relativeTo = localStart; } isTouch = isTouchEvent(originalEvent); context = (0, _minDash.assign)({ prefix: prefix, data: data, payload: {}, globalStart: globalStart, displacement: (0, _PositionUtil.delta)(relativeTo, localStart), localStart: localStart, isTouch: isTouch }, options); // skip dom registration if trigger // is set to manual (during testing) if (!options.manual) { // add dom listeners if (isTouch) { _minDom.event.bind(document, 'touchstart', trapTouch, true); _minDom.event.bind(document, 'touchcancel', cancel, true); _minDom.event.bind(document, 'touchmove', move, true); _minDom.event.bind(document, 'touchend', end, true); } else { // assume we use the mouse to interact per default _minDom.event.bind(document, 'mousemove', move); // prevent default browser drag and text selection behavior _minDom.event.bind(document, 'dragstart', preventDefault); _minDom.event.bind(document, 'selectstart', preventDefault); _minDom.event.bind(document, 'mousedown', endDrag, true); _minDom.event.bind(document, 'mouseup', endDrag, true); } _minDom.event.bind(document, 'keyup', checkCancel); eventBus.on('element.hover', hover); eventBus.on('element.out', out); } fire('init'); if (options.autoActivate) { move(event, true); } } // cancel on diagram destruction eventBus.on('diagram.destroy', cancel); // API this.init = init; this.move = move; this.hover = hover; this.out = out; this.end = end; this.cancel = cancel; // for introspection this.context = function () { return context; }; this.setOptions = function (options) { (0, _minDash.assign)(defaultOptions, options); }; } Dragging.$inject = ['eventBus', 'canvas', 'selection', 'elementRegistry']; },{"../../util/ClickTrap":312,"../../util/Cursor":314,"../../util/Event":317,"../../util/PositionUtil":325,"min-dash":555,"min-dom":556}],196:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = HoverFix; var _minDom = require("min-dom"); var _Event = require("../../util/Event"); var HIGH_PRIORITY = 1500; /** * Browsers may swallow certain events (hover, out ...) if users are to * fast with the mouse. * * @see http://stackoverflow.com/questions/7448468/why-cant-i-reliably-capture-a-mouseout-event * * The fix implemented in this component ensure that we * * 1) have a hover state after a successful drag.move event * 2) have an out event when dragging leaves an element * * @param {EventBus} eventBus * @param {Dragging} dragging * @param {ElementRegistry} elementRegistry */ function HoverFix(eventBus, dragging, elementRegistry) { var self = this; /** * Make sure we are god damn hovering! * * @param {Event} dragging event */ function ensureHover(event) { if (event.hover) { return; } var originalEvent = event.originalEvent; var gfx = self._findTargetGfx(originalEvent); var element = gfx && elementRegistry.get(gfx); if (gfx && element) { // 1) cancel current mousemove event.stopPropagation(); // 2) emit fake hover for new target dragging.hover({ element: element, gfx: gfx }); // 3) re-trigger move event dragging.move(originalEvent); } } /** * We wait for a specific sequence of events before * emitting a fake drag.hover event. * * Event Sequence: * * drag.start * drag.move >> ensure we are hovering */ eventBus.on('drag.start', function (event) { eventBus.once('drag.move', HIGH_PRIORITY, function (event) { ensureHover(event); }); }); /** * We make sure that drag.out is always fired, even if the * browser swallows an element.out event. * * Event sequence: * * drag.hover * (element.out >> sometimes swallowed) * element.hover >> ensure we fired drag.out */ eventBus.on('drag.init', function () { var hover, hoverGfx; function setDragHover(event) { hover = event.hover; hoverGfx = event.hoverGfx; } function unsetHover() { hover = null; hoverGfx = null; } function ensureOut() { if (!hover) { return; } var element = hover, gfx = hoverGfx; hover = null; hoverGfx = null; // emit synthetic out event dragging.out({ element: element, gfx: gfx }); } eventBus.on('drag.hover', setDragHover); eventBus.on('element.out', unsetHover); eventBus.on('element.hover', HIGH_PRIORITY, ensureOut); eventBus.once('drag.cleanup', function () { eventBus.off('drag.hover', setDragHover); eventBus.off('element.out', unsetHover); eventBus.off('element.hover', ensureOut); }); }); this._findTargetGfx = function (event) { var position, target; if (!(event instanceof MouseEvent)) { return; } position = (0, _Event.toPoint)(event); // damn expensive operation, ouch! target = document.elementFromPoint(position.x, position.y); return getGfx(target); }; } HoverFix.$inject = ['eventBus', 'dragging', 'elementRegistry']; // helpers ///////////////////// function getGfx(target) { return (0, _minDom.closest)(target, 'svg, .djs-element', true); } },{"../../util/Event":317,"min-dom":556}],197:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _selection = _interopRequireDefault(require("../selection")); var _Dragging = _interopRequireDefault(require("./Dragging")); var _HoverFix = _interopRequireDefault(require("./HoverFix")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['hoverFix'], __depends__: [_selection.default], dragging: ['type', _Dragging.default], hoverFix: ['type', _HoverFix.default] }; exports.default = _default; },{"../selection":278,"./Dragging":195,"./HoverFix":196}],198:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = EditorActions; var _minDash = require("min-dash"); var NOT_REGISTERED_ERROR = 'is not a registered action', IS_REGISTERED_ERROR = 'is already registered'; /** * An interface that provides access to modeling actions by decoupling * the one who requests the action to be triggered and the trigger itself. * * It's possible to add new actions by registering them with ´registerAction´ * and likewise unregister existing ones with ´unregisterAction´. * * * ## Life-Cycle and configuration * * The editor actions will wait for diagram initialization before * registering default actions _and_ firing an `editorActions.init` event. * * Interested parties may listen to the `editorActions.init` event with * low priority to check, which actions got registered. Other components * may use the event to register their own actions via `registerAction`. * * @param {EventBus} eventBus * @param {Injector} injector */ function EditorActions(eventBus, injector) { // initialize actions this._actions = {}; var self = this; eventBus.on('diagram.init', function () { // all diagram modules got loaded; check which ones // are available and register the respective default actions self._registerDefaultActions(injector); // ask interested parties to register available editor // actions on diagram initialization eventBus.fire('editorActions.init', { editorActions: self }); }); } EditorActions.$inject = ['eventBus', 'injector']; /** * Register default actions. * * @param {Injector} injector */ EditorActions.prototype._registerDefaultActions = function (injector) { // (1) retrieve optional components to integrate with var commandStack = injector.get('commandStack', false); var modeling = injector.get('modeling', false); var selection = injector.get('selection', false); var zoomScroll = injector.get('zoomScroll', false); var copyPaste = injector.get('copyPaste', false); var canvas = injector.get('canvas', false); var rules = injector.get('rules', false); var keyboardMove = injector.get('keyboardMove', false); var keyboardMoveSelection = injector.get('keyboardMoveSelection', false); // (2) check components and register actions if (commandStack) { this.register('undo', function () { commandStack.undo(); }); this.register('redo', function () { commandStack.redo(); }); } if (copyPaste && selection) { this.register('copy', function () { var selectedElements = selection.get(); copyPaste.copy(selectedElements); }); } if (copyPaste) { this.register('paste', function () { copyPaste.paste(); }); } if (zoomScroll) { this.register('stepZoom', function (opts) { zoomScroll.stepZoom(opts.value); }); } if (canvas) { this.register('zoom', function (opts) { canvas.zoom(opts.value); }); } if (modeling && selection && rules) { this.register('removeSelection', function () { var selectedElements = selection.get(); if (!selectedElements.length) { return; } var allowed = rules.allowed('elements.delete', { elements: selectedElements }), removableElements; if (allowed === false) { return; } else if ((0, _minDash.isArray)(allowed)) { removableElements = allowed; } else { removableElements = selectedElements; } if (removableElements.length) { modeling.removeElements(removableElements.slice()); } }); } if (keyboardMove) { this.register('moveCanvas', function (opts) { keyboardMove.moveCanvas(opts); }); } if (keyboardMoveSelection) { this.register('moveSelection', function (opts) { keyboardMoveSelection.moveSelection(opts.direction, opts.accelerated); }); } }; /** * Triggers a registered action * * @param {string} action * @param {Object} opts * * @return {Unknown} Returns what the registered listener returns */ EditorActions.prototype.trigger = function (action, opts) { if (!this._actions[action]) { throw error(action, NOT_REGISTERED_ERROR); } return this._actions[action](opts); }; /** * Registers a collections of actions. * The key of the object will be the name of the action. * * @example * ´´´ * var actions = { * spaceTool: function() { * spaceTool.activateSelection(); * }, * lassoTool: function() { * lassoTool.activateSelection(); * } * ]; * * editorActions.register(actions); * * editorActions.isRegistered('spaceTool'); // true * ´´´ * * @param {Object} actions */ EditorActions.prototype.register = function (actions, listener) { var self = this; if (typeof actions === 'string') { return this._registerAction(actions, listener); } (0, _minDash.forEach)(actions, function (listener, action) { self._registerAction(action, listener); }); }; /** * Registers a listener to an action key * * @param {string} action * @param {Function} listener */ EditorActions.prototype._registerAction = function (action, listener) { if (this.isRegistered(action)) { throw error(action, IS_REGISTERED_ERROR); } this._actions[action] = listener; }; /** * Unregister an existing action * * @param {string} action */ EditorActions.prototype.unregister = function (action) { if (!this.isRegistered(action)) { throw error(action, NOT_REGISTERED_ERROR); } this._actions[action] = undefined; }; /** * Returns the number of actions that are currently registered * * @return {number} */ EditorActions.prototype.getActions = function () { return Object.keys(this._actions); }; /** * Checks wether the given action is registered * * @param {string} action * * @return {boolean} */ EditorActions.prototype.isRegistered = function (action) { return !!this._actions[action]; }; function error(action, message) { return new Error(action + ' ' + message); } },{"min-dash":555}],199:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _EditorActions = _interopRequireDefault(require("./EditorActions")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['editorActions'], editorActions: ['type', _EditorActions.default] }; exports.default = _default; },{"./EditorActions":198}],200:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = GlobalConnect; var MARKER_OK = 'connect-ok', MARKER_NOT_OK = 'connect-not-ok'; /** * @class * @constructor * * @param {EventBus} eventBus * @param {Dragging} dragging * @param {Connect} connect * @param {Canvas} canvas * @param {ToolManager} toolManager * @param {Rules} rules */ function GlobalConnect(eventBus, dragging, connect, canvas, toolManager, rules) { var self = this; this._dragging = dragging; this._rules = rules; toolManager.registerTool('global-connect', { tool: 'global-connect', dragging: 'global-connect.drag' }); eventBus.on('global-connect.hover', function (event) { var context = event.context, startTarget = event.hover; var canStartConnect = context.canStartConnect = self.canStartConnect(startTarget); // simply ignore hover if (canStartConnect === null) { return; } context.startTarget = startTarget; canvas.addMarker(startTarget, canStartConnect ? MARKER_OK : MARKER_NOT_OK); }); eventBus.on(['global-connect.out', 'global-connect.cleanup'], function (event) { var startTarget = event.context.startTarget, canStartConnect = event.context.canStartConnect; if (startTarget) { canvas.removeMarker(startTarget, canStartConnect ? MARKER_OK : MARKER_NOT_OK); } }); eventBus.on(['global-connect.ended'], function (event) { var context = event.context, startTarget = context.startTarget, startPosition = { x: event.x, y: event.y }; var canStartConnect = self.canStartConnect(startTarget); if (!canStartConnect) { return; } eventBus.once('element.out', function () { eventBus.once(['connect.ended', 'connect.canceled'], function () { eventBus.fire('global-connect.drag.ended'); }); connect.start(null, startTarget, startPosition); }); return false; }); } GlobalConnect.$inject = ['eventBus', 'dragging', 'connect', 'canvas', 'toolManager', 'rules']; /** * Initiates tool activity. */ GlobalConnect.prototype.start = function (event) { this._dragging.init(event, 'global-connect', { trapClick: false, data: { context: {} } }); }; GlobalConnect.prototype.toggle = function () { if (this.isActive()) { this._dragging.cancel(); } else { this.start(); } }; GlobalConnect.prototype.isActive = function () { var context = this._dragging.context(); return context && /^global-connect/.test(context.prefix); }; /** * Check if source shape can initiate connection. * * @param {Shape} startTarget * @return {boolean} */ GlobalConnect.prototype.canStartConnect = function (startTarget) { return this._rules.allowed('connection.start', { source: startTarget }); }; },{}],201:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _connect = _interopRequireDefault(require("../connect")); var _rules = _interopRequireDefault(require("../rules")); var _dragging = _interopRequireDefault(require("../dragging")); var _toolManager = _interopRequireDefault(require("../tool-manager")); var _GlobalConnect = _interopRequireDefault(require("./GlobalConnect")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_connect.default, _rules.default, _dragging.default, _toolManager.default], globalConnect: ['type', _GlobalConnect.default] }; exports.default = _default; },{"../connect":183,"../dragging":197,"../rules":272,"../tool-manager":290,"./GlobalConnect":200}],202:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = GridSnapping; var _SnapUtil = require("../snapping/SnapUtil"); var _KeyboardUtil = require("../keyboard/KeyboardUtil"); var _minDash = require("min-dash"); var _GridUtil = require("./GridUtil"); var LOWER_PRIORITY = 1200; var LOW_PRIORITY = 800; /** * Basic grid snapping that covers connecting, creating, moving, resizing shapes, moving bendpoints * and connection segments. */ function GridSnapping(elementRegistry, eventBus, config) { var active = !config || config.active !== false; this._eventBus = eventBus; var self = this; eventBus.on('diagram.init', LOW_PRIORITY, function () { self.setActive(active); }); eventBus.on(['create.move', 'create.end', 'bendpoint.move.move', 'bendpoint.move.end', 'connect.move', 'connect.end', 'connectionSegment.move.move', 'connectionSegment.move.end', 'resize.move', 'resize.end', 'shape.move.move', 'shape.move.end'], LOWER_PRIORITY, function (event) { var originalEvent = event.originalEvent; if (!self.active || originalEvent && (0, _KeyboardUtil.isCmd)(originalEvent)) { return; } var context = event.context, gridSnappingContext = context.gridSnappingContext; if (!gridSnappingContext) { gridSnappingContext = context.gridSnappingContext = {}; } ['x', 'y'].forEach(function (axis) { var options = {}; // allow snapping with offset var snapOffset = getSnapOffset(event, axis, elementRegistry); if (snapOffset) { options.offset = snapOffset; } // allow snapping with min and max var snapConstraints = getSnapConstraints(event, axis); if (snapConstraints) { (0, _minDash.assign)(options, snapConstraints); } if (!(0, _SnapUtil.isSnapped)(event, axis)) { self.snapEvent(event, axis, options); } }); }); } /** * Snap an events x or y with optional min, max and offset. * * @param {Object} event * @param {string} axis * @param {number} [options.min] * @param {number} [options.max] * @param {number} [options.offset] */ GridSnapping.prototype.snapEvent = function (event, axis, options) { var snappedValue = this.snapValue(event[axis], options); (0, _SnapUtil.setSnapped)(event, axis, snappedValue); }; /** * Expose grid spacing for third parties (i.e. extensions). * * @return {number} spacing of grid dots */ GridSnapping.prototype.getGridSpacing = function () { return _GridUtil.SPACING; }; /** * Snap value with optional min, max and offset. * * @param {number} value * @param {Object} options * @param {number} [options.min] * @param {number} [options.max] * @param {number} [options.offset] */ GridSnapping.prototype.snapValue = function (value, options) { var offset = 0; if (options && options.offset) { offset = options.offset; } value += offset; value = (0, _GridUtil.quantize)(value, _GridUtil.SPACING); var min, max; if (options && options.min) { min = options.min; if ((0, _minDash.isNumber)(min)) { min = (0, _GridUtil.quantize)(min + offset, _GridUtil.SPACING, 'ceil'); value = Math.max(value, min); } } if (options && options.max) { max = options.max; if ((0, _minDash.isNumber)(max)) { max = (0, _GridUtil.quantize)(max + offset, _GridUtil.SPACING, 'floor'); value = Math.min(value, max); } } value -= offset; return value; }; GridSnapping.prototype.isActive = function () { return this.active; }; GridSnapping.prototype.setActive = function (active) { this.active = active; this._eventBus.fire('gridSnapping.toggle', { active: active }); }; GridSnapping.prototype.toggleActive = function () { this.setActive(!this.active); }; GridSnapping.$inject = ['elementRegistry', 'eventBus', 'config.gridSnapping']; // helpers ////////// /** * Get minimum and maximum snap constraints. * Constraints are cached. * * @param {Object} event * @param {Object} event.context * @param {string} axis * * @returns {boolean|Object} */ function getSnapConstraints(event, axis) { var context = event.context, createConstraints = context.createConstraints, resizeConstraints = context.resizeConstraints || {}, gridSnappingContext = context.gridSnappingContext, snapConstraints = gridSnappingContext.snapConstraints; // cache snap constraints if (snapConstraints && snapConstraints[axis]) { return snapConstraints[axis]; } if (!snapConstraints) { snapConstraints = gridSnappingContext.snapConstraints = {}; } if (!snapConstraints[axis]) { snapConstraints[axis] = {}; } var direction = context.direction; // create if (createConstraints) { if (isHorizontal(axis)) { snapConstraints.x.min = createConstraints.left; snapConstraints.x.max = createConstraints.right; } else { snapConstraints.y.min = createConstraints.top; snapConstraints.y.max = createConstraints.bottom; } } // resize var minResizeConstraints = resizeConstraints.min, maxResizeConstraints = resizeConstraints.max; if (minResizeConstraints) { if (isHorizontal(axis)) { if (isWest(direction)) { snapConstraints.x.max = minResizeConstraints.left; } else { snapConstraints.x.min = minResizeConstraints.right; } } else { if (isNorth(direction)) { snapConstraints.y.max = minResizeConstraints.top; } else { snapConstraints.y.min = minResizeConstraints.bottom; } } } if (maxResizeConstraints) { if (isHorizontal(axis)) { if (isWest(direction)) { snapConstraints.x.min = maxResizeConstraints.left; } else { snapConstraints.x.max = maxResizeConstraints.right; } } else { if (isNorth(direction)) { snapConstraints.y.min = maxResizeConstraints.top; } else { snapConstraints.y.max = maxResizeConstraints.bottom; } } } return snapConstraints[axis]; } /** * Get snap offset. * Offset is cached. * * @param {Object} event * @param {string} axis * @param {ElementRegistry} elementRegistry * * @returns {number} */ function getSnapOffset(event, axis, elementRegistry) { var context = event.context, shape = event.shape, gridSnappingContext = context.gridSnappingContext, snapLocation = gridSnappingContext.snapLocation, snapOffset = gridSnappingContext.snapOffset; // cache snap offset if (snapOffset && (0, _minDash.isNumber)(snapOffset[axis])) { return snapOffset[axis]; } if (!snapOffset) { snapOffset = gridSnappingContext.snapOffset = {}; } if (!(0, _minDash.isNumber)(snapOffset[axis])) { snapOffset[axis] = 0; } if (!shape) { return snapOffset[axis]; } if (!elementRegistry.get(shape.id)) { if (isHorizontal(axis)) { snapOffset[axis] += shape[axis] + shape.width / 2; } else { snapOffset[axis] += shape[axis] + shape.height / 2; } } if (!snapLocation) { return snapOffset[axis]; } if (axis === 'x') { if (/left/.test(snapLocation)) { snapOffset[axis] -= shape.width / 2; } else if (/right/.test(snapLocation)) { snapOffset[axis] += shape.width / 2; } } else { if (/top/.test(snapLocation)) { snapOffset[axis] -= shape.height / 2; } else if (/bottom/.test(snapLocation)) { snapOffset[axis] += shape.height / 2; } } return snapOffset[axis]; } function isHorizontal(axis) { return axis === 'x'; } function isNorth(direction) { return direction.indexOf('n') !== -1; } function isWest(direction) { return direction.indexOf('w') !== -1; } },{"../keyboard/KeyboardUtil":216,"../snapping/SnapUtil":282,"./GridUtil":203,"min-dash":555}],203:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.quantize = quantize; exports.SPACING = void 0; var SPACING = 10; exports.SPACING = SPACING; function quantize(value, quantum, fn) { if (!fn) { fn = 'round'; } return Math[fn](value / quantum) * quantum; } },{}],204:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeBehavior; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("../../../command/CommandInterceptor")); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Integrates resizing with grid snapping. */ function ResizeBehavior(eventBus, gridSnapping) { _CommandInterceptor.default.call(this, eventBus); this._gridSnapping = gridSnapping; var self = this; this.preExecute('shape.resize', function (event) { var context = event.context, hints = context.hints || {}, autoResize = hints.autoResize; if (!autoResize) { return; } var shape = context.shape, newBounds = context.newBounds; if ((0, _minDash.isString)(autoResize)) { context.newBounds = self.snapComplex(newBounds, autoResize); } else { context.newBounds = self.snapSimple(shape, newBounds); } }); } ResizeBehavior.$inject = ['eventBus', 'gridSnapping', 'modeling']; (0, _inherits.default)(ResizeBehavior, _CommandInterceptor.default); /** * Snap width and height in relation to center. * * @param {djs.model.shape} shape * @param {Bounds} newBounds * * @returns {Bounds} Snapped bounds. */ ResizeBehavior.prototype.snapSimple = function (shape, newBounds) { var gridSnapping = this._gridSnapping; newBounds.width = gridSnapping.snapValue(newBounds.width, { min: newBounds.width }); newBounds.height = gridSnapping.snapValue(newBounds.height, { min: newBounds.height }); newBounds.x = shape.x + shape.width / 2 - newBounds.width / 2; newBounds.y = shape.y + shape.height / 2 - newBounds.height / 2; return newBounds; }; /** * Snap x, y, width and height according to given directions. * * @param {Bounds} newBounds * @param {string} directions - Directions as {n|w|s|e}. * * @returns {Bounds} Snapped bounds. */ ResizeBehavior.prototype.snapComplex = function (newBounds, directions) { if (/w|e/.test(directions)) { newBounds = this.snapHorizontally(newBounds, directions); } if (/n|s/.test(directions)) { newBounds = this.snapVertically(newBounds, directions); } return newBounds; }; /** * Snap in one or both directions horizontally. * * @param {Bounds} newBounds * @param {string} directions - Directions as {n|w|s|e}. * * @returns {Bounds} Snapped bounds. */ ResizeBehavior.prototype.snapHorizontally = function (newBounds, directions) { var gridSnapping = this._gridSnapping, west = /w/.test(directions), east = /e/.test(directions); var snappedNewBounds = {}; snappedNewBounds.width = gridSnapping.snapValue(newBounds.width, { min: newBounds.width }); if (east) { // handle <we> if (west) { snappedNewBounds.x = gridSnapping.snapValue(newBounds.x, { max: newBounds.x }); snappedNewBounds.width += gridSnapping.snapValue(newBounds.x - snappedNewBounds.x, { min: newBounds.x - snappedNewBounds.x }); } // handle <e> else { newBounds.x = newBounds.x + newBounds.width - snappedNewBounds.width; } } // assign snapped x and width (0, _minDash.assign)(newBounds, snappedNewBounds); return newBounds; }; /** * Snap in one or both directions vertically. * * @param {Bounds} newBounds * @param {string} directions - Directions as {n|w|s|e}. * * @returns {Bounds} Snapped bounds. */ ResizeBehavior.prototype.snapVertically = function (newBounds, directions) { var gridSnapping = this._gridSnapping, north = /n/.test(directions), south = /s/.test(directions); var snappedNewBounds = {}; snappedNewBounds.height = gridSnapping.snapValue(newBounds.height, { min: newBounds.height }); if (north) { // handle <ns> if (south) { snappedNewBounds.y = gridSnapping.snapValue(newBounds.y, { max: newBounds.y }); snappedNewBounds.height += gridSnapping.snapValue(newBounds.y - snappedNewBounds.y, { min: newBounds.y - snappedNewBounds.y }); } // handle <n> else { newBounds.y = newBounds.y + newBounds.height - snappedNewBounds.height; } } // assign snapped y and height (0, _minDash.assign)(newBounds, snappedNewBounds); return newBounds; }; },{"../../../command/CommandInterceptor":145,"inherits":347,"min-dash":555}],205:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceToolBehavior; var HIGH_PRIORITY = 2000; /** * Integrates space tool with grid snapping. */ function SpaceToolBehavior(eventBus, gridSnapping) { eventBus.on(['spaceTool.move', 'spaceTool.end'], HIGH_PRIORITY, function (event) { var context = event.context; if (!context.initialized) { return; } var axis = context.axis; var snapped; if (axis === 'x') { // snap delta x to multiple of 10 snapped = gridSnapping.snapValue(event.dx); event.x = event.x + snapped - event.dx; event.dx = snapped; } else { // snap delta y to multiple of 10 snapped = gridSnapping.snapValue(event.dy); event.y = event.y + snapped - event.dy; event.dy = snapped; } }); } SpaceToolBehavior.$inject = ['eventBus', 'gridSnapping']; },{}],206:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ResizeBehavior = _interopRequireDefault(require("./ResizeBehavior")); var _SpaceToolBehavior = _interopRequireDefault(require("./SpaceToolBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['gridSnappingResizeBehavior', 'gridSnappingSpaceToolBehavior'], gridSnappingResizeBehavior: ['type', _ResizeBehavior.default], gridSnappingSpaceToolBehavior: ['type', _SpaceToolBehavior.default] }; exports.default = _default; },{"./ResizeBehavior":204,"./SpaceToolBehavior":205}],207:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _GridSnapping = _interopRequireDefault(require("./GridSnapping")); var _behavior = _interopRequireDefault(require("./behavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_behavior.default], __init__: ['gridSnapping'], gridSnapping: ['type', _GridSnapping.default] }; exports.default = _default; },{"./GridSnapping":202,"./behavior":206}],208:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = HandTool; var _Mouse = require("../../util/Mouse"); var _KeyboardUtil = require("../../features/keyboard/KeyboardUtil"); var HIGH_PRIORITY = 1500; var HAND_CURSOR = 'grab'; function HandTool(eventBus, canvas, dragging, injector, toolManager) { this._dragging = dragging; var self = this, keyboard = injector.get('keyboard', false); toolManager.registerTool('hand', { tool: 'hand', dragging: 'hand.move' }); eventBus.on('element.mousedown', HIGH_PRIORITY, function (event) { if ((0, _Mouse.hasPrimaryModifier)(event)) { this.activateMove(event.originalEvent); return false; } }, this); keyboard && keyboard.addListener(HIGH_PRIORITY, function (e) { if (!isSpace(e.keyEvent)) { return; } if (self.isActive()) { return; } function activateMove(event) { self.activateMove(event); window.removeEventListener('mousemove', activateMove); } window.addEventListener('mousemove', activateMove); function deactivateMove(e) { if (!isSpace(e.keyEvent)) { return; } window.removeEventListener('mousemove', activateMove); keyboard.removeListener(deactivateMove, 'keyboard.keyup'); dragging.cancel(); } keyboard.addListener(HIGH_PRIORITY, deactivateMove, 'keyboard.keyup'); }, 'keyboard.keydown'); eventBus.on('hand.end', function (event) { var target = event.originalEvent.target; // only reactive on diagram click // on some occasions, event.hover is not set and we have to check if the target is an svg if (!event.hover && !(target instanceof SVGElement)) { return false; } eventBus.once('hand.ended', function () { this.activateMove(event.originalEvent, { reactivate: true }); }, this); }, this); eventBus.on('hand.move.move', function (event) { var scale = canvas.viewbox().scale; canvas.scroll({ dx: event.dx * scale, dy: event.dy * scale }); }); eventBus.on('hand.move.end', function (event) { var context = event.context, reactivate = context.reactivate; // Don't reactivate if the user is using the keyboard keybinding if (!(0, _Mouse.hasPrimaryModifier)(event) && reactivate) { eventBus.once('hand.move.ended', function (event) { this.activateHand(event.originalEvent, true, true); }, this); } return false; }, this); } HandTool.$inject = ['eventBus', 'canvas', 'dragging', 'injector', 'toolManager']; HandTool.prototype.activateMove = function (event, autoActivate, context) { if (typeof autoActivate === 'object') { context = autoActivate; autoActivate = false; } this._dragging.init(event, 'hand.move', { autoActivate: autoActivate, cursor: HAND_CURSOR, data: { context: context || {} } }); }; HandTool.prototype.activateHand = function (event, autoActivate, reactivate) { this._dragging.init(event, 'hand', { trapClick: false, autoActivate: autoActivate, cursor: HAND_CURSOR, data: { context: { reactivate: reactivate } } }); }; HandTool.prototype.toggle = function () { if (this.isActive()) { this._dragging.cancel(); } else { this.activateHand(); } }; HandTool.prototype.isActive = function () { var context = this._dragging.context(); if (context) { return /^(hand|hand\.move)$/.test(context.prefix); } return false; }; // helpers ////////// function isSpace(keyEvent) { return (0, _KeyboardUtil.isKey)(' ', keyEvent); } },{"../../features/keyboard/KeyboardUtil":216,"../../util/Mouse":323}],209:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _toolManager = _interopRequireDefault(require("../tool-manager")); var _HandTool = _interopRequireDefault(require("./HandTool")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_toolManager.default], __init__: ['handTool'], handTool: ['type', _HandTool.default] }; exports.default = _default; },{"../tool-manager":290,"./HandTool":208}],210:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = InteractionEvents; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _Mouse = require("../../util/Mouse"); var _tinySvg = require("tiny-svg"); var _RenderUtil = require("../../util/RenderUtil"); function allowAll(e) { return true; } var LOW_PRIORITY = 500; /** * A plugin that provides interaction events for diagram elements. * * It emits the following events: * * * element.click * * element.contextmenu * * element.dblclick * * element.hover * * element.mousedown * * element.mousemove * * element.mouseup * * element.out * * Each event is a tuple { element, gfx, originalEvent }. * * Canceling the event via Event#preventDefault() * prevents the original DOM operation. * * @param {EventBus} eventBus */ function InteractionEvents(eventBus, elementRegistry, styles) { var self = this; /** * Fire an interaction event. * * @param {string} type local event name, e.g. element.click. * @param {DOMEvent} event native event * @param {djs.model.Base} [element] the diagram element to emit the event on; * defaults to the event target */ function fire(type, event, element) { if (isIgnored(type, event)) { return; } var target, gfx, returnValue; if (!element) { target = event.delegateTarget || event.target; if (target) { gfx = target; element = elementRegistry.get(gfx); } } else { gfx = elementRegistry.getGraphics(element); } if (!gfx || !element) { return; } returnValue = eventBus.fire(type, { element: element, gfx: gfx, originalEvent: event }); if (returnValue === false) { event.stopPropagation(); event.preventDefault(); } } // TODO(nikku): document this var handlers = {}; function mouseHandler(localEventName) { return handlers[localEventName]; } function isIgnored(localEventName, event) { var filter = ignoredFilters[localEventName] || _Mouse.isPrimaryButton; // only react on left mouse button interactions // except for interaction events that are enabled // for secundary mouse button return !filter(event); } var bindings = { click: 'element.click', contextmenu: 'element.contextmenu', dblclick: 'element.dblclick', mousedown: 'element.mousedown', mousemove: 'element.mousemove', mouseover: 'element.hover', mouseout: 'element.out', mouseup: 'element.mouseup' }; var ignoredFilters = { 'element.contextmenu': allowAll }; // manual event trigger ////////// /** * Trigger an interaction event (based on a native dom event) * on the target shape or connection. * * @param {string} eventName the name of the triggered DOM event * @param {MouseEvent} event * @param {djs.model.Base} targetElement */ function triggerMouseEvent(eventName, event, targetElement) { // i.e. element.mousedown... var localEventName = bindings[eventName]; if (!localEventName) { throw new Error('unmapped DOM event name <' + eventName + '>'); } return fire(localEventName, event, targetElement); } var ELEMENT_SELECTOR = 'svg, .djs-element'; // event handling /////// function registerEvent(node, event, localEvent, ignoredFilter) { var handler = handlers[localEvent] = function (event) { fire(localEvent, event); }; if (ignoredFilter) { ignoredFilters[localEvent] = ignoredFilter; } handler.$delegate = _minDom.delegate.bind(node, ELEMENT_SELECTOR, event, handler); } function unregisterEvent(node, event, localEvent) { var handler = mouseHandler(localEvent); if (!handler) { return; } _minDom.delegate.unbind(node, event, handler.$delegate); } function registerEvents(svg) { (0, _minDash.forEach)(bindings, function (val, key) { registerEvent(svg, key, val); }); } function unregisterEvents(svg) { (0, _minDash.forEach)(bindings, function (val, key) { unregisterEvent(svg, key, val); }); } eventBus.on('canvas.destroy', function (event) { unregisterEvents(event.svg); }); eventBus.on('canvas.init', function (event) { registerEvents(event.svg); }); // hit box updating //////////////// eventBus.on(['shape.added', 'connection.added'], function (event) { var element = event.element, gfx = event.gfx; eventBus.fire('interactionEvents.createHit', { element: element, gfx: gfx }); }); // Update djs-hit on change. // A low priortity is necessary, because djs-hit of labels has to be updated // after the label bounds have been updated in the renderer. eventBus.on(['shape.changed', 'connection.changed'], LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; eventBus.fire('interactionEvents.updateHit', { element: element, gfx: gfx }); }); eventBus.on('interactionEvents.createHit', LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; self.createDefaultHit(element, gfx); }); eventBus.on('interactionEvents.updateHit', function (event) { var element = event.element, gfx = event.gfx; self.updateDefaultHit(element, gfx); }); // hit styles //////////// var STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-stroke'); var CLICK_STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-click-stroke'); var ALL_HIT_STYLE = createHitStyle('djs-hit djs-hit-all'); var HIT_TYPES = { 'all': ALL_HIT_STYLE, 'click-stroke': CLICK_STROKE_HIT_STYLE, 'stroke': STROKE_HIT_STYLE }; function createHitStyle(classNames, attrs) { attrs = (0, _minDash.assign)({ stroke: 'white', strokeWidth: 15 }, attrs || {}); return styles.cls(classNames, ['no-fill', 'no-border'], attrs); } // style helpers /////////////// function applyStyle(hit, type) { var attrs = HIT_TYPES[type]; if (!attrs) { throw new Error('invalid hit type <' + type + '>'); } (0, _tinySvg.attr)(hit, attrs); return hit; } function appendHit(gfx, hit) { (0, _tinySvg.append)(gfx, hit); } // API /** * Remove hints on the given graphics. * * @param {SVGElement} gfx */ this.removeHits = function (gfx) { var hits = (0, _minDom.queryAll)('.djs-hit', gfx); (0, _minDash.forEach)(hits, _tinySvg.remove); }; /** * Create default hit for the given element. * * @param {djs.model.Base} element * @param {SVGElement} gfx * * @return {SVGElement} created hit */ this.createDefaultHit = function (element, gfx) { var waypoints = element.waypoints, isFrame = element.isFrame, boxType; if (waypoints) { return this.createWaypointsHit(gfx, waypoints); } else { boxType = isFrame ? 'stroke' : 'all'; return this.createBoxHit(gfx, boxType, { width: element.width, height: element.height }); } }; /** * Create hits for the given waypoints. * * @param {SVGElement} gfx * @param {Array<Point>} waypoints * * @return {SVGElement} */ this.createWaypointsHit = function (gfx, waypoints) { var hit = (0, _RenderUtil.createLine)(waypoints); applyStyle(hit, 'stroke'); appendHit(gfx, hit); return hit; }; /** * Create hits for a box. * * @param {SVGElement} gfx * @param {string} hitType * @param {Object} attrs * * @return {SVGElement} */ this.createBoxHit = function (gfx, type, attrs) { attrs = (0, _minDash.assign)({ x: 0, y: 0 }, attrs); var hit = (0, _tinySvg.create)('rect'); applyStyle(hit, type); (0, _tinySvg.attr)(hit, attrs); appendHit(gfx, hit); return hit; }; /** * Update default hit of the element. * * @param {djs.model.Base} element * @param {SVGElement} gfx * * @return {SVGElement} updated hit */ this.updateDefaultHit = function (element, gfx) { var hit = (0, _minDom.query)('.djs-hit', gfx); if (!hit) { return; } if (element.waypoints) { (0, _RenderUtil.updateLine)(hit, element.waypoints); } else { (0, _tinySvg.attr)(hit, { width: element.width, height: element.height }); } return hit; }; this.fire = fire; this.triggerMouseEvent = triggerMouseEvent; this.mouseHandler = mouseHandler; this.registerEvent = registerEvent; this.unregisterEvent = unregisterEvent; } InteractionEvents.$inject = ['eventBus', 'elementRegistry', 'styles']; /** * An event indicating that the mouse hovered over an element * * @event element.hover * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has left an element * * @event element.out * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has clicked an element * * @event element.click * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has double clicked an element * * @event element.dblclick * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has gone down on an element. * * @event element.mousedown * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has gone up on an element. * * @event element.mouseup * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the context menu action is triggered * via mouse or touch controls. * * @event element.contextmenu * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ },{"../../util/Mouse":323,"../../util/RenderUtil":327,"min-dash":555,"min-dom":556,"tiny-svg":567}],211:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _InteractionEvents = _interopRequireDefault(require("./InteractionEvents")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['interactionEvents'], interactionEvents: ['type', _InteractionEvents.default] }; exports.default = _default; },{"./InteractionEvents":210}],212:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = KeyboardMoveSelection; var _minDash = require("min-dash"); var DEFAULT_CONFIG = { moveSpeed: 1, moveSpeedAccelerated: 10 }; var HIGHER_PRIORITY = 1500; var LEFT = 'left'; var UP = 'up'; var RIGHT = 'right'; var DOWN = 'down'; var KEY_TO_DIRECTION = { ArrowLeft: LEFT, Left: LEFT, ArrowUp: UP, Up: UP, ArrowRight: RIGHT, Right: RIGHT, ArrowDown: DOWN, Down: DOWN }; var DIRECTIONS_DELTA = { left: function (speed) { return { x: -speed, y: 0 }; }, up: function (speed) { return { x: 0, y: -speed }; }, right: function (speed) { return { x: speed, y: 0 }; }, down: function (speed) { return { x: 0, y: speed }; } }; /** * Enables to move selection with keyboard arrows. * Use with Shift for modified speed (default=1, with Shift=10). * Pressed Cmd/Ctrl turns the feature off. * * @param {Object} config * @param {number} [config.moveSpeed=1] * @param {number} [config.moveSpeedAccelerated=10] * @param {Keyboard} keyboard * @param {Modeling} modeling * @param {Selection} selection */ function KeyboardMoveSelection(config, keyboard, modeling, rules, selection) { var self = this; this._config = (0, _minDash.assign)({}, DEFAULT_CONFIG, config || {}); keyboard.addListener(HIGHER_PRIORITY, function (event) { var keyEvent = event.keyEvent; var direction = KEY_TO_DIRECTION[keyEvent.key]; if (!direction) { return; } if (keyboard.isCmd(keyEvent)) { return; } var accelerated = keyboard.isShift(keyEvent); self.moveSelection(direction, accelerated); return true; }); /** * Move selected elements in the given direction, * optionally specifying accelerated movement. * * @param {string} direction * @param {boolean} [accelerated=false] */ this.moveSelection = function (direction, accelerated) { var selectedElements = selection.get(); if (!selectedElements.length) { return; } var speed = this._config[accelerated ? 'moveSpeedAccelerated' : 'moveSpeed']; var delta = DIRECTIONS_DELTA[direction](speed); var canMove = rules.allowed('elements.move', { shapes: selectedElements }); if (canMove) { modeling.moveElements(selectedElements, delta); } }; } KeyboardMoveSelection.$inject = ['config.keyboardMoveSelection', 'keyboard', 'modeling', 'rules', 'selection']; },{"min-dash":555}],213:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _keyboard = _interopRequireDefault(require("../keyboard")); var _selection = _interopRequireDefault(require("../selection")); var _KeyboardMoveSelection = _interopRequireDefault(require("./KeyboardMoveSelection")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_keyboard.default, _selection.default], __init__: ['keyboardMoveSelection'], keyboardMoveSelection: ['type', _KeyboardMoveSelection.default] }; exports.default = _default; },{"../keyboard":217,"../selection":278,"./KeyboardMoveSelection":212}],214:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Keyboard; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _KeyboardUtil = require("./KeyboardUtil"); var KEYDOWN_EVENT = 'keyboard.keydown', KEYUP_EVENT = 'keyboard.keyup'; var DEFAULT_PRIORITY = 1000; /** * A keyboard abstraction that may be activated and * deactivated by users at will, consuming key events * and triggering diagram actions. * * For keys pressed down, keyboard fires `keyboard.keydown` event. * The event context contains one field which is `KeyboardEvent` event. * * The implementation fires the following key events that allow * other components to hook into key handling: * * - keyboard.bind * - keyboard.unbind * - keyboard.init * - keyboard.destroy * * All events contain one field which is node. * * A default binding for the keyboard may be specified via the * `keyboard.bindTo` configuration option. * * @param {Config} config * @param {EventBus} eventBus */ function Keyboard(config, eventBus) { var self = this; this._config = config || {}; this._eventBus = eventBus; this._keydownHandler = this._keydownHandler.bind(this); this._keyupHandler = this._keyupHandler.bind(this); // properly clean dom registrations eventBus.on('diagram.destroy', function () { self._fire('destroy'); self.unbind(); }); eventBus.on('diagram.init', function () { self._fire('init'); }); eventBus.on('attach', function () { if (config && config.bindTo) { self.bind(config.bindTo); } }); eventBus.on('detach', function () { self.unbind(); }); } Keyboard.$inject = ['config.keyboard', 'eventBus']; Keyboard.prototype._keydownHandler = function (event) { this._keyHandler(event, KEYDOWN_EVENT); }; Keyboard.prototype._keyupHandler = function (event) { this._keyHandler(event, KEYUP_EVENT); }; Keyboard.prototype._keyHandler = function (event, type) { var target = event.target, eventBusResult; if (isInput(target)) { return; } var context = { keyEvent: event }; eventBusResult = this._eventBus.fire(type || KEYDOWN_EVENT, context); if (eventBusResult) { event.preventDefault(); } }; Keyboard.prototype.bind = function (node) { // make sure that the keyboard is only bound once to the DOM this.unbind(); this._node = node; // bind key events _minDom.event.bind(node, 'keydown', this._keydownHandler, true); _minDom.event.bind(node, 'keyup', this._keyupHandler, true); this._fire('bind'); }; Keyboard.prototype.getBinding = function () { return this._node; }; Keyboard.prototype.unbind = function () { var node = this._node; if (node) { this._fire('unbind'); // unbind key events _minDom.event.unbind(node, 'keydown', this._keydownHandler, true); _minDom.event.unbind(node, 'keyup', this._keyupHandler, true); } this._node = null; }; Keyboard.prototype._fire = function (event) { this._eventBus.fire('keyboard.' + event, { node: this._node }); }; /** * Add a listener function that is notified with `KeyboardEvent` whenever * the keyboard is bound and the user presses a key. If no priority is * provided, the default value of 1000 is used. * * @param {number} [priority] * @param {Function} listener * @param {string} type */ Keyboard.prototype.addListener = function (priority, listener, type) { if ((0, _minDash.isFunction)(priority)) { type = listener; listener = priority; priority = DEFAULT_PRIORITY; } this._eventBus.on(type || KEYDOWN_EVENT, priority, listener); }; Keyboard.prototype.removeListener = function (listener, type) { this._eventBus.off(type || KEYDOWN_EVENT, listener); }; Keyboard.prototype.hasModifier = _KeyboardUtil.hasModifier; Keyboard.prototype.isCmd = _KeyboardUtil.isCmd; Keyboard.prototype.isShift = _KeyboardUtil.isShift; Keyboard.prototype.isKey = _KeyboardUtil.isKey; // helpers /////// function isInput(target) { return target && ((0, _minDom.matches)(target, 'input, textarea') || target.contentEditable === 'true'); } },{"./KeyboardUtil":216,"min-dash":555,"min-dom":556}],215:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = KeyboardBindings; exports.KEYS_UNDO = exports.KEYS_REDO = exports.KEYS_PASTE = exports.KEYS_COPY = exports.KEYCODE_Z = exports.KEYCODE_Y = exports.KEYCODE_V = exports.KEYCODE_C = void 0; var _KeyboardUtil = require("./KeyboardUtil"); var LOW_PRIORITY = 500; var KEYCODE_C = 67; exports.KEYCODE_C = KEYCODE_C; var KEYCODE_V = 86; exports.KEYCODE_V = KEYCODE_V; var KEYCODE_Y = 89; exports.KEYCODE_Y = KEYCODE_Y; var KEYCODE_Z = 90; exports.KEYCODE_Z = KEYCODE_Z; var KEYS_COPY = ['c', 'C', KEYCODE_C]; exports.KEYS_COPY = KEYS_COPY; var KEYS_PASTE = ['v', 'V', KEYCODE_V]; exports.KEYS_PASTE = KEYS_PASTE; var KEYS_REDO = ['y', 'Y', KEYCODE_Y]; exports.KEYS_REDO = KEYS_REDO; var KEYS_UNDO = ['z', 'Z', KEYCODE_Z]; /** * Adds default keyboard bindings. * * This does not pull in any features will bind only actions that * have previously been registered against the editorActions component. * * @param {EventBus} eventBus * @param {Keyboard} keyboard */ exports.KEYS_UNDO = KEYS_UNDO; function KeyboardBindings(eventBus, keyboard) { var self = this; eventBus.on('editorActions.init', LOW_PRIORITY, function (event) { var editorActions = event.editorActions; self.registerBindings(keyboard, editorActions); }); } KeyboardBindings.$inject = ['eventBus', 'keyboard']; /** * Register available keyboard bindings. * * @param {Keyboard} keyboard * @param {EditorActions} editorActions */ KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions) { /** * Add keyboard binding if respective editor action * is registered. * * @param {string} action name * @param {Function} fn that implements the key binding */ function addListener(action, fn) { if (editorActions.isRegistered(action)) { keyboard.addListener(fn); } } // undo // (CTRL|CMD) + Z addListener('undo', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isCmd)(event) && !(0, _KeyboardUtil.isShift)(event) && (0, _KeyboardUtil.isKey)(KEYS_UNDO, event)) { editorActions.trigger('undo'); return true; } }); // redo // CTRL + Y // CMD + SHIFT + Z addListener('redo', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isCmd)(event) && ((0, _KeyboardUtil.isKey)(KEYS_REDO, event) || (0, _KeyboardUtil.isKey)(KEYS_UNDO, event) && (0, _KeyboardUtil.isShift)(event))) { editorActions.trigger('redo'); return true; } }); // copy // CTRL/CMD + C addListener('copy', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isCmd)(event) && (0, _KeyboardUtil.isKey)(KEYS_COPY, event)) { editorActions.trigger('copy'); return true; } }); // paste // CTRL/CMD + V addListener('paste', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isCmd)(event) && (0, _KeyboardUtil.isKey)(KEYS_PASTE, event)) { editorActions.trigger('paste'); return true; } }); // zoom in one step // CTRL/CMD + + addListener('stepZoom', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isKey)(['+', 'Add'], event) && (0, _KeyboardUtil.isCmd)(event)) { editorActions.trigger('stepZoom', { value: 1 }); return true; } }); // zoom out one step // CTRL + - addListener('stepZoom', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isKey)(['-', 'Subtract'], event) && (0, _KeyboardUtil.isCmd)(event)) { editorActions.trigger('stepZoom', { value: -1 }); return true; } }); // zoom to the default level // CTRL + 0 addListener('zoom', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isKey)('0', event) && (0, _KeyboardUtil.isCmd)(event)) { editorActions.trigger('zoom', { value: 1 }); return true; } }); // delete selected element // DEL addListener('removeSelection', function (context) { var event = context.keyEvent; if ((0, _KeyboardUtil.isKey)(['Backspace', 'Delete', 'Del'], event)) { editorActions.trigger('removeSelection'); return true; } }); }; },{"./KeyboardUtil":216}],216:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.hasModifier = hasModifier; exports.isCmd = isCmd; exports.isKey = isKey; exports.isShift = isShift; var _minDash = require("min-dash"); /** * Returns true if event was triggered with any modifier * @param {KeyboardEvent} event */ function hasModifier(event) { return event.ctrlKey || event.metaKey || event.shiftKey || event.altKey; } /** * @param {KeyboardEvent} event */ function isCmd(event) { // ensure we don't react to AltGr // (mapped to CTRL + ALT) if (event.altKey) { return false; } return event.ctrlKey || event.metaKey; } /** * Checks if key pressed is one of provided keys. * * @param {string|Array<string>} keys * @param {KeyboardEvent} event */ function isKey(keys, event) { keys = (0, _minDash.isArray)(keys) ? keys : [keys]; return keys.indexOf(event.key) !== -1 || keys.indexOf(event.keyCode) !== -1; } /** * @param {KeyboardEvent} event */ function isShift(event) { return event.shiftKey; } },{"min-dash":555}],217:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Keyboard = _interopRequireDefault(require("./Keyboard")); var _KeyboardBindings = _interopRequireDefault(require("./KeyboardBindings")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['keyboard', 'keyboardBindings'], keyboard: ['type', _Keyboard.default], keyboardBindings: ['type', _KeyboardBindings.default] }; exports.default = _default; },{"./Keyboard":214,"./KeyboardBindings":215}],218:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LabelSupport; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _Collections = require("../../util/Collections"); var _Removal = require("../../util/Removal"); var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var LOW_PRIORITY = 250, HIGH_PRIORITY = 1400; /** * A handler that makes sure labels are properly moved with * their label targets. * * @param {didi.Injector} injector * @param {EventBus} eventBus * @param {Modeling} modeling */ function LabelSupport(injector, eventBus, modeling) { _CommandInterceptor.default.call(this, eventBus); var movePreview = injector.get('movePreview', false); // remove labels from the collection that are being // moved with other elements anyway eventBus.on('shape.move.start', HIGH_PRIORITY, function (e) { var context = e.context, shapes = context.shapes, validatedShapes = context.validatedShapes; context.shapes = removeLabels(shapes); context.validatedShapes = removeLabels(validatedShapes); }); // add labels to visual's group movePreview && eventBus.on('shape.move.start', LOW_PRIORITY, function (e) { var context = e.context, shapes = context.shapes; var labels = []; (0, _minDash.forEach)(shapes, function (element) { (0, _minDash.forEach)(element.labels, function (label) { if (!label.hidden && context.shapes.indexOf(label) === -1) { labels.push(label); } if (element.labelTarget) { labels.push(element); } }); }); (0, _minDash.forEach)(labels, function (label) { movePreview.makeDraggable(context, label, true); }); }); // add all labels to move closure this.preExecuted('elements.move', HIGH_PRIORITY, function (e) { var context = e.context, closure = context.closure, enclosedElements = closure.enclosedElements; var enclosedLabels = []; // find labels that are not part of // move closure yet and add them (0, _minDash.forEach)(enclosedElements, function (element) { (0, _minDash.forEach)(element.labels, function (label) { if (!enclosedElements[label.id]) { enclosedLabels.push(label); } }); }); closure.addAll(enclosedLabels); }); this.preExecute(['connection.delete', 'shape.delete'], function (e) { var context = e.context, element = context.connection || context.shape; (0, _Removal.saveClear)(element.labels, function (label) { modeling.removeShape(label, { nested: true }); }); }); this.execute('shape.delete', function (e) { var context = e.context, shape = context.shape, labelTarget = shape.labelTarget; // unset labelTarget if (labelTarget) { context.labelTargetIndex = (0, _Collections.indexOf)(labelTarget.labels, shape); context.labelTarget = labelTarget; shape.labelTarget = null; } }); this.revert('shape.delete', function (e) { var context = e.context, shape = context.shape, labelTarget = context.labelTarget, labelTargetIndex = context.labelTargetIndex; // restore labelTarget if (labelTarget) { (0, _Collections.add)(labelTarget.labels, shape, labelTargetIndex); shape.labelTarget = labelTarget; } }); } (0, _inherits.default)(LabelSupport, _CommandInterceptor.default); LabelSupport.$inject = ['injector', 'eventBus', 'modeling']; /** * Return a filtered list of elements that do not * contain attached elements with hosts being part * of the selection. * * @param {Array<djs.model.Base>} elements * * @return {Array<djs.model.Base>} filtered */ function removeLabels(elements) { return (0, _minDash.filter)(elements, function (element) { // filter out labels that are move together // with their label targets return elements.indexOf(element.labelTarget) === -1; }); } },{"../../command/CommandInterceptor":145,"../../util/Collections":313,"../../util/Removal":326,"inherits":347,"min-dash":555}],219:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _LabelSupport = _interopRequireDefault(require("./LabelSupport")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['labelSupport'], labelSupport: ['type', _LabelSupport.default] }; exports.default = _default; },{"./LabelSupport":218}],220:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LassoTool; var _minDash = require("min-dash"); var _Elements = require("../../util/Elements"); var _Mouse = require("../../util/Mouse"); var _tinySvg = require("tiny-svg"); var LASSO_TOOL_CURSOR = 'crosshair'; function LassoTool(eventBus, canvas, dragging, elementRegistry, selection, toolManager) { this._selection = selection; this._dragging = dragging; var self = this; // lasso visuals implementation /** * A helper that realizes the selection box visual */ var visuals = { create: function (context) { var container = canvas.getDefaultLayer(), frame; frame = context.frame = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(frame, { class: 'djs-lasso-overlay', width: 1, height: 1, x: 0, y: 0 }); (0, _tinySvg.append)(container, frame); }, update: function (context) { var frame = context.frame, bbox = context.bbox; (0, _tinySvg.attr)(frame, { x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height }); }, remove: function (context) { if (context.frame) { (0, _tinySvg.remove)(context.frame); } } }; toolManager.registerTool('lasso', { tool: 'lasso.selection', dragging: 'lasso' }); eventBus.on('lasso.selection.end', function (event) { var target = event.originalEvent.target; // only reactive on diagram click // on some occasions, event.hover is not set and we have to check if the target is an svg if (!event.hover && !(target instanceof SVGElement)) { return; } eventBus.once('lasso.selection.ended', function () { self.activateLasso(event.originalEvent, true); }); }); // lasso interaction implementation eventBus.on('lasso.end', function (event) { var bbox = toBBox(event); var elements = elementRegistry.filter(function (element) { return element; }); self.select(elements, bbox); }); eventBus.on('lasso.start', function (event) { var context = event.context; context.bbox = toBBox(event); visuals.create(context); }); eventBus.on('lasso.move', function (event) { var context = event.context; context.bbox = toBBox(event); visuals.update(context); }); eventBus.on('lasso.cleanup', function (event) { var context = event.context; visuals.remove(context); }); // event integration eventBus.on('element.mousedown', 1500, function (event) { if ((0, _Mouse.hasSecondaryModifier)(event)) { self.activateLasso(event.originalEvent); // we've handled the event return true; } }); } LassoTool.$inject = ['eventBus', 'canvas', 'dragging', 'elementRegistry', 'selection', 'toolManager']; LassoTool.prototype.activateLasso = function (event, autoActivate) { this._dragging.init(event, 'lasso', { autoActivate: autoActivate, cursor: LASSO_TOOL_CURSOR, data: { context: {} } }); }; LassoTool.prototype.activateSelection = function (event) { this._dragging.init(event, 'lasso.selection', { trapClick: false, cursor: LASSO_TOOL_CURSOR, data: { context: {} } }); }; LassoTool.prototype.select = function (elements, bbox) { var selectedElements = (0, _Elements.getEnclosedElements)(elements, bbox); this._selection.select((0, _minDash.values)(selectedElements)); }; LassoTool.prototype.toggle = function () { if (this.isActive()) { this._dragging.cancel(); } else { this.activateSelection(); } }; LassoTool.prototype.isActive = function () { var context = this._dragging.context(); return context && /^lasso/.test(context.prefix); }; function toBBox(event) { var start = { x: event.x - event.dx, y: event.y - event.dy }; var end = { x: event.x, y: event.y }; var bbox; if (start.x <= end.x && start.y < end.y || start.x < end.x && start.y <= end.y) { bbox = { x: start.x, y: start.y, width: end.x - start.x, height: end.y - start.y }; } else if (start.x >= end.x && start.y < end.y || start.x > end.x && start.y <= end.y) { bbox = { x: end.x, y: start.y, width: start.x - end.x, height: end.y - start.y }; } else if (start.x <= end.x && start.y > end.y || start.x < end.x && start.y >= end.y) { bbox = { x: start.x, y: end.y, width: end.x - start.x, height: start.y - end.y }; } else if (start.x >= end.x && start.y > end.y || start.x > end.x && start.y >= end.y) { bbox = { x: end.x, y: end.y, width: start.x - end.x, height: start.y - end.y }; } else { bbox = { x: end.x, y: end.y, width: 0, height: 0 }; } return bbox; } },{"../../util/Elements":315,"../../util/Mouse":323,"min-dash":555,"tiny-svg":567}],221:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _toolManager = _interopRequireDefault(require("../tool-manager")); var _LassoTool = _interopRequireDefault(require("./LassoTool")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_toolManager.default], __init__: ['lassoTool'], lassoTool: ['type', _LassoTool.default] }; exports.default = _default; },{"../tool-manager":290,"./LassoTool":220}],222:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Modeling; var _minDash = require("min-dash"); var _model = require("../../model"); var _AlignElementsHandler = _interopRequireDefault(require("./cmd/AlignElementsHandler")); var _AppendShapeHandler = _interopRequireDefault(require("./cmd/AppendShapeHandler")); var _CreateConnectionHandler = _interopRequireDefault(require("./cmd/CreateConnectionHandler")); var _CreateElementsHandler = _interopRequireDefault(require("./cmd/CreateElementsHandler")); var _CreateLabelHandler = _interopRequireDefault(require("./cmd/CreateLabelHandler")); var _CreateShapeHandler = _interopRequireDefault(require("./cmd/CreateShapeHandler")); var _DeleteConnectionHandler = _interopRequireDefault(require("./cmd/DeleteConnectionHandler")); var _DeleteElementsHandler = _interopRequireDefault(require("./cmd/DeleteElementsHandler")); var _DeleteShapeHandler = _interopRequireDefault(require("./cmd/DeleteShapeHandler")); var _DistributeElementsHandler = _interopRequireDefault(require("./cmd/DistributeElementsHandler")); var _LayoutConnectionHandler = _interopRequireDefault(require("./cmd/LayoutConnectionHandler")); var _MoveConnectionHandler = _interopRequireDefault(require("./cmd/MoveConnectionHandler")); var _MoveElementsHandler = _interopRequireDefault(require("./cmd/MoveElementsHandler")); var _MoveShapeHandler = _interopRequireDefault(require("./cmd/MoveShapeHandler")); var _ReconnectConnectionHandler = _interopRequireDefault(require("./cmd/ReconnectConnectionHandler")); var _ReplaceShapeHandler = _interopRequireDefault(require("./cmd/ReplaceShapeHandler")); var _ResizeShapeHandler = _interopRequireDefault(require("./cmd/ResizeShapeHandler")); var _SpaceToolHandler = _interopRequireDefault(require("./cmd/SpaceToolHandler")); var _ToggleShapeCollapseHandler = _interopRequireDefault(require("./cmd/ToggleShapeCollapseHandler")); var _UpdateAttachmentHandler = _interopRequireDefault(require("./cmd/UpdateAttachmentHandler")); var _UpdateWaypointsHandler = _interopRequireDefault(require("./cmd/UpdateWaypointsHandler")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * The basic modeling entry point. * * @param {EventBus} eventBus * @param {ElementFactory} elementFactory * @param {CommandStack} commandStack */ function Modeling(eventBus, elementFactory, commandStack) { this._eventBus = eventBus; this._elementFactory = elementFactory; this._commandStack = commandStack; var self = this; eventBus.on('diagram.init', function () { // register modeling handlers self.registerHandlers(commandStack); }); } Modeling.$inject = ['eventBus', 'elementFactory', 'commandStack']; Modeling.prototype.getHandlers = function () { return { 'shape.append': _AppendShapeHandler.default, 'shape.create': _CreateShapeHandler.default, 'shape.delete': _DeleteShapeHandler.default, 'shape.move': _MoveShapeHandler.default, 'shape.resize': _ResizeShapeHandler.default, 'shape.replace': _ReplaceShapeHandler.default, 'shape.toggleCollapse': _ToggleShapeCollapseHandler.default, 'spaceTool': _SpaceToolHandler.default, 'label.create': _CreateLabelHandler.default, 'connection.create': _CreateConnectionHandler.default, 'connection.delete': _DeleteConnectionHandler.default, 'connection.move': _MoveConnectionHandler.default, 'connection.layout': _LayoutConnectionHandler.default, 'connection.updateWaypoints': _UpdateWaypointsHandler.default, 'connection.reconnect': _ReconnectConnectionHandler.default, 'elements.create': _CreateElementsHandler.default, 'elements.move': _MoveElementsHandler.default, 'elements.delete': _DeleteElementsHandler.default, 'elements.distribute': _DistributeElementsHandler.default, 'elements.align': _AlignElementsHandler.default, 'element.updateAttachment': _UpdateAttachmentHandler.default }; }; /** * Register handlers with the command stack * * @param {CommandStack} commandStack */ Modeling.prototype.registerHandlers = function (commandStack) { (0, _minDash.forEach)(this.getHandlers(), function (handler, id) { commandStack.registerHandler(id, handler); }); }; // modeling helpers ////////////////////// Modeling.prototype.moveShape = function (shape, delta, newParent, newParentIndex, hints) { if (typeof newParentIndex === 'object') { hints = newParentIndex; newParentIndex = null; } var context = { shape: shape, delta: delta, newParent: newParent, newParentIndex: newParentIndex, hints: hints || {} }; this._commandStack.execute('shape.move', context); }; /** * Update the attachment of the given shape. * * @param {djs.mode.Base} shape * @param {djs.model.Base} [newHost] */ Modeling.prototype.updateAttachment = function (shape, newHost) { var context = { shape: shape, newHost: newHost }; this._commandStack.execute('element.updateAttachment', context); }; /** * Move a number of shapes to a new target, either setting it as * the new parent or attaching it. * * @param {Array<djs.mode.Base>} shapes * @param {Point} delta * @param {djs.model.Base} [target] * @param {Object} [hints] * @param {boolean} [hints.attach=false] */ Modeling.prototype.moveElements = function (shapes, delta, target, hints) { hints = hints || {}; var attach = hints.attach; var newParent = target, newHost; if (attach === true) { newHost = target; newParent = target.parent; } else if (attach === false) { newHost = null; } var context = { shapes: shapes, delta: delta, newParent: newParent, newHost: newHost, hints: hints }; this._commandStack.execute('elements.move', context); }; Modeling.prototype.moveConnection = function (connection, delta, newParent, newParentIndex, hints) { if (typeof newParentIndex === 'object') { hints = newParentIndex; newParentIndex = undefined; } var context = { connection: connection, delta: delta, newParent: newParent, newParentIndex: newParentIndex, hints: hints || {} }; this._commandStack.execute('connection.move', context); }; Modeling.prototype.layoutConnection = function (connection, hints) { var context = { connection: connection, hints: hints || {} }; this._commandStack.execute('connection.layout', context); }; /** * Create connection. * * @param {djs.model.Base} source * @param {djs.model.Base} target * @param {number} [parentIndex] * @param {Object|djs.model.Connection} connection * @param {djs.model.Base} parent * @param {Object} hints * * @return {djs.model.Connection} the created connection. */ Modeling.prototype.createConnection = function (source, target, parentIndex, connection, parent, hints) { if (typeof parentIndex === 'object') { hints = parent; parent = connection; connection = parentIndex; parentIndex = undefined; } connection = this._create('connection', connection); var context = { source: source, target: target, parent: parent, parentIndex: parentIndex, connection: connection, hints: hints }; this._commandStack.execute('connection.create', context); return context.connection; }; /** * Create a shape at the specified position. * * @param {djs.model.Shape|Object} shape * @param {Point} position * @param {djs.model.Shape|djs.model.Root} target * @param {number} [parentIndex] position in parents children list * @param {Object} [hints] * @param {boolean} [hints.attach] whether to attach to target or become a child * * @return {djs.model.Shape} the created shape */ Modeling.prototype.createShape = function (shape, position, target, parentIndex, hints) { if (typeof parentIndex !== 'number') { hints = parentIndex; parentIndex = undefined; } hints = hints || {}; var attach = hints.attach, parent, host; shape = this._create('shape', shape); if (attach) { parent = target.parent; host = target; } else { parent = target; } var context = { position: position, shape: shape, parent: parent, parentIndex: parentIndex, host: host, hints: hints }; this._commandStack.execute('shape.create', context); return context.shape; }; Modeling.prototype.createElements = function (elements, position, parent, parentIndex, hints) { if (!(0, _minDash.isArray)(elements)) { elements = [elements]; } if (typeof parentIndex !== 'number') { hints = parentIndex; parentIndex = undefined; } hints = hints || {}; var context = { position: position, elements: elements, parent: parent, parentIndex: parentIndex, hints: hints }; this._commandStack.execute('elements.create', context); return context.elements; }; Modeling.prototype.createLabel = function (labelTarget, position, label, parent) { label = this._create('label', label); var context = { labelTarget: labelTarget, position: position, parent: parent || labelTarget.parent, shape: label }; this._commandStack.execute('label.create', context); return context.shape; }; /** * Append shape to given source, drawing a connection * between source and the newly created shape. * * @param {djs.model.Shape} source * @param {djs.model.Shape|Object} shape * @param {Point} position * @param {djs.model.Shape} target * @param {Object} [hints] * @param {boolean} [hints.attach] * @param {djs.model.Connection|Object} [hints.connection] * @param {djs.model.Base} [hints.connectionParent] * * @return {djs.model.Shape} the newly created shape */ Modeling.prototype.appendShape = function (source, shape, position, target, hints) { hints = hints || {}; shape = this._create('shape', shape); var context = { source: source, position: position, target: target, shape: shape, connection: hints.connection, connectionParent: hints.connectionParent, hints: hints }; this._commandStack.execute('shape.append', context); return context.shape; }; Modeling.prototype.removeElements = function (elements) { var context = { elements: elements }; this._commandStack.execute('elements.delete', context); }; Modeling.prototype.distributeElements = function (groups, axis, dimension) { var context = { groups: groups, axis: axis, dimension: dimension }; this._commandStack.execute('elements.distribute', context); }; Modeling.prototype.removeShape = function (shape, hints) { var context = { shape: shape, hints: hints || {} }; this._commandStack.execute('shape.delete', context); }; Modeling.prototype.removeConnection = function (connection, hints) { var context = { connection: connection, hints: hints || {} }; this._commandStack.execute('connection.delete', context); }; Modeling.prototype.replaceShape = function (oldShape, newShape, hints) { var context = { oldShape: oldShape, newData: newShape, hints: hints || {} }; this._commandStack.execute('shape.replace', context); return context.newShape; }; Modeling.prototype.alignElements = function (elements, alignment) { var context = { elements: elements, alignment: alignment }; this._commandStack.execute('elements.align', context); }; Modeling.prototype.resizeShape = function (shape, newBounds, minBounds, hints) { var context = { shape: shape, newBounds: newBounds, minBounds: minBounds, hints: hints }; this._commandStack.execute('shape.resize', context); }; Modeling.prototype.createSpace = function (movingShapes, resizingShapes, delta, direction, start) { var context = { delta: delta, direction: direction, movingShapes: movingShapes, resizingShapes: resizingShapes, start: start }; this._commandStack.execute('spaceTool', context); }; Modeling.prototype.updateWaypoints = function (connection, newWaypoints, hints) { var context = { connection: connection, newWaypoints: newWaypoints, hints: hints || {} }; this._commandStack.execute('connection.updateWaypoints', context); }; Modeling.prototype.reconnect = function (connection, source, target, dockingOrPoints, hints) { var context = { connection: connection, newSource: source, newTarget: target, dockingOrPoints: dockingOrPoints, hints: hints || {} }; this._commandStack.execute('connection.reconnect', context); }; Modeling.prototype.reconnectStart = function (connection, newSource, dockingOrPoints, hints) { if (!hints) { hints = {}; } this.reconnect(connection, newSource, connection.target, dockingOrPoints, (0, _minDash.assign)(hints, { docking: 'source' })); }; Modeling.prototype.reconnectEnd = function (connection, newTarget, dockingOrPoints, hints) { if (!hints) { hints = {}; } this.reconnect(connection, connection.source, newTarget, dockingOrPoints, (0, _minDash.assign)(hints, { docking: 'target' })); }; Modeling.prototype.connect = function (source, target, attrs, hints) { return this.createConnection(source, target, attrs || {}, source.parent, hints); }; Modeling.prototype._create = function (type, attrs) { if (attrs instanceof _model.Base) { return attrs; } else { return this._elementFactory.create(type, attrs); } }; Modeling.prototype.toggleCollapse = function (shape, hints) { var context = { shape: shape, hints: hints || {} }; this._commandStack.execute('shape.toggleCollapse', context); }; },{"../../model":302,"./cmd/AlignElementsHandler":223,"./cmd/AppendShapeHandler":224,"./cmd/CreateConnectionHandler":225,"./cmd/CreateElementsHandler":226,"./cmd/CreateLabelHandler":227,"./cmd/CreateShapeHandler":228,"./cmd/DeleteConnectionHandler":229,"./cmd/DeleteElementsHandler":230,"./cmd/DeleteShapeHandler":231,"./cmd/DistributeElementsHandler":232,"./cmd/LayoutConnectionHandler":233,"./cmd/MoveConnectionHandler":234,"./cmd/MoveElementsHandler":235,"./cmd/MoveShapeHandler":236,"./cmd/ReconnectConnectionHandler":237,"./cmd/ReplaceShapeHandler":238,"./cmd/ResizeShapeHandler":239,"./cmd/SpaceToolHandler":240,"./cmd/ToggleShapeCollapseHandler":241,"./cmd/UpdateAttachmentHandler":242,"./cmd/UpdateWaypointsHandler":243,"min-dash":555}],223:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AlignElements; var _minDash = require("min-dash"); /** * A handler that align elements in a certain way. * */ function AlignElements(modeling, canvas) { this._modeling = modeling; this._canvas = canvas; } AlignElements.$inject = ['modeling', 'canvas']; AlignElements.prototype.preExecute = function (context) { var modeling = this._modeling; var elements = context.elements, alignment = context.alignment; (0, _minDash.forEach)(elements, function (element) { var delta = { x: 0, y: 0 }; if (alignment.left) { delta.x = alignment.left - element.x; } else if (alignment.right) { delta.x = alignment.right - element.width - element.x; } else if (alignment.center) { delta.x = alignment.center - Math.round(element.width / 2) - element.x; } else if (alignment.top) { delta.y = alignment.top - element.y; } else if (alignment.bottom) { delta.y = alignment.bottom - element.height - element.y; } else if (alignment.middle) { delta.y = alignment.middle - Math.round(element.height / 2) - element.y; } modeling.moveElements([element], delta, element.parent); }); }; AlignElements.prototype.postExecute = function (context) {}; },{"min-dash":555}],224:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = AppendShapeHandler; var _minDash = require("min-dash"); /** * A handler that implements reversible appending of shapes * to a source shape. * * @param {canvas} Canvas * @param {elementFactory} ElementFactory * @param {modeling} Modeling */ function AppendShapeHandler(modeling) { this._modeling = modeling; } AppendShapeHandler.$inject = ['modeling']; // api ////////////////////// /** * Creates a new shape * * @param {Object} context * @param {ElementDescriptor} context.shape the new shape * @param {ElementDescriptor} context.source the source object * @param {ElementDescriptor} context.parent the parent object * @param {Point} context.position position of the new element */ AppendShapeHandler.prototype.preExecute = function (context) { var source = context.source; if (!source) { throw new Error('source required'); } var target = context.target || source.parent, shape = context.shape, hints = context.hints || {}; shape = context.shape = this._modeling.createShape(shape, context.position, target, { attach: hints.attach }); context.shape = shape; }; AppendShapeHandler.prototype.postExecute = function (context) { var hints = context.hints || {}; if (!existsConnection(context.source, context.shape)) { // create connection if (hints.connectionTarget === context.source) { this._modeling.connect(context.shape, context.source, context.connection); } else { this._modeling.connect(context.source, context.shape, context.connection); } } }; function existsConnection(source, target) { return (0, _minDash.some)(source.outgoing, function (c) { return c.target === target; }); } },{"min-dash":555}],225:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateConnectionHandler; function CreateConnectionHandler(canvas, layouter) { this._canvas = canvas; this._layouter = layouter; } CreateConnectionHandler.$inject = ['canvas', 'layouter']; // api ////////////////////// /** * Appends a shape to a target shape * * @param {Object} context * @param {djs.element.Base} context.source the source object * @param {djs.element.Base} context.target the parent object * @param {Point} context.position position of the new element */ CreateConnectionHandler.prototype.execute = function (context) { var connection = context.connection, source = context.source, target = context.target, parent = context.parent, parentIndex = context.parentIndex, hints = context.hints; if (!source || !target) { throw new Error('source and target required'); } if (!parent) { throw new Error('parent required'); } connection.source = source; connection.target = target; if (!connection.waypoints) { connection.waypoints = this._layouter.layoutConnection(connection, hints); } // add connection this._canvas.addConnection(connection, parent, parentIndex); return connection; }; CreateConnectionHandler.prototype.revert = function (context) { var connection = context.connection; this._canvas.removeConnection(connection); connection.source = null; connection.target = null; return connection; }; },{}],226:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateElementsHandler; var _minDash = require("min-dash"); var _Elements = require("../../../util/Elements"); var round = Math.round; function CreateElementsHandler(modeling) { this._modeling = modeling; } CreateElementsHandler.$inject = ['modeling']; CreateElementsHandler.prototype.preExecute = function (context) { var elements = context.elements, parent = context.parent, parentIndex = context.parentIndex, position = context.position, hints = context.hints; var modeling = this._modeling; // make sure each element has x and y (0, _minDash.forEach)(elements, function (element) { if (!(0, _minDash.isNumber)(element.x)) { element.x = 0; } if (!(0, _minDash.isNumber)(element.y)) { element.y = 0; } }); var bbox = (0, _Elements.getBBox)(elements); // center elements around position (0, _minDash.forEach)(elements, function (element) { if (isConnection(element)) { element.waypoints = (0, _minDash.map)(element.waypoints, function (waypoint) { return { x: round(waypoint.x - bbox.x - bbox.width / 2 + position.x), y: round(waypoint.y - bbox.y - bbox.height / 2 + position.y) }; }); } (0, _minDash.assign)(element, { x: round(element.x - bbox.x - bbox.width / 2 + position.x), y: round(element.y - bbox.y - bbox.height / 2 + position.y) }); }); var parents = (0, _Elements.getParents)(elements); var cache = {}; (0, _minDash.forEach)(elements, function (element) { if (isConnection(element)) { cache[element.id] = (0, _minDash.isNumber)(parentIndex) ? modeling.createConnection(cache[element.source.id], cache[element.target.id], parentIndex, element, element.parent || parent, hints) : modeling.createConnection(cache[element.source.id], cache[element.target.id], element, element.parent || parent, hints); return; } var createShapeHints = (0, _minDash.assign)({}, hints); if (parents.indexOf(element) === -1) { createShapeHints.autoResize = false; } cache[element.id] = (0, _minDash.isNumber)(parentIndex) ? modeling.createShape(element, (0, _minDash.pick)(element, ['x', 'y', 'width', 'height']), element.parent || parent, parentIndex, createShapeHints) : modeling.createShape(element, (0, _minDash.pick)(element, ['x', 'y', 'width', 'height']), element.parent || parent, createShapeHints); }); context.elements = (0, _minDash.values)(cache); }; // helpers ////////// function isConnection(element) { return !!element.waypoints; } },{"../../../util/Elements":315,"min-dash":555}],227:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateLabelHandler; var _inherits = _interopRequireDefault(require("inherits")); var _CreateShapeHandler = _interopRequireDefault(require("./CreateShapeHandler")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A handler that attaches a label to a given target shape. * * @param {Canvas} canvas */ function CreateLabelHandler(canvas) { _CreateShapeHandler.default.call(this, canvas); } (0, _inherits.default)(CreateLabelHandler, _CreateShapeHandler.default); CreateLabelHandler.$inject = ['canvas']; // api ////////////////////// var originalExecute = _CreateShapeHandler.default.prototype.execute; /** * Appends a label to a target shape. * * @method CreateLabelHandler#execute * * @param {Object} context * @param {ElementDescriptor} context.target the element the label is attached to * @param {ElementDescriptor} context.parent the parent object * @param {Point} context.position position of the new element */ CreateLabelHandler.prototype.execute = function (context) { var label = context.shape; ensureValidDimensions(label); label.labelTarget = context.labelTarget; return originalExecute.call(this, context); }; var originalRevert = _CreateShapeHandler.default.prototype.revert; /** * Undo append by removing the shape */ CreateLabelHandler.prototype.revert = function (context) { context.shape.labelTarget = null; return originalRevert.call(this, context); }; // helpers ////////////////////// function ensureValidDimensions(label) { // make sure a label has valid { width, height } dimensions ['width', 'height'].forEach(function (prop) { if (typeof label[prop] === 'undefined') { label[prop] = 0; } }); } },{"./CreateShapeHandler":228,"inherits":347}],228:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateShapeHandler; var _minDash = require("min-dash"); var round = Math.round; /** * A handler that implements reversible addition of shapes. * * @param {canvas} Canvas */ function CreateShapeHandler(canvas) { this._canvas = canvas; } CreateShapeHandler.$inject = ['canvas']; // api ////////////////////// /** * Appends a shape to a target shape * * @param {Object} context * @param {djs.model.Base} context.parent the parent object * @param {Point} context.position position of the new element */ CreateShapeHandler.prototype.execute = function (context) { var shape = context.shape, positionOrBounds = context.position, parent = context.parent, parentIndex = context.parentIndex; if (!parent) { throw new Error('parent required'); } if (!positionOrBounds) { throw new Error('position required'); } // (1) add at event center position _or_ at given bounds if (positionOrBounds.width !== undefined) { (0, _minDash.assign)(shape, positionOrBounds); } else { (0, _minDash.assign)(shape, { x: positionOrBounds.x - round(shape.width / 2), y: positionOrBounds.y - round(shape.height / 2) }); } // (2) add to canvas this._canvas.addShape(shape, parent, parentIndex); return shape; }; /** * Undo append by removing the shape */ CreateShapeHandler.prototype.revert = function (context) { var shape = context.shape; // (3) remove form canvas this._canvas.removeShape(shape); return shape; }; },{"min-dash":555}],229:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteConnectionHandler; var _Collections = require("../../../util/Collections"); /** * A handler that implements reversible deletion of Connections. */ function DeleteConnectionHandler(canvas, modeling) { this._canvas = canvas; this._modeling = modeling; } DeleteConnectionHandler.$inject = ['canvas', 'modeling']; DeleteConnectionHandler.prototype.execute = function (context) { var connection = context.connection, parent = connection.parent; context.parent = parent; // remember containment context.parentIndex = (0, _Collections.indexOf)(parent.children, connection); context.source = connection.source; context.target = connection.target; this._canvas.removeConnection(connection); connection.source = null; connection.target = null; return connection; }; /** * Command revert implementation. */ DeleteConnectionHandler.prototype.revert = function (context) { var connection = context.connection, parent = context.parent, parentIndex = context.parentIndex; connection.source = context.source; connection.target = context.target; // restore containment (0, _Collections.add)(parent.children, connection, parentIndex); this._canvas.addConnection(connection, parent); return connection; }; },{"../../../util/Collections":313}],230:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteElementsHandler; var _minDash = require("min-dash"); function DeleteElementsHandler(modeling, elementRegistry) { this._modeling = modeling; this._elementRegistry = elementRegistry; } DeleteElementsHandler.$inject = ['modeling', 'elementRegistry']; DeleteElementsHandler.prototype.postExecute = function (context) { var modeling = this._modeling, elementRegistry = this._elementRegistry, elements = context.elements; (0, _minDash.forEach)(elements, function (element) { // element may have been removed with previous // remove operations already (e.g. in case of nesting) if (!elementRegistry.get(element.id)) { return; } if (element.waypoints) { modeling.removeConnection(element); } else { modeling.removeShape(element); } }); }; },{"min-dash":555}],231:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DeleteShapeHandler; var _Collections = require("../../../util/Collections"); var _Removal = require("../../../util/Removal"); /** * A handler that implements reversible deletion of shapes. * */ function DeleteShapeHandler(canvas, modeling) { this._canvas = canvas; this._modeling = modeling; } DeleteShapeHandler.$inject = ['canvas', 'modeling']; /** * - Remove connections * - Remove all direct children */ DeleteShapeHandler.prototype.preExecute = function (context) { var modeling = this._modeling; var shape = context.shape; // remove connections (0, _Removal.saveClear)(shape.incoming, function (connection) { // To make sure that the connection isn't removed twice // For example if a container is removed modeling.removeConnection(connection, { nested: true }); }); (0, _Removal.saveClear)(shape.outgoing, function (connection) { modeling.removeConnection(connection, { nested: true }); }); // remove child shapes and connections (0, _Removal.saveClear)(shape.children, function (child) { if (isConnection(child)) { modeling.removeConnection(child, { nested: true }); } else { modeling.removeShape(child, { nested: true }); } }); }; /** * Remove shape and remember the parent */ DeleteShapeHandler.prototype.execute = function (context) { var canvas = this._canvas; var shape = context.shape, oldParent = shape.parent; context.oldParent = oldParent; // remove containment context.oldParentIndex = (0, _Collections.indexOf)(oldParent.children, shape); // remove shape canvas.removeShape(shape); return shape; }; /** * Command revert implementation */ DeleteShapeHandler.prototype.revert = function (context) { var canvas = this._canvas; var shape = context.shape, oldParent = context.oldParent, oldParentIndex = context.oldParentIndex; // restore containment (0, _Collections.add)(oldParent.children, shape, oldParentIndex); canvas.addShape(shape, oldParent); return shape; }; function isConnection(element) { return element.waypoints; } },{"../../../util/Collections":313,"../../../util/Removal":326}],232:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DistributeElements; var _minDash = require("min-dash"); /** * A handler that distributes elements evenly. */ function DistributeElements(modeling) { this._modeling = modeling; } DistributeElements.$inject = ['modeling']; var OFF_AXIS = { x: 'y', y: 'x' }; DistributeElements.prototype.preExecute = function (context) { var modeling = this._modeling; var groups = context.groups, axis = context.axis, dimension = context.dimension; function updateRange(group, element) { group.range.min = Math.min(element[axis], group.range.min); group.range.max = Math.max(element[axis] + element[dimension], group.range.max); } function center(element) { return element[axis] + element[dimension] / 2; } function lastIdx(arr) { return arr.length - 1; } function rangeDiff(range) { return range.max - range.min; } function centerElement(refCenter, element) { var delta = { y: 0 }; delta[axis] = refCenter - center(element); if (delta[axis]) { delta[OFF_AXIS[axis]] = 0; modeling.moveElements([element], delta, element.parent); } } var firstGroup = groups[0], lastGroupIdx = lastIdx(groups), lastGroup = groups[lastGroupIdx]; var margin, spaceInBetween, groupsSize = 0; // the size of each range (0, _minDash.forEach)(groups, function (group, idx) { var sortedElements, refElem, refCenter; if (group.elements.length < 2) { if (idx && idx !== groups.length - 1) { updateRange(group, group.elements[0]); groupsSize += rangeDiff(group.range); } return; } sortedElements = (0, _minDash.sortBy)(group.elements, axis); refElem = sortedElements[0]; if (idx === lastGroupIdx) { refElem = sortedElements[lastIdx(sortedElements)]; } refCenter = center(refElem); // wanna update the ranges after the shapes have been centered group.range = null; (0, _minDash.forEach)(sortedElements, function (element) { centerElement(refCenter, element); if (group.range === null) { group.range = { min: element[axis], max: element[axis] + element[dimension] }; return; } // update group's range after centering the range elements updateRange(group, element); }); if (idx && idx !== groups.length - 1) { groupsSize += rangeDiff(group.range); } }); spaceInBetween = Math.abs(lastGroup.range.min - firstGroup.range.max); margin = Math.round((spaceInBetween - groupsSize) / (groups.length - 1)); if (margin < groups.length - 1) { return; } (0, _minDash.forEach)(groups, function (group, groupIdx) { var delta = {}, prevGroup; if (group === firstGroup || group === lastGroup) { return; } prevGroup = groups[groupIdx - 1]; group.range.max = 0; (0, _minDash.forEach)(group.elements, function (element, idx) { delta[OFF_AXIS[axis]] = 0; delta[axis] = prevGroup.range.max - element[axis] + margin; if (group.range.min !== element[axis]) { delta[axis] += element[axis] - group.range.min; } if (delta[axis]) { modeling.moveElements([element], delta, element.parent); } group.range.max = Math.max(element[axis] + element[dimension], idx ? group.range.max : 0); }); }); }; DistributeElements.prototype.postExecute = function (context) {}; },{"min-dash":555}],233:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = LayoutConnectionHandler; var _minDash = require("min-dash"); /** * A handler that implements reversible moving of shapes. */ function LayoutConnectionHandler(layouter, canvas) { this._layouter = layouter; this._canvas = canvas; } LayoutConnectionHandler.$inject = ['layouter', 'canvas']; LayoutConnectionHandler.prototype.execute = function (context) { var connection = context.connection; var oldWaypoints = connection.waypoints; (0, _minDash.assign)(context, { oldWaypoints: oldWaypoints }); connection.waypoints = this._layouter.layoutConnection(connection, context.hints); return connection; }; LayoutConnectionHandler.prototype.revert = function (context) { var connection = context.connection; connection.waypoints = context.oldWaypoints; return connection; }; },{"min-dash":555}],234:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveConnectionHandler; var _minDash = require("min-dash"); var _Collections = require("../../../util/Collections"); /** * A handler that implements reversible moving of connections. * * The handler differs from the layout connection handler in a sense * that it preserves the connection layout. */ function MoveConnectionHandler() {} MoveConnectionHandler.prototype.execute = function (context) { var connection = context.connection, delta = context.delta; var newParent = context.newParent || connection.parent, newParentIndex = context.newParentIndex, oldParent = connection.parent; // save old parent in context context.oldParent = oldParent; context.oldParentIndex = (0, _Collections.remove)(oldParent.children, connection); // add to new parent at position (0, _Collections.add)(newParent.children, connection, newParentIndex); // update parent connection.parent = newParent; // update waypoint positions (0, _minDash.forEach)(connection.waypoints, function (p) { p.x += delta.x; p.y += delta.y; if (p.original) { p.original.x += delta.x; p.original.y += delta.y; } }); return connection; }; MoveConnectionHandler.prototype.revert = function (context) { var connection = context.connection, newParent = connection.parent, oldParent = context.oldParent, oldParentIndex = context.oldParentIndex, delta = context.delta; // remove from newParent (0, _Collections.remove)(newParent.children, connection); // restore previous location in old parent (0, _Collections.add)(oldParent.children, connection, oldParentIndex); // restore parent connection.parent = oldParent; // revert to old waypoint positions (0, _minDash.forEach)(connection.waypoints, function (p) { p.x -= delta.x; p.y -= delta.y; if (p.original) { p.original.x -= delta.x; p.original.y -= delta.y; } }); return connection; }; },{"../../../util/Collections":313,"min-dash":555}],235:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveElementsHandler; var _MoveHelper = _interopRequireDefault(require("./helper/MoveHelper")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A handler that implements reversible moving of shapes. */ function MoveElementsHandler(modeling) { this._helper = new _MoveHelper.default(modeling); } MoveElementsHandler.$inject = ['modeling']; MoveElementsHandler.prototype.preExecute = function (context) { context.closure = this._helper.getClosure(context.shapes); }; MoveElementsHandler.prototype.postExecute = function (context) { var hints = context.hints, primaryShape; if (hints && hints.primaryShape) { primaryShape = hints.primaryShape; hints.oldParent = primaryShape.parent; } this._helper.moveClosure(context.closure, context.delta, context.newParent, context.newHost, primaryShape); }; },{"./helper/MoveHelper":246}],236:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveShapeHandler; var _minDash = require("min-dash"); var _MoveHelper = _interopRequireDefault(require("./helper/MoveHelper")); var _Collections = require("../../../util/Collections"); var _AnchorsHelper = require("./helper/AnchorsHelper"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A handler that implements reversible moving of shapes. */ function MoveShapeHandler(modeling) { this._modeling = modeling; this._helper = new _MoveHelper.default(modeling); } MoveShapeHandler.$inject = ['modeling']; MoveShapeHandler.prototype.execute = function (context) { var shape = context.shape, delta = context.delta, newParent = context.newParent || shape.parent, newParentIndex = context.newParentIndex, oldParent = shape.parent; context.oldBounds = (0, _minDash.pick)(shape, ['x', 'y', 'width', 'height']); // save old parent in context context.oldParent = oldParent; context.oldParentIndex = (0, _Collections.remove)(oldParent.children, shape); // add to new parent at position (0, _Collections.add)(newParent.children, shape, newParentIndex); // update shape parent + position (0, _minDash.assign)(shape, { parent: newParent, x: shape.x + delta.x, y: shape.y + delta.y }); return shape; }; MoveShapeHandler.prototype.postExecute = function (context) { var shape = context.shape, delta = context.delta, hints = context.hints; var modeling = this._modeling; if (hints.layout !== false) { (0, _minDash.forEach)(shape.incoming, function (c) { modeling.layoutConnection(c, { connectionEnd: (0, _AnchorsHelper.getMovedTargetAnchor)(c, shape, delta) }); }); (0, _minDash.forEach)(shape.outgoing, function (c) { modeling.layoutConnection(c, { connectionStart: (0, _AnchorsHelper.getMovedSourceAnchor)(c, shape, delta) }); }); } if (hints.recurse !== false) { this.moveChildren(context); } }; MoveShapeHandler.prototype.revert = function (context) { var shape = context.shape, oldParent = context.oldParent, oldParentIndex = context.oldParentIndex, delta = context.delta; // restore previous location in old parent (0, _Collections.add)(oldParent.children, shape, oldParentIndex); // revert to old position and parent (0, _minDash.assign)(shape, { parent: oldParent, x: shape.x - delta.x, y: shape.y - delta.y }); return shape; }; MoveShapeHandler.prototype.moveChildren = function (context) { var delta = context.delta, shape = context.shape; this._helper.moveRecursive(shape.children, delta, null); }; MoveShapeHandler.prototype.getNewParent = function (context) { return context.newParent || context.shape.parent; }; },{"../../../util/Collections":313,"./helper/AnchorsHelper":244,"./helper/MoveHelper":246,"min-dash":555}],237:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReconnectConnectionHandler; var _minDash = require("min-dash"); /** * Reconnect connection handler */ function ReconnectConnectionHandler(modeling) { this._modeling = modeling; } ReconnectConnectionHandler.$inject = ['modeling']; ReconnectConnectionHandler.prototype.execute = function (context) { var newSource = context.newSource, newTarget = context.newTarget, connection = context.connection, dockingOrPoints = context.dockingOrPoints; if (!newSource && !newTarget) { throw new Error('newSource or newTarget required'); } if ((0, _minDash.isArray)(dockingOrPoints)) { context.oldWaypoints = connection.waypoints; connection.waypoints = dockingOrPoints; } if (newSource) { context.oldSource = connection.source; connection.source = newSource; } if (newTarget) { context.oldTarget = connection.target; connection.target = newTarget; } return connection; }; ReconnectConnectionHandler.prototype.postExecute = function (context) { var connection = context.connection, newSource = context.newSource, newTarget = context.newTarget, dockingOrPoints = context.dockingOrPoints, hints = context.hints || {}; var layoutConnectionHints = {}; if (hints.connectionStart) { layoutConnectionHints.connectionStart = hints.connectionStart; } if (hints.connectionEnd) { layoutConnectionHints.connectionEnd = hints.connectionEnd; } if (hints.layoutConnection === false) { return; } if (newSource && (!newTarget || hints.docking === 'source')) { layoutConnectionHints.connectionStart = layoutConnectionHints.connectionStart || getDocking((0, _minDash.isArray)(dockingOrPoints) ? dockingOrPoints[0] : dockingOrPoints); } if (newTarget && (!newSource || hints.docking === 'target')) { layoutConnectionHints.connectionEnd = layoutConnectionHints.connectionEnd || getDocking((0, _minDash.isArray)(dockingOrPoints) ? dockingOrPoints[dockingOrPoints.length - 1] : dockingOrPoints); } if (hints.newWaypoints) { layoutConnectionHints.waypoints = hints.newWaypoints; } this._modeling.layoutConnection(connection, layoutConnectionHints); }; ReconnectConnectionHandler.prototype.revert = function (context) { var oldSource = context.oldSource, oldTarget = context.oldTarget, oldWaypoints = context.oldWaypoints, connection = context.connection; if (oldSource) { connection.source = oldSource; } if (oldTarget) { connection.target = oldTarget; } if (oldWaypoints) { connection.waypoints = oldWaypoints; } return connection; }; // helpers ////////// function getDocking(point) { return point.original || point; } },{"min-dash":555}],238:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ReplaceShapeHandler; var _minDash = require("min-dash"); var _AnchorsHelper = require("./helper/AnchorsHelper"); /** * Replace shape by adding new shape and removing old shape. Incoming and outgoing connections will * be kept if possible. * * @class * @constructor * * @param {Modeling} modeling * @param {Rules} rules */ function ReplaceShapeHandler(modeling, rules) { this._modeling = modeling; this._rules = rules; } ReplaceShapeHandler.$inject = ['modeling', 'rules']; /** * Add new shape. * * @param {Object} context * @param {djs.model.Shape} context.oldShape * @param {Object} context.newData * @param {string} context.newData.type * @param {number} context.newData.x * @param {number} context.newData.y * @param {Object} [hints] */ ReplaceShapeHandler.prototype.preExecute = function (context) { var self = this, modeling = this._modeling, rules = this._rules; var oldShape = context.oldShape, newData = context.newData, hints = context.hints || {}, newShape; function canReconnect(source, target, connection) { return rules.allowed('connection.reconnect', { connection: connection, source: source, target: target }); } // (1) add new shape at given position var position = { x: newData.x, y: newData.y }; var oldBounds = { x: oldShape.x, y: oldShape.y, width: oldShape.width, height: oldShape.height }; newShape = context.newShape = context.newShape || self.createShape(newData, position, oldShape.parent, hints); // (2) update host if (oldShape.host) { modeling.updateAttachment(newShape, oldShape.host); } // (3) adopt all children from old shape var children; if (hints.moveChildren !== false) { children = oldShape.children.slice(); modeling.moveElements(children, { x: 0, y: 0 }, newShape, hints); } // (4) reconnect connections to new shape if possible var incoming = oldShape.incoming.slice(), outgoing = oldShape.outgoing.slice(); (0, _minDash.forEach)(incoming, function (connection) { var source = connection.source, allowed = canReconnect(source, newShape, connection); if (allowed) { self.reconnectEnd(connection, newShape, (0, _AnchorsHelper.getResizedTargetAnchor)(connection, newShape, oldBounds), hints); } }); (0, _minDash.forEach)(outgoing, function (connection) { var target = connection.target, allowed = canReconnect(newShape, target, connection); if (allowed) { self.reconnectStart(connection, newShape, (0, _AnchorsHelper.getResizedSourceAnchor)(connection, newShape, oldBounds), hints); } }); }; /** * Remove old shape. */ ReplaceShapeHandler.prototype.postExecute = function (context) { var oldShape = context.oldShape; this._modeling.removeShape(oldShape); }; ReplaceShapeHandler.prototype.execute = function (context) {}; ReplaceShapeHandler.prototype.revert = function (context) {}; ReplaceShapeHandler.prototype.createShape = function (shape, position, target, hints) { return this._modeling.createShape(shape, position, target, hints); }; ReplaceShapeHandler.prototype.reconnectStart = function (connection, newSource, dockingPoint, hints) { this._modeling.reconnectStart(connection, newSource, dockingPoint, hints); }; ReplaceShapeHandler.prototype.reconnectEnd = function (connection, newTarget, dockingPoint, hints) { this._modeling.reconnectEnd(connection, newTarget, dockingPoint, hints); }; },{"./helper/AnchorsHelper":244,"min-dash":555}],239:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeShapeHandler; var _minDash = require("min-dash"); var _AnchorsHelper = require("./helper/AnchorsHelper"); /** * A handler that implements reversible resizing of shapes. * * @param {Modeling} modeling */ function ResizeShapeHandler(modeling) { this._modeling = modeling; } ResizeShapeHandler.$inject = ['modeling']; /** * { * shape: {....} * newBounds: { * width: 20, * height: 40, * x: 5, * y: 10 * } * * } */ ResizeShapeHandler.prototype.execute = function (context) { var shape = context.shape, newBounds = context.newBounds, minBounds = context.minBounds; if (newBounds.x === undefined || newBounds.y === undefined || newBounds.width === undefined || newBounds.height === undefined) { throw new Error('newBounds must have {x, y, width, height} properties'); } if (minBounds && (newBounds.width < minBounds.width || newBounds.height < minBounds.height)) { throw new Error('width and height cannot be less than minimum height and width'); } else if (!minBounds && newBounds.width < 10 || newBounds.height < 10) { throw new Error('width and height cannot be less than 10px'); } // save old bbox in context context.oldBounds = { width: shape.width, height: shape.height, x: shape.x, y: shape.y }; // update shape (0, _minDash.assign)(shape, { width: newBounds.width, height: newBounds.height, x: newBounds.x, y: newBounds.y }); return shape; }; ResizeShapeHandler.prototype.postExecute = function (context) { var modeling = this._modeling; var shape = context.shape, oldBounds = context.oldBounds, hints = context.hints || {}; if (hints.layout === false) { return; } (0, _minDash.forEach)(shape.incoming, function (c) { modeling.layoutConnection(c, { connectionEnd: (0, _AnchorsHelper.getResizedTargetAnchor)(c, shape, oldBounds) }); }); (0, _minDash.forEach)(shape.outgoing, function (c) { modeling.layoutConnection(c, { connectionStart: (0, _AnchorsHelper.getResizedSourceAnchor)(c, shape, oldBounds) }); }); }; ResizeShapeHandler.prototype.revert = function (context) { var shape = context.shape, oldBounds = context.oldBounds; // restore previous bbox (0, _minDash.assign)(shape, { width: oldBounds.width, height: oldBounds.height, x: oldBounds.x, y: oldBounds.y }); return shape; }; },{"./helper/AnchorsHelper":244,"min-dash":555}],240:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceToolHandler; var _minDash = require("min-dash"); var _SpaceUtil = require("../../space-tool/SpaceUtil"); var _AnchorsHelper = require("./helper/AnchorsHelper"); /** * Add or remove space by moving and resizing shapes and updating connection waypoints. */ function SpaceToolHandler(modeling) { this._modeling = modeling; } SpaceToolHandler.$inject = ['modeling']; SpaceToolHandler.prototype.preExecute = function (context) { var delta = context.delta, direction = context.direction, movingShapes = context.movingShapes, resizingShapes = context.resizingShapes, start = context.start, oldBounds = {}; // (1) move shapes this.moveShapes(movingShapes, delta); // (2a) save old bounds of resized shapes (0, _minDash.forEach)(resizingShapes, function (shape) { oldBounds[shape.id] = getBounds(shape); }); // (2b) resize shapes this.resizeShapes(resizingShapes, delta, direction); // (3) update connection waypoints this.updateConnectionWaypoints((0, _SpaceUtil.getWaypointsUpdatingConnections)(movingShapes, resizingShapes), delta, direction, start, movingShapes, resizingShapes, oldBounds); }; SpaceToolHandler.prototype.execute = function () {}; SpaceToolHandler.prototype.revert = function () {}; SpaceToolHandler.prototype.moveShapes = function (shapes, delta) { var self = this; (0, _minDash.forEach)(shapes, function (element) { self._modeling.moveShape(element, delta, null, { autoResize: false, layout: false, recurse: false }); }); }; SpaceToolHandler.prototype.resizeShapes = function (shapes, delta, direction) { var self = this; (0, _minDash.forEach)(shapes, function (shape) { var newBounds = (0, _SpaceUtil.resizeBounds)(shape, direction, delta); self._modeling.resizeShape(shape, newBounds, null, { attachSupport: false, autoResize: false, layout: false }); }); }; /** * Update connections waypoints according to the rules: * 1. Both source and target are moved/resized => move waypoints by the delta * 2. Only one of source and target is moved/resized => re-layout connection with moved start/end */ SpaceToolHandler.prototype.updateConnectionWaypoints = function (connections, delta, direction, start, movingShapes, resizingShapes, oldBounds) { var self = this, affectedShapes = movingShapes.concat(resizingShapes); (0, _minDash.forEach)(connections, function (connection) { var source = connection.source, target = connection.target, waypoints = copyWaypoints(connection), axis = getAxisFromDirection(direction), layoutHints = { labelBehavior: false }; if (includes(affectedShapes, source) && includes(affectedShapes, target)) { // move waypoints waypoints = (0, _minDash.map)(waypoints, function (waypoint) { if (shouldMoveWaypoint(waypoint, start, direction)) { // move waypoint waypoint[axis] = waypoint[axis] + delta[axis]; } if (waypoint.original && shouldMoveWaypoint(waypoint.original, start, direction)) { // move waypoint original waypoint.original[axis] = waypoint.original[axis] + delta[axis]; } return waypoint; }); self._modeling.updateWaypoints(connection, waypoints, { labelBehavior: false }); } else if (includes(affectedShapes, source) || includes(affectedShapes, target)) { // re-layout connection with moved start/end if (includes(movingShapes, source)) { layoutHints.connectionStart = (0, _AnchorsHelper.getMovedSourceAnchor)(connection, source, delta); } else if (includes(movingShapes, target)) { layoutHints.connectionEnd = (0, _AnchorsHelper.getMovedTargetAnchor)(connection, target, delta); } else if (includes(resizingShapes, source)) { layoutHints.connectionStart = (0, _AnchorsHelper.getResizedSourceAnchor)(connection, source, oldBounds[source.id]); } else if (includes(resizingShapes, target)) { layoutHints.connectionEnd = (0, _AnchorsHelper.getResizedTargetAnchor)(connection, target, oldBounds[target.id]); } self._modeling.layoutConnection(connection, layoutHints); } }); }; // helpers ////////// function copyWaypoint(waypoint) { return (0, _minDash.assign)({}, waypoint); } function copyWaypoints(connection) { return (0, _minDash.map)(connection.waypoints, function (waypoint) { waypoint = copyWaypoint(waypoint); if (waypoint.original) { waypoint.original = copyWaypoint(waypoint.original); } return waypoint; }); } function getAxisFromDirection(direction) { switch (direction) { case 'n': return 'y'; case 'w': return 'x'; case 's': return 'y'; case 'e': return 'x'; } } function shouldMoveWaypoint(waypoint, start, direction) { var relevantAxis = getAxisFromDirection(direction); if (/e|s/.test(direction)) { return waypoint[relevantAxis] > start; } else if (/n|w/.test(direction)) { return waypoint[relevantAxis] < start; } } function includes(array, item) { return array.indexOf(item) !== -1; } function getBounds(shape) { return { x: shape.x, y: shape.y, height: shape.height, width: shape.width }; } },{"../../space-tool/SpaceUtil":287,"./helper/AnchorsHelper":244,"min-dash":555}],241:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ToggleShapeCollapseHandler; var _minDash = require("min-dash"); /** * A handler that toggles the collapsed state of an element * and the visibility of all its children. * * @param {Modeling} modeling */ function ToggleShapeCollapseHandler(modeling) { this._modeling = modeling; } ToggleShapeCollapseHandler.$inject = ['modeling']; ToggleShapeCollapseHandler.prototype.execute = function (context) { var shape = context.shape, children = shape.children; // recursively remember previous visibility of children context.oldChildrenVisibility = getElementsVisibilityRecursive(children); // toggle state shape.collapsed = !shape.collapsed; // recursively hide/show children var result = setHiddenRecursive(children, shape.collapsed); return [shape].concat(result); }; ToggleShapeCollapseHandler.prototype.revert = function (context) { var shape = context.shape, oldChildrenVisibility = context.oldChildrenVisibility; var children = shape.children; // recursively set old visability of children var result = restoreVisibilityRecursive(children, oldChildrenVisibility); // retoggle state shape.collapsed = !shape.collapsed; return [shape].concat(result); }; // helpers ////////////////////// /** * Return a map { elementId -> hiddenState}. * * @param {Array<djs.model.Shape>} elements * * @return {Object} */ function getElementsVisibilityRecursive(elements) { var result = {}; (0, _minDash.forEach)(elements, function (element) { result[element.id] = element.hidden; if (element.children) { result = (0, _minDash.assign)({}, result, getElementsVisibilityRecursive(element.children)); } }); return result; } function setHiddenRecursive(elements, newHidden) { var result = []; (0, _minDash.forEach)(elements, function (element) { element.hidden = newHidden; result = result.concat(element); if (element.children) { result = result.concat(setHiddenRecursive(element.children, element.collapsed || newHidden)); } }); return result; } function restoreVisibilityRecursive(elements, lastState) { var result = []; (0, _minDash.forEach)(elements, function (element) { element.hidden = lastState[element.id]; result = result.concat(element); if (element.children) { result = result.concat(restoreVisibilityRecursive(element.children, lastState)); } }); return result; } },{"min-dash":555}],242:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateAttachmentHandler; var _Collections = require("../../../util/Collections"); /** * A handler that implements reversible attaching/detaching of shapes. */ function UpdateAttachmentHandler(modeling) { this._modeling = modeling; } UpdateAttachmentHandler.$inject = ['modeling']; UpdateAttachmentHandler.prototype.execute = function (context) { var shape = context.shape, newHost = context.newHost, oldHost = shape.host; // (0) detach from old host context.oldHost = oldHost; context.attacherIdx = removeAttacher(oldHost, shape); // (1) attach to new host addAttacher(newHost, shape); // (2) update host shape.host = newHost; return shape; }; UpdateAttachmentHandler.prototype.revert = function (context) { var shape = context.shape, newHost = context.newHost, oldHost = context.oldHost, attacherIdx = context.attacherIdx; // (2) update host shape.host = oldHost; // (1) attach to new host removeAttacher(newHost, shape); // (0) detach from old host addAttacher(oldHost, shape, attacherIdx); return shape; }; function removeAttacher(host, attacher) { // remove attacher from host return (0, _Collections.remove)(host && host.attachers, attacher); } function addAttacher(host, attacher, idx) { if (!host) { return; } var attachers = host.attachers; if (!attachers) { host.attachers = attachers = []; } (0, _Collections.add)(attachers, attacher, idx); } },{"../../../util/Collections":313}],243:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = UpdateWaypointsHandler; function UpdateWaypointsHandler() {} UpdateWaypointsHandler.prototype.execute = function (context) { var connection = context.connection, newWaypoints = context.newWaypoints; context.oldWaypoints = connection.waypoints; connection.waypoints = newWaypoints; return connection; }; UpdateWaypointsHandler.prototype.revert = function (context) { var connection = context.connection, oldWaypoints = context.oldWaypoints; connection.waypoints = oldWaypoints; return connection; }; },{}],244:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getResizedSourceAnchor = getResizedSourceAnchor; exports.getResizedTargetAnchor = getResizedTargetAnchor; exports.getMovedSourceAnchor = getMovedSourceAnchor; exports.getMovedTargetAnchor = getMovedTargetAnchor; var _AttachUtil = require("../../../../util/AttachUtil"); var _LayoutUtil = require("../../../../layout/LayoutUtil"); var _minDash = require("min-dash"); function getResizedSourceAnchor(connection, shape, oldBounds) { var waypoints = safeGetWaypoints(connection), waypointsInsideNewBounds = getWaypointsInsideBounds(waypoints, shape), oldAnchor = waypoints[0]; // new anchor is the last waypoint enclosed be resized source if (waypointsInsideNewBounds.length) { return waypointsInsideNewBounds[waypointsInsideNewBounds.length - 1]; } return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape); } function getResizedTargetAnchor(connection, shape, oldBounds) { var waypoints = safeGetWaypoints(connection), waypointsInsideNewBounds = getWaypointsInsideBounds(waypoints, shape), oldAnchor = waypoints[waypoints.length - 1]; // new anchor is the first waypoint enclosed be resized target if (waypointsInsideNewBounds.length) { return waypointsInsideNewBounds[0]; } return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, shape); } function getMovedSourceAnchor(connection, source, moveDelta) { var waypoints = safeGetWaypoints(connection), oldBounds = subtract(source, moveDelta), oldAnchor = waypoints[0]; return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, source); } function getMovedTargetAnchor(connection, target, moveDelta) { var waypoints = safeGetWaypoints(connection), oldBounds = subtract(target, moveDelta), oldAnchor = waypoints[waypoints.length - 1]; return (0, _AttachUtil.getNewAttachPoint)(oldAnchor.original || oldAnchor, oldBounds, target); } // helpers ////////////////////// function subtract(bounds, delta) { return { x: bounds.x - delta.x, y: bounds.y - delta.y, width: bounds.width, height: bounds.height }; } /** * Return waypoints of given connection; throw if non exists (should not happen!!). * * @param {Connection} connection * * @return {Array<Point>} */ function safeGetWaypoints(connection) { var waypoints = connection.waypoints; if (!waypoints.length) { throw new Error('connection#' + connection.id + ': no waypoints'); } return waypoints; } function getWaypointsInsideBounds(waypoints, bounds) { var originalWaypoints = (0, _minDash.map)(waypoints, getOriginal); return (0, _minDash.filter)(originalWaypoints, function (waypoint) { return isInsideBounds(waypoint, bounds); }); } /** * Checks if point is inside bounds, incl. edges. * * @param {Point} point * @param {Bounds} bounds */ function isInsideBounds(point, bounds) { return (0, _LayoutUtil.getOrientation)(bounds, point, 1) === 'intersect'; } function getOriginal(point) { return point.original || point; } },{"../../../../layout/LayoutUtil":300,"../../../../util/AttachUtil":311,"min-dash":555}],245:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveClosure; var _minDash = require("min-dash"); var _Elements = require("../../../../util/Elements"); function MoveClosure() { this.allShapes = {}; this.allConnections = {}; this.enclosedElements = {}; this.enclosedConnections = {}; this.topLevel = {}; } MoveClosure.prototype.add = function (element, isTopLevel) { return this.addAll([element], isTopLevel); }; MoveClosure.prototype.addAll = function (elements, isTopLevel) { var newClosure = (0, _Elements.getClosure)(elements, !!isTopLevel, this); (0, _minDash.assign)(this, newClosure); return this; }; },{"../../../../util/Elements":315,"min-dash":555}],246:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveHelper; var _minDash = require("min-dash"); var _AnchorsHelper = require("./AnchorsHelper"); var _MoveClosure = _interopRequireDefault(require("./MoveClosure")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A helper that is able to carry out serialized move * operations on multiple elements. * * @param {Modeling} modeling */ function MoveHelper(modeling) { this._modeling = modeling; } /** * Move the specified elements and all children by the given delta. * * This moves all enclosed connections, too and layouts all affected * external connections. * * @param {Array<djs.model.Base>} elements * @param {Point} delta * @param {djs.model.Base} newParent applied to the first level of shapes * * @return {Array<djs.model.Base>} list of touched elements */ MoveHelper.prototype.moveRecursive = function (elements, delta, newParent) { if (!elements) { return []; } else { return this.moveClosure(this.getClosure(elements), delta, newParent); } }; /** * Move the given closure of elmements. * * @param {Object} closure * @param {Point} delta * @param {djs.model.Base} [newParent] * @param {djs.model.Base} [newHost] */ MoveHelper.prototype.moveClosure = function (closure, delta, newParent, newHost, primaryShape) { var modeling = this._modeling; var allShapes = closure.allShapes, allConnections = closure.allConnections, enclosedConnections = closure.enclosedConnections, topLevel = closure.topLevel, keepParent = false; if (primaryShape && primaryShape.parent === newParent) { keepParent = true; } // move all shapes (0, _minDash.forEach)(allShapes, function (shape) { // move the element according to the given delta modeling.moveShape(shape, delta, topLevel[shape.id] && !keepParent && newParent, { recurse: false, layout: false }); }); // move all child connections / layout external connections (0, _minDash.forEach)(allConnections, function (c) { var sourceMoved = !!allShapes[c.source.id], targetMoved = !!allShapes[c.target.id]; if (enclosedConnections[c.id] && sourceMoved && targetMoved) { modeling.moveConnection(c, delta, topLevel[c.id] && !keepParent && newParent); } else { modeling.layoutConnection(c, { connectionStart: sourceMoved && (0, _AnchorsHelper.getMovedSourceAnchor)(c, c.source, delta), connectionEnd: targetMoved && (0, _AnchorsHelper.getMovedTargetAnchor)(c, c.target, delta) }); } }); }; /** * Returns the closure for the selected elements * * @param {Array<djs.model.Base>} elements * @return {MoveClosure} closure */ MoveHelper.prototype.getClosure = function (elements) { return new _MoveClosure.default().addAll(elements, true); }; },{"./AnchorsHelper":244,"./MoveClosure":245,"min-dash":555}],247:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Mouse; exports.createMoveEvent = createMoveEvent; function Mouse(eventBus) { var self = this; this._lastMoveEvent = null; function setLastMoveEvent(mousemoveEvent) { self._lastMoveEvent = mousemoveEvent; } eventBus.on('canvas.init', function (context) { var svg = self._svg = context.svg; svg.addEventListener('mousemove', setLastMoveEvent); }); eventBus.on('canvas.destroy', function () { self._lastMouseEvent = null; self._svg.removeEventListener('mousemove', setLastMoveEvent); }); } Mouse.$inject = ['eventBus']; Mouse.prototype.getLastMoveEvent = function () { return this._lastMoveEvent || createMoveEvent(0, 0); }; // helpers ////////// function createMoveEvent(x, y) { var event = document.createEvent('MouseEvent'); var screenX = x, screenY = y, clientX = x, clientY = y; if (event.initMouseEvent) { event.initMouseEvent('mousemove', true, true, window, 0, screenX, screenY, clientX, clientY, false, false, false, false, 0, null); } return event; } },{}],248:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Mouse = _interopRequireDefault(require("./Mouse")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['mouse'], mouse: ['type', _Mouse.default] }; exports.default = _default; },{"./Mouse":247}],249:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveEvents; var _minDash = require("min-dash"); var _Event = require("../../util/Event"); var LOW_PRIORITY = 500, MEDIUM_PRIORITY = 1250, HIGH_PRIORITY = 1500; var round = Math.round; function mid(element) { return { x: element.x + round(element.width / 2), y: element.y + round(element.height / 2) }; } /** * A plugin that makes shapes draggable / droppable. * * @param {EventBus} eventBus * @param {Dragging} dragging * @param {Modeling} modeling * @param {Selection} selection * @param {Rules} rules */ function MoveEvents(eventBus, dragging, modeling, selection, rules) { // rules function canMove(shapes, delta, position, target) { return rules.allowed('elements.move', { shapes: shapes, delta: delta, position: position, target: target }); } // move events // assign a high priority to this handler to setup the environment // others may hook up later, e.g. at default priority and modify // the move environment. // // This sets up the context with // // * shape: the primary shape being moved // * shapes: a list of shapes to be moved // * validatedShapes: a list of shapes that are being checked // against the rules before and during move // eventBus.on('shape.move.start', HIGH_PRIORITY, function (event) { var context = event.context, shape = event.shape, shapes = selection.get().slice(); // move only single shape if the dragged element // is not part of the current selection if (shapes.indexOf(shape) === -1) { shapes = [shape]; } // ensure we remove nested elements in the collection // and add attachers for a proper dragger shapes = removeNested(shapes); // attach shapes to drag context (0, _minDash.assign)(context, { shapes: shapes, validatedShapes: shapes, shape: shape }); }); // assign a high priority to this handler to setup the environment // others may hook up later, e.g. at default priority and modify // the move environment // eventBus.on('shape.move.start', MEDIUM_PRIORITY, function (event) { var context = event.context, validatedShapes = context.validatedShapes, canExecute; canExecute = context.canExecute = canMove(validatedShapes); // check if we can move the elements if (!canExecute) { return false; } }); // assign a low priority to this handler // to let others modify the move event before we update // the context // eventBus.on('shape.move.move', LOW_PRIORITY, function (event) { var context = event.context, validatedShapes = context.validatedShapes, hover = event.hover, delta = { x: event.dx, y: event.dy }, position = { x: event.x, y: event.y }, canExecute; // check if we can move the elements canExecute = canMove(validatedShapes, delta, position, hover); context.delta = delta; context.canExecute = canExecute; // simply ignore move over if (canExecute === null) { context.target = null; return; } context.target = hover; }); eventBus.on('shape.move.end', function (event) { var context = event.context; var delta = context.delta, canExecute = context.canExecute, isAttach = canExecute === 'attach', shapes = context.shapes; if (canExecute === false) { return false; } // ensure we have actual pixel values deltas // (important when zoom level was > 1 during move) delta.x = round(delta.x); delta.y = round(delta.y); if (delta.x === 0 && delta.y === 0) { // didn't move return; } modeling.moveElements(shapes, delta, context.target, { primaryShape: context.shape, attach: isAttach }); }); // move activation eventBus.on('element.mousedown', function (event) { var originalEvent = (0, _Event.getOriginal)(event); if (!originalEvent) { throw new Error('must supply DOM mousedown event'); } return start(originalEvent, event.element); }); /** * Start move. * * @param {MouseEvent} event * @param {djs.model.Shape} shape * @param {boolean} [activate] * @param {Object} [context] */ function start(event, element, activate, context) { if ((0, _minDash.isObject)(activate)) { context = activate; activate = false; } // do not move connections or the root element if (element.waypoints || !element.parent) { return; } var referencePoint = mid(element); dragging.init(event, referencePoint, 'shape.move', { cursor: 'grabbing', autoActivate: activate, data: { shape: element, context: context || {} } }); // we've handled the event return true; } // API this.start = start; } MoveEvents.$inject = ['eventBus', 'dragging', 'modeling', 'selection', 'rules']; /** * Return a filtered list of elements that do not contain * those nested into others. * * @param {Array<djs.model.Base>} elements * * @return {Array<djs.model.Base>} filtered */ function removeNested(elements) { var ids = (0, _minDash.groupBy)(elements, 'id'); return (0, _minDash.filter)(elements, function (element) { while (element = element.parent) { // parent in selection if (ids[element.id]) { return false; } } return true; }); } },{"../../util/Event":317,"min-dash":555}],250:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MovePreview; var _minDash = require("min-dash"); var _Elements = require("../../util/Elements"); var _tinySvg = require("tiny-svg"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var LOW_PRIORITY = 499; var MARKER_DRAGGING = 'djs-dragging', MARKER_OK = 'drop-ok', MARKER_NOT_OK = 'drop-not-ok', MARKER_NEW_PARENT = 'new-parent', MARKER_ATTACH = 'attach-ok'; /** * Provides previews for moving shapes when moving. * * @param {EventBus} eventBus * @param {ElementRegistry} elementRegistry * @param {Canvas} canvas * @param {Styles} styles */ function MovePreview(eventBus, canvas, styles, previewSupport) { function getVisualDragShapes(shapes) { var elements = getAllDraggedElements(shapes); var filteredElements = removeEdges(elements); return filteredElements; } function getAllDraggedElements(shapes) { var allShapes = (0, _Elements.selfAndAllChildren)(shapes, true); var allConnections = (0, _minDash.map)(allShapes, function (shape) { return (shape.incoming || []).concat(shape.outgoing || []); }); return (0, _minDash.flatten)(allShapes.concat(allConnections)); } /** * Sets drop marker on an element. */ function setMarker(element, marker) { [MARKER_ATTACH, MARKER_OK, MARKER_NOT_OK, MARKER_NEW_PARENT].forEach(function (m) { if (m === marker) { canvas.addMarker(element, m); } else { canvas.removeMarker(element, m); } }); } /** * Make an element draggable. * * @param {Object} context * @param {djs.model.Base} element * @param {boolean} addMarker */ function makeDraggable(context, element, addMarker) { previewSupport.addDragger(element, context.dragGroup); if (addMarker) { canvas.addMarker(element, MARKER_DRAGGING); } if (context.allDraggedElements) { context.allDraggedElements.push(element); } else { context.allDraggedElements = [element]; } } // assign a low priority to this handler // to let others modify the move context before // we draw things eventBus.on('shape.move.start', LOW_PRIORITY, function (event) { var context = event.context, dragShapes = context.shapes, allDraggedElements = context.allDraggedElements; var visuallyDraggedShapes = getVisualDragShapes(dragShapes); if (!context.dragGroup) { var dragGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events'])); var defaultLayer = canvas.getDefaultLayer(); (0, _tinySvg.append)(defaultLayer, dragGroup); context.dragGroup = dragGroup; } // add previews visuallyDraggedShapes.forEach(function (shape) { previewSupport.addDragger(shape, context.dragGroup); }); // cache all dragged elements / gfx // so that we can quickly undo their state changes later if (!allDraggedElements) { allDraggedElements = getAllDraggedElements(dragShapes); } else { allDraggedElements = (0, _minDash.flatten)([allDraggedElements, getAllDraggedElements(dragShapes)]); } // add dragging marker (0, _minDash.forEach)(allDraggedElements, function (e) { canvas.addMarker(e, MARKER_DRAGGING); }); context.allDraggedElements = allDraggedElements; // determine, if any of the dragged elements have different parents context.differentParents = haveDifferentParents(dragShapes); }); // update previews eventBus.on('shape.move.move', LOW_PRIORITY, function (event) { var context = event.context, dragGroup = context.dragGroup, target = context.target, parent = context.shape.parent, canExecute = context.canExecute; if (target) { if (canExecute === 'attach') { setMarker(target, MARKER_ATTACH); } else if (context.canExecute && target && target.id !== parent.id) { setMarker(target, MARKER_NEW_PARENT); } else { setMarker(target, context.canExecute ? MARKER_OK : MARKER_NOT_OK); } } (0, _SvgTransformUtil.translate)(dragGroup, event.dx, event.dy); }); eventBus.on(['shape.move.out', 'shape.move.cleanup'], function (event) { var context = event.context, target = context.target; if (target) { setMarker(target, null); } }); // remove previews eventBus.on('shape.move.cleanup', function (event) { var context = event.context, allDraggedElements = context.allDraggedElements, dragGroup = context.dragGroup; // remove dragging marker (0, _minDash.forEach)(allDraggedElements, function (e) { canvas.removeMarker(e, MARKER_DRAGGING); }); if (dragGroup) { (0, _tinySvg.remove)(dragGroup); } }); // API ////////////////////// /** * Make an element draggable. * * @param {Object} context * @param {djs.model.Base} element * @param {boolean} addMarker */ this.makeDraggable = makeDraggable; } MovePreview.$inject = ['eventBus', 'canvas', 'styles', 'previewSupport']; // helpers ////////////////////// /** * returns elements minus all connections * where source or target is not elements */ function removeEdges(elements) { var filteredElements = (0, _minDash.filter)(elements, function (element) { if (!isConnection(element)) { return true; } else { return (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.source.id })) && (0, _minDash.find)(elements, (0, _minDash.matchPattern)({ id: element.target.id })); } }); return filteredElements; } function haveDifferentParents(elements) { return (0, _minDash.size)((0, _minDash.groupBy)(elements, function (e) { return e.parent && e.parent.id; })) !== 1; } /** * Checks if an element is a connection. */ function isConnection(element) { return element.waypoints; } },{"../../util/Elements":315,"../../util/SvgTransformUtil":328,"min-dash":555,"tiny-svg":567}],251:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("../interaction-events")); var _selection = _interopRequireDefault(require("../selection")); var _outline = _interopRequireDefault(require("../outline")); var _rules = _interopRequireDefault(require("../rules")); var _dragging = _interopRequireDefault(require("../dragging")); var _previewSupport = _interopRequireDefault(require("../preview-support")); var _Move = _interopRequireDefault(require("./Move")); var _MovePreview = _interopRequireDefault(require("./MovePreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_interactionEvents.default, _selection.default, _outline.default, _rules.default, _dragging.default, _previewSupport.default], __init__: ['move', 'movePreview'], move: ['type', _Move.default], movePreview: ['type', _MovePreview.default] }; exports.default = _default; },{"../dragging":197,"../interaction-events":211,"../outline":254,"../preview-support":262,"../rules":272,"../selection":278,"./Move":249,"./MovePreview":250}],252:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = OrderingProvider; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * An abstract provider that allows modelers to implement a custom * ordering of diagram elements on the canvas. * * It makes sure that the order is always preserved during element * creation and move operations. * * In order to use this behavior, inherit from it and override * the method {@link OrderingProvider#getOrdering}. * * @example * * ```javascript * function CustomOrderingProvider(eventBus) { * OrderingProvider.call(this, eventBus); * * this.getOrdering = function(element, newParent) { * // always insert elements at the front * // when moving * return { * index: 0, * parent: newParent * }; * }; * } * ``` * * @param {EventBus} eventBus */ function OrderingProvider(eventBus) { _CommandInterceptor.default.call(this, eventBus); var self = this; this.preExecute(['shape.create', 'connection.create'], function (event) { var context = event.context, element = context.shape || context.connection, parent = context.parent; var ordering = self.getOrdering(element, parent); if (ordering) { if (ordering.parent !== undefined) { context.parent = ordering.parent; } context.parentIndex = ordering.index; } }); this.preExecute(['shape.move', 'connection.move'], function (event) { var context = event.context, element = context.shape || context.connection, parent = context.newParent || element.parent; var ordering = self.getOrdering(element, parent); if (ordering) { if (ordering.parent !== undefined) { context.newParent = ordering.parent; } context.newParentIndex = ordering.index; } }); } /** * Return a custom ordering of the element, both in terms * of parent element and index in the new parent. * * Implementors of this method must return an object with * `parent` _and_ `index` in it. * * @param {djs.model.Base} element * @param {djs.model.Shape} newParent * * @return {Object} ordering descriptor */ OrderingProvider.prototype.getOrdering = function (element, newParent) { return null; }; (0, _inherits.default)(OrderingProvider, _CommandInterceptor.default); },{"../../command/CommandInterceptor":145,"inherits":347}],253:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Outline; var _Elements = require("../../util/Elements"); var _tinySvg = require("tiny-svg"); var _minDom = require("min-dom"); var _minDash = require("min-dash"); var LOW_PRIORITY = 500; /** * @class * * A plugin that adds an outline to shapes and connections that may be activated and styled * via CSS classes. * * @param {EventBus} eventBus * @param {Styles} styles * @param {ElementRegistry} elementRegistry */ function Outline(eventBus, styles, elementRegistry) { this.offset = 6; var OUTLINE_STYLE = styles.cls('djs-outline', ['no-fill']); var self = this; function createOutline(gfx, bounds) { var outline = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(outline, (0, _minDash.assign)({ x: 10, y: 10, width: 100, height: 100 }, OUTLINE_STYLE)); (0, _tinySvg.append)(gfx, outline); return outline; } // A low priortity is necessary, because outlines of labels have to be updated // after the label bounds have been updated in the renderer. eventBus.on(['shape.added', 'shape.changed'], LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; var outline = (0, _minDom.query)('.djs-outline', gfx); if (!outline) { outline = createOutline(gfx, element); } self.updateShapeOutline(outline, element); }); eventBus.on(['connection.added', 'connection.changed'], function (event) { var element = event.element, gfx = event.gfx; var outline = (0, _minDom.query)('.djs-outline', gfx); if (!outline) { outline = createOutline(gfx, element); } self.updateConnectionOutline(outline, element); }); } /** * Updates the outline of a shape respecting the dimension of the * element and an outline offset. * * @param {SVGElement} outline * @param {djs.model.Base} element */ Outline.prototype.updateShapeOutline = function (outline, element) { (0, _tinySvg.attr)(outline, { x: -this.offset, y: -this.offset, width: element.width + this.offset * 2, height: element.height + this.offset * 2 }); }; /** * Updates the outline of a connection respecting the bounding box of * the connection and an outline offset. * * @param {SVGElement} outline * @param {djs.model.Base} element */ Outline.prototype.updateConnectionOutline = function (outline, connection) { var bbox = (0, _Elements.getBBox)(connection); (0, _tinySvg.attr)(outline, { x: bbox.x - this.offset, y: bbox.y - this.offset, width: bbox.width + this.offset * 2, height: bbox.height + this.offset * 2 }); }; Outline.$inject = ['eventBus', 'styles', 'elementRegistry']; },{"../../util/Elements":315,"min-dash":555,"min-dom":556,"tiny-svg":567}],254:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Outline = _interopRequireDefault(require("./Outline")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['outline'], outline: ['type', _Outline.default] }; exports.default = _default; },{"./Outline":253}],255:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Overlays; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _Elements = require("../../util/Elements"); var _IdGenerator = _interopRequireDefault(require("../../util/IdGenerator")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // document wide unique overlay ids var ids = new _IdGenerator.default('ov'); var LOW_PRIORITY = 500; /** * A service that allows users to attach overlays to diagram elements. * * The overlay service will take care of overlay positioning during updates. * * @example * * // add a pink badge on the top left of the shape * overlays.add(someShape, { * position: { * top: -5, * left: -5 * }, * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>' * }); * * // or add via shape id * * overlays.add('some-element-id', { * position: { * top: -5, * left: -5 * } * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>' * }); * * // or add with optional type * * overlays.add(someShape, 'badge', { * position: { * top: -5, * left: -5 * } * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>' * }); * * * // remove an overlay * * var id = overlays.add(...); * overlays.remove(id); * * * You may configure overlay defaults during tool by providing a `config` module * with `overlays.defaults` as an entry: * * { * overlays: { * defaults: { * show: { * minZoom: 0.7, * maxZoom: 5.0 * }, * scale: { * min: 1 * } * } * } * * @param {Object} config * @param {EventBus} eventBus * @param {Canvas} canvas * @param {ElementRegistry} elementRegistry */ function Overlays(config, eventBus, canvas, elementRegistry) { this._eventBus = eventBus; this._canvas = canvas; this._elementRegistry = elementRegistry; this._ids = ids; this._overlayDefaults = (0, _minDash.assign)({ // no show constraints show: null, // always scale scale: true }, config && config.defaults); /** * Mapping overlayId -> overlay */ this._overlays = {}; /** * Mapping elementId -> overlay container */ this._overlayContainers = []; // root html element for all overlays this._overlayRoot = createRoot(canvas.getContainer()); this._init(); } Overlays.$inject = ['config.overlays', 'eventBus', 'canvas', 'elementRegistry']; /** * Returns the overlay with the specified id or a list of overlays * for an element with a given type. * * @example * * // return the single overlay with the given id * overlays.get('some-id'); * * // return all overlays for the shape * overlays.get({ element: someShape }); * * // return all overlays on shape with type 'badge' * overlays.get({ element: someShape, type: 'badge' }); * * // shape can also be specified as id * overlays.get({ element: 'element-id', type: 'badge' }); * * * @param {Object} search * @param {string} [search.id] * @param {string|djs.model.Base} [search.element] * @param {string} [search.type] * * @return {Object|Array<Object>} the overlay(s) */ Overlays.prototype.get = function (search) { if ((0, _minDash.isString)(search)) { search = { id: search }; } if ((0, _minDash.isString)(search.element)) { search.element = this._elementRegistry.get(search.element); } if (search.element) { var container = this._getOverlayContainer(search.element, true); // return a list of overlays when searching by element (+type) if (container) { return search.type ? (0, _minDash.filter)(container.overlays, (0, _minDash.matchPattern)({ type: search.type })) : container.overlays.slice(); } else { return []; } } else if (search.type) { return (0, _minDash.filter)(this._overlays, (0, _minDash.matchPattern)({ type: search.type })); } else { // return single element when searching by id return search.id ? this._overlays[search.id] : null; } }; /** * Adds a HTML overlay to an element. * * @param {string|djs.model.Base} element attach overlay to this shape * @param {string} [type] optional type to assign to the overlay * @param {Object} overlay the overlay configuration * * @param {string|DOMElement} overlay.html html element to use as an overlay * @param {Object} [overlay.show] show configuration * @param {number} [overlay.show.minZoom] minimal zoom level to show the overlay * @param {number} [overlay.show.maxZoom] maximum zoom level to show the overlay * @param {Object} overlay.position where to attach the overlay * @param {number} [overlay.position.left] relative to element bbox left attachment * @param {number} [overlay.position.top] relative to element bbox top attachment * @param {number} [overlay.position.bottom] relative to element bbox bottom attachment * @param {number} [overlay.position.right] relative to element bbox right attachment * @param {boolean|Object} [overlay.scale=true] false to preserve the same size regardless of * diagram zoom * @param {number} [overlay.scale.min] * @param {number} [overlay.scale.max] * * @return {string} id that may be used to reference the overlay for update or removal */ Overlays.prototype.add = function (element, type, overlay) { if ((0, _minDash.isObject)(type)) { overlay = type; type = null; } if (!element.id) { element = this._elementRegistry.get(element); } if (!overlay.position) { throw new Error('must specifiy overlay position'); } if (!overlay.html) { throw new Error('must specifiy overlay html'); } if (!element) { throw new Error('invalid element specified'); } var id = this._ids.next(); overlay = (0, _minDash.assign)({}, this._overlayDefaults, overlay, { id: id, type: type, element: element, html: overlay.html }); this._addOverlay(overlay); return id; }; /** * Remove an overlay with the given id or all overlays matching the given filter. * * @see Overlays#get for filter options. * * @param {string} [id] * @param {Object} [filter] */ Overlays.prototype.remove = function (filter) { var overlays = this.get(filter) || []; if (!(0, _minDash.isArray)(overlays)) { overlays = [overlays]; } var self = this; (0, _minDash.forEach)(overlays, function (overlay) { var container = self._getOverlayContainer(overlay.element, true); if (overlay) { (0, _minDom.remove)(overlay.html); (0, _minDom.remove)(overlay.htmlContainer); delete overlay.htmlContainer; delete overlay.element; delete self._overlays[overlay.id]; } if (container) { var idx = container.overlays.indexOf(overlay); if (idx !== -1) { container.overlays.splice(idx, 1); } } }); }; Overlays.prototype.show = function () { setVisible(this._overlayRoot); }; Overlays.prototype.hide = function () { setVisible(this._overlayRoot, false); }; Overlays.prototype.clear = function () { this._overlays = {}; this._overlayContainers = []; (0, _minDom.clear)(this._overlayRoot); }; Overlays.prototype._updateOverlayContainer = function (container) { var element = container.element, html = container.html; // update container left,top according to the elements x,y coordinates // this ensures we can attach child elements relative to this container var x = element.x, y = element.y; if (element.waypoints) { var bbox = (0, _Elements.getBBox)(element); x = bbox.x; y = bbox.y; } setPosition(html, x, y); (0, _minDom.attr)(container.html, 'data-container-id', element.id); }; Overlays.prototype._updateOverlay = function (overlay) { var position = overlay.position, htmlContainer = overlay.htmlContainer, element = overlay.element; // update overlay html relative to shape because // it is already positioned on the element // update relative var left = position.left, top = position.top; if (position.right !== undefined) { var width; if (element.waypoints) { width = (0, _Elements.getBBox)(element).width; } else { width = element.width; } left = position.right * -1 + width; } if (position.bottom !== undefined) { var height; if (element.waypoints) { height = (0, _Elements.getBBox)(element).height; } else { height = element.height; } top = position.bottom * -1 + height; } setPosition(htmlContainer, left || 0, top || 0); }; Overlays.prototype._createOverlayContainer = function (element) { var html = (0, _minDom.domify)('<div class="djs-overlays" style="position: absolute" />'); this._overlayRoot.appendChild(html); var container = { html: html, element: element, overlays: [] }; this._updateOverlayContainer(container); this._overlayContainers.push(container); return container; }; Overlays.prototype._updateRoot = function (viewbox) { var scale = viewbox.scale || 1; var matrix = 'matrix(' + [scale, 0, 0, scale, -1 * viewbox.x * scale, -1 * viewbox.y * scale].join(',') + ')'; setTransform(this._overlayRoot, matrix); }; Overlays.prototype._getOverlayContainer = function (element, raw) { var container = (0, _minDash.find)(this._overlayContainers, function (c) { return c.element === element; }); if (!container && !raw) { return this._createOverlayContainer(element); } return container; }; Overlays.prototype._addOverlay = function (overlay) { var id = overlay.id, element = overlay.element, html = overlay.html, htmlContainer, overlayContainer; // unwrap jquery (for those who need it) if (html.get && html.constructor.prototype.jquery) { html = html.get(0); } // create proper html elements from // overlay HTML strings if ((0, _minDash.isString)(html)) { html = (0, _minDom.domify)(html); } overlayContainer = this._getOverlayContainer(element); htmlContainer = (0, _minDom.domify)('<div class="djs-overlay" data-overlay-id="' + id + '" style="position: absolute">'); htmlContainer.appendChild(html); if (overlay.type) { (0, _minDom.classes)(htmlContainer).add('djs-overlay-' + overlay.type); } overlay.htmlContainer = htmlContainer; overlayContainer.overlays.push(overlay); overlayContainer.html.appendChild(htmlContainer); this._overlays[id] = overlay; this._updateOverlay(overlay); this._updateOverlayVisibilty(overlay, this._canvas.viewbox()); }; Overlays.prototype._updateOverlayVisibilty = function (overlay, viewbox) { var show = overlay.show, minZoom = show && show.minZoom, maxZoom = show && show.maxZoom, htmlContainer = overlay.htmlContainer, visible = true; if (show) { if ((0, _minDash.isDefined)(minZoom) && minZoom > viewbox.scale || (0, _minDash.isDefined)(maxZoom) && maxZoom < viewbox.scale) { visible = false; } setVisible(htmlContainer, visible); } this._updateOverlayScale(overlay, viewbox); }; Overlays.prototype._updateOverlayScale = function (overlay, viewbox) { var shouldScale = overlay.scale, minScale, maxScale, htmlContainer = overlay.htmlContainer; var scale, transform = ''; if (shouldScale !== true) { if (shouldScale === false) { minScale = 1; maxScale = 1; } else { minScale = shouldScale.min; maxScale = shouldScale.max; } if ((0, _minDash.isDefined)(minScale) && viewbox.scale < minScale) { scale = (1 / viewbox.scale || 1) * minScale; } if ((0, _minDash.isDefined)(maxScale) && viewbox.scale > maxScale) { scale = (1 / viewbox.scale || 1) * maxScale; } } if ((0, _minDash.isDefined)(scale)) { transform = 'scale(' + scale + ',' + scale + ')'; } setTransform(htmlContainer, transform); }; Overlays.prototype._updateOverlaysVisibilty = function (viewbox) { var self = this; (0, _minDash.forEach)(this._overlays, function (overlay) { self._updateOverlayVisibilty(overlay, viewbox); }); }; Overlays.prototype._init = function () { var eventBus = this._eventBus; var self = this; // scroll/zoom integration function updateViewbox(viewbox) { self._updateRoot(viewbox); self._updateOverlaysVisibilty(viewbox); self.show(); } eventBus.on('canvas.viewbox.changing', function (event) { self.hide(); }); eventBus.on('canvas.viewbox.changed', function (event) { updateViewbox(event.viewbox); }); // remove integration eventBus.on(['shape.remove', 'connection.remove'], function (e) { var element = e.element; var overlays = self.get({ element: element }); (0, _minDash.forEach)(overlays, function (o) { self.remove(o.id); }); var container = self._getOverlayContainer(element); if (container) { (0, _minDom.remove)(container.html); var i = self._overlayContainers.indexOf(container); if (i !== -1) { self._overlayContainers.splice(i, 1); } } }); // move integration eventBus.on('element.changed', LOW_PRIORITY, function (e) { var element = e.element; var container = self._getOverlayContainer(element, true); if (container) { (0, _minDash.forEach)(container.overlays, function (overlay) { self._updateOverlay(overlay); }); self._updateOverlayContainer(container); } }); // marker integration, simply add them on the overlays as classes, too. eventBus.on('element.marker.update', function (e) { var container = self._getOverlayContainer(e.element, true); if (container) { (0, _minDom.classes)(container.html)[e.add ? 'add' : 'remove'](e.marker); } }); // clear overlays with diagram eventBus.on('diagram.clear', this.clear, this); }; // helpers ///////////////////////////// function createRoot(parentNode) { var root = (0, _minDom.domify)('<div class="djs-overlay-container" style="position: absolute; width: 0; height: 0;" />'); parentNode.insertBefore(root, parentNode.firstChild); return root; } function setPosition(el, x, y) { (0, _minDash.assign)(el.style, { left: x + 'px', top: y + 'px' }); } function setVisible(el, visible) { el.style.display = visible === false ? 'none' : ''; } function setTransform(el, transform) { el.style['transform-origin'] = 'top left'; ['', '-ms-', '-webkit-'].forEach(function (prefix) { el.style[prefix + 'transform'] = transform; }); } },{"../../util/Elements":315,"../../util/IdGenerator":320,"min-dash":555,"min-dom":556}],256:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Overlays = _interopRequireDefault(require("./Overlays")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['overlays'], overlays: ['type', _Overlays.default] }; exports.default = _default; },{"./Overlays":255}],257:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Palette; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var TOGGLE_SELECTOR = '.djs-palette-toggle', ENTRY_SELECTOR = '.entry', ELEMENT_SELECTOR = TOGGLE_SELECTOR + ', ' + ENTRY_SELECTOR; var PALETTE_OPEN_CLS = 'open', PALETTE_TWO_COLUMN_CLS = 'two-column'; var DEFAULT_PRIORITY = 1000; /** * A palette containing modeling elements. */ function Palette(eventBus, canvas) { this._eventBus = eventBus; this._canvas = canvas; var self = this; eventBus.on('tool-manager.update', function (event) { var tool = event.tool; self.updateToolHighlight(tool); }); eventBus.on('i18n.changed', function () { self._update(); }); eventBus.on('diagram.init', function () { self._diagramInitialized = true; self._rebuild(); }); } Palette.$inject = ['eventBus', 'canvas']; /** * Register a provider with the palette * * @param {number} [priority=1000] * @param {PaletteProvider} provider * * @example * const paletteProvider = { * getPaletteEntries: function() { * return function(entries) { * return { * ...entries, * 'entry-1': { * label: 'My Entry', * action: function() { alert("I have been clicked!"); } * } * }; * } * } * }; * * palette.registerProvider(800, paletteProvider); */ Palette.prototype.registerProvider = function (priority, provider) { if (!provider) { provider = priority; priority = DEFAULT_PRIORITY; } this._eventBus.on('palette.getProviders', priority, function (event) { event.providers.push(provider); }); this._rebuild(); }; /** * Returns the palette entries * * @return {Object<string, PaletteEntryDescriptor>} map of entries */ Palette.prototype.getEntries = function () { var providers = this._getProviders(); return providers.reduce(addPaletteEntries, {}); }; Palette.prototype._rebuild = function () { if (!this._diagramInitialized) { return; } var providers = this._getProviders(); if (!providers.length) { return; } if (!this._container) { this._init(); } this._update(); }; /** * Initialize */ Palette.prototype._init = function () { var self = this; var eventBus = this._eventBus; var parentContainer = this._getParentContainer(); var container = this._container = (0, _minDom.domify)(Palette.HTML_MARKUP); parentContainer.appendChild(container); _minDom.delegate.bind(container, ELEMENT_SELECTOR, 'click', function (event) { var target = event.delegateTarget; if ((0, _minDom.matches)(target, TOGGLE_SELECTOR)) { return self.toggle(); } self.trigger('click', event); }); // prevent drag propagation _minDom.event.bind(container, 'mousedown', function (event) { event.stopPropagation(); }); // prevent drag propagation _minDom.delegate.bind(container, ENTRY_SELECTOR, 'dragstart', function (event) { self.trigger('dragstart', event); }); eventBus.on('canvas.resized', this._layoutChanged, this); eventBus.fire('palette.create', { container: container }); }; Palette.prototype._getProviders = function (id) { var event = this._eventBus.createEvent({ type: 'palette.getProviders', providers: [] }); this._eventBus.fire(event); return event.providers; }; /** * Update palette state. * * @param {Object} [state] { open, twoColumn } */ Palette.prototype._toggleState = function (state) { state = state || {}; var parent = this._getParentContainer(), container = this._container; var eventBus = this._eventBus; var twoColumn; var cls = (0, _minDom.classes)(container); if ('twoColumn' in state) { twoColumn = state.twoColumn; } else { twoColumn = this._needsCollapse(parent.clientHeight, this._entries || {}); } // always update two column cls.toggle(PALETTE_TWO_COLUMN_CLS, twoColumn); if ('open' in state) { cls.toggle(PALETTE_OPEN_CLS, state.open); } eventBus.fire('palette.changed', { twoColumn: twoColumn, open: this.isOpen() }); }; Palette.prototype._update = function () { var entriesContainer = (0, _minDom.query)('.djs-palette-entries', this._container), entries = this._entries = this.getEntries(); (0, _minDom.clear)(entriesContainer); (0, _minDash.forEach)(entries, function (entry, id) { var grouping = entry.group || 'default'; var container = (0, _minDom.query)('[data-group=' + grouping + ']', entriesContainer); if (!container) { container = (0, _minDom.domify)('<div class="group" data-group="' + grouping + '"></div>'); entriesContainer.appendChild(container); } var html = entry.html || (entry.separator ? '<hr class="separator" />' : '<div class="entry" draggable="true"></div>'); var control = (0, _minDom.domify)(html); container.appendChild(control); if (!entry.separator) { (0, _minDom.attr)(control, 'data-action', id); if (entry.title) { (0, _minDom.attr)(control, 'title', entry.title); } if (entry.className) { addClasses(control, entry.className); } if (entry.imageUrl) { control.appendChild((0, _minDom.domify)('<img src="' + entry.imageUrl + '">')); } } }); // open after update this.open(); }; /** * Trigger an action available on the palette * * @param {string} action * @param {Event} event */ Palette.prototype.trigger = function (action, event, autoActivate) { var entries = this._entries, entry, handler, originalEvent, button = event.delegateTarget || event.target; if (!button) { return event.preventDefault(); } entry = entries[(0, _minDom.attr)(button, 'data-action')]; // when user clicks on the palette and not on an action if (!entry) { return; } handler = entry.action; originalEvent = event.originalEvent || event; // simple action (via callback function) if ((0, _minDash.isFunction)(handler)) { if (action === 'click') { handler(originalEvent, autoActivate); } } else { if (handler[action]) { handler[action](originalEvent, autoActivate); } } // silence other actions event.preventDefault(); }; Palette.prototype._layoutChanged = function () { this._toggleState({}); }; /** * Do we need to collapse to two columns? * * @param {number} availableHeight * @param {Object} entries * * @return {boolean} */ Palette.prototype._needsCollapse = function (availableHeight, entries) { // top margin + bottom toggle + bottom margin // implementors must override this method if they // change the palette styles var margin = 20 + 10 + 20; var entriesHeight = Object.keys(entries).length * 46; return availableHeight < entriesHeight + margin; }; /** * Close the palette */ Palette.prototype.close = function () { this._toggleState({ open: false, twoColumn: false }); }; /** * Open the palette */ Palette.prototype.open = function () { this._toggleState({ open: true }); }; Palette.prototype.toggle = function (open) { if (this.isOpen()) { this.close(); } else { this.open(); } }; Palette.prototype.isActiveTool = function (tool) { return tool && this._activeTool === tool; }; Palette.prototype.updateToolHighlight = function (name) { var entriesContainer, toolsContainer; if (!this._toolsContainer) { entriesContainer = (0, _minDom.query)('.djs-palette-entries', this._container); this._toolsContainer = (0, _minDom.query)('[data-group=tools]', entriesContainer); } toolsContainer = this._toolsContainer; (0, _minDash.forEach)(toolsContainer.children, function (tool) { var actionName = tool.getAttribute('data-action'); if (!actionName) { return; } var toolClasses = (0, _minDom.classes)(tool); actionName = actionName.replace('-tool', ''); if (toolClasses.contains('entry') && actionName === name) { toolClasses.add('highlighted-entry'); } else { toolClasses.remove('highlighted-entry'); } }); }; /** * Return true if the palette is opened. * * @example * * palette.open(); * * if (palette.isOpen()) { * // yes, we are open * } * * @return {boolean} true if palette is opened */ Palette.prototype.isOpen = function () { return (0, _minDom.classes)(this._container).has(PALETTE_OPEN_CLS); }; /** * Get container the palette lives in. * * @return {Element} */ Palette.prototype._getParentContainer = function () { return this._canvas.getContainer(); }; /* markup definition */ Palette.HTML_MARKUP = '<div class="djs-palette">' + '<div class="djs-palette-entries"></div>' + '<div class="djs-palette-toggle"></div>' + '</div>'; // helpers ////////////////////// function addClasses(element, classNames) { var classes = (0, _minDom.classes)(element); var actualClassNames = (0, _minDash.isArray)(classNames) ? classNames : classNames.split(/\s+/g); actualClassNames.forEach(function (cls) { classes.add(cls); }); } function addPaletteEntries(entries, provider) { var entriesOrUpdater = provider.getPaletteEntries(); if ((0, _minDash.isFunction)(entriesOrUpdater)) { return entriesOrUpdater(entries); } (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) { entries[id] = entry; }); return entries; } },{"min-dash":555,"min-dom":556}],258:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Palette = _interopRequireDefault(require("./Palette")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['palette'], palette: ['type', _Palette.default] }; exports.default = _default; },{"./Palette":257}],259:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = PopupMenu; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var DATA_REF = 'data-id'; var CLOSE_EVENTS = ['contextPad.close', 'canvas.viewbox.changing', 'commandStack.changed']; var DEFAULT_PRIORITY = 1000; /** * A popup menu that can be used to display a list of actions anywhere in the canvas. * * @param {Object} config * @param {boolean|Object} [config.scale={ min: 1.0, max: 1.5 }] * @param {number} [config.scale.min] * @param {number} [config.scale.max] * @param {EventBus} eventBus * @param {Canvas} canvas * * @class * @constructor */ function PopupMenu(config, eventBus, canvas) { var scale = (0, _minDash.isDefined)(config && config.scale) ? config.scale : { min: 1, max: 1.5 }; this._config = { scale: scale }; this._eventBus = eventBus; this._canvas = canvas; this._providers = {}; this._current = {}; } PopupMenu.$inject = ['config.popupMenu', 'eventBus', 'canvas']; /** * Registers a popup menu provider * * @param {string} id * @param {number} [priority=1000] * @param {Object} provider * * @example * const popupMenuProvider = { * getPopupMenuEntries: function(element) { * return { * 'entry-1': { * label: 'My Entry', * action: function() { alert("I have been clicked!"); } * } * } * } * }; * * popupMenu.registerProvider('myMenuID', popupMenuProvider); */ PopupMenu.prototype.registerProvider = function (id, priority, provider) { if (!provider) { provider = priority; priority = DEFAULT_PRIORITY; } this._eventBus.on('popupMenu.getProviders.' + id, priority, function (event) { event.providers.push(provider); }); }; /** * Determine if the popup menu has entries. * * @return {boolean} true if empty */ PopupMenu.prototype.isEmpty = function (element, providerId) { if (!element) { throw new Error('element parameter is missing'); } if (!providerId) { throw new Error('providerId parameter is missing'); } var providers = this._getProviders(providerId); if (!providers) { return true; } var entries = this._getEntries(element, providers), headerEntries = this._getHeaderEntries(element, providers); var hasEntries = (0, _minDash.size)(entries) > 0, hasHeaderEntries = headerEntries && (0, _minDash.size)(headerEntries) > 0; return !hasEntries && !hasHeaderEntries; }; /** * Create entries and open popup menu at given position * * @param {Object} element * @param {string} id provider id * @param {Object} position * * @return {Object} popup menu instance */ PopupMenu.prototype.open = function (element, id, position) { var providers = this._getProviders(id); if (!element) { throw new Error('Element is missing'); } if (!providers || !providers.length) { throw new Error('No registered providers for: ' + id); } if (!position) { throw new Error('the position argument is missing'); } if (this.isOpen()) { this.close(); } this._emit('open'); var current = this._current = { className: id, element: element, position: position }; var entries = this._getEntries(element, providers), headerEntries = this._getHeaderEntries(element, providers); current.entries = (0, _minDash.assign)({}, entries, headerEntries); current.container = this._createContainer(); if ((0, _minDash.size)(headerEntries)) { current.container.appendChild(this._createEntries(headerEntries, 'djs-popup-header')); } if ((0, _minDash.size)(entries)) { current.container.appendChild(this._createEntries(entries, 'djs-popup-body')); } var canvas = this._canvas, parent = canvas.getContainer(); this._attachContainer(current.container, parent, position.cursor); this._bindAutoClose(); }; /** * Removes the popup menu and unbinds the event handlers. */ PopupMenu.prototype.close = function () { if (!this.isOpen()) { return; } this._emit('close'); this._unbindAutoClose(); (0, _minDom.remove)(this._current.container); this._current.container = null; }; /** * Determine if an open popup menu exist. * * @return {boolean} true if open */ PopupMenu.prototype.isOpen = function () { return !!this._current.container; }; /** * Trigger an action associated with an entry. * * @param {Object} event * * @return the result of the action callback, if any */ PopupMenu.prototype.trigger = function (event) { // silence other actions event.preventDefault(); var element = event.delegateTarget || event.target, entryId = (0, _minDom.attr)(element, DATA_REF); var entry = this._getEntry(entryId); if (entry.action) { return entry.action.call(null, event, entry); } }; PopupMenu.prototype._getProviders = function (id) { var event = this._eventBus.createEvent({ type: 'popupMenu.getProviders.' + id, providers: [] }); this._eventBus.fire(event); return event.providers; }; PopupMenu.prototype._getEntries = function (element, providers) { var entries = {}; (0, _minDash.forEach)(providers, function (provider) { // handle legacy method if (!provider.getPopupMenuEntries) { (0, _minDash.forEach)(provider.getEntries(element), function (entry) { var id = entry.id; if (!id) { throw new Error('every entry must have the id property set'); } entries[id] = (0, _minDash.omit)(entry, ['id']); }); return; } var entriesOrUpdater = provider.getPopupMenuEntries(element); if ((0, _minDash.isFunction)(entriesOrUpdater)) { entries = entriesOrUpdater(entries); } else { (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) { entries[id] = entry; }); } }); return entries; }; PopupMenu.prototype._getHeaderEntries = function (element, providers) { var entries = {}; (0, _minDash.forEach)(providers, function (provider) { // handle legacy method if (!provider.getPopupMenuHeaderEntries) { if (!provider.getHeaderEntries) { return; } (0, _minDash.forEach)(provider.getHeaderEntries(element), function (entry) { var id = entry.id; if (!id) { throw new Error('every entry must have the id property set'); } entries[id] = (0, _minDash.omit)(entry, ['id']); }); return; } var entriesOrUpdater = provider.getPopupMenuHeaderEntries(element); if ((0, _minDash.isFunction)(entriesOrUpdater)) { entries = entriesOrUpdater(entries); } else { (0, _minDash.forEach)(entriesOrUpdater, function (entry, id) { entries[id] = entry; }); } }); return entries; }; /** * Gets an entry instance (either entry or headerEntry) by id. * * @param {string} entryId * * @return {Object} entry instance */ PopupMenu.prototype._getEntry = function (entryId) { var entry = this._current.entries[entryId]; if (!entry) { throw new Error('entry not found'); } return entry; }; PopupMenu.prototype._emit = function (eventName) { this._eventBus.fire('popupMenu.' + eventName); }; /** * Creates the popup menu container. * * @return {Object} a DOM container */ PopupMenu.prototype._createContainer = function () { var container = (0, _minDom.domify)('<div class="djs-popup">'), position = this._current.position, className = this._current.className; (0, _minDash.assign)(container.style, { position: 'absolute', left: position.x + 'px', top: position.y + 'px', visibility: 'hidden' }); (0, _minDom.classes)(container).add(className); return container; }; /** * Attaches the container to the DOM. * * @param {Object} container * @param {Object} parent */ PopupMenu.prototype._attachContainer = function (container, parent, cursor) { var self = this; // Event handler _minDom.delegate.bind(container, '.entry', 'click', function (event) { self.trigger(event); }); this._updateScale(container); // Attach to DOM parent.appendChild(container); if (cursor) { this._assureIsInbounds(container, cursor); } }; /** * Updates popup style.transform with respect to the config and zoom level. * * @method _updateScale * * @param {Object} container */ PopupMenu.prototype._updateScale = function (container) { var zoom = this._canvas.zoom(); var scaleConfig = this._config.scale, minScale, maxScale, scale = zoom; if (scaleConfig !== true) { if (scaleConfig === false) { minScale = 1; maxScale = 1; } else { minScale = scaleConfig.min; maxScale = scaleConfig.max; } if ((0, _minDash.isDefined)(minScale) && zoom < minScale) { scale = minScale; } if ((0, _minDash.isDefined)(maxScale) && zoom > maxScale) { scale = maxScale; } } setTransform(container, 'scale(' + scale + ')'); }; /** * Make sure that the menu is always fully shown * * @method function * * @param {Object} container * @param {Position} cursor {x, y} */ PopupMenu.prototype._assureIsInbounds = function (container, cursor) { var canvas = this._canvas, clientRect = canvas._container.getBoundingClientRect(); var containerX = container.offsetLeft, containerY = container.offsetTop, containerWidth = container.scrollWidth, containerHeight = container.scrollHeight, overAxis = {}, left, top; var cursorPosition = { x: cursor.x - clientRect.left, y: cursor.y - clientRect.top }; if (containerX + containerWidth > clientRect.width) { overAxis.x = true; } if (containerY + containerHeight > clientRect.height) { overAxis.y = true; } if (overAxis.x && overAxis.y) { left = cursorPosition.x - containerWidth + 'px'; top = cursorPosition.y - containerHeight + 'px'; } else if (overAxis.x) { left = cursorPosition.x - containerWidth + 'px'; top = cursorPosition.y + 'px'; } else if (overAxis.y && cursorPosition.y < containerHeight) { left = cursorPosition.x + 'px'; top = 10 + 'px'; } else if (overAxis.y) { left = cursorPosition.x + 'px'; top = cursorPosition.y - containerHeight + 'px'; } (0, _minDash.assign)(container.style, { left: left, top: top }, { visibility: 'visible', 'z-index': 1000 }); }; /** * Creates a list of entries and returns them as a DOM container. * * @param {Array<Object>} entries an array of entry objects * @param {string} className the class name of the entry container * * @return {Object} a DOM container */ PopupMenu.prototype._createEntries = function (entries, className) { var entriesContainer = (0, _minDom.domify)('<div>'), self = this; (0, _minDom.classes)(entriesContainer).add(className); (0, _minDash.forEach)(entries, function (entry, id) { var entryContainer = self._createEntry(entry, id); entriesContainer.appendChild(entryContainer); }); return entriesContainer; }; /** * Creates a single entry and returns it as a DOM container. * * @param {Object} entry * * @return {Object} a DOM container */ PopupMenu.prototype._createEntry = function (entry, id) { var entryContainer = (0, _minDom.domify)('<div>'), entryClasses = (0, _minDom.classes)(entryContainer); entryClasses.add('entry'); if (entry.className) { entry.className.split(' ').forEach(function (className) { entryClasses.add(className); }); } (0, _minDom.attr)(entryContainer, DATA_REF, id); if (entry.label) { var label = (0, _minDom.domify)('<span>'); label.textContent = entry.label; entryContainer.appendChild(label); } if (entry.imageUrl) { entryContainer.appendChild((0, _minDom.domify)('<img src="' + entry.imageUrl + '" />')); } if (entry.active === true) { entryClasses.add('active'); } if (entry.disabled === true) { entryClasses.add('disabled'); } if (entry.title) { entryContainer.title = entry.title; } return entryContainer; }; /** * Set up listener to close popup automatically on certain events. */ PopupMenu.prototype._bindAutoClose = function () { this._eventBus.once(CLOSE_EVENTS, this.close, this); }; /** * Remove the auto-closing listener. */ PopupMenu.prototype._unbindAutoClose = function () { this._eventBus.off(CLOSE_EVENTS, this.close, this); }; // helpers ///////////////////////////// function setTransform(element, transform) { element.style['transform-origin'] = 'top left'; ['', '-ms-', '-webkit-'].forEach(function (prefix) { element.style[prefix + 'transform'] = transform; }); } },{"min-dash":555,"min-dom":556}],260:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _PopupMenu = _interopRequireDefault(require("./PopupMenu")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['popupMenu'], popupMenu: ['type', _PopupMenu.default] }; exports.default = _default; },{"./PopupMenu":259}],261:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = PreviewSupport; var _minDash = require("min-dash"); var _tinySvg = require("tiny-svg"); var _minDom = require("min-dom"); var _GraphicsUtil = require("../../util/GraphicsUtil"); var MARKER_TYPES = ['marker-start', 'marker-mid', 'marker-end']; var NODES_CAN_HAVE_MARKER = ['circle', 'ellipse', 'line', 'path', 'polygon', 'polyline', 'rect']; /** * Adds support for previews of moving/resizing elements. */ function PreviewSupport(elementRegistry, eventBus, canvas, styles) { this._elementRegistry = elementRegistry; this._canvas = canvas; this._styles = styles; this._clonedMarkers = {}; var self = this; eventBus.on('drag.cleanup', function () { (0, _minDash.forEach)(self._clonedMarkers, function (clonedMarker) { (0, _tinySvg.remove)(clonedMarker); }); self._clonedMarkers = {}; }); } PreviewSupport.$inject = ['elementRegistry', 'eventBus', 'canvas', 'styles']; /** * Returns graphics of an element. * * @param {djs.model.Base} element * * @return {SVGElement} */ PreviewSupport.prototype.getGfx = function (element) { return this._elementRegistry.getGraphics(element); }; /** * Adds a move preview of a given shape to a given svg group. * * @param {djs.model.Base} element * @param {SVGElement} group * @param {SVGElement} [gfx] * * @return {SVGElement} dragger */ PreviewSupport.prototype.addDragger = function (element, group, gfx) { gfx = gfx || this.getGfx(element); var dragger = (0, _tinySvg.clone)(gfx); var bbox = gfx.getBoundingClientRect(); this._cloneMarkers((0, _GraphicsUtil.getVisual)(dragger)); (0, _tinySvg.attr)(dragger, this._styles.cls('djs-dragger', [], { x: bbox.top, y: bbox.left })); (0, _tinySvg.append)(group, dragger); return dragger; }; /** * Adds a resize preview of a given shape to a given svg group. * * @param {djs.model.Base} element * @param {SVGElement} group * * @return {SVGElement} frame */ PreviewSupport.prototype.addFrame = function (shape, group) { var frame = (0, _tinySvg.create)('rect', { class: 'djs-resize-overlay', width: shape.width, height: shape.height, x: shape.x, y: shape.y }); (0, _tinySvg.append)(group, frame); return frame; }; /** * Clone all markers referenced by a node and its child nodes. * * @param {SVGElement} gfx */ PreviewSupport.prototype._cloneMarkers = function (gfx) { var self = this; if (gfx.childNodes) { // TODO: use forEach once we drop PhantomJS for (var i = 0; i < gfx.childNodes.length; i++) { // recursively clone markers of child nodes self._cloneMarkers(gfx.childNodes[i]); } } if (!canHaveMarker(gfx)) { return; } MARKER_TYPES.forEach(function (markerType) { if ((0, _tinySvg.attr)(gfx, markerType)) { var marker = getMarker(gfx, markerType, self._canvas.getContainer()); self._cloneMarker(gfx, marker, markerType); } }); }; /** * Clone marker referenced by an element. * * @param {SVGElement} gfx * @param {SVGElement} marker * @param {string} markerType */ PreviewSupport.prototype._cloneMarker = function (gfx, marker, markerType) { var markerId = marker.id; var clonedMarker = this._clonedMarkers[markerId]; if (!clonedMarker) { clonedMarker = (0, _tinySvg.clone)(marker); var clonedMarkerId = markerId + '-clone'; clonedMarker.id = clonedMarkerId; (0, _tinySvg.classes)(clonedMarker).add('djs-dragger').add('djs-dragger-marker'); this._clonedMarkers[markerId] = clonedMarker; var defs = (0, _minDom.query)('defs', this._canvas._svg); if (!defs) { defs = (0, _tinySvg.create)('defs'); (0, _tinySvg.append)(this._canvas._svg, defs); } (0, _tinySvg.append)(defs, clonedMarker); } var reference = idToReference(this._clonedMarkers[markerId].id); (0, _tinySvg.attr)(gfx, markerType, reference); }; // helpers ////////// /** * Get marker of given type referenced by node. * * @param {Node} node * @param {string} markerType * @param {Node} [parentNode] * * @param {Node} */ function getMarker(node, markerType, parentNode) { var id = referenceToId((0, _tinySvg.attr)(node, markerType)); return (0, _minDom.query)('marker#' + id, parentNode || document); } /** * Get ID of fragment within current document from its functional IRI reference. * References may use single or double quotes. * * @param {string} reference * * @returns {string} */ function referenceToId(reference) { return reference.match(/url\(['"]?#([^'"]*)['"]?\)/)[1]; } /** * Get functional IRI reference for given ID of fragment within current document. * * @param {string} id * * @returns {string} */ function idToReference(id) { return 'url(#' + id + ')'; } /** * Check wether node type can have marker attributes. * * @param {Node} node * * @returns {boolean} */ function canHaveMarker(node) { return NODES_CAN_HAVE_MARKER.indexOf(node.nodeName) !== -1; } },{"../../util/GraphicsUtil":319,"min-dash":555,"min-dom":556,"tiny-svg":567}],262:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _PreviewSupport = _interopRequireDefault(require("./PreviewSupport")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['previewSupport'], previewSupport: ['type', _PreviewSupport.default] }; exports.default = _default; },{"./PreviewSupport":261}],263:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Replace; var _minDash = require("min-dash"); var round = Math.round; /** * Service that allow replacing of elements. */ function Replace(modeling) { this._modeling = modeling; } Replace.$inject = ['modeling']; /** * @param {Element} oldElement - Element to be replaced * @param {Object} newElementData - Containing information about the new element, * for example the new bounds and type. * @param {Object} options - Custom options that will be attached to the context. It can be used to inject data * that is needed in the command chain. For example it could be used in * eventbus.on('commandStack.shape.replace.postExecute') to change shape attributes after * shape creation. */ Replace.prototype.replaceElement = function (oldElement, newElementData, options) { if (oldElement.waypoints) { // TODO(nikku): we do not replace connections, yet return null; } var modeling = this._modeling; var width = newElementData.width || oldElement.width, height = newElementData.height || oldElement.height, x = newElementData.x || oldElement.x, y = newElementData.y || oldElement.y, centerX = round(x + width / 2), centerY = round(y + height / 2); // modeling API requires center coordinates, // account for that when handling shape bounds return modeling.replaceShape(oldElement, (0, _minDash.assign)({}, newElementData, { x: centerX, y: centerY, width: width, height: height }), options); }; },{"min-dash":555}],264:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Replace = _interopRequireDefault(require("./Replace")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['replace'], replace: ['type', _Replace.default] }; exports.default = _default; },{"./Replace":263}],265:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Resize; exports.getReferencePoint = getReferencePoint; var _minDash = require("min-dash"); var _ResizeUtil = require("./ResizeUtil"); var _LayoutUtil = require("../../layout/LayoutUtil"); var DEFAULT_MIN_WIDTH = 10; /** * A component that provides resizing of shapes on the canvas. * * The following components are part of shape resize: * * * adding resize handles, * * creating a visual during resize * * checking resize rules * * committing a change once finished * * * ## Customizing * * It's possible to customize the resizing behaviour by intercepting 'resize.start' * and providing the following parameters through the 'context': * * * minDimensions ({ width, height }): minimum shape dimensions * * * childrenBoxPadding ({ left, top, bottom, right } || number): * gap between the minimum bounding box and the container * * f.ex: * * ```javascript * eventBus.on('resize.start', 1500, function(event) { * var context = event.context, * * context.minDimensions = { width: 140, height: 120 }; * * // Passing general padding * context.childrenBoxPadding = 30; * * // Passing padding to a specific side * context.childrenBoxPadding.left = 20; * }); * ``` */ function Resize(eventBus, rules, modeling, dragging) { this._dragging = dragging; this._rules = rules; var self = this; /** * Handle resize move by specified delta. * * @param {Object} context * @param {Point} delta */ function handleMove(context, delta) { var shape = context.shape, direction = context.direction, resizeConstraints = context.resizeConstraints, newBounds; context.delta = delta; newBounds = (0, _ResizeUtil.resizeBounds)(shape, direction, delta); // ensure constraints during resize context.newBounds = (0, _ResizeUtil.ensureConstraints)(newBounds, resizeConstraints); // update + cache executable state context.canExecute = self.canResize(context); } /** * Handle resize start. * * @param {Object} context */ function handleStart(context) { var resizeConstraints = context.resizeConstraints, // evaluate minBounds for backwards compatibility minBounds = context.minBounds; if (resizeConstraints !== undefined) { return; } if (minBounds === undefined) { minBounds = self.computeMinResizeBox(context); } context.resizeConstraints = { min: (0, _LayoutUtil.asTRBL)(minBounds) }; } /** * Handle resize end. * * @param {Object} context */ function handleEnd(context) { var shape = context.shape, canExecute = context.canExecute, newBounds = context.newBounds; if (canExecute) { // ensure we have actual pixel values for new bounds // (important when zoom level was > 1 during move) newBounds = (0, _LayoutUtil.roundBounds)(newBounds); if (!boundsChanged(shape, newBounds)) { // no resize necessary return; } // perform the actual resize modeling.resizeShape(shape, newBounds); } } eventBus.on('resize.start', function (event) { handleStart(event.context); }); eventBus.on('resize.move', function (event) { var delta = { x: event.dx, y: event.dy }; handleMove(event.context, delta); }); eventBus.on('resize.end', function (event) { handleEnd(event.context); }); } Resize.prototype.canResize = function (context) { var rules = this._rules; var ctx = (0, _minDash.pick)(context, ['newBounds', 'shape', 'delta', 'direction']); return rules.allowed('shape.resize', ctx); }; /** * Activate a resize operation. * * You may specify additional contextual information and must specify a * resize direction during activation of the resize event. * * @param {MouseEvent} event * @param {djs.model.Shape} shape * @param {Object|string} contextOrDirection */ Resize.prototype.activate = function (event, shape, contextOrDirection) { var dragging = this._dragging, context, direction; if (typeof contextOrDirection === 'string') { contextOrDirection = { direction: contextOrDirection }; } context = (0, _minDash.assign)({ shape: shape }, contextOrDirection); direction = context.direction; if (!direction) { throw new Error('must provide a direction (n|w|s|e|nw|se|ne|sw)'); } dragging.init(event, getReferencePoint(shape, direction), 'resize', { autoActivate: true, cursor: getCursor(direction), data: { shape: shape, context: context } }); }; Resize.prototype.computeMinResizeBox = function (context) { var shape = context.shape, direction = context.direction, minDimensions, childrenBounds; minDimensions = context.minDimensions || { width: DEFAULT_MIN_WIDTH, height: DEFAULT_MIN_WIDTH }; // get children bounds childrenBounds = (0, _ResizeUtil.computeChildrenBBox)(shape, context.childrenBoxPadding); // get correct minimum bounds from given resize direction // basically ensures that the minBounds is max(childrenBounds, minDimensions) return (0, _ResizeUtil.getMinResizeBounds)(direction, shape, minDimensions, childrenBounds); }; Resize.$inject = ['eventBus', 'rules', 'modeling', 'dragging']; // helpers ////////// function boundsChanged(shape, newBounds) { return shape.x !== newBounds.x || shape.y !== newBounds.y || shape.width !== newBounds.width || shape.height !== newBounds.height; } function getReferencePoint(shape, direction) { var mid = (0, _LayoutUtil.getMid)(shape), trbl = (0, _LayoutUtil.asTRBL)(shape); var referencePoint = { x: mid.x, y: mid.y }; if (direction.indexOf('n') !== -1) { referencePoint.y = trbl.top; } else if (direction.indexOf('s') !== -1) { referencePoint.y = trbl.bottom; } if (direction.indexOf('e') !== -1) { referencePoint.x = trbl.right; } else if (direction.indexOf('w') !== -1) { referencePoint.x = trbl.left; } return referencePoint; } function getCursor(direction) { var prefix = 'resize-'; if (direction === 'n' || direction === 's') { return prefix + 'ns'; } else if (direction === 'e' || direction === 'w') { return prefix + 'ew'; } else if (direction === 'nw' || direction === 'se') { return prefix + 'nwse'; } else { return prefix + 'nesw'; } } },{"../../layout/LayoutUtil":300,"./ResizeUtil":268,"min-dash":555}],266:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeHandles; var _minDash = require("min-dash"); var _tinySvg = require("tiny-svg"); var _minDom = require("min-dom"); var _Mouse = require("../../util/Mouse"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var _Resize = require("./Resize"); var HANDLE_OFFSET = -6, HANDLE_SIZE = 4, HANDLE_HIT_SIZE = 20; var CLS_RESIZER = 'djs-resizer'; var directions = ['n', 'w', 's', 'e', 'nw', 'ne', 'se', 'sw']; /** * This component is responsible for adding resize handles. * * @param {EventBus} eventBus * @param {Canvas} canvas * @param {Selection} selection * @param {Resize} resize */ function ResizeHandles(eventBus, canvas, selection, resize) { this._resize = resize; this._canvas = canvas; var self = this; eventBus.on('selection.changed', function (e) { var newSelection = e.newSelection; // remove old selection markers self.removeResizers(); // add new selection markers ONLY if single selection if (newSelection.length === 1) { (0, _minDash.forEach)(newSelection, (0, _minDash.bind)(self.addResizer, self)); } }); eventBus.on('shape.changed', function (e) { var shape = e.element; if (selection.isSelected(shape)) { self.removeResizers(); self.addResizer(shape); } }); } ResizeHandles.prototype.makeDraggable = function (element, gfx, direction) { var resize = this._resize; function startResize(event) { // only trigger on left mouse button if ((0, _Mouse.isPrimaryButton)(event)) { resize.activate(event, element, direction); } } _minDom.event.bind(gfx, 'mousedown', startResize); _minDom.event.bind(gfx, 'touchstart', startResize); }; ResizeHandles.prototype._createResizer = function (element, x, y, direction) { var resizersParent = this._getResizersParent(); var offset = getHandleOffset(direction); var group = (0, _tinySvg.create)('g'); (0, _tinySvg.classes)(group).add(CLS_RESIZER); (0, _tinySvg.classes)(group).add(CLS_RESIZER + '-' + element.id); (0, _tinySvg.classes)(group).add(CLS_RESIZER + '-' + direction); (0, _tinySvg.append)(resizersParent, group); var visual = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(visual, { x: -HANDLE_SIZE / 2 + offset.x, y: -HANDLE_SIZE / 2 + offset.y, width: HANDLE_SIZE, height: HANDLE_SIZE }); (0, _tinySvg.classes)(visual).add(CLS_RESIZER + '-visual'); (0, _tinySvg.append)(group, visual); var hit = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(hit, { x: -HANDLE_HIT_SIZE / 2 + offset.x, y: -HANDLE_HIT_SIZE / 2 + offset.y, width: HANDLE_HIT_SIZE, height: HANDLE_HIT_SIZE }); (0, _tinySvg.classes)(hit).add(CLS_RESIZER + '-hit'); (0, _tinySvg.append)(group, hit); (0, _SvgTransformUtil.transform)(group, x, y); return group; }; ResizeHandles.prototype.createResizer = function (element, direction) { var point = (0, _Resize.getReferencePoint)(element, direction); var resizer = this._createResizer(element, point.x, point.y, direction); this.makeDraggable(element, resizer, direction); }; // resize handles implementation /////////////////////////////// /** * Add resizers for a given element. * * @param {djs.model.Shape} shape */ ResizeHandles.prototype.addResizer = function (shape) { var self = this; var resize = this._resize; if (!resize.canResize({ shape: shape })) { return; } (0, _minDash.forEach)(directions, function (direction) { self.createResizer(shape, direction); }); }; /** * Remove all resizers */ ResizeHandles.prototype.removeResizers = function () { var resizersParent = this._getResizersParent(); (0, _tinySvg.clear)(resizersParent); }; ResizeHandles.prototype._getResizersParent = function () { return this._canvas.getLayer('resizers'); }; ResizeHandles.$inject = ['eventBus', 'canvas', 'selection', 'resize']; // helpers ////////// function getHandleOffset(direction) { var offset = { x: 0, y: 0 }; if (direction.indexOf('e') !== -1) { offset.x = -HANDLE_OFFSET; } else if (direction.indexOf('w') !== -1) { offset.x = HANDLE_OFFSET; } if (direction.indexOf('s') !== -1) { offset.y = -HANDLE_OFFSET; } else if (direction.indexOf('n') !== -1) { offset.y = HANDLE_OFFSET; } return offset; } },{"../../util/Mouse":323,"../../util/SvgTransformUtil":328,"./Resize":265,"min-dash":555,"min-dom":556,"tiny-svg":567}],267:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizePreview; var _tinySvg = require("tiny-svg"); var MARKER_RESIZING = 'djs-resizing', MARKER_RESIZE_NOT_OK = 'resize-not-ok'; var LOW_PRIORITY = 500; /** * Provides previews for resizing shapes when resizing. * * @param {EventBus} eventBus * @param {Canvas} canvas * @param {PreviewSupport} previewSupport */ function ResizePreview(eventBus, canvas, previewSupport) { /** * Update resizer frame. * * @param {Object} context */ function updateFrame(context) { var shape = context.shape, bounds = context.newBounds, frame = context.frame; if (!frame) { frame = context.frame = previewSupport.addFrame(shape, canvas.getDefaultLayer()); canvas.addMarker(shape, MARKER_RESIZING); } if (bounds.width > 5) { (0, _tinySvg.attr)(frame, { x: bounds.x, width: bounds.width }); } if (bounds.height > 5) { (0, _tinySvg.attr)(frame, { y: bounds.y, height: bounds.height }); } if (context.canExecute) { (0, _tinySvg.classes)(frame).remove(MARKER_RESIZE_NOT_OK); } else { (0, _tinySvg.classes)(frame).add(MARKER_RESIZE_NOT_OK); } } /** * Remove resizer frame. * * @param {Object} context */ function removeFrame(context) { var shape = context.shape, frame = context.frame; if (frame) { (0, _tinySvg.remove)(context.frame); } canvas.removeMarker(shape, MARKER_RESIZING); } // add and update previews eventBus.on('resize.move', LOW_PRIORITY, function (event) { updateFrame(event.context); }); // remove previews eventBus.on('resize.cleanup', function (event) { removeFrame(event.context); }); } ResizePreview.$inject = ['eventBus', 'canvas', 'previewSupport']; },{"tiny-svg":567}],268:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.substractTRBL = substractTRBL; exports.resizeBounds = resizeBounds; exports.resizeTRBL = resizeTRBL; exports.reattachPoint = reattachPoint; exports.ensureConstraints = ensureConstraints; exports.getMinResizeBounds = getMinResizeBounds; exports.addPadding = addPadding; exports.computeChildrenBBox = computeChildrenBBox; var _minDash = require("min-dash"); var _Elements = require("../../util/Elements"); var _LayoutUtil = require("../../layout/LayoutUtil"); var max = Math.max, min = Math.min; var DEFAULT_CHILD_BOX_PADDING = 20; /** * Substract a TRBL from another * * @param {TRBL} trblA * @param {TRBL} trblB * * @return {TRBL} */ function substractTRBL(trblA, trblB) { return { top: trblA.top - trblB.top, right: trblA.right - trblB.right, bottom: trblA.bottom - trblB.bottom, left: trblA.left - trblB.left }; } /** * Resize the given bounds by the specified delta from a given anchor point. * * @param {Bounds} bounds the bounding box that should be resized * @param {string} direction in which the element is resized (nw, ne, se, sw) * @param {Point} delta of the resize operation * * @return {Bounds} resized bounding box */ function resizeBounds(bounds, direction, delta) { var dx = delta.x, dy = delta.y; var newBounds = { x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height }; if (direction.indexOf('n') !== -1) { newBounds.y = bounds.y + dy; newBounds.height = bounds.height - dy; } else if (direction.indexOf('s') !== -1) { newBounds.height = bounds.height + dy; } if (direction.indexOf('e') !== -1) { newBounds.width = bounds.width + dx; } else if (direction.indexOf('w') !== -1) { newBounds.x = bounds.x + dx; newBounds.width = bounds.width - dx; } return newBounds; } /** * Resize the given bounds by applying the passed * { top, right, bottom, left } delta. * * @param {Bounds} bounds * @param {TRBL} trblResize * * @return {Bounds} */ function resizeTRBL(bounds, resize) { return { x: bounds.x + (resize.left || 0), y: bounds.y + (resize.top || 0), width: bounds.width - (resize.left || 0) + (resize.right || 0), height: bounds.height - (resize.top || 0) + (resize.bottom || 0) }; } function reattachPoint(bounds, newBounds, point) { var sx = bounds.width / newBounds.width, sy = bounds.height / newBounds.height; return { x: Math.round(newBounds.x + newBounds.width / 2) - Math.floor((bounds.x + bounds.width / 2 - point.x) / sx), y: Math.round(newBounds.y + newBounds.height / 2) - Math.floor((bounds.y + bounds.height / 2 - point.y) / sy) }; } function applyConstraints(attr, trbl, resizeConstraints) { var value = trbl[attr], minValue = resizeConstraints.min && resizeConstraints.min[attr], maxValue = resizeConstraints.max && resizeConstraints.max[attr]; if ((0, _minDash.isNumber)(minValue)) { value = (/top|left/.test(attr) ? min : max)(value, minValue); } if ((0, _minDash.isNumber)(maxValue)) { value = (/top|left/.test(attr) ? max : min)(value, maxValue); } return value; } function ensureConstraints(currentBounds, resizeConstraints) { if (!resizeConstraints) { return currentBounds; } var currentTrbl = (0, _LayoutUtil.asTRBL)(currentBounds); return (0, _LayoutUtil.asBounds)({ top: applyConstraints('top', currentTrbl, resizeConstraints), right: applyConstraints('right', currentTrbl, resizeConstraints), bottom: applyConstraints('bottom', currentTrbl, resizeConstraints), left: applyConstraints('left', currentTrbl, resizeConstraints) }); } function getMinResizeBounds(direction, currentBounds, minDimensions, childrenBounds) { var currentBox = (0, _LayoutUtil.asTRBL)(currentBounds); var minBox = { top: /n/.test(direction) ? currentBox.bottom - minDimensions.height : currentBox.top, left: /w/.test(direction) ? currentBox.right - minDimensions.width : currentBox.left, bottom: /s/.test(direction) ? currentBox.top + minDimensions.height : currentBox.bottom, right: /e/.test(direction) ? currentBox.left + minDimensions.width : currentBox.right }; var childrenBox = childrenBounds ? (0, _LayoutUtil.asTRBL)(childrenBounds) : minBox; var combinedBox = { top: min(minBox.top, childrenBox.top), left: min(minBox.left, childrenBox.left), bottom: max(minBox.bottom, childrenBox.bottom), right: max(minBox.right, childrenBox.right) }; return (0, _LayoutUtil.asBounds)(combinedBox); } function asPadding(mayBePadding, defaultValue) { if (typeof mayBePadding !== 'undefined') { return mayBePadding; } else { return DEFAULT_CHILD_BOX_PADDING; } } function addPadding(bbox, padding) { var left, right, top, bottom; if (typeof padding === 'object') { left = asPadding(padding.left); right = asPadding(padding.right); top = asPadding(padding.top); bottom = asPadding(padding.bottom); } else { left = right = top = bottom = asPadding(padding); } return { x: bbox.x - left, y: bbox.y - top, width: bbox.width + left + right, height: bbox.height + top + bottom }; } /** * Is the given element part of the resize * targets min boundary box? * * This is the default implementation which excludes * connections and labels. * * @param {djs.model.Base} element */ function isBBoxChild(element) { // exclude connections if (element.waypoints) { return false; } // exclude labels if (element.type === 'label') { return false; } return true; } /** * Return children bounding computed from a shapes children * or a list of prefiltered children. * * @param {djs.model.Shape|Array<djs.model.Shape>} shapeOrChildren * @param {number|Object} padding * * @return {Bounds} */ function computeChildrenBBox(shapeOrChildren, padding) { var elements; // compute based on shape if (shapeOrChildren.length === undefined) { // grab all the children that are part of the // parents children box elements = (0, _minDash.filter)(shapeOrChildren.children, isBBoxChild); } else { elements = shapeOrChildren; } if (elements.length) { return addPadding((0, _Elements.getBBox)(elements), padding); } } },{"../../layout/LayoutUtil":300,"../../util/Elements":315,"min-dash":555}],269:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _rules = _interopRequireDefault(require("../rules")); var _dragging = _interopRequireDefault(require("../dragging")); var _previewSupport = _interopRequireDefault(require("../preview-support")); var _Resize = _interopRequireDefault(require("./Resize")); var _ResizePreview = _interopRequireDefault(require("./ResizePreview")); var _ResizeHandles = _interopRequireDefault(require("./ResizeHandles")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_rules.default, _dragging.default, _previewSupport.default], __init__: ['resize', 'resizePreview', 'resizeHandles'], resize: ['type', _Resize.default], resizePreview: ['type', _ResizePreview.default], resizeHandles: ['type', _ResizeHandles.default] }; exports.default = _default; },{"../dragging":197,"../preview-support":262,"../rules":272,"./Resize":265,"./ResizeHandles":266,"./ResizePreview":267}],270:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = RuleProvider; var _inherits = _interopRequireDefault(require("inherits")); var _CommandInterceptor = _interopRequireDefault(require("../../command/CommandInterceptor")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A basic provider that may be extended to implement modeling rules. * * Extensions should implement the init method to actually add their custom * modeling checks. Checks may be added via the #addRule(action, fn) method. * * @param {EventBus} eventBus */ function RuleProvider(eventBus) { _CommandInterceptor.default.call(this, eventBus); this.init(); } RuleProvider.$inject = ['eventBus']; (0, _inherits.default)(RuleProvider, _CommandInterceptor.default); /** * Adds a modeling rule for the given action, implemented through * a callback function. * * The function will receive the modeling specific action context * to perform its check. It must return `false` to disallow the * action from happening or `true` to allow the action. * * A rule provider may pass over the evaluation to lower priority * rules by returning return nothing (or <code>undefined</code>). * * @example * * ResizableRules.prototype.init = function() { * * \/** * * Return `true`, `false` or nothing to denote * * _allowed_, _not allowed_ and _continue evaluating_. * *\/ * this.addRule('shape.resize', function(context) { * * var shape = context.shape; * * if (!context.newBounds) { * // check general resizability * if (!shape.resizable) { * return false; * } * * // not returning anything (read: undefined) * // will continue the evaluation of other rules * // (with lower priority) * return; * } else { * // element must have minimum size of 10*10 points * return context.newBounds.width > 10 && context.newBounds.height > 10; * } * }); * }; * * @param {string|Array<string>} actions the identifier for the modeling action to check * @param {number} [priority] the priority at which this rule is being applied * @param {Function} fn the callback function that performs the actual check */ RuleProvider.prototype.addRule = function (actions, priority, fn) { var self = this; if (typeof actions === 'string') { actions = [actions]; } actions.forEach(function (action) { self.canExecute(action, priority, function (context, action, event) { return fn(context); }, true); }); }; /** * Implement this method to add new rules during provider initialization. */ RuleProvider.prototype.init = function () {}; },{"../../command/CommandInterceptor":145,"inherits":347}],271:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Rules; /** * A service that provides rules for certain diagram actions. * * The default implementation will hook into the {@link CommandStack} * to perform the actual rule evaluation. Make sure to provide the * `commandStack` service with this module if you plan to use it. * * Together with this implementation you may use the {@link RuleProvider} * to implement your own rule checkers. * * This module is ment to be easily replaced, thus the tiny foot print. * * @param {Injector} injector */ function Rules(injector) { this._commandStack = injector.get('commandStack', false); } Rules.$inject = ['injector']; /** * Returns whether or not a given modeling action can be executed * in the specified context. * * This implementation will respond with allow unless anyone * objects. * * @param {string} action the action to be checked * @param {Object} [context] the context to check the action in * * @return {boolean} returns true, false or null depending on whether the * operation is allowed, not allowed or should be ignored. */ Rules.prototype.allowed = function (action, context) { var allowed = true; var commandStack = this._commandStack; if (commandStack) { allowed = commandStack.canExecute(action, context); } // map undefined to true, i.e. no rules return allowed === undefined ? true : allowed; }; },{}],272:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Rules = _interopRequireDefault(require("./Rules")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['rules'], rules: ['type', _Rules.default] }; exports.default = _default; },{"./Rules":271}],273:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SearchPad; var _minDom = require("min-dom"); var _Elements = require("../../util/Elements"); var _EscapeUtil = require("../../util/EscapeUtil"); /** * Provides searching infrastructure */ function SearchPad(canvas, eventBus, overlays, selection) { this._open = false; this._results = []; this._eventMaps = []; this._canvas = canvas; this._eventBus = eventBus; this._overlays = overlays; this._selection = selection; // setup elements this._container = (0, _minDom.domify)(SearchPad.BOX_HTML); this._searchInput = (0, _minDom.query)(SearchPad.INPUT_SELECTOR, this._container); this._resultsContainer = (0, _minDom.query)(SearchPad.RESULTS_CONTAINER_SELECTOR, this._container); // attach search pad this._canvas.getContainer().appendChild(this._container); // cleanup on destroy eventBus.on(['canvas.destroy', 'diagram.destroy'], this.close, this); } SearchPad.$inject = ['canvas', 'eventBus', 'overlays', 'selection']; /** * Binds and keeps track of all event listereners */ SearchPad.prototype._bindEvents = function () { var self = this; function listen(el, selector, type, fn) { self._eventMaps.push({ el: el, type: type, listener: _minDom.delegate.bind(el, selector, type, fn) }); } // close search on clicking anywhere outside listen(document, 'html', 'click', function (e) { self.close(); }); // stop event from propagating and closing search // focus on input listen(this._container, SearchPad.INPUT_SELECTOR, 'click', function (e) { e.stopPropagation(); e.delegateTarget.focus(); }); // preselect result on hover listen(this._container, SearchPad.RESULT_SELECTOR, 'mouseover', function (e) { e.stopPropagation(); self._scrollToNode(e.delegateTarget); self._preselect(e.delegateTarget); }); // selects desired result on mouse click listen(this._container, SearchPad.RESULT_SELECTOR, 'click', function (e) { e.stopPropagation(); self._select(e.delegateTarget); }); // prevent cursor in input from going left and right when using up/down to // navigate results listen(this._container, SearchPad.INPUT_SELECTOR, 'keydown', function (e) { // up if (e.keyCode === 38) { e.preventDefault(); } // down if (e.keyCode === 40) { e.preventDefault(); } }); // handle keyboard input listen(this._container, SearchPad.INPUT_SELECTOR, 'keyup', function (e) { // escape if (e.keyCode === 27) { return self.close(); } // enter if (e.keyCode === 13) { var selected = self._getCurrentResult(); return selected ? self._select(selected) : self.close(); } // up if (e.keyCode === 38) { return self._scrollToDirection(true); } // down if (e.keyCode === 40) { return self._scrollToDirection(); } // left && right // do not search while navigating text input if (e.keyCode === 37 || e.keyCode === 39) { return; } // anything else self._search(e.delegateTarget.value); }); }; /** * Unbinds all previously established listeners */ SearchPad.prototype._unbindEvents = function () { this._eventMaps.forEach(function (m) { _minDom.delegate.unbind(m.el, m.type, m.listener); }); }; /** * Performs a search for the given pattern. * * @param {string} pattern */ SearchPad.prototype._search = function (pattern) { var self = this; this._clearResults(); // do not search on empty query if (!pattern || pattern === '') { return; } var searchResults = this._searchProvider.find(pattern); if (!searchResults.length) { return; } // append new results searchResults.forEach(function (result) { var id = result.element.id; var node = self._createResultNode(result, id); self._results[id] = { element: result.element, node: node }; }); // preselect first result var node = (0, _minDom.query)(SearchPad.RESULT_SELECTOR, this._resultsContainer); this._scrollToNode(node); this._preselect(node); }; /** * Navigate to the previous/next result. Defaults to next result. * @param {boolean} previous */ SearchPad.prototype._scrollToDirection = function (previous) { var selected = this._getCurrentResult(); if (!selected) { return; } var node = previous ? selected.previousElementSibling : selected.nextElementSibling; if (node) { this._scrollToNode(node); this._preselect(node); } }; /** * Scroll to the node if it is not visible. * * @param {Element} node */ SearchPad.prototype._scrollToNode = function (node) { if (!node || node === this._getCurrentResult()) { return; } var nodeOffset = node.offsetTop; var containerScroll = this._resultsContainer.scrollTop; var bottomScroll = nodeOffset - this._resultsContainer.clientHeight + node.clientHeight; if (nodeOffset < containerScroll) { this._resultsContainer.scrollTop = nodeOffset; } else if (containerScroll < bottomScroll) { this._resultsContainer.scrollTop = bottomScroll; } }; /** * Clears all results data. */ SearchPad.prototype._clearResults = function () { (0, _minDom.clear)(this._resultsContainer); this._results = []; this._resetOverlay(); this._eventBus.fire('searchPad.cleared'); }; /** * Get currently selected result. * * @return {Element} */ SearchPad.prototype._getCurrentResult = function () { return (0, _minDom.query)(SearchPad.RESULT_SELECTED_SELECTOR, this._resultsContainer); }; /** * Create result DOM element within results container * that corresponds to a search result. * * 'result' : one of the elements returned by SearchProvider * 'id' : id attribute value to assign to the new DOM node * return : created DOM element * * @param {SearchResult} result * @param {string} id * @return {Element} */ SearchPad.prototype._createResultNode = function (result, id) { var node = (0, _minDom.domify)(SearchPad.RESULT_HTML); // create only if available if (result.primaryTokens.length > 0) { createInnerTextNode(node, result.primaryTokens, SearchPad.RESULT_PRIMARY_HTML); } // secondary tokens (represent element ID) are allways available createInnerTextNode(node, result.secondaryTokens, SearchPad.RESULT_SECONDARY_HTML); (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE, id); this._resultsContainer.appendChild(node); return node; }; /** * Register search element provider. * * SearchProvider.find - provides search function over own elements * (pattern) => [{ text: <String>, element: <Element>}, ...] * * @param {SearchProvider} provider */ SearchPad.prototype.registerProvider = function (provider) { this._searchProvider = provider; }; /** * Open search pad. */ SearchPad.prototype.open = function () { if (!this._searchProvider) { throw new Error('no search provider registered'); } if (this.isOpen()) { return; } this._bindEvents(); this._open = true; (0, _minDom.classes)(this._container).add('open'); this._searchInput.focus(); this._eventBus.fire('searchPad.opened'); }; /** * Close search pad. */ SearchPad.prototype.close = function () { if (!this.isOpen()) { return; } this._unbindEvents(); this._open = false; (0, _minDom.classes)(this._container).remove('open'); this._clearResults(); this._searchInput.value = ''; this._searchInput.blur(); this._resetOverlay(); this._eventBus.fire('searchPad.closed'); }; /** * Toggles search pad on/off. */ SearchPad.prototype.toggle = function () { this.isOpen() ? this.close() : this.open(); }; /** * Report state of search pad. */ SearchPad.prototype.isOpen = function () { return this._open; }; /** * Preselect result entry. * * @param {Element} element */ SearchPad.prototype._preselect = function (node) { var selectedNode = this._getCurrentResult(); // already selected if (node === selectedNode) { return; } // removing preselection from current node if (selectedNode) { (0, _minDom.classes)(selectedNode).remove(SearchPad.RESULT_SELECTED_CLASS); } var id = (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE); var element = this._results[id].element; (0, _minDom.classes)(node).add(SearchPad.RESULT_SELECTED_CLASS); this._resetOverlay(element); this._centerViewbox(element); this._selection.select(element); this._eventBus.fire('searchPad.preselected', element); }; /** * Select result node. * * @param {Element} element */ SearchPad.prototype._select = function (node) { var id = (0, _minDom.attr)(node, SearchPad.RESULT_ID_ATTRIBUTE); var element = this._results[id].element; this.close(); this._resetOverlay(); this._centerViewbox(element); this._selection.select(element); this._eventBus.fire('searchPad.selected', element); }; /** * Center viewbox on the element middle point. * * @param {Element} element */ SearchPad.prototype._centerViewbox = function (element) { var viewbox = this._canvas.viewbox(); var box = (0, _Elements.getBBox)(element); var newViewbox = { x: box.x + box.width / 2 - viewbox.outer.width / 2, y: box.y + box.height / 2 - viewbox.outer.height / 2, width: viewbox.outer.width, height: viewbox.outer.height }; this._canvas.viewbox(newViewbox); this._canvas.zoom(viewbox.scale); }; /** * Reset overlay removes and, optionally, set * overlay to a new element. * * @param {Element} element */ SearchPad.prototype._resetOverlay = function (element) { if (this._overlayId) { this._overlays.remove(this._overlayId); } if (element) { var box = (0, _Elements.getBBox)(element); var overlay = constructOverlay(box); this._overlayId = this._overlays.add(element, overlay); } }; /** * Construct overlay object for the given bounding box. * * @param {BoundingBox} box * @return {Object} */ function constructOverlay(box) { var offset = 6; var w = box.width + offset * 2; var h = box.height + offset * 2; var styles = ['width: ' + w + 'px', 'height: ' + h + 'px'].join('; '); return { position: { bottom: h - offset, right: w - offset }, show: true, html: '<div style="' + styles + '" class="' + SearchPad.OVERLAY_CLASS + '"></div>' }; } /** * Creates and appends child node from result tokens and HTML template. * * @param {Element} node * @param {Array<Object>} tokens * @param {string} template */ function createInnerTextNode(parentNode, tokens, template) { var text = createHtmlText(tokens); var childNode = (0, _minDom.domify)(template); childNode.innerHTML = text; parentNode.appendChild(childNode); } /** * Create internal HTML markup from result tokens. * Caters for highlighting pattern matched tokens. * * @param {Array<Object>} tokens * @return {string} */ function createHtmlText(tokens) { var htmlText = ''; tokens.forEach(function (t) { if (t.matched) { htmlText += '<strong class="' + SearchPad.RESULT_HIGHLIGHT_CLASS + '">' + (0, _EscapeUtil.escapeHTML)(t.matched) + '</strong>'; } else { htmlText += (0, _EscapeUtil.escapeHTML)(t.normal); } }); return htmlText !== '' ? htmlText : null; } /** * CONSTANTS */ SearchPad.CONTAINER_SELECTOR = '.djs-search-container'; SearchPad.INPUT_SELECTOR = '.djs-search-input input'; SearchPad.RESULTS_CONTAINER_SELECTOR = '.djs-search-results'; SearchPad.RESULT_SELECTOR = '.djs-search-result'; SearchPad.RESULT_SELECTED_CLASS = 'djs-search-result-selected'; SearchPad.RESULT_SELECTED_SELECTOR = '.' + SearchPad.RESULT_SELECTED_CLASS; SearchPad.RESULT_ID_ATTRIBUTE = 'data-result-id'; SearchPad.RESULT_HIGHLIGHT_CLASS = 'djs-search-highlight'; SearchPad.OVERLAY_CLASS = 'djs-search-overlay'; SearchPad.BOX_HTML = '<div class="djs-search-container djs-draggable djs-scrollable">' + '<div class="djs-search-input">' + '<input type="text"/>' + '</div>' + '<div class="djs-search-results"></div>' + '</div>'; SearchPad.RESULT_HTML = '<div class="djs-search-result"></div>'; SearchPad.RESULT_PRIMARY_HTML = '<div class="djs-search-result-primary"></div>'; SearchPad.RESULT_SECONDARY_HTML = '<p class="djs-search-result-secondary"></p>'; },{"../../util/Elements":315,"../../util/EscapeUtil":316,"min-dom":556}],274:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _overlays = _interopRequireDefault(require("../overlays")); var _selection = _interopRequireDefault(require("../selection")); var _SearchPad = _interopRequireDefault(require("./SearchPad")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_overlays.default, _selection.default], searchPad: ['type', _SearchPad.default] }; exports.default = _default; },{"../overlays":256,"../selection":278,"./SearchPad":273}],275:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Selection; var _minDash = require("min-dash"); /** * A service that offers the current selection in a diagram. * Offers the api to control the selection, too. * * @class * * @param {EventBus} eventBus the event bus */ function Selection(eventBus) { this._eventBus = eventBus; this._selectedElements = []; var self = this; eventBus.on(['shape.remove', 'connection.remove'], function (e) { var element = e.element; self.deselect(element); }); eventBus.on(['diagram.clear'], function (e) { self.select(null); }); } Selection.$inject = ['eventBus']; Selection.prototype.deselect = function (element) { var selectedElements = this._selectedElements; var idx = selectedElements.indexOf(element); if (idx !== -1) { var oldSelection = selectedElements.slice(); selectedElements.splice(idx, 1); this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements }); } }; Selection.prototype.get = function () { return this._selectedElements; }; Selection.prototype.isSelected = function (element) { return this._selectedElements.indexOf(element) !== -1; }; /** * This method selects one or more elements on the diagram. * * By passing an additional add parameter you can decide whether or not the element(s) * should be added to the already existing selection or not. * * @method Selection#select * * @param {Object|Object[]} elements element or array of elements to be selected * @param {boolean} [add] whether the element(s) should be appended to the current selection, defaults to false */ Selection.prototype.select = function (elements, add) { var selectedElements = this._selectedElements, oldSelection = selectedElements.slice(); if (!(0, _minDash.isArray)(elements)) { elements = elements ? [elements] : []; } // selection may be cleared by passing an empty array or null // to the method if (add) { (0, _minDash.forEach)(elements, function (element) { if (selectedElements.indexOf(element) !== -1) { // already selected return; } else { selectedElements.push(element); } }); } else { this._selectedElements = selectedElements = elements.slice(); } this._eventBus.fire('selection.changed', { oldSelection: oldSelection, newSelection: selectedElements }); }; },{"min-dash":555}],276:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SelectionBehavior; var _Mouse = require("../../util/Mouse"); var _minDash = require("min-dash"); function SelectionBehavior(eventBus, selection, canvas, elementRegistry) { // Select elements on create eventBus.on('create.end', 500, function (event) { var context = event.context, canExecute = context.canExecute, elements = context.elements, hints = context.hints || {}, autoSelect = hints.autoSelect; if (canExecute) { if (autoSelect === false) { // Select no elements return; } if ((0, _minDash.isArray)(autoSelect)) { selection.select(autoSelect); } else { // Select all elements by default selection.select(elements.filter(isShown)); } } }); // Select connection targets on connect eventBus.on('connect.end', 500, function (event) { var context = event.context, canExecute = context.canExecute, hover = context.hover; if (canExecute && hover) { selection.select(hover); } }); // Select shapes on move eventBus.on('shape.move.end', 500, function (event) { var previousSelection = event.previousSelection || []; var shape = elementRegistry.get(event.context.shape.id); // Always select main shape on move var isSelected = (0, _minDash.find)(previousSelection, function (selectedShape) { return shape.id === selectedShape.id; }); if (!isSelected) { selection.select(shape); } }); // Select elements on click eventBus.on('element.click', function (event) { var element = event.element; if (element === canvas.getRootElement()) { element = null; } var isSelected = selection.isSelected(element), isMultiSelect = selection.get().length > 1; // Add to selection if CTRL or SHIFT pressed var add = (0, _Mouse.hasPrimaryModifier)(event) || (0, _Mouse.hasSecondaryModifier)(event); if (isSelected && isMultiSelect) { if (add) { // Deselect element return selection.deselect(element); } else { // Select element only return selection.select(element); } } else if (!isSelected) { // Select element selection.select(element, add); } else { // Deselect element selection.deselect(element); } }); } SelectionBehavior.$inject = ['eventBus', 'selection', 'canvas', 'elementRegistry']; function isShown(element) { return !element.hidden; } },{"../../util/Mouse":323,"min-dash":555}],277:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SelectionVisuals; var _minDash = require("min-dash"); var MARKER_HOVER = 'hover', MARKER_SELECTED = 'selected'; /** * A plugin that adds a visible selection UI to shapes and connections * by appending the <code>hover</code> and <code>selected</code> classes to them. * * @class * * Makes elements selectable, too. * * @param {EventBus} events * @param {SelectionService} selection * @param {Canvas} canvas */ function SelectionVisuals(events, canvas, selection, styles) { this._multiSelectionBox = null; function addMarker(e, cls) { canvas.addMarker(e, cls); } function removeMarker(e, cls) { canvas.removeMarker(e, cls); } events.on('element.hover', function (event) { addMarker(event.element, MARKER_HOVER); }); events.on('element.out', function (event) { removeMarker(event.element, MARKER_HOVER); }); events.on('selection.changed', function (event) { function deselect(s) { removeMarker(s, MARKER_SELECTED); } function select(s) { addMarker(s, MARKER_SELECTED); } var oldSelection = event.oldSelection, newSelection = event.newSelection; (0, _minDash.forEach)(oldSelection, function (e) { if (newSelection.indexOf(e) === -1) { deselect(e); } }); (0, _minDash.forEach)(newSelection, function (e) { if (oldSelection.indexOf(e) === -1) { select(e); } }); }); } SelectionVisuals.$inject = ['eventBus', 'canvas', 'selection', 'styles']; },{"min-dash":555}],278:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("../interaction-events")); var _outline = _interopRequireDefault(require("../outline")); var _Selection = _interopRequireDefault(require("./Selection")); var _SelectionVisuals = _interopRequireDefault(require("./SelectionVisuals")); var _SelectionBehavior = _interopRequireDefault(require("./SelectionBehavior")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['selectionVisuals', 'selectionBehavior'], __depends__: [_interactionEvents.default, _outline.default], selection: ['type', _Selection.default], selectionVisuals: ['type', _SelectionVisuals.default], selectionBehavior: ['type', _SelectionBehavior.default] }; exports.default = _default; },{"../interaction-events":211,"../outline":254,"./Selection":275,"./SelectionBehavior":276,"./SelectionVisuals":277}],279:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CreateMoveSnapping; var _SnapContext = _interopRequireDefault(require("./SnapContext")); var _SnapUtil = require("./SnapUtil"); var _KeyboardUtil = require("../keyboard/KeyboardUtil"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGHER_PRIORITY = 1250; /** * Snap during create and move. * * @param {EventBus} elementRegistry * @param {EventBus} eventBus * @param {Snapping} snapping */ function CreateMoveSnapping(elementRegistry, eventBus, snapping) { var self = this; this._elementRegistry = elementRegistry; eventBus.on(['create.start', 'shape.move.start'], function (event) { self.initSnap(event); }); eventBus.on(['create.move', 'create.end', 'shape.move.move', 'shape.move.end'], HIGHER_PRIORITY, function (event) { var context = event.context, shape = context.shape, snapContext = context.snapContext, target = context.target; if (event.originalEvent && (0, _KeyboardUtil.isCmd)(event.originalEvent)) { return; } if ((0, _SnapUtil.isSnapped)(event) || !target) { return; } var snapPoints = snapContext.pointsForTarget(target); if (!snapPoints.initialized) { snapPoints = self.addSnapTargetPoints(snapPoints, shape, target); snapPoints.initialized = true; } snapping.snap(event, snapPoints); }); eventBus.on(['create.cleanup', 'shape.move.cleanup'], function () { snapping.hide(); }); } CreateMoveSnapping.$inject = ['elementRegistry', 'eventBus', 'snapping']; CreateMoveSnapping.prototype.initSnap = function (event) { var elementRegistry = this._elementRegistry; var context = event.context, shape = context.shape, snapContext = context.snapContext; if (!snapContext) { snapContext = context.snapContext = new _SnapContext.default(); } var shapeMid; if (elementRegistry.get(shape.id)) { // move shapeMid = (0, _SnapUtil.mid)(shape, event); } else { // create shapeMid = { x: event.x + (0, _SnapUtil.mid)(shape).x, y: event.y + (0, _SnapUtil.mid)(shape).y }; } var shapeTopLeft = { x: shapeMid.x - shape.width / 2, y: shapeMid.y - shape.height / 2 }, shapeBottomRight = { x: shapeMid.x + shape.width / 2, y: shapeMid.y + shape.height / 2 }; snapContext.setSnapOrigin('mid', { x: shapeMid.x - event.x, y: shapeMid.y - event.y }); // snap labels to mid only if (isLabel(shape)) { return snapContext; } snapContext.setSnapOrigin('top-left', { x: shapeTopLeft.x - event.x, y: shapeTopLeft.y - event.y }); snapContext.setSnapOrigin('bottom-right', { x: shapeBottomRight.x - event.x, y: shapeBottomRight.y - event.y }); return snapContext; }; CreateMoveSnapping.prototype.addSnapTargetPoints = function (snapPoints, shape, target) { var snapTargets = this.getSnapTargets(shape, target); (0, _minDash.forEach)(snapTargets, function (snapTarget) { // handle labels if (isLabel(snapTarget)) { if (isLabel(shape)) { snapPoints.add('mid', (0, _SnapUtil.mid)(snapTarget)); } return; } // handle connections if (isConnection(snapTarget)) { // ignore single segment connections if (snapTarget.waypoints.length < 3) { return; } // ignore first and last waypoint var waypoints = snapTarget.waypoints.slice(1, -1); (0, _minDash.forEach)(waypoints, function (waypoint) { snapPoints.add('mid', waypoint); }); return; } // handle shapes snapPoints.add('mid', (0, _SnapUtil.mid)(snapTarget)); }); if (!(0, _minDash.isNumber)(shape.x) || !(0, _minDash.isNumber)(shape.y)) { return snapPoints; } // snap to original position when moving if (this._elementRegistry.get(shape.id)) { snapPoints.add('mid', (0, _SnapUtil.mid)(shape)); } return snapPoints; }; CreateMoveSnapping.prototype.getSnapTargets = function (shape, target) { return (0, _SnapUtil.getChildren)(target).filter(function (child) { return !isHidden(child); }); }; // helpers ////////// function isConnection(element) { return !!element.waypoints; } function isHidden(element) { return !!element.hidden; } function isLabel(element) { return !!element.labelTarget; } },{"../keyboard/KeyboardUtil":216,"./SnapContext":281,"./SnapUtil":282,"min-dash":555}],280:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ResizeSnapping; var _SnapContext = _interopRequireDefault(require("./SnapContext")); var _SnapUtil = require("./SnapUtil"); var _KeyboardUtil = require("../keyboard/KeyboardUtil"); var _LayoutUtil = require("../../layout/LayoutUtil"); var _minDash = require("min-dash"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HIGHER_PRIORITY = 1250; /** * Snap during resize. * * @param {EventBus} eventBus * @param {Snapping} snapping */ function ResizeSnapping(eventBus, snapping) { var self = this; eventBus.on(['resize.start'], function (event) { self.initSnap(event); }); eventBus.on(['resize.move', 'resize.end'], HIGHER_PRIORITY, function (event) { var context = event.context, shape = context.shape, parent = shape.parent, direction = context.direction, snapContext = context.snapContext; if (event.originalEvent && (0, _KeyboardUtil.isCmd)(event.originalEvent)) { return; } if ((0, _SnapUtil.isSnapped)(event)) { return; } var snapPoints = snapContext.pointsForTarget(parent); if (!snapPoints.initialized) { snapPoints = self.addSnapTargetPoints(snapPoints, shape, parent, direction); snapPoints.initialized = true; } if (isHorizontal(direction)) { (0, _SnapUtil.setSnapped)(event, 'x', event.x); } if (isVertical(direction)) { (0, _SnapUtil.setSnapped)(event, 'y', event.y); } snapping.snap(event, snapPoints); }); eventBus.on(['resize.cleanup'], function () { snapping.hide(); }); } ResizeSnapping.prototype.initSnap = function (event) { var context = event.context, shape = context.shape, direction = context.direction, snapContext = context.snapContext; if (!snapContext) { snapContext = context.snapContext = new _SnapContext.default(); } var snapOrigin = getSnapOrigin(shape, direction); snapContext.setSnapOrigin('corner', { x: snapOrigin.x - event.x, y: snapOrigin.y - event.y }); return snapContext; }; ResizeSnapping.prototype.addSnapTargetPoints = function (snapPoints, shape, target, direction) { var snapTargets = this.getSnapTargets(shape, target); (0, _minDash.forEach)(snapTargets, function (snapTarget) { snapPoints.add('corner', (0, _SnapUtil.bottomRight)(snapTarget)); snapPoints.add('corner', (0, _SnapUtil.topLeft)(snapTarget)); }); snapPoints.add('corner', getSnapOrigin(shape, direction)); return snapPoints; }; ResizeSnapping.$inject = ['eventBus', 'snapping']; ResizeSnapping.prototype.getSnapTargets = function (shape, target) { return (0, _SnapUtil.getChildren)(target).filter(function (child) { return !isAttached(child, shape) && !isConnection(child) && !isHidden(child) && !isLabel(child); }); }; // helpers ////////// function getSnapOrigin(shape, direction) { var mid = (0, _LayoutUtil.getMid)(shape), trbl = (0, _LayoutUtil.asTRBL)(shape); var snapOrigin = { x: mid.x, y: mid.y }; if (direction.indexOf('n') !== -1) { snapOrigin.y = trbl.top; } else if (direction.indexOf('s') !== -1) { snapOrigin.y = trbl.bottom; } if (direction.indexOf('e') !== -1) { snapOrigin.x = trbl.right; } else if (direction.indexOf('w') !== -1) { snapOrigin.x = trbl.left; } return snapOrigin; } function isAttached(element, host) { return element.host === host; } function isConnection(element) { return !!element.waypoints; } function isHidden(element) { return !!element.hidden; } function isLabel(element) { return !!element.labelTarget; } function isHorizontal(direction) { return direction === 'n' || direction === 's'; } function isVertical(direction) { return direction === 'e' || direction === 'w'; } },{"../../layout/LayoutUtil":300,"../keyboard/KeyboardUtil":216,"./SnapContext":281,"./SnapUtil":282,"min-dash":555}],281:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SnapContext; exports.SnapPoints = SnapPoints; var _minDash = require("min-dash"); var _SnapUtil = require("./SnapUtil"); /** * A snap context, containing the (possibly incomplete) * mappings of drop targets (to identify the snapping) * to computed snap points. */ function SnapContext() { /** * Map<String, SnapPoints> mapping drop targets to * a list of possible snappings. * * @type {Object} */ this._targets = {}; /** * Map<String, Point> initial positioning of element * regarding various snap directions. * * @type {Object} */ this._snapOrigins = {}; /** * List of snap locations * * @type {Array<string>} */ this._snapLocations = []; /** * Map<String, Array<Point>> of default snapping locations * * @type {Object} */ this._defaultSnaps = {}; } SnapContext.prototype.getSnapOrigin = function (snapLocation) { return this._snapOrigins[snapLocation]; }; SnapContext.prototype.setSnapOrigin = function (snapLocation, initialValue) { this._snapOrigins[snapLocation] = initialValue; if (this._snapLocations.indexOf(snapLocation) === -1) { this._snapLocations.push(snapLocation); } }; SnapContext.prototype.addDefaultSnap = function (type, point) { var snapValues = this._defaultSnaps[type]; if (!snapValues) { snapValues = this._defaultSnaps[type] = []; } snapValues.push(point); }; /** * Return a number of initialized snaps, i.e. snap locations such as * top-left, mid, bottom-right and so forth. * * @return {Array<string>} snapLocations */ SnapContext.prototype.getSnapLocations = function () { return this._snapLocations; }; /** * Set the snap locations for this context. * * The order of locations determines precedence. * * @param {Array<string>} snapLocations */ SnapContext.prototype.setSnapLocations = function (snapLocations) { this._snapLocations = snapLocations; }; /** * Get snap points for a given target * * @param {Element|string} target */ SnapContext.prototype.pointsForTarget = function (target) { var targetId = target.id || target; var snapPoints = this._targets[targetId]; if (!snapPoints) { snapPoints = this._targets[targetId] = new SnapPoints(); snapPoints.initDefaults(this._defaultSnaps); } return snapPoints; }; /** * Creates the snap points and initializes them with the * given default values. * * @param {Object<string, Array<Point>>} [defaultPoints] */ function SnapPoints(defaultSnaps) { /** * Map<String, Map<(x|y), Array<number>>> mapping snap locations, * i.e. top-left, bottom-right, center to actual snap values. * * @type {Object} */ this._snapValues = {}; } SnapPoints.prototype.add = function (snapLocation, point) { var snapValues = this._snapValues[snapLocation]; if (!snapValues) { snapValues = this._snapValues[snapLocation] = { x: [], y: [] }; } if (snapValues.x.indexOf(point.x) === -1) { snapValues.x.push(point.x); } if (snapValues.y.indexOf(point.y) === -1) { snapValues.y.push(point.y); } }; SnapPoints.prototype.snap = function (point, snapLocation, axis, tolerance) { var snappingValues = this._snapValues[snapLocation]; return snappingValues && (0, _SnapUtil.snapTo)(point[axis], snappingValues[axis], tolerance); }; /** * Initialize a number of default snapping points. * * @param {Object} defaultSnaps */ SnapPoints.prototype.initDefaults = function (defaultSnaps) { var self = this; (0, _minDash.forEach)(defaultSnaps || {}, function (snapPoints, snapLocation) { (0, _minDash.forEach)(snapPoints, function (point) { self.add(snapLocation, point); }); }); }; },{"./SnapUtil":282,"min-dash":555}],282:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.snapTo = snapTo; exports.topLeft = topLeft; exports.topRight = topRight; exports.bottomLeft = bottomLeft; exports.bottomRight = bottomRight; exports.mid = mid; exports.isSnapped = isSnapped; exports.setSnapped = setSnapped; exports.getChildren = getChildren; var abs = Math.abs, round = Math.round; /** * Snap value to a collection of reference values. * * @param {number} value * @param {Array<number>} values * @param {number} [tolerance=10] * * @return {number} the value we snapped to or null, if none snapped */ function snapTo(value, values, tolerance) { tolerance = tolerance === undefined ? 10 : tolerance; var idx, snapValue; for (idx = 0; idx < values.length; idx++) { snapValue = values[idx]; if (abs(snapValue - value) <= tolerance) { return snapValue; } } } function topLeft(bounds) { return { x: bounds.x, y: bounds.y }; } function topRight(bounds) { return { x: bounds.x + bounds.width, y: bounds.y }; } function bottomLeft(bounds) { return { x: bounds.x, y: bounds.y + bounds.height }; } function bottomRight(bounds) { return { x: bounds.x + bounds.width, y: bounds.y + bounds.height }; } function mid(bounds, defaultValue) { if (!bounds || isNaN(bounds.x) || isNaN(bounds.y)) { return defaultValue; } return { x: round(bounds.x + bounds.width / 2), y: round(bounds.y + bounds.height / 2) }; } /** * Retrieve the snap state of the given event. * * @param {Event} event * @param {string} axis * * @return {boolean} the snapped state * */ function isSnapped(event, axis) { var snapped = event.snapped; if (!snapped) { return false; } if (typeof axis === 'string') { return snapped[axis]; } return snapped.x && snapped.y; } /** * Set the given event as snapped. * * This method may change the x and/or y position of the shape * from the given event! * * @param {Event} event * @param {string} axis * @param {number|boolean} value * * @return {number} old value */ function setSnapped(event, axis, value) { if (typeof axis !== 'string') { throw new Error('axis must be in [x, y]'); } if (typeof value !== 'number' && value !== false) { throw new Error('value must be Number or false'); } var delta, previousValue = event[axis]; var snapped = event.snapped = event.snapped || {}; if (value === false) { snapped[axis] = false; } else { snapped[axis] = true; delta = value - previousValue; event[axis] += delta; event['d' + axis] += delta; } return previousValue; } /** * Get children of a shape. * * @param {djs.model.Shape} parent * * @returns {Array<djs.model.Shape|djs.model.Connection>} */ function getChildren(parent) { return parent.children || []; } },{}],283:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Snapping; exports.SNAP_LINE_HIDE_DELAY = void 0; var _minDash = require("min-dash"); var _SnapUtil = require("./SnapUtil"); var _tinySvg = require("tiny-svg"); var SNAP_TOLERANCE = 7; var SNAP_LINE_HIDE_DELAY = 1000; /** * Generic snapping feature. * * @param {EventBus} eventBus * @param {Canvas} canvas */ exports.SNAP_LINE_HIDE_DELAY = SNAP_LINE_HIDE_DELAY; function Snapping(canvas) { this._canvas = canvas; // delay hide by 1000 seconds since last snap this._asyncHide = (0, _minDash.debounce)((0, _minDash.bind)(this.hide, this), SNAP_LINE_HIDE_DELAY); } Snapping.$inject = ['canvas']; /** * Snap an event to given snap points. * * @param {Event} event * @param {SnapPoints} snapPoints */ Snapping.prototype.snap = function (event, snapPoints) { var context = event.context, snapContext = context.snapContext, snapLocations = snapContext.getSnapLocations(); var snapping = { x: (0, _SnapUtil.isSnapped)(event, 'x'), y: (0, _SnapUtil.isSnapped)(event, 'y') }; (0, _minDash.forEach)(snapLocations, function (location) { var snapOrigin = snapContext.getSnapOrigin(location); var snapCurrent = { x: event.x + snapOrigin.x, y: event.y + snapOrigin.y }; // snap both axis if not snapped already (0, _minDash.forEach)(['x', 'y'], function (axis) { var locationSnapping; if (!snapping[axis]) { locationSnapping = snapPoints.snap(snapCurrent, location, axis, SNAP_TOLERANCE); if (locationSnapping !== undefined) { snapping[axis] = { value: locationSnapping, originValue: locationSnapping - snapOrigin[axis] }; } } }); // no need to continue snapping if (snapping.x && snapping.y) { return false; } }); // show snap lines this.showSnapLine('vertical', snapping.x && snapping.x.value); this.showSnapLine('horizontal', snapping.y && snapping.y.value); // snap event (0, _minDash.forEach)(['x', 'y'], function (axis) { var axisSnapping = snapping[axis]; if ((0, _minDash.isObject)(axisSnapping)) { (0, _SnapUtil.setSnapped)(event, axis, axisSnapping.originValue); } }); }; Snapping.prototype._createLine = function (orientation) { var root = this._canvas.getLayer('snap'); var line = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(line, { d: 'M0,0 L0,0' }); (0, _tinySvg.classes)(line).add('djs-snap-line'); (0, _tinySvg.append)(root, line); return { update: function (position) { if (!(0, _minDash.isNumber)(position)) { (0, _tinySvg.attr)(line, { display: 'none' }); } else { if (orientation === 'horizontal') { (0, _tinySvg.attr)(line, { d: 'M-100000,' + position + ' L+100000,' + position, display: '' }); } else { (0, _tinySvg.attr)(line, { d: 'M ' + position + ',-100000 L ' + position + ', +100000', display: '' }); } } } }; }; Snapping.prototype._createSnapLines = function () { this._snapLines = { horizontal: this._createLine('horizontal'), vertical: this._createLine('vertical') }; }; Snapping.prototype.showSnapLine = function (orientation, position) { var line = this.getSnapLine(orientation); if (line) { line.update(position); } this._asyncHide(); }; Snapping.prototype.getSnapLine = function (orientation) { if (!this._snapLines) { this._createSnapLines(); } return this._snapLines[orientation]; }; Snapping.prototype.hide = function () { (0, _minDash.forEach)(this._snapLines, function (snapLine) { snapLine.update(); }); }; },{"./SnapUtil":282,"min-dash":555,"tiny-svg":567}],284:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _CreateMoveSnapping = _interopRequireDefault(require("./CreateMoveSnapping")); var _ResizeSnapping = _interopRequireDefault(require("./ResizeSnapping")); var _Snapping = _interopRequireDefault(require("./Snapping")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['createMoveSnapping', 'resizeSnapping', 'snapping'], createMoveSnapping: ['type', _CreateMoveSnapping.default], resizeSnapping: ['type', _ResizeSnapping.default], snapping: ['type', _Snapping.default] }; exports.default = _default; },{"./CreateMoveSnapping":279,"./ResizeSnapping":280,"./Snapping":283}],285:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceTool; var _minDash = require("min-dash"); var _LayoutUtil = require("../../layout/LayoutUtil"); var _Elements = require("../../util/Elements"); var _SpaceUtil = require("./SpaceUtil"); var _Mouse = require("../../util/Mouse"); var _Cursor = require("../../util/Cursor"); var abs = Math.abs, round = Math.round; var AXIS_TO_DIMENSION = { x: 'width', y: 'height' }; var CURSOR_CROSSHAIR = 'crosshair'; var DIRECTION_TO_TRBL = { n: 'top', w: 'left', s: 'bottom', e: 'right' }; var HIGH_PRIORITY = 1500; var DIRECTION_TO_OPPOSITE = { n: 's', w: 'e', s: 'n', e: 'w' }; var PADDING = 20; /** * Add or remove space by moving and resizing elements. * * @param {Canvas} canvas * @param {Dragging} dragging * @param {EventBus} eventBus * @param {Modeling} modeling * @param {Rules} rules * @param {toolManager} toolManager */ function SpaceTool(canvas, dragging, eventBus, modeling, rules, toolManager) { this._canvas = canvas; this._dragging = dragging; this._eventBus = eventBus; this._modeling = modeling; this._rules = rules; this._toolManager = toolManager; var self = this; toolManager.registerTool('space', { tool: 'spaceTool.selection', dragging: 'spaceTool' }); eventBus.on('spaceTool.selection.end', function (event) { eventBus.once('spaceTool.selection.ended', function () { self.activateMakeSpace(event.originalEvent); }); }); eventBus.on('spaceTool.move', HIGH_PRIORITY, function (event) { var context = event.context, initialized = context.initialized; if (!initialized) { initialized = context.initialized = self.init(event, context); } if (initialized) { ensureConstraints(event); } }); eventBus.on('spaceTool.end', function (event) { var context = event.context, axis = context.axis, direction = context.direction, movingShapes = context.movingShapes, resizingShapes = context.resizingShapes, start = context.start; if (!context.initialized) { return; } ensureConstraints(event); var delta = { x: 0, y: 0 }; delta[axis] = round(event['d' + axis]); self.makeSpace(movingShapes, resizingShapes, delta, direction, start); eventBus.once('spaceTool.ended', function (event) { // activate space tool selection after make space self.activateSelection(event.originalEvent, true, true); }); }); } SpaceTool.$inject = ['canvas', 'dragging', 'eventBus', 'modeling', 'rules', 'toolManager']; /** * Activate space tool selection. * * @param {Object} event * @param {boolean} autoActivate */ SpaceTool.prototype.activateSelection = function (event, autoActivate, reactivate) { this._dragging.init(event, 'spaceTool.selection', { autoActivate: autoActivate, cursor: CURSOR_CROSSHAIR, data: { context: { reactivate: reactivate } }, trapClick: false }); }; /** * Activate space tool make space. * * @param {MouseEvent} event */ SpaceTool.prototype.activateMakeSpace = function (event) { this._dragging.init(event, 'spaceTool', { autoActivate: true, cursor: CURSOR_CROSSHAIR, data: { context: {} } }); }; /** * Make space. * * @param {Array<djs.model.Shape>} movingShapes * @param {Array<djs.model.Shape>} resizingShapes * @param {Object} delta * @param {number} delta.x * @param {number} delta.y * @param {string} direction * @param {number} start */ SpaceTool.prototype.makeSpace = function (movingShapes, resizingShapes, delta, direction, start) { return this._modeling.createSpace(movingShapes, resizingShapes, delta, direction, start); }; /** * Initialize make space and return true if that was successful. * * @param {Object} event * @param {Object} context * * @return {boolean} */ SpaceTool.prototype.init = function (event, context) { var axis = abs(event.dx) > abs(event.dy) ? 'x' : 'y', delta = event['d' + axis], start = event[axis] - delta; if (abs(delta) < 5) { return false; } // invert delta to remove space when moving left if (delta < 0) { delta *= -1; } // invert delta to add/remove space when removing/adding space if modifier key is pressed if ((0, _Mouse.hasPrimaryModifier)(event)) { delta *= -1; } var direction = (0, _SpaceUtil.getDirection)(axis, delta); var root = this._canvas.getRootElement(); var children = (0, _Elements.selfAndAllChildren)(root, true); var elements = this.calculateAdjustments(children, axis, delta, start); var minDimensions = this._eventBus.fire('spaceTool.getMinDimensions', { axis: axis, direction: direction, shapes: elements.resizingShapes, start: start }); var spaceToolConstraints = getSpaceToolConstraints(elements, axis, direction, start, minDimensions); (0, _minDash.assign)(context, elements, { axis: axis, direction: direction, spaceToolConstraints: spaceToolConstraints, start: start }); (0, _Cursor.set)('resize-' + (axis === 'x' ? 'ew' : 'ns')); return true; }; /** * Get elements to be moved and resized. * * @param {Array<djs.model.Shape>} elements * @param {string} axis * @param {number} delta * @param {number} start * * @return {Object} */ SpaceTool.prototype.calculateAdjustments = function (elements, axis, delta, start) { var rules = this._rules; var movingShapes = [], resizingShapes = []; (0, _minDash.forEach)(elements, function (element) { if (!element.parent || isConnection(element)) { return; } var shapeStart = element[axis], shapeEnd = shapeStart + element[AXIS_TO_DIMENSION[axis]]; // shape to be moved if (delta > 0 && shapeStart > start || delta < 0 && shapeEnd < start) { return movingShapes.push(element); } // shape to be resized if (shapeStart < start && shapeEnd > start && rules.allowed('shape.resize', { shape: element })) { return resizingShapes.push(element); } }); return { movingShapes: movingShapes, resizingShapes: resizingShapes }; }; SpaceTool.prototype.toggle = function () { if (this.isActive()) { this._dragging.cancel(); } else { this.activateSelection(); } }; SpaceTool.prototype.isActive = function () { var context = this._dragging.context(); return context && /^spaceTool/.test(context.prefix); }; // helpers ////////// function addPadding(trbl) { return { top: trbl.top - PADDING, right: trbl.right + PADDING, bottom: trbl.bottom + PADDING, left: trbl.left - PADDING }; } function ensureConstraints(event) { var context = event.context, spaceToolConstraints = context.spaceToolConstraints; if (!spaceToolConstraints) { return; } var x, y; if ((0, _minDash.isNumber)(spaceToolConstraints.left)) { x = Math.max(event.x, spaceToolConstraints.left); event.dx = event.dx + x - event.x; event.x = x; } if ((0, _minDash.isNumber)(spaceToolConstraints.right)) { x = Math.min(event.x, spaceToolConstraints.right); event.dx = event.dx + x - event.x; event.x = x; } if ((0, _minDash.isNumber)(spaceToolConstraints.top)) { y = Math.max(event.y, spaceToolConstraints.top); event.dy = event.dy + y - event.y; event.y = y; } if ((0, _minDash.isNumber)(spaceToolConstraints.bottom)) { y = Math.min(event.y, spaceToolConstraints.bottom); event.dy = event.dy + y - event.y; event.y = y; } } function getSpaceToolConstraints(elements, axis, direction, start, minDimensions) { var movingShapes = elements.movingShapes, resizingShapes = elements.resizingShapes; if (!resizingShapes.length) { return; } var spaceToolConstraints = {}, min, max; (0, _minDash.forEach)(resizingShapes, function (resizingShape) { var resizingShapeBBox = (0, _LayoutUtil.asTRBL)(resizingShape); // find children that are not moving or resizing var nonMovingResizingChildren = (0, _minDash.filter)(resizingShape.children, function (child) { return !isConnection(child) && !isLabel(child) && !includes(movingShapes, child) && !includes(resizingShapes, child); }); // find children that are moving var movingChildren = (0, _minDash.filter)(resizingShape.children, function (child) { return !isConnection(child) && !isLabel(child) && includes(movingShapes, child); }); var minOrMax, nonMovingResizingChildrenBBox, movingChildrenBBox; if (nonMovingResizingChildren.length) { nonMovingResizingChildrenBBox = addPadding((0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(nonMovingResizingChildren))); minOrMax = start - resizingShapeBBox[DIRECTION_TO_TRBL[direction]] + nonMovingResizingChildrenBBox[DIRECTION_TO_TRBL[direction]]; if (direction === 'n') { spaceToolConstraints.bottom = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 'w') { spaceToolConstraints.right = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 's') { spaceToolConstraints.top = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } else if (direction === 'e') { spaceToolConstraints.left = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } } if (movingChildren.length) { movingChildrenBBox = addPadding((0, _LayoutUtil.asTRBL)((0, _Elements.getBBox)(movingChildren))); minOrMax = start - movingChildrenBBox[DIRECTION_TO_TRBL[DIRECTION_TO_OPPOSITE[direction]]] + resizingShapeBBox[DIRECTION_TO_TRBL[DIRECTION_TO_OPPOSITE[direction]]]; if (direction === 'n') { spaceToolConstraints.bottom = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 'w') { spaceToolConstraints.right = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 's') { spaceToolConstraints.top = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } else if (direction === 'e') { spaceToolConstraints.left = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } } var resizingShapeMinDimensions = minDimensions && minDimensions[resizingShape.id]; if (resizingShapeMinDimensions) { if (direction === 'n') { minOrMax = start + resizingShape[AXIS_TO_DIMENSION[axis]] - resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]]; spaceToolConstraints.bottom = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 'w') { minOrMax = start + resizingShape[AXIS_TO_DIMENSION[axis]] - resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]]; spaceToolConstraints.right = max = (0, _minDash.isNumber)(max) ? Math.min(max, minOrMax) : minOrMax; } else if (direction === 's') { minOrMax = start - resizingShape[AXIS_TO_DIMENSION[axis]] + resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]]; spaceToolConstraints.top = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } else if (direction === 'e') { minOrMax = start - resizingShape[AXIS_TO_DIMENSION[axis]] + resizingShapeMinDimensions[AXIS_TO_DIMENSION[axis]]; spaceToolConstraints.left = min = (0, _minDash.isNumber)(min) ? Math.max(min, minOrMax) : minOrMax; } } }); return spaceToolConstraints; } function includes(array, item) { return array.indexOf(item) !== -1; } function isConnection(element) { return !!element.waypoints; } function isLabel(element) { return !!element.labelTarget; } },{"../../layout/LayoutUtil":300,"../../util/Cursor":314,"../../util/Elements":315,"../../util/Mouse":323,"./SpaceUtil":287,"min-dash":555}],286:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = SpaceToolPreview; var _minDash = require("min-dash"); var _tinySvg = require("tiny-svg"); var _SvgTransformUtil = require("../../util/SvgTransformUtil"); var MARKER_DRAGGING = 'djs-dragging', MARKER_RESIZING = 'djs-resizing'; var LOW_PRIORITY = 250; var max = Math.max; /** * Provides previews for selecting/moving/resizing shapes when creating/removing space. * * @param {EventBus} eventBus * @param {ElementRegistry} elementRegistry * @param {Canvas} canvas * @param {Styles} styles */ function SpaceToolPreview(eventBus, elementRegistry, canvas, styles, previewSupport) { function addPreviewGfx(collection, dragGroup) { (0, _minDash.forEach)(collection, function (element) { previewSupport.addDragger(element, dragGroup); canvas.addMarker(element, MARKER_DRAGGING); }); } // add crosshair eventBus.on('spaceTool.selection.start', function (event) { var space = canvas.getLayer('space'), context = event.context; var orientation = { x: 'M 0,-10000 L 0,10000', y: 'M -10000,0 L 10000,0' }; var crosshairGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(crosshairGroup, styles.cls('djs-crosshair-group', ['no-events'])); (0, _tinySvg.append)(space, crosshairGroup); // horizontal path var pathX = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(pathX, 'd', orientation.x); (0, _tinySvg.classes)(pathX).add('djs-crosshair'); (0, _tinySvg.append)(crosshairGroup, pathX); // vertical path var pathY = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(pathY, 'd', orientation.y); (0, _tinySvg.classes)(pathY).add('djs-crosshair'); (0, _tinySvg.append)(crosshairGroup, pathY); context.crosshairGroup = crosshairGroup; }); // update crosshair eventBus.on('spaceTool.selection.move', function (event) { var crosshairGroup = event.context.crosshairGroup; (0, _SvgTransformUtil.translate)(crosshairGroup, event.x, event.y); }); // remove crosshair eventBus.on('spaceTool.selection.cleanup', function (event) { var context = event.context, crosshairGroup = context.crosshairGroup; if (crosshairGroup) { (0, _tinySvg.remove)(crosshairGroup); } }); // add and update move/resize previews eventBus.on('spaceTool.move', LOW_PRIORITY, function (event) { var context = event.context, line = context.line, axis = context.axis, movingShapes = context.movingShapes, resizingShapes = context.resizingShapes; if (!context.initialized) { return; } if (!context.dragGroup) { var spaceLayer = canvas.getLayer('space'); line = (0, _tinySvg.create)('path'); (0, _tinySvg.attr)(line, 'd', 'M0,0 L0,0'); (0, _tinySvg.classes)(line).add('djs-crosshair'); (0, _tinySvg.append)(spaceLayer, line); context.line = line; var dragGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(dragGroup, styles.cls('djs-drag-group', ['no-events'])); (0, _tinySvg.append)(canvas.getDefaultLayer(), dragGroup); // shapes addPreviewGfx(movingShapes, dragGroup); // connections var movingConnections = context.movingConnections = elementRegistry.filter(function (element) { var sourceIsMoving = false; (0, _minDash.forEach)(movingShapes, function (shape) { (0, _minDash.forEach)(shape.outgoing, function (connection) { if (element === connection) { sourceIsMoving = true; } }); }); var targetIsMoving = false; (0, _minDash.forEach)(movingShapes, function (shape) { (0, _minDash.forEach)(shape.incoming, function (connection) { if (element === connection) { targetIsMoving = true; } }); }); var sourceIsResizing = false; (0, _minDash.forEach)(resizingShapes, function (shape) { (0, _minDash.forEach)(shape.outgoing, function (connection) { if (element === connection) { sourceIsResizing = true; } }); }); var targetIsResizing = false; (0, _minDash.forEach)(resizingShapes, function (shape) { (0, _minDash.forEach)(shape.incoming, function (connection) { if (element === connection) { targetIsResizing = true; } }); }); return isConnection(element) && (sourceIsMoving || sourceIsResizing) && (targetIsMoving || targetIsResizing); }); addPreviewGfx(movingConnections, dragGroup); context.dragGroup = dragGroup; } if (!context.frameGroup) { var frameGroup = (0, _tinySvg.create)('g'); (0, _tinySvg.attr)(frameGroup, styles.cls('djs-frame-group', ['no-events'])); (0, _tinySvg.append)(canvas.getDefaultLayer(), frameGroup); var frames = []; (0, _minDash.forEach)(resizingShapes, function (shape) { var frame = previewSupport.addFrame(shape, frameGroup); var initialBounds = frame.getBBox(); frames.push({ element: frame, initialBounds: initialBounds }); canvas.addMarker(shape, MARKER_RESIZING); }); context.frameGroup = frameGroup; context.frames = frames; } var orientation = { x: 'M' + event.x + ', -10000 L' + event.x + ', 10000', y: 'M -10000, ' + event.y + ' L 10000, ' + event.y }; (0, _tinySvg.attr)(line, { d: orientation[axis] }); var opposite = { x: 'y', y: 'x' }; var delta = { x: event.dx, y: event.dy }; delta[opposite[context.axis]] = 0; // update move previews (0, _SvgTransformUtil.translate)(context.dragGroup, delta.x, delta.y); // update resize previews (0, _minDash.forEach)(context.frames, function (frame) { var element = frame.element, initialBounds = frame.initialBounds, width, height; if (context.direction === 'e') { (0, _tinySvg.attr)(element, { width: max(initialBounds.width + delta.x, 5) }); } else { width = max(initialBounds.width - delta.x, 5); (0, _tinySvg.attr)(element, { width: width, x: initialBounds.x + initialBounds.width - width }); } if (context.direction === 's') { (0, _tinySvg.attr)(element, { height: max(initialBounds.height + delta.y, 5) }); } else { height = max(initialBounds.height - delta.y, 5); (0, _tinySvg.attr)(element, { height: height, y: initialBounds.y + initialBounds.height - height }); } }); }); // remove move/resize previews eventBus.on('spaceTool.cleanup', function (event) { var context = event.context, movingShapes = context.movingShapes, movingConnections = context.movingConnections, resizingShapes = context.resizingShapes, line = context.line, dragGroup = context.dragGroup, frameGroup = context.frameGroup; // moving shapes (0, _minDash.forEach)(movingShapes, function (shape) { canvas.removeMarker(shape, MARKER_DRAGGING); }); // moving connections (0, _minDash.forEach)(movingConnections, function (connection) { canvas.removeMarker(connection, MARKER_DRAGGING); }); if (dragGroup) { (0, _tinySvg.remove)(line); (0, _tinySvg.remove)(dragGroup); } (0, _minDash.forEach)(resizingShapes, function (shape) { canvas.removeMarker(shape, MARKER_RESIZING); }); if (frameGroup) { (0, _tinySvg.remove)(frameGroup); } }); } SpaceToolPreview.$inject = ['eventBus', 'elementRegistry', 'canvas', 'styles', 'previewSupport']; // helpers ////////////////////// /** * Checks if an element is a connection. */ function isConnection(element) { return element.waypoints; } },{"../../util/SvgTransformUtil":328,"min-dash":555,"tiny-svg":567}],287:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDirection = getDirection; exports.getWaypointsUpdatingConnections = getWaypointsUpdatingConnections; exports.resizeBounds = resizeBounds; var _minDash = require("min-dash"); /** * Return direction given axis and delta. * * @param {string} axis * @param {number} delta * * @return {string} */ function getDirection(axis, delta) { if (axis === 'x') { if (delta > 0) { return 'e'; } if (delta < 0) { return 'w'; } } if (axis === 'y') { if (delta > 0) { return 's'; } if (delta < 0) { return 'n'; } } return null; } /** * Returns connections whose waypoints are to be updated. Waypoints are to be updated if start * or end is to be moved or resized. * * @param {Array<djs.model.Shape} movingShapes * @param {Array<djs.model.Shape} resizingShapes * * @returns {Array<djs.model.Connection>} */ function getWaypointsUpdatingConnections(movingShapes, resizingShapes) { var waypointsUpdatingConnections = []; (0, _minDash.forEach)(movingShapes.concat(resizingShapes), function (shape) { var incoming = shape.incoming, outgoing = shape.outgoing; (0, _minDash.forEach)(incoming.concat(outgoing), function (connection) { var source = connection.source, target = connection.target; if (includes(movingShapes, source) || includes(movingShapes, target) || includes(resizingShapes, source) || includes(resizingShapes, target)) { if (!includes(waypointsUpdatingConnections, connection)) { waypointsUpdatingConnections.push(connection); } } }); }); return waypointsUpdatingConnections; } function includes(array, item) { return array.indexOf(item) !== -1; } /** * Resize bounds. * * @param {Object} bounds * @param {number} bounds.x * @param {number} bounds.y * @param {number} bounds.width * @param {number} bounds.height * @param {string} direction * @param {Object} delta * @param {number} delta.x * @param {number} delta.y * * @return {Object} */ function resizeBounds(bounds, direction, delta) { var x = bounds.x, y = bounds.y, width = bounds.width, height = bounds.height, dx = delta.x, dy = delta.y; switch (direction) { case 'n': return { x: x, y: y + dy, width: width, height: height - dy }; case 's': return { x: x, y: y, width: width, height: height + dy }; case 'w': return { x: x + dx, y: y, width: width - dx, height: height }; case 'e': return { x: x, y: y, width: width + dx, height: height }; default: throw new Error('unknown direction: ' + direction); } } },{"min-dash":555}],288:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _rules = _interopRequireDefault(require("../rules")); var _toolManager = _interopRequireDefault(require("../tool-manager")); var _previewSupport = _interopRequireDefault(require("../preview-support")); var _SpaceTool = _interopRequireDefault(require("./SpaceTool")); var _SpaceToolPreview = _interopRequireDefault(require("./SpaceToolPreview")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['spaceToolPreview'], __depends__: [_dragging.default, _rules.default, _toolManager.default, _previewSupport.default], spaceTool: ['type', _SpaceTool.default], spaceToolPreview: ['type', _SpaceToolPreview.default] }; exports.default = _default; },{"../dragging":197,"../preview-support":262,"../rules":272,"../tool-manager":290,"./SpaceTool":285,"./SpaceToolPreview":286}],289:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ToolManager; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var LOW_PRIORITY = 250; /** * The tool manager acts as middle-man between the available tool's and the Palette, * it takes care of making sure that the correct active state is set. * * @param {Object} eventBus * @param {Object} dragging */ function ToolManager(eventBus, dragging) { this._eventBus = eventBus; this._dragging = dragging; this._tools = []; this._active = null; } ToolManager.$inject = ['eventBus', 'dragging']; ToolManager.prototype.registerTool = function (name, events) { var tools = this._tools; if (!events) { throw new Error('A tool has to be registered with it\'s "events"'); } tools.push(name); this.bindEvents(name, events); }; ToolManager.prototype.isActive = function (tool) { return tool && this._active === tool; }; ToolManager.prototype.length = function (tool) { return this._tools.length; }; ToolManager.prototype.setActive = function (tool) { var eventBus = this._eventBus; if (this._active !== tool) { this._active = tool; eventBus.fire('tool-manager.update', { tool: tool }); } }; ToolManager.prototype.bindEvents = function (name, events) { var eventBus = this._eventBus, dragging = this._dragging; var eventsToRegister = []; eventBus.on(events.tool + '.init', function (event) { var context = event.context; // Active tools that want to reactivate themselves must do this explicitly if (!context.reactivate && this.isActive(name)) { this.setActive(null); dragging.cancel(); return; } this.setActive(name); }, this); // Todo[ricardo]: add test cases (0, _minDash.forEach)(events, function (event) { eventsToRegister.push(event + '.ended'); eventsToRegister.push(event + '.canceled'); }); eventBus.on(eventsToRegister, LOW_PRIORITY, function (event) { var originalEvent = event.originalEvent; // We defer the de-activation of the tool to the .activate phase, // so we're able to check if we want to toggle off the current // active tool or switch to a new one if (!this._active) { return; } if (originalEvent && (0, _minDom.closest)(originalEvent.target, '.group[data-group="tools"]')) { return; } this.setActive(null); }, this); }; },{"min-dash":555,"min-dom":556}],290:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _dragging = _interopRequireDefault(require("../dragging")); var _ToolManager = _interopRequireDefault(require("./ToolManager")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_dragging.default], __init__: ['toolManager'], toolManager: ['type', _ToolManager.default] }; exports.default = _default; },{"../dragging":197,"./ToolManager":289}],291:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Tooltips; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _IdGenerator = _interopRequireDefault(require("../../util/IdGenerator")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // document wide unique tooltip ids var ids = new _IdGenerator.default('tt'); function createRoot(parentNode) { var root = (0, _minDom.domify)('<div class="djs-tooltip-container" style="position: absolute; width: 0; height: 0;" />'); parentNode.insertBefore(root, parentNode.firstChild); return root; } function setPosition(el, x, y) { (0, _minDash.assign)(el.style, { left: x + 'px', top: y + 'px' }); } function setVisible(el, visible) { el.style.display = visible === false ? 'none' : ''; } var tooltipClass = 'djs-tooltip', tooltipSelector = '.' + tooltipClass; /** * A service that allows users to render tool tips on the diagram. * * The tooltip service will take care of updating the tooltip positioning * during navigation + zooming. * * @example * * ```javascript * * // add a pink badge on the top left of the shape * tooltips.add({ * position: { * x: 50, * y: 100 * }, * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>' * }); * * // or with optional life span * tooltips.add({ * position: { * top: -5, * left: -5 * }, * html: '<div style="width: 10px; background: fuchsia; color: white;">0</div>', * ttl: 2000 * }); * * // remove a tool tip * var id = tooltips.add(...); * tooltips.remove(id); * ``` * * @param {EventBus} eventBus * @param {Canvas} canvas */ function Tooltips(eventBus, canvas) { this._eventBus = eventBus; this._canvas = canvas; this._ids = ids; this._tooltipDefaults = { show: { minZoom: 0.7, maxZoom: 5.0 } }; /** * Mapping tooltipId -> tooltip */ this._tooltips = {}; // root html element for all tooltips this._tooltipRoot = createRoot(canvas.getContainer()); var self = this; _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mousedown', function (event) { event.stopPropagation(); }); _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mouseover', function (event) { self.trigger('mouseover', event); }); _minDom.delegate.bind(this._tooltipRoot, tooltipSelector, 'mouseout', function (event) { self.trigger('mouseout', event); }); this._init(); } Tooltips.$inject = ['eventBus', 'canvas']; /** * Adds a HTML tooltip to the diagram * * @param {Object} tooltip the tooltip configuration * * @param {string|DOMElement} tooltip.html html element to use as an tooltip * @param {Object} [tooltip.show] show configuration * @param {number} [tooltip.show.minZoom] minimal zoom level to show the tooltip * @param {number} [tooltip.show.maxZoom] maximum zoom level to show the tooltip * @param {Object} tooltip.position where to attach the tooltip * @param {number} [tooltip.position.left] relative to element bbox left attachment * @param {number} [tooltip.position.top] relative to element bbox top attachment * @param {number} [tooltip.position.bottom] relative to element bbox bottom attachment * @param {number} [tooltip.position.right] relative to element bbox right attachment * @param {number} [tooltip.timeout=-1] * * @return {string} id that may be used to reference the tooltip for update or removal */ Tooltips.prototype.add = function (tooltip) { if (!tooltip.position) { throw new Error('must specifiy tooltip position'); } if (!tooltip.html) { throw new Error('must specifiy tooltip html'); } var id = this._ids.next(); tooltip = (0, _minDash.assign)({}, this._tooltipDefaults, tooltip, { id: id }); this._addTooltip(tooltip); if (tooltip.timeout) { this.setTimeout(tooltip); } return id; }; Tooltips.prototype.trigger = function (action, event) { var node = event.delegateTarget || event.target; var tooltip = this.get((0, _minDom.attr)(node, 'data-tooltip-id')); if (!tooltip) { return; } if (action === 'mouseover' && tooltip.timeout) { this.clearTimeout(tooltip); } if (action === 'mouseout' && tooltip.timeout) { // cut timeout after mouse out tooltip.timeout = 1000; this.setTimeout(tooltip); } }; /** * Get a tooltip with the given id * * @param {string} id */ Tooltips.prototype.get = function (id) { if (typeof id !== 'string') { id = id.id; } return this._tooltips[id]; }; Tooltips.prototype.clearTimeout = function (tooltip) { tooltip = this.get(tooltip); if (!tooltip) { return; } var removeTimer = tooltip.removeTimer; if (removeTimer) { clearTimeout(removeTimer); tooltip.removeTimer = null; } }; Tooltips.prototype.setTimeout = function (tooltip) { tooltip = this.get(tooltip); if (!tooltip) { return; } this.clearTimeout(tooltip); var self = this; tooltip.removeTimer = setTimeout(function () { self.remove(tooltip); }, tooltip.timeout); }; /** * Remove an tooltip with the given id * * @param {string} id */ Tooltips.prototype.remove = function (id) { var tooltip = this.get(id); if (tooltip) { (0, _minDom.remove)(tooltip.html); (0, _minDom.remove)(tooltip.htmlContainer); delete tooltip.htmlContainer; delete this._tooltips[tooltip.id]; } }; Tooltips.prototype.show = function () { setVisible(this._tooltipRoot); }; Tooltips.prototype.hide = function () { setVisible(this._tooltipRoot, false); }; Tooltips.prototype._updateRoot = function (viewbox) { var a = viewbox.scale || 1; var d = viewbox.scale || 1; var matrix = 'matrix(' + a + ',0,0,' + d + ',' + -1 * viewbox.x * a + ',' + -1 * viewbox.y * d + ')'; this._tooltipRoot.style.transform = matrix; this._tooltipRoot.style['-ms-transform'] = matrix; }; Tooltips.prototype._addTooltip = function (tooltip) { var id = tooltip.id, html = tooltip.html, htmlContainer, tooltipRoot = this._tooltipRoot; // unwrap jquery (for those who need it) if (html.get && html.constructor.prototype.jquery) { html = html.get(0); } // create proper html elements from // tooltip HTML strings if ((0, _minDash.isString)(html)) { html = (0, _minDom.domify)(html); } htmlContainer = (0, _minDom.domify)('<div data-tooltip-id="' + id + '" class="' + tooltipClass + '" style="position: absolute">'); htmlContainer.appendChild(html); if (tooltip.type) { (0, _minDom.classes)(htmlContainer).add('djs-tooltip-' + tooltip.type); } if (tooltip.className) { (0, _minDom.classes)(htmlContainer).add(tooltip.className); } tooltip.htmlContainer = htmlContainer; tooltipRoot.appendChild(htmlContainer); this._tooltips[id] = tooltip; this._updateTooltip(tooltip); }; Tooltips.prototype._updateTooltip = function (tooltip) { var position = tooltip.position, htmlContainer = tooltip.htmlContainer; // update overlay html based on tooltip x, y setPosition(htmlContainer, position.x, position.y); }; Tooltips.prototype._updateTooltipVisibilty = function (viewbox) { (0, _minDash.forEach)(this._tooltips, function (tooltip) { var show = tooltip.show, htmlContainer = tooltip.htmlContainer, visible = true; if (show) { if (show.minZoom > viewbox.scale || show.maxZoom < viewbox.scale) { visible = false; } setVisible(htmlContainer, visible); } }); }; Tooltips.prototype._init = function () { var self = this; // scroll/zoom integration function updateViewbox(viewbox) { self._updateRoot(viewbox); self._updateTooltipVisibilty(viewbox); self.show(); } this._eventBus.on('canvas.viewbox.changing', function (event) { self.hide(); }); this._eventBus.on('canvas.viewbox.changed', function (event) { updateViewbox(event.viewbox); }); }; },{"../../util/IdGenerator":320,"min-dash":555,"min-dom":556}],292:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _Tooltips = _interopRequireDefault(require("./Tooltips")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['tooltips'], tooltips: ['type', _Tooltips.default] }; exports.default = _default; },{"./Tooltips":291}],293:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TouchFix; var _tinySvg = require("tiny-svg"); function TouchFix(canvas, eventBus) { var self = this; eventBus.on('canvas.init', function (e) { self.addBBoxMarker(e.svg); }); } TouchFix.$inject = ['canvas', 'eventBus']; /** * Safari mobile (iOS 7) does not fire touchstart event in <SVG> element * if there is no shape between 0,0 and viewport elements origin. * * So touchstart event is only fired when the <g class="viewport"> element was hit. * Putting an element over and below the 'viewport' fixes that behavior. */ TouchFix.prototype.addBBoxMarker = function (svg) { var markerStyle = { fill: 'none', class: 'outer-bound-marker' }; var rect1 = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(rect1, { x: -10000, y: 10000, width: 10, height: 10 }); (0, _tinySvg.attr)(rect1, markerStyle); (0, _tinySvg.append)(svg, rect1); var rect2 = (0, _tinySvg.create)('rect'); (0, _tinySvg.attr)(rect2, { x: 10000, y: 10000, width: 10, height: 10 }); (0, _tinySvg.attr)(rect2, markerStyle); (0, _tinySvg.append)(svg, rect2); }; },{"tiny-svg":567}],294:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TouchInteractionEvents; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _hammerjs = _interopRequireDefault(require("hammerjs")); var _Event = require("../../util/Event"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var MIN_ZOOM = 0.2, MAX_ZOOM = 4; var mouseEvents = ['mousedown', 'mouseup', 'mouseover', 'mouseout', 'click', 'dblclick']; function log() {// console.log.apply(console, arguments); } function get(service, injector) { return injector.get(service, false); } function stopEvent(event) { event.preventDefault(); if (typeof event.stopPropagation === 'function') { event.stopPropagation(); } else if (event.srcEvent && typeof event.srcEvent.stopPropagation === 'function') { // iPhone & iPad event.srcEvent.stopPropagation(); } if (typeof event.stopImmediatePropagation === 'function') { event.stopImmediatePropagation(); } } function createTouchRecognizer(node) { function stopMouse(event) { (0, _minDash.forEach)(mouseEvents, function (e) { _minDom.event.bind(node, e, stopEvent, true); }); } function allowMouse(event) { setTimeout(function () { (0, _minDash.forEach)(mouseEvents, function (e) { _minDom.event.unbind(node, e, stopEvent, true); }); }, 500); } _minDom.event.bind(node, 'touchstart', stopMouse, true); _minDom.event.bind(node, 'touchend', allowMouse, true); _minDom.event.bind(node, 'touchcancel', allowMouse, true); // A touch event recognizer that handles // touch events only (we know, we can already handle // mouse events out of the box) var recognizer = new _hammerjs.default.Manager(node, { inputClass: _hammerjs.default.TouchInput, recognizers: [], domEvents: true }); var tap = new _hammerjs.default.Tap(); var pan = new _hammerjs.default.Pan({ threshold: 10 }); var press = new _hammerjs.default.Press(); var pinch = new _hammerjs.default.Pinch(); var doubleTap = new _hammerjs.default.Tap({ event: 'doubletap', taps: 2 }); pinch.requireFailure(pan); pinch.requireFailure(press); recognizer.add([pan, press, pinch, doubleTap, tap]); recognizer.reset = function (force) { var recognizers = this.recognizers, session = this.session; if (session.stopped) { return; } log('recognizer', 'stop'); recognizer.stop(force); setTimeout(function () { var i, r; log('recognizer', 'reset'); for (i = 0; r = recognizers[i]; i++) { r.reset(); r.state = 8; // FAILED STATE } session.curRecognizer = null; }, 0); }; recognizer.on('hammer.input', function (event) { if (event.srcEvent.defaultPrevented) { recognizer.reset(true); } }); return recognizer; } /** * A plugin that provides touch events for elements. * * @param {EventBus} eventBus * @param {InteractionEvents} interactionEvents */ function TouchInteractionEvents(injector, canvas, eventBus, elementRegistry, interactionEvents) { // optional integrations var dragging = get('dragging', injector), move = get('move', injector), contextPad = get('contextPad', injector), palette = get('palette', injector); // the touch recognizer var recognizer; function handler(type) { return function (event) { log('element', type, event); interactionEvents.fire(type, event); }; } function getGfx(target) { var node = (0, _minDom.closest)(target, 'svg, .djs-element', true); return node; } function initEvents(svg) { // touch recognizer recognizer = createTouchRecognizer(svg); recognizer.on('doubletap', handler('element.dblclick')); recognizer.on('tap', handler('element.click')); function startGrabCanvas(event) { log('canvas', 'grab start'); var lx = 0, ly = 0; function update(e) { var dx = e.deltaX - lx, dy = e.deltaY - ly; canvas.scroll({ dx: dx, dy: dy }); lx = e.deltaX; ly = e.deltaY; } function end(e) { recognizer.off('panmove', update); recognizer.off('panend', end); recognizer.off('pancancel', end); log('canvas', 'grab end'); } recognizer.on('panmove', update); recognizer.on('panend', end); recognizer.on('pancancel', end); } function startGrab(event) { var gfx = getGfx(event.target), element = gfx && elementRegistry.get(gfx); // recognizer if (move && canvas.getRootElement() !== element) { log('element', 'move start', element, event, true); return move.start(event, element, true); } else { startGrabCanvas(event); } } function startZoom(e) { log('canvas', 'zoom start'); var zoom = canvas.zoom(), mid = e.center; function update(e) { var ratio = 1 - (1 - e.scale) / 1.50, newZoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, ratio * zoom)); canvas.zoom(newZoom, mid); stopEvent(e); } function end(e) { recognizer.off('pinchmove', update); recognizer.off('pinchend', end); recognizer.off('pinchcancel', end); recognizer.reset(true); log('canvas', 'zoom end'); } recognizer.on('pinchmove', update); recognizer.on('pinchend', end); recognizer.on('pinchcancel', end); } recognizer.on('panstart', startGrab); recognizer.on('press', startGrab); recognizer.on('pinchstart', startZoom); } if (dragging) { // simulate hover during dragging eventBus.on('drag.move', function (event) { var originalEvent = event.originalEvent; if (!originalEvent || originalEvent instanceof MouseEvent) { return; } var position = (0, _Event.toPoint)(originalEvent); // this gets really expensive ... var node = document.elementFromPoint(position.x, position.y), gfx = getGfx(node), element = gfx && elementRegistry.get(gfx); if (element !== event.hover) { if (event.hover) { dragging.out(event); } if (element) { dragging.hover({ element: element, gfx: gfx }); event.hover = element; event.hoverGfx = gfx; } } }); } if (contextPad) { eventBus.on('contextPad.create', function (event) { var node = event.pad.html; // touch recognizer var padRecognizer = createTouchRecognizer(node); padRecognizer.on('panstart', function (event) { log('context-pad', 'panstart', event); contextPad.trigger('dragstart', event, true); }); padRecognizer.on('press', function (event) { log('context-pad', 'press', event); contextPad.trigger('dragstart', event, true); }); padRecognizer.on('tap', function (event) { log('context-pad', 'tap', event); contextPad.trigger('click', event); }); }); } if (palette) { eventBus.on('palette.create', function (event) { var node = event.container; // touch recognizer var padRecognizer = createTouchRecognizer(node); padRecognizer.on('panstart', function (event) { log('palette', 'panstart', event); palette.trigger('dragstart', event, true); }); padRecognizer.on('press', function (event) { log('palette', 'press', event); palette.trigger('dragstart', event, true); }); padRecognizer.on('tap', function (event) { log('palette', 'tap', event); palette.trigger('click', event); }); }); } eventBus.on('canvas.init', function (event) { initEvents(event.svg); }); } TouchInteractionEvents.$inject = ['injector', 'canvas', 'eventBus', 'elementRegistry', 'interactionEvents', 'touchFix']; },{"../../util/Event":317,"hammerjs":345,"min-dash":555,"min-dom":556}],295:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("../interaction-events")); var _TouchInteractionEvents = _interopRequireDefault(require("./TouchInteractionEvents")); var _TouchFix = _interopRequireDefault(require("./TouchFix")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_interactionEvents.default], __init__: ['touchInteractionEvents'], touchInteractionEvents: ['type', _TouchInteractionEvents.default], touchFix: ['type', _TouchFix.default] }; exports.default = _default; },{"../interaction-events":211,"./TouchFix":293,"./TouchInteractionEvents":294}],296:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _translate = _interopRequireDefault(require("./translate")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { translate: ['value', _translate.default] }; exports.default = _default; },{"./translate":297}],297:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = translate; /** * A simple translation stub to be used for multi-language support * in diagrams. Can be easily replaced with a more sophisticated * solution. * * @example * * // use it inside any diagram component by injecting `translate`. * * function MyService(translate) { * alert(translate('HELLO {you}', { you: 'You!' })); * } * * @param {string} template to interpolate * @param {Object} [replacements] a map with substitutes * * @return {string} the translated string */ function translate(template, replacements) { replacements = replacements || {}; return template.replace(/{([^}]+)}/g, function (_, key) { return replacements[key] || '{' + key + '}'; }); } },{}],298:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = BaseLayouter; var _LayoutUtil = require("./LayoutUtil"); /** * A base connection layouter implementation * that layouts the connection by directly connecting * mid(source) + mid(target). */ function BaseLayouter() {} /** * Return the new layouted waypoints for the given connection. * * The connection passed is still unchanged; you may figure out about * the new connection start / end via the layout hints provided. * * @param {djs.model.Connection} connection * @param {Object} [hints] * @param {Point} [hints.connectionStart] * @param {Point} [hints.connectionEnd] * @param {Point} [hints.source] * @param {Point} [hints.target] * * @return {Array<Point>} the layouted connection waypoints */ BaseLayouter.prototype.layoutConnection = function (connection, hints) { hints = hints || {}; return [hints.connectionStart || (0, _LayoutUtil.getMid)(hints.source || connection.source), hints.connectionEnd || (0, _LayoutUtil.getMid)(hints.target || connection.target)]; }; },{"./LayoutUtil":300}],299:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = CroppingConnectionDocking; var _minDash = require("min-dash"); var _LayoutUtil = require("./LayoutUtil"); function dockingToPoint(docking) { // use the dockings actual point and // retain the original docking return (0, _minDash.assign)({ original: docking.point.original || docking.point }, docking.actual); } /** * A {@link ConnectionDocking} that crops connection waypoints based on * the path(s) of the connection source and target. * * @param {djs.core.ElementRegistry} elementRegistry */ function CroppingConnectionDocking(elementRegistry, graphicsFactory) { this._elementRegistry = elementRegistry; this._graphicsFactory = graphicsFactory; } CroppingConnectionDocking.$inject = ['elementRegistry', 'graphicsFactory']; /** * @inheritDoc ConnectionDocking#getCroppedWaypoints */ CroppingConnectionDocking.prototype.getCroppedWaypoints = function (connection, source, target) { source = source || connection.source; target = target || connection.target; var sourceDocking = this.getDockingPoint(connection, source, true), targetDocking = this.getDockingPoint(connection, target); var croppedWaypoints = connection.waypoints.slice(sourceDocking.idx + 1, targetDocking.idx); croppedWaypoints.unshift(dockingToPoint(sourceDocking)); croppedWaypoints.push(dockingToPoint(targetDocking)); return croppedWaypoints; }; /** * Return the connection docking point on the specified shape * * @inheritDoc ConnectionDocking#getDockingPoint */ CroppingConnectionDocking.prototype.getDockingPoint = function (connection, shape, dockStart) { var waypoints = connection.waypoints, dockingIdx, dockingPoint, croppedPoint; dockingIdx = dockStart ? 0 : waypoints.length - 1; dockingPoint = waypoints[dockingIdx]; croppedPoint = this._getIntersection(shape, connection, dockStart); return { point: dockingPoint, actual: croppedPoint || dockingPoint, idx: dockingIdx }; }; // helpers ////////////////////// CroppingConnectionDocking.prototype._getIntersection = function (shape, connection, takeFirst) { var shapePath = this._getShapePath(shape), connectionPath = this._getConnectionPath(connection); return (0, _LayoutUtil.getElementLineIntersection)(shapePath, connectionPath, takeFirst); }; CroppingConnectionDocking.prototype._getConnectionPath = function (connection) { return this._graphicsFactory.getConnectionPath(connection); }; CroppingConnectionDocking.prototype._getShapePath = function (shape) { return this._graphicsFactory.getShapePath(shape); }; CroppingConnectionDocking.prototype._getGfx = function (element) { return this._elementRegistry.getGraphics(element); }; },{"./LayoutUtil":300,"min-dash":555}],300:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.roundBounds = roundBounds; exports.roundPoint = roundPoint; exports.asTRBL = asTRBL; exports.asBounds = asBounds; exports.getMid = getMid; exports.getOrientation = getOrientation; exports.getElementLineIntersection = getElementLineIntersection; exports.getIntersections = getIntersections; exports.filterRedundantWaypoints = filterRedundantWaypoints; var _minDash = require("min-dash"); var _Geometry = require("../util/Geometry"); var _pathIntersection = _interopRequireDefault(require("path-intersection")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function roundBounds(bounds) { return { x: Math.round(bounds.x), y: Math.round(bounds.y), width: Math.round(bounds.width), height: Math.round(bounds.height) }; } function roundPoint(point) { return { x: Math.round(point.x), y: Math.round(point.y) }; } /** * Convert the given bounds to a { top, left, bottom, right } descriptor. * * @param {Bounds|Point} bounds * * @return {Object} */ function asTRBL(bounds) { return { top: bounds.y, right: bounds.x + (bounds.width || 0), bottom: bounds.y + (bounds.height || 0), left: bounds.x }; } /** * Convert a { top, left, bottom, right } to an objects bounds. * * @param {Object} trbl * * @return {Bounds} */ function asBounds(trbl) { return { x: trbl.left, y: trbl.top, width: trbl.right - trbl.left, height: trbl.bottom - trbl.top }; } /** * Get the mid of the given bounds or point. * * @param {Bounds|Point} bounds * * @return {Point} */ function getMid(bounds) { return roundPoint({ x: bounds.x + (bounds.width || 0) / 2, y: bounds.y + (bounds.height || 0) / 2 }); } // orientation utils ////////////////////// /** * Get orientation of the given rectangle with respect to * the reference rectangle. * * A padding (positive or negative) may be passed to influence * horizontal / vertical orientation and intersection. * * @param {Bounds} rect * @param {Bounds} reference * @param {Point|number} padding * * @return {string} the orientation; one of top, top-left, left, ..., bottom, right or intersect. */ function getOrientation(rect, reference, padding) { padding = padding || 0; // make sure we can use an object, too // for individual { x, y } padding if (!(0, _minDash.isObject)(padding)) { padding = { x: padding, y: padding }; } var rectOrientation = asTRBL(rect), referenceOrientation = asTRBL(reference); var top = rectOrientation.bottom + padding.y <= referenceOrientation.top, right = rectOrientation.left - padding.x >= referenceOrientation.right, bottom = rectOrientation.top - padding.y >= referenceOrientation.bottom, left = rectOrientation.right + padding.x <= referenceOrientation.left; var vertical = top ? 'top' : bottom ? 'bottom' : null, horizontal = left ? 'left' : right ? 'right' : null; if (horizontal && vertical) { return vertical + '-' + horizontal; } else { return horizontal || vertical || 'intersect'; } } // intersection utils ////////////////////// /** * Get intersection between an element and a line path. * * @param {PathDef} elementPath * @param {PathDef} linePath * @param {boolean} cropStart crop from start or end * * @return {Point} */ function getElementLineIntersection(elementPath, linePath, cropStart) { var intersections = getIntersections(elementPath, linePath); // recognize intersections // only one -> choose // two close together -> choose first // two or more distinct -> pull out appropriate one // none -> ok (fallback to point itself) if (intersections.length === 1) { return roundPoint(intersections[0]); } else if (intersections.length === 2 && (0, _Geometry.pointDistance)(intersections[0], intersections[1]) < 1) { return roundPoint(intersections[0]); } else if (intersections.length > 1) { // sort by intersections based on connection segment + // distance from start intersections = (0, _minDash.sortBy)(intersections, function (i) { var distance = Math.floor(i.t2 * 100) || 1; distance = 100 - distance; distance = (distance < 10 ? '0' : '') + distance; // create a sort string that makes sure we sort // line segment ASC + line segment position DESC (for cropStart) // line segment ASC + line segment position ASC (for cropEnd) return i.segment2 + '#' + distance; }); return roundPoint(intersections[cropStart ? 0 : intersections.length - 1]); } return null; } function getIntersections(a, b) { return (0, _pathIntersection.default)(a, b); } function filterRedundantWaypoints(waypoints) { // alter copy of waypoints, not original waypoints = waypoints.slice(); var idx = 0, point, previousPoint, nextPoint; while (waypoints[idx]) { point = waypoints[idx]; previousPoint = waypoints[idx - 1]; nextPoint = waypoints[idx + 1]; if ((0, _Geometry.pointDistance)(point, nextPoint) === 0 || (0, _Geometry.pointsOnLine)(previousPoint, nextPoint, point)) { // remove point, if overlapping with {nextPoint} // or on line with {previousPoint} -> {point} -> {nextPoint} waypoints.splice(idx, 1); } else { idx++; } } return waypoints; } },{"../util/Geometry":318,"min-dash":555,"path-intersection":563}],301:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.connectPoints = connectPoints; exports.connectRectangles = connectRectangles; exports.repairConnection = repairConnection; exports.tryLayoutStraight = tryLayoutStraight; exports.withoutRedundantPoints = withoutRedundantPoints; var _minDash = require("min-dash"); var _LayoutUtil = require("./LayoutUtil"); var _Geometry = require("../util/Geometry"); var MIN_SEGMENT_LENGTH = 20, POINT_ORIENTATION_PADDING = 5; var round = Math.round; var INTERSECTION_THRESHOLD = 20, ORIENTATION_THRESHOLD = { 'h:h': 20, 'v:v': 20, 'h:v': -10, 'v:h': -10 }; function needsTurn(orientation, startDirection) { return !{ t: /top/, r: /right/, b: /bottom/, l: /left/, h: /./, v: /./ }[startDirection].test(orientation); } function canLayoutStraight(direction, targetOrientation) { return { t: /top/, r: /right/, b: /bottom/, l: /left/, h: /left|right/, v: /top|bottom/ }[direction].test(targetOrientation); } function getSegmentBendpoints(a, b, directions) { var orientation = (0, _LayoutUtil.getOrientation)(b, a, POINT_ORIENTATION_PADDING); var startDirection = directions.split(':')[0]; var xmid = round((b.x - a.x) / 2 + a.x), ymid = round((b.y - a.y) / 2 + a.y); var segmentEnd, segmentDirections; var layoutStraight = canLayoutStraight(startDirection, orientation), layoutHorizontal = /h|r|l/.test(startDirection), layoutTurn = false; var turnNextDirections = false; if (layoutStraight) { segmentEnd = layoutHorizontal ? { x: xmid, y: a.y } : { x: a.x, y: ymid }; segmentDirections = layoutHorizontal ? 'h:h' : 'v:v'; } else { layoutTurn = needsTurn(orientation, startDirection); segmentDirections = layoutHorizontal ? 'h:v' : 'v:h'; if (layoutTurn) { if (layoutHorizontal) { turnNextDirections = ymid === a.y; segmentEnd = { x: a.x + MIN_SEGMENT_LENGTH * (/l/.test(startDirection) ? -1 : 1), y: turnNextDirections ? ymid + MIN_SEGMENT_LENGTH : ymid }; } else { turnNextDirections = xmid === a.x; segmentEnd = { x: turnNextDirections ? xmid + MIN_SEGMENT_LENGTH : xmid, y: a.y + MIN_SEGMENT_LENGTH * (/t/.test(startDirection) ? -1 : 1) }; } } else { segmentEnd = { x: xmid, y: ymid }; } } return { waypoints: getBendpoints(a, segmentEnd, segmentDirections).concat(segmentEnd), directions: segmentDirections, turnNextDirections: turnNextDirections }; } function getStartSegment(a, b, directions) { return getSegmentBendpoints(a, b, directions); } function getEndSegment(a, b, directions) { var invertedSegment = getSegmentBendpoints(b, a, invertDirections(directions)); return { waypoints: invertedSegment.waypoints.slice().reverse(), directions: invertDirections(invertedSegment.directions), turnNextDirections: invertedSegment.turnNextDirections }; } function getMidSegment(startSegment, endSegment) { var startDirection = startSegment.directions.split(':')[1], endDirection = endSegment.directions.split(':')[0]; if (startSegment.turnNextDirections) { startDirection = startDirection == 'h' ? 'v' : 'h'; } if (endSegment.turnNextDirections) { endDirection = endDirection == 'h' ? 'v' : 'h'; } var directions = startDirection + ':' + endDirection; var bendpoints = getBendpoints(startSegment.waypoints[startSegment.waypoints.length - 1], endSegment.waypoints[0], directions); return { waypoints: bendpoints, directions: directions }; } function invertDirections(directions) { return directions.split(':').reverse().join(':'); } /** * Handle simple layouts with maximum two bendpoints. */ function getSimpleBendpoints(a, b, directions) { var xmid = round((b.x - a.x) / 2 + a.x), ymid = round((b.y - a.y) / 2 + a.y); // one point, right or left from a if (directions === 'h:v') { return [{ x: b.x, y: a.y }]; } // one point, above or below a if (directions === 'v:h') { return [{ x: a.x, y: b.y }]; } // vertical segment between a and b if (directions === 'h:h') { return [{ x: xmid, y: a.y }, { x: xmid, y: b.y }]; } // horizontal segment between a and b if (directions === 'v:v') { return [{ x: a.x, y: ymid }, { x: b.x, y: ymid }]; } throw new Error('invalid directions: can only handle varians of [hv]:[hv]'); } /** * Returns the mid points for a manhattan connection between two points. * * @example h:h (horizontal:horizontal) * * [a]----[x] * | * [x]----[b] * * @example h:v (horizontal:vertical) * * [a]----[x] * | * [b] * * @example h:r (horizontal:right) * * [a]----[x] * | * [b]-[x] * * @param {Point} a * @param {Point} b * @param {string} directions * * @return {Array<Point>} */ function getBendpoints(a, b, directions) { directions = directions || 'h:h'; if (!isValidDirections(directions)) { throw new Error('unknown directions: <' + directions + '>: ' + 'must be specified as <start>:<end> ' + 'with start/end in { h,v,t,r,b,l }'); } // compute explicit directions, involving trbl dockings // using a three segmented layouting algorithm if (isExplicitDirections(directions)) { var startSegment = getStartSegment(a, b, directions), endSegment = getEndSegment(a, b, directions), midSegment = getMidSegment(startSegment, endSegment); return [].concat(startSegment.waypoints, midSegment.waypoints, endSegment.waypoints); } // handle simple [hv]:[hv] cases that can be easily computed return getSimpleBendpoints(a, b, directions); } /** * Create a connection between the two points according * to the manhattan layout (only horizontal and vertical) edges. * * @param {Point} a * @param {Point} b * * @param {string} [directions='h:h'] specifies manhattan directions for each point as {adirection}:{bdirection}. A directionfor a point is either `h` (horizontal) or `v` (vertical) * * @return {Array<Point>} */ function connectPoints(a, b, directions) { var points = getBendpoints(a, b, directions); points.unshift(a); points.push(b); return withoutRedundantPoints(points); } /** * Connect two rectangles using a manhattan layouted connection. * * @param {Bounds} source source rectangle * @param {Bounds} target target rectangle * @param {Point} [start] source docking * @param {Point} [end] target docking * * @param {Object} [hints] * @param {string} [hints.preserveDocking=source] preserve docking on selected side * @param {Array<string>} [hints.preferredLayouts] * @param {Point|boolean} [hints.connectionStart] whether the start changed * @param {Point|boolean} [hints.connectionEnd] whether the end changed * * @return {Array<Point>} connection points */ function connectRectangles(source, target, start, end, hints) { var preferredLayouts = hints && hints.preferredLayouts || []; var preferredLayout = (0, _minDash.without)(preferredLayouts, 'straight')[0] || 'h:h'; var threshold = ORIENTATION_THRESHOLD[preferredLayout] || 0; var orientation = (0, _LayoutUtil.getOrientation)(source, target, threshold); var directions = getDirections(orientation, preferredLayout); start = start || (0, _LayoutUtil.getMid)(source); end = end || (0, _LayoutUtil.getMid)(target); var directionSplit = directions.split(':'); // compute actual docking points for start / end // this ensures we properly layout only parts of the // connection that lies in between the two rectangles var startDocking = getDockingPoint(start, source, directionSplit[0], invertOrientation(orientation)), endDocking = getDockingPoint(end, target, directionSplit[1], orientation); return connectPoints(startDocking, endDocking, directions); } /** * Repair the connection between two rectangles, of which one has been updated. * * @param {Bounds} source * @param {Bounds} target * @param {Point} [start] * @param {Point} [end] * @param {Array<Point>} [waypoints] * @param {Object} [hints] * @param {Array<string>} [hints.preferredLayouts] list of preferred layouts * @param {boolean} [hints.connectionStart] * @param {boolean} [hints.connectionEnd] * * @return {Array<Point>} repaired waypoints */ function repairConnection(source, target, start, end, waypoints, hints) { if ((0, _minDash.isArray)(start)) { waypoints = start; hints = end; start = (0, _LayoutUtil.getMid)(source); end = (0, _LayoutUtil.getMid)(target); } hints = (0, _minDash.assign)({ preferredLayouts: [] }, hints); waypoints = waypoints || []; var preferredLayouts = hints.preferredLayouts, preferStraight = preferredLayouts.indexOf('straight') !== -1, repairedWaypoints; // just layout non-existing or simple connections // attempt to render straight lines, if required // attempt to layout a straight line repairedWaypoints = preferStraight && tryLayoutStraight(source, target, start, end, hints); if (repairedWaypoints) { return repairedWaypoints; } // try to layout from end repairedWaypoints = hints.connectionEnd && tryRepairConnectionEnd(target, source, end, waypoints); if (repairedWaypoints) { return repairedWaypoints; } // try to layout from start repairedWaypoints = hints.connectionStart && tryRepairConnectionStart(source, target, start, waypoints); if (repairedWaypoints) { return repairedWaypoints; } // or whether nothing seems to have changed if (!hints.connectionStart && !hints.connectionEnd && waypoints && waypoints.length) { return waypoints; } // simply reconnect if nothing else worked return connectRectangles(source, target, start, end, hints); } function inRange(a, start, end) { return a >= start && a <= end; } function isInRange(axis, a, b) { var size = { x: 'width', y: 'height' }; return inRange(a[axis], b[axis], b[axis] + b[size[axis]]); } /** * Layout a straight connection * * @param {Bounds} source * @param {Bounds} target * @param {Point} start * @param {Point} end * @param {Object} [hints] * * @return {Array<Point>|null} waypoints if straight layout worked */ function tryLayoutStraight(source, target, start, end, hints) { var axis = {}, primaryAxis, orientation; orientation = (0, _LayoutUtil.getOrientation)(source, target); // only layout a straight connection if shapes are // horizontally or vertically aligned if (!/^(top|bottom|left|right)$/.test(orientation)) { return null; } if (/top|bottom/.test(orientation)) { primaryAxis = 'x'; } if (/left|right/.test(orientation)) { primaryAxis = 'y'; } if (hints.preserveDocking === 'target') { if (!isInRange(primaryAxis, end, source)) { return null; } axis[primaryAxis] = end[primaryAxis]; return [{ x: axis.x !== undefined ? axis.x : start.x, y: axis.y !== undefined ? axis.y : start.y, original: { x: axis.x !== undefined ? axis.x : start.x, y: axis.y !== undefined ? axis.y : start.y } }, { x: end.x, y: end.y }]; } else { if (!isInRange(primaryAxis, start, target)) { return null; } axis[primaryAxis] = start[primaryAxis]; return [{ x: start.x, y: start.y }, { x: axis.x !== undefined ? axis.x : end.x, y: axis.y !== undefined ? axis.y : end.y, original: { x: axis.x !== undefined ? axis.x : end.x, y: axis.y !== undefined ? axis.y : end.y } }]; } } /** * Repair a connection from start. * * @param {Bounds} moved * @param {Bounds} other * @param {Point} newDocking * @param {Array<Point>} points originalPoints from moved to other * * @return {Array<Point>|null} the repaired points between the two rectangles */ function tryRepairConnectionStart(moved, other, newDocking, points) { return _tryRepairConnectionSide(moved, other, newDocking, points); } /** * Repair a connection from end. * * @param {Bounds} moved * @param {Bounds} other * @param {Point} newDocking * @param {Array<Point>} points originalPoints from moved to other * * @return {Array<Point>|null} the repaired points between the two rectangles */ function tryRepairConnectionEnd(moved, other, newDocking, points) { var waypoints = points.slice().reverse(); waypoints = _tryRepairConnectionSide(moved, other, newDocking, waypoints); return waypoints ? waypoints.reverse() : null; } /** * Repair a connection from one side that moved. * * @param {Bounds} moved * @param {Bounds} other * @param {Point} newDocking * @param {Array<Point>} points originalPoints from moved to other * * @return {Array<Point>} the repaired points between the two rectangles */ function _tryRepairConnectionSide(moved, other, newDocking, points) { function needsRelayout(points) { if (points.length < 3) { return true; } if (points.length > 4) { return false; } // relayout if two points overlap // this is most likely due to return !!(0, _minDash.find)(points, function (p, idx) { var q = points[idx - 1]; return q && (0, _Geometry.pointDistance)(p, q) < 3; }); } function repairBendpoint(candidate, oldPeer, newPeer) { var alignment = (0, _Geometry.pointsAligned)(oldPeer, candidate); switch (alignment) { case 'v': // repair horizontal alignment return { x: newPeer.x, y: candidate.y }; case 'h': // repair vertical alignment return { x: candidate.x, y: newPeer.y }; } return { x: candidate.x, y: candidate.y }; } function removeOverlapping(points, a, b) { var i; for (i = points.length - 2; i !== 0; i--) { // intersects (?) break, remove all bendpoints up to this one and relayout if ((0, _Geometry.pointInRect)(points[i], a, INTERSECTION_THRESHOLD) || (0, _Geometry.pointInRect)(points[i], b, INTERSECTION_THRESHOLD)) { // return sliced old connection return points.slice(i); } } return points; } // (0) only repair what has layoutable bendpoints // (1) if only one bendpoint and on shape moved onto other shapes axis // (horizontally / vertically), relayout if (needsRelayout(points)) { return null; } var oldDocking = points[0], newPoints = points.slice(), slicedPoints; // (2) repair only last line segment and only if it was layouted before newPoints[0] = newDocking; newPoints[1] = repairBendpoint(newPoints[1], oldDocking, newDocking); // (3) if shape intersects with any bendpoint after repair, // remove all segments up to this bendpoint and repair from there slicedPoints = removeOverlapping(newPoints, moved, other); if (slicedPoints !== newPoints) { newPoints = _tryRepairConnectionSide(moved, other, newDocking, slicedPoints); } // (4) do NOT repair if repaired bendpoints are aligned if (newPoints && (0, _Geometry.pointsAligned)(newPoints)) { return null; } return newPoints; } /** * Returns the manhattan directions connecting two rectangles * with the given orientation. * * Will always return the default layout, if it is specific * regarding sides already (trbl). * * @example * * getDirections('top'); // -> 'v:v' * getDirections('intersect'); // -> 't:t' * * getDirections('top-right', 'v:h'); // -> 'v:h' * getDirections('top-right', 'h:h'); // -> 'h:h' * * * @param {string} orientation * @param {string} defaultLayout * * @return {string} */ function getDirections(orientation, defaultLayout) { // don't override specific trbl directions if (isExplicitDirections(defaultLayout)) { return defaultLayout; } switch (orientation) { case 'intersect': return 't:t'; case 'top': case 'bottom': return 'v:v'; case 'left': case 'right': return 'h:h'; // 'top-left' // 'top-right' // 'bottom-left' // 'bottom-right' default: return defaultLayout; } } function isValidDirections(directions) { return directions && /^h|v|t|r|b|l:h|v|t|r|b|l$/.test(directions); } function isExplicitDirections(directions) { return directions && /t|r|b|l/.test(directions); } function invertOrientation(orientation) { return { 'top': 'bottom', 'bottom': 'top', 'left': 'right', 'right': 'left', 'top-left': 'bottom-right', 'bottom-right': 'top-left', 'top-right': 'bottom-left', 'bottom-left': 'top-right' }[orientation]; } function getDockingPoint(point, rectangle, dockingDirection, targetOrientation) { // ensure we end up with a specific docking direction // based on the targetOrientation, if <h|v> is being passed if (dockingDirection === 'h') { dockingDirection = /left/.test(targetOrientation) ? 'l' : 'r'; } if (dockingDirection === 'v') { dockingDirection = /top/.test(targetOrientation) ? 't' : 'b'; } if (dockingDirection === 't') { return { original: point, x: point.x, y: rectangle.y }; } if (dockingDirection === 'r') { return { original: point, x: rectangle.x + rectangle.width, y: point.y }; } if (dockingDirection === 'b') { return { original: point, x: point.x, y: rectangle.y + rectangle.height }; } if (dockingDirection === 'l') { return { original: point, x: rectangle.x, y: point.y }; } throw new Error('unexpected dockingDirection: <' + dockingDirection + '>'); } /** * Return list of waypoints with redundant ones filtered out. * * @example * * Original points: * * [x] ----- [x] ------ [x] * | * [x] ----- [x] - [x] * * Filtered: * * [x] ---------------- [x] * | * [x] ----------- [x] * * @param {Array<Point>} waypoints * * @return {Array<Point>} */ function withoutRedundantPoints(waypoints) { return waypoints.reduce(function (points, p, idx) { var previous = points[points.length - 1], next = waypoints[idx + 1]; if (!(0, _Geometry.pointsOnLine)(previous, next, p, 0)) { points.push(p); } return points; }, []); } },{"../util/Geometry":318,"./LayoutUtil":300,"min-dash":555}],302:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Base = Base; exports.Shape = Shape; exports.Root = Root; exports.Label = Label; exports.Connection = Connection; exports.create = create; var _minDash = require("min-dash"); var _inherits = _interopRequireDefault(require("inherits")); var _objectRefs = _interopRequireDefault(require("object-refs")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var parentRefs = new _objectRefs.default({ name: 'children', enumerable: true, collection: true }, { name: 'parent' }), labelRefs = new _objectRefs.default({ name: 'labels', enumerable: true, collection: true }, { name: 'labelTarget' }), attacherRefs = new _objectRefs.default({ name: 'attachers', collection: true }, { name: 'host' }), outgoingRefs = new _objectRefs.default({ name: 'outgoing', collection: true }, { name: 'source' }), incomingRefs = new _objectRefs.default({ name: 'incoming', collection: true }, { name: 'target' }); /** * @namespace djs.model */ /** * @memberOf djs.model */ /** * The basic graphical representation * * @class * * @abstract */ function Base() { /** * The object that backs up the shape * * @name Base#businessObject * @type Object */ Object.defineProperty(this, 'businessObject', { writable: true }); /** * Single label support, will mapped to multi label array * * @name Base#label * @type Object */ Object.defineProperty(this, 'label', { get: function () { return this.labels[0]; }, set: function (newLabel) { var label = this.label, labels = this.labels; if (!newLabel && label) { labels.remove(label); } else { labels.add(newLabel, 0); } } }); /** * The parent shape * * @name Base#parent * @type Shape */ parentRefs.bind(this, 'parent'); /** * The list of labels * * @name Base#labels * @type Label */ labelRefs.bind(this, 'labels'); /** * The list of outgoing connections * * @name Base#outgoing * @type Array<Connection> */ outgoingRefs.bind(this, 'outgoing'); /** * The list of incoming connections * * @name Base#incoming * @type Array<Connection> */ incomingRefs.bind(this, 'incoming'); } /** * A graphical object * * @class * @constructor * * @extends Base */ function Shape() { Base.call(this); /** * Indicates frame shapes * * @name Shape#isFrame * @type boolean */ /** * The list of children * * @name Shape#children * @type Array<Base> */ parentRefs.bind(this, 'children'); /** * @name Shape#host * @type Shape */ attacherRefs.bind(this, 'host'); /** * @name Shape#attachers * @type Shape */ attacherRefs.bind(this, 'attachers'); } (0, _inherits.default)(Shape, Base); /** * A root graphical object * * @class * @constructor * * @extends Shape */ function Root() { Shape.call(this); } (0, _inherits.default)(Root, Shape); /** * A label for an element * * @class * @constructor * * @extends Shape */ function Label() { Shape.call(this); /** * The labeled element * * @name Label#labelTarget * @type Base */ labelRefs.bind(this, 'labelTarget'); } (0, _inherits.default)(Label, Shape); /** * A connection between two elements * * @class * @constructor * * @extends Base */ function Connection() { Base.call(this); /** * The element this connection originates from * * @name Connection#source * @type Base */ outgoingRefs.bind(this, 'source'); /** * The element this connection points to * * @name Connection#target * @type Base */ incomingRefs.bind(this, 'target'); } (0, _inherits.default)(Connection, Base); var types = { connection: Connection, shape: Shape, label: Label, root: Root }; /** * Creates a new model element of the specified type * * @method create * * @example * * var shape1 = Model.create('shape', { x: 10, y: 10, width: 100, height: 100 }); * var shape2 = Model.create('shape', { x: 210, y: 210, width: 100, height: 100 }); * * var connection = Model.create('connection', { waypoints: [ { x: 110, y: 55 }, {x: 210, y: 55 } ] }); * * @param {string} type lower-cased model name * @param {Object} attrs attributes to initialize the new model instance with * * @return {Base} the new model instance */ function create(type, attrs) { var Type = types[type]; if (!Type) { throw new Error('unknown type: <' + type + '>'); } return (0, _minDash.assign)(new Type(), attrs); } },{"inherits":347,"min-dash":555,"object-refs":560}],303:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = KeyboardMove; var _minDash = require("min-dash"); var DEFAULT_CONFIG = { moveSpeed: 50, moveSpeedAccelerated: 200 }; /** * A feature that allows users to move the canvas using the keyboard. * * @param {Object} config * @param {number} [config.moveSpeed=50] * @param {number} [config.moveSpeedAccelerated=200] * @param {Keyboard} keyboard * @param {Canvas} canvas */ function KeyboardMove(config, keyboard, canvas) { var self = this; this._config = (0, _minDash.assign)({}, DEFAULT_CONFIG, config || {}); keyboard.addListener(arrowsListener); function arrowsListener(context) { var event = context.keyEvent, config = self._config; if (!keyboard.isCmd(event)) { return; } if (keyboard.isKey(['ArrowLeft', 'Left', 'ArrowUp', 'Up', 'ArrowDown', 'Down', 'ArrowRight', 'Right'], event)) { var speed = keyboard.isShift(event) ? config.moveSpeedAccelerated : config.moveSpeed; var direction; switch (event.key) { case 'ArrowLeft': case 'Left': direction = 'left'; break; case 'ArrowUp': case 'Up': direction = 'up'; break; case 'ArrowRight': case 'Right': direction = 'right'; break; case 'ArrowDown': case 'Down': direction = 'down'; break; } self.moveCanvas({ speed: speed, direction: direction }); return true; } } this.moveCanvas = function (opts) { var dx = 0, dy = 0, speed = opts.speed; var actualSpeed = speed / Math.min(Math.sqrt(canvas.viewbox().scale), 1); switch (opts.direction) { case 'left': // Left dx = actualSpeed; break; case 'up': // Up dy = actualSpeed; break; case 'right': // Right dx = -actualSpeed; break; case 'down': // Down dy = -actualSpeed; break; } canvas.scroll({ dx: dx, dy: dy }); }; } KeyboardMove.$inject = ['config.keyboardMove', 'keyboard', 'canvas']; },{"min-dash":555}],304:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _keyboard = _interopRequireDefault(require("../../features/keyboard")); var _KeyboardMove = _interopRequireDefault(require("./KeyboardMove")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_keyboard.default], __init__: ['keyboardMove'], keyboardMove: ['type', _KeyboardMove.default] }; exports.default = _default; },{"../../features/keyboard":217,"./KeyboardMove":303}],305:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = MoveCanvas; var _Cursor = require("../../util/Cursor"); var _ClickTrap = require("../../util/ClickTrap"); var _PositionUtil = require("../../util/PositionUtil"); var _minDom = require("min-dom"); var _Event = require("../../util/Event"); var THRESHOLD = 15; /** * Move the canvas via mouse. * * @param {EventBus} eventBus * @param {Canvas} canvas */ function MoveCanvas(eventBus, canvas) { var context; // listen for move on element mouse down; // allow others to hook into the event before us though // (dragging / element moving will do this) eventBus.on('element.mousedown', 500, function (e) { return handleStart(e.originalEvent); }); function handleMove(event) { var start = context.start, position = (0, _Event.toPoint)(event), delta = (0, _PositionUtil.delta)(position, start); if (!context.dragging && length(delta) > THRESHOLD) { context.dragging = true; (0, _ClickTrap.install)(eventBus); (0, _Cursor.set)('grab'); } if (context.dragging) { var lastPosition = context.last || context.start; delta = (0, _PositionUtil.delta)(position, lastPosition); canvas.scroll({ dx: delta.x, dy: delta.y }); context.last = position; } // prevent select event.preventDefault(); } function handleEnd(event) { _minDom.event.unbind(document, 'mousemove', handleMove); _minDom.event.unbind(document, 'mouseup', handleEnd); context = null; (0, _Cursor.unset)(); } function handleStart(event) { // event is already handled by '.djs-draggable' if ((0, _minDom.closest)(event.target, '.djs-draggable')) { return; } // reject non-left left mouse button or modifier key if (event.button || event.ctrlKey || event.shiftKey || event.altKey) { return; } context = { start: (0, _Event.toPoint)(event) }; _minDom.event.bind(document, 'mousemove', handleMove); _minDom.event.bind(document, 'mouseup', handleEnd); // we've handled the event return true; } } MoveCanvas.$inject = ['eventBus', 'canvas']; // helpers /////// function length(point) { return Math.sqrt(Math.pow(point.x, 2) + Math.pow(point.y, 2)); } },{"../../util/ClickTrap":312,"../../util/Cursor":314,"../../util/Event":317,"../../util/PositionUtil":325,"min-dom":556}],306:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _MoveCanvas = _interopRequireDefault(require("./MoveCanvas")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['moveCanvas'], moveCanvas: ['type', _MoveCanvas.default] }; exports.default = _default; },{"./MoveCanvas":305}],307:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _touch = _interopRequireDefault(require("../../features/touch")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_touch.default] }; exports.default = _default; },{"../../features/touch":295}],308:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = ZoomScroll; var _minDom = require("min-dom"); var _ZoomUtil = require("./ZoomUtil"); var _Math = require("../../util/Math"); var _minDash = require("min-dash"); var sign = Math.sign || function (n) { return n >= 0 ? 1 : -1; }; var RANGE = { min: 0.2, max: 4 }, NUM_STEPS = 10; var DELTA_THRESHOLD = 0.1; var DEFAULT_SCALE = 0.75; /** * An implementation of zooming and scrolling within the * {@link Canvas} via the mouse wheel. * * Mouse wheel zooming / scrolling may be disabled using * the {@link toggle(enabled)} method. * * @param {Object} [config] * @param {boolean} [config.enabled=true] default enabled state * @param {number} [config.scale=.75] scroll sensivity * @param {EventBus} eventBus * @param {Canvas} canvas */ function ZoomScroll(config, eventBus, canvas) { config = config || {}; this._enabled = false; this._canvas = canvas; this._container = canvas._container; this._handleWheel = (0, _minDash.bind)(this._handleWheel, this); this._totalDelta = 0; this._scale = config.scale || DEFAULT_SCALE; var self = this; eventBus.on('canvas.init', function (e) { self._init(config.enabled !== false); }); } ZoomScroll.$inject = ['config.zoomScroll', 'eventBus', 'canvas']; ZoomScroll.prototype.scroll = function scroll(delta) { this._canvas.scroll(delta); }; ZoomScroll.prototype.reset = function reset() { this._canvas.zoom('fit-viewport'); }; /** * Zoom depending on delta. * * @param {number} delta * @param {Object} position */ ZoomScroll.prototype.zoom = function zoom(delta, position) { // zoom with half the step size of stepZoom var stepSize = (0, _ZoomUtil.getStepSize)(RANGE, NUM_STEPS * 2); // add until threshold reached this._totalDelta += delta; if (Math.abs(this._totalDelta) > DELTA_THRESHOLD) { this._zoom(delta, position, stepSize); // reset this._totalDelta = 0; } }; ZoomScroll.prototype._handleWheel = function handleWheel(event) { // event is already handled by '.djs-scrollable' if ((0, _minDom.closest)(event.target, '.djs-scrollable', true)) { return; } var element = this._container; event.preventDefault(); // pinch to zoom is mapped to wheel + ctrlKey = true // in modern browsers (!) var isZoom = event.ctrlKey; var isHorizontalScroll = event.shiftKey; var factor = -1 * this._scale, delta; if (isZoom) { factor *= event.deltaMode === 0 ? 0.020 : 0.32; } else { factor *= event.deltaMode === 0 ? 1.0 : 16.0; } if (isZoom) { var elementRect = element.getBoundingClientRect(); var offset = { x: event.clientX - elementRect.left, y: event.clientY - elementRect.top }; delta = Math.sqrt(Math.pow(event.deltaY, 2) + Math.pow(event.deltaX, 2)) * sign(event.deltaY) * factor; // zoom in relative to diagram {x,y} coordinates this.zoom(delta, offset); } else { if (isHorizontalScroll) { delta = { dx: factor * event.deltaY, dy: 0 }; } else { delta = { dx: factor * event.deltaX, dy: factor * event.deltaY }; } this.scroll(delta); } }; /** * Zoom with fixed step size. * * @param {number} delta - Zoom delta (1 for zooming in, -1 for out). * @param {Object} position */ ZoomScroll.prototype.stepZoom = function stepZoom(delta, position) { var stepSize = (0, _ZoomUtil.getStepSize)(RANGE, NUM_STEPS); this._zoom(delta, position, stepSize); }; /** * Zoom in/out given a step size. * * @param {number} delta * @param {Object} position * @param {number} stepSize */ ZoomScroll.prototype._zoom = function (delta, position, stepSize) { var canvas = this._canvas; var direction = delta > 0 ? 1 : -1; var currentLinearZoomLevel = (0, _Math.log10)(canvas.zoom()); // snap to a proximate zoom step var newLinearZoomLevel = Math.round(currentLinearZoomLevel / stepSize) * stepSize; // increase or decrease one zoom step in the given direction newLinearZoomLevel += stepSize * direction; // calculate the absolute logarithmic zoom level based on the linear zoom level // (e.g. 2 for an absolute x2 zoom) var newLogZoomLevel = Math.pow(10, newLinearZoomLevel); canvas.zoom((0, _ZoomUtil.cap)(RANGE, newLogZoomLevel), position); }; /** * Toggle the zoom scroll ability via mouse wheel. * * @param {boolean} [newEnabled] new enabled state */ ZoomScroll.prototype.toggle = function toggle(newEnabled) { var element = this._container; var handleWheel = this._handleWheel; var oldEnabled = this._enabled; if (typeof newEnabled === 'undefined') { newEnabled = !oldEnabled; } // only react on actual changes if (oldEnabled !== newEnabled) { // add or remove wheel listener based on // changed enabled state _minDom.event[newEnabled ? 'bind' : 'unbind'](element, 'wheel', handleWheel, false); } this._enabled = newEnabled; return newEnabled; }; ZoomScroll.prototype._init = function (newEnabled) { this.toggle(newEnabled); }; },{"../../util/Math":322,"./ZoomUtil":309,"min-dash":555,"min-dom":556}],309:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getStepSize = getStepSize; exports.cap = cap; var _Math = require("../../util/Math"); /** * Get step size for given range and number of steps. * * @param {Object} range * @param {number} range.min * @param {number} range.max */ function getStepSize(range, steps) { var minLinearRange = (0, _Math.log10)(range.min), maxLinearRange = (0, _Math.log10)(range.max); var absoluteLinearRange = Math.abs(minLinearRange) + Math.abs(maxLinearRange); return absoluteLinearRange / steps; } function cap(range, scale) { return Math.max(range.min, Math.min(range.max, scale)); } },{"../../util/Math":322}],310:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ZoomScroll = _interopRequireDefault(require("./ZoomScroll")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['zoomScroll'], zoomScroll: ['type', _ZoomScroll.default] }; exports.default = _default; },{"./ZoomScroll":308}],311:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNewAttachPoint = getNewAttachPoint; exports.getNewAttachShapeDelta = getNewAttachShapeDelta; var _LayoutUtil = require("../layout/LayoutUtil"); var _PositionUtil = require("./PositionUtil"); /** * Calculates the absolute point relative to the new element's position * * @param {point} point [absolute] * @param {bounds} oldBounds * @param {bounds} newBounds * * @return {point} point [absolute] */ function getNewAttachPoint(point, oldBounds, newBounds) { var oldCenter = (0, _PositionUtil.center)(oldBounds), newCenter = (0, _PositionUtil.center)(newBounds), oldDelta = (0, _PositionUtil.delta)(point, oldCenter); var newDelta = { x: oldDelta.x * (newBounds.width / oldBounds.width), y: oldDelta.y * (newBounds.height / oldBounds.height) }; return (0, _LayoutUtil.roundPoint)({ x: newCenter.x + newDelta.x, y: newCenter.y + newDelta.y }); } /** * Calculates the shape's delta relative to a new position * of a certain element's bounds * * @param {djs.model.Shape} point [absolute] * @param {bounds} oldBounds * @param {bounds} newBounds * * @return {delta} delta */ function getNewAttachShapeDelta(shape, oldBounds, newBounds) { var shapeCenter = (0, _PositionUtil.center)(shape), oldCenter = (0, _PositionUtil.center)(oldBounds), newCenter = (0, _PositionUtil.center)(newBounds), shapeDelta = (0, _PositionUtil.delta)(shape, shapeCenter), oldCenterDelta = (0, _PositionUtil.delta)(shapeCenter, oldCenter), stickyPositionDelta = getStickyPositionDelta(shapeCenter, oldBounds, newBounds); if (stickyPositionDelta) { return stickyPositionDelta; } var newCenterDelta = { x: oldCenterDelta.x * (newBounds.width / oldBounds.width), y: oldCenterDelta.y * (newBounds.height / oldBounds.height) }; var newShapeCenter = { x: newCenter.x + newCenterDelta.x, y: newCenter.y + newCenterDelta.y }; return (0, _LayoutUtil.roundPoint)({ x: newShapeCenter.x + shapeDelta.x - shape.x, y: newShapeCenter.y + shapeDelta.y - shape.y }); } function getStickyPositionDelta(oldShapeCenter, oldBounds, newBounds) { var oldTRBL = (0, _LayoutUtil.asTRBL)(oldBounds), newTRBL = (0, _LayoutUtil.asTRBL)(newBounds); if (isMoved(oldTRBL, newTRBL)) { return null; } var oldOrientation = (0, _LayoutUtil.getOrientation)(oldBounds, oldShapeCenter), stickyPositionDelta, newShapeCenter, newOrientation; if (oldOrientation === 'top') { stickyPositionDelta = { x: 0, y: newTRBL.bottom - oldTRBL.bottom }; } else if (oldOrientation === 'bottom') { stickyPositionDelta = { x: 0, y: newTRBL.top - oldTRBL.top }; } else if (oldOrientation === 'right') { stickyPositionDelta = { x: newTRBL.left - oldTRBL.left, y: 0 }; } else if (oldOrientation === 'left') { stickyPositionDelta = { x: newTRBL.right - oldTRBL.right, y: 0 }; } else { // fallback to proportional movement for corner-placed attachments return null; } newShapeCenter = { x: oldShapeCenter.x + stickyPositionDelta.x, y: oldShapeCenter.y + stickyPositionDelta.y }; newOrientation = (0, _LayoutUtil.getOrientation)(newBounds, newShapeCenter); if (newOrientation !== oldOrientation) { // fallback to proportional movement if orientation would otherwise change return null; } return stickyPositionDelta; } function isMoved(oldTRBL, newTRBL) { return isHorizontallyMoved(oldTRBL, newTRBL) || isVerticallyMoved(oldTRBL, newTRBL); } function isHorizontallyMoved(oldTRBL, newTRBL) { return oldTRBL.right !== newTRBL.right && oldTRBL.left !== newTRBL.left; } function isVerticallyMoved(oldTRBL, newTRBL) { return oldTRBL.top !== newTRBL.top && oldTRBL.bottom !== newTRBL.bottom; } },{"../layout/LayoutUtil":300,"./PositionUtil":325}],312:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.install = install; var TRAP_PRIORITY = 5000; /** * Installs a click trap that prevents a ghost click following a dragging operation. * * @return {Function} a function to immediately remove the installed trap. */ function install(eventBus, eventName) { eventName = eventName || 'element.click'; function trap() { return false; } eventBus.once(eventName, TRAP_PRIORITY, trap); return function () { eventBus.off(eventName, trap); }; } },{}],313:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.remove = remove; exports.add = add; exports.indexOf = indexOf; /** * Failsafe remove an element from a collection * * @param {Array<Object>} [collection] * @param {Object} [element] * * @return {number} the previous index of the element */ function remove(collection, element) { if (!collection || !element) { return -1; } var idx = collection.indexOf(element); if (idx !== -1) { collection.splice(idx, 1); } return idx; } /** * Fail save add an element to the given connection, ensuring * it does not yet exist. * * @param {Array<Object>} collection * @param {Object} element * @param {number} idx */ function add(collection, element, idx) { if (!collection || !element) { return; } if (typeof idx !== 'number') { idx = -1; } var currentIdx = collection.indexOf(element); if (currentIdx !== -1) { if (currentIdx === idx) { // nothing to do, position has not changed return; } else { if (idx !== -1) { // remove from current position collection.splice(currentIdx, 1); } else { // already exists in collection return; } } } if (idx !== -1) { // insert at specified position collection.splice(idx, 0, element); } else { // push to end collection.push(element); } } /** * Fail save get the index of an element in a collection. * * @param {Array<Object>} collection * @param {Object} element * * @return {number} the index or -1 if collection or element do * not exist or the element is not contained. */ function indexOf(collection, element) { if (!collection || !element) { return -1; } return collection.indexOf(element); } },{}],314:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.set = set; exports.unset = unset; exports.has = has; var _minDom = require("min-dom"); var CURSOR_CLS_PATTERN = /^djs-cursor-.*$/; function set(mode) { var classes = (0, _minDom.classes)(document.body); classes.removeMatching(CURSOR_CLS_PATTERN); if (mode) { classes.add('djs-cursor-' + mode); } } function unset() { set(null); } function has(mode) { var classes = (0, _minDom.classes)(document.body); return classes.has('djs-cursor-' + mode); } },{"min-dom":556}],315:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getParents = getParents; exports.add = add; exports.eachElement = eachElement; exports.selfAndChildren = selfAndChildren; exports.selfAndDirectChildren = selfAndDirectChildren; exports.selfAndAllChildren = selfAndAllChildren; exports.getClosure = getClosure; exports.getBBox = getBBox; exports.getEnclosedElements = getEnclosedElements; exports.getType = getType; exports.isFrameElement = isFrameElement; var _minDash = require("min-dash"); /** * Get parent elements. * * @param {Array<djs.model.base>} elements * * @returns {Array<djs.model.Base>} */ function getParents(elements) { // find elements that are not children of any other elements return (0, _minDash.filter)(elements, function (element) { return !(0, _minDash.find)(elements, function (e) { return e !== element && getParent(element, e); }); }); } function getParent(element, parent) { if (!parent) { return; } if (element === parent) { return parent; } if (!element.parent) { return; } return getParent(element.parent, parent); } /** * Adds an element to a collection and returns true if the * element was added. * * @param {Array<Object>} elements * @param {Object} e * @param {boolean} unique */ function add(elements, e, unique) { var canAdd = !unique || elements.indexOf(e) === -1; if (canAdd) { elements.push(e); } return canAdd; } /** * Iterate over each element in a collection, calling the iterator function `fn` * with (element, index, recursionDepth). * * Recurse into all elements that are returned by `fn`. * * @param {Object|Array<Object>} elements * @param {Function} fn iterator function called with (element, index, recursionDepth) * @param {number} [depth] maximum recursion depth */ function eachElement(elements, fn, depth) { depth = depth || 0; if (!(0, _minDash.isArray)(elements)) { elements = [elements]; } (0, _minDash.forEach)(elements, function (s, i) { var filter = fn(s, i, depth); if ((0, _minDash.isArray)(filter) && filter.length) { eachElement(filter, fn, depth + 1); } }); } /** * Collects self + child elements up to a given depth from a list of elements. * * @param {djs.model.Base|Array<djs.model.Base>} elements the elements to select the children from * @param {boolean} unique whether to return a unique result set (no duplicates) * @param {number} maxDepth the depth to search through or -1 for infinite * * @return {Array<djs.model.Base>} found elements */ function selfAndChildren(elements, unique, maxDepth) { var result = [], processedChildren = []; eachElement(elements, function (element, i, depth) { add(result, element, unique); var children = element.children; // max traversal depth not reached yet if (maxDepth === -1 || depth < maxDepth) { // children exist && children not yet processed if (children && add(processedChildren, children, unique)) { return children; } } }); return result; } /** * Return self + direct children for a number of elements * * @param {Array<djs.model.Base>} elements to query * @param {boolean} allowDuplicates to allow duplicates in the result set * * @return {Array<djs.model.Base>} the collected elements */ function selfAndDirectChildren(elements, allowDuplicates) { return selfAndChildren(elements, !allowDuplicates, 1); } /** * Return self + ALL children for a number of elements * * @param {Array<djs.model.Base>} elements to query * @param {boolean} allowDuplicates to allow duplicates in the result set * * @return {Array<djs.model.Base>} the collected elements */ function selfAndAllChildren(elements, allowDuplicates) { return selfAndChildren(elements, !allowDuplicates, -1); } /** * Gets the the closure for all selected elements, * their enclosed children and connections. * * @param {Array<djs.model.Base>} elements * @param {boolean} [isTopLevel=true] * @param {Object} [existingClosure] * * @return {Object} newClosure */ function getClosure(elements, isTopLevel, closure) { if ((0, _minDash.isUndefined)(isTopLevel)) { isTopLevel = true; } if ((0, _minDash.isObject)(isTopLevel)) { closure = isTopLevel; isTopLevel = true; } closure = closure || {}; var allShapes = copyObject(closure.allShapes), allConnections = copyObject(closure.allConnections), enclosedElements = copyObject(closure.enclosedElements), enclosedConnections = copyObject(closure.enclosedConnections); var topLevel = copyObject(closure.topLevel, isTopLevel && (0, _minDash.groupBy)(elements, function (e) { return e.id; })); function handleConnection(c) { if (topLevel[c.source.id] && topLevel[c.target.id]) { topLevel[c.id] = [c]; } // not enclosed as a child, but maybe logically // (connecting two moved elements?) if (allShapes[c.source.id] && allShapes[c.target.id]) { enclosedConnections[c.id] = enclosedElements[c.id] = c; } allConnections[c.id] = c; } function handleElement(element) { enclosedElements[element.id] = element; if (element.waypoints) { // remember connection enclosedConnections[element.id] = allConnections[element.id] = element; } else { // remember shape allShapes[element.id] = element; // remember all connections (0, _minDash.forEach)(element.incoming, handleConnection); (0, _minDash.forEach)(element.outgoing, handleConnection); // recurse into children return element.children; } } eachElement(elements, handleElement); return { allShapes: allShapes, allConnections: allConnections, topLevel: topLevel, enclosedConnections: enclosedConnections, enclosedElements: enclosedElements }; } /** * Returns the surrounding bbox for all elements in * the array or the element primitive. * * @param {Array<djs.model.Shape>|djs.model.Shape} elements * @param {boolean} stopRecursion */ function getBBox(elements, stopRecursion) { stopRecursion = !!stopRecursion; if (!(0, _minDash.isArray)(elements)) { elements = [elements]; } var minX, minY, maxX, maxY; (0, _minDash.forEach)(elements, function (element) { // If element is a connection the bbox must be computed first var bbox = element; if (element.waypoints && !stopRecursion) { bbox = getBBox(element.waypoints, true); } var x = bbox.x, y = bbox.y, height = bbox.height || 0, width = bbox.width || 0; if (x < minX || minX === undefined) { minX = x; } if (y < minY || minY === undefined) { minY = y; } if (x + width > maxX || maxX === undefined) { maxX = x + width; } if (y + height > maxY || maxY === undefined) { maxY = y + height; } }); return { x: minX, y: minY, height: maxY - minY, width: maxX - minX }; } /** * Returns all elements that are enclosed from the bounding box. * * * If bbox.(width|height) is not specified the method returns * all elements with element.x/y > bbox.x/y * * If only bbox.x or bbox.y is specified, method return all elements with * e.x > bbox.x or e.y > bbox.y * * @param {Array<djs.model.Shape>} elements List of Elements to search through * @param {djs.model.Shape} bbox the enclosing bbox. * * @return {Array<djs.model.Shape>} enclosed elements */ function getEnclosedElements(elements, bbox) { var filteredElements = {}; (0, _minDash.forEach)(elements, function (element) { var e = element; if (e.waypoints) { e = getBBox(e); } if (!(0, _minDash.isNumber)(bbox.y) && e.x > bbox.x) { filteredElements[element.id] = element; } if (!(0, _minDash.isNumber)(bbox.x) && e.y > bbox.y) { filteredElements[element.id] = element; } if (e.x > bbox.x && e.y > bbox.y) { if ((0, _minDash.isNumber)(bbox.width) && (0, _minDash.isNumber)(bbox.height) && e.width + e.x < bbox.width + bbox.x && e.height + e.y < bbox.height + bbox.y) { filteredElements[element.id] = element; } else if (!(0, _minDash.isNumber)(bbox.width) || !(0, _minDash.isNumber)(bbox.height)) { filteredElements[element.id] = element; } } }); return filteredElements; } function getType(element) { if ('waypoints' in element) { return 'connection'; } if ('x' in element) { return 'shape'; } return 'root'; } function isFrameElement(element) { return !!(element && element.isFrame); } // helpers /////////////////////////////// function copyObject(src1, src2) { return (0, _minDash.assign)({}, src1 || {}, src2 || {}); } },{"min-dash":555}],316:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.escapeHTML = escapeHTML; Object.defineProperty(exports, "escapeCSS", { enumerable: true, get: function () { return _css.default; } }); var _css = _interopRequireDefault(require("css.escape")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var HTML_ESCAPE_MAP = { '&': '&', '<': '<', '>': '>', '"': '"', '\'': ''' }; function escapeHTML(str) { str = '' + str; return str && str.replace(/[&<>"']/g, function (match) { return HTML_ESCAPE_MAP[match]; }); } },{"css.escape":331}],317:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getOriginal = getOriginal; exports.stopPropagation = stopPropagation; exports.toPoint = toPoint; function __stopPropagation(event) { if (!event || typeof event.stopPropagation !== 'function') { return; } event.stopPropagation(); } function getOriginal(event) { return event.originalEvent || event.srcEvent; } function stopPropagation(event, immediate) { __stopPropagation(event, immediate); __stopPropagation(getOriginal(event), immediate); } function toPoint(event) { if (event.pointers && event.pointers.length) { event = event.pointers[0]; } if (event.touches && event.touches.length) { event = event.touches[0]; } return event ? { x: event.clientX, y: event.clientY } : null; } },{}],318:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.pointDistance = pointDistance; exports.pointsOnLine = pointsOnLine; exports.pointsAligned = pointsAligned; exports.pointsAlignedHorizontally = pointsAlignedHorizontally; exports.pointsAlignedVertically = pointsAlignedVertically; exports.pointInRect = pointInRect; exports.getMidPoint = getMidPoint; var _minDash = require("min-dash"); /** * Computes the distance between two points * * @param {Point} p * @param {Point} q * * @return {number} distance */ function pointDistance(a, b) { if (!a || !b) { return -1; } return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2)); } /** * Returns true if the point r is on the line between p and q * * @param {Point} p * @param {Point} q * @param {Point} r * @param {number} [accuracy=5] accuracy for points on line check (lower is better) * * @return {boolean} */ function pointsOnLine(p, q, r, accuracy) { if (typeof accuracy === 'undefined') { accuracy = 5; } if (!p || !q || !r) { return false; } var val = (q.x - p.x) * (r.y - p.y) - (q.y - p.y) * (r.x - p.x), dist = pointDistance(p, q); // @see http://stackoverflow.com/a/907491/412190 return Math.abs(val / dist) <= accuracy; } var ALIGNED_THRESHOLD = 2; /** * Check whether two points are horizontally or vertically aligned. * * @param {Array<Point>|Point} * @param {Point} * * @return {string|boolean} */ function pointsAligned(a, b) { var points; if ((0, _minDash.isArray)(a)) { points = a; } else { points = [a, b]; } if (pointsAlignedHorizontally(points)) { return 'h'; } if (pointsAlignedVertically(points)) { return 'v'; } return false; } function pointsAlignedHorizontally(a, b) { var points; if ((0, _minDash.isArray)(a)) { points = a; } else { points = [a, b]; } var firstPoint = points.slice().shift(); return (0, _minDash.every)(points, function (point) { return Math.abs(firstPoint.y - point.y) <= ALIGNED_THRESHOLD; }); } function pointsAlignedVertically(a, b) { var points; if ((0, _minDash.isArray)(a)) { points = a; } else { points = [a, b]; } var firstPoint = points.slice().shift(); return (0, _minDash.every)(points, function (point) { return Math.abs(firstPoint.x - point.x) <= ALIGNED_THRESHOLD; }); } /** * Returns true if the point p is inside the rectangle rect * * @param {Point} p * @param {Rect} rect * @param {number} tolerance * * @return {boolean} */ function pointInRect(p, rect, tolerance) { tolerance = tolerance || 0; return p.x > rect.x - tolerance && p.y > rect.y - tolerance && p.x < rect.x + rect.width + tolerance && p.y < rect.y + rect.height + tolerance; } /** * Returns a point in the middle of points p and q * * @param {Point} p * @param {Point} q * * @return {Point} middle point */ function getMidPoint(p, q) { return { x: Math.round(p.x + (q.x - p.x) / 2.0), y: Math.round(p.y + (q.y - p.y) / 2.0) }; } },{"min-dash":555}],319:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getVisual = getVisual; exports.getChildren = getChildren; /** * SVGs for elements are generated by the {@link GraphicsFactory}. * * This utility gives quick access to the important semantic * parts of an element. */ /** * Returns the visual part of a diagram element * * @param {Snap<SVGElement>} gfx * * @return {Snap<SVGElement>} */ function getVisual(gfx) { return gfx.childNodes[0]; } /** * Returns the children for a given diagram element. * * @param {Snap<SVGElement>} gfx * @return {Snap<SVGElement>} */ function getChildren(gfx) { return gfx.parentNode.childNodes[1]; } },{}],320:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = IdGenerator; /** * Util that provides unique IDs. * * @class djs.util.IdGenerator * @constructor * @memberOf djs.util * * The ids can be customized via a given prefix and contain a random value to avoid collisions. * * @param {string} prefix a prefix to prepend to generated ids (for better readability) */ function IdGenerator(prefix) { this._counter = 0; this._prefix = (prefix ? prefix + '-' : '') + Math.floor(Math.random() * 1000000000) + '-'; } /** * Returns a next unique ID. * * @method djs.util.IdGenerator#next * * @returns {string} the id */ IdGenerator.prototype.next = function () { return this._prefix + ++this._counter; }; },{}],321:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getApproxIntersection = getApproxIntersection; var _Geometry = require("./Geometry"); var _pathIntersection = _interopRequireDefault(require("path-intersection")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var round = Math.round, max = Math.max; function circlePath(center, r) { var x = center.x, y = center.y; return [['M', x, y], ['m', 0, -r], ['a', r, r, 0, 1, 1, 0, 2 * r], ['a', r, r, 0, 1, 1, 0, -2 * r], ['z']]; } function linePath(points) { var segments = []; points.forEach(function (p, idx) { segments.push([idx === 0 ? 'M' : 'L', p.x, p.y]); }); return segments; } var INTERSECTION_THRESHOLD = 10; function getBendpointIntersection(waypoints, reference) { var i, w; for (i = 0; w = waypoints[i]; i++) { if ((0, _Geometry.pointDistance)(w, reference) <= INTERSECTION_THRESHOLD) { return { point: waypoints[i], bendpoint: true, index: i }; } } return null; } function getPathIntersection(waypoints, reference) { var intersections = (0, _pathIntersection.default)(circlePath(reference, INTERSECTION_THRESHOLD), linePath(waypoints)); var a = intersections[0], b = intersections[intersections.length - 1], idx; if (!a) { // no intersection return null; } if (a !== b) { if (a.segment2 !== b.segment2) { // we use the bendpoint in between both segments // as the intersection point idx = max(a.segment2, b.segment2) - 1; return { point: waypoints[idx], bendpoint: true, index: idx }; } return { point: { x: round(a.x + b.x) / 2, y: round(a.y + b.y) / 2 }, index: a.segment2 }; } return { point: { x: round(a.x), y: round(a.y) }, index: a.segment2 }; } /** * Returns the closest point on the connection towards a given reference point. * * @param {Array<Point>} waypoints * @param {Point} reference * * @return {Object} intersection data (segment, point) */ function getApproxIntersection(waypoints, reference) { return getBendpointIntersection(waypoints, reference) || getPathIntersection(waypoints, reference); } },{"./Geometry":318,"path-intersection":563}],322:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.log10 = log10; Object.defineProperty(exports, "substract", { enumerable: true, get: function () { return _PositionUtil.delta; } }); var _PositionUtil = require("./PositionUtil"); /** * Get the logarithm of x with base 10 * @param {Integer} value */ function log10(x) { return Math.log(x) / Math.log(10); } },{"./PositionUtil":325}],323:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isPrimaryButton = isPrimaryButton; exports.hasPrimaryModifier = hasPrimaryModifier; exports.hasSecondaryModifier = hasSecondaryModifier; Object.defineProperty(exports, "isMac", { enumerable: true, get: function () { return _Platform.isMac; } }); var _Event = require("./Event"); var _Platform = require("./Platform"); function isPrimaryButton(event) { // button === 0 -> left áka primary mouse button return !((0, _Event.getOriginal)(event) || event).button; } function hasPrimaryModifier(event) { var originalEvent = (0, _Event.getOriginal)(event) || event; if (!isPrimaryButton(event)) { return false; } // Use alt as primary modifier key for mac OS if ((0, _Platform.isMac)()) { return originalEvent.metaKey; } else { return originalEvent.ctrlKey; } } function hasSecondaryModifier(event) { var originalEvent = (0, _Event.getOriginal)(event) || event; return isPrimaryButton(event) && originalEvent.shiftKey; } },{"./Event":317,"./Platform":324}],324:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.isMac = isMac; function isMac() { return /mac/i.test(navigator.platform); } },{}],325:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.center = center; exports.delta = delta; function center(bounds) { return { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 }; } function delta(a, b) { return { x: a.x - b.x, y: a.y - b.y }; } },{}],326:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.saveClear = saveClear; /** * Remove from the beginning of a collection until it is empty. * * This is a null-safe operation that ensures elements * are being removed from the given collection until the * collection is empty. * * The implementation deals with the fact that a remove operation * may touch, i.e. remove multiple elements in the collection * at a time. * * @param {Array<Object>} [collection] * @param {Function} removeFn * * @return {Array<Object>} the cleared collection */ function saveClear(collection, removeFn) { if (typeof removeFn !== 'function') { throw new Error('removeFn iterator must be a function'); } if (!collection) { return; } var e; while (e = collection[0]) { removeFn(e); } return collection; } },{}],327:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.componentsToPath = componentsToPath; exports.toSVGPoints = toSVGPoints; exports.createLine = createLine; exports.updateLine = updateLine; var _tinySvg = require("tiny-svg"); function componentsToPath(elements) { return elements.join(',').replace(/,?([A-z]),?/g, '$1'); } function toSVGPoints(points) { var result = ''; for (var i = 0, p; p = points[i]; i++) { result += p.x + ',' + p.y + ' '; } return result; } function createLine(points, attrs) { var line = (0, _tinySvg.create)('polyline'); (0, _tinySvg.attr)(line, { points: toSVGPoints(points) }); if (attrs) { (0, _tinySvg.attr)(line, attrs); } return line; } function updateLine(gfx, points) { (0, _tinySvg.attr)(gfx, { points: toSVGPoints(points) }); return gfx; } },{"tiny-svg":567}],328:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transform = transform; exports.translate = translate; exports.rotate = rotate; exports.scale = scale; var _tinySvg = require("tiny-svg"); /** * @param {<SVGElement>} element * @param {number} x * @param {number} y * @param {number} angle * @param {number} amount */ function transform(gfx, x, y, angle, amount) { var translate = (0, _tinySvg.createTransform)(); translate.setTranslate(x, y); var rotate = (0, _tinySvg.createTransform)(); rotate.setRotate(angle || 0, 0, 0); var scale = (0, _tinySvg.createTransform)(); scale.setScale(amount || 1, amount || 1); (0, _tinySvg.transform)(gfx, [translate, rotate, scale]); } /** * @param {SVGElement} element * @param {number} x * @param {number} y */ function translate(gfx, x, y) { var translate = (0, _tinySvg.createTransform)(); translate.setTranslate(x, y); (0, _tinySvg.transform)(gfx, translate); } /** * @param {SVGElement} element * @param {number} angle */ function rotate(gfx, angle) { var rotate = (0, _tinySvg.createTransform)(); rotate.setRotate(angle, 0, 0); (0, _tinySvg.transform)(gfx, rotate); } /** * @param {SVGElement} element * @param {number} amount */ function scale(gfx, amount) { var scale = (0, _tinySvg.createTransform)(); scale.setScale(amount, amount); (0, _tinySvg.transform)(gfx, scale); } },{"tiny-svg":567}],329:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = Text; var _minDash = require("min-dash"); var _tinySvg = require("tiny-svg"); var DEFAULT_BOX_PADDING = 0; var DEFAULT_LABEL_SIZE = { width: 150, height: 50 }; function parseAlign(align) { var parts = align.split('-'); return { horizontal: parts[0] || 'center', vertical: parts[1] || 'top' }; } function parsePadding(padding) { if ((0, _minDash.isObject)(padding)) { return (0, _minDash.assign)({ top: 0, left: 0, right: 0, bottom: 0 }, padding); } else { return { top: padding, left: padding, right: padding, bottom: padding }; } } function getTextBBox(text, fakeText) { fakeText.textContent = text; var textBBox; try { var bbox, emptyLine = text === ''; // add dummy text, when line is empty to // determine correct height fakeText.textContent = emptyLine ? 'dummy' : text; textBBox = fakeText.getBBox(); // take text rendering related horizontal // padding into account bbox = { width: textBBox.width + textBBox.x * 2, height: textBBox.height }; if (emptyLine) { // correct width bbox.width = 0; } return bbox; } catch (e) { return { width: 0, height: 0 }; } } /** * Layout the next line and return the layouted element. * * Alters the lines passed. * * @param {Array<string>} lines * @return {Object} the line descriptor, an object { width, height, text } */ function layoutNext(lines, maxWidth, fakeText) { var originalLine = lines.shift(), fitLine = originalLine; var textBBox; for (;;) { textBBox = getTextBBox(fitLine, fakeText); textBBox.width = fitLine ? textBBox.width : 0; // try to fit if (fitLine === ' ' || fitLine === '' || textBBox.width < Math.round(maxWidth) || fitLine.length < 2) { return fit(lines, fitLine, originalLine, textBBox); } fitLine = shortenLine(fitLine, textBBox.width, maxWidth); } } function fit(lines, fitLine, originalLine, textBBox) { if (fitLine.length < originalLine.length) { var remainder = originalLine.slice(fitLine.length).trim(); lines.unshift(remainder); } return { width: textBBox.width, height: textBBox.height, text: fitLine }; } /** * Shortens a line based on spacing and hyphens. * Returns the shortened result on success. * * @param {string} line * @param {number} maxLength the maximum characters of the string * @return {string} the shortened string */ function semanticShorten(line, maxLength) { var parts = line.split(/(\s|-)/g), part, shortenedParts = [], length = 0; // try to shorten via spaces + hyphens if (parts.length > 1) { while (part = parts.shift()) { if (part.length + length < maxLength) { shortenedParts.push(part); length += part.length; } else { // remove previous part, too if hyphen does not fit anymore if (part === '-') { shortenedParts.pop(); } break; } } } return shortenedParts.join(''); } function shortenLine(line, width, maxWidth) { var length = Math.max(line.length * (maxWidth / width), 1); // try to shorten semantically (i.e. based on spaces and hyphens) var shortenedLine = semanticShorten(line, length); if (!shortenedLine) { // force shorten by cutting the long word shortenedLine = line.slice(0, Math.max(Math.round(length - 1), 1)); } return shortenedLine; } function getHelperSvg() { var helperSvg = document.getElementById('helper-svg'); if (!helperSvg) { helperSvg = (0, _tinySvg.create)('svg'); (0, _tinySvg.attr)(helperSvg, { id: 'helper-svg', width: 0, height: 0, style: 'visibility: hidden; position: fixed' }); document.body.appendChild(helperSvg); } return helperSvg; } /** * Creates a new label utility * * @param {Object} config * @param {Dimensions} config.size * @param {number} config.padding * @param {Object} config.style * @param {string} config.align */ function Text(config) { this._config = (0, _minDash.assign)({}, { size: DEFAULT_LABEL_SIZE, padding: DEFAULT_BOX_PADDING, style: {}, align: 'center-top' }, config || {}); } /** * Returns the layouted text as an SVG element. * * @param {string} text * @param {Object} options * * @return {SVGElement} */ Text.prototype.createText = function (text, options) { return this.layoutText(text, options).element; }; /** * Returns a labels layouted dimensions. * * @param {string} text to layout * @param {Object} options * * @return {Dimensions} */ Text.prototype.getDimensions = function (text, options) { return this.layoutText(text, options).dimensions; }; /** * Creates and returns a label and its bounding box. * * @method Text#createText * * @param {string} text the text to render on the label * @param {Object} options * @param {string} options.align how to align in the bounding box. * Any of { 'center-middle', 'center-top' }, * defaults to 'center-top'. * @param {string} options.style style to be applied to the text * @param {boolean} options.fitBox indicates if box will be recalculated to * fit text * * @return {Object} { element, dimensions } */ Text.prototype.layoutText = function (text, options) { var box = (0, _minDash.assign)({}, this._config.size, options.box), style = (0, _minDash.assign)({}, this._config.style, options.style), align = parseAlign(options.align || this._config.align), padding = parsePadding(options.padding !== undefined ? options.padding : this._config.padding), fitBox = options.fitBox || false; var lineHeight = getLineHeight(style); var lines = text.split(/\r?\n/g), layouted = []; var maxWidth = box.width - padding.left - padding.right; // ensure correct rendering by attaching helper text node to invisible SVG var helperText = (0, _tinySvg.create)('text'); (0, _tinySvg.attr)(helperText, { x: 0, y: 0 }); (0, _tinySvg.attr)(helperText, style); var helperSvg = getHelperSvg(); (0, _tinySvg.append)(helperSvg, helperText); while (lines.length) { layouted.push(layoutNext(lines, maxWidth, helperText)); } if (align.vertical === 'middle') { padding.top = padding.bottom = 0; } var totalHeight = (0, _minDash.reduce)(layouted, function (sum, line, idx) { return sum + (lineHeight || line.height); }, 0) + padding.top + padding.bottom; var maxLineWidth = (0, _minDash.reduce)(layouted, function (sum, line, idx) { return line.width > sum ? line.width : sum; }, 0); // the y position of the next line var y = padding.top; if (align.vertical === 'middle') { y += (box.height - totalHeight) / 2; } // magic number initial offset y -= (lineHeight || layouted[0].height) / 4; var textElement = (0, _tinySvg.create)('text'); (0, _tinySvg.attr)(textElement, style); // layout each line taking into account that parent // shape might resize to fit text size (0, _minDash.forEach)(layouted, function (line) { var x; y += lineHeight || line.height; switch (align.horizontal) { case 'left': x = padding.left; break; case 'right': x = (fitBox ? maxLineWidth : maxWidth) - padding.right - line.width; break; default: // aka center x = Math.max(((fitBox ? maxLineWidth : maxWidth) - line.width) / 2 + padding.left, 0); } var tspan = (0, _tinySvg.create)('tspan'); (0, _tinySvg.attr)(tspan, { x: x, y: y }); tspan.textContent = line.text; (0, _tinySvg.append)(textElement, tspan); }); (0, _tinySvg.remove)(helperText); var dimensions = { width: maxLineWidth, height: totalHeight }; return { dimensions: dimensions, element: textElement }; }; function getLineHeight(style) { if ('fontSize' in style && 'lineHeight' in style) { return style.lineHeight * parseInt(style.fontSize, 10); } } },{"min-dash":555,"tiny-svg":567}],330:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _minDash = require("min-dash"); var _moddle = require("moddle"); var _moddleXml = require("moddle-xml"); /** * A sub class of {@link Moddle} with support for import and export of BPMN 2.0 xml files. * * @class BpmnModdle * @extends Moddle * * @param {Object|Array} packages to use for instantiating the model * @param {Object} [options] additional options to pass over */ function BpmnModdle(packages, options) { _moddle.Moddle.call(this, packages, options); } BpmnModdle.prototype = Object.create(_moddle.Moddle.prototype); /** * The fromXML result. * * @typedef {Object} ParseResult * * @property {ModdleElement} rootElement * @property {Array<Object>} references * @property {Array<Error>} warnings * @property {Object} elementsById - a mapping containing each ID -> ModdleElement */ /** * The fromXML error. * * @typedef {Error} ParseError * * @property {Array<Error>} warnings */ /** * Instantiates a BPMN model tree from a given xml string. * * @param {String} xmlStr * @param {String} [typeName='bpmn:Definitions'] name of the root element * @param {Object} [options] options to pass to the underlying reader * * @returns {Promise<ParseResult, ParseError>} */ BpmnModdle.prototype.fromXML = function (xmlStr, typeName, options) { if (!(0, _minDash.isString)(typeName)) { options = typeName; typeName = 'bpmn:Definitions'; } var reader = new _moddleXml.Reader((0, _minDash.assign)({ model: this, lax: true }, options)); var rootHandler = reader.handler(typeName); return reader.fromXML(xmlStr, rootHandler); }; /** * The toXML result. * * @typedef {Object} SerializationResult * * @property {String} xml */ /** * Serializes a BPMN 2.0 object tree to XML. * * @param {String} element the root element, typically an instance of `bpmn:Definitions` * @param {Object} [options] to pass to the underlying writer * * @returns {Promise<SerializationResult, Error>} */ BpmnModdle.prototype.toXML = function (element, options) { var writer = new _moddleXml.Writer(options); return new Promise(function (resolve, reject) { try { var result = writer.toXML(element); return resolve({ xml: result }); } catch (err) { return reject(err); } }); }; var name = "BPMN20"; var uri = "http://www.omg.org/spec/BPMN/20100524/MODEL"; var prefix = "bpmn"; var associations = []; var types = [{ name: "Interface", superClass: ["RootElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "operations", type: "Operation", isMany: true }, { name: "implementationRef", isAttr: true, type: "String" }] }, { name: "Operation", superClass: ["BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "inMessageRef", type: "Message", isReference: true }, { name: "outMessageRef", type: "Message", isReference: true }, { name: "errorRef", type: "Error", isMany: true, isReference: true }, { name: "implementationRef", isAttr: true, type: "String" }] }, { name: "EndPoint", superClass: ["RootElement"] }, { name: "Auditing", superClass: ["BaseElement"] }, { name: "GlobalTask", superClass: ["CallableElement"], properties: [{ name: "resources", type: "ResourceRole", isMany: true }] }, { name: "Monitoring", superClass: ["BaseElement"] }, { name: "Performer", superClass: ["ResourceRole"] }, { name: "Process", superClass: ["FlowElementsContainer", "CallableElement"], properties: [{ name: "processType", type: "ProcessType", isAttr: true }, { name: "isClosed", isAttr: true, type: "Boolean" }, { name: "auditing", type: "Auditing" }, { name: "monitoring", type: "Monitoring" }, { name: "properties", type: "Property", isMany: true }, { name: "laneSets", isMany: true, replaces: "FlowElementsContainer#laneSets", type: "LaneSet" }, { name: "flowElements", isMany: true, replaces: "FlowElementsContainer#flowElements", type: "FlowElement" }, { name: "artifacts", type: "Artifact", isMany: true }, { name: "resources", type: "ResourceRole", isMany: true }, { name: "correlationSubscriptions", type: "CorrelationSubscription", isMany: true }, { name: "supports", type: "Process", isMany: true, isReference: true }, { name: "definitionalCollaborationRef", type: "Collaboration", isAttr: true, isReference: true }, { name: "isExecutable", isAttr: true, type: "Boolean" }] }, { name: "LaneSet", superClass: ["BaseElement"], properties: [{ name: "lanes", type: "Lane", isMany: true }, { name: "name", isAttr: true, type: "String" }] }, { name: "Lane", superClass: ["BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "partitionElementRef", type: "BaseElement", isAttr: true, isReference: true }, { name: "partitionElement", type: "BaseElement" }, { name: "flowNodeRef", type: "FlowNode", isMany: true, isReference: true }, { name: "childLaneSet", type: "LaneSet", xml: { serialize: "xsi:type" } }] }, { name: "GlobalManualTask", superClass: ["GlobalTask"] }, { name: "ManualTask", superClass: ["Task"] }, { name: "UserTask", superClass: ["Task"], properties: [{ name: "renderings", type: "Rendering", isMany: true }, { name: "implementation", isAttr: true, type: "String" }] }, { name: "Rendering", superClass: ["BaseElement"] }, { name: "HumanPerformer", superClass: ["Performer"] }, { name: "PotentialOwner", superClass: ["HumanPerformer"] }, { name: "GlobalUserTask", superClass: ["GlobalTask"], properties: [{ name: "implementation", isAttr: true, type: "String" }, { name: "renderings", type: "Rendering", isMany: true }] }, { name: "Gateway", isAbstract: true, superClass: ["FlowNode"], properties: [{ name: "gatewayDirection", type: "GatewayDirection", "default": "Unspecified", isAttr: true }] }, { name: "EventBasedGateway", superClass: ["Gateway"], properties: [{ name: "instantiate", "default": false, isAttr: true, type: "Boolean" }, { name: "eventGatewayType", type: "EventBasedGatewayType", isAttr: true, "default": "Exclusive" }] }, { name: "ComplexGateway", superClass: ["Gateway"], properties: [{ name: "activationCondition", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "default", type: "SequenceFlow", isAttr: true, isReference: true }] }, { name: "ExclusiveGateway", superClass: ["Gateway"], properties: [{ name: "default", type: "SequenceFlow", isAttr: true, isReference: true }] }, { name: "InclusiveGateway", superClass: ["Gateway"], properties: [{ name: "default", type: "SequenceFlow", isAttr: true, isReference: true }] }, { name: "ParallelGateway", superClass: ["Gateway"] }, { name: "RootElement", isAbstract: true, superClass: ["BaseElement"] }, { name: "Relationship", superClass: ["BaseElement"], properties: [{ name: "type", isAttr: true, type: "String" }, { name: "direction", type: "RelationshipDirection", isAttr: true }, { name: "source", isMany: true, isReference: true, type: "Element" }, { name: "target", isMany: true, isReference: true, type: "Element" }] }, { name: "BaseElement", isAbstract: true, properties: [{ name: "id", isAttr: true, type: "String", isId: true }, { name: "documentation", type: "Documentation", isMany: true }, { name: "extensionDefinitions", type: "ExtensionDefinition", isMany: true, isReference: true }, { name: "extensionElements", type: "ExtensionElements" }] }, { name: "Extension", properties: [{ name: "mustUnderstand", "default": false, isAttr: true, type: "Boolean" }, { name: "definition", type: "ExtensionDefinition", isAttr: true, isReference: true }] }, { name: "ExtensionDefinition", properties: [{ name: "name", isAttr: true, type: "String" }, { name: "extensionAttributeDefinitions", type: "ExtensionAttributeDefinition", isMany: true }] }, { name: "ExtensionAttributeDefinition", properties: [{ name: "name", isAttr: true, type: "String" }, { name: "type", isAttr: true, type: "String" }, { name: "isReference", "default": false, isAttr: true, type: "Boolean" }, { name: "extensionDefinition", type: "ExtensionDefinition", isAttr: true, isReference: true }] }, { name: "ExtensionElements", properties: [{ name: "valueRef", isAttr: true, isReference: true, type: "Element" }, { name: "values", type: "Element", isMany: true }, { name: "extensionAttributeDefinition", type: "ExtensionAttributeDefinition", isAttr: true, isReference: true }] }, { name: "Documentation", superClass: ["BaseElement"], properties: [{ name: "text", type: "String", isBody: true }, { name: "textFormat", "default": "text/plain", isAttr: true, type: "String" }] }, { name: "Event", isAbstract: true, superClass: ["FlowNode", "InteractionNode"], properties: [{ name: "properties", type: "Property", isMany: true }] }, { name: "IntermediateCatchEvent", superClass: ["CatchEvent"] }, { name: "IntermediateThrowEvent", superClass: ["ThrowEvent"] }, { name: "EndEvent", superClass: ["ThrowEvent"] }, { name: "StartEvent", superClass: ["CatchEvent"], properties: [{ name: "isInterrupting", "default": true, isAttr: true, type: "Boolean" }] }, { name: "ThrowEvent", isAbstract: true, superClass: ["Event"], properties: [{ name: "dataInputs", type: "DataInput", isMany: true }, { name: "dataInputAssociations", type: "DataInputAssociation", isMany: true }, { name: "inputSet", type: "InputSet" }, { name: "eventDefinitions", type: "EventDefinition", isMany: true }, { name: "eventDefinitionRef", type: "EventDefinition", isMany: true, isReference: true }] }, { name: "CatchEvent", isAbstract: true, superClass: ["Event"], properties: [{ name: "parallelMultiple", isAttr: true, type: "Boolean", "default": false }, { name: "dataOutputs", type: "DataOutput", isMany: true }, { name: "dataOutputAssociations", type: "DataOutputAssociation", isMany: true }, { name: "outputSet", type: "OutputSet" }, { name: "eventDefinitions", type: "EventDefinition", isMany: true }, { name: "eventDefinitionRef", type: "EventDefinition", isMany: true, isReference: true }] }, { name: "BoundaryEvent", superClass: ["CatchEvent"], properties: [{ name: "cancelActivity", "default": true, isAttr: true, type: "Boolean" }, { name: "attachedToRef", type: "Activity", isAttr: true, isReference: true }] }, { name: "EventDefinition", isAbstract: true, superClass: ["RootElement"] }, { name: "CancelEventDefinition", superClass: ["EventDefinition"] }, { name: "ErrorEventDefinition", superClass: ["EventDefinition"], properties: [{ name: "errorRef", type: "Error", isAttr: true, isReference: true }] }, { name: "TerminateEventDefinition", superClass: ["EventDefinition"] }, { name: "EscalationEventDefinition", superClass: ["EventDefinition"], properties: [{ name: "escalationRef", type: "Escalation", isAttr: true, isReference: true }] }, { name: "Escalation", properties: [{ name: "structureRef", type: "ItemDefinition", isAttr: true, isReference: true }, { name: "name", isAttr: true, type: "String" }, { name: "escalationCode", isAttr: true, type: "String" }], superClass: ["RootElement"] }, { name: "CompensateEventDefinition", superClass: ["EventDefinition"], properties: [{ name: "waitForCompletion", isAttr: true, type: "Boolean", "default": true }, { name: "activityRef", type: "Activity", isAttr: true, isReference: true }] }, { name: "TimerEventDefinition", superClass: ["EventDefinition"], properties: [{ name: "timeDate", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "timeCycle", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "timeDuration", type: "Expression", xml: { serialize: "xsi:type" } }] }, { name: "LinkEventDefinition", superClass: ["EventDefinition"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "target", type: "LinkEventDefinition", isAttr: true, isReference: true }, { name: "source", type: "LinkEventDefinition", isMany: true, isReference: true }] }, { name: "MessageEventDefinition", superClass: ["EventDefinition"], properties: [{ name: "messageRef", type: "Message", isAttr: true, isReference: true }, { name: "operationRef", type: "Operation", isAttr: true, isReference: true }] }, { name: "ConditionalEventDefinition", superClass: ["EventDefinition"], properties: [{ name: "condition", type: "Expression", xml: { serialize: "xsi:type" } }] }, { name: "SignalEventDefinition", superClass: ["EventDefinition"], properties: [{ name: "signalRef", type: "Signal", isAttr: true, isReference: true }] }, { name: "Signal", superClass: ["RootElement"], properties: [{ name: "structureRef", type: "ItemDefinition", isAttr: true, isReference: true }, { name: "name", isAttr: true, type: "String" }] }, { name: "ImplicitThrowEvent", superClass: ["ThrowEvent"] }, { name: "DataState", superClass: ["BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }] }, { name: "ItemAwareElement", superClass: ["BaseElement"], properties: [{ name: "itemSubjectRef", type: "ItemDefinition", isAttr: true, isReference: true }, { name: "dataState", type: "DataState" }] }, { name: "DataAssociation", superClass: ["BaseElement"], properties: [{ name: "sourceRef", type: "ItemAwareElement", isMany: true, isReference: true }, { name: "targetRef", type: "ItemAwareElement", isReference: true }, { name: "transformation", type: "FormalExpression", xml: { serialize: "property" } }, { name: "assignment", type: "Assignment", isMany: true }] }, { name: "DataInput", superClass: ["ItemAwareElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "isCollection", "default": false, isAttr: true, type: "Boolean" }, { name: "inputSetRef", type: "InputSet", isMany: true, isVirtual: true, isReference: true }, { name: "inputSetWithOptional", type: "InputSet", isMany: true, isVirtual: true, isReference: true }, { name: "inputSetWithWhileExecuting", type: "InputSet", isMany: true, isVirtual: true, isReference: true }] }, { name: "DataOutput", superClass: ["ItemAwareElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "isCollection", "default": false, isAttr: true, type: "Boolean" }, { name: "outputSetRef", type: "OutputSet", isMany: true, isVirtual: true, isReference: true }, { name: "outputSetWithOptional", type: "OutputSet", isMany: true, isVirtual: true, isReference: true }, { name: "outputSetWithWhileExecuting", type: "OutputSet", isMany: true, isVirtual: true, isReference: true }] }, { name: "InputSet", superClass: ["BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "dataInputRefs", type: "DataInput", isMany: true, isReference: true }, { name: "optionalInputRefs", type: "DataInput", isMany: true, isReference: true }, { name: "whileExecutingInputRefs", type: "DataInput", isMany: true, isReference: true }, { name: "outputSetRefs", type: "OutputSet", isMany: true, isReference: true }] }, { name: "OutputSet", superClass: ["BaseElement"], properties: [{ name: "dataOutputRefs", type: "DataOutput", isMany: true, isReference: true }, { name: "name", isAttr: true, type: "String" }, { name: "inputSetRefs", type: "InputSet", isMany: true, isReference: true }, { name: "optionalOutputRefs", type: "DataOutput", isMany: true, isReference: true }, { name: "whileExecutingOutputRefs", type: "DataOutput", isMany: true, isReference: true }] }, { name: "Property", superClass: ["ItemAwareElement"], properties: [{ name: "name", isAttr: true, type: "String" }] }, { name: "DataInputAssociation", superClass: ["DataAssociation"] }, { name: "DataOutputAssociation", superClass: ["DataAssociation"] }, { name: "InputOutputSpecification", superClass: ["BaseElement"], properties: [{ name: "dataInputs", type: "DataInput", isMany: true }, { name: "dataOutputs", type: "DataOutput", isMany: true }, { name: "inputSets", type: "InputSet", isMany: true }, { name: "outputSets", type: "OutputSet", isMany: true }] }, { name: "DataObject", superClass: ["FlowElement", "ItemAwareElement"], properties: [{ name: "isCollection", "default": false, isAttr: true, type: "Boolean" }] }, { name: "InputOutputBinding", properties: [{ name: "inputDataRef", type: "InputSet", isAttr: true, isReference: true }, { name: "outputDataRef", type: "OutputSet", isAttr: true, isReference: true }, { name: "operationRef", type: "Operation", isAttr: true, isReference: true }] }, { name: "Assignment", superClass: ["BaseElement"], properties: [{ name: "from", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "to", type: "Expression", xml: { serialize: "xsi:type" } }] }, { name: "DataStore", superClass: ["RootElement", "ItemAwareElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "capacity", isAttr: true, type: "Integer" }, { name: "isUnlimited", "default": true, isAttr: true, type: "Boolean" }] }, { name: "DataStoreReference", superClass: ["ItemAwareElement", "FlowElement"], properties: [{ name: "dataStoreRef", type: "DataStore", isAttr: true, isReference: true }] }, { name: "DataObjectReference", superClass: ["ItemAwareElement", "FlowElement"], properties: [{ name: "dataObjectRef", type: "DataObject", isAttr: true, isReference: true }] }, { name: "ConversationLink", superClass: ["BaseElement"], properties: [{ name: "sourceRef", type: "InteractionNode", isAttr: true, isReference: true }, { name: "targetRef", type: "InteractionNode", isAttr: true, isReference: true }, { name: "name", isAttr: true, type: "String" }] }, { name: "ConversationAssociation", superClass: ["BaseElement"], properties: [{ name: "innerConversationNodeRef", type: "ConversationNode", isAttr: true, isReference: true }, { name: "outerConversationNodeRef", type: "ConversationNode", isAttr: true, isReference: true }] }, { name: "CallConversation", superClass: ["ConversationNode"], properties: [{ name: "calledCollaborationRef", type: "Collaboration", isAttr: true, isReference: true }, { name: "participantAssociations", type: "ParticipantAssociation", isMany: true }] }, { name: "Conversation", superClass: ["ConversationNode"] }, { name: "SubConversation", superClass: ["ConversationNode"], properties: [{ name: "conversationNodes", type: "ConversationNode", isMany: true }] }, { name: "ConversationNode", isAbstract: true, superClass: ["InteractionNode", "BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "participantRef", type: "Participant", isMany: true, isReference: true }, { name: "messageFlowRefs", type: "MessageFlow", isMany: true, isReference: true }, { name: "correlationKeys", type: "CorrelationKey", isMany: true }] }, { name: "GlobalConversation", superClass: ["Collaboration"] }, { name: "PartnerEntity", superClass: ["RootElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "participantRef", type: "Participant", isMany: true, isReference: true }] }, { name: "PartnerRole", superClass: ["RootElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "participantRef", type: "Participant", isMany: true, isReference: true }] }, { name: "CorrelationProperty", superClass: ["RootElement"], properties: [{ name: "correlationPropertyRetrievalExpression", type: "CorrelationPropertyRetrievalExpression", isMany: true }, { name: "name", isAttr: true, type: "String" }, { name: "type", type: "ItemDefinition", isAttr: true, isReference: true }] }, { name: "Error", superClass: ["RootElement"], properties: [{ name: "structureRef", type: "ItemDefinition", isAttr: true, isReference: true }, { name: "name", isAttr: true, type: "String" }, { name: "errorCode", isAttr: true, type: "String" }] }, { name: "CorrelationKey", superClass: ["BaseElement"], properties: [{ name: "correlationPropertyRef", type: "CorrelationProperty", isMany: true, isReference: true }, { name: "name", isAttr: true, type: "String" }] }, { name: "Expression", superClass: ["BaseElement"], isAbstract: false, properties: [{ name: "body", isBody: true, type: "String" }] }, { name: "FormalExpression", superClass: ["Expression"], properties: [{ name: "language", isAttr: true, type: "String" }, { name: "evaluatesToTypeRef", type: "ItemDefinition", isAttr: true, isReference: true }] }, { name: "Message", superClass: ["RootElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "itemRef", type: "ItemDefinition", isAttr: true, isReference: true }] }, { name: "ItemDefinition", superClass: ["RootElement"], properties: [{ name: "itemKind", type: "ItemKind", isAttr: true }, { name: "structureRef", isAttr: true, type: "String" }, { name: "isCollection", "default": false, isAttr: true, type: "Boolean" }, { name: "import", type: "Import", isAttr: true, isReference: true }] }, { name: "FlowElement", isAbstract: true, superClass: ["BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "auditing", type: "Auditing" }, { name: "monitoring", type: "Monitoring" }, { name: "categoryValueRef", type: "CategoryValue", isMany: true, isReference: true }] }, { name: "SequenceFlow", superClass: ["FlowElement"], properties: [{ name: "isImmediate", isAttr: true, type: "Boolean" }, { name: "conditionExpression", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "sourceRef", type: "FlowNode", isAttr: true, isReference: true }, { name: "targetRef", type: "FlowNode", isAttr: true, isReference: true }] }, { name: "FlowElementsContainer", isAbstract: true, superClass: ["BaseElement"], properties: [{ name: "laneSets", type: "LaneSet", isMany: true }, { name: "flowElements", type: "FlowElement", isMany: true }] }, { name: "CallableElement", isAbstract: true, superClass: ["RootElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "ioSpecification", type: "InputOutputSpecification", xml: { serialize: "property" } }, { name: "supportedInterfaceRef", type: "Interface", isMany: true, isReference: true }, { name: "ioBinding", type: "InputOutputBinding", isMany: true, xml: { serialize: "property" } }] }, { name: "FlowNode", isAbstract: true, superClass: ["FlowElement"], properties: [{ name: "incoming", type: "SequenceFlow", isMany: true, isReference: true }, { name: "outgoing", type: "SequenceFlow", isMany: true, isReference: true }, { name: "lanes", type: "Lane", isMany: true, isVirtual: true, isReference: true }] }, { name: "CorrelationPropertyRetrievalExpression", superClass: ["BaseElement"], properties: [{ name: "messagePath", type: "FormalExpression" }, { name: "messageRef", type: "Message", isAttr: true, isReference: true }] }, { name: "CorrelationPropertyBinding", superClass: ["BaseElement"], properties: [{ name: "dataPath", type: "FormalExpression" }, { name: "correlationPropertyRef", type: "CorrelationProperty", isAttr: true, isReference: true }] }, { name: "Resource", superClass: ["RootElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "resourceParameters", type: "ResourceParameter", isMany: true }] }, { name: "ResourceParameter", superClass: ["BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "isRequired", isAttr: true, type: "Boolean" }, { name: "type", type: "ItemDefinition", isAttr: true, isReference: true }] }, { name: "CorrelationSubscription", superClass: ["BaseElement"], properties: [{ name: "correlationKeyRef", type: "CorrelationKey", isAttr: true, isReference: true }, { name: "correlationPropertyBinding", type: "CorrelationPropertyBinding", isMany: true }] }, { name: "MessageFlow", superClass: ["BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "sourceRef", type: "InteractionNode", isAttr: true, isReference: true }, { name: "targetRef", type: "InteractionNode", isAttr: true, isReference: true }, { name: "messageRef", type: "Message", isAttr: true, isReference: true }] }, { name: "MessageFlowAssociation", superClass: ["BaseElement"], properties: [{ name: "innerMessageFlowRef", type: "MessageFlow", isAttr: true, isReference: true }, { name: "outerMessageFlowRef", type: "MessageFlow", isAttr: true, isReference: true }] }, { name: "InteractionNode", isAbstract: true, properties: [{ name: "incomingConversationLinks", type: "ConversationLink", isMany: true, isVirtual: true, isReference: true }, { name: "outgoingConversationLinks", type: "ConversationLink", isMany: true, isVirtual: true, isReference: true }] }, { name: "Participant", superClass: ["InteractionNode", "BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "interfaceRef", type: "Interface", isMany: true, isReference: true }, { name: "participantMultiplicity", type: "ParticipantMultiplicity" }, { name: "endPointRefs", type: "EndPoint", isMany: true, isReference: true }, { name: "processRef", type: "Process", isAttr: true, isReference: true }] }, { name: "ParticipantAssociation", superClass: ["BaseElement"], properties: [{ name: "innerParticipantRef", type: "Participant", isAttr: true, isReference: true }, { name: "outerParticipantRef", type: "Participant", isAttr: true, isReference: true }] }, { name: "ParticipantMultiplicity", properties: [{ name: "minimum", "default": 0, isAttr: true, type: "Integer" }, { name: "maximum", "default": 1, isAttr: true, type: "Integer" }], superClass: ["BaseElement"] }, { name: "Collaboration", superClass: ["RootElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "isClosed", isAttr: true, type: "Boolean" }, { name: "participants", type: "Participant", isMany: true }, { name: "messageFlows", type: "MessageFlow", isMany: true }, { name: "artifacts", type: "Artifact", isMany: true }, { name: "conversations", type: "ConversationNode", isMany: true }, { name: "conversationAssociations", type: "ConversationAssociation" }, { name: "participantAssociations", type: "ParticipantAssociation", isMany: true }, { name: "messageFlowAssociations", type: "MessageFlowAssociation", isMany: true }, { name: "correlationKeys", type: "CorrelationKey", isMany: true }, { name: "choreographyRef", type: "Choreography", isMany: true, isReference: true }, { name: "conversationLinks", type: "ConversationLink", isMany: true }] }, { name: "ChoreographyActivity", isAbstract: true, superClass: ["FlowNode"], properties: [{ name: "participantRef", type: "Participant", isMany: true, isReference: true }, { name: "initiatingParticipantRef", type: "Participant", isAttr: true, isReference: true }, { name: "correlationKeys", type: "CorrelationKey", isMany: true }, { name: "loopType", type: "ChoreographyLoopType", "default": "None", isAttr: true }] }, { name: "CallChoreography", superClass: ["ChoreographyActivity"], properties: [{ name: "calledChoreographyRef", type: "Choreography", isAttr: true, isReference: true }, { name: "participantAssociations", type: "ParticipantAssociation", isMany: true }] }, { name: "SubChoreography", superClass: ["ChoreographyActivity", "FlowElementsContainer"], properties: [{ name: "artifacts", type: "Artifact", isMany: true }] }, { name: "ChoreographyTask", superClass: ["ChoreographyActivity"], properties: [{ name: "messageFlowRef", type: "MessageFlow", isMany: true, isReference: true }] }, { name: "Choreography", superClass: ["Collaboration", "FlowElementsContainer"] }, { name: "GlobalChoreographyTask", superClass: ["Choreography"], properties: [{ name: "initiatingParticipantRef", type: "Participant", isAttr: true, isReference: true }] }, { name: "TextAnnotation", superClass: ["Artifact"], properties: [{ name: "text", type: "String" }, { name: "textFormat", "default": "text/plain", isAttr: true, type: "String" }] }, { name: "Group", superClass: ["Artifact"], properties: [{ name: "categoryValueRef", type: "CategoryValue", isAttr: true, isReference: true }] }, { name: "Association", superClass: ["Artifact"], properties: [{ name: "associationDirection", type: "AssociationDirection", isAttr: true }, { name: "sourceRef", type: "BaseElement", isAttr: true, isReference: true }, { name: "targetRef", type: "BaseElement", isAttr: true, isReference: true }] }, { name: "Category", superClass: ["RootElement"], properties: [{ name: "categoryValue", type: "CategoryValue", isMany: true }, { name: "name", isAttr: true, type: "String" }] }, { name: "Artifact", isAbstract: true, superClass: ["BaseElement"] }, { name: "CategoryValue", superClass: ["BaseElement"], properties: [{ name: "categorizedFlowElements", type: "FlowElement", isMany: true, isVirtual: true, isReference: true }, { name: "value", isAttr: true, type: "String" }] }, { name: "Activity", isAbstract: true, superClass: ["FlowNode"], properties: [{ name: "isForCompensation", "default": false, isAttr: true, type: "Boolean" }, { name: "default", type: "SequenceFlow", isAttr: true, isReference: true }, { name: "ioSpecification", type: "InputOutputSpecification", xml: { serialize: "property" } }, { name: "boundaryEventRefs", type: "BoundaryEvent", isMany: true, isReference: true }, { name: "properties", type: "Property", isMany: true }, { name: "dataInputAssociations", type: "DataInputAssociation", isMany: true }, { name: "dataOutputAssociations", type: "DataOutputAssociation", isMany: true }, { name: "startQuantity", "default": 1, isAttr: true, type: "Integer" }, { name: "resources", type: "ResourceRole", isMany: true }, { name: "completionQuantity", "default": 1, isAttr: true, type: "Integer" }, { name: "loopCharacteristics", type: "LoopCharacteristics" }] }, { name: "ServiceTask", superClass: ["Task"], properties: [{ name: "implementation", isAttr: true, type: "String" }, { name: "operationRef", type: "Operation", isAttr: true, isReference: true }] }, { name: "SubProcess", superClass: ["Activity", "FlowElementsContainer", "InteractionNode"], properties: [{ name: "triggeredByEvent", "default": false, isAttr: true, type: "Boolean" }, { name: "artifacts", type: "Artifact", isMany: true }] }, { name: "LoopCharacteristics", isAbstract: true, superClass: ["BaseElement"] }, { name: "MultiInstanceLoopCharacteristics", superClass: ["LoopCharacteristics"], properties: [{ name: "isSequential", "default": false, isAttr: true, type: "Boolean" }, { name: "behavior", type: "MultiInstanceBehavior", "default": "All", isAttr: true }, { name: "loopCardinality", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "loopDataInputRef", type: "ItemAwareElement", isReference: true }, { name: "loopDataOutputRef", type: "ItemAwareElement", isReference: true }, { name: "inputDataItem", type: "DataInput", xml: { serialize: "property" } }, { name: "outputDataItem", type: "DataOutput", xml: { serialize: "property" } }, { name: "complexBehaviorDefinition", type: "ComplexBehaviorDefinition", isMany: true }, { name: "completionCondition", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "oneBehaviorEventRef", type: "EventDefinition", isAttr: true, isReference: true }, { name: "noneBehaviorEventRef", type: "EventDefinition", isAttr: true, isReference: true }] }, { name: "StandardLoopCharacteristics", superClass: ["LoopCharacteristics"], properties: [{ name: "testBefore", "default": false, isAttr: true, type: "Boolean" }, { name: "loopCondition", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "loopMaximum", type: "Integer", isAttr: true }] }, { name: "CallActivity", superClass: ["Activity"], properties: [{ name: "calledElement", type: "String", isAttr: true }] }, { name: "Task", superClass: ["Activity", "InteractionNode"] }, { name: "SendTask", superClass: ["Task"], properties: [{ name: "implementation", isAttr: true, type: "String" }, { name: "operationRef", type: "Operation", isAttr: true, isReference: true }, { name: "messageRef", type: "Message", isAttr: true, isReference: true }] }, { name: "ReceiveTask", superClass: ["Task"], properties: [{ name: "implementation", isAttr: true, type: "String" }, { name: "instantiate", "default": false, isAttr: true, type: "Boolean" }, { name: "operationRef", type: "Operation", isAttr: true, isReference: true }, { name: "messageRef", type: "Message", isAttr: true, isReference: true }] }, { name: "ScriptTask", superClass: ["Task"], properties: [{ name: "scriptFormat", isAttr: true, type: "String" }, { name: "script", type: "String" }] }, { name: "BusinessRuleTask", superClass: ["Task"], properties: [{ name: "implementation", isAttr: true, type: "String" }] }, { name: "AdHocSubProcess", superClass: ["SubProcess"], properties: [{ name: "completionCondition", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "ordering", type: "AdHocOrdering", isAttr: true }, { name: "cancelRemainingInstances", "default": true, isAttr: true, type: "Boolean" }] }, { name: "Transaction", superClass: ["SubProcess"], properties: [{ name: "protocol", isAttr: true, type: "String" }, { name: "method", isAttr: true, type: "String" }] }, { name: "GlobalScriptTask", superClass: ["GlobalTask"], properties: [{ name: "scriptLanguage", isAttr: true, type: "String" }, { name: "script", isAttr: true, type: "String" }] }, { name: "GlobalBusinessRuleTask", superClass: ["GlobalTask"], properties: [{ name: "implementation", isAttr: true, type: "String" }] }, { name: "ComplexBehaviorDefinition", superClass: ["BaseElement"], properties: [{ name: "condition", type: "FormalExpression" }, { name: "event", type: "ImplicitThrowEvent" }] }, { name: "ResourceRole", superClass: ["BaseElement"], properties: [{ name: "resourceRef", type: "Resource", isReference: true }, { name: "resourceParameterBindings", type: "ResourceParameterBinding", isMany: true }, { name: "resourceAssignmentExpression", type: "ResourceAssignmentExpression" }, { name: "name", isAttr: true, type: "String" }] }, { name: "ResourceParameterBinding", properties: [{ name: "expression", type: "Expression", xml: { serialize: "xsi:type" } }, { name: "parameterRef", type: "ResourceParameter", isAttr: true, isReference: true }], superClass: ["BaseElement"] }, { name: "ResourceAssignmentExpression", properties: [{ name: "expression", type: "Expression", xml: { serialize: "xsi:type" } }], superClass: ["BaseElement"] }, { name: "Import", properties: [{ name: "importType", isAttr: true, type: "String" }, { name: "location", isAttr: true, type: "String" }, { name: "namespace", isAttr: true, type: "String" }] }, { name: "Definitions", superClass: ["BaseElement"], properties: [{ name: "name", isAttr: true, type: "String" }, { name: "targetNamespace", isAttr: true, type: "String" }, { name: "expressionLanguage", "default": "http://www.w3.org/1999/XPath", isAttr: true, type: "String" }, { name: "typeLanguage", "default": "http://www.w3.org/2001/XMLSchema", isAttr: true, type: "String" }, { name: "imports", type: "Import", isMany: true }, { name: "extensions", type: "Extension", isMany: true }, { name: "rootElements", type: "RootElement", isMany: true }, { name: "diagrams", isMany: true, type: "bpmndi:BPMNDiagram" }, { name: "exporter", isAttr: true, type: "String" }, { name: "relationships", type: "Relationship", isMany: true }, { name: "exporterVersion", isAttr: true, type: "String" }] }]; var enumerations = [{ name: "ProcessType", literalValues: [{ name: "None" }, { name: "Public" }, { name: "Private" }] }, { name: "GatewayDirection", literalValues: [{ name: "Unspecified" }, { name: "Converging" }, { name: "Diverging" }, { name: "Mixed" }] }, { name: "EventBasedGatewayType", literalValues: [{ name: "Parallel" }, { name: "Exclusive" }] }, { name: "RelationshipDirection", literalValues: [{ name: "None" }, { name: "Forward" }, { name: "Backward" }, { name: "Both" }] }, { name: "ItemKind", literalValues: [{ name: "Physical" }, { name: "Information" }] }, { name: "ChoreographyLoopType", literalValues: [{ name: "None" }, { name: "Standard" }, { name: "MultiInstanceSequential" }, { name: "MultiInstanceParallel" }] }, { name: "AssociationDirection", literalValues: [{ name: "None" }, { name: "One" }, { name: "Both" }] }, { name: "MultiInstanceBehavior", literalValues: [{ name: "None" }, { name: "One" }, { name: "All" }, { name: "Complex" }] }, { name: "AdHocOrdering", literalValues: [{ name: "Parallel" }, { name: "Sequential" }] }]; var xml = { tagAlias: "lowerCase", typePrefix: "t" }; var BpmnPackage = { name: name, uri: uri, prefix: prefix, associations: associations, types: types, enumerations: enumerations, xml: xml }; var name$1 = "BPMNDI"; var uri$1 = "http://www.omg.org/spec/BPMN/20100524/DI"; var prefix$1 = "bpmndi"; var types$1 = [{ name: "BPMNDiagram", properties: [{ name: "plane", type: "BPMNPlane", redefines: "di:Diagram#rootElement" }, { name: "labelStyle", type: "BPMNLabelStyle", isMany: true }], superClass: ["di:Diagram"] }, { name: "BPMNPlane", properties: [{ name: "bpmnElement", isAttr: true, isReference: true, type: "bpmn:BaseElement", redefines: "di:DiagramElement#modelElement" }], superClass: ["di:Plane"] }, { name: "BPMNShape", properties: [{ name: "bpmnElement", isAttr: true, isReference: true, type: "bpmn:BaseElement", redefines: "di:DiagramElement#modelElement" }, { name: "isHorizontal", isAttr: true, type: "Boolean" }, { name: "isExpanded", isAttr: true, type: "Boolean" }, { name: "isMarkerVisible", isAttr: true, type: "Boolean" }, { name: "label", type: "BPMNLabel" }, { name: "isMessageVisible", isAttr: true, type: "Boolean" }, { name: "participantBandKind", type: "ParticipantBandKind", isAttr: true }, { name: "choreographyActivityShape", type: "BPMNShape", isAttr: true, isReference: true }], superClass: ["di:LabeledShape"] }, { name: "BPMNEdge", properties: [{ name: "label", type: "BPMNLabel" }, { name: "bpmnElement", isAttr: true, isReference: true, type: "bpmn:BaseElement", redefines: "di:DiagramElement#modelElement" }, { name: "sourceElement", isAttr: true, isReference: true, type: "di:DiagramElement", redefines: "di:Edge#source" }, { name: "targetElement", isAttr: true, isReference: true, type: "di:DiagramElement", redefines: "di:Edge#target" }, { name: "messageVisibleKind", type: "MessageVisibleKind", isAttr: true, "default": "initiating" }], superClass: ["di:LabeledEdge"] }, { name: "BPMNLabel", properties: [{ name: "labelStyle", type: "BPMNLabelStyle", isAttr: true, isReference: true, redefines: "di:DiagramElement#style" }], superClass: ["di:Label"] }, { name: "BPMNLabelStyle", properties: [{ name: "font", type: "dc:Font" }], superClass: ["di:Style"] }]; var enumerations$1 = [{ name: "ParticipantBandKind", literalValues: [{ name: "top_initiating" }, { name: "middle_initiating" }, { name: "bottom_initiating" }, { name: "top_non_initiating" }, { name: "middle_non_initiating" }, { name: "bottom_non_initiating" }] }, { name: "MessageVisibleKind", literalValues: [{ name: "initiating" }, { name: "non_initiating" }] }]; var associations$1 = []; var BpmnDiPackage = { name: name$1, uri: uri$1, prefix: prefix$1, types: types$1, enumerations: enumerations$1, associations: associations$1 }; var name$2 = "DC"; var uri$2 = "http://www.omg.org/spec/DD/20100524/DC"; var prefix$2 = "dc"; var types$2 = [{ name: "Boolean" }, { name: "Integer" }, { name: "Real" }, { name: "String" }, { name: "Font", properties: [{ name: "name", type: "String", isAttr: true }, { name: "size", type: "Real", isAttr: true }, { name: "isBold", type: "Boolean", isAttr: true }, { name: "isItalic", type: "Boolean", isAttr: true }, { name: "isUnderline", type: "Boolean", isAttr: true }, { name: "isStrikeThrough", type: "Boolean", isAttr: true }] }, { name: "Point", properties: [{ name: "x", type: "Real", "default": "0", isAttr: true }, { name: "y", type: "Real", "default": "0", isAttr: true }] }, { name: "Bounds", properties: [{ name: "x", type: "Real", "default": "0", isAttr: true }, { name: "y", type: "Real", "default": "0", isAttr: true }, { name: "width", type: "Real", isAttr: true }, { name: "height", type: "Real", isAttr: true }] }]; var associations$2 = []; var DcPackage = { name: name$2, uri: uri$2, prefix: prefix$2, types: types$2, associations: associations$2 }; var name$3 = "DI"; var uri$3 = "http://www.omg.org/spec/DD/20100524/DI"; var prefix$3 = "di"; var types$3 = [{ name: "DiagramElement", isAbstract: true, properties: [{ name: "id", isAttr: true, isId: true, type: "String" }, { name: "extension", type: "Extension" }, { name: "owningDiagram", type: "Diagram", isReadOnly: true, isVirtual: true, isReference: true }, { name: "owningElement", type: "DiagramElement", isReadOnly: true, isVirtual: true, isReference: true }, { name: "modelElement", isReadOnly: true, isVirtual: true, isReference: true, type: "Element" }, { name: "style", type: "Style", isReadOnly: true, isVirtual: true, isReference: true }, { name: "ownedElement", type: "DiagramElement", isReadOnly: true, isMany: true, isVirtual: true }] }, { name: "Node", isAbstract: true, superClass: ["DiagramElement"] }, { name: "Edge", isAbstract: true, superClass: ["DiagramElement"], properties: [{ name: "source", type: "DiagramElement", isReadOnly: true, isVirtual: true, isReference: true }, { name: "target", type: "DiagramElement", isReadOnly: true, isVirtual: true, isReference: true }, { name: "waypoint", isUnique: false, isMany: true, type: "dc:Point", xml: { serialize: "xsi:type" } }] }, { name: "Diagram", isAbstract: true, properties: [{ name: "id", isAttr: true, isId: true, type: "String" }, { name: "rootElement", type: "DiagramElement", isReadOnly: true, isVirtual: true }, { name: "name", isAttr: true, type: "String" }, { name: "documentation", isAttr: true, type: "String" }, { name: "resolution", isAttr: true, type: "Real" }, { name: "ownedStyle", type: "Style", isReadOnly: true, isMany: true, isVirtual: true }] }, { name: "Shape", isAbstract: true, superClass: ["Node"], properties: [{ name: "bounds", type: "dc:Bounds" }] }, { name: "Plane", isAbstract: true, superClass: ["Node"], properties: [{ name: "planeElement", type: "DiagramElement", subsettedProperty: "DiagramElement-ownedElement", isMany: true }] }, { name: "LabeledEdge", isAbstract: true, superClass: ["Edge"], properties: [{ name: "ownedLabel", type: "Label", isReadOnly: true, subsettedProperty: "DiagramElement-ownedElement", isMany: true, isVirtual: true }] }, { name: "LabeledShape", isAbstract: true, superClass: ["Shape"], properties: [{ name: "ownedLabel", type: "Label", isReadOnly: true, subsettedProperty: "DiagramElement-ownedElement", isMany: true, isVirtual: true }] }, { name: "Label", isAbstract: true, superClass: ["Node"], properties: [{ name: "bounds", type: "dc:Bounds" }] }, { name: "Style", isAbstract: true, properties: [{ name: "id", isAttr: true, isId: true, type: "String" }] }, { name: "Extension", properties: [{ name: "values", isMany: true, type: "Element" }] }]; var associations$3 = []; var xml$1 = { tagAlias: "lowerCase" }; var DiPackage = { name: name$3, uri: uri$3, prefix: prefix$3, types: types$3, associations: associations$3, xml: xml$1 }; var name$4 = "bpmn.io colors for BPMN"; var uri$4 = "http://bpmn.io/schema/bpmn/biocolor/1.0"; var prefix$4 = "bioc"; var types$4 = [{ name: "ColoredShape", "extends": ["bpmndi:BPMNShape"], properties: [{ name: "stroke", isAttr: true, type: "String" }, { name: "fill", isAttr: true, type: "String" }] }, { name: "ColoredEdge", "extends": ["bpmndi:BPMNEdge"], properties: [{ name: "stroke", isAttr: true, type: "String" }, { name: "fill", isAttr: true, type: "String" }] }]; var enumerations$2 = []; var associations$4 = []; var BiocPackage = { name: name$4, uri: uri$4, prefix: prefix$4, types: types$4, enumerations: enumerations$2, associations: associations$4 }; var packages = { bpmn: BpmnPackage, bpmndi: BpmnDiPackage, dc: DcPackage, di: DiPackage, bioc: BiocPackage }; function simple(additionalPackages, options) { var pks = (0, _minDash.assign)({}, packages, additionalPackages); return new BpmnModdle(pks, options); } var _default = simple; exports.default = _default; },{"min-dash":555,"moddle":559,"moddle-xml":558}],331:[function(require,module,exports){ (function (global){(function (){ /*! https://mths.be/cssescape v1.5.1 by @mathias | MIT license */ ;(function(root, factory) { // https://github.com/umdjs/umd/blob/master/returnExports.js if (typeof exports == 'object') { // For Node.js. module.exports = factory(root); } else if (typeof define == 'function' && define.amd) { // For AMD. Register as an anonymous module. define([], factory.bind(root, root)); } else { // For browser globals (not exposing the function separately). factory(root); } }(typeof global != 'undefined' ? global : this, function(root) { if (root.CSS && root.CSS.escape) { return root.CSS.escape; } // https://drafts.csswg.org/cssom/#serialize-an-identifier var cssEscape = function(value) { if (arguments.length == 0) { throw new TypeError('`CSS.escape` requires an argument.'); } var string = String(value); var length = string.length; var index = -1; var codeUnit; var result = ''; var firstCodeUnit = string.charCodeAt(0); while (++index < length) { codeUnit = string.charCodeAt(index); // Note: there’s no need to special-case astral symbols, surrogate // pairs, or lone surrogates. // If the character is NULL (U+0000), then the REPLACEMENT CHARACTER // (U+FFFD). if (codeUnit == 0x0000) { result += '\uFFFD'; continue; } if ( // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is // U+007F, […] (codeUnit >= 0x0001 && codeUnit <= 0x001F) || codeUnit == 0x007F || // If the character is the first character and is in the range [0-9] // (U+0030 to U+0039), […] (index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) || // If the character is the second character and is in the range [0-9] // (U+0030 to U+0039) and the first character is a `-` (U+002D), […] ( index == 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && firstCodeUnit == 0x002D ) ) { // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point result += '\\' + codeUnit.toString(16) + ' '; continue; } if ( // If the character is the first character and is a `-` (U+002D), and // there is no second character, […] index == 0 && length == 1 && codeUnit == 0x002D ) { result += '\\' + string.charAt(index); continue; } // If the character is not handled by one of the above rules and is // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to // U+005A), or [a-z] (U+0061 to U+007A), […] if ( codeUnit >= 0x0080 || codeUnit == 0x002D || codeUnit == 0x005F || codeUnit >= 0x0030 && codeUnit <= 0x0039 || codeUnit >= 0x0041 && codeUnit <= 0x005A || codeUnit >= 0x0061 && codeUnit <= 0x007A ) { // the character itself result += string.charAt(index); continue; } // Otherwise, the escaped character. // https://drafts.csswg.org/cssom/#escape-a-character result += '\\' + string.charAt(index); } return result; }; if (!root.CSS) { root.CSS = {}; } root.CSS.escape = cssEscape; return cssEscape; })); }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],332:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _interactionEvents = _interopRequireDefault(require("diagram-js/lib/features/interaction-events")); var _DirectEditing = _interopRequireDefault(require("./lib/DirectEditing")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __depends__: [_interactionEvents.default], __init__: ['directEditing'], directEditing: ['type', _DirectEditing.default] }; exports.default = _default; },{"./lib/DirectEditing":333,"diagram-js/lib/features/interaction-events":336}],333:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = DirectEditing; var _minDash = require("min-dash"); var _TextBox = _interopRequireDefault(require("./TextBox")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * A direct editing component that allows users * to edit an elements text directly in the diagram * * @param {EventBus} eventBus the event bus */ function DirectEditing(eventBus, canvas) { this._eventBus = eventBus; this._providers = []; this._textbox = new _TextBox.default({ container: canvas.getContainer(), keyHandler: (0, _minDash.bind)(this._handleKey, this), resizeHandler: (0, _minDash.bind)(this._handleResize, this) }); } DirectEditing.$inject = ['eventBus', 'canvas']; /** * Register a direct editing provider * @param {Object} provider the provider, must expose an #activate(element) method that returns * an activation context ({ bounds: {x, y, width, height }, text }) if * direct editing is available for the given element. * Additionally the provider must expose a #update(element, value) method * to receive direct editing updates. */ DirectEditing.prototype.registerProvider = function (provider) { this._providers.push(provider); }; /** * Returns true if direct editing is currently active * * @return {Boolean} */ DirectEditing.prototype.isActive = function () { return !!this._active; }; /** * Cancel direct editing, if it is currently active */ DirectEditing.prototype.cancel = function () { if (!this._active) { return; } this._fire('cancel'); this.close(); }; DirectEditing.prototype._fire = function (event, context) { this._eventBus.fire('directEditing.' + event, context || { active: this._active }); }; DirectEditing.prototype.close = function () { this._textbox.destroy(); this._fire('deactivate'); this._active = null; this.resizable = undefined; }; DirectEditing.prototype.complete = function () { var active = this._active; if (!active) { return; } var containerBounds, previousBounds = active.context.bounds, newBounds = this.$textbox.getBoundingClientRect(), newText = this.getValue(), previousText = active.context.text; if (newText !== previousText || newBounds.height !== previousBounds.height || newBounds.width !== previousBounds.width) { containerBounds = this._textbox.container.getBoundingClientRect(); active.provider.update(active.element, newText, active.context.text, { x: newBounds.left - containerBounds.left, y: newBounds.top - containerBounds.top, width: newBounds.width, height: newBounds.height }); } this._fire('complete'); this.close(); }; DirectEditing.prototype.getValue = function () { return this._textbox.getValue(); }; DirectEditing.prototype._handleKey = function (e) { // stop bubble e.stopPropagation(); var key = e.keyCode || e.charCode; // ESC if (key === 27) { e.preventDefault(); return this.cancel(); } // Enter if (key === 13 && !e.shiftKey) { e.preventDefault(); return this.complete(); } }; DirectEditing.prototype._handleResize = function (event) { this._fire('resize', event); }; /** * Activate direct editing on the given element * * @param {Object} ElementDescriptor the descriptor for a shape or connection * @return {Boolean} true if the activation was possible */ DirectEditing.prototype.activate = function (element) { if (this.isActive()) { this.cancel(); } // the direct editing context var context; var provider = (0, _minDash.find)(this._providers, function (p) { return (context = p.activate(element)) ? p : null; }); // check if activation took place if (context) { this.$textbox = this._textbox.create(context.bounds, context.style, context.text, context.options); this._active = { element: element, context: context, provider: provider }; if (context.options && context.options.resizable) { this.resizable = true; } this._fire('activate'); } return !!context; }; },{"./TextBox":334,"min-dash":555}],334:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = TextBox; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var min = Math.min, max = Math.max; function preventDefault(e) { e.preventDefault(); } function stopPropagation(e) { e.stopPropagation(); } function isTextNode(node) { return node.nodeType === Node.TEXT_NODE; } function toArray(nodeList) { return [].slice.call(nodeList); } /** * Initializes a container for a content editable div. * * Structure: * * container * parent * content * resize-handle * * @param {object} options * @param {DOMElement} options.container The DOM element to append the contentContainer to * @param {Function} options.keyHandler Handler for key events * @param {Function} options.resizeHandler Handler for resize events */ function TextBox(options) { this.container = options.container; this.parent = (0, _minDom.domify)('<div class="djs-direct-editing-parent">' + '<div class="djs-direct-editing-content" contenteditable="true"></div>' + '</div>'); this.content = (0, _minDom.query)('[contenteditable]', this.parent); this.keyHandler = options.keyHandler || function () {}; this.resizeHandler = options.resizeHandler || function () {}; this.autoResize = (0, _minDash.bind)(this.autoResize, this); this.handlePaste = (0, _minDash.bind)(this.handlePaste, this); } /** * Create a text box with the given position, size, style and text content * * @param {Object} bounds * @param {Number} bounds.x absolute x position * @param {Number} bounds.y absolute y position * @param {Number} [bounds.width] fixed width value * @param {Number} [bounds.height] fixed height value * @param {Number} [bounds.maxWidth] maximum width value * @param {Number} [bounds.maxHeight] maximum height value * @param {Number} [bounds.minWidth] minimum width value * @param {Number} [bounds.minHeight] minimum height value * @param {Object} [style] * @param {String} value text content * * @return {DOMElement} The created content DOM element */ TextBox.prototype.create = function (bounds, style, value, options) { var self = this; var parent = this.parent, content = this.content, container = this.container; options = this.options = options || {}; style = this.style = style || {}; var parentStyle = (0, _minDash.pick)(style, ['width', 'height', 'maxWidth', 'maxHeight', 'minWidth', 'minHeight', 'left', 'top', 'backgroundColor', 'position', 'overflow', 'border', 'wordWrap', 'textAlign', 'outline', 'transform']); (0, _minDash.assign)(parent.style, { width: bounds.width + 'px', height: bounds.height + 'px', maxWidth: bounds.maxWidth + 'px', maxHeight: bounds.maxHeight + 'px', minWidth: bounds.minWidth + 'px', minHeight: bounds.minHeight + 'px', left: bounds.x + 'px', top: bounds.y + 'px', backgroundColor: '#ffffff', position: 'absolute', overflow: 'visible', border: '1px solid #ccc', boxSizing: 'border-box', wordWrap: 'normal', textAlign: 'center', outline: 'none' }, parentStyle); var contentStyle = (0, _minDash.pick)(style, ['fontFamily', 'fontSize', 'fontWeight', 'lineHeight', 'padding', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft']); (0, _minDash.assign)(content.style, { boxSizing: 'border-box', width: '100%', outline: 'none', wordWrap: 'break-word' }, contentStyle); if (options.centerVertically) { (0, _minDash.assign)(content.style, { position: 'absolute', top: '50%', transform: 'translate(0, -50%)' }, contentStyle); } content.innerText = value; _minDom.event.bind(content, 'keydown', this.keyHandler); _minDom.event.bind(content, 'mousedown', stopPropagation); _minDom.event.bind(content, 'paste', self.handlePaste); if (options.autoResize) { _minDom.event.bind(content, 'input', this.autoResize); } if (options.resizable) { this.resizable(style); } container.appendChild(parent); // set selection to end of text this.setSelection(content.lastChild, content.lastChild && content.lastChild.length); return parent; }; /** * Intercept paste events to remove formatting from pasted text. */ TextBox.prototype.handlePaste = function (e) { var options = this.options, style = this.style; e.preventDefault(); var text; if (e.clipboardData) { // Chrome, Firefox, Safari text = e.clipboardData.getData('text/plain'); } else { // Internet Explorer text = window.clipboardData.getData('Text'); } this.insertText(text); if (options.autoResize) { var hasResized = this.autoResize(style); if (hasResized) { this.resizeHandler(hasResized); } } }; TextBox.prototype.insertText = function (text) { // insertText command not supported by Internet Explorer var success = document.execCommand('insertText', false, text); if (success) { return; } this._insertTextIE(text); }; TextBox.prototype._insertTextIE = function (text) { // Internet Explorer var range = this.getSelection(), startContainer = range.startContainer, endContainer = range.endContainer, startOffset = range.startOffset, endOffset = range.endOffset, commonAncestorContainer = range.commonAncestorContainer; var childNodesArray = toArray(commonAncestorContainer.childNodes); var container, offset; if (isTextNode(commonAncestorContainer)) { var containerTextContent = startContainer.textContent; startContainer.textContent = containerTextContent.substring(0, startOffset) + text + containerTextContent.substring(endOffset); container = startContainer; offset = startOffset + text.length; } else if (startContainer === this.content && endContainer === this.content) { var textNode = document.createTextNode(text); this.content.insertBefore(textNode, childNodesArray[startOffset]); container = textNode; offset = textNode.textContent.length; } else { var startContainerChildIndex = childNodesArray.indexOf(startContainer), endContainerChildIndex = childNodesArray.indexOf(endContainer); childNodesArray.forEach(function (childNode, index) { if (index === startContainerChildIndex) { childNode.textContent = startContainer.textContent.substring(0, startOffset) + text + endContainer.textContent.substring(endOffset); } else if (index > startContainerChildIndex && index <= endContainerChildIndex) { (0, _minDom.remove)(childNode); } }); container = startContainer; offset = startOffset + text.length; } if (container && offset !== undefined) { // is necessary in Internet Explorer setTimeout(function () { self.setSelection(container, offset); }); } }; /** * Automatically resize element vertically to fit its content. */ TextBox.prototype.autoResize = function () { var parent = this.parent, content = this.content; var fontSize = parseInt(this.style.fontSize) || 12; if (content.scrollHeight > parent.offsetHeight || content.scrollHeight < parent.offsetHeight - fontSize) { var bounds = parent.getBoundingClientRect(); var height = content.scrollHeight; parent.style.height = height + 'px'; this.resizeHandler({ width: bounds.width, height: bounds.height, dx: 0, dy: height - bounds.height }); } }; /** * Make an element resizable by adding a resize handle. */ TextBox.prototype.resizable = function () { var self = this; var parent = this.parent, resizeHandle = this.resizeHandle; var minWidth = parseInt(this.style.minWidth) || 0, minHeight = parseInt(this.style.minHeight) || 0, maxWidth = parseInt(this.style.maxWidth) || Infinity, maxHeight = parseInt(this.style.maxHeight) || Infinity; if (!resizeHandle) { resizeHandle = this.resizeHandle = (0, _minDom.domify)('<div class="djs-direct-editing-resize-handle"></div>'); var startX, startY, startWidth, startHeight; var onMouseDown = function (e) { preventDefault(e); stopPropagation(e); startX = e.clientX; startY = e.clientY; var bounds = parent.getBoundingClientRect(); startWidth = bounds.width; startHeight = bounds.height; _minDom.event.bind(document, 'mousemove', onMouseMove); _minDom.event.bind(document, 'mouseup', onMouseUp); }; var onMouseMove = function (e) { preventDefault(e); stopPropagation(e); var newWidth = min(max(startWidth + e.clientX - startX, minWidth), maxWidth); var newHeight = min(max(startHeight + e.clientY - startY, minHeight), maxHeight); parent.style.width = newWidth + 'px'; parent.style.height = newHeight + 'px'; self.resizeHandler({ width: startWidth, height: startHeight, dx: e.clientX - startX, dy: e.clientY - startY }); }; var onMouseUp = function (e) { preventDefault(e); stopPropagation(e); _minDom.event.unbind(document, 'mousemove', onMouseMove, false); _minDom.event.unbind(document, 'mouseup', onMouseUp, false); }; _minDom.event.bind(resizeHandle, 'mousedown', onMouseDown); } (0, _minDash.assign)(resizeHandle.style, { position: 'absolute', bottom: '0px', right: '0px', cursor: 'nwse-resize', width: '0', height: '0', borderTop: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid transparent', borderRight: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid #ccc', borderBottom: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid #ccc', borderLeft: (parseInt(this.style.fontSize) / 4 || 3) + 'px solid transparent' }); parent.appendChild(resizeHandle); }; /** * Clear content and style of the textbox, unbind listeners and * reset CSS style. */ TextBox.prototype.destroy = function () { var parent = this.parent, content = this.content, resizeHandle = this.resizeHandle; // clear content content.innerText = ''; // clear styles parent.removeAttribute('style'); content.removeAttribute('style'); _minDom.event.unbind(content, 'keydown', this.keyHandler); _minDom.event.unbind(content, 'mousedown', stopPropagation); _minDom.event.unbind(content, 'input', this.autoResize); _minDom.event.unbind(content, 'paste', this.handlePaste); if (resizeHandle) { resizeHandle.removeAttribute('style'); (0, _minDom.remove)(resizeHandle); } (0, _minDom.remove)(parent); }; TextBox.prototype.getValue = function () { return this.content.innerText.trim(); }; TextBox.prototype.getSelection = function () { var selection = window.getSelection(), range = selection.getRangeAt(0); return range; }; TextBox.prototype.setSelection = function (container, offset) { var range = document.createRange(); if (container === null) { range.selectNodeContents(this.content); } else { range.setStart(container, offset); range.setEnd(container, offset); } var selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); }; },{"min-dash":555,"min-dom":556}],335:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = InteractionEvents; var _minDash = require("min-dash"); var _minDom = require("min-dom"); var _Mouse = require("../../util/Mouse"); var _tinySvg = require("tiny-svg"); var _RenderUtil = require("../../util/RenderUtil"); function allowAll(e) { return true; } var LOW_PRIORITY = 500; /** * A plugin that provides interaction events for diagram elements. * * It emits the following events: * * * element.click * * element.contextmenu * * element.dblclick * * element.hover * * element.mousedown * * element.mousemove * * element.mouseup * * element.out * * Each event is a tuple { element, gfx, originalEvent }. * * Canceling the event via Event#preventDefault() * prevents the original DOM operation. * * @param {EventBus} eventBus */ function InteractionEvents(eventBus, elementRegistry, styles) { var self = this; /** * Fire an interaction event. * * @param {String} type local event name, e.g. element.click. * @param {DOMEvent} event native event * @param {djs.model.Base} [element] the diagram element to emit the event on; * defaults to the event target */ function fire(type, event, element) { if (isIgnored(type, event)) { return; } var target, gfx, returnValue; if (!element) { target = event.delegateTarget || event.target; if (target) { gfx = target; element = elementRegistry.get(gfx); } } else { gfx = elementRegistry.getGraphics(element); } if (!gfx || !element) { return; } returnValue = eventBus.fire(type, { element: element, gfx: gfx, originalEvent: event }); if (returnValue === false) { event.stopPropagation(); event.preventDefault(); } } // TODO(nikku): document this var handlers = {}; function mouseHandler(localEventName) { return handlers[localEventName]; } function isIgnored(localEventName, event) { var filter = ignoredFilters[localEventName] || _Mouse.isPrimaryButton; // only react on left mouse button interactions // except for interaction events that are enabled // for secundary mouse button return !filter(event); } var bindings = { click: 'element.click', contextmenu: 'element.contextmenu', dblclick: 'element.dblclick', mousedown: 'element.mousedown', mousemove: 'element.mousemove', mouseover: 'element.hover', mouseout: 'element.out', mouseup: 'element.mouseup' }; var ignoredFilters = { 'element.contextmenu': allowAll }; // manual event trigger ////////// /** * Trigger an interaction event (based on a native dom event) * on the target shape or connection. * * @param {String} eventName the name of the triggered DOM event * @param {MouseEvent} event * @param {djs.model.Base} targetElement */ function triggerMouseEvent(eventName, event, targetElement) { // i.e. element.mousedown... var localEventName = bindings[eventName]; if (!localEventName) { throw new Error('unmapped DOM event name <' + eventName + '>'); } return fire(localEventName, event, targetElement); } var ELEMENT_SELECTOR = 'svg, .djs-element'; // event handling /////// function registerEvent(node, event, localEvent, ignoredFilter) { var handler = handlers[localEvent] = function (event) { fire(localEvent, event); }; if (ignoredFilter) { ignoredFilters[localEvent] = ignoredFilter; } handler.$delegate = _minDom.delegate.bind(node, ELEMENT_SELECTOR, event, handler); } function unregisterEvent(node, event, localEvent) { var handler = mouseHandler(localEvent); if (!handler) { return; } _minDom.delegate.unbind(node, event, handler.$delegate); } function registerEvents(svg) { (0, _minDash.forEach)(bindings, function (val, key) { registerEvent(svg, key, val); }); } function unregisterEvents(svg) { (0, _minDash.forEach)(bindings, function (val, key) { unregisterEvent(svg, key, val); }); } eventBus.on('canvas.destroy', function (event) { unregisterEvents(event.svg); }); eventBus.on('canvas.init', function (event) { registerEvents(event.svg); }); // hit box updating //////////////// eventBus.on(['shape.added', 'connection.added'], function (event) { var element = event.element, gfx = event.gfx; eventBus.fire('interactionEvents.createHit', { element: element, gfx: gfx }); }); // Update djs-hit on change. // A low priortity is necessary, because djs-hit of labels has to be updated // after the label bounds have been updated in the renderer. eventBus.on(['shape.changed', 'connection.changed'], LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; eventBus.fire('interactionEvents.updateHit', { element: element, gfx: gfx }); }); eventBus.on('interactionEvents.createHit', LOW_PRIORITY, function (event) { var element = event.element, gfx = event.gfx; self.createDefaultHit(element, gfx); }); eventBus.on('interactionEvents.updateHit', function (event) { var element = event.element, gfx = event.gfx; self.updateDefaultHit(element, gfx); }); // hit styles //////////// var STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-stroke'); var CLICK_STROKE_HIT_STYLE = createHitStyle('djs-hit djs-hit-click-stroke'); var ALL_HIT_STYLE = createHitStyle('djs-hit djs-hit-all'); var HIT_TYPES = { 'all': ALL_HIT_STYLE, 'click-stroke': CLICK_STROKE_HIT_STYLE, 'stroke': STROKE_HIT_STYLE }; function createHitStyle(classNames, attrs) { attrs = (0, _minDash.assign)({ stroke: 'white', strokeWidth: 15 }, attrs || {}); return styles.cls(classNames, ['no-fill', 'no-border'], attrs); } // style helpers /////////////// function applyStyle(hit, type) { var attrs = HIT_TYPES[type]; if (!attrs) { throw new Error('invalid hit type <' + type + '>'); } (0, _tinySvg.attr)(hit, attrs); return hit; } function appendHit(gfx, hit) { (0, _tinySvg.append)(gfx, hit); } // API /** * Remove hints on the given graphics. * * @param {SVGElement} gfx */ this.removeHits = function (gfx) { var hits = (0, _minDom.queryAll)('.djs-hit', gfx); (0, _minDash.forEach)(hits, _tinySvg.remove); }; /** * Create default hit for the given element. * * @param {djs.model.Base} element * @param {SVGElement} gfx * * @return {SVGElement} created hit */ this.createDefaultHit = function (element, gfx) { var waypoints = element.waypoints, isFrame = element.isFrame, boxType; if (waypoints) { return this.createWaypointsHit(gfx, waypoints); } else { boxType = isFrame ? 'stroke' : 'all'; return this.createBoxHit(gfx, boxType, { width: element.width, height: element.height }); } }; /** * Create hits for the given waypoints. * * @param {SVGElement} gfx * @param {Array<Point>} waypoints * * @return {SVGElement} */ this.createWaypointsHit = function (gfx, waypoints) { var hit = (0, _RenderUtil.createLine)(waypoints); applyStyle(hit, 'stroke'); appendHit(gfx, hit); return hit; }; /** * Create hits for a box. * * @param {SVGElement} gfx * @param {String} hitType * @param {Object} attrs * * @return {SVGElement} */ this.createBoxHit = function (gfx, type, attrs) { attrs = (0, _minDash.assign)({ x: 0, y: 0 }, attrs); var hit = (0, _tinySvg.create)('rect'); applyStyle(hit, type); (0, _tinySvg.attr)(hit, attrs); appendHit(gfx, hit); return hit; }; /** * Update default hit of the element. * * @param {djs.model.Base} element * @param {SVGElement} gfx * * @return {SVGElement} updated hit */ this.updateDefaultHit = function (element, gfx) { var hit = (0, _minDom.query)('.djs-hit', gfx); if (!hit) { return; } if (element.waypoints) { (0, _RenderUtil.updateLine)(hit, element.waypoints); } else { (0, _tinySvg.attr)(hit, { width: element.width, height: element.height }); } return hit; }; this.fire = fire; this.triggerMouseEvent = triggerMouseEvent; this.mouseHandler = mouseHandler; this.registerEvent = registerEvent; this.unregisterEvent = unregisterEvent; } InteractionEvents.$inject = ['eventBus', 'elementRegistry', 'styles']; /** * An event indicating that the mouse hovered over an element * * @event element.hover * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has left an element * * @event element.out * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has clicked an element * * @event element.click * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has double clicked an element * * @event element.dblclick * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has gone down on an element. * * @event element.mousedown * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the mouse has gone up on an element. * * @event element.mouseup * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ /** * An event indicating that the context menu action is triggered * via mouse or touch controls. * * @event element.contextmenu * * @type {Object} * @property {djs.model.Base} element * @property {SVGElement} gfx * @property {Event} originalEvent */ },{"../../util/Mouse":341,"../../util/RenderUtil":343,"min-dash":555,"min-dom":556,"tiny-svg":567}],336:[function(require,module,exports){ arguments[4][211][0].apply(exports,arguments) },{"./InteractionEvents":335,"dup":211}],337:[function(require,module,exports){ arguments[4][296][0].apply(exports,arguments) },{"./translate":338,"dup":296}],338:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = translate; /** * A simple translation stub to be used for multi-language support * in diagrams. Can be easily replaced with a more sophisticated * solution. * * @example * * // use it inside any diagram component by injecting `translate`. * * function MyService(translate) { * alert(translate('HELLO {you}', { you: 'You!' })); * } * * @param {String} template to interpolate * @param {Object} [replacements] a map with substitutes * * @return {String} the translated string */ function translate(template, replacements) { replacements = replacements || {}; return template.replace(/{([^}]+)}/g, function (_, key) { return replacements[key] || '{' + key + '}'; }); } },{}],339:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.remove = remove; exports.add = add; exports.indexOf = indexOf; /** * Failsafe remove an element from a collection * * @param {Array<Object>} [collection] * @param {Object} [element] * * @return {Number} the previous index of the element */ function remove(collection, element) { if (!collection || !element) { return -1; } var idx = collection.indexOf(element); if (idx !== -1) { collection.splice(idx, 1); } return idx; } /** * Fail save add an element to the given connection, ensuring * it does not yet exist. * * @param {Array<Object>} collection * @param {Object} element * @param {Number} idx */ function add(collection, element, idx) { if (!collection || !element) { return; } if (typeof idx !== 'number') { idx = -1; } var currentIdx = collection.indexOf(element); if (currentIdx !== -1) { if (currentIdx === idx) { // nothing to do, position has not changed return; } else { if (idx !== -1) { // remove from current position collection.splice(currentIdx, 1); } else { // already exists in collection return; } } } if (idx !== -1) { // insert at specified position collection.splice(idx, 0, element); } else { // push to end collection.push(element); } } /** * Fail save get the index of an element in a collection. * * @param {Array<Object>} collection * @param {Object} element * * @return {Number} the index or -1 if collection or element do * not exist or the element is not contained. */ function indexOf(collection, element) { if (!collection || !element) { return -1; } return collection.indexOf(element); } },{}],340:[function(require,module,exports){ arguments[4][317][0].apply(exports,arguments) },{"dup":317}],341:[function(require,module,exports){ arguments[4][323][0].apply(exports,arguments) },{"./Event":340,"./Platform":342,"dup":323}],342:[function(require,module,exports){ arguments[4][324][0].apply(exports,arguments) },{"dup":324}],343:[function(require,module,exports){ arguments[4][327][0].apply(exports,arguments) },{"dup":327,"tiny-svg":567}],344:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.annotate = annotate; exports.Module = Module; exports.Injector = Injector; var CLASS_PATTERN = /^class /; function isClass(fn) { return CLASS_PATTERN.test(fn.toString()); } function isArray(obj) { return Object.prototype.toString.call(obj) === '[object Array]'; } function annotate() { var args = Array.prototype.slice.call(arguments); if (args.length === 1 && isArray(args[0])) { args = args[0]; } var fn = args.pop(); fn.$inject = args; return fn; } // Current limitations: // - can't put into "function arg" comments // function /* (no parenthesis like this) */ (){} // function abc( /* xx (no parenthesis like this) */ a, b) {} // // Just put the comment before function or inside: // /* (((this is fine))) */ function(a, b) {} // function abc(a) { /* (((this is fine))) */} // // - can't reliably auto-annotate constructor; we'll match the // first constructor(...) pattern found which may be the one // of a nested class, too. var CONSTRUCTOR_ARGS = /constructor\s*[^(]*\(\s*([^)]*)\)/m; var FN_ARGS = /^function\s*[^(]*\(\s*([^)]*)\)/m; var FN_ARG = /\/\*([^*]*)\*\//m; function parse(fn) { if (typeof fn !== 'function') { throw new Error('Cannot annotate "' + fn + '". Expected a function!'); } var match = fn.toString().match(isClass(fn) ? CONSTRUCTOR_ARGS : FN_ARGS); // may parse class without constructor if (!match) { return []; } return match[1] && match[1].split(',').map(function (arg) { match = arg.match(FN_ARG); return match ? match[1].trim() : arg.trim(); }) || []; } function Module() { var providers = []; this.factory = function (name, factory) { providers.push([name, 'factory', factory]); return this; }; this.value = function (name, value) { providers.push([name, 'value', value]); return this; }; this.type = function (name, type) { providers.push([name, 'type', type]); return this; }; this.forEach = function (iterator) { providers.forEach(iterator); }; } var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } function Injector(modules, parent) { parent = parent || { get: function get(name, strict) { currentlyResolving.push(name); if (strict === false) { return null; } else { throw error('No provider for "' + name + '"!'); } } }; var currentlyResolving = []; var providers = this._providers = Object.create(parent._providers || null); var instances = this._instances = Object.create(null); var self = instances.injector = this; var error = function error(msg) { var stack = currentlyResolving.join(' -> '); currentlyResolving.length = 0; return new Error(stack ? msg + ' (Resolving: ' + stack + ')' : msg); }; /** * Return a named service. * * @param {String} name * @param {Boolean} [strict=true] if false, resolve missing services to null * * @return {Object} */ var get = function get(name, strict) { if (!providers[name] && name.indexOf('.') !== -1) { var parts = name.split('.'); var pivot = get(parts.shift()); while (parts.length) { pivot = pivot[parts.shift()]; } return pivot; } if (hasProp(instances, name)) { return instances[name]; } if (hasProp(providers, name)) { if (currentlyResolving.indexOf(name) !== -1) { currentlyResolving.push(name); throw error('Cannot resolve circular dependency!'); } currentlyResolving.push(name); instances[name] = providers[name][0](providers[name][1]); currentlyResolving.pop(); return instances[name]; } return parent.get(name, strict); }; var fnDef = function fnDef(fn) { var locals = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (typeof fn !== 'function') { if (isArray(fn)) { fn = annotate(fn.slice()); } else { throw new Error('Cannot invoke "' + fn + '". Expected a function!'); } } var inject = fn.$inject || parse(fn); var dependencies = inject.map(function (dep) { if (hasProp(locals, dep)) { return locals[dep]; } else { return get(dep); } }); return { fn: fn, dependencies: dependencies }; }; var instantiate = function instantiate(Type) { var _fnDef = fnDef(Type), dependencies = _fnDef.dependencies, fn = _fnDef.fn; return new (Function.prototype.bind.apply(fn, [null].concat(_toConsumableArray(dependencies))))(); }; var invoke = function invoke(func, context, locals) { var _fnDef2 = fnDef(func, locals), dependencies = _fnDef2.dependencies, fn = _fnDef2.fn; return fn.call.apply(fn, [context].concat(_toConsumableArray(dependencies))); }; var createPrivateInjectorFactory = function createPrivateInjectorFactory(privateChildInjector) { return annotate(function (key) { return privateChildInjector.get(key); }); }; var createChild = function createChild(modules, forceNewInstances) { if (forceNewInstances && forceNewInstances.length) { var fromParentModule = Object.create(null); var matchedScopes = Object.create(null); var privateInjectorsCache = []; var privateChildInjectors = []; var privateChildFactories = []; var provider; var cacheIdx; var privateChildInjector; var privateChildInjectorFactory; for (var name in providers) { provider = providers[name]; if (forceNewInstances.indexOf(name) !== -1) { if (provider[2] === 'private') { cacheIdx = privateInjectorsCache.indexOf(provider[3]); if (cacheIdx === -1) { privateChildInjector = provider[3].createChild([], forceNewInstances); privateChildInjectorFactory = createPrivateInjectorFactory(privateChildInjector); privateInjectorsCache.push(provider[3]); privateChildInjectors.push(privateChildInjector); privateChildFactories.push(privateChildInjectorFactory); fromParentModule[name] = [privateChildInjectorFactory, name, 'private', privateChildInjector]; } else { fromParentModule[name] = [privateChildFactories[cacheIdx], name, 'private', privateChildInjectors[cacheIdx]]; } } else { fromParentModule[name] = [provider[2], provider[1]]; } matchedScopes[name] = true; } if ((provider[2] === 'factory' || provider[2] === 'type') && provider[1].$scope) { /* jshint -W083 */ forceNewInstances.forEach(function (scope) { if (provider[1].$scope.indexOf(scope) !== -1) { fromParentModule[name] = [provider[2], provider[1]]; matchedScopes[scope] = true; } }); } } forceNewInstances.forEach(function (scope) { if (!matchedScopes[scope]) { throw new Error('No provider for "' + scope + '". Cannot use provider from the parent!'); } }); modules.unshift(fromParentModule); } return new Injector(modules, self); }; var factoryMap = { factory: invoke, type: instantiate, value: function value(_value) { return _value; } }; modules.forEach(function (module) { function arrayUnwrap(type, value) { if (type !== 'value' && isArray(value)) { value = annotate(value.slice()); } return value; } // TODO(vojta): handle wrong inputs (modules) if (module instanceof Module) { module.forEach(function (provider) { var name = provider[0]; var type = provider[1]; var value = provider[2]; providers[name] = [factoryMap[type], arrayUnwrap(type, value), type]; }); } else if ((typeof module === 'undefined' ? 'undefined' : _typeof(module)) === 'object') { if (module.__exports__) { var clonedModule = Object.keys(module).reduce(function (m, key) { if (key.substring(0, 2) !== '__') { m[key] = module[key]; } return m; }, Object.create(null)); var privateInjector = new Injector((module.__modules__ || []).concat([clonedModule]), self); var getFromPrivateInjector = annotate(function (key) { return privateInjector.get(key); }); module.__exports__.forEach(function (key) { providers[key] = [getFromPrivateInjector, key, 'private', privateInjector]; }); } else { Object.keys(module).forEach(function (name) { if (module[name][2] === 'private') { providers[name] = module[name]; return; } var type = module[name][0]; var value = module[name][1]; providers[name] = [factoryMap[type], arrayUnwrap(type, value), type]; }); } } }); // public API this.get = get; this.invoke = invoke; this.instantiate = instantiate; this.createChild = createChild; } // helpers ///////////////// function hasProp(obj, prop) { return Object.hasOwnProperty.call(obj, prop); } },{}],345:[function(require,module,exports){ /*! Hammer.JS - v2.0.7 - 2016-04-22 * http://hammerjs.github.io/ * * Copyright (c) 2016 Jorik Tangelder; * Licensed under the MIT license */ (function(window, document, exportName, undefined) { 'use strict'; var VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o']; var TEST_ELEMENT = document.createElement('div'); var TYPE_FUNCTION = 'function'; var round = Math.round; var abs = Math.abs; var now = Date.now; /** * set a timeout with a given scope * @param {Function} fn * @param {Number} timeout * @param {Object} context * @returns {number} */ function setTimeoutContext(fn, timeout, context) { return setTimeout(bindFn(fn, context), timeout); } /** * if the argument is an array, we want to execute the fn on each entry * if it aint an array we don't want to do a thing. * this is used by all the methods that accept a single and array argument. * @param {*|Array} arg * @param {String} fn * @param {Object} [context] * @returns {Boolean} */ function invokeArrayArg(arg, fn, context) { if (Array.isArray(arg)) { each(arg, context[fn], context); return true; } return false; } /** * walk objects and arrays * @param {Object} obj * @param {Function} iterator * @param {Object} context */ function each(obj, iterator, context) { var i; if (!obj) { return; } if (obj.forEach) { obj.forEach(iterator, context); } else if (obj.length !== undefined) { i = 0; while (i < obj.length) { iterator.call(context, obj[i], i, obj); i++; } } else { for (i in obj) { obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj); } } } /** * wrap a method with a deprecation warning and stack trace * @param {Function} method * @param {String} name * @param {String} message * @returns {Function} A new function wrapping the supplied method. */ function deprecate(method, name, message) { var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\n' + message + ' AT \n'; return function() { var e = new Error('get-stack-trace'); var stack = e && e.stack ? e.stack.replace(/^[^\(]+?[\n$]/gm, '') .replace(/^\s+at\s+/gm, '') .replace(/^Object.<anonymous>\s*\(/gm, '{anonymous}()@') : 'Unknown Stack Trace'; var log = window.console && (window.console.warn || window.console.log); if (log) { log.call(window.console, deprecationMessage, stack); } return method.apply(this, arguments); }; } /** * extend object. * means that properties in dest will be overwritten by the ones in src. * @param {Object} target * @param {...Object} objects_to_assign * @returns {Object} target */ var assign; if (typeof Object.assign !== 'function') { assign = function assign(target) { if (target === undefined || target === null) { throw new TypeError('Cannot convert undefined or null to object'); } var output = Object(target); for (var index = 1; index < arguments.length; index++) { var source = arguments[index]; if (source !== undefined && source !== null) { for (var nextKey in source) { if (source.hasOwnProperty(nextKey)) { output[nextKey] = source[nextKey]; } } } } return output; }; } else { assign = Object.assign; } /** * extend object. * means that properties in dest will be overwritten by the ones in src. * @param {Object} dest * @param {Object} src * @param {Boolean} [merge=false] * @returns {Object} dest */ var extend = deprecate(function extend(dest, src, merge) { var keys = Object.keys(src); var i = 0; while (i < keys.length) { if (!merge || (merge && dest[keys[i]] === undefined)) { dest[keys[i]] = src[keys[i]]; } i++; } return dest; }, 'extend', 'Use `assign`.'); /** * merge the values from src in the dest. * means that properties that exist in dest will not be overwritten by src * @param {Object} dest * @param {Object} src * @returns {Object} dest */ var merge = deprecate(function merge(dest, src) { return extend(dest, src, true); }, 'merge', 'Use `assign`.'); /** * simple class inheritance * @param {Function} child * @param {Function} base * @param {Object} [properties] */ function inherit(child, base, properties) { var baseP = base.prototype, childP; childP = child.prototype = Object.create(baseP); childP.constructor = child; childP._super = baseP; if (properties) { assign(childP, properties); } } /** * simple function bind * @param {Function} fn * @param {Object} context * @returns {Function} */ function bindFn(fn, context) { return function boundFn() { return fn.apply(context, arguments); }; } /** * let a boolean value also be a function that must return a boolean * this first item in args will be used as the context * @param {Boolean|Function} val * @param {Array} [args] * @returns {Boolean} */ function boolOrFn(val, args) { if (typeof val == TYPE_FUNCTION) { return val.apply(args ? args[0] || undefined : undefined, args); } return val; } /** * use the val2 when val1 is undefined * @param {*} val1 * @param {*} val2 * @returns {*} */ function ifUndefined(val1, val2) { return (val1 === undefined) ? val2 : val1; } /** * addEventListener with multiple events at once * @param {EventTarget} target * @param {String} types * @param {Function} handler */ function addEventListeners(target, types, handler) { each(splitStr(types), function(type) { target.addEventListener(type, handler, false); }); } /** * removeEventListener with multiple events at once * @param {EventTarget} target * @param {String} types * @param {Function} handler */ function removeEventListeners(target, types, handler) { each(splitStr(types), function(type) { target.removeEventListener(type, handler, false); }); } /** * find if a node is in the given parent * @method hasParent * @param {HTMLElement} node * @param {HTMLElement} parent * @return {Boolean} found */ function hasParent(node, parent) { while (node) { if (node == parent) { return true; } node = node.parentNode; } return false; } /** * small indexOf wrapper * @param {String} str * @param {String} find * @returns {Boolean} found */ function inStr(str, find) { return str.indexOf(find) > -1; } /** * split string on whitespace * @param {String} str * @returns {Array} words */ function splitStr(str) { return str.trim().split(/\s+/g); } /** * find if a array contains the object using indexOf or a simple polyFill * @param {Array} src * @param {String} find * @param {String} [findByKey] * @return {Boolean|Number} false when not found, or the index */ function inArray(src, find, findByKey) { if (src.indexOf && !findByKey) { return src.indexOf(find); } else { var i = 0; while (i < src.length) { if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) { return i; } i++; } return -1; } } /** * convert array-like objects to real arrays * @param {Object} obj * @returns {Array} */ function toArray(obj) { return Array.prototype.slice.call(obj, 0); } /** * unique array with objects based on a key (like 'id') or just by the array's value * @param {Array} src [{id:1},{id:2},{id:1}] * @param {String} [key] * @param {Boolean} [sort=False] * @returns {Array} [{id:1},{id:2}] */ function uniqueArray(src, key, sort) { var results = []; var values = []; var i = 0; while (i < src.length) { var val = key ? src[i][key] : src[i]; if (inArray(values, val) < 0) { results.push(src[i]); } values[i] = val; i++; } if (sort) { if (!key) { results = results.sort(); } else { results = results.sort(function sortUniqueArray(a, b) { return a[key] > b[key]; }); } } return results; } /** * get the prefixed property * @param {Object} obj * @param {String} property * @returns {String|Undefined} prefixed */ function prefixed(obj, property) { var prefix, prop; var camelProp = property[0].toUpperCase() + property.slice(1); var i = 0; while (i < VENDOR_PREFIXES.length) { prefix = VENDOR_PREFIXES[i]; prop = (prefix) ? prefix + camelProp : property; if (prop in obj) { return prop; } i++; } return undefined; } /** * get a unique id * @returns {number} uniqueId */ var _uniqueId = 1; function uniqueId() { return _uniqueId++; } /** * get the window object of an element * @param {HTMLElement} element * @returns {DocumentView|Window} */ function getWindowForElement(element) { var doc = element.ownerDocument || element; return (doc.defaultView || doc.parentWindow || window); } var MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i; var SUPPORT_TOUCH = ('ontouchstart' in window); var SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined; var SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent); var INPUT_TYPE_TOUCH = 'touch'; var INPUT_TYPE_PEN = 'pen'; var INPUT_TYPE_MOUSE = 'mouse'; var INPUT_TYPE_KINECT = 'kinect'; var COMPUTE_INTERVAL = 25; var INPUT_START = 1; var INPUT_MOVE = 2; var INPUT_END = 4; var INPUT_CANCEL = 8; var DIRECTION_NONE = 1; var DIRECTION_LEFT = 2; var DIRECTION_RIGHT = 4; var DIRECTION_UP = 8; var DIRECTION_DOWN = 16; var DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT; var DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN; var DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL; var PROPS_XY = ['x', 'y']; var PROPS_CLIENT_XY = ['clientX', 'clientY']; /** * create new input type manager * @param {Manager} manager * @param {Function} callback * @returns {Input} * @constructor */ function Input(manager, callback) { var self = this; this.manager = manager; this.callback = callback; this.element = manager.element; this.target = manager.options.inputTarget; // smaller wrapper around the handler, for the scope and the enabled state of the manager, // so when disabled the input events are completely bypassed. this.domHandler = function(ev) { if (boolOrFn(manager.options.enable, [manager])) { self.handler(ev); } }; this.init(); } Input.prototype = { /** * should handle the inputEvent data and trigger the callback * @virtual */ handler: function() { }, /** * bind the events */ init: function() { this.evEl && addEventListeners(this.element, this.evEl, this.domHandler); this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler); this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); }, /** * unbind the events */ destroy: function() { this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler); this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler); this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler); } }; /** * create new input type manager * called by the Manager constructor * @param {Hammer} manager * @returns {Input} */ function createInputInstance(manager) { var Type; var inputClass = manager.options.inputClass; if (inputClass) { Type = inputClass; } else if (SUPPORT_POINTER_EVENTS) { Type = PointerEventInput; } else if (SUPPORT_ONLY_TOUCH) { Type = TouchInput; } else if (!SUPPORT_TOUCH) { Type = MouseInput; } else { Type = TouchMouseInput; } return new (Type)(manager, inputHandler); } /** * handle input events * @param {Manager} manager * @param {String} eventType * @param {Object} input */ function inputHandler(manager, eventType, input) { var pointersLen = input.pointers.length; var changedPointersLen = input.changedPointers.length; var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0)); var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0)); input.isFirst = !!isFirst; input.isFinal = !!isFinal; if (isFirst) { manager.session = {}; } // source event is the normalized value of the domEvents // like 'touchstart, mouseup, pointerdown' input.eventType = eventType; // compute scale, rotation etc computeInputData(manager, input); // emit secret event manager.emit('hammer.input', input); manager.recognize(input); manager.session.prevInput = input; } /** * extend the data with some usable properties like scale, rotate, velocity etc * @param {Object} manager * @param {Object} input */ function computeInputData(manager, input) { var session = manager.session; var pointers = input.pointers; var pointersLength = pointers.length; // store the first input to calculate the distance and direction if (!session.firstInput) { session.firstInput = simpleCloneInputData(input); } // to compute scale and rotation we need to store the multiple touches if (pointersLength > 1 && !session.firstMultiple) { session.firstMultiple = simpleCloneInputData(input); } else if (pointersLength === 1) { session.firstMultiple = false; } var firstInput = session.firstInput; var firstMultiple = session.firstMultiple; var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center; var center = input.center = getCenter(pointers); input.timeStamp = now(); input.deltaTime = input.timeStamp - firstInput.timeStamp; input.angle = getAngle(offsetCenter, center); input.distance = getDistance(offsetCenter, center); computeDeltaXY(session, input); input.offsetDirection = getDirection(input.deltaX, input.deltaY); var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY); input.overallVelocityX = overallVelocity.x; input.overallVelocityY = overallVelocity.y; input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y; input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1; input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0; input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length > session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers); computeIntervalInputData(session, input); // find the correct target var target = manager.element; if (hasParent(input.srcEvent.target, target)) { target = input.srcEvent.target; } input.target = target; } function computeDeltaXY(session, input) { var center = input.center; var offset = session.offsetDelta || {}; var prevDelta = session.prevDelta || {}; var prevInput = session.prevInput || {}; if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) { prevDelta = session.prevDelta = { x: prevInput.deltaX || 0, y: prevInput.deltaY || 0 }; offset = session.offsetDelta = { x: center.x, y: center.y }; } input.deltaX = prevDelta.x + (center.x - offset.x); input.deltaY = prevDelta.y + (center.y - offset.y); } /** * velocity is calculated every x ms * @param {Object} session * @param {Object} input */ function computeIntervalInputData(session, input) { var last = session.lastInterval || input, deltaTime = input.timeStamp - last.timeStamp, velocity, velocityX, velocityY, direction; if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) { var deltaX = input.deltaX - last.deltaX; var deltaY = input.deltaY - last.deltaY; var v = getVelocity(deltaTime, deltaX, deltaY); velocityX = v.x; velocityY = v.y; velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y; direction = getDirection(deltaX, deltaY); session.lastInterval = input; } else { // use latest velocity info if it doesn't overtake a minimum period velocity = last.velocity; velocityX = last.velocityX; velocityY = last.velocityY; direction = last.direction; } input.velocity = velocity; input.velocityX = velocityX; input.velocityY = velocityY; input.direction = direction; } /** * create a simple clone from the input used for storage of firstInput and firstMultiple * @param {Object} input * @returns {Object} clonedInputData */ function simpleCloneInputData(input) { // make a simple copy of the pointers because we will get a reference if we don't // we only need clientXY for the calculations var pointers = []; var i = 0; while (i < input.pointers.length) { pointers[i] = { clientX: round(input.pointers[i].clientX), clientY: round(input.pointers[i].clientY) }; i++; } return { timeStamp: now(), pointers: pointers, center: getCenter(pointers), deltaX: input.deltaX, deltaY: input.deltaY }; } /** * get the center of all the pointers * @param {Array} pointers * @return {Object} center contains `x` and `y` properties */ function getCenter(pointers) { var pointersLength = pointers.length; // no need to loop when only one touch if (pointersLength === 1) { return { x: round(pointers[0].clientX), y: round(pointers[0].clientY) }; } var x = 0, y = 0, i = 0; while (i < pointersLength) { x += pointers[i].clientX; y += pointers[i].clientY; i++; } return { x: round(x / pointersLength), y: round(y / pointersLength) }; } /** * calculate the velocity between two points. unit is in px per ms. * @param {Number} deltaTime * @param {Number} x * @param {Number} y * @return {Object} velocity `x` and `y` */ function getVelocity(deltaTime, x, y) { return { x: x / deltaTime || 0, y: y / deltaTime || 0 }; } /** * get the direction between two points * @param {Number} x * @param {Number} y * @return {Number} direction */ function getDirection(x, y) { if (x === y) { return DIRECTION_NONE; } if (abs(x) >= abs(y)) { return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT; } return y < 0 ? DIRECTION_UP : DIRECTION_DOWN; } /** * calculate the absolute distance between two points * @param {Object} p1 {x, y} * @param {Object} p2 {x, y} * @param {Array} [props] containing x and y keys * @return {Number} distance */ function getDistance(p1, p2, props) { if (!props) { props = PROPS_XY; } var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]]; return Math.sqrt((x * x) + (y * y)); } /** * calculate the angle between two coordinates * @param {Object} p1 * @param {Object} p2 * @param {Array} [props] containing x and y keys * @return {Number} angle */ function getAngle(p1, p2, props) { if (!props) { props = PROPS_XY; } var x = p2[props[0]] - p1[props[0]], y = p2[props[1]] - p1[props[1]]; return Math.atan2(y, x) * 180 / Math.PI; } /** * calculate the rotation degrees between two pointersets * @param {Array} start array of pointers * @param {Array} end array of pointers * @return {Number} rotation */ function getRotation(start, end) { return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY); } /** * calculate the scale factor between two pointersets * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out * @param {Array} start array of pointers * @param {Array} end array of pointers * @return {Number} scale */ function getScale(start, end) { return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY); } var MOUSE_INPUT_MAP = { mousedown: INPUT_START, mousemove: INPUT_MOVE, mouseup: INPUT_END }; var MOUSE_ELEMENT_EVENTS = 'mousedown'; var MOUSE_WINDOW_EVENTS = 'mousemove mouseup'; /** * Mouse events input * @constructor * @extends Input */ function MouseInput() { this.evEl = MOUSE_ELEMENT_EVENTS; this.evWin = MOUSE_WINDOW_EVENTS; this.pressed = false; // mousedown state Input.apply(this, arguments); } inherit(MouseInput, Input, { /** * handle mouse events * @param {Object} ev */ handler: function MEhandler(ev) { var eventType = MOUSE_INPUT_MAP[ev.type]; // on start we want to have the left mouse button down if (eventType & INPUT_START && ev.button === 0) { this.pressed = true; } if (eventType & INPUT_MOVE && ev.which !== 1) { eventType = INPUT_END; } // mouse must be down if (!this.pressed) { return; } if (eventType & INPUT_END) { this.pressed = false; } this.callback(this.manager, eventType, { pointers: [ev], changedPointers: [ev], pointerType: INPUT_TYPE_MOUSE, srcEvent: ev }); } }); var POINTER_INPUT_MAP = { pointerdown: INPUT_START, pointermove: INPUT_MOVE, pointerup: INPUT_END, pointercancel: INPUT_CANCEL, pointerout: INPUT_CANCEL }; // in IE10 the pointer types is defined as an enum var IE10_POINTER_TYPE_ENUM = { 2: INPUT_TYPE_TOUCH, 3: INPUT_TYPE_PEN, 4: INPUT_TYPE_MOUSE, 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816 }; var POINTER_ELEMENT_EVENTS = 'pointerdown'; var POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel'; // IE10 has prefixed support, and case-sensitive if (window.MSPointerEvent && !window.PointerEvent) { POINTER_ELEMENT_EVENTS = 'MSPointerDown'; POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel'; } /** * Pointer events input * @constructor * @extends Input */ function PointerEventInput() { this.evEl = POINTER_ELEMENT_EVENTS; this.evWin = POINTER_WINDOW_EVENTS; Input.apply(this, arguments); this.store = (this.manager.session.pointerEvents = []); } inherit(PointerEventInput, Input, { /** * handle mouse events * @param {Object} ev */ handler: function PEhandler(ev) { var store = this.store; var removePointer = false; var eventTypeNormalized = ev.type.toLowerCase().replace('ms', ''); var eventType = POINTER_INPUT_MAP[eventTypeNormalized]; var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType; var isTouch = (pointerType == INPUT_TYPE_TOUCH); // get index of the event in the store var storeIndex = inArray(store, ev.pointerId, 'pointerId'); // start and mouse must be down if (eventType & INPUT_START && (ev.button === 0 || isTouch)) { if (storeIndex < 0) { store.push(ev); storeIndex = store.length - 1; } } else if (eventType & (INPUT_END | INPUT_CANCEL)) { removePointer = true; } // it not found, so the pointer hasn't been down (so it's probably a hover) if (storeIndex < 0) { return; } // update the event in the store store[storeIndex] = ev; this.callback(this.manager, eventType, { pointers: store, changedPointers: [ev], pointerType: pointerType, srcEvent: ev }); if (removePointer) { // remove from the store store.splice(storeIndex, 1); } } }); var SINGLE_TOUCH_INPUT_MAP = { touchstart: INPUT_START, touchmove: INPUT_MOVE, touchend: INPUT_END, touchcancel: INPUT_CANCEL }; var SINGLE_TOUCH_TARGET_EVENTS = 'touchstart'; var SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel'; /** * Touch events input * @constructor * @extends Input */ function SingleTouchInput() { this.evTarget = SINGLE_TOUCH_TARGET_EVENTS; this.evWin = SINGLE_TOUCH_WINDOW_EVENTS; this.started = false; Input.apply(this, arguments); } inherit(SingleTouchInput, Input, { handler: function TEhandler(ev) { var type = SINGLE_TOUCH_INPUT_MAP[ev.type]; // should we handle the touch events? if (type === INPUT_START) { this.started = true; } if (!this.started) { return; } var touches = normalizeSingleTouches.call(this, ev, type); // when done, reset the started state if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) { this.started = false; } this.callback(this.manager, type, { pointers: touches[0], changedPointers: touches[1], pointerType: INPUT_TYPE_TOUCH, srcEvent: ev }); } }); /** * @this {TouchInput} * @param {Object} ev * @param {Number} type flag * @returns {undefined|Array} [all, changed] */ function normalizeSingleTouches(ev, type) { var all = toArray(ev.touches); var changed = toArray(ev.changedTouches); if (type & (INPUT_END | INPUT_CANCEL)) { all = uniqueArray(all.concat(changed), 'identifier', true); } return [all, changed]; } var TOUCH_INPUT_MAP = { touchstart: INPUT_START, touchmove: INPUT_MOVE, touchend: INPUT_END, touchcancel: INPUT_CANCEL }; var TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel'; /** * Multi-user touch events input * @constructor * @extends Input */ function TouchInput() { this.evTarget = TOUCH_TARGET_EVENTS; this.targetIds = {}; Input.apply(this, arguments); } inherit(TouchInput, Input, { handler: function MTEhandler(ev) { var type = TOUCH_INPUT_MAP[ev.type]; var touches = getTouches.call(this, ev, type); if (!touches) { return; } this.callback(this.manager, type, { pointers: touches[0], changedPointers: touches[1], pointerType: INPUT_TYPE_TOUCH, srcEvent: ev }); } }); /** * @this {TouchInput} * @param {Object} ev * @param {Number} type flag * @returns {undefined|Array} [all, changed] */ function getTouches(ev, type) { var allTouches = toArray(ev.touches); var targetIds = this.targetIds; // when there is only one touch, the process can be simplified if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) { targetIds[allTouches[0].identifier] = true; return [allTouches, allTouches]; } var i, targetTouches, changedTouches = toArray(ev.changedTouches), changedTargetTouches = [], target = this.target; // get target touches from touches targetTouches = allTouches.filter(function(touch) { return hasParent(touch.target, target); }); // collect touches if (type === INPUT_START) { i = 0; while (i < targetTouches.length) { targetIds[targetTouches[i].identifier] = true; i++; } } // filter changed touches to only contain touches that exist in the collected target ids i = 0; while (i < changedTouches.length) { if (targetIds[changedTouches[i].identifier]) { changedTargetTouches.push(changedTouches[i]); } // cleanup removed touches if (type & (INPUT_END | INPUT_CANCEL)) { delete targetIds[changedTouches[i].identifier]; } i++; } if (!changedTargetTouches.length) { return; } return [ // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel' uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true), changedTargetTouches ]; } /** * Combined touch and mouse input * * Touch has a higher priority then mouse, and while touching no mouse events are allowed. * This because touch devices also emit mouse events while doing a touch. * * @constructor * @extends Input */ var DEDUP_TIMEOUT = 2500; var DEDUP_DISTANCE = 25; function TouchMouseInput() { Input.apply(this, arguments); var handler = bindFn(this.handler, this); this.touch = new TouchInput(this.manager, handler); this.mouse = new MouseInput(this.manager, handler); this.primaryTouch = null; this.lastTouches = []; } inherit(TouchMouseInput, Input, { /** * handle mouse and touch events * @param {Hammer} manager * @param {String} inputEvent * @param {Object} inputData */ handler: function TMEhandler(manager, inputEvent, inputData) { var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH), isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE); if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) { return; } // when we're in a touch event, record touches to de-dupe synthetic mouse event if (isTouch) { recordTouches.call(this, inputEvent, inputData); } else if (isMouse && isSyntheticEvent.call(this, inputData)) { return; } this.callback(manager, inputEvent, inputData); }, /** * remove the event listeners */ destroy: function destroy() { this.touch.destroy(); this.mouse.destroy(); } }); function recordTouches(eventType, eventData) { if (eventType & INPUT_START) { this.primaryTouch = eventData.changedPointers[0].identifier; setLastTouch.call(this, eventData); } else if (eventType & (INPUT_END | INPUT_CANCEL)) { setLastTouch.call(this, eventData); } } function setLastTouch(eventData) { var touch = eventData.changedPointers[0]; if (touch.identifier === this.primaryTouch) { var lastTouch = {x: touch.clientX, y: touch.clientY}; this.lastTouches.push(lastTouch); var lts = this.lastTouches; var removeLastTouch = function() { var i = lts.indexOf(lastTouch); if (i > -1) { lts.splice(i, 1); } }; setTimeout(removeLastTouch, DEDUP_TIMEOUT); } } function isSyntheticEvent(eventData) { var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY; for (var i = 0; i < this.lastTouches.length; i++) { var t = this.lastTouches[i]; var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y); if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) { return true; } } return false; } var PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction'); var NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined; // magical touchAction value var TOUCH_ACTION_COMPUTE = 'compute'; var TOUCH_ACTION_AUTO = 'auto'; var TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented var TOUCH_ACTION_NONE = 'none'; var TOUCH_ACTION_PAN_X = 'pan-x'; var TOUCH_ACTION_PAN_Y = 'pan-y'; var TOUCH_ACTION_MAP = getTouchActionProps(); /** * Touch Action * sets the touchAction property or uses the js alternative * @param {Manager} manager * @param {String} value * @constructor */ function TouchAction(manager, value) { this.manager = manager; this.set(value); } TouchAction.prototype = { /** * set the touchAction value on the element or enable the polyfill * @param {String} value */ set: function(value) { // find out the touch-action by the event handlers if (value == TOUCH_ACTION_COMPUTE) { value = this.compute(); } if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) { this.manager.element.style[PREFIXED_TOUCH_ACTION] = value; } this.actions = value.toLowerCase().trim(); }, /** * just re-set the touchAction value */ update: function() { this.set(this.manager.options.touchAction); }, /** * compute the value for the touchAction property based on the recognizer's settings * @returns {String} value */ compute: function() { var actions = []; each(this.manager.recognizers, function(recognizer) { if (boolOrFn(recognizer.options.enable, [recognizer])) { actions = actions.concat(recognizer.getTouchAction()); } }); return cleanTouchActions(actions.join(' ')); }, /** * this method is called on each input cycle and provides the preventing of the browser behavior * @param {Object} input */ preventDefaults: function(input) { var srcEvent = input.srcEvent; var direction = input.offsetDirection; // if the touch action did prevented once this session if (this.manager.session.prevented) { srcEvent.preventDefault(); return; } var actions = this.actions; var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE]; var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y]; var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X]; if (hasNone) { //do not prevent defaults if this is a tap gesture var isTapPointer = input.pointers.length === 1; var isTapMovement = input.distance < 2; var isTapTouchTime = input.deltaTime < 250; if (isTapPointer && isTapMovement && isTapTouchTime) { return; } } if (hasPanX && hasPanY) { // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent return; } if (hasNone || (hasPanY && direction & DIRECTION_HORIZONTAL) || (hasPanX && direction & DIRECTION_VERTICAL)) { return this.preventSrc(srcEvent); } }, /** * call preventDefault to prevent the browser's default behavior (scrolling in most cases) * @param {Object} srcEvent */ preventSrc: function(srcEvent) { this.manager.session.prevented = true; srcEvent.preventDefault(); } }; /** * when the touchActions are collected they are not a valid value, so we need to clean things up. * * @param {String} actions * @returns {*} */ function cleanTouchActions(actions) { // none if (inStr(actions, TOUCH_ACTION_NONE)) { return TOUCH_ACTION_NONE; } var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X); var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y); // if both pan-x and pan-y are set (different recognizers // for different directions, e.g. horizontal pan but vertical swipe?) // we need none (as otherwise with pan-x pan-y combined none of these // recognizers will work, since the browser would handle all panning if (hasPanX && hasPanY) { return TOUCH_ACTION_NONE; } // pan-x OR pan-y if (hasPanX || hasPanY) { return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y; } // manipulation if (inStr(actions, TOUCH_ACTION_MANIPULATION)) { return TOUCH_ACTION_MANIPULATION; } return TOUCH_ACTION_AUTO; } function getTouchActionProps() { if (!NATIVE_TOUCH_ACTION) { return false; } var touchMap = {}; var cssSupports = window.CSS && window.CSS.supports; ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function(val) { // If css.supports is not supported but there is native touch-action assume it supports // all values. This is the case for IE 10 and 11. touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true; }); return touchMap; } /** * Recognizer flow explained; * * All recognizers have the initial state of POSSIBLE when a input session starts. * The definition of a input session is from the first input until the last input, with all it's movement in it. * * Example session for mouse-input: mousedown -> mousemove -> mouseup * * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed * which determines with state it should be. * * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to * POSSIBLE to give it another change on the next cycle. * * Possible * | * +-----+---------------+ * | | * +-----+-----+ | * | | | * Failed Cancelled | * +-------+------+ * | | * Recognized Began * | * Changed * | * Ended/Recognized */ var STATE_POSSIBLE = 1; var STATE_BEGAN = 2; var STATE_CHANGED = 4; var STATE_ENDED = 8; var STATE_RECOGNIZED = STATE_ENDED; var STATE_CANCELLED = 16; var STATE_FAILED = 32; /** * Recognizer * Every recognizer needs to extend from this class. * @constructor * @param {Object} options */ function Recognizer(options) { this.options = assign({}, this.defaults, options || {}); this.id = uniqueId(); this.manager = null; // default is enable true this.options.enable = ifUndefined(this.options.enable, true); this.state = STATE_POSSIBLE; this.simultaneous = {}; this.requireFail = []; } Recognizer.prototype = { /** * @virtual * @type {Object} */ defaults: {}, /** * set options * @param {Object} options * @return {Recognizer} */ set: function(options) { assign(this.options, options); // also update the touchAction, in case something changed about the directions/enabled state this.manager && this.manager.touchAction.update(); return this; }, /** * recognize simultaneous with an other recognizer. * @param {Recognizer} otherRecognizer * @returns {Recognizer} this */ recognizeWith: function(otherRecognizer) { if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) { return this; } var simultaneous = this.simultaneous; otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); if (!simultaneous[otherRecognizer.id]) { simultaneous[otherRecognizer.id] = otherRecognizer; otherRecognizer.recognizeWith(this); } return this; }, /** * drop the simultaneous link. it doesnt remove the link on the other recognizer. * @param {Recognizer} otherRecognizer * @returns {Recognizer} this */ dropRecognizeWith: function(otherRecognizer) { if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) { return this; } otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); delete this.simultaneous[otherRecognizer.id]; return this; }, /** * recognizer can only run when an other is failing * @param {Recognizer} otherRecognizer * @returns {Recognizer} this */ requireFailure: function(otherRecognizer) { if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) { return this; } var requireFail = this.requireFail; otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); if (inArray(requireFail, otherRecognizer) === -1) { requireFail.push(otherRecognizer); otherRecognizer.requireFailure(this); } return this; }, /** * drop the requireFailure link. it does not remove the link on the other recognizer. * @param {Recognizer} otherRecognizer * @returns {Recognizer} this */ dropRequireFailure: function(otherRecognizer) { if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) { return this; } otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this); var index = inArray(this.requireFail, otherRecognizer); if (index > -1) { this.requireFail.splice(index, 1); } return this; }, /** * has require failures boolean * @returns {boolean} */ hasRequireFailures: function() { return this.requireFail.length > 0; }, /** * if the recognizer can recognize simultaneous with an other recognizer * @param {Recognizer} otherRecognizer * @returns {Boolean} */ canRecognizeWith: function(otherRecognizer) { return !!this.simultaneous[otherRecognizer.id]; }, /** * You should use `tryEmit` instead of `emit` directly to check * that all the needed recognizers has failed before emitting. * @param {Object} input */ emit: function(input) { var self = this; var state = this.state; function emit(event) { self.manager.emit(event, input); } // 'panstart' and 'panmove' if (state < STATE_ENDED) { emit(self.options.event + stateStr(state)); } emit(self.options.event); // simple 'eventName' events if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...) emit(input.additionalEvent); } // panend and pancancel if (state >= STATE_ENDED) { emit(self.options.event + stateStr(state)); } }, /** * Check that all the require failure recognizers has failed, * if true, it emits a gesture event, * otherwise, setup the state to FAILED. * @param {Object} input */ tryEmit: function(input) { if (this.canEmit()) { return this.emit(input); } // it's failing anyway this.state = STATE_FAILED; }, /** * can we emit? * @returns {boolean} */ canEmit: function() { var i = 0; while (i < this.requireFail.length) { if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) { return false; } i++; } return true; }, /** * update the recognizer * @param {Object} inputData */ recognize: function(inputData) { // make a new copy of the inputData // so we can change the inputData without messing up the other recognizers var inputDataClone = assign({}, inputData); // is is enabled and allow recognizing? if (!boolOrFn(this.options.enable, [this, inputDataClone])) { this.reset(); this.state = STATE_FAILED; return; } // reset when we've reached the end if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) { this.state = STATE_POSSIBLE; } this.state = this.process(inputDataClone); // the recognizer has recognized a gesture // so trigger an event if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) { this.tryEmit(inputDataClone); } }, /** * return the state of the recognizer * the actual recognizing happens in this method * @virtual * @param {Object} inputData * @returns {Const} STATE */ process: function(inputData) { }, // jshint ignore:line /** * return the preferred touch-action * @virtual * @returns {Array} */ getTouchAction: function() { }, /** * called when the gesture isn't allowed to recognize * like when another is being recognized or it is disabled * @virtual */ reset: function() { } }; /** * get a usable string, used as event postfix * @param {Const} state * @returns {String} state */ function stateStr(state) { if (state & STATE_CANCELLED) { return 'cancel'; } else if (state & STATE_ENDED) { return 'end'; } else if (state & STATE_CHANGED) { return 'move'; } else if (state & STATE_BEGAN) { return 'start'; } return ''; } /** * direction cons to string * @param {Const} direction * @returns {String} */ function directionStr(direction) { if (direction == DIRECTION_DOWN) { return 'down'; } else if (direction == DIRECTION_UP) { return 'up'; } else if (direction == DIRECTION_LEFT) { return 'left'; } else if (direction == DIRECTION_RIGHT) { return 'right'; } return ''; } /** * get a recognizer by name if it is bound to a manager * @param {Recognizer|String} otherRecognizer * @param {Recognizer} recognizer * @returns {Recognizer} */ function getRecognizerByNameIfManager(otherRecognizer, recognizer) { var manager = recognizer.manager; if (manager) { return manager.get(otherRecognizer); } return otherRecognizer; } /** * This recognizer is just used as a base for the simple attribute recognizers. * @constructor * @extends Recognizer */ function AttrRecognizer() { Recognizer.apply(this, arguments); } inherit(AttrRecognizer, Recognizer, { /** * @namespace * @memberof AttrRecognizer */ defaults: { /** * @type {Number} * @default 1 */ pointers: 1 }, /** * Used to check if it the recognizer receives valid input, like input.distance > 10. * @memberof AttrRecognizer * @param {Object} input * @returns {Boolean} recognized */ attrTest: function(input) { var optionPointers = this.options.pointers; return optionPointers === 0 || input.pointers.length === optionPointers; }, /** * Process the input and return the state for the recognizer * @memberof AttrRecognizer * @param {Object} input * @returns {*} State */ process: function(input) { var state = this.state; var eventType = input.eventType; var isRecognized = state & (STATE_BEGAN | STATE_CHANGED); var isValid = this.attrTest(input); // on cancel input and we've recognized before, return STATE_CANCELLED if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) { return state | STATE_CANCELLED; } else if (isRecognized || isValid) { if (eventType & INPUT_END) { return state | STATE_ENDED; } else if (!(state & STATE_BEGAN)) { return STATE_BEGAN; } return state | STATE_CHANGED; } return STATE_FAILED; } }); /** * Pan * Recognized when the pointer is down and moved in the allowed direction. * @constructor * @extends AttrRecognizer */ function PanRecognizer() { AttrRecognizer.apply(this, arguments); this.pX = null; this.pY = null; } inherit(PanRecognizer, AttrRecognizer, { /** * @namespace * @memberof PanRecognizer */ defaults: { event: 'pan', threshold: 10, pointers: 1, direction: DIRECTION_ALL }, getTouchAction: function() { var direction = this.options.direction; var actions = []; if (direction & DIRECTION_HORIZONTAL) { actions.push(TOUCH_ACTION_PAN_Y); } if (direction & DIRECTION_VERTICAL) { actions.push(TOUCH_ACTION_PAN_X); } return actions; }, directionTest: function(input) { var options = this.options; var hasMoved = true; var distance = input.distance; var direction = input.direction; var x = input.deltaX; var y = input.deltaY; // lock to axis? if (!(direction & options.direction)) { if (options.direction & DIRECTION_HORIZONTAL) { direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT; hasMoved = x != this.pX; distance = Math.abs(input.deltaX); } else { direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN; hasMoved = y != this.pY; distance = Math.abs(input.deltaY); } } input.direction = direction; return hasMoved && distance > options.threshold && direction & options.direction; }, attrTest: function(input) { return AttrRecognizer.prototype.attrTest.call(this, input) && (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input))); }, emit: function(input) { this.pX = input.deltaX; this.pY = input.deltaY; var direction = directionStr(input.direction); if (direction) { input.additionalEvent = this.options.event + direction; } this._super.emit.call(this, input); } }); /** * Pinch * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out). * @constructor * @extends AttrRecognizer */ function PinchRecognizer() { AttrRecognizer.apply(this, arguments); } inherit(PinchRecognizer, AttrRecognizer, { /** * @namespace * @memberof PinchRecognizer */ defaults: { event: 'pinch', threshold: 0, pointers: 2 }, getTouchAction: function() { return [TOUCH_ACTION_NONE]; }, attrTest: function(input) { return this._super.attrTest.call(this, input) && (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN); }, emit: function(input) { if (input.scale !== 1) { var inOut = input.scale < 1 ? 'in' : 'out'; input.additionalEvent = this.options.event + inOut; } this._super.emit.call(this, input); } }); /** * Press * Recognized when the pointer is down for x ms without any movement. * @constructor * @extends Recognizer */ function PressRecognizer() { Recognizer.apply(this, arguments); this._timer = null; this._input = null; } inherit(PressRecognizer, Recognizer, { /** * @namespace * @memberof PressRecognizer */ defaults: { event: 'press', pointers: 1, time: 251, // minimal time of the pointer to be pressed threshold: 9 // a minimal movement is ok, but keep it low }, getTouchAction: function() { return [TOUCH_ACTION_AUTO]; }, process: function(input) { var options = this.options; var validPointers = input.pointers.length === options.pointers; var validMovement = input.distance < options.threshold; var validTime = input.deltaTime > options.time; this._input = input; // we only allow little movement // and we've reached an end event, so a tap is possible if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) { this.reset(); } else if (input.eventType & INPUT_START) { this.reset(); this._timer = setTimeoutContext(function() { this.state = STATE_RECOGNIZED; this.tryEmit(); }, options.time, this); } else if (input.eventType & INPUT_END) { return STATE_RECOGNIZED; } return STATE_FAILED; }, reset: function() { clearTimeout(this._timer); }, emit: function(input) { if (this.state !== STATE_RECOGNIZED) { return; } if (input && (input.eventType & INPUT_END)) { this.manager.emit(this.options.event + 'up', input); } else { this._input.timeStamp = now(); this.manager.emit(this.options.event, this._input); } } }); /** * Rotate * Recognized when two or more pointer are moving in a circular motion. * @constructor * @extends AttrRecognizer */ function RotateRecognizer() { AttrRecognizer.apply(this, arguments); } inherit(RotateRecognizer, AttrRecognizer, { /** * @namespace * @memberof RotateRecognizer */ defaults: { event: 'rotate', threshold: 0, pointers: 2 }, getTouchAction: function() { return [TOUCH_ACTION_NONE]; }, attrTest: function(input) { return this._super.attrTest.call(this, input) && (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN); } }); /** * Swipe * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction. * @constructor * @extends AttrRecognizer */ function SwipeRecognizer() { AttrRecognizer.apply(this, arguments); } inherit(SwipeRecognizer, AttrRecognizer, { /** * @namespace * @memberof SwipeRecognizer */ defaults: { event: 'swipe', threshold: 10, velocity: 0.3, direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL, pointers: 1 }, getTouchAction: function() { return PanRecognizer.prototype.getTouchAction.call(this); }, attrTest: function(input) { var direction = this.options.direction; var velocity; if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) { velocity = input.overallVelocity; } else if (direction & DIRECTION_HORIZONTAL) { velocity = input.overallVelocityX; } else if (direction & DIRECTION_VERTICAL) { velocity = input.overallVelocityY; } return this._super.attrTest.call(this, input) && direction & input.offsetDirection && input.distance > this.options.threshold && input.maxPointers == this.options.pointers && abs(velocity) > this.options.velocity && input.eventType & INPUT_END; }, emit: function(input) { var direction = directionStr(input.offsetDirection); if (direction) { this.manager.emit(this.options.event + direction, input); } this.manager.emit(this.options.event, input); } }); /** * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur * between the given interval and position. The delay option can be used to recognize multi-taps without firing * a single tap. * * The eventData from the emitted event contains the property `tapCount`, which contains the amount of * multi-taps being recognized. * @constructor * @extends Recognizer */ function TapRecognizer() { Recognizer.apply(this, arguments); // previous time and center, // used for tap counting this.pTime = false; this.pCenter = false; this._timer = null; this._input = null; this.count = 0; } inherit(TapRecognizer, Recognizer, { /** * @namespace * @memberof PinchRecognizer */ defaults: { event: 'tap', pointers: 1, taps: 1, interval: 300, // max time between the multi-tap taps time: 250, // max time of the pointer to be down (like finger on the screen) threshold: 9, // a minimal movement is ok, but keep it low posThreshold: 10 // a multi-tap can be a bit off the initial position }, getTouchAction: function() { return [TOUCH_ACTION_MANIPULATION]; }, process: function(input) { var options = this.options; var validPointers = input.pointers.length === options.pointers; var validMovement = input.distance < options.threshold; var validTouchTime = input.deltaTime < options.time; this.reset(); if ((input.eventType & INPUT_START) && (this.count === 0)) { return this.failTimeout(); } // we only allow little movement // and we've reached an end event, so a tap is possible if (validMovement && validTouchTime && validPointers) { if (input.eventType != INPUT_END) { return this.failTimeout(); } var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true; var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold; this.pTime = input.timeStamp; this.pCenter = input.center; if (!validMultiTap || !validInterval) { this.count = 1; } else { this.count += 1; } this._input = input; // if tap count matches we have recognized it, // else it has began recognizing... var tapCount = this.count % options.taps; if (tapCount === 0) { // no failing requirements, immediately trigger the tap event // or wait as long as the multitap interval to trigger if (!this.hasRequireFailures()) { return STATE_RECOGNIZED; } else { this._timer = setTimeoutContext(function() { this.state = STATE_RECOGNIZED; this.tryEmit(); }, options.interval, this); return STATE_BEGAN; } } } return STATE_FAILED; }, failTimeout: function() { this._timer = setTimeoutContext(function() { this.state = STATE_FAILED; }, this.options.interval, this); return STATE_FAILED; }, reset: function() { clearTimeout(this._timer); }, emit: function() { if (this.state == STATE_RECOGNIZED) { this._input.tapCount = this.count; this.manager.emit(this.options.event, this._input); } } }); /** * Simple way to create a manager with a default set of recognizers. * @param {HTMLElement} element * @param {Object} [options] * @constructor */ function Hammer(element, options) { options = options || {}; options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset); return new Manager(element, options); } /** * @const {string} */ Hammer.VERSION = '2.0.7'; /** * default settings * @namespace */ Hammer.defaults = { /** * set if DOM events are being triggered. * But this is slower and unused by simple implementations, so disabled by default. * @type {Boolean} * @default false */ domEvents: false, /** * The value for the touchAction property/fallback. * When set to `compute` it will magically set the correct value based on the added recognizers. * @type {String} * @default compute */ touchAction: TOUCH_ACTION_COMPUTE, /** * @type {Boolean} * @default true */ enable: true, /** * EXPERIMENTAL FEATURE -- can be removed/changed * Change the parent input target element. * If Null, then it is being set the to main element. * @type {Null|EventTarget} * @default null */ inputTarget: null, /** * force an input class * @type {Null|Function} * @default null */ inputClass: null, /** * Default recognizer setup when calling `Hammer()` * When creating a new Manager these will be skipped. * @type {Array} */ preset: [ // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...] [RotateRecognizer, {enable: false}], [PinchRecognizer, {enable: false}, ['rotate']], [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}], [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']], [TapRecognizer], [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']], [PressRecognizer] ], /** * Some CSS properties can be used to improve the working of Hammer. * Add them to this method and they will be set when creating a new Manager. * @namespace */ cssProps: { /** * Disables text selection to improve the dragging gesture. Mainly for desktop browsers. * @type {String} * @default 'none' */ userSelect: 'none', /** * Disable the Windows Phone grippers when pressing an element. * @type {String} * @default 'none' */ touchSelect: 'none', /** * Disables the default callout shown when you touch and hold a touch target. * On iOS, when you touch and hold a touch target such as a link, Safari displays * a callout containing information about the link. This property allows you to disable that callout. * @type {String} * @default 'none' */ touchCallout: 'none', /** * Specifies whether zooming is enabled. Used by IE10> * @type {String} * @default 'none' */ contentZooming: 'none', /** * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers. * @type {String} * @default 'none' */ userDrag: 'none', /** * Overrides the highlight color shown when the user taps a link or a JavaScript * clickable element in iOS. This property obeys the alpha value, if specified. * @type {String} * @default 'rgba(0,0,0,0)' */ tapHighlightColor: 'rgba(0,0,0,0)' } }; var STOP = 1; var FORCED_STOP = 2; /** * Manager * @param {HTMLElement} element * @param {Object} [options] * @constructor */ function Manager(element, options) { this.options = assign({}, Hammer.defaults, options || {}); this.options.inputTarget = this.options.inputTarget || element; this.handlers = {}; this.session = {}; this.recognizers = []; this.oldCssProps = {}; this.element = element; this.input = createInputInstance(this); this.touchAction = new TouchAction(this, this.options.touchAction); toggleCssProps(this, true); each(this.options.recognizers, function(item) { var recognizer = this.add(new (item[0])(item[1])); item[2] && recognizer.recognizeWith(item[2]); item[3] && recognizer.requireFailure(item[3]); }, this); } Manager.prototype = { /** * set options * @param {Object} options * @returns {Manager} */ set: function(options) { assign(this.options, options); // Options that need a little more setup if (options.touchAction) { this.touchAction.update(); } if (options.inputTarget) { // Clean up existing event listeners and reinitialize this.input.destroy(); this.input.target = options.inputTarget; this.input.init(); } return this; }, /** * stop recognizing for this session. * This session will be discarded, when a new [input]start event is fired. * When forced, the recognizer cycle is stopped immediately. * @param {Boolean} [force] */ stop: function(force) { this.session.stopped = force ? FORCED_STOP : STOP; }, /** * run the recognizers! * called by the inputHandler function on every movement of the pointers (touches) * it walks through all the recognizers and tries to detect the gesture that is being made * @param {Object} inputData */ recognize: function(inputData) { var session = this.session; if (session.stopped) { return; } // run the touch-action polyfill this.touchAction.preventDefaults(inputData); var recognizer; var recognizers = this.recognizers; // this holds the recognizer that is being recognized. // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED // if no recognizer is detecting a thing, it is set to `null` var curRecognizer = session.curRecognizer; // reset when the last recognizer is recognized // or when we're in a new session if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) { curRecognizer = session.curRecognizer = null; } var i = 0; while (i < recognizers.length) { recognizer = recognizers[i]; // find out if we are allowed try to recognize the input for this one. // 1. allow if the session is NOT forced stopped (see the .stop() method) // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one // that is being recognized. // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer. // this can be setup with the `recognizeWith()` method on the recognizer. if (session.stopped !== FORCED_STOP && ( // 1 !curRecognizer || recognizer == curRecognizer || // 2 recognizer.canRecognizeWith(curRecognizer))) { // 3 recognizer.recognize(inputData); } else { recognizer.reset(); } // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the // current active recognizer. but only if we don't already have an active recognizer if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) { curRecognizer = session.curRecognizer = recognizer; } i++; } }, /** * get a recognizer by its event name. * @param {Recognizer|String} recognizer * @returns {Recognizer|Null} */ get: function(recognizer) { if (recognizer instanceof Recognizer) { return recognizer; } var recognizers = this.recognizers; for (var i = 0; i < recognizers.length; i++) { if (recognizers[i].options.event == recognizer) { return recognizers[i]; } } return null; }, /** * add a recognizer to the manager * existing recognizers with the same event name will be removed * @param {Recognizer} recognizer * @returns {Recognizer|Manager} */ add: function(recognizer) { if (invokeArrayArg(recognizer, 'add', this)) { return this; } // remove existing var existing = this.get(recognizer.options.event); if (existing) { this.remove(existing); } this.recognizers.push(recognizer); recognizer.manager = this; this.touchAction.update(); return recognizer; }, /** * remove a recognizer by name or instance * @param {Recognizer|String} recognizer * @returns {Manager} */ remove: function(recognizer) { if (invokeArrayArg(recognizer, 'remove', this)) { return this; } recognizer = this.get(recognizer); // let's make sure this recognizer exists if (recognizer) { var recognizers = this.recognizers; var index = inArray(recognizers, recognizer); if (index !== -1) { recognizers.splice(index, 1); this.touchAction.update(); } } return this; }, /** * bind event * @param {String} events * @param {Function} handler * @returns {EventEmitter} this */ on: function(events, handler) { if (events === undefined) { return; } if (handler === undefined) { return; } var handlers = this.handlers; each(splitStr(events), function(event) { handlers[event] = handlers[event] || []; handlers[event].push(handler); }); return this; }, /** * unbind event, leave emit blank to remove all handlers * @param {String} events * @param {Function} [handler] * @returns {EventEmitter} this */ off: function(events, handler) { if (events === undefined) { return; } var handlers = this.handlers; each(splitStr(events), function(event) { if (!handler) { delete handlers[event]; } else { handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1); } }); return this; }, /** * emit event to the listeners * @param {String} event * @param {Object} data */ emit: function(event, data) { // we also want to trigger dom events if (this.options.domEvents) { triggerDomEvent(event, data); } // no handlers, so skip it all var handlers = this.handlers[event] && this.handlers[event].slice(); if (!handlers || !handlers.length) { return; } data.type = event; data.preventDefault = function() { data.srcEvent.preventDefault(); }; var i = 0; while (i < handlers.length) { handlers[i](data); i++; } }, /** * destroy the manager and unbinds all events * it doesn't unbind dom events, that is the user own responsibility */ destroy: function() { this.element && toggleCssProps(this, false); this.handlers = {}; this.session = {}; this.input.destroy(); this.element = null; } }; /** * add/remove the css properties as defined in manager.options.cssProps * @param {Manager} manager * @param {Boolean} add */ function toggleCssProps(manager, add) { var element = manager.element; if (!element.style) { return; } var prop; each(manager.options.cssProps, function(value, name) { prop = prefixed(element.style, name); if (add) { manager.oldCssProps[prop] = element.style[prop]; element.style[prop] = value; } else { element.style[prop] = manager.oldCssProps[prop] || ''; } }); if (!add) { manager.oldCssProps = {}; } } /** * trigger dom event * @param {String} event * @param {Object} data */ function triggerDomEvent(event, data) { var gestureEvent = document.createEvent('Event'); gestureEvent.initEvent(event, true, true); gestureEvent.gesture = data; data.target.dispatchEvent(gestureEvent); } assign(Hammer, { INPUT_START: INPUT_START, INPUT_MOVE: INPUT_MOVE, INPUT_END: INPUT_END, INPUT_CANCEL: INPUT_CANCEL, STATE_POSSIBLE: STATE_POSSIBLE, STATE_BEGAN: STATE_BEGAN, STATE_CHANGED: STATE_CHANGED, STATE_ENDED: STATE_ENDED, STATE_RECOGNIZED: STATE_RECOGNIZED, STATE_CANCELLED: STATE_CANCELLED, STATE_FAILED: STATE_FAILED, DIRECTION_NONE: DIRECTION_NONE, DIRECTION_LEFT: DIRECTION_LEFT, DIRECTION_RIGHT: DIRECTION_RIGHT, DIRECTION_UP: DIRECTION_UP, DIRECTION_DOWN: DIRECTION_DOWN, DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL, DIRECTION_VERTICAL: DIRECTION_VERTICAL, DIRECTION_ALL: DIRECTION_ALL, Manager: Manager, Input: Input, TouchAction: TouchAction, TouchInput: TouchInput, MouseInput: MouseInput, PointerEventInput: PointerEventInput, TouchMouseInput: TouchMouseInput, SingleTouchInput: SingleTouchInput, Recognizer: Recognizer, AttrRecognizer: AttrRecognizer, Tap: TapRecognizer, Pan: PanRecognizer, Swipe: SwipeRecognizer, Pinch: PinchRecognizer, Rotate: RotateRecognizer, Press: PressRecognizer, on: addEventListeners, off: removeEventListeners, each: each, merge: merge, extend: extend, assign: assign, inherit: inherit, bindFn: bindFn, prefixed: prefixed }); // this prevents errors when Hammer is loaded in the presence of an AMD // style loader but by script tag, not by the loader. var freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line freeGlobal.Hammer = Hammer; if (typeof define === 'function' && define.amd) { define(function() { return Hammer; }); } else if (typeof module != 'undefined' && module.exports) { module.exports = Hammer; } else { window[exportName] = Hammer; } })(window, document, 'Hammer'); },{}],346:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var hat_1 = createCommonjsModule(function (module) { var hat = module.exports = function (bits, base) { if (!base) base = 16; if (bits === undefined) bits = 128; if (bits <= 0) return '0'; var digits = Math.log(Math.pow(2, bits)) / Math.log(base); for (var i = 2; digits === Infinity; i *= 2) { digits = Math.log(Math.pow(2, bits / i)) / Math.log(base) * i; } var rem = digits - Math.floor(digits); var res = ''; for (var i = 0; i < Math.floor(digits); i++) { var x = Math.floor(Math.random() * base).toString(base); res = x + res; } if (rem) { var b = Math.pow(base, rem); var x = Math.floor(Math.random() * b).toString(base); res = x + res; } var parsed = parseInt(res, base); if (parsed !== Infinity && parsed >= Math.pow(2, bits)) { return hat(bits, base); } else return res; }; hat.rack = function (bits, base, expandBy) { var fn = function (data) { var iters = 0; do { if (iters++ > 10) { if (expandBy) bits += expandBy;else throw new Error('too many ID collisions, use more bits'); } var id = hat(bits, base); } while (Object.hasOwnProperty.call(hats, id)); hats[id] = data; return id; }; var hats = fn.hats = {}; fn.get = function (id) { return fn.hats[id]; }; fn.set = function (id, value) { fn.hats[id] = value; return fn; }; fn.bits = bits || 128; fn.base = base || 16; return fn; }; }); /** * Create a new id generator / cache instance. * * You may optionally provide a seed that is used internally. * * @param {Seed} seed */ function Ids(seed) { if (!(this instanceof Ids)) { return new Ids(seed); } seed = seed || [128, 36, 1]; this._seed = seed.length ? hat_1.rack(seed[0], seed[1], seed[2]) : seed; } /** * Generate a next id. * * @param {Object} [element] element to bind the id to * * @return {String} id */ Ids.prototype.next = function (element) { return this._seed(element || true); }; /** * Generate a next id with a given prefix. * * @param {Object} [element] element to bind the id to * * @return {String} id */ Ids.prototype.nextPrefixed = function (prefix, element) { var id; do { id = prefix + this.next(true); } while (this.assigned(id)); // claim {prefix}{random} this.claim(id, element); // return return id; }; /** * Manually claim an existing id. * * @param {String} id * @param {String} [element] element the id is claimed by */ Ids.prototype.claim = function (id, element) { this._seed.set(id, element || true); }; /** * Returns true if the given id has already been assigned. * * @param {String} id * @return {Boolean} */ Ids.prototype.assigned = function (id) { return this._seed.get(id) || false; }; /** * Unclaim an id. * * @param {String} id the id to unclaim */ Ids.prototype.unclaim = function (id) { delete this._seed.hats[id]; }; /** * Clear all claimed ids. */ Ids.prototype.clear = function () { var hats = this._seed.hats, id; for (id in hats) { this.unclaim(id); } }; var _default = Ids; exports.default = _default; },{}],347:[function(require,module,exports){ if (typeof Object.create === 'function') { // implementation from standard node.js 'util' module module.exports = function inherits(ctor, superCtor) { if (superCtor) { ctor.super_ = superCtor ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }) } }; } else { // old school shim for old browsers module.exports = function inherits(ctor, superCtor) { if (superCtor) { ctor.super_ = superCtor var TempCtor = function () {} TempCtor.prototype = superCtor.prototype ctor.prototype = new TempCtor() ctor.prototype.constructor = ctor } } } },{}],348:[function(require,module,exports){ /*! * jQuery JavaScript Library v3.5.1 * https://jquery.com/ * * Includes Sizzle.js * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://jquery.org/license * * Date: 2020-05-04T22:49Z */ ( function( global, factory ) { "use strict"; if ( typeof module === "object" && typeof module.exports === "object" ) { // For CommonJS and CommonJS-like environments where a proper `window` // is present, execute the factory and get jQuery. // For environments that do not have a `window` with a `document` // (such as Node.js), expose a factory as module.exports. // This accentuates the need for the creation of a real `window`. // e.g. var jQuery = require("jquery")(window); // See ticket #14549 for more info. module.exports = global.document ? factory( global, true ) : function( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); }; } else { factory( global ); } // Pass this if window is not defined yet } )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { // Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 // throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode // arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common // enough that all such attempts are guarded in a try block. "use strict"; var arr = []; var getProto = Object.getPrototypeOf; var slice = arr.slice; var flat = arr.flat ? function( array ) { return arr.flat.call( array ); } : function( array ) { return arr.concat.apply( [], array ); }; var push = arr.push; var indexOf = arr.indexOf; var class2type = {}; var toString = class2type.toString; var hasOwn = class2type.hasOwnProperty; var fnToString = hasOwn.toString; var ObjectFunctionString = fnToString.call( Object ); var support = {}; var isFunction = function isFunction( obj ) { // Support: Chrome <=57, Firefox <=52 // In some browsers, typeof returns "function" for HTML <object> elements // (i.e., `typeof document.createElement( "object" ) === "function"`). // We don't want to classify *any* DOM node as a function. return typeof obj === "function" && typeof obj.nodeType !== "number"; }; var isWindow = function isWindow( obj ) { return obj != null && obj === obj.window; }; var document = window.document; var preservedScriptAttributes = { type: true, src: true, nonce: true, noModule: true }; function DOMEval( code, node, doc ) { doc = doc || document; var i, val, script = doc.createElement( "script" ); script.text = code; if ( node ) { for ( i in preservedScriptAttributes ) { // Support: Firefox 64+, Edge 18+ // Some browsers don't support the "nonce" property on scripts. // On the other hand, just using `getAttribute` is not enough as // the `nonce` attribute is reset to an empty string whenever it // becomes browsing-context connected. // See https://github.com/whatwg/html/issues/2369 // See https://html.spec.whatwg.org/#nonce-attributes // The `node.getAttribute` check was added for the sake of // `jQuery.globalEval` so that it can fake a nonce-containing node // via an object. val = node[ i ] || node.getAttribute && node.getAttribute( i ); if ( val ) { script.setAttribute( i, val ); } } } doc.head.appendChild( script ).parentNode.removeChild( script ); } function toType( obj ) { if ( obj == null ) { return obj + ""; } // Support: Android <=2.3 only (functionish RegExp) return typeof obj === "object" || typeof obj === "function" ? class2type[ toString.call( obj ) ] || "object" : typeof obj; } /* global Symbol */ // Defining this global in .eslintrc.json would create a danger of using the global // unguarded in another place, it seems safer to define global only for this module var version = "3.5.1", // Define a local copy of jQuery jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery.fn.init( selector, context ); }; jQuery.fn = jQuery.prototype = { // The current version of jQuery being used jquery: version, constructor: jQuery, // The default length of a jQuery object is 0 length: 0, toArray: function() { return slice.call( this ); }, // Get the Nth element in the matched element set OR // Get the whole matched element set as a clean array get: function( num ) { // Return all the elements in a clean array if ( num == null ) { return slice.call( this ); } // Return just the one element from the set return num < 0 ? this[ num + this.length ] : this[ num ]; }, // Take an array of elements and push it onto the stack // (returning the new matched element set) pushStack: function( elems ) { // Build a new jQuery matched element set var ret = jQuery.merge( this.constructor(), elems ); // Add the old object onto the stack (as a reference) ret.prevObject = this; // Return the newly-formed element set return ret; }, // Execute a callback for every element in the matched set. each: function( callback ) { return jQuery.each( this, callback ); }, map: function( callback ) { return this.pushStack( jQuery.map( this, function( elem, i ) { return callback.call( elem, i, elem ); } ) ); }, slice: function() { return this.pushStack( slice.apply( this, arguments ) ); }, first: function() { return this.eq( 0 ); }, last: function() { return this.eq( -1 ); }, even: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return ( i + 1 ) % 2; } ) ); }, odd: function() { return this.pushStack( jQuery.grep( this, function( _elem, i ) { return i % 2; } ) ); }, eq: function( i ) { var len = this.length, j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); }, end: function() { return this.prevObject || this.constructor(); }, // For internal use only. // Behaves like an Array's method, not like a jQuery method. push: push, sort: arr.sort, splice: arr.splice }; jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[ 0 ] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && !isFunction( target ) ) { target = {}; } // Extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( ( options = arguments[ i ] ) != null ) { // Extend the base object for ( name in options ) { copy = options[ name ]; // Prevent Object.prototype pollution // Prevent never-ending loop if ( name === "__proto__" || target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( jQuery.isPlainObject( copy ) || ( copyIsArray = Array.isArray( copy ) ) ) ) { src = target[ name ]; // Ensure proper type for the source value if ( copyIsArray && !Array.isArray( src ) ) { clone = []; } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { clone = {}; } else { clone = src; } copyIsArray = false; // Never move original objects, clone them target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; jQuery.extend( { // Unique for each copy of jQuery on the page expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), // Assume jQuery is ready without the ready module isReady: true, error: function( msg ) { throw new Error( msg ); }, noop: function() {}, isPlainObject: function( obj ) { var proto, Ctor; // Detect obvious negatives // Use toString instead of jQuery.type to catch host objects if ( !obj || toString.call( obj ) !== "[object Object]" ) { return false; } proto = getProto( obj ); // Objects with no prototype (e.g., `Object.create( null )`) are plain if ( !proto ) { return true; } // Objects with prototype are plain iff they were constructed by a global Object function Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; }, isEmptyObject: function( obj ) { var name; for ( name in obj ) { return false; } return true; }, // Evaluates a script in a provided context; falls back to the global one // if not specified. globalEval: function( code, options, doc ) { DOMEval( code, { nonce: options && options.nonce }, doc ); }, each: function( obj, callback ) { var length, i = 0; if ( isArrayLike( obj ) ) { length = obj.length; for ( ; i < length; i++ ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } else { for ( i in obj ) { if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { break; } } } return obj; }, // results is for internal usage only makeArray: function( arr, results ) { var ret = results || []; if ( arr != null ) { if ( isArrayLike( Object( arr ) ) ) { jQuery.merge( ret, typeof arr === "string" ? [ arr ] : arr ); } else { push.call( ret, arr ); } } return ret; }, inArray: function( elem, arr, i ) { return arr == null ? -1 : indexOf.call( arr, elem, i ); }, // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit merge: function( first, second ) { var len = +second.length, j = 0, i = first.length; for ( ; j < len; j++ ) { first[ i++ ] = second[ j ]; } first.length = i; return first; }, grep: function( elems, callback, invert ) { var callbackInverse, matches = [], i = 0, length = elems.length, callbackExpect = !invert; // Go through the array, only saving the items // that pass the validator function for ( ; i < length; i++ ) { callbackInverse = !callback( elems[ i ], i ); if ( callbackInverse !== callbackExpect ) { matches.push( elems[ i ] ); } } return matches; }, // arg is for internal usage only map: function( elems, callback, arg ) { var length, value, i = 0, ret = []; // Go through the array, translating each of the items to their new values if ( isArrayLike( elems ) ) { length = elems.length; for ( ; i < length; i++ ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } // Go through every key on the object, } else { for ( i in elems ) { value = callback( elems[ i ], i, arg ); if ( value != null ) { ret.push( value ); } } } // Flatten any nested arrays return flat( ret ); }, // A global GUID counter for objects guid: 1, // jQuery.support is not used in Core but other projects attach their // properties to it so it needs to exist. support: support } ); if ( typeof Symbol === "function" ) { jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; } // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), function( _i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); function isArrayLike( obj ) { // Support: real iOS 8.2 only (not reproducible in simulator) // `in` check used to prevent JIT error (gh-2145) // hasOwn isn't used here due to false negatives // regarding Nodelist length in IE var length = !!obj && "length" in obj && obj.length, type = toType( obj ); if ( isFunction( obj ) || isWindow( obj ) ) { return false; } return type === "array" || length === 0 || typeof length === "number" && length > 0 && ( length - 1 ) in obj; } var Sizzle = /*! * Sizzle CSS Selector Engine v2.3.5 * https://sizzlejs.com/ * * Copyright JS Foundation and other contributors * Released under the MIT license * https://js.foundation/ * * Date: 2020-03-14 */ ( function( window ) { var i, support, Expr, getText, isXML, tokenize, compile, select, outermostContext, sortInput, hasDuplicate, // Local document vars setDocument, document, docElem, documentIsHTML, rbuggyQSA, rbuggyMatches, matches, contains, // Instance-specific data expando = "sizzle" + 1 * new Date(), preferredDoc = window.document, dirruns = 0, done = 0, classCache = createCache(), tokenCache = createCache(), compilerCache = createCache(), nonnativeSelectorCache = createCache(), sortOrder = function( a, b ) { if ( a === b ) { hasDuplicate = true; } return 0; }, // Instance methods hasOwn = ( {} ).hasOwnProperty, arr = [], pop = arr.pop, pushNative = arr.push, push = arr.push, slice = arr.slice, // Use a stripped-down indexOf as it's faster than native // https://jsperf.com/thor-indexof-vs-for/5 indexOf = function( list, elem ) { var i = 0, len = list.length; for ( ; i < len; i++ ) { if ( list[ i ] === elem ) { return i; } } return -1; }, booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + "ismap|loop|multiple|open|readonly|required|scoped", // Regular expressions // http://www.w3.org/TR/css3-selectors/#whitespace whitespace = "[\\x20\\t\\r\\n\\f]", // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2) "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] // or strings [capture 3 or capture 4]" "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]", pseudos = ":(" + identifier + ")(?:\\((" + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: // 1. quoted (capture 3; capture 4 or capture 5) "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + // 2. simple (capture 6) "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + // 3. anything else (capture 2) ".*" + ")\\)|)", // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter rwhitespace = new RegExp( whitespace + "+", "g" ), rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), rdescend = new RegExp( whitespace + "|>" ), rpseudo = new RegExp( pseudos ), ridentifier = new RegExp( "^" + identifier + "$" ), matchExpr = { "ID": new RegExp( "^#(" + identifier + ")" ), "CLASS": new RegExp( "^\\.(" + identifier + ")" ), "TAG": new RegExp( "^(" + identifier + "|[*])" ), "ATTR": new RegExp( "^" + attributes ), "PSEUDO": new RegExp( "^" + pseudos ), "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), // For use in libraries implementing .is() // We use this for POS matching in `select` "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) }, rhtml = /HTML$/i, rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rnative = /^[^{]+\{\s*\[native \w/, // Easily-parseable/retrievable ID or TAG or CLASS selectors rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, rsibling = /[+~]/, // CSS escapes // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), funescape = function( escape, nonHex ) { var high = "0x" + escape.slice( 1 ) - 0x10000; return nonHex ? // Strip the backslash prefix from a non-hex escape sequence nonHex : // Replace a hexadecimal escape sequence with the encoded Unicode code point // Support: IE <=11+ // For values outside the Basic Multilingual Plane (BMP), manually construct a // surrogate pair high < 0 ? String.fromCharCode( high + 0x10000 ) : String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); }, // CSS string/identifier serialization // https://drafts.csswg.org/cssom/#common-serializing-idioms rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, fcssescape = function( ch, asCodePoint ) { if ( asCodePoint ) { // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER if ( ch === "\0" ) { return "\uFFFD"; } // Control characters and (dependent upon position) numbers get escaped as code points return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; } // Other potentially-special ASCII characters get backslash-escaped return "\\" + ch; }, // Used for iframes // See setDocument() // Removing the function wrapper causes a "Permission Denied" // error in IE unloadHandler = function() { setDocument(); }, inDisabledFieldset = addCombinator( function( elem ) { return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; }, { dir: "parentNode", next: "legend" } ); // Optimize for push.apply( _, NodeList ) try { push.apply( ( arr = slice.call( preferredDoc.childNodes ) ), preferredDoc.childNodes ); // Support: Android<4.0 // Detect silently failing push.apply // eslint-disable-next-line no-unused-expressions arr[ preferredDoc.childNodes.length ].nodeType; } catch ( e ) { push = { apply: arr.length ? // Leverage slice if possible function( target, els ) { pushNative.apply( target, slice.call( els ) ); } : // Support: IE<9 // Otherwise append directly function( target, els ) { var j = target.length, i = 0; // Can't trust NodeList.length while ( ( target[ j++ ] = els[ i++ ] ) ) {} target.length = j - 1; } }; } function Sizzle( selector, context, results, seed ) { var m, i, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, // nodeType defaults to 9, since context defaults to document nodeType = context ? context.nodeType : 9; results = results || []; // Return early from calls with invalid selector or context if ( typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { return results; } // Try to shortcut find operations (as opposed to filters) in HTML documents if ( !seed ) { setDocument( context ); context = context || document; if ( documentIsHTML ) { // If the selector is sufficiently simple, try using a "get*By*" DOM method // (excepting DocumentFragment context, where the methods don't exist) if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { // ID selector if ( ( m = match[ 1 ] ) ) { // Document context if ( nodeType === 9 ) { if ( ( elem = context.getElementById( m ) ) ) { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( elem.id === m ) { results.push( elem ); return results; } } else { return results; } // Element context } else { // Support: IE, Opera, Webkit // TODO: identify versions // getElementById can match elements by name instead of ID if ( newContext && ( elem = newContext.getElementById( m ) ) && contains( context, elem ) && elem.id === m ) { results.push( elem ); return results; } } // Type selector } else if ( match[ 2 ] ) { push.apply( results, context.getElementsByTagName( selector ) ); return results; // Class selector } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && context.getElementsByClassName ) { push.apply( results, context.getElementsByClassName( m ) ); return results; } } // Take advantage of querySelectorAll if ( support.qsa && !nonnativeSelectorCache[ selector + " " ] && ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && // Support: IE 8 only // Exclude object elements ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { newSelector = selector; newContext = context; // qSA considers elements outside a scoping root when evaluating child or // descendant combinators, which is not what we want. // In such cases, we work around the behavior by prefixing every selector in the // list with an ID selector referencing the scope context. // The technique has to be used as well when a leading combinator is used // as such selectors are not recognized by querySelectorAll. // Thanks to Andrew Dupont for this technique. if ( nodeType === 1 && ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { // Expand context for sibling selectors newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; // We can use :scope instead of the ID hack if the browser // supports it & if we're not changing the context. if ( newContext !== context || !support.scope ) { // Capture the context ID, setting it first if necessary if ( ( nid = context.getAttribute( "id" ) ) ) { nid = nid.replace( rcssescape, fcssescape ); } else { context.setAttribute( "id", ( nid = expando ) ); } } // Prefix every selector in the list groups = tokenize( selector ); i = groups.length; while ( i-- ) { groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + toSelector( groups[ i ] ); } newSelector = groups.join( "," ); } try { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch ( qsaError ) { nonnativeSelectorCache( selector, true ); } finally { if ( nid === expando ) { context.removeAttribute( "id" ); } } } } } // All others return select( selector.replace( rtrim, "$1" ), context, results, seed ); } /** * Create key-value caches of limited size * @returns {function(string, object)} Returns the Object data after storing it on itself with * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) * deleting the oldest entry */ function createCache() { var keys = []; function cache( key, value ) { // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) if ( keys.push( key + " " ) > Expr.cacheLength ) { // Only keep the most recent entries delete cache[ keys.shift() ]; } return ( cache[ key + " " ] = value ); } return cache; } /** * Mark a function for special use by Sizzle * @param {Function} fn The function to mark */ function markFunction( fn ) { fn[ expando ] = true; return fn; } /** * Support testing using an element * @param {Function} fn Passed the created element and returns a boolean result */ function assert( fn ) { var el = document.createElement( "fieldset" ); try { return !!fn( el ); } catch ( e ) { return false; } finally { // Remove from its parent by default if ( el.parentNode ) { el.parentNode.removeChild( el ); } // release memory in IE el = null; } } /** * Adds the same handler for all of the specified attrs * @param {String} attrs Pipe-separated list of attributes * @param {Function} handler The method that will be applied */ function addHandle( attrs, handler ) { var arr = attrs.split( "|" ), i = arr.length; while ( i-- ) { Expr.attrHandle[ arr[ i ] ] = handler; } } /** * Checks document order of two siblings * @param {Element} a * @param {Element} b * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b */ function siblingCheck( a, b ) { var cur = b && a, diff = cur && a.nodeType === 1 && b.nodeType === 1 && a.sourceIndex - b.sourceIndex; // Use IE sourceIndex if available on both nodes if ( diff ) { return diff; } // Check if b follows a if ( cur ) { while ( ( cur = cur.nextSibling ) ) { if ( cur === b ) { return -1; } } } return a ? 1 : -1; } /** * Returns a function to use in pseudos for input types * @param {String} type */ function createInputPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === type; }; } /** * Returns a function to use in pseudos for buttons * @param {String} type */ function createButtonPseudo( type ) { return function( elem ) { var name = elem.nodeName.toLowerCase(); return ( name === "input" || name === "button" ) && elem.type === type; }; } /** * Returns a function to use in pseudos for :enabled/:disabled * @param {Boolean} disabled true for :disabled; false for :enabled */ function createDisabledPseudo( disabled ) { // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable return function( elem ) { // Only certain elements can match :enabled or :disabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled if ( "form" in elem ) { // Check for inherited disabledness on relevant non-disabled elements: // * listed form-associated elements in a disabled fieldset // https://html.spec.whatwg.org/multipage/forms.html#category-listed // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled // * option elements in a disabled optgroup // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled // All such elements have a "form" property. if ( elem.parentNode && elem.disabled === false ) { // Option elements defer to a parent optgroup if present if ( "label" in elem ) { if ( "label" in elem.parentNode ) { return elem.parentNode.disabled === disabled; } else { return elem.disabled === disabled; } } // Support: IE 6 - 11 // Use the isDisabled shortcut property to check for disabled fieldset ancestors return elem.isDisabled === disabled || // Where there is no isDisabled, check manually /* jshint -W018 */ elem.isDisabled !== !disabled && inDisabledFieldset( elem ) === disabled; } return elem.disabled === disabled; // Try to winnow out elements that can't be disabled before trusting the disabled property. // Some victims get caught in our net (label, legend, menu, track), but it shouldn't // even exist on them, let alone have a boolean value. } else if ( "label" in elem ) { return elem.disabled === disabled; } // Remaining elements are neither :enabled nor :disabled return false; }; } /** * Returns a function to use in pseudos for positionals * @param {Function} fn */ function createPositionalPseudo( fn ) { return markFunction( function( argument ) { argument = +argument; return markFunction( function( seed, matches ) { var j, matchIndexes = fn( [], seed.length, argument ), i = matchIndexes.length; // Match elements found at the specified indexes while ( i-- ) { if ( seed[ ( j = matchIndexes[ i ] ) ] ) { seed[ j ] = !( matches[ j ] = seed[ j ] ); } } } ); } ); } /** * Checks a node for validity as a Sizzle context * @param {Element|Object=} context * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value */ function testContext( context ) { return context && typeof context.getElementsByTagName !== "undefined" && context; } // Expose support vars for convenience support = Sizzle.support = {}; /** * Detects XML nodes * @param {Element|Object} elem An element or a document * @returns {Boolean} True iff elem is a non-HTML XML node */ isXML = Sizzle.isXML = function( elem ) { var namespace = elem.namespaceURI, docElem = ( elem.ownerDocument || elem ).documentElement; // Support: IE <=8 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes // https://bugs.jquery.com/ticket/4833 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); }; /** * Sets document-related variables once based on the current document * @param {Element|Object} [doc] An element or document object to use to set the document * @returns {Object} Returns the current document */ setDocument = Sizzle.setDocument = function( node ) { var hasCompare, subWindow, doc = node ? node.ownerDocument || node : preferredDoc; // Return early if doc is invalid or already selected // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { return document; } // Update global variables document = doc; docElem = document.documentElement; documentIsHTML = !isXML( document ); // Support: IE 9 - 11+, Edge 12 - 18+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( preferredDoc != document && ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { // Support: IE 11, Edge if ( subWindow.addEventListener ) { subWindow.addEventListener( "unload", unloadHandler, false ); // Support: IE 9 - 10 only } else if ( subWindow.attachEvent ) { subWindow.attachEvent( "onunload", unloadHandler ); } } // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, // Safari 4 - 5 only, Opera <=11.6 - 12.x only // IE/Edge & older browsers don't support the :scope pseudo-class. // Support: Safari 6.0 only // Safari 6.0 supports :scope but it's an alias of :root there. support.scope = assert( function( el ) { docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); return typeof el.querySelectorAll !== "undefined" && !el.querySelectorAll( ":scope fieldset div" ).length; } ); /* Attributes ---------------------------------------------------------------------- */ // Support: IE<8 // Verify that getAttribute really returns attributes and not properties // (excepting IE8 booleans) support.attributes = assert( function( el ) { el.className = "i"; return !el.getAttribute( "className" ); } ); /* getElement(s)By* ---------------------------------------------------------------------- */ // Check if getElementsByTagName("*") returns only elements support.getElementsByTagName = assert( function( el ) { el.appendChild( document.createComment( "" ) ); return !el.getElementsByTagName( "*" ).length; } ); // Support: IE<9 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); // Support: IE<10 // Check if getElementById returns elements by name // The broken getElementById methods don't pick up programmatically-set names, // so use a roundabout getElementsByName test support.getById = assert( function( el ) { docElem.appendChild( el ).id = expando; return !document.getElementsByName || !document.getElementsByName( expando ).length; } ); // ID filter and find if ( support.getById ) { Expr.filter[ "ID" ] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { return elem.getAttribute( "id" ) === attrId; }; }; Expr.find[ "ID" ] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var elem = context.getElementById( id ); return elem ? [ elem ] : []; } }; } else { Expr.filter[ "ID" ] = function( id ) { var attrId = id.replace( runescape, funescape ); return function( elem ) { var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode( "id" ); return node && node.value === attrId; }; }; // Support: IE 6 - 7 only // getElementById is not reliable as a find shortcut Expr.find[ "ID" ] = function( id, context ) { if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { var node, i, elems, elem = context.getElementById( id ); if ( elem ) { // Verify the id attribute node = elem.getAttributeNode( "id" ); if ( node && node.value === id ) { return [ elem ]; } // Fall back on getElementsByName elems = context.getElementsByName( id ); i = 0; while ( ( elem = elems[ i++ ] ) ) { node = elem.getAttributeNode( "id" ); if ( node && node.value === id ) { return [ elem ]; } } } return []; } }; } // Tag Expr.find[ "TAG" ] = support.getElementsByTagName ? function( tag, context ) { if ( typeof context.getElementsByTagName !== "undefined" ) { return context.getElementsByTagName( tag ); // DocumentFragment nodes don't have gEBTN } else if ( support.qsa ) { return context.querySelectorAll( tag ); } } : function( tag, context ) { var elem, tmp = [], i = 0, // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too results = context.getElementsByTagName( tag ); // Filter out possible comments if ( tag === "*" ) { while ( ( elem = results[ i++ ] ) ) { if ( elem.nodeType === 1 ) { tmp.push( elem ); } } return tmp; } return results; }; // Class Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { return context.getElementsByClassName( className ); } }; /* QSA/matchesSelector ---------------------------------------------------------------------- */ // QSA and matchesSelector support // matchesSelector(:active) reports false when true (IE9/Opera 11.5) rbuggyMatches = []; // qSa(:focus) reports false when true (Chrome 21) // We allow this because of a bug in IE8/9 that throws an error // whenever `document.activeElement` is accessed on an iframe // So, we allow :focus to pass through QSA all the time to avoid the IE error // See https://bugs.jquery.com/ticket/13378 rbuggyQSA = []; if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { // Build QSA regex // Regex strategy adopted from Diego Perini assert( function( el ) { var input; // Select is set to empty string on purpose // This is to test IE's treatment of not explicitly // setting a boolean content attribute, // since its presence should be enough // https://bugs.jquery.com/ticket/12359 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + "<select id='" + expando + "-\r\\' msallowcapture=''>" + "<option selected=''></option></select>"; // Support: IE8, Opera 11-12.16 // Nothing should be selected when empty strings follow ^= or $= or *= // The test attribute must be unknown in Opera but "safe" for WinRT // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); } // Support: IE8 // Boolean attributes and "value" are not treated correctly if ( !el.querySelectorAll( "[selected]" ).length ) { rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); } // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { rbuggyQSA.push( "~=" ); } // Support: IE 11+, Edge 15 - 18+ // IE 11/Edge don't find elements on a `[name='']` query in some cases. // Adding a temporary attribute to the document before the selection works // around the issue. // Interestingly, IE 10 & older don't seem to have the issue. input = document.createElement( "input" ); input.setAttribute( "name", "" ); el.appendChild( input ); if ( !el.querySelectorAll( "[name='']" ).length ) { rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + whitespace + "*(?:''|\"\")" ); } // Webkit/Opera - :checked should return selected option elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked // IE8 throws error here and will not see later tests if ( !el.querySelectorAll( ":checked" ).length ) { rbuggyQSA.push( ":checked" ); } // Support: Safari 8+, iOS 8+ // https://bugs.webkit.org/show_bug.cgi?id=136851 // In-page `selector#id sibling-combinator selector` fails if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { rbuggyQSA.push( ".#.+[+~]" ); } // Support: Firefox <=3.6 - 5 only // Old Firefox doesn't throw on a badly-escaped identifier. el.querySelectorAll( "\\\f" ); rbuggyQSA.push( "[\\r\\n\\f]" ); } ); assert( function( el ) { el.innerHTML = "<a href='' disabled='disabled'></a>" + "<select disabled='disabled'><option/></select>"; // Support: Windows 8 Native Apps // The type and name attributes are restricted during .innerHTML assignment var input = document.createElement( "input" ); input.setAttribute( "type", "hidden" ); el.appendChild( input ).setAttribute( "name", "D" ); // Support: IE8 // Enforce case-sensitivity of name attribute if ( el.querySelectorAll( "[name=d]" ).length ) { rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); } // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) // IE8 throws error here and will not see later tests if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Support: IE9-11+ // IE's :disabled selector does not pick up the children of disabled fieldsets docElem.appendChild( el ).disabled = true; if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { rbuggyQSA.push( ":enabled", ":disabled" ); } // Support: Opera 10 - 11 only // Opera 10-11 does not throw on post-comma invalid pseudos el.querySelectorAll( "*,:x" ); rbuggyQSA.push( ",.*:" ); } ); } if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector ) ) ) ) { assert( function( el ) { // Check to see if it's possible to do matchesSelector // on a disconnected node (IE 9) support.disconnectedMatch = matches.call( el, "*" ); // This should fail with an exception // Gecko does not error, returns false instead matches.call( el, "[s!='']:x" ); rbuggyMatches.push( "!=", pseudos ); } ); } rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); /* Contains ---------------------------------------------------------------------- */ hasCompare = rnative.test( docElem.compareDocumentPosition ); // Element contains another // Purposefully self-exclusive // As in, an element does not contain itself contains = hasCompare || rnative.test( docElem.contains ) ? function( a, b ) { var adown = a.nodeType === 9 ? a.documentElement : a, bup = b && b.parentNode; return a === bup || !!( bup && bup.nodeType === 1 && ( adown.contains ? adown.contains( bup ) : a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 ) ); } : function( a, b ) { if ( b ) { while ( ( b = b.parentNode ) ) { if ( b === a ) { return true; } } } return false; }; /* Sorting ---------------------------------------------------------------------- */ // Document order sorting sortOrder = hasCompare ? function( a, b ) { // Flag for duplicate removal if ( a === b ) { hasDuplicate = true; return 0; } // Sort on method existence if only one input has compareDocumentPosition var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; if ( compare ) { return compare; } // Calculate position if both inputs belong to the same document // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? a.compareDocumentPosition( b ) : // Otherwise we know they are disconnected 1; // Disconnected nodes if ( compare & 1 || ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { // Choose the first element that is related to our preferred document // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( a == document || a.ownerDocument == preferredDoc && contains( preferredDoc, a ) ) { return -1; } // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( b == document || b.ownerDocument == preferredDoc && contains( preferredDoc, b ) ) { return 1; } // Maintain original order return sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; } return compare & 4 ? -1 : 1; } : function( a, b ) { // Exit early if the nodes are identical if ( a === b ) { hasDuplicate = true; return 0; } var cur, i = 0, aup = a.parentNode, bup = b.parentNode, ap = [ a ], bp = [ b ]; // Parentless nodes are either documents or disconnected if ( !aup || !bup ) { // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. /* eslint-disable eqeqeq */ return a == document ? -1 : b == document ? 1 : /* eslint-enable eqeqeq */ aup ? -1 : bup ? 1 : sortInput ? ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 0; // If the nodes are siblings, we can do a quick check } else if ( aup === bup ) { return siblingCheck( a, b ); } // Otherwise we need full lists of their ancestors for comparison cur = a; while ( ( cur = cur.parentNode ) ) { ap.unshift( cur ); } cur = b; while ( ( cur = cur.parentNode ) ) { bp.unshift( cur ); } // Walk down the tree looking for a discrepancy while ( ap[ i ] === bp[ i ] ) { i++; } return i ? // Do a sibling check if the nodes have a common ancestor siblingCheck( ap[ i ], bp[ i ] ) : // Otherwise nodes in our document sort first // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. /* eslint-disable eqeqeq */ ap[ i ] == preferredDoc ? -1 : bp[ i ] == preferredDoc ? 1 : /* eslint-enable eqeqeq */ 0; }; return document; }; Sizzle.matches = function( expr, elements ) { return Sizzle( expr, null, null, elements ); }; Sizzle.matchesSelector = function( elem, expr ) { setDocument( elem ); if ( support.matchesSelector && documentIsHTML && !nonnativeSelectorCache[ expr + " " ] && ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { try { var ret = matches.call( elem, expr ); // IE 9's matchesSelector returns false on disconnected nodes if ( ret || support.disconnectedMatch || // As well, disconnected nodes are said to be in a document // fragment in IE 9 elem.document && elem.document.nodeType !== 11 ) { return ret; } } catch ( e ) { nonnativeSelectorCache( expr, true ); } } return Sizzle( expr, document, null, [ elem ] ).length > 0; }; Sizzle.contains = function( context, elem ) { // Set document vars if needed // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( ( context.ownerDocument || context ) != document ) { setDocument( context ); } return contains( context, elem ); }; Sizzle.attr = function( elem, name ) { // Set document vars if needed // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( ( elem.ownerDocument || elem ) != document ) { setDocument( elem ); } var fn = Expr.attrHandle[ name.toLowerCase() ], // Don't get fooled by Object.prototype properties (jQuery #13807) val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? fn( elem, name, !documentIsHTML ) : undefined; return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute( name ) : ( val = elem.getAttributeNode( name ) ) && val.specified ? val.value : null; }; Sizzle.escape = function( sel ) { return ( sel + "" ).replace( rcssescape, fcssescape ); }; Sizzle.error = function( msg ) { throw new Error( "Syntax error, unrecognized expression: " + msg ); }; /** * Document sorting and removing duplicates * @param {ArrayLike} results */ Sizzle.uniqueSort = function( results ) { var elem, duplicates = [], j = 0, i = 0; // Unless we *know* we can detect duplicates, assume their presence hasDuplicate = !support.detectDuplicates; sortInput = !support.sortStable && results.slice( 0 ); results.sort( sortOrder ); if ( hasDuplicate ) { while ( ( elem = results[ i++ ] ) ) { if ( elem === results[ i ] ) { j = duplicates.push( i ); } } while ( j-- ) { results.splice( duplicates[ j ], 1 ); } } // Clear input after sorting to release objects // See https://github.com/jquery/sizzle/pull/225 sortInput = null; return results; }; /** * Utility function for retrieving the text value of an array of DOM nodes * @param {Array|Element} elem */ getText = Sizzle.getText = function( elem ) { var node, ret = "", i = 0, nodeType = elem.nodeType; if ( !nodeType ) { // If no nodeType, this is expected to be an array while ( ( node = elem[ i++ ] ) ) { // Do not traverse comment nodes ret += getText( node ); } } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { // Use textContent for elements // innerText usage removed for consistency of new lines (jQuery #11153) if ( typeof elem.textContent === "string" ) { return elem.textContent; } else { // Traverse its children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { ret += getText( elem ); } } } else if ( nodeType === 3 || nodeType === 4 ) { return elem.nodeValue; } // Do not include comment or processing instruction nodes return ret; }; Expr = Sizzle.selectors = { // Can be adjusted by the user cacheLength: 50, createPseudo: markFunction, match: matchExpr, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: true }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: true }, "~": { dir: "previousSibling" } }, preFilter: { "ATTR": function( match ) { match[ 1 ] = match[ 1 ].replace( runescape, funescape ); // Move the given value to match[3] whether quoted or unquoted match[ 3 ] = ( match[ 3 ] || match[ 4 ] || match[ 5 ] || "" ).replace( runescape, funescape ); if ( match[ 2 ] === "~=" ) { match[ 3 ] = " " + match[ 3 ] + " "; } return match.slice( 0, 4 ); }, "CHILD": function( match ) { /* matches from matchExpr["CHILD"] 1 type (only|nth|...) 2 what (child|of-type) 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 4 xn-component of xn+y argument ([+-]?\d*n|) 5 sign of xn-component 6 x of xn-component 7 sign of y-component 8 y of y-component */ match[ 1 ] = match[ 1 ].toLowerCase(); if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { // nth-* requires argument if ( !match[ 3 ] ) { Sizzle.error( match[ 0 ] ); } // numeric x and y parameters for Expr.filter.CHILD // remember that false/true cast respectively to 0/1 match[ 4 ] = +( match[ 4 ] ? match[ 5 ] + ( match[ 6 ] || 1 ) : 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); // other types prohibit arguments } else if ( match[ 3 ] ) { Sizzle.error( match[ 0 ] ); } return match; }, "PSEUDO": function( match ) { var excess, unquoted = !match[ 6 ] && match[ 2 ]; if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { return null; } // Accept quoted arguments as-is if ( match[ 3 ] ) { match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; // Strip excess characters from unquoted arguments } else if ( unquoted && rpseudo.test( unquoted ) && // Get excess from tokenize (recursively) ( excess = tokenize( unquoted, true ) ) && // advance to the next closing parenthesis ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { // excess is a negative index match[ 0 ] = match[ 0 ].slice( 0, excess ); match[ 2 ] = unquoted.slice( 0, excess ); } // Return only captures needed by the pseudo filter method (type and argument) return match.slice( 0, 3 ); } }, filter: { "TAG": function( nodeNameSelector ) { var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); return nodeNameSelector === "*" ? function() { return true; } : function( elem ) { return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; }; }, "CLASS": function( className ) { var pattern = classCache[ className + " " ]; return pattern || ( pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" ) ) && classCache( className, function( elem ) { return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute( "class" ) || "" ); } ); }, "ATTR": function( name, operator, check ) { return function( elem ) { var result = Sizzle.attr( elem, name ); if ( result == null ) { return operator === "!="; } if ( !operator ) { return true; } result += ""; /* eslint-disable max-len */ return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf( check ) === 0 : operator === "*=" ? check && result.indexOf( check ) > -1 : operator === "$=" ? check && result.slice( -check.length ) === check : operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : false; /* eslint-enable max-len */ }; }, "CHILD": function( type, what, _argument, first, last ) { var simple = type.slice( 0, 3 ) !== "nth", forward = type.slice( -4 ) !== "last", ofType = what === "of-type"; return first === 1 && last === 0 ? // Shortcut for :nth-*(n) function( elem ) { return !!elem.parentNode; } : function( elem, _context, xml ) { var cache, uniqueCache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false; if ( parent ) { // :(first|last|only)-(child|of-type) if ( simple ) { while ( dir ) { node = elem; while ( ( node = node[ dir ] ) ) { if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { return false; } } // Reverse direction for :only-* (if we haven't yet done so) start = dir = type === "only" && !start && "nextSibling"; } return true; } start = [ forward ? parent.firstChild : parent.lastChild ]; // non-xml :nth-child(...) stores cache data on `parent` if ( forward && useCache ) { // Seek `elem` from a previously-cached index // ...in a gzip-friendly way node = parent; outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || ( outerCache[ node.uniqueID ] = {} ); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex && cache[ 2 ]; node = nodeIndex && parent.childNodes[ nodeIndex ]; while ( ( node = ++nodeIndex && node && node[ dir ] || // Fallback to seeking `elem` from the start ( diff = nodeIndex = 0 ) || start.pop() ) ) { // When found, cache indexes on `parent` and break if ( node.nodeType === 1 && ++diff && node === elem ) { uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; break; } } } else { // Use previously-cached element index if available if ( useCache ) { // ...in a gzip-friendly way node = elem; outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || ( outerCache[ node.uniqueID ] = {} ); cache = uniqueCache[ type ] || []; nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; diff = nodeIndex; } // xml :nth-child(...) // or :nth-last-child(...) or :nth(-last)?-of-type(...) if ( diff === false ) { // Use the same loop as above to seek `elem` from the start while ( ( node = ++nodeIndex && node && node[ dir ] || ( diff = nodeIndex = 0 ) || start.pop() ) ) { if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { // Cache the index of each encountered element if ( useCache ) { outerCache = node[ expando ] || ( node[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ node.uniqueID ] || ( outerCache[ node.uniqueID ] = {} ); uniqueCache[ type ] = [ dirruns, diff ]; } if ( node === elem ) { break; } } } } } // Incorporate the offset, then check against cycle size diff -= last; return diff === first || ( diff % first === 0 && diff / first >= 0 ); } }; }, "PSEUDO": function( pseudo, argument ) { // pseudo-class names are case-insensitive // http://www.w3.org/TR/selectors/#pseudo-classes // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters // Remember that setFilters inherits from pseudos var args, fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || Sizzle.error( "unsupported pseudo: " + pseudo ); // The user may use createPseudo to indicate that // arguments are needed to create the filter function // just as Sizzle does if ( fn[ expando ] ) { return fn( argument ); } // But maintain support for old signatures if ( fn.length > 1 ) { args = [ pseudo, pseudo, "", argument ]; return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? markFunction( function( seed, matches ) { var idx, matched = fn( seed, argument ), i = matched.length; while ( i-- ) { idx = indexOf( seed, matched[ i ] ); seed[ idx ] = !( matches[ idx ] = matched[ i ] ); } } ) : function( elem ) { return fn( elem, 0, args ); }; } return fn; } }, pseudos: { // Potentially complex pseudos "not": markFunction( function( selector ) { // Trim the selector passed to compile // to avoid treating leading and trailing // spaces as combinators var input = [], results = [], matcher = compile( selector.replace( rtrim, "$1" ) ); return matcher[ expando ] ? markFunction( function( seed, matches, _context, xml ) { var elem, unmatched = matcher( seed, null, xml, [] ), i = seed.length; // Match elements unmatched by `matcher` while ( i-- ) { if ( ( elem = unmatched[ i ] ) ) { seed[ i ] = !( matches[ i ] = elem ); } } } ) : function( elem, _context, xml ) { input[ 0 ] = elem; matcher( input, null, xml, results ); // Don't keep the element (issue #299) input[ 0 ] = null; return !results.pop(); }; } ), "has": markFunction( function( selector ) { return function( elem ) { return Sizzle( selector, elem ).length > 0; }; } ), "contains": markFunction( function( text ) { text = text.replace( runescape, funescape ); return function( elem ) { return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; }; } ), // "Whether an element is represented by a :lang() selector // is based solely on the element's language value // being equal to the identifier C, // or beginning with the identifier C immediately followed by "-". // The matching of C against the element's language value is performed case-insensitively. // The identifier C does not have to be a valid language name." // http://www.w3.org/TR/selectors/#lang-pseudo "lang": markFunction( function( lang ) { // lang value must be a valid identifier if ( !ridentifier.test( lang || "" ) ) { Sizzle.error( "unsupported lang: " + lang ); } lang = lang.replace( runescape, funescape ).toLowerCase(); return function( elem ) { var elemLang; do { if ( ( elemLang = documentIsHTML ? elem.lang : elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { elemLang = elemLang.toLowerCase(); return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; } } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); return false; }; } ), // Miscellaneous "target": function( elem ) { var hash = window.location && window.location.hash; return hash && hash.slice( 1 ) === elem.id; }, "root": function( elem ) { return elem === docElem; }, "focus": function( elem ) { return elem === document.activeElement && ( !document.hasFocus || document.hasFocus() ) && !!( elem.type || elem.href || ~elem.tabIndex ); }, // Boolean properties "enabled": createDisabledPseudo( false ), "disabled": createDisabledPseudo( true ), "checked": function( elem ) { // In CSS3, :checked should return both checked and selected elements // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked var nodeName = elem.nodeName.toLowerCase(); return ( nodeName === "input" && !!elem.checked ) || ( nodeName === "option" && !!elem.selected ); }, "selected": function( elem ) { // Accessing this property makes selected-by-default // options in Safari work properly if ( elem.parentNode ) { // eslint-disable-next-line no-unused-expressions elem.parentNode.selectedIndex; } return elem.selected === true; }, // Contents "empty": function( elem ) { // http://www.w3.org/TR/selectors/#empty-pseudo // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), // but not by others (comment: 8; processing instruction: 7; etc.) // nodeType < 6 works because attributes (2) do not appear as children for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { if ( elem.nodeType < 6 ) { return false; } } return true; }, "parent": function( elem ) { return !Expr.pseudos[ "empty" ]( elem ); }, // Element/input types "header": function( elem ) { return rheader.test( elem.nodeName ); }, "input": function( elem ) { return rinputs.test( elem.nodeName ); }, "button": function( elem ) { var name = elem.nodeName.toLowerCase(); return name === "input" && elem.type === "button" || name === "button"; }, "text": function( elem ) { var attr; return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && // Support: IE<8 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" ( ( attr = elem.getAttribute( "type" ) ) == null || attr.toLowerCase() === "text" ); }, // Position-in-collection "first": createPositionalPseudo( function() { return [ 0 ]; } ), "last": createPositionalPseudo( function( _matchIndexes, length ) { return [ length - 1 ]; } ), "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { return [ argument < 0 ? argument + length : argument ]; } ), "even": createPositionalPseudo( function( matchIndexes, length ) { var i = 0; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; } ), "odd": createPositionalPseudo( function( matchIndexes, length ) { var i = 1; for ( ; i < length; i += 2 ) { matchIndexes.push( i ); } return matchIndexes; } ), "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument > length ? length : argument; for ( ; --i >= 0; ) { matchIndexes.push( i ); } return matchIndexes; } ), "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { var i = argument < 0 ? argument + length : argument; for ( ; ++i < length; ) { matchIndexes.push( i ); } return matchIndexes; } ) } }; Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; // Add button/input type pseudos for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { Expr.pseudos[ i ] = createInputPseudo( i ); } for ( i in { submit: true, reset: true } ) { Expr.pseudos[ i ] = createButtonPseudo( i ); } // Easy API for creating new setFilters function setFilters() {} setFilters.prototype = Expr.filters = Expr.pseudos; Expr.setFilters = new setFilters(); tokenize = Sizzle.tokenize = function( selector, parseOnly ) { var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[ selector + " " ]; if ( cached ) { return parseOnly ? 0 : cached.slice( 0 ); } soFar = selector; groups = []; preFilters = Expr.preFilter; while ( soFar ) { // Comma and first run if ( !matched || ( match = rcomma.exec( soFar ) ) ) { if ( match ) { // Don't consume trailing commas as valid soFar = soFar.slice( match[ 0 ].length ) || soFar; } groups.push( ( tokens = [] ) ); } matched = false; // Combinators if ( ( match = rcombinators.exec( soFar ) ) ) { matched = match.shift(); tokens.push( { value: matched, // Cast descendant combinators to space type: match[ 0 ].replace( rtrim, " " ) } ); soFar = soFar.slice( matched.length ); } // Filters for ( type in Expr.filter ) { if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || ( match = preFilters[ type ]( match ) ) ) ) { matched = match.shift(); tokens.push( { value: matched, type: type, matches: match } ); soFar = soFar.slice( matched.length ); } } if ( !matched ) { break; } } // Return the length of the invalid excess // if we're just parsing // Otherwise, throw an error or return tokens return parseOnly ? soFar.length : soFar ? Sizzle.error( selector ) : // Cache the tokens tokenCache( selector, groups ).slice( 0 ); }; function toSelector( tokens ) { var i = 0, len = tokens.length, selector = ""; for ( ; i < len; i++ ) { selector += tokens[ i ].value; } return selector; } function addCombinator( matcher, combinator, base ) { var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++; return combinator.first ? // Check against closest ancestor/preceding element function( elem, context, xml ) { while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { return matcher( elem, context, xml ); } } return false; } : // Check against all ancestor/preceding elements function( elem, context, xml ) { var oldCache, uniqueCache, outerCache, newCache = [ dirruns, doneName ]; // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching if ( xml ) { while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { if ( matcher( elem, context, xml ) ) { return true; } } } } else { while ( ( elem = elem[ dir ] ) ) { if ( elem.nodeType === 1 || checkNonElements ) { outerCache = elem[ expando ] || ( elem[ expando ] = {} ); // Support: IE <9 only // Defend against cloned attroperties (jQuery gh-1709) uniqueCache = outerCache[ elem.uniqueID ] || ( outerCache[ elem.uniqueID ] = {} ); if ( skip && skip === elem.nodeName.toLowerCase() ) { elem = elem[ dir ] || elem; } else if ( ( oldCache = uniqueCache[ key ] ) && oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { // Assign to newCache so results back-propagate to previous elements return ( newCache[ 2 ] = oldCache[ 2 ] ); } else { // Reuse newcache so results back-propagate to previous elements uniqueCache[ key ] = newCache; // A match means we're done; a fail means we have to keep checking if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { return true; } } } } } return false; }; } function elementMatcher( matchers ) { return matchers.length > 1 ? function( elem, context, xml ) { var i = matchers.length; while ( i-- ) { if ( !matchers[ i ]( elem, context, xml ) ) { return false; } } return true; } : matchers[ 0 ]; } function multipleContexts( selector, contexts, results ) { var i = 0, len = contexts.length; for ( ; i < len; i++ ) { Sizzle( selector, contexts[ i ], results ); } return results; } function condense( unmatched, map, filter, context, xml ) { var elem, newUnmatched = [], i = 0, len = unmatched.length, mapped = map != null; for ( ; i < len; i++ ) { if ( ( elem = unmatched[ i ] ) ) { if ( !filter || filter( elem, context, xml ) ) { newUnmatched.push( elem ); if ( mapped ) { map.push( i ); } } } } return newUnmatched; } function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { if ( postFilter && !postFilter[ expando ] ) { postFilter = setMatcher( postFilter ); } if ( postFinder && !postFinder[ expando ] ) { postFinder = setMatcher( postFinder, postSelector ); } return markFunction( function( seed, results, context, xml ) { var temp, i, elem, preMap = [], postMap = [], preexisting = results.length, // Get initial elements from seed or context elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), // Prefilter to get matcher input, preserving a map for seed-results synchronization matcherIn = preFilter && ( seed || !selector ) ? condense( elems, preMap, preFilter, context, xml ) : elems, matcherOut = matcher ? // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, postFinder || ( seed ? preFilter : preexisting || postFilter ) ? // ...intermediate processing is necessary [] : // ...otherwise use results directly results : matcherIn; // Find primary matches if ( matcher ) { matcher( matcherIn, matcherOut, context, xml ); } // Apply postFilter if ( postFilter ) { temp = condense( matcherOut, postMap ); postFilter( temp, [], context, xml ); // Un-match failing elements by moving them back to matcherIn i = temp.length; while ( i-- ) { if ( ( elem = temp[ i ] ) ) { matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); } } } if ( seed ) { if ( postFinder || preFilter ) { if ( postFinder ) { // Get the final matcherOut by condensing this intermediate into postFinder contexts temp = []; i = matcherOut.length; while ( i-- ) { if ( ( elem = matcherOut[ i ] ) ) { // Restore matcherIn since elem is not yet a final match temp.push( ( matcherIn[ i ] = elem ) ); } } postFinder( null, ( matcherOut = [] ), temp, xml ); } // Move matched elements from seed to results to keep them synchronized i = matcherOut.length; while ( i-- ) { if ( ( elem = matcherOut[ i ] ) && ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { seed[ temp ] = !( results[ temp ] = elem ); } } } // Add elements to results, through postFinder if defined } else { matcherOut = condense( matcherOut === results ? matcherOut.splice( preexisting, matcherOut.length ) : matcherOut ); if ( postFinder ) { postFinder( null, results, matcherOut, xml ); } else { push.apply( results, matcherOut ); } } } ); } function matcherFromTokens( tokens ) { var checkContext, matcher, j, len = tokens.length, leadingRelative = Expr.relative[ tokens[ 0 ].type ], implicitRelative = leadingRelative || Expr.relative[ " " ], i = leadingRelative ? 1 : 0, // The foundational matcher ensures that elements are reachable from top-level context(s) matchContext = addCombinator( function( elem ) { return elem === checkContext; }, implicitRelative, true ), matchAnyContext = addCombinator( function( elem ) { return indexOf( checkContext, elem ) > -1; }, implicitRelative, true ), matchers = [ function( elem, context, xml ) { var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( ( checkContext = context ).nodeType ? matchContext( elem, context, xml ) : matchAnyContext( elem, context, xml ) ); // Avoid hanging onto element (issue #299) checkContext = null; return ret; } ]; for ( ; i < len; i++ ) { if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; } else { matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); // Return special upon seeing a positional matcher if ( matcher[ expando ] ) { // Find the next relative operator (if any) for proper handling j = ++i; for ( ; j < len; j++ ) { if ( Expr.relative[ tokens[ j ].type ] ) { break; } } return setMatcher( i > 1 && elementMatcher( matchers ), i > 1 && toSelector( // If the preceding token was a descendant combinator, insert an implicit any-element `*` tokens .slice( 0, i - 1 ) .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) ).replace( rtrim, "$1" ), matcher, i < j && matcherFromTokens( tokens.slice( i, j ) ), j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), j < len && toSelector( tokens ) ); } matchers.push( matcher ); } } return elementMatcher( matchers ); } function matcherFromGroupMatchers( elementMatchers, setMatchers ) { var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function( seed, context, xml, results, outermost ) { var elem, j, matcher, matchedCount = 0, i = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, // We must always have either seed elements or outermost context elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), // Use integer dirruns iff this is the outermost matcher dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), len = elems.length; if ( outermost ) { // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq outermostContext = context == document || context || outermost; } // Add elements passing elementMatchers directly to results // Support: IE<9, Safari // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { if ( byElement && elem ) { j = 0; // Support: IE 11+, Edge 17 - 18+ // IE/Edge sometimes throw a "Permission denied" error when strict-comparing // two documents; shallow comparisons work. // eslint-disable-next-line eqeqeq if ( !context && elem.ownerDocument != document ) { setDocument( elem ); xml = !documentIsHTML; } while ( ( matcher = elementMatchers[ j++ ] ) ) { if ( matcher( elem, context || document, xml ) ) { results.push( elem ); break; } } if ( outermost ) { dirruns = dirrunsUnique; } } // Track unmatched elements for set filters if ( bySet ) { // They will have gone through all possible matchers if ( ( elem = !matcher && elem ) ) { matchedCount--; } // Lengthen the array for every element, matched or not if ( seed ) { unmatched.push( elem ); } } } // `i` is now the count of elements visited above, and adding it to `matchedCount` // makes the latter nonnegative. matchedCount += i; // Apply set filters to unmatched elements // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` // equals `i`), unless we didn't visit _any_ elements in the above loop because we have // no element matchers and no seed. // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that // case, which will result in a "00" `matchedCount` that differs from `i` but is also // numerically zero. if ( bySet && i !== matchedCount ) { j = 0; while ( ( matcher = setMatchers[ j++ ] ) ) { matcher( unmatched, setMatched, context, xml ); } if ( seed ) { // Reintegrate element matches to eliminate the need for sorting if ( matchedCount > 0 ) { while ( i-- ) { if ( !( unmatched[ i ] || setMatched[ i ] ) ) { setMatched[ i ] = pop.call( results ); } } } // Discard index placeholder values to get only actual matches setMatched = condense( setMatched ); } // Add matches to results push.apply( results, setMatched ); // Seedless set matches succeeding multiple successful matchers stipulate sorting if ( outermost && !seed && setMatched.length > 0 && ( matchedCount + setMatchers.length ) > 1 ) { Sizzle.uniqueSort( results ); } } // Override manipulation of globals by nested matchers if ( outermost ) { dirruns = dirrunsUnique; outermostContext = contextBackup; } return unmatched; }; return bySet ? markFunction( superMatcher ) : superMatcher; } compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { var i, setMatchers = [], elementMatchers = [], cached = compilerCache[ selector + " " ]; if ( !cached ) { // Generate a function of recursive functions that can be used to check each element if ( !match ) { match = tokenize( selector ); } i = match.length; while ( i-- ) { cached = matcherFromTokens( match[ i ] ); if ( cached[ expando ] ) { setMatchers.push( cached ); } else { elementMatchers.push( cached ); } } // Cache the compiled function cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); // Save selector and tokenization cached.selector = selector; } return cached; }; /** * A low-level selection function that works with Sizzle's compiled * selector functions * @param {String|Function} selector A selector or a pre-compiled * selector function built with Sizzle.compile * @param {Element} context * @param {Array} [results] * @param {Array} [seed] A set of elements to match against */ select = Sizzle.select = function( selector, context, results, seed ) { var i, tokens, token, type, find, compiled = typeof selector === "function" && selector, match = !seed && tokenize( ( selector = compiled.selector || selector ) ); results = results || []; // Try to minimize operations if there is only one selector in the list and no seed // (the latter of which guarantees us context) if ( match.length === 1 ) { // Reduce context if the leading compound selector is an ID tokens = match[ 0 ] = match[ 0 ].slice( 0 ); if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { context = ( Expr.find[ "ID" ]( token.matches[ 0 ] .replace( runescape, funescape ), context ) || [] )[ 0 ]; if ( !context ) { return results; // Precompiled matchers will still verify ancestry, so step up a level } else if ( compiled ) { context = context.parentNode; } selector = selector.slice( tokens.shift().value.length ); } // Fetch a seed set for right-to-left matching i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; while ( i-- ) { token = tokens[ i ]; // Abort if we hit a combinator if ( Expr.relative[ ( type = token.type ) ] ) { break; } if ( ( find = Expr.find[ type ] ) ) { // Search, expanding context for leading sibling combinators if ( ( seed = find( token.matches[ 0 ].replace( runescape, funescape ), rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || context ) ) ) { // If seed is empty or no tokens remain, we can return early tokens.splice( i, 1 ); selector = seed.length && toSelector( tokens ); if ( !selector ) { push.apply( results, seed ); return results; } break; } } } } // Compile and execute a filtering function if one is not provided // Provide `match` to avoid retokenization if we modified the selector above ( compiled || compile( selector, match ) )( seed, context, !documentIsHTML, results, !context || rsibling.test( selector ) && testContext( context.parentNode ) || context ); return results; }; // One-time assignments // Sort stability support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; // Support: Chrome 14-35+ // Always assume duplicates if they aren't passed to the comparison function support.detectDuplicates = !!hasDuplicate; // Initialize against the default document setDocument(); // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) // Detached nodes confoundingly follow *each other* support.sortDetached = assert( function( el ) { // Should return 1, but returns 4 (following) return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; } ); // Support: IE<8 // Prevent attribute/property "interpolation" // https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx if ( !assert( function( el ) { el.innerHTML = "<a href='#'></a>"; return el.firstChild.getAttribute( "href" ) === "#"; } ) ) { addHandle( "type|href|height|width", function( elem, name, isXML ) { if ( !isXML ) { return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); } } ); } // Support: IE<9 // Use defaultValue in place of getAttribute("value") if ( !support.attributes || !assert( function( el ) { el.innerHTML = "<input/>"; el.firstChild.setAttribute( "value", "" ); return el.firstChild.getAttribute( "value" ) === ""; } ) ) { addHandle( "value", function( elem, _name, isXML ) { if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { return elem.defaultValue; } } ); } // Support: IE<9 // Use getAttributeNode to fetch booleans when getAttribute lies if ( !assert( function( el ) { return el.getAttribute( "disabled" ) == null; } ) ) { addHandle( booleans, function( elem, name, isXML ) { var val; if ( !isXML ) { return elem[ name ] === true ? name.toLowerCase() : ( val = elem.getAttributeNode( name ) ) && val.specified ? val.value : null; } } ); } return Sizzle; } )( window ); jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; // Deprecated jQuery.expr[ ":" ] = jQuery.expr.pseudos; jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; jQuery.text = Sizzle.getText; jQuery.isXMLDoc = Sizzle.isXML; jQuery.contains = Sizzle.contains; jQuery.escapeSelector = Sizzle.escape; var dir = function( elem, dir, until ) { var matched = [], truncate = until !== undefined; while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { if ( elem.nodeType === 1 ) { if ( truncate && jQuery( elem ).is( until ) ) { break; } matched.push( elem ); } } return matched; }; var siblings = function( n, elem ) { var matched = []; for ( ; n; n = n.nextSibling ) { if ( n.nodeType === 1 && n !== elem ) { matched.push( n ); } } return matched; }; var rneedsContext = jQuery.expr.match.needsContext; function nodeName( elem, name ) { return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); }; var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); // Implement the identical functionality for filter and not function winnow( elements, qualifier, not ) { if ( isFunction( qualifier ) ) { return jQuery.grep( elements, function( elem, i ) { return !!qualifier.call( elem, i, elem ) !== not; } ); } // Single element if ( qualifier.nodeType ) { return jQuery.grep( elements, function( elem ) { return ( elem === qualifier ) !== not; } ); } // Arraylike of elements (jQuery, arguments, Array) if ( typeof qualifier !== "string" ) { return jQuery.grep( elements, function( elem ) { return ( indexOf.call( qualifier, elem ) > -1 ) !== not; } ); } // Filtered directly for both simple and complex selectors return jQuery.filter( qualifier, elements, not ); } jQuery.filter = function( expr, elems, not ) { var elem = elems[ 0 ]; if ( not ) { expr = ":not(" + expr + ")"; } if ( elems.length === 1 && elem.nodeType === 1 ) { return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; } return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { return elem.nodeType === 1; } ) ); }; jQuery.fn.extend( { find: function( selector ) { var i, ret, len = this.length, self = this; if ( typeof selector !== "string" ) { return this.pushStack( jQuery( selector ).filter( function() { for ( i = 0; i < len; i++ ) { if ( jQuery.contains( self[ i ], this ) ) { return true; } } } ) ); } ret = this.pushStack( [] ); for ( i = 0; i < len; i++ ) { jQuery.find( selector, self[ i ], ret ); } return len > 1 ? jQuery.uniqueSort( ret ) : ret; }, filter: function( selector ) { return this.pushStack( winnow( this, selector || [], false ) ); }, not: function( selector ) { return this.pushStack( winnow( this, selector || [], true ) ); }, is: function( selector ) { return !!winnow( this, // If this is a positional/relative selector, check membership in the returned set // so $("p:first").is("p:last") won't return true for a doc with two "p". typeof selector === "string" && rneedsContext.test( selector ) ? jQuery( selector ) : selector || [], false ).length; } } ); // Initialize a jQuery object // A central reference to the root jQuery(document) var rootjQuery, // A simple way to check for HTML strings // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) // Strict HTML recognition (#11290: must start with <) // Shortcut simple #id case for speed rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, init = jQuery.fn.init = function( selector, context, root ) { var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false) if ( !selector ) { return this; } // Method init() accepts an alternate rootjQuery // so migrate can support jQuery.sub (gh-2101) root = root || rootjQuery; // Handle HTML strings if ( typeof selector === "string" ) { if ( selector[ 0 ] === "<" && selector[ selector.length - 1 ] === ">" && selector.length >= 3 ) { // Assume that strings that start and end with <> are HTML and skip the regex check match = [ null, selector, null ]; } else { match = rquickExpr.exec( selector ); } // Match html or make sure no context is specified for #id if ( match && ( match[ 1 ] || !context ) ) { // HANDLE: $(html) -> $(array) if ( match[ 1 ] ) { context = context instanceof jQuery ? context[ 0 ] : context; // Option to run scripts is true for back-compat // Intentionally let the error be thrown if parseHTML is not present jQuery.merge( this, jQuery.parseHTML( match[ 1 ], context && context.nodeType ? context.ownerDocument || context : document, true ) ); // HANDLE: $(html, props) if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { for ( match in context ) { // Properties of context are called as methods if possible if ( isFunction( this[ match ] ) ) { this[ match ]( context[ match ] ); // ...and otherwise set as attributes } else { this.attr( match, context[ match ] ); } } } return this; // HANDLE: $(#id) } else { elem = document.getElementById( match[ 2 ] ); if ( elem ) { // Inject the element directly into the jQuery object this[ 0 ] = elem; this.length = 1; } return this; } // HANDLE: $(expr, $(...)) } else if ( !context || context.jquery ) { return ( context || root ).find( selector ); // HANDLE: $(expr, context) // (which is just equivalent to: $(context).find(expr) } else { return this.constructor( context ).find( selector ); } // HANDLE: $(DOMElement) } else if ( selector.nodeType ) { this[ 0 ] = selector; this.length = 1; return this; // HANDLE: $(function) // Shortcut for document ready } else if ( isFunction( selector ) ) { return root.ready !== undefined ? root.ready( selector ) : // Execute immediately if ready is not present selector( jQuery ); } return jQuery.makeArray( selector, this ); }; // Give the init function the jQuery prototype for later instantiation init.prototype = jQuery.fn; // Initialize central reference rootjQuery = jQuery( document ); var rparentsprev = /^(?:parents|prev(?:Until|All))/, // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique = { children: true, contents: true, next: true, prev: true }; jQuery.fn.extend( { has: function( target ) { var targets = jQuery( target, this ), l = targets.length; return this.filter( function() { var i = 0; for ( ; i < l; i++ ) { if ( jQuery.contains( this, targets[ i ] ) ) { return true; } } } ); }, closest: function( selectors, context ) { var cur, i = 0, l = this.length, matched = [], targets = typeof selectors !== "string" && jQuery( selectors ); // Positional selectors never match, since there's no _selection_ context if ( !rneedsContext.test( selectors ) ) { for ( ; i < l; i++ ) { for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { // Always skip document fragments if ( cur.nodeType < 11 && ( targets ? targets.index( cur ) > -1 : // Don't pass non-elements to Sizzle cur.nodeType === 1 && jQuery.find.matchesSelector( cur, selectors ) ) ) { matched.push( cur ); break; } } } } return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); }, // Determine the position of an element within the set index: function( elem ) { // No argument, return index in parent if ( !elem ) { return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; } // Index in selector if ( typeof elem === "string" ) { return indexOf.call( jQuery( elem ), this[ 0 ] ); } // Locate the position of the desired element return indexOf.call( this, // If it receives a jQuery object, the first element is used elem.jquery ? elem[ 0 ] : elem ); }, add: function( selector, context ) { return this.pushStack( jQuery.uniqueSort( jQuery.merge( this.get(), jQuery( selector, context ) ) ) ); }, addBack: function( selector ) { return this.add( selector == null ? this.prevObject : this.prevObject.filter( selector ) ); } } ); function sibling( cur, dir ) { while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} return cur; } jQuery.each( { parent: function( elem ) { var parent = elem.parentNode; return parent && parent.nodeType !== 11 ? parent : null; }, parents: function( elem ) { return dir( elem, "parentNode" ); }, parentsUntil: function( elem, _i, until ) { return dir( elem, "parentNode", until ); }, next: function( elem ) { return sibling( elem, "nextSibling" ); }, prev: function( elem ) { return sibling( elem, "previousSibling" ); }, nextAll: function( elem ) { return dir( elem, "nextSibling" ); }, prevAll: function( elem ) { return dir( elem, "previousSibling" ); }, nextUntil: function( elem, _i, until ) { return dir( elem, "nextSibling", until ); }, prevUntil: function( elem, _i, until ) { return dir( elem, "previousSibling", until ); }, siblings: function( elem ) { return siblings( ( elem.parentNode || {} ).firstChild, elem ); }, children: function( elem ) { return siblings( elem.firstChild ); }, contents: function( elem ) { if ( elem.contentDocument != null && // Support: IE 11+ // <object> elements with no `data` attribute has an object // `contentDocument` with a `null` prototype. getProto( elem.contentDocument ) ) { return elem.contentDocument; } // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only // Treat the template element as a regular one in browsers that // don't support it. if ( nodeName( elem, "template" ) ) { elem = elem.content || elem; } return jQuery.merge( [], elem.childNodes ); } }, function( name, fn ) { jQuery.fn[ name ] = function( until, selector ) { var matched = jQuery.map( this, fn, until ); if ( name.slice( -5 ) !== "Until" ) { selector = until; } if ( selector && typeof selector === "string" ) { matched = jQuery.filter( selector, matched ); } if ( this.length > 1 ) { // Remove duplicates if ( !guaranteedUnique[ name ] ) { jQuery.uniqueSort( matched ); } // Reverse order for parents* and prev-derivatives if ( rparentsprev.test( name ) ) { matched.reverse(); } } return this.pushStack( matched ); }; } ); var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); // Convert String-formatted options into Object-formatted ones function createOptions( options ) { var object = {}; jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { object[ flag ] = true; } ); return object; } /* * Create a callback list using the following parameters: * * options: an optional list of space-separated options that will change how * the callback list behaves or a more traditional option object * * By default a callback list will act like an event callback list and can be * "fired" multiple times. * * Possible options: * * once: will ensure the callback list can only be fired once (like a Deferred) * * memory: will keep track of previous values and will call any callback added * after the list has been fired right away with the latest "memorized" * values (like a Deferred) * * unique: will ensure a callback can only be added once (no duplicate in the list) * * stopOnFalse: interrupt callings when a callback returns false * */ jQuery.Callbacks = function( options ) { // Convert options from String-formatted to Object-formatted if needed // (we check in cache first) options = typeof options === "string" ? createOptions( options ) : jQuery.extend( {}, options ); var // Flag to know if list is currently firing firing, // Last fire value for non-forgettable lists memory, // Flag to know if list was already fired fired, // Flag to prevent firing locked, // Actual callback list list = [], // Queue of execution data for repeatable lists queue = [], // Index of currently firing callback (modified by add/remove as needed) firingIndex = -1, // Fire callbacks fire = function() { // Enforce single-firing locked = locked || options.once; // Execute callbacks for all pending executions, // respecting firingIndex overrides and runtime changes fired = firing = true; for ( ; queue.length; firingIndex = -1 ) { memory = queue.shift(); while ( ++firingIndex < list.length ) { // Run callback and check for early termination if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && options.stopOnFalse ) { // Jump to end and forget the data so .add doesn't re-fire firingIndex = list.length; memory = false; } } } // Forget the data if we're done with it if ( !options.memory ) { memory = false; } firing = false; // Clean up if we're done firing for good if ( locked ) { // Keep an empty list if we have data for future add calls if ( memory ) { list = []; // Otherwise, this object is spent } else { list = ""; } } }, // Actual Callbacks object self = { // Add a callback or a collection of callbacks to the list add: function() { if ( list ) { // If we have memory from a past run, we should fire after adding if ( memory && !firing ) { firingIndex = list.length - 1; queue.push( memory ); } ( function add( args ) { jQuery.each( args, function( _, arg ) { if ( isFunction( arg ) ) { if ( !options.unique || !self.has( arg ) ) { list.push( arg ); } } else if ( arg && arg.length && toType( arg ) !== "string" ) { // Inspect recursively add( arg ); } } ); } )( arguments ); if ( memory && !firing ) { fire(); } } return this; }, // Remove a callback from the list remove: function() { jQuery.each( arguments, function( _, arg ) { var index; while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { list.splice( index, 1 ); // Handle firing indexes if ( index <= firingIndex ) { firingIndex--; } } } ); return this; }, // Check if a given callback is in the list. // If no argument is given, return whether or not list has callbacks attached. has: function( fn ) { return fn ? jQuery.inArray( fn, list ) > -1 : list.length > 0; }, // Remove all callbacks from the list empty: function() { if ( list ) { list = []; } return this; }, // Disable .fire and .add // Abort any current/pending executions // Clear all callbacks and values disable: function() { locked = queue = []; list = memory = ""; return this; }, disabled: function() { return !list; }, // Disable .fire // Also disable .add unless we have memory (since it would have no effect) // Abort any pending executions lock: function() { locked = queue = []; if ( !memory && !firing ) { list = memory = ""; } return this; }, locked: function() { return !!locked; }, // Call all callbacks with the given context and arguments fireWith: function( context, args ) { if ( !locked ) { args = args || []; args = [ context, args.slice ? args.slice() : args ]; queue.push( args ); if ( !firing ) { fire(); } } return this; }, // Call all the callbacks with the given arguments fire: function() { self.fireWith( this, arguments ); return this; }, // To know if the callbacks have already been called at least once fired: function() { return !!fired; } }; return self; }; function Identity( v ) { return v; } function Thrower( ex ) { throw ex; } function adoptValue( value, resolve, reject, noValue ) { var method; try { // Check for promise aspect first to privilege synchronous behavior if ( value && isFunction( ( method = value.promise ) ) ) { method.call( value ).done( resolve ).fail( reject ); // Other thenables } else if ( value && isFunction( ( method = value.then ) ) ) { method.call( value, resolve, reject ); // Other non-thenables } else { // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: // * false: [ value ].slice( 0 ) => resolve( value ) // * true: [ value ].slice( 1 ) => resolve() resolve.apply( undefined, [ value ].slice( noValue ) ); } // For Promises/A+, convert exceptions into rejections // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in // Deferred#then to conditionally suppress rejection. } catch ( value ) { // Support: Android 4.0 only // Strict mode functions invoked without .call/.apply get global-object context reject.apply( undefined, [ value ] ); } } jQuery.extend( { Deferred: function( func ) { var tuples = [ // action, add listener, callbacks, // ... .then handlers, argument index, [final state] [ "notify", "progress", jQuery.Callbacks( "memory" ), jQuery.Callbacks( "memory" ), 2 ], [ "resolve", "done", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 0, "resolved" ], [ "reject", "fail", jQuery.Callbacks( "once memory" ), jQuery.Callbacks( "once memory" ), 1, "rejected" ] ], state = "pending", promise = { state: function() { return state; }, always: function() { deferred.done( arguments ).fail( arguments ); return this; }, "catch": function( fn ) { return promise.then( null, fn ); }, // Keep pipe for back-compat pipe: function( /* fnDone, fnFail, fnProgress */ ) { var fns = arguments; return jQuery.Deferred( function( newDefer ) { jQuery.each( tuples, function( _i, tuple ) { // Map tuples (progress, done, fail) to arguments (done, fail, progress) var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; // deferred.progress(function() { bind to newDefer or newDefer.notify }) // deferred.done(function() { bind to newDefer or newDefer.resolve }) // deferred.fail(function() { bind to newDefer or newDefer.reject }) deferred[ tuple[ 1 ] ]( function() { var returned = fn && fn.apply( this, arguments ); if ( returned && isFunction( returned.promise ) ) { returned.promise() .progress( newDefer.notify ) .done( newDefer.resolve ) .fail( newDefer.reject ); } else { newDefer[ tuple[ 0 ] + "With" ]( this, fn ? [ returned ] : arguments ); } } ); } ); fns = null; } ).promise(); }, then: function( onFulfilled, onRejected, onProgress ) { var maxDepth = 0; function resolve( depth, deferred, handler, special ) { return function() { var that = this, args = arguments, mightThrow = function() { var returned, then; // Support: Promises/A+ section 2.3.3.3.3 // https://promisesaplus.com/#point-59 // Ignore double-resolution attempts if ( depth < maxDepth ) { return; } returned = handler.apply( that, args ); // Support: Promises/A+ section 2.3.1 // https://promisesaplus.com/#point-48 if ( returned === deferred.promise() ) { throw new TypeError( "Thenable self-resolution" ); } // Support: Promises/A+ sections 2.3.3.1, 3.5 // https://promisesaplus.com/#point-54 // https://promisesaplus.com/#point-75 // Retrieve `then` only once then = returned && // Support: Promises/A+ section 2.3.4 // https://promisesaplus.com/#point-64 // Only check objects and functions for thenability ( typeof returned === "object" || typeof returned === "function" ) && returned.then; // Handle a returned thenable if ( isFunction( then ) ) { // Special processors (notify) just wait for resolution if ( special ) { then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ) ); // Normal processors (resolve) also hook into progress } else { // ...and disregard older resolution values maxDepth++; then.call( returned, resolve( maxDepth, deferred, Identity, special ), resolve( maxDepth, deferred, Thrower, special ), resolve( maxDepth, deferred, Identity, deferred.notifyWith ) ); } // Handle all other returned values } else { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Identity ) { that = undefined; args = [ returned ]; } // Process the value(s) // Default process is resolve ( special || deferred.resolveWith )( that, args ); } }, // Only normal processors (resolve) catch and reject exceptions process = special ? mightThrow : function() { try { mightThrow(); } catch ( e ) { if ( jQuery.Deferred.exceptionHook ) { jQuery.Deferred.exceptionHook( e, process.stackTrace ); } // Support: Promises/A+ section 2.3.3.3.4.1 // https://promisesaplus.com/#point-61 // Ignore post-resolution exceptions if ( depth + 1 >= maxDepth ) { // Only substitute handlers pass on context // and multiple values (non-spec behavior) if ( handler !== Thrower ) { that = undefined; args = [ e ]; } deferred.rejectWith( that, args ); } } }; // Support: Promises/A+ section 2.3.3.3.1 // https://promisesaplus.com/#point-57 // Re-resolve promises immediately to dodge false rejection from // subsequent errors if ( depth ) { process(); } else { // Call an optional hook to record the stack, in case of exception // since it's otherwise lost when execution goes async if ( jQuery.Deferred.getStackHook ) { process.stackTrace = jQuery.Deferred.getStackHook(); } window.setTimeout( process ); } }; } return jQuery.Deferred( function( newDefer ) { // progress_handlers.add( ... ) tuples[ 0 ][ 3 ].add( resolve( 0, newDefer, isFunction( onProgress ) ? onProgress : Identity, newDefer.notifyWith ) ); // fulfilled_handlers.add( ... ) tuples[ 1 ][ 3 ].add( resolve( 0, newDefer, isFunction( onFulfilled ) ? onFulfilled : Identity ) ); // rejected_handlers.add( ... ) tuples[ 2 ][ 3 ].add( resolve( 0, newDefer, isFunction( onRejected ) ? onRejected : Thrower ) ); } ).promise(); }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { return obj != null ? jQuery.extend( obj, promise ) : promise; } }, deferred = {}; // Add list-specific methods jQuery.each( tuples, function( i, tuple ) { var list = tuple[ 2 ], stateString = tuple[ 5 ]; // promise.progress = list.add // promise.done = list.add // promise.fail = list.add promise[ tuple[ 1 ] ] = list.add; // Handle state if ( stateString ) { list.add( function() { // state = "resolved" (i.e., fulfilled) // state = "rejected" state = stateString; }, // rejected_callbacks.disable // fulfilled_callbacks.disable tuples[ 3 - i ][ 2 ].disable, // rejected_handlers.disable // fulfilled_handlers.disable tuples[ 3 - i ][ 3 ].disable, // progress_callbacks.lock tuples[ 0 ][ 2 ].lock, // progress_handlers.lock tuples[ 0 ][ 3 ].lock ); } // progress_handlers.fire // fulfilled_handlers.fire // rejected_handlers.fire list.add( tuple[ 3 ].fire ); // deferred.notify = function() { deferred.notifyWith(...) } // deferred.resolve = function() { deferred.resolveWith(...) } // deferred.reject = function() { deferred.rejectWith(...) } deferred[ tuple[ 0 ] ] = function() { deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); return this; }; // deferred.notifyWith = list.fireWith // deferred.resolveWith = list.fireWith // deferred.rejectWith = list.fireWith deferred[ tuple[ 0 ] + "With" ] = list.fireWith; } ); // Make the deferred a promise promise.promise( deferred ); // Call given func if any if ( func ) { func.call( deferred, deferred ); } // All done! return deferred; }, // Deferred helper when: function( singleValue ) { var // count of uncompleted subordinates remaining = arguments.length, // count of unprocessed arguments i = remaining, // subordinate fulfillment data resolveContexts = Array( i ), resolveValues = slice.call( arguments ), // the master Deferred master = jQuery.Deferred(), // subordinate callback factory updateFunc = function( i ) { return function( value ) { resolveContexts[ i ] = this; resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; if ( !( --remaining ) ) { master.resolveWith( resolveContexts, resolveValues ); } }; }; // Single- and empty arguments are adopted like Promise.resolve if ( remaining <= 1 ) { adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, !remaining ); // Use .then() to unwrap secondary thenables (cf. gh-3000) if ( master.state() === "pending" || isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { return master.then(); } } // Multiple arguments are aggregated like Promise.all array elements while ( i-- ) { adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); } return master.promise(); } } ); // These usually indicate a programmer mistake during development, // warn about them ASAP rather than swallowing them by default. var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; jQuery.Deferred.exceptionHook = function( error, stack ) { // Support: IE 8 - 9 only // Console exists when dev tools are open, which can happen at any time if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); } }; jQuery.readyException = function( error ) { window.setTimeout( function() { throw error; } ); }; // The deferred used on DOM ready var readyList = jQuery.Deferred(); jQuery.fn.ready = function( fn ) { readyList .then( fn ) // Wrap jQuery.readyException in a function so that the lookup // happens at the time of error handling instead of callback // registration. .catch( function( error ) { jQuery.readyException( error ); } ); return this; }; jQuery.extend( { // Is the DOM ready to be used? Set to true once it occurs. isReady: false, // A counter to track how many items to wait for before // the ready event fires. See #6781 readyWait: 1, // Handle when the DOM is ready ready: function( wait ) { // Abort if there are pending holds or we're already ready if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { return; } // Remember that the DOM is ready jQuery.isReady = true; // If a normal DOM Ready event fired, decrement, and wait if need be if ( wait !== true && --jQuery.readyWait > 0 ) { return; } // If there are functions bound, to execute readyList.resolveWith( document, [ jQuery ] ); } } ); jQuery.ready.then = readyList.then; // The ready event handler and self cleanup method function completed() { document.removeEventListener( "DOMContentLoaded", completed ); window.removeEventListener( "load", completed ); jQuery.ready(); } // Catch cases where $(document).ready() is called // after the browser event has already occurred. // Support: IE <=9 - 10 only // Older IE sometimes signals "interactive" too soon if ( document.readyState === "complete" || ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { // Handle it asynchronously to allow scripts the opportunity to delay ready window.setTimeout( jQuery.ready ); } else { // Use the handy event callback document.addEventListener( "DOMContentLoaded", completed ); // A fallback to window.onload, that will always work window.addEventListener( "load", completed ); } // Multifunctional method to get and set values of a collection // The value/s can optionally be executed if it's a function var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { var i = 0, len = elems.length, bulk = key == null; // Sets many values if ( toType( key ) === "object" ) { chainable = true; for ( i in key ) { access( elems, fn, i, key[ i ], true, emptyGet, raw ); } // Sets one value } else if ( value !== undefined ) { chainable = true; if ( !isFunction( value ) ) { raw = true; } if ( bulk ) { // Bulk operations run against the entire set if ( raw ) { fn.call( elems, value ); fn = null; // ...except when executing function values } else { bulk = fn; fn = function( elem, _key, value ) { return bulk.call( jQuery( elem ), value ); }; } } if ( fn ) { for ( ; i < len; i++ ) { fn( elems[ i ], key, raw ? value : value.call( elems[ i ], i, fn( elems[ i ], key ) ) ); } } } if ( chainable ) { return elems; } // Gets if ( bulk ) { return fn.call( elems ); } return len ? fn( elems[ 0 ], key ) : emptyGet; }; // Matches dashed string for camelizing var rmsPrefix = /^-ms-/, rdashAlpha = /-([a-z])/g; // Used by camelCase as callback to replace() function fcamelCase( _all, letter ) { return letter.toUpperCase(); } // Convert dashed to camelCase; used by the css and data modules // Support: IE <=9 - 11, Edge 12 - 15 // Microsoft forgot to hump their vendor prefix (#9572) function camelCase( string ) { return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); } var acceptData = function( owner ) { // Accepts only: // - Node // - Node.ELEMENT_NODE // - Node.DOCUMENT_NODE // - Object // - Any return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); }; function Data() { this.expando = jQuery.expando + Data.uid++; } Data.uid = 1; Data.prototype = { cache: function( owner ) { // Check if the owner object already has a cache var value = owner[ this.expando ]; // If not, create one if ( !value ) { value = {}; // We can accept data for non-element nodes in modern browsers, // but we should not, see #8335. // Always return an empty object. if ( acceptData( owner ) ) { // If it is a node unlikely to be stringify-ed or looped over // use plain assignment if ( owner.nodeType ) { owner[ this.expando ] = value; // Otherwise secure it in a non-enumerable property // configurable must be true to allow the property to be // deleted when data is removed } else { Object.defineProperty( owner, this.expando, { value: value, configurable: true } ); } } } return value; }, set: function( owner, data, value ) { var prop, cache = this.cache( owner ); // Handle: [ owner, key, value ] args // Always use camelCase key (gh-2257) if ( typeof data === "string" ) { cache[ camelCase( data ) ] = value; // Handle: [ owner, { properties } ] args } else { // Copy the properties one-by-one to the cache object for ( prop in data ) { cache[ camelCase( prop ) ] = data[ prop ]; } } return cache; }, get: function( owner, key ) { return key === undefined ? this.cache( owner ) : // Always use camelCase key (gh-2257) owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; }, access: function( owner, key, value ) { // In cases where either: // // 1. No key was specified // 2. A string key was specified, but no value provided // // Take the "read" path and allow the get method to determine // which value to return, respectively either: // // 1. The entire cache object // 2. The data stored at the key // if ( key === undefined || ( ( key && typeof key === "string" ) && value === undefined ) ) { return this.get( owner, key ); } // When the key is not a string, or both a key and value // are specified, set or extend (existing objects) with either: // // 1. An object of properties // 2. A key and value // this.set( owner, key, value ); // Since the "set" path can have two possible entry points // return the expected data based on which path was taken[*] return value !== undefined ? value : key; }, remove: function( owner, key ) { var i, cache = owner[ this.expando ]; if ( cache === undefined ) { return; } if ( key !== undefined ) { // Support array or space separated string of keys if ( Array.isArray( key ) ) { // If key is an array of keys... // We always set camelCase keys, so remove that. key = key.map( camelCase ); } else { key = camelCase( key ); // If a key with the spaces exists, use it. // Otherwise, create an array by matching non-whitespace key = key in cache ? [ key ] : ( key.match( rnothtmlwhite ) || [] ); } i = key.length; while ( i-- ) { delete cache[ key[ i ] ]; } } // Remove the expando if there's no more data if ( key === undefined || jQuery.isEmptyObject( cache ) ) { // Support: Chrome <=35 - 45 // Webkit & Blink performance suffers when deleting properties // from DOM nodes, so set to undefined instead // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) if ( owner.nodeType ) { owner[ this.expando ] = undefined; } else { delete owner[ this.expando ]; } } }, hasData: function( owner ) { var cache = owner[ this.expando ]; return cache !== undefined && !jQuery.isEmptyObject( cache ); } }; var dataPriv = new Data(); var dataUser = new Data(); // Implementation Summary // // 1. Enforce API surface and semantic compatibility with 1.9.x branch // 2. Improve the module's maintainability by reducing the storage // paths to a single mechanism. // 3. Use the same single mechanism to support "private" and "user" data. // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) // 5. Avoid exposing implementation details on user objects (eg. expando properties) // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, rmultiDash = /[A-Z]/g; function getData( data ) { if ( data === "true" ) { return true; } if ( data === "false" ) { return false; } if ( data === "null" ) { return null; } // Only convert to a number if it doesn't change the string if ( data === +data + "" ) { return +data; } if ( rbrace.test( data ) ) { return JSON.parse( data ); } return data; } function dataAttr( elem, key, data ) { var name; // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { data = getData( data ); } catch ( e ) {} // Make sure we set the data so it isn't changed later dataUser.set( elem, key, data ); } else { data = undefined; } } return data; } jQuery.extend( { hasData: function( elem ) { return dataUser.hasData( elem ) || dataPriv.hasData( elem ); }, data: function( elem, name, data ) { return dataUser.access( elem, name, data ); }, removeData: function( elem, name ) { dataUser.remove( elem, name ); }, // TODO: Now that all calls to _data and _removeData have been replaced // with direct calls to dataPriv methods, these can be deprecated. _data: function( elem, name, data ) { return dataPriv.access( elem, name, data ); }, _removeData: function( elem, name ) { dataPriv.remove( elem, name ); } } ); jQuery.fn.extend( { data: function( key, value ) { var i, name, data, elem = this[ 0 ], attrs = elem && elem.attributes; // Gets all values if ( key === undefined ) { if ( this.length ) { data = dataUser.get( elem ); if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { i = attrs.length; while ( i-- ) { // Support: IE 11 only // The attrs elements can be null (#14894) if ( attrs[ i ] ) { name = attrs[ i ].name; if ( name.indexOf( "data-" ) === 0 ) { name = camelCase( name.slice( 5 ) ); dataAttr( elem, name, data[ name ] ); } } } dataPriv.set( elem, "hasDataAttrs", true ); } } return data; } // Sets multiple values if ( typeof key === "object" ) { return this.each( function() { dataUser.set( this, key ); } ); } return access( this, function( value ) { var data; // The calling jQuery object (element matches) is not empty // (and therefore has an element appears at this[ 0 ]) and the // `value` parameter was not undefined. An empty jQuery object // will result in `undefined` for elem = this[ 0 ] which will // throw an exception if an attempt to read a data cache is made. if ( elem && value === undefined ) { // Attempt to get data from the cache // The key will always be camelCased in Data data = dataUser.get( elem, key ); if ( data !== undefined ) { return data; } // Attempt to "discover" the data in // HTML5 custom data-* attrs data = dataAttr( elem, key ); if ( data !== undefined ) { return data; } // We tried really hard, but the data doesn't exist. return; } // Set the data... this.each( function() { // We always store the camelCased key dataUser.set( this, key, value ); } ); }, null, value, arguments.length > 1, null, true ); }, removeData: function( key ) { return this.each( function() { dataUser.remove( this, key ); } ); } } ); jQuery.extend( { queue: function( elem, type, data ) { var queue; if ( elem ) { type = ( type || "fx" ) + "queue"; queue = dataPriv.get( elem, type ); // Speed up dequeue by getting out quickly if this is just a lookup if ( data ) { if ( !queue || Array.isArray( data ) ) { queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); } else { queue.push( data ); } } return queue || []; } }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), startLength = queue.length, fn = queue.shift(), hooks = jQuery._queueHooks( elem, type ), next = function() { jQuery.dequeue( elem, type ); }; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { fn = queue.shift(); startLength--; } if ( fn ) { // Add a progress sentinel to prevent the fx queue from being // automatically dequeued if ( type === "fx" ) { queue.unshift( "inprogress" ); } // Clear up the last queue stop function delete hooks.stop; fn.call( elem, next, hooks ); } if ( !startLength && hooks ) { hooks.empty.fire(); } }, // Not public - generate a queueHooks object, or return the current one _queueHooks: function( elem, type ) { var key = type + "queueHooks"; return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { empty: jQuery.Callbacks( "once memory" ).add( function() { dataPriv.remove( elem, [ type + "queue", key ] ); } ) } ); } } ); jQuery.fn.extend( { queue: function( type, data ) { var setter = 2; if ( typeof type !== "string" ) { data = type; type = "fx"; setter--; } if ( arguments.length < setter ) { return jQuery.queue( this[ 0 ], type ); } return data === undefined ? this : this.each( function() { var queue = jQuery.queue( this, type, data ); // Ensure a hooks for this queue jQuery._queueHooks( this, type ); if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { jQuery.dequeue( this, type ); } } ); }, dequeue: function( type ) { return this.each( function() { jQuery.dequeue( this, type ); } ); }, clearQueue: function( type ) { return this.queue( type || "fx", [] ); }, // Get a promise resolved when queues of a certain type // are emptied (fx is the type by default) promise: function( type, obj ) { var tmp, count = 1, defer = jQuery.Deferred(), elements = this, i = this.length, resolve = function() { if ( !( --count ) ) { defer.resolveWith( elements, [ elements ] ); } }; if ( typeof type !== "string" ) { obj = type; type = undefined; } type = type || "fx"; while ( i-- ) { tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); if ( tmp && tmp.empty ) { count++; tmp.empty.add( resolve ); } } resolve(); return defer.promise( obj ); } } ); var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; var documentElement = document.documentElement; var isAttached = function( elem ) { return jQuery.contains( elem.ownerDocument, elem ); }, composed = { composed: true }; // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only // Check attachment across shadow DOM boundaries when possible (gh-3504) // Support: iOS 10.0-10.2 only // Early iOS 10 versions support `attachShadow` but not `getRootNode`, // leading to errors. We need to check for `getRootNode`. if ( documentElement.getRootNode ) { isAttached = function( elem ) { return jQuery.contains( elem.ownerDocument, elem ) || elem.getRootNode( composed ) === elem.ownerDocument; }; } var isHiddenWithinTree = function( elem, el ) { // isHiddenWithinTree might be called from jQuery#filter function; // in that case, element will be second argument elem = el || elem; // Inline style trumps all return elem.style.display === "none" || elem.style.display === "" && // Otherwise, check computed style // Support: Firefox <=43 - 45 // Disconnected elements can have computed display: none, so first confirm that elem is // in the document. isAttached( elem ) && jQuery.css( elem, "display" ) === "none"; }; function adjustCSS( elem, prop, valueParts, tween ) { var adjusted, scale, maxIterations = 20, currentValue = tween ? function() { return tween.cur(); } : function() { return jQuery.css( elem, prop, "" ); }, initial = currentValue(), unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), // Starting value computation is required for potential unit mismatches initialInUnit = elem.nodeType && ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && rcssNum.exec( jQuery.css( elem, prop ) ); if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { // Support: Firefox <=54 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) initial = initial / 2; // Trust units reported by jQuery.css unit = unit || initialInUnit[ 3 ]; // Iteratively approximate from a nonzero starting point initialInUnit = +initial || 1; while ( maxIterations-- ) { // Evaluate and update our best guess (doubling guesses that zero out). // Finish if the scale equals or crosses 1 (making the old*new product non-positive). jQuery.style( elem, prop, initialInUnit + unit ); if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { maxIterations = 0; } initialInUnit = initialInUnit / scale; } initialInUnit = initialInUnit * 2; jQuery.style( elem, prop, initialInUnit + unit ); // Make sure we update the tween properties later on valueParts = valueParts || []; } if ( valueParts ) { initialInUnit = +initialInUnit || +initial || 0; // Apply relative offset (+=/-=) if specified adjusted = valueParts[ 1 ] ? initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : +valueParts[ 2 ]; if ( tween ) { tween.unit = unit; tween.start = initialInUnit; tween.end = adjusted; } } return adjusted; } var defaultDisplayMap = {}; function getDefaultDisplay( elem ) { var temp, doc = elem.ownerDocument, nodeName = elem.nodeName, display = defaultDisplayMap[ nodeName ]; if ( display ) { return display; } temp = doc.body.appendChild( doc.createElement( nodeName ) ); display = jQuery.css( temp, "display" ); temp.parentNode.removeChild( temp ); if ( display === "none" ) { display = "block"; } defaultDisplayMap[ nodeName ] = display; return display; } function showHide( elements, show ) { var display, elem, values = [], index = 0, length = elements.length; // Determine new display value for elements that need to change for ( ; index < length; index++ ) { elem = elements[ index ]; if ( !elem.style ) { continue; } display = elem.style.display; if ( show ) { // Since we force visibility upon cascade-hidden elements, an immediate (and slow) // check is required in this first loop unless we have a nonempty display value (either // inline or about-to-be-restored) if ( display === "none" ) { values[ index ] = dataPriv.get( elem, "display" ) || null; if ( !values[ index ] ) { elem.style.display = ""; } } if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { values[ index ] = getDefaultDisplay( elem ); } } else { if ( display !== "none" ) { values[ index ] = "none"; // Remember what we're overwriting dataPriv.set( elem, "display", display ); } } } // Set the display of the elements in a second loop to avoid constant reflow for ( index = 0; index < length; index++ ) { if ( values[ index ] != null ) { elements[ index ].style.display = values[ index ]; } } return elements; } jQuery.fn.extend( { show: function() { return showHide( this, true ); }, hide: function() { return showHide( this ); }, toggle: function( state ) { if ( typeof state === "boolean" ) { return state ? this.show() : this.hide(); } return this.each( function() { if ( isHiddenWithinTree( this ) ) { jQuery( this ).show(); } else { jQuery( this ).hide(); } } ); } } ); var rcheckableType = ( /^(?:checkbox|radio)$/i ); var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); ( function() { var fragment = document.createDocumentFragment(), div = fragment.appendChild( document.createElement( "div" ) ), input = document.createElement( "input" ); // Support: Android 4.0 - 4.3 only // Check state lost if the name is set (#11217) // Support: Windows Web Apps (WWA) // `name` and `type` must use .setAttribute for WWA (#14901) input.setAttribute( "type", "radio" ); input.setAttribute( "checked", "checked" ); input.setAttribute( "name", "t" ); div.appendChild( input ); // Support: Android <=4.1 only // Older WebKit doesn't clone checked state correctly in fragments support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; // Support: IE <=11 only // Make sure textarea (and checkbox) defaultValue is properly cloned div.innerHTML = "<textarea>x</textarea>"; support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; // Support: IE <=9 only // IE <=9 replaces <option> tags with their contents when inserted outside of // the select element. div.innerHTML = "<option></option>"; support.option = !!div.lastChild; } )(); // We have to close these tags to support XHTML (#13200) var wrapMap = { // XHTML parsers do not magically insert elements in the // same way that tag soup parsers do. So we cannot shorten // this by omitting <tbody> or other required elements. thead: [ 1, "<table>", "</table>" ], col: [ 2, "<table><colgroup>", "</colgroup></table>" ], tr: [ 2, "<table><tbody>", "</tbody></table>" ], td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], _default: [ 0, "", "" ] }; wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; wrapMap.th = wrapMap.td; // Support: IE <=9 only if ( !support.option ) { wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; } function getAll( context, tag ) { // Support: IE <=9 - 11 only // Use typeof to avoid zero-argument method invocation on host objects (#15151) var ret; if ( typeof context.getElementsByTagName !== "undefined" ) { ret = context.getElementsByTagName( tag || "*" ); } else if ( typeof context.querySelectorAll !== "undefined" ) { ret = context.querySelectorAll( tag || "*" ); } else { ret = []; } if ( tag === undefined || tag && nodeName( context, tag ) ) { return jQuery.merge( [ context ], ret ); } return ret; } // Mark scripts as having already been evaluated function setGlobalEval( elems, refElements ) { var i = 0, l = elems.length; for ( ; i < l; i++ ) { dataPriv.set( elems[ i ], "globalEval", !refElements || dataPriv.get( refElements[ i ], "globalEval" ) ); } } var rhtml = /<|&#?\w+;/; function buildFragment( elems, context, scripts, selection, ignored ) { var elem, tmp, tag, wrap, attached, j, fragment = context.createDocumentFragment(), nodes = [], i = 0, l = elems.length; for ( ; i < l; i++ ) { elem = elems[ i ]; if ( elem || elem === 0 ) { // Add nodes directly if ( toType( elem ) === "object" ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); // Convert non-html into a text node } else if ( !rhtml.test( elem ) ) { nodes.push( context.createTextNode( elem ) ); // Convert html into DOM nodes } else { tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); // Deserialize a standard representation tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); wrap = wrapMap[ tag ] || wrapMap._default; tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; // Descend through wrappers to the right content j = wrap[ 0 ]; while ( j-- ) { tmp = tmp.lastChild; } // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( nodes, tmp.childNodes ); // Remember the top-level container tmp = fragment.firstChild; // Ensure the created nodes are orphaned (#12392) tmp.textContent = ""; } } } // Remove wrapper from fragment fragment.textContent = ""; i = 0; while ( ( elem = nodes[ i++ ] ) ) { // Skip elements already in the context collection (trac-4087) if ( selection && jQuery.inArray( elem, selection ) > -1 ) { if ( ignored ) { ignored.push( elem ); } continue; } attached = isAttached( elem ); // Append to fragment tmp = getAll( fragment.appendChild( elem ), "script" ); // Preserve script evaluation history if ( attached ) { setGlobalEval( tmp ); } // Capture executables if ( scripts ) { j = 0; while ( ( elem = tmp[ j++ ] ) ) { if ( rscriptType.test( elem.type || "" ) ) { scripts.push( elem ); } } } } return fragment; } var rkeyEvent = /^key/, rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, rtypenamespace = /^([^.]*)(?:\.(.+)|)/; function returnTrue() { return true; } function returnFalse() { return false; } // Support: IE <=9 - 11+ // focus() and blur() are asynchronous, except when they are no-op. // So expect focus to be synchronous when the element is already active, // and blur to be synchronous when the element is not already active. // (focus and blur are always synchronous in other supported browsers, // this just defines when we can count on it). function expectSync( elem, type ) { return ( elem === safeActiveElement() ) === ( type === "focus" ); } // Support: IE <=9 only // Accessing document.activeElement can throw unexpectedly // https://bugs.jquery.com/ticket/13393 function safeActiveElement() { try { return document.activeElement; } catch ( err ) { } } function on( elem, types, selector, data, fn, one ) { var origFn, type; // Types can be a map of types/handlers if ( typeof types === "object" ) { // ( types-Object, selector, data ) if ( typeof selector !== "string" ) { // ( types-Object, data ) data = data || selector; selector = undefined; } for ( type in types ) { on( elem, type, selector, data, types[ type ], one ); } return elem; } if ( data == null && fn == null ) { // ( types, fn ) fn = selector; data = selector = undefined; } else if ( fn == null ) { if ( typeof selector === "string" ) { // ( types, selector, fn ) fn = data; data = undefined; } else { // ( types, data, fn ) fn = data; data = selector; selector = undefined; } } if ( fn === false ) { fn = returnFalse; } else if ( !fn ) { return elem; } if ( one === 1 ) { origFn = fn; fn = function( event ) { // Can use an empty set, since event contains the info jQuery().off( event ); return origFn.apply( this, arguments ); }; // Use same guid so caller can remove using origFn fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); } return elem.each( function() { jQuery.event.add( this, types, fn, data, selector ); } ); } /* * Helper functions for managing events -- not part of the public interface. * Props to Dean Edwards' addEvent library for many of the ideas. */ jQuery.event = { global: {}, add: function( elem, types, handler, data, selector ) { var handleObjIn, eventHandle, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.get( elem ); // Only attach events to objects that accept data if ( !acceptData( elem ) ) { return; } // Caller can pass in an object of custom data in lieu of the handler if ( handler.handler ) { handleObjIn = handler; handler = handleObjIn.handler; selector = handleObjIn.selector; } // Ensure that invalid selectors throw exceptions at attach time // Evaluate against documentElement in case elem is a non-element node (e.g., document) if ( selector ) { jQuery.find.matchesSelector( documentElement, selector ); } // Make sure that the handler has a unique ID, used to find/remove it later if ( !handler.guid ) { handler.guid = jQuery.guid++; } // Init the element's event structure and main handler, if this is the first if ( !( events = elemData.events ) ) { events = elemData.events = Object.create( null ); } if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; }; } // Handle multiple events separated by a space types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // There *must* be a type, no attaching namespace-only handlers if ( !type ) { continue; } // If event changes its type, use the special event handlers for the changed type special = jQuery.event.special[ type ] || {}; // If selector defined, determine special event api type, otherwise given type type = ( selector ? special.delegateType : special.bindType ) || type; // Update special based on newly reset type special = jQuery.event.special[ type ] || {}; // handleObj is passed to all event handlers handleObj = jQuery.extend( { type: type, origType: origType, data: data, handler: handler, guid: handler.guid, selector: selector, needsContext: selector && jQuery.expr.match.needsContext.test( selector ), namespace: namespaces.join( "." ) }, handleObjIn ); // Init the event handler queue if we're the first if ( !( handlers = events[ type ] ) ) { handlers = events[ type ] = []; handlers.delegateCount = 0; // Only use addEventListener if the special events handler returns false if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { if ( elem.addEventListener ) { elem.addEventListener( type, eventHandle ); } } } if ( special.add ) { special.add.call( elem, handleObj ); if ( !handleObj.handler.guid ) { handleObj.handler.guid = handler.guid; } } // Add to the element's handler list, delegates in front if ( selector ) { handlers.splice( handlers.delegateCount++, 0, handleObj ); } else { handlers.push( handleObj ); } // Keep track of which events have ever been used, for event optimization jQuery.event.global[ type ] = true; } }, // Detach an event or set of events from an element remove: function( elem, types, handler, selector, mappedTypes ) { var j, origCount, tmp, events, t, handleObj, special, handlers, type, namespaces, origType, elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); if ( !elemData || !( events = elemData.events ) ) { return; } // Once for each type.namespace in types; type may be omitted types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; t = types.length; while ( t-- ) { tmp = rtypenamespace.exec( types[ t ] ) || []; type = origType = tmp[ 1 ]; namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); // Unbind all events (on this namespace, if provided) for the element if ( !type ) { for ( type in events ) { jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); } continue; } special = jQuery.event.special[ type ] || {}; type = ( selector ? special.delegateType : special.bindType ) || type; handlers = events[ type ] || []; tmp = tmp[ 2 ] && new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); // Remove matching events origCount = j = handlers.length; while ( j-- ) { handleObj = handlers[ j ]; if ( ( mappedTypes || origType === handleObj.origType ) && ( !handler || handler.guid === handleObj.guid ) && ( !tmp || tmp.test( handleObj.namespace ) ) && ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { handlers.splice( j, 1 ); if ( handleObj.selector ) { handlers.delegateCount--; } if ( special.remove ) { special.remove.call( elem, handleObj ); } } } // Remove generic event handler if we removed something and no more handlers exist // (avoids potential for endless recursion during removal of special event handlers) if ( origCount && !handlers.length ) { if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { jQuery.removeEvent( elem, type, elemData.handle ); } delete events[ type ]; } } // Remove data and the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { dataPriv.remove( elem, "handle events" ); } }, dispatch: function( nativeEvent ) { var i, j, ret, matched, handleObj, handlerQueue, args = new Array( arguments.length ), // Make a writable jQuery.Event from the native event object event = jQuery.event.fix( nativeEvent ), handlers = ( dataPriv.get( this, "events" ) || Object.create( null ) )[ event.type ] || [], special = jQuery.event.special[ event.type ] || {}; // Use the fix-ed jQuery.Event rather than the (read-only) native event args[ 0 ] = event; for ( i = 1; i < arguments.length; i++ ) { args[ i ] = arguments[ i ]; } event.delegateTarget = this; // Call the preDispatch hook for the mapped type, and let it bail if desired if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { return; } // Determine handlers handlerQueue = jQuery.event.handlers.call( this, event, handlers ); // Run delegates first; they may want to stop propagation beneath us i = 0; while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { event.currentTarget = matched.elem; j = 0; while ( ( handleObj = matched.handlers[ j++ ] ) && !event.isImmediatePropagationStopped() ) { // If the event is namespaced, then each handler is only invoked if it is // specially universal or its namespaces are a superset of the event's. if ( !event.rnamespace || handleObj.namespace === false || event.rnamespace.test( handleObj.namespace ) ) { event.handleObj = handleObj; event.data = handleObj.data; ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || handleObj.handler ).apply( matched.elem, args ); if ( ret !== undefined ) { if ( ( event.result = ret ) === false ) { event.preventDefault(); event.stopPropagation(); } } } } } // Call the postDispatch hook for the mapped type if ( special.postDispatch ) { special.postDispatch.call( this, event ); } return event.result; }, handlers: function( event, handlers ) { var i, handleObj, sel, matchedHandlers, matchedSelectors, handlerQueue = [], delegateCount = handlers.delegateCount, cur = event.target; // Find delegate handlers if ( delegateCount && // Support: IE <=9 // Black-hole SVG <use> instance trees (trac-13180) cur.nodeType && // Support: Firefox <=42 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click // Support: IE 11 only // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) !( event.type === "click" && event.button >= 1 ) ) { for ( ; cur !== this; cur = cur.parentNode || this ) { // Don't check non-elements (#13208) // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { matchedHandlers = []; matchedSelectors = {}; for ( i = 0; i < delegateCount; i++ ) { handleObj = handlers[ i ]; // Don't conflict with Object.prototype properties (#13203) sel = handleObj.selector + " "; if ( matchedSelectors[ sel ] === undefined ) { matchedSelectors[ sel ] = handleObj.needsContext ? jQuery( sel, this ).index( cur ) > -1 : jQuery.find( sel, this, null, [ cur ] ).length; } if ( matchedSelectors[ sel ] ) { matchedHandlers.push( handleObj ); } } if ( matchedHandlers.length ) { handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); } } } } // Add the remaining (directly-bound) handlers cur = this; if ( delegateCount < handlers.length ) { handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); } return handlerQueue; }, addProp: function( name, hook ) { Object.defineProperty( jQuery.Event.prototype, name, { enumerable: true, configurable: true, get: isFunction( hook ) ? function() { if ( this.originalEvent ) { return hook( this.originalEvent ); } } : function() { if ( this.originalEvent ) { return this.originalEvent[ name ]; } }, set: function( value ) { Object.defineProperty( this, name, { enumerable: true, configurable: true, writable: true, value: value } ); } } ); }, fix: function( originalEvent ) { return originalEvent[ jQuery.expando ] ? originalEvent : new jQuery.Event( originalEvent ); }, special: { load: { // Prevent triggered image.load events from bubbling to window.load noBubble: true }, click: { // Utilize native event to ensure correct state for checkable inputs setup: function( data ) { // For mutual compressibility with _default, replace `this` access with a local var. // `|| data` is dead code meant only to preserve the variable through minification. var el = this || data; // Claim the first handler if ( rcheckableType.test( el.type ) && el.click && nodeName( el, "input" ) ) { // dataPriv.set( el, "click", ... ) leverageNative( el, "click", returnTrue ); } // Return false to allow normal processing in the caller return false; }, trigger: function( data ) { // For mutual compressibility with _default, replace `this` access with a local var. // `|| data` is dead code meant only to preserve the variable through minification. var el = this || data; // Force setup before triggering a click if ( rcheckableType.test( el.type ) && el.click && nodeName( el, "input" ) ) { leverageNative( el, "click" ); } // Return non-false to allow normal event-path propagation return true; }, // For cross-browser consistency, suppress native .click() on links // Also prevent it if we're currently inside a leveraged native-event stack _default: function( event ) { var target = event.target; return rcheckableType.test( target.type ) && target.click && nodeName( target, "input" ) && dataPriv.get( target, "click" ) || nodeName( target, "a" ); } }, beforeunload: { postDispatch: function( event ) { // Support: Firefox 20+ // Firefox doesn't alert if the returnValue field is not set. if ( event.result !== undefined && event.originalEvent ) { event.originalEvent.returnValue = event.result; } } } } }; // Ensure the presence of an event listener that handles manually-triggered // synthetic events by interrupting progress until reinvoked in response to // *native* events that it fires directly, ensuring that state changes have // already occurred before other listeners are invoked. function leverageNative( el, type, expectSync ) { // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add if ( !expectSync ) { if ( dataPriv.get( el, type ) === undefined ) { jQuery.event.add( el, type, returnTrue ); } return; } // Register the controller as a special universal handler for all event namespaces dataPriv.set( el, type, false ); jQuery.event.add( el, type, { namespace: false, handler: function( event ) { var notAsync, result, saved = dataPriv.get( this, type ); if ( ( event.isTrigger & 1 ) && this[ type ] ) { // Interrupt processing of the outer synthetic .trigger()ed event // Saved data should be false in such cases, but might be a leftover capture object // from an async native handler (gh-4350) if ( !saved.length ) { // Store arguments for use when handling the inner native event // There will always be at least one argument (an event object), so this array // will not be confused with a leftover capture object. saved = slice.call( arguments ); dataPriv.set( this, type, saved ); // Trigger the native event and capture its result // Support: IE <=9 - 11+ // focus() and blur() are asynchronous notAsync = expectSync( this, type ); this[ type ](); result = dataPriv.get( this, type ); if ( saved !== result || notAsync ) { dataPriv.set( this, type, false ); } else { result = {}; } if ( saved !== result ) { // Cancel the outer synthetic event event.stopImmediatePropagation(); event.preventDefault(); return result.value; } // If this is an inner synthetic event for an event with a bubbling surrogate // (focus or blur), assume that the surrogate already propagated from triggering the // native event and prevent that from happening again here. // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the // bubbling surrogate propagates *after* the non-bubbling base), but that seems // less bad than duplication. } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { event.stopPropagation(); } // If this is a native event triggered above, everything is now in order // Fire an inner synthetic event with the original arguments } else if ( saved.length ) { // ...and capture the result dataPriv.set( this, type, { value: jQuery.event.trigger( // Support: IE <=9 - 11+ // Extend with the prototype to reset the above stopImmediatePropagation() jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), saved.slice( 1 ), this ) } ); // Abort handling of the native event event.stopImmediatePropagation(); } } } ); } jQuery.removeEvent = function( elem, type, handle ) { // This "if" is needed for plain objects if ( elem.removeEventListener ) { elem.removeEventListener( type, handle ); } }; jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !( this instanceof jQuery.Event ) ) { return new jQuery.Event( src, props ); } // Event object if ( src && src.type ) { this.originalEvent = src; this.type = src.type; // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined && // Support: Android <=2.3 only src.returnValue === false ? returnTrue : returnFalse; // Create target properties // Support: Safari <=6 - 7 only // Target should not be a text node (#504, #13143) this.target = ( src.target && src.target.nodeType === 3 ) ? src.target.parentNode : src.target; this.currentTarget = src.currentTarget; this.relatedTarget = src.relatedTarget; // Event type } else { this.type = src; } // Put explicitly provided properties onto the event object if ( props ) { jQuery.extend( this, props ); } // Create a timestamp if incoming event doesn't have one this.timeStamp = src && src.timeStamp || Date.now(); // Mark it as fixed this[ jQuery.expando ] = true; }; // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding // https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html jQuery.Event.prototype = { constructor: jQuery.Event, isDefaultPrevented: returnFalse, isPropagationStopped: returnFalse, isImmediatePropagationStopped: returnFalse, isSimulated: false, preventDefault: function() { var e = this.originalEvent; this.isDefaultPrevented = returnTrue; if ( e && !this.isSimulated ) { e.preventDefault(); } }, stopPropagation: function() { var e = this.originalEvent; this.isPropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopPropagation(); } }, stopImmediatePropagation: function() { var e = this.originalEvent; this.isImmediatePropagationStopped = returnTrue; if ( e && !this.isSimulated ) { e.stopImmediatePropagation(); } this.stopPropagation(); } }; // Includes all common event props including KeyEvent and MouseEvent specific props jQuery.each( { altKey: true, bubbles: true, cancelable: true, changedTouches: true, ctrlKey: true, detail: true, eventPhase: true, metaKey: true, pageX: true, pageY: true, shiftKey: true, view: true, "char": true, code: true, charCode: true, key: true, keyCode: true, button: true, buttons: true, clientX: true, clientY: true, offsetX: true, offsetY: true, pointerId: true, pointerType: true, screenX: true, screenY: true, targetTouches: true, toElement: true, touches: true, which: function( event ) { var button = event.button; // Add which for key events if ( event.which == null && rkeyEvent.test( event.type ) ) { return event.charCode != null ? event.charCode : event.keyCode; } // Add which for click: 1 === left; 2 === middle; 3 === right if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { if ( button & 1 ) { return 1; } if ( button & 2 ) { return 3; } if ( button & 4 ) { return 2; } return 0; } return event.which; } }, jQuery.event.addProp ); jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { jQuery.event.special[ type ] = { // Utilize native event if possible so blur/focus sequence is correct setup: function() { // Claim the first handler // dataPriv.set( this, "focus", ... ) // dataPriv.set( this, "blur", ... ) leverageNative( this, type, expectSync ); // Return false to allow normal processing in the caller return false; }, trigger: function() { // Force setup before trigger leverageNative( this, type ); // Return non-false to allow normal event-path propagation return true; }, delegateType: delegateType }; } ); // Create mouseenter/leave events using mouseover/out and event-time checks // so that event delegation works in jQuery. // Do the same for pointerenter/pointerleave and pointerover/pointerout // // Support: Safari 7 only // Safari sends mouseenter too often; see: // https://bugs.chromium.org/p/chromium/issues/detail?id=470258 // for the description of the bug (it existed in older Chrome versions as well). jQuery.each( { mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function( orig, fix ) { jQuery.event.special[ orig ] = { delegateType: fix, bindType: fix, handle: function( event ) { var ret, target = this, related = event.relatedTarget, handleObj = event.handleObj; // For mouseenter/leave call the handler if related is outside the target. // NB: No relatedTarget if the mouse left/entered the browser window if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { event.type = handleObj.origType; ret = handleObj.handler.apply( this, arguments ); event.type = fix; } return ret; } }; } ); jQuery.fn.extend( { on: function( types, selector, data, fn ) { return on( this, types, selector, data, fn ); }, one: function( types, selector, data, fn ) { return on( this, types, selector, data, fn, 1 ); }, off: function( types, selector, fn ) { var handleObj, type; if ( types && types.preventDefault && types.handleObj ) { // ( event ) dispatched jQuery.Event handleObj = types.handleObj; jQuery( types.delegateTarget ).off( handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler ); return this; } if ( typeof types === "object" ) { // ( types-object [, selector] ) for ( type in types ) { this.off( type, selector, types[ type ] ); } return this; } if ( selector === false || typeof selector === "function" ) { // ( types [, fn] ) fn = selector; selector = undefined; } if ( fn === false ) { fn = returnFalse; } return this.each( function() { jQuery.event.remove( this, types, fn, selector ); } ); } } ); var // Support: IE <=10 - 11, Edge 12 - 13 only // In IE/Edge using regex groups here causes severe slowdowns. // See https://connect.microsoft.com/IE/feedback/details/1736512/ rnoInnerhtml = /<script|<style|<link/i, // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; // Prefer a tbody over its parent table for containing new rows function manipulationTarget( elem, content ) { if ( nodeName( elem, "table" ) && nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { return jQuery( elem ).children( "tbody" )[ 0 ] || elem; } return elem; } // Replace/restore the type attribute of script elements for safe DOM manipulation function disableScript( elem ) { elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; return elem; } function restoreScript( elem ) { if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { elem.type = elem.type.slice( 5 ); } else { elem.removeAttribute( "type" ); } return elem; } function cloneCopyEvent( src, dest ) { var i, l, type, pdataOld, udataOld, udataCur, events; if ( dest.nodeType !== 1 ) { return; } // 1. Copy private data: events, handlers, etc. if ( dataPriv.hasData( src ) ) { pdataOld = dataPriv.get( src ); events = pdataOld.events; if ( events ) { dataPriv.remove( dest, "handle events" ); for ( type in events ) { for ( i = 0, l = events[ type ].length; i < l; i++ ) { jQuery.event.add( dest, type, events[ type ][ i ] ); } } } } // 2. Copy user data if ( dataUser.hasData( src ) ) { udataOld = dataUser.access( src ); udataCur = jQuery.extend( {}, udataOld ); dataUser.set( dest, udataCur ); } } // Fix IE bugs, see support tests function fixInput( src, dest ) { var nodeName = dest.nodeName.toLowerCase(); // Fails to persist the checked state of a cloned checkbox or radio button. if ( nodeName === "input" && rcheckableType.test( src.type ) ) { dest.checked = src.checked; // Fails to return the selected option to the default selected state when cloning options } else if ( nodeName === "input" || nodeName === "textarea" ) { dest.defaultValue = src.defaultValue; } } function domManip( collection, args, callback, ignored ) { // Flatten any nested arrays args = flat( args ); var fragment, first, scripts, hasScripts, node, doc, i = 0, l = collection.length, iNoClone = l - 1, value = args[ 0 ], valueIsFunction = isFunction( value ); // We can't cloneNode fragments that contain checked, in WebKit if ( valueIsFunction || ( l > 1 && typeof value === "string" && !support.checkClone && rchecked.test( value ) ) ) { return collection.each( function( index ) { var self = collection.eq( index ); if ( valueIsFunction ) { args[ 0 ] = value.call( this, index, self.html() ); } domManip( self, args, callback, ignored ); } ); } if ( l ) { fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); first = fragment.firstChild; if ( fragment.childNodes.length === 1 ) { fragment = first; } // Require either new content or an interest in ignored elements to invoke the callback if ( first || ignored ) { scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); hasScripts = scripts.length; // Use the original fragment for the last item // instead of the first because it can end up // being emptied incorrectly in certain situations (#8070). for ( ; i < l; i++ ) { node = fragment; if ( i !== iNoClone ) { node = jQuery.clone( node, true, true ); // Keep references to cloned scripts for later restoration if ( hasScripts ) { // Support: Android <=4.0 only, PhantomJS 1 only // push.apply(_, arraylike) throws on ancient WebKit jQuery.merge( scripts, getAll( node, "script" ) ); } } callback.call( collection[ i ], node, i ); } if ( hasScripts ) { doc = scripts[ scripts.length - 1 ].ownerDocument; // Reenable scripts jQuery.map( scripts, restoreScript ); // Evaluate executable scripts on first document insertion for ( i = 0; i < hasScripts; i++ ) { node = scripts[ i ]; if ( rscriptType.test( node.type || "" ) && !dataPriv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) { if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { // Optional AJAX dependency, but won't run scripts if not present if ( jQuery._evalUrl && !node.noModule ) { jQuery._evalUrl( node.src, { nonce: node.nonce || node.getAttribute( "nonce" ) }, doc ); } } else { DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); } } } } } } return collection; } function remove( elem, selector, keepData ) { var node, nodes = selector ? jQuery.filter( selector, elem ) : elem, i = 0; for ( ; ( node = nodes[ i ] ) != null; i++ ) { if ( !keepData && node.nodeType === 1 ) { jQuery.cleanData( getAll( node ) ); } if ( node.parentNode ) { if ( keepData && isAttached( node ) ) { setGlobalEval( getAll( node, "script" ) ); } node.parentNode.removeChild( node ); } } return elem; } jQuery.extend( { htmlPrefilter: function( html ) { return html; }, clone: function( elem, dataAndEvents, deepDataAndEvents ) { var i, l, srcElements, destElements, clone = elem.cloneNode( true ), inPage = isAttached( elem ); // Fix IE cloning issues if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) { // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 destElements = getAll( clone ); srcElements = getAll( elem ); for ( i = 0, l = srcElements.length; i < l; i++ ) { fixInput( srcElements[ i ], destElements[ i ] ); } } // Copy the events from the original to the clone if ( dataAndEvents ) { if ( deepDataAndEvents ) { srcElements = srcElements || getAll( elem ); destElements = destElements || getAll( clone ); for ( i = 0, l = srcElements.length; i < l; i++ ) { cloneCopyEvent( srcElements[ i ], destElements[ i ] ); } } else { cloneCopyEvent( elem, clone ); } } // Preserve script evaluation history destElements = getAll( clone, "script" ); if ( destElements.length > 0 ) { setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); } // Return the cloned set return clone; }, cleanData: function( elems ) { var data, elem, type, special = jQuery.event.special, i = 0; for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { if ( acceptData( elem ) ) { if ( ( data = elem[ dataPriv.expando ] ) ) { if ( data.events ) { for ( type in data.events ) { if ( special[ type ] ) { jQuery.event.remove( elem, type ); // This is a shortcut to avoid jQuery.event.remove's overhead } else { jQuery.removeEvent( elem, type, data.handle ); } } } // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataPriv.expando ] = undefined; } if ( elem[ dataUser.expando ] ) { // Support: Chrome <=35 - 45+ // Assign undefined instead of using delete, see Data#remove elem[ dataUser.expando ] = undefined; } } } } } ); jQuery.fn.extend( { detach: function( selector ) { return remove( this, selector, true ); }, remove: function( selector ) { return remove( this, selector ); }, text: function( value ) { return access( this, function( value ) { return value === undefined ? jQuery.text( this ) : this.empty().each( function() { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { this.textContent = value; } } ); }, null, value, arguments.length ); }, append: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.appendChild( elem ); } } ); }, prepend: function() { return domManip( this, arguments, function( elem ) { if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { var target = manipulationTarget( this, elem ); target.insertBefore( elem, target.firstChild ); } } ); }, before: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this ); } } ); }, after: function() { return domManip( this, arguments, function( elem ) { if ( this.parentNode ) { this.parentNode.insertBefore( elem, this.nextSibling ); } } ); }, empty: function() { var elem, i = 0; for ( ; ( elem = this[ i ] ) != null; i++ ) { if ( elem.nodeType === 1 ) { // Prevent memory leaks jQuery.cleanData( getAll( elem, false ) ); // Remove any remaining nodes elem.textContent = ""; } } return this; }, clone: function( dataAndEvents, deepDataAndEvents ) { dataAndEvents = dataAndEvents == null ? false : dataAndEvents; deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; return this.map( function() { return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); } ); }, html: function( value ) { return access( this, function( value ) { var elem = this[ 0 ] || {}, i = 0, l = this.length; if ( value === undefined && elem.nodeType === 1 ) { return elem.innerHTML; } // See if we can take a shortcut and just use innerHTML if ( typeof value === "string" && !rnoInnerhtml.test( value ) && !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { value = jQuery.htmlPrefilter( value ); try { for ( ; i < l; i++ ) { elem = this[ i ] || {}; // Remove element nodes and prevent memory leaks if ( elem.nodeType === 1 ) { jQuery.cleanData( getAll( elem, false ) ); elem.innerHTML = value; } } elem = 0; // If using innerHTML throws an exception, use the fallback method } catch ( e ) {} } if ( elem ) { this.empty().append( value ); } }, null, value, arguments.length ); }, replaceWith: function() { var ignored = []; // Make the changes, replacing each non-ignored context element with the new content return domManip( this, arguments, function( elem ) { var parent = this.parentNode; if ( jQuery.inArray( this, ignored ) < 0 ) { jQuery.cleanData( getAll( this ) ); if ( parent ) { parent.replaceChild( elem, this ); } } // Force callback invocation }, ignored ); } } ); jQuery.each( { appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function( name, original ) { jQuery.fn[ name ] = function( selector ) { var elems, ret = [], insert = jQuery( selector ), last = insert.length - 1, i = 0; for ( ; i <= last; i++ ) { elems = i === last ? this : this.clone( true ); jQuery( insert[ i ] )[ original ]( elems ); // Support: Android <=4.0 only, PhantomJS 1 only // .get() because push.apply(_, arraylike) throws on ancient WebKit push.apply( ret, elems.get() ); } return this.pushStack( ret ); }; } ); var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); var getStyles = function( elem ) { // Support: IE <=11 only, Firefox <=30 (#15098, #14150) // IE throws on elements created in popups // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" var view = elem.ownerDocument.defaultView; if ( !view || !view.opener ) { view = window; } return view.getComputedStyle( elem ); }; var swap = function( elem, options, callback ) { var ret, name, old = {}; // Remember the old values, and insert the new ones for ( name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } ret = callback.call( elem ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } return ret; }; var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); ( function() { // Executing both pixelPosition & boxSizingReliable tests require only one layout // so they're executed at the same time to save the second computation. function computeStyleTests() { // This is a singleton, we need to execute it only once if ( !div ) { return; } container.style.cssText = "position:absolute;left:-11111px;width:60px;" + "margin-top:1px;padding:0;border:0"; div.style.cssText = "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + "margin:auto;border:1px;padding:1px;" + "width:60%;top:1%"; documentElement.appendChild( container ).appendChild( div ); var divStyle = window.getComputedStyle( div ); pixelPositionVal = divStyle.top !== "1%"; // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 // Some styles come back with percentage values, even though they shouldn't div.style.right = "60%"; pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; // Support: IE 9 - 11 only // Detect misreporting of content dimensions for box-sizing:border-box elements boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; // Support: IE 9 only // Detect overflow:scroll screwiness (gh-3699) // Support: Chrome <=64 // Don't get tricked when zoom affects offsetWidth (gh-4029) div.style.position = "absolute"; scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; documentElement.removeChild( container ); // Nullify the div so it wouldn't be stored in the memory and // it will also be a sign that checks already performed div = null; } function roundPixelMeasures( measure ) { return Math.round( parseFloat( measure ) ); } var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, reliableTrDimensionsVal, reliableMarginLeftVal, container = document.createElement( "div" ), div = document.createElement( "div" ); // Finish early in limited (non-browser) environments if ( !div.style ) { return; } // Support: IE <=9 - 11 only // Style of cloned element affects source element cloned (#8908) div.style.backgroundClip = "content-box"; div.cloneNode( true ).style.backgroundClip = ""; support.clearCloneStyle = div.style.backgroundClip === "content-box"; jQuery.extend( support, { boxSizingReliable: function() { computeStyleTests(); return boxSizingReliableVal; }, pixelBoxStyles: function() { computeStyleTests(); return pixelBoxStylesVal; }, pixelPosition: function() { computeStyleTests(); return pixelPositionVal; }, reliableMarginLeft: function() { computeStyleTests(); return reliableMarginLeftVal; }, scrollboxSize: function() { computeStyleTests(); return scrollboxSizeVal; }, // Support: IE 9 - 11+, Edge 15 - 18+ // IE/Edge misreport `getComputedStyle` of table rows with width/height // set in CSS while `offset*` properties report correct values. // Behavior in IE 9 is more subtle than in newer versions & it passes // some versions of this test; make sure not to make it pass there! reliableTrDimensions: function() { var table, tr, trChild, trStyle; if ( reliableTrDimensionsVal == null ) { table = document.createElement( "table" ); tr = document.createElement( "tr" ); trChild = document.createElement( "div" ); table.style.cssText = "position:absolute;left:-11111px"; tr.style.height = "1px"; trChild.style.height = "9px"; documentElement .appendChild( table ) .appendChild( tr ) .appendChild( trChild ); trStyle = window.getComputedStyle( tr ); reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; documentElement.removeChild( table ); } return reliableTrDimensionsVal; } } ); } )(); function curCSS( elem, name, computed ) { var width, minWidth, maxWidth, ret, // Support: Firefox 51+ // Retrieving style before computed somehow // fixes an issue with getting wrong values // on detached elements style = elem.style; computed = computed || getStyles( elem ); // getPropertyValue is needed for: // .css('filter') (IE 9 only, #12537) // .css('--customProperty) (#3144) if ( computed ) { ret = computed.getPropertyValue( name ) || computed[ name ]; if ( ret === "" && !isAttached( elem ) ) { ret = jQuery.style( elem, name ); } // A tribute to the "awesome hack by Dean Edwards" // Android Browser returns percentage for some values, // but width seems to be reliably pixels. // This is against the CSSOM draft spec: // https://drafts.csswg.org/cssom/#resolved-values if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { // Remember the original values width = style.width; minWidth = style.minWidth; maxWidth = style.maxWidth; // Put in the new values to get a computed value out style.minWidth = style.maxWidth = style.width = ret; ret = computed.width; // Revert the changed values style.width = width; style.minWidth = minWidth; style.maxWidth = maxWidth; } } return ret !== undefined ? // Support: IE <=9 - 11 only // IE returns zIndex value as an integer. ret + "" : ret; } function addGetHookIf( conditionFn, hookFn ) { // Define the hook, we'll check on the first run if it's really needed. return { get: function() { if ( conditionFn() ) { // Hook not needed (or it's not possible to use it due // to missing dependency), remove it. delete this.get; return; } // Hook needed; redefine it so that the support test is not executed again. return ( this.get = hookFn ).apply( this, arguments ); } }; } var cssPrefixes = [ "Webkit", "Moz", "ms" ], emptyStyle = document.createElement( "div" ).style, vendorProps = {}; // Return a vendor-prefixed property or undefined function vendorPropName( name ) { // Check for vendor prefixed names var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), i = cssPrefixes.length; while ( i-- ) { name = cssPrefixes[ i ] + capName; if ( name in emptyStyle ) { return name; } } } // Return a potentially-mapped jQuery.cssProps or vendor prefixed property function finalPropName( name ) { var final = jQuery.cssProps[ name ] || vendorProps[ name ]; if ( final ) { return final; } if ( name in emptyStyle ) { return name; } return vendorProps[ name ] = vendorPropName( name ) || name; } var // Swappable if display is none or starts with table // except "table", "table-cell", or "table-caption" // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display rdisplayswap = /^(none|table(?!-c[ea]).+)/, rcustomProp = /^--/, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssNormalTransform = { letterSpacing: "0", fontWeight: "400" }; function setPositiveNumber( _elem, value, subtract ) { // Any relative (+/-) values have already been // normalized at this point var matches = rcssNum.exec( value ); return matches ? // Guard against undefined "subtract", e.g., when used as in cssHooks Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : value; } function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { var i = dimension === "width" ? 1 : 0, extra = 0, delta = 0; // Adjustment may not be necessary if ( box === ( isBorderBox ? "border" : "content" ) ) { return 0; } for ( ; i < 4; i += 2 ) { // Both box models exclude margin if ( box === "margin" ) { delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); } // If we get here with a content-box, we're seeking "padding" or "border" or "margin" if ( !isBorderBox ) { // Add padding delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); // For "border" or "margin", add border if ( box !== "padding" ) { delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); // But still keep track of it otherwise } else { extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } // If we get here with a border-box (content + padding + border), we're seeking "content" or // "padding" or "margin" } else { // For "content", subtract padding if ( box === "content" ) { delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } // For "content" or "padding", subtract border if ( box !== "margin" ) { delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } // Account for positive content-box scroll gutter when requested by providing computedVal if ( !isBorderBox && computedVal >= 0 ) { // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border // Assuming integer scroll gutter, subtract the rest and round down delta += Math.max( 0, Math.ceil( elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - computedVal - delta - extra - 0.5 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter // Use an explicit zero to avoid NaN (gh-3964) ) ) || 0; } return delta; } function getWidthOrHeight( elem, dimension, extra ) { // Start with computed style var styles = getStyles( elem ), // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). // Fake content-box until we know it's needed to know the true value. boxSizingNeeded = !support.boxSizingReliable() || extra, isBorderBox = boxSizingNeeded && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", valueIsBorderBox = isBorderBox, val = curCSS( elem, dimension, styles ), offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); // Support: Firefox <=54 // Return a confounding non-pixel value or feign ignorance, as appropriate. if ( rnumnonpx.test( val ) ) { if ( !extra ) { return val; } val = "auto"; } // Support: IE 9 - 11 only // Use offsetWidth/offsetHeight for when box sizing is unreliable. // In those cases, the computed value can be trusted to be border-box. if ( ( !support.boxSizingReliable() && isBorderBox || // Support: IE 10 - 11+, Edge 15 - 18+ // IE/Edge misreport `getComputedStyle` of table rows with width/height // set in CSS while `offset*` properties report correct values. // Interestingly, in some cases IE 9 doesn't suffer from this issue. !support.reliableTrDimensions() && nodeName( elem, "tr" ) || // Fall back to offsetWidth/offsetHeight when value is "auto" // This happens for inline elements with no explicit setting (gh-3571) val === "auto" || // Support: Android <=4.1 - 4.3 only // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && // Make sure the element is visible & connected elem.getClientRects().length ) { isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; // Where available, offsetWidth/offsetHeight approximate border box dimensions. // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the // retrieved value as a content box dimension. valueIsBorderBox = offsetProp in elem; if ( valueIsBorderBox ) { val = elem[ offsetProp ]; } } // Normalize "" and auto val = parseFloat( val ) || 0; // Adjust for the element's box model return ( val + boxModelAdjustment( elem, dimension, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, styles, // Provide the current computed size to request scroll gutter calculation (gh-3589) val ) ) + "px"; } jQuery.extend( { // Add in style property hooks for overriding the default // behavior of getting and setting a style property cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { // We should always get a number back from opacity var ret = curCSS( elem, "opacity" ); return ret === "" ? "1" : ret; } } } }, // Don't automatically add "px" to these possibly-unitless properties cssNumber: { "animationIterationCount": true, "columnCount": true, "fillOpacity": true, "flexGrow": true, "flexShrink": true, "fontWeight": true, "gridArea": true, "gridColumn": true, "gridColumnEnd": true, "gridColumnStart": true, "gridRow": true, "gridRowEnd": true, "gridRowStart": true, "lineHeight": true, "opacity": true, "order": true, "orphans": true, "widows": true, "zIndex": true, "zoom": true }, // Add in properties whose names you wish to fix before // setting or getting the value cssProps: {}, // Get and set the style property on a DOM Node style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = camelCase( name ), isCustomProp = rcustomProp.test( name ), style = elem.style; // Make sure that we're working with the right name. We don't // want to query the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Gets hook for the prefixed version, then unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; // Convert "+=" or "-=" to relative numbers (#7345) if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { value = adjustCSS( elem, name, ret ); // Fixes bug #9237 type = "number"; } // Make sure that null and NaN values aren't set (#7116) if ( value == null || value !== value ) { return; } // If a number was passed in, add the unit (except for certain CSS properties) // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append // "px" to a few hardcoded values. if ( type === "number" && !isCustomProp ) { value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); } // background-* props affect original clone's values if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !( "set" in hooks ) || ( value = hooks.set( elem, value, extra ) ) !== undefined ) { if ( isCustomProp ) { style.setProperty( name, value ); } else { style[ name ] = value; } } } else { // If a hook was provided get the non-computed value from there if ( hooks && "get" in hooks && ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { return ret; } // Otherwise just get the value from the style object return style[ name ]; } }, css: function( elem, name, extra, styles ) { var val, num, hooks, origName = camelCase( name ), isCustomProp = rcustomProp.test( name ); // Make sure that we're working with the right name. We don't // want to modify the value if it is a CSS custom property // since they are user-defined. if ( !isCustomProp ) { name = finalPropName( origName ); } // Try prefixed name followed by the unprefixed name hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name, styles ); } // Convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // Make numeric if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || isFinite( num ) ? num || 0 : val; } return val; } } ); jQuery.each( [ "height", "width" ], function( _i, dimension ) { jQuery.cssHooks[ dimension ] = { get: function( elem, computed, extra ) { if ( computed ) { // Certain elements can have dimension info if we invisibly show them // but it must have a current display style that would benefit return rdisplayswap.test( jQuery.css( elem, "display" ) ) && // Support: Safari 8+ // Table columns in Safari have non-zero offsetWidth & zero // getBoundingClientRect().width unless display is changed. // Support: IE <=11 only // Running getBoundingClientRect on a disconnected node // in IE throws an error. ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? swap( elem, cssShow, function() { return getWidthOrHeight( elem, dimension, extra ); } ) : getWidthOrHeight( elem, dimension, extra ); } }, set: function( elem, value, extra ) { var matches, styles = getStyles( elem ), // Only read styles.position if the test has a chance to fail // to avoid forcing a reflow. scrollboxSizeBuggy = !support.scrollboxSize() && styles.position === "absolute", // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) boxSizingNeeded = scrollboxSizeBuggy || extra, isBorderBox = boxSizingNeeded && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", subtract = extra ? boxModelAdjustment( elem, dimension, extra, isBorderBox, styles ) : 0; // Account for unreliable border-box dimensions by comparing offset* to computed and // faking a content-box to get border and padding (gh-3699) if ( isBorderBox && scrollboxSizeBuggy ) { subtract -= Math.ceil( elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - parseFloat( styles[ dimension ] ) - boxModelAdjustment( elem, dimension, "border", false, styles ) - 0.5 ); } // Convert to pixels if value adjustment is needed if ( subtract && ( matches = rcssNum.exec( value ) ) && ( matches[ 3 ] || "px" ) !== "px" ) { elem.style[ dimension ] = value; value = jQuery.css( elem, dimension ); } return setPositiveNumber( elem, value, subtract ); } }; } ); jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, function( elem, computed ) { if ( computed ) { return ( parseFloat( curCSS( elem, "marginLeft" ) ) || elem.getBoundingClientRect().left - swap( elem, { marginLeft: 0 }, function() { return elem.getBoundingClientRect().left; } ) ) + "px"; } } ); // These hooks are used by animate to expand properties jQuery.each( { margin: "", padding: "", border: "Width" }, function( prefix, suffix ) { jQuery.cssHooks[ prefix + suffix ] = { expand: function( value ) { var i = 0, expanded = {}, // Assumes a single number if not a string parts = typeof value === "string" ? value.split( " " ) : [ value ]; for ( ; i < 4; i++ ) { expanded[ prefix + cssExpand[ i ] + suffix ] = parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; } return expanded; } }; if ( prefix !== "margin" ) { jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; } } ); jQuery.fn.extend( { css: function( name, value ) { return access( this, function( elem, name, value ) { var styles, len, map = {}, i = 0; if ( Array.isArray( name ) ) { styles = getStyles( elem ); len = name.length; for ( ; i < len; i++ ) { map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); } return map; } return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); } } ); function Tween( elem, options, prop, end, easing ) { return new Tween.prototype.init( elem, options, prop, end, easing ); } jQuery.Tween = Tween; Tween.prototype = { constructor: Tween, init: function( elem, options, prop, end, easing, unit ) { this.elem = elem; this.prop = prop; this.easing = easing || jQuery.easing._default; this.options = options; this.start = this.now = this.cur(); this.end = end; this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); }, cur: function() { var hooks = Tween.propHooks[ this.prop ]; return hooks && hooks.get ? hooks.get( this ) : Tween.propHooks._default.get( this ); }, run: function( percent ) { var eased, hooks = Tween.propHooks[ this.prop ]; if ( this.options.duration ) { this.pos = eased = jQuery.easing[ this.easing ]( percent, this.options.duration * percent, 0, 1, this.options.duration ); } else { this.pos = eased = percent; } this.now = ( this.end - this.start ) * eased + this.start; if ( this.options.step ) { this.options.step.call( this.elem, this.now, this ); } if ( hooks && hooks.set ) { hooks.set( this ); } else { Tween.propHooks._default.set( this ); } return this; } }; Tween.prototype.init.prototype = Tween.prototype; Tween.propHooks = { _default: { get: function( tween ) { var result; // Use a property on the element directly when it is not a DOM element, // or when there is no matching style property that exists. if ( tween.elem.nodeType !== 1 || tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { return tween.elem[ tween.prop ]; } // Passing an empty string as a 3rd parameter to .css will automatically // attempt a parseFloat and fallback to a string if the parse fails. // Simple values such as "10px" are parsed to Float; // complex values such as "rotate(1rad)" are returned as-is. result = jQuery.css( tween.elem, tween.prop, "" ); // Empty strings, null, undefined and "auto" are converted to 0. return !result || result === "auto" ? 0 : result; }, set: function( tween ) { // Use step hook for back compat. // Use cssHook if its there. // Use .style if available and use plain properties where available. if ( jQuery.fx.step[ tween.prop ] ) { jQuery.fx.step[ tween.prop ]( tween ); } else if ( tween.elem.nodeType === 1 && ( jQuery.cssHooks[ tween.prop ] || tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); } else { tween.elem[ tween.prop ] = tween.now; } } } }; // Support: IE <=9 only // Panic based approach to setting things on disconnected nodes Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { set: function( tween ) { if ( tween.elem.nodeType && tween.elem.parentNode ) { tween.elem[ tween.prop ] = tween.now; } } }; jQuery.easing = { linear: function( p ) { return p; }, swing: function( p ) { return 0.5 - Math.cos( p * Math.PI ) / 2; }, _default: "swing" }; jQuery.fx = Tween.prototype.init; // Back compat <1.8 extension point jQuery.fx.step = {}; var fxNow, inProgress, rfxtypes = /^(?:toggle|show|hide)$/, rrun = /queueHooks$/; function schedule() { if ( inProgress ) { if ( document.hidden === false && window.requestAnimationFrame ) { window.requestAnimationFrame( schedule ); } else { window.setTimeout( schedule, jQuery.fx.interval ); } jQuery.fx.tick(); } } // Animations created synchronously will run synchronously function createFxNow() { window.setTimeout( function() { fxNow = undefined; } ); return ( fxNow = Date.now() ); } // Generate parameters to create a standard animation function genFx( type, includeWidth ) { var which, i = 0, attrs = { height: type }; // If we include width, step value is 1 to do all cssExpand values, // otherwise step value is 2 to skip over Left and Right includeWidth = includeWidth ? 1 : 0; for ( ; i < 4; i += 2 - includeWidth ) { which = cssExpand[ i ]; attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; } if ( includeWidth ) { attrs.opacity = attrs.width = type; } return attrs; } function createTween( value, prop, animation ) { var tween, collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), index = 0, length = collection.length; for ( ; index < length; index++ ) { if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { // We're done with this property return tween; } } } function defaultPrefilter( elem, props, opts ) { var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, isBox = "width" in props || "height" in props, anim = this, orig = {}, style = elem.style, hidden = elem.nodeType && isHiddenWithinTree( elem ), dataShow = dataPriv.get( elem, "fxshow" ); // Queue-skipping animations hijack the fx hooks if ( !opts.queue ) { hooks = jQuery._queueHooks( elem, "fx" ); if ( hooks.unqueued == null ) { hooks.unqueued = 0; oldfire = hooks.empty.fire; hooks.empty.fire = function() { if ( !hooks.unqueued ) { oldfire(); } }; } hooks.unqueued++; anim.always( function() { // Ensure the complete handler is called before this completes anim.always( function() { hooks.unqueued--; if ( !jQuery.queue( elem, "fx" ).length ) { hooks.empty.fire(); } } ); } ); } // Detect show/hide animations for ( prop in props ) { value = props[ prop ]; if ( rfxtypes.test( value ) ) { delete props[ prop ]; toggle = toggle || value === "toggle"; if ( value === ( hidden ? "hide" : "show" ) ) { // Pretend to be hidden if this is a "show" and // there is still data from a stopped show/hide if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { hidden = true; // Ignore all other no-op show/hide data } else { continue; } } orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); } } // Bail out if this is a no-op like .hide().hide() propTween = !jQuery.isEmptyObject( props ); if ( !propTween && jQuery.isEmptyObject( orig ) ) { return; } // Restrict "overflow" and "display" styles during box animations if ( isBox && elem.nodeType === 1 ) { // Support: IE <=9 - 11, Edge 12 - 15 // Record all 3 overflow attributes because IE does not infer the shorthand // from identically-valued overflowX and overflowY and Edge just mirrors // the overflowX value there. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; // Identify a display type, preferring old show/hide data over the CSS cascade restoreDisplay = dataShow && dataShow.display; if ( restoreDisplay == null ) { restoreDisplay = dataPriv.get( elem, "display" ); } display = jQuery.css( elem, "display" ); if ( display === "none" ) { if ( restoreDisplay ) { display = restoreDisplay; } else { // Get nonempty value(s) by temporarily forcing visibility showHide( [ elem ], true ); restoreDisplay = elem.style.display || restoreDisplay; display = jQuery.css( elem, "display" ); showHide( [ elem ] ); } } // Animate inline elements as inline-block if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { if ( jQuery.css( elem, "float" ) === "none" ) { // Restore the original display value at the end of pure show/hide animations if ( !propTween ) { anim.done( function() { style.display = restoreDisplay; } ); if ( restoreDisplay == null ) { display = style.display; restoreDisplay = display === "none" ? "" : display; } } style.display = "inline-block"; } } } if ( opts.overflow ) { style.overflow = "hidden"; anim.always( function() { style.overflow = opts.overflow[ 0 ]; style.overflowX = opts.overflow[ 1 ]; style.overflowY = opts.overflow[ 2 ]; } ); } // Implement show/hide animations propTween = false; for ( prop in orig ) { // General show/hide setup for this element animation if ( !propTween ) { if ( dataShow ) { if ( "hidden" in dataShow ) { hidden = dataShow.hidden; } } else { dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); } // Store hidden/visible for toggle so `.stop().toggle()` "reverses" if ( toggle ) { dataShow.hidden = !hidden; } // Show elements before animating them if ( hidden ) { showHide( [ elem ], true ); } /* eslint-disable no-loop-func */ anim.done( function() { /* eslint-enable no-loop-func */ // The final step of a "hide" animation is actually hiding the element if ( !hidden ) { showHide( [ elem ] ); } dataPriv.remove( elem, "fxshow" ); for ( prop in orig ) { jQuery.style( elem, prop, orig[ prop ] ); } } ); } // Per-property setup propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); if ( !( prop in dataShow ) ) { dataShow[ prop ] = propTween.start; if ( hidden ) { propTween.end = propTween.start; propTween.start = 0; } } } } function propFilter( props, specialEasing ) { var index, name, easing, value, hooks; // camelCase, specialEasing and expand cssHook pass for ( index in props ) { name = camelCase( index ); easing = specialEasing[ name ]; value = props[ index ]; if ( Array.isArray( value ) ) { easing = value[ 1 ]; value = props[ index ] = value[ 0 ]; } if ( index !== name ) { props[ name ] = value; delete props[ index ]; } hooks = jQuery.cssHooks[ name ]; if ( hooks && "expand" in hooks ) { value = hooks.expand( value ); delete props[ name ]; // Not quite $.extend, this won't overwrite existing keys. // Reusing 'index' because we have the correct "name" for ( index in value ) { if ( !( index in props ) ) { props[ index ] = value[ index ]; specialEasing[ index ] = easing; } } } else { specialEasing[ name ] = easing; } } } function Animation( elem, properties, options ) { var result, stopped, index = 0, length = Animation.prefilters.length, deferred = jQuery.Deferred().always( function() { // Don't match elem in the :animated selector delete tick.elem; } ), tick = function() { if ( stopped ) { return false; } var currentTime = fxNow || createFxNow(), remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), // Support: Android 2.3 only // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) temp = remaining / animation.duration || 0, percent = 1 - temp, index = 0, length = animation.tweens.length; for ( ; index < length; index++ ) { animation.tweens[ index ].run( percent ); } deferred.notifyWith( elem, [ animation, percent, remaining ] ); // If there's more to do, yield if ( percent < 1 && length ) { return remaining; } // If this was an empty animation, synthesize a final progress notification if ( !length ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); } // Resolve the animation and report its conclusion deferred.resolveWith( elem, [ animation ] ); return false; }, animation = deferred.promise( { elem: elem, props: jQuery.extend( {}, properties ), opts: jQuery.extend( true, { specialEasing: {}, easing: jQuery.easing._default }, options ), originalProperties: properties, originalOptions: options, startTime: fxNow || createFxNow(), duration: options.duration, tweens: [], createTween: function( prop, end ) { var tween = jQuery.Tween( elem, animation.opts, prop, end, animation.opts.specialEasing[ prop ] || animation.opts.easing ); animation.tweens.push( tween ); return tween; }, stop: function( gotoEnd ) { var index = 0, // If we are going to the end, we want to run all the tweens // otherwise we skip this part length = gotoEnd ? animation.tweens.length : 0; if ( stopped ) { return this; } stopped = true; for ( ; index < length; index++ ) { animation.tweens[ index ].run( 1 ); } // Resolve when we played the last frame; otherwise, reject if ( gotoEnd ) { deferred.notifyWith( elem, [ animation, 1, 0 ] ); deferred.resolveWith( elem, [ animation, gotoEnd ] ); } else { deferred.rejectWith( elem, [ animation, gotoEnd ] ); } return this; } } ), props = animation.props; propFilter( props, animation.opts.specialEasing ); for ( ; index < length; index++ ) { result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); if ( result ) { if ( isFunction( result.stop ) ) { jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = result.stop.bind( result ); } return result; } } jQuery.map( props, createTween, animation ); if ( isFunction( animation.opts.start ) ) { animation.opts.start.call( elem, animation ); } // Attach callbacks from options animation .progress( animation.opts.progress ) .done( animation.opts.done, animation.opts.complete ) .fail( animation.opts.fail ) .always( animation.opts.always ); jQuery.fx.timer( jQuery.extend( tick, { elem: elem, anim: animation, queue: animation.opts.queue } ) ); return animation; } jQuery.Animation = jQuery.extend( Animation, { tweeners: { "*": [ function( prop, value ) { var tween = this.createTween( prop, value ); adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); return tween; } ] }, tweener: function( props, callback ) { if ( isFunction( props ) ) { callback = props; props = [ "*" ]; } else { props = props.match( rnothtmlwhite ); } var prop, index = 0, length = props.length; for ( ; index < length; index++ ) { prop = props[ index ]; Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; Animation.tweeners[ prop ].unshift( callback ); } }, prefilters: [ defaultPrefilter ], prefilter: function( callback, prepend ) { if ( prepend ) { Animation.prefilters.unshift( callback ); } else { Animation.prefilters.push( callback ); } } } ); jQuery.speed = function( speed, easing, fn ) { var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { complete: fn || !fn && easing || isFunction( speed ) && speed, duration: speed, easing: fn && easing || easing && !isFunction( easing ) && easing }; // Go to the end state if fx are off if ( jQuery.fx.off ) { opt.duration = 0; } else { if ( typeof opt.duration !== "number" ) { if ( opt.duration in jQuery.fx.speeds ) { opt.duration = jQuery.fx.speeds[ opt.duration ]; } else { opt.duration = jQuery.fx.speeds._default; } } } // Normalize opt.queue - true/undefined/null -> "fx" if ( opt.queue == null || opt.queue === true ) { opt.queue = "fx"; } // Queueing opt.old = opt.complete; opt.complete = function() { if ( isFunction( opt.old ) ) { opt.old.call( this ); } if ( opt.queue ) { jQuery.dequeue( this, opt.queue ); } }; return opt; }; jQuery.fn.extend( { fadeTo: function( speed, to, easing, callback ) { // Show any hidden elements after setting opacity to 0 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() // Animate to the value specified .end().animate( { opacity: to }, speed, easing, callback ); }, animate: function( prop, speed, easing, callback ) { var empty = jQuery.isEmptyObject( prop ), optall = jQuery.speed( speed, easing, callback ), doAnimation = function() { // Operate on a copy of prop so per-property easing won't be lost var anim = Animation( this, jQuery.extend( {}, prop ), optall ); // Empty animations, or finishing resolves immediately if ( empty || dataPriv.get( this, "finish" ) ) { anim.stop( true ); } }; doAnimation.finish = doAnimation; return empty || optall.queue === false ? this.each( doAnimation ) : this.queue( optall.queue, doAnimation ); }, stop: function( type, clearQueue, gotoEnd ) { var stopQueue = function( hooks ) { var stop = hooks.stop; delete hooks.stop; stop( gotoEnd ); }; if ( typeof type !== "string" ) { gotoEnd = clearQueue; clearQueue = type; type = undefined; } if ( clearQueue ) { this.queue( type || "fx", [] ); } return this.each( function() { var dequeue = true, index = type != null && type + "queueHooks", timers = jQuery.timers, data = dataPriv.get( this ); if ( index ) { if ( data[ index ] && data[ index ].stop ) { stopQueue( data[ index ] ); } } else { for ( index in data ) { if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { stopQueue( data[ index ] ); } } } for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && ( type == null || timers[ index ].queue === type ) ) { timers[ index ].anim.stop( gotoEnd ); dequeue = false; timers.splice( index, 1 ); } } // Start the next in the queue if the last step wasn't forced. // Timers currently will call their complete callbacks, which // will dequeue but only if they were gotoEnd. if ( dequeue || !gotoEnd ) { jQuery.dequeue( this, type ); } } ); }, finish: function( type ) { if ( type !== false ) { type = type || "fx"; } return this.each( function() { var index, data = dataPriv.get( this ), queue = data[ type + "queue" ], hooks = data[ type + "queueHooks" ], timers = jQuery.timers, length = queue ? queue.length : 0; // Enable finishing flag on private data data.finish = true; // Empty the queue first jQuery.queue( this, type, [] ); if ( hooks && hooks.stop ) { hooks.stop.call( this, true ); } // Look for any active animations, and finish them for ( index = timers.length; index--; ) { if ( timers[ index ].elem === this && timers[ index ].queue === type ) { timers[ index ].anim.stop( true ); timers.splice( index, 1 ); } } // Look for any animations in the old queue and finish them for ( index = 0; index < length; index++ ) { if ( queue[ index ] && queue[ index ].finish ) { queue[ index ].finish.call( this ); } } // Turn off finishing flag delete data.finish; } ); } } ); jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { var cssFn = jQuery.fn[ name ]; jQuery.fn[ name ] = function( speed, easing, callback ) { return speed == null || typeof speed === "boolean" ? cssFn.apply( this, arguments ) : this.animate( genFx( name, true ), speed, easing, callback ); }; } ); // Generate shortcuts for custom animations jQuery.each( { slideDown: genFx( "show" ), slideUp: genFx( "hide" ), slideToggle: genFx( "toggle" ), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function( name, props ) { jQuery.fn[ name ] = function( speed, easing, callback ) { return this.animate( props, speed, easing, callback ); }; } ); jQuery.timers = []; jQuery.fx.tick = function() { var timer, i = 0, timers = jQuery.timers; fxNow = Date.now(); for ( ; i < timers.length; i++ ) { timer = timers[ i ]; // Run the timer and safely remove it when done (allowing for external removal) if ( !timer() && timers[ i ] === timer ) { timers.splice( i--, 1 ); } } if ( !timers.length ) { jQuery.fx.stop(); } fxNow = undefined; }; jQuery.fx.timer = function( timer ) { jQuery.timers.push( timer ); jQuery.fx.start(); }; jQuery.fx.interval = 13; jQuery.fx.start = function() { if ( inProgress ) { return; } inProgress = true; schedule(); }; jQuery.fx.stop = function() { inProgress = null; }; jQuery.fx.speeds = { slow: 600, fast: 200, // Default speed _default: 400 }; // Based off of the plugin by Clint Helfers, with permission. // https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ jQuery.fn.delay = function( time, type ) { time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; type = type || "fx"; return this.queue( type, function( next, hooks ) { var timeout = window.setTimeout( next, time ); hooks.stop = function() { window.clearTimeout( timeout ); }; } ); }; ( function() { var input = document.createElement( "input" ), select = document.createElement( "select" ), opt = select.appendChild( document.createElement( "option" ) ); input.type = "checkbox"; // Support: Android <=4.3 only // Default value for a checkbox should be "on" support.checkOn = input.value !== ""; // Support: IE <=11 only // Must access selectedIndex to make default options select support.optSelected = opt.selected; // Support: IE <=11 only // An input loses its value after becoming a radio input = document.createElement( "input" ); input.value = "t"; input.type = "radio"; support.radioValue = input.value === "t"; } )(); var boolHook, attrHandle = jQuery.expr.attrHandle; jQuery.fn.extend( { attr: function( name, value ) { return access( this, jQuery.attr, name, value, arguments.length > 1 ); }, removeAttr: function( name ) { return this.each( function() { jQuery.removeAttr( this, name ); } ); } } ); jQuery.extend( { attr: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set attributes on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } // Fallback to prop when attributes are not supported if ( typeof elem.getAttribute === "undefined" ) { return jQuery.prop( elem, name, value ); } // Attribute hooks are determined by the lowercase version // Grab necessary hook if one is defined if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { hooks = jQuery.attrHooks[ name.toLowerCase() ] || ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); } if ( value !== undefined ) { if ( value === null ) { jQuery.removeAttr( elem, name ); return; } if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } elem.setAttribute( name, value + "" ); return value; } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } ret = jQuery.find.attr( elem, name ); // Non-existent attributes return null, we normalize to undefined return ret == null ? undefined : ret; }, attrHooks: { type: { set: function( elem, value ) { if ( !support.radioValue && value === "radio" && nodeName( elem, "input" ) ) { var val = elem.value; elem.setAttribute( "type", value ); if ( val ) { elem.value = val; } return value; } } } }, removeAttr: function( elem, value ) { var name, i = 0, // Attribute names can contain non-HTML whitespace characters // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 attrNames = value && value.match( rnothtmlwhite ); if ( attrNames && elem.nodeType === 1 ) { while ( ( name = attrNames[ i++ ] ) ) { elem.removeAttribute( name ); } } } } ); // Hooks for boolean attributes boolHook = { set: function( elem, value, name ) { if ( value === false ) { // Remove boolean attributes when set to false jQuery.removeAttr( elem, name ); } else { elem.setAttribute( name, name ); } return name; } }; jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { var getter = attrHandle[ name ] || jQuery.find.attr; attrHandle[ name ] = function( elem, name, isXML ) { var ret, handle, lowercaseName = name.toLowerCase(); if ( !isXML ) { // Avoid an infinite loop by temporarily removing this function from the getter handle = attrHandle[ lowercaseName ]; attrHandle[ lowercaseName ] = ret; ret = getter( elem, name, isXML ) != null ? lowercaseName : null; attrHandle[ lowercaseName ] = handle; } return ret; }; } ); var rfocusable = /^(?:input|select|textarea|button)$/i, rclickable = /^(?:a|area)$/i; jQuery.fn.extend( { prop: function( name, value ) { return access( this, jQuery.prop, name, value, arguments.length > 1 ); }, removeProp: function( name ) { return this.each( function() { delete this[ jQuery.propFix[ name ] || name ]; } ); } } ); jQuery.extend( { prop: function( elem, name, value ) { var ret, hooks, nType = elem.nodeType; // Don't get/set properties on text, comment and attribute nodes if ( nType === 3 || nType === 8 || nType === 2 ) { return; } if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { // Fix name and attach hooks name = jQuery.propFix[ name ] || name; hooks = jQuery.propHooks[ name ]; } if ( value !== undefined ) { if ( hooks && "set" in hooks && ( ret = hooks.set( elem, value, name ) ) !== undefined ) { return ret; } return ( elem[ name ] = value ); } if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { return ret; } return elem[ name ]; }, propHooks: { tabIndex: { get: function( elem ) { // Support: IE <=9 - 11 only // elem.tabIndex doesn't always return the // correct value when it hasn't been explicitly set // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // Use proper attribute retrieval(#12072) var tabindex = jQuery.find.attr( elem, "tabindex" ); if ( tabindex ) { return parseInt( tabindex, 10 ); } if ( rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ) { return 0; } return -1; } } }, propFix: { "for": "htmlFor", "class": "className" } } ); // Support: IE <=11 only // Accessing the selectedIndex property // forces the browser to respect setting selected // on the option // The getter ensures a default option is selected // when in an optgroup // eslint rule "no-unused-expressions" is disabled for this code // since it considers such accessions noop if ( !support.optSelected ) { jQuery.propHooks.selected = { get: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent && parent.parentNode ) { parent.parentNode.selectedIndex; } return null; }, set: function( elem ) { /* eslint no-unused-expressions: "off" */ var parent = elem.parentNode; if ( parent ) { parent.selectedIndex; if ( parent.parentNode ) { parent.parentNode.selectedIndex; } } } }; } jQuery.each( [ "tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable" ], function() { jQuery.propFix[ this.toLowerCase() ] = this; } ); // Strip and collapse whitespace according to HTML spec // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace function stripAndCollapse( value ) { var tokens = value.match( rnothtmlwhite ) || []; return tokens.join( " " ); } function getClass( elem ) { return elem.getAttribute && elem.getAttribute( "class" ) || ""; } function classesToArray( value ) { if ( Array.isArray( value ) ) { return value; } if ( typeof value === "string" ) { return value.match( rnothtmlwhite ) || []; } return []; } jQuery.fn.extend( { addClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); } ); } classes = classesToArray( value ); if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { if ( cur.indexOf( " " + clazz + " " ) < 0 ) { cur += clazz + " "; } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, removeClass: function( value ) { var classes, elem, cur, curValue, clazz, j, finalValue, i = 0; if ( isFunction( value ) ) { return this.each( function( j ) { jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); } ); } if ( !arguments.length ) { return this.attr( "class", "" ); } classes = classesToArray( value ); if ( classes.length ) { while ( ( elem = this[ i++ ] ) ) { curValue = getClass( elem ); // This expression is here for better compressibility (see addClass) cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); if ( cur ) { j = 0; while ( ( clazz = classes[ j++ ] ) ) { // Remove *all* instances while ( cur.indexOf( " " + clazz + " " ) > -1 ) { cur = cur.replace( " " + clazz + " ", " " ); } } // Only assign if different to avoid unneeded rendering. finalValue = stripAndCollapse( cur ); if ( curValue !== finalValue ) { elem.setAttribute( "class", finalValue ); } } } } return this; }, toggleClass: function( value, stateVal ) { var type = typeof value, isValidValue = type === "string" || Array.isArray( value ); if ( typeof stateVal === "boolean" && isValidValue ) { return stateVal ? this.addClass( value ) : this.removeClass( value ); } if ( isFunction( value ) ) { return this.each( function( i ) { jQuery( this ).toggleClass( value.call( this, i, getClass( this ), stateVal ), stateVal ); } ); } return this.each( function() { var className, i, self, classNames; if ( isValidValue ) { // Toggle individual class names i = 0; self = jQuery( this ); classNames = classesToArray( value ); while ( ( className = classNames[ i++ ] ) ) { // Check each className given, space separated list if ( self.hasClass( className ) ) { self.removeClass( className ); } else { self.addClass( className ); } } // Toggle whole class name } else if ( value === undefined || type === "boolean" ) { className = getClass( this ); if ( className ) { // Store className if set dataPriv.set( this, "__className__", className ); } // If the element has a class name or if we're passed `false`, // then remove the whole classname (if there was one, the above saved it). // Otherwise bring back whatever was previously saved (if anything), // falling back to the empty string if nothing was stored. if ( this.setAttribute ) { this.setAttribute( "class", className || value === false ? "" : dataPriv.get( this, "__className__" ) || "" ); } } } ); }, hasClass: function( selector ) { var className, elem, i = 0; className = " " + selector + " "; while ( ( elem = this[ i++ ] ) ) { if ( elem.nodeType === 1 && ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { return true; } } return false; } } ); var rreturn = /\r/g; jQuery.fn.extend( { val: function( value ) { var hooks, ret, valueIsFunction, elem = this[ 0 ]; if ( !arguments.length ) { if ( elem ) { hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; if ( hooks && "get" in hooks && ( ret = hooks.get( elem, "value" ) ) !== undefined ) { return ret; } ret = elem.value; // Handle most common string cases if ( typeof ret === "string" ) { return ret.replace( rreturn, "" ); } // Handle cases where value is null/undef or number return ret == null ? "" : ret; } return; } valueIsFunction = isFunction( value ); return this.each( function( i ) { var val; if ( this.nodeType !== 1 ) { return; } if ( valueIsFunction ) { val = value.call( this, i, jQuery( this ).val() ); } else { val = value; } // Treat null/undefined as ""; convert numbers to string if ( val == null ) { val = ""; } else if ( typeof val === "number" ) { val += ""; } else if ( Array.isArray( val ) ) { val = jQuery.map( val, function( value ) { return value == null ? "" : value + ""; } ); } hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; // If set returns undefined, fall back to normal setting if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } } ); } } ); jQuery.extend( { valHooks: { option: { get: function( elem ) { var val = jQuery.find.attr( elem, "value" ); return val != null ? val : // Support: IE <=10 - 11 only // option.text throws exceptions (#14686, #14858) // Strip and collapse whitespace // https://html.spec.whatwg.org/#strip-and-collapse-whitespace stripAndCollapse( jQuery.text( elem ) ); } }, select: { get: function( elem ) { var value, option, i, options = elem.options, index = elem.selectedIndex, one = elem.type === "select-one", values = one ? null : [], max = one ? index + 1 : options.length; if ( index < 0 ) { i = max; } else { i = one ? index : 0; } // Loop through all the selected options for ( ; i < max; i++ ) { option = options[ i ]; // Support: IE <=9 only // IE8-9 doesn't update selected after form reset (#2551) if ( ( option.selected || i === index ) && // Don't return options that are disabled or in a disabled optgroup !option.disabled && ( !option.parentNode.disabled || !nodeName( option.parentNode, "optgroup" ) ) ) { // Get the specific value for the option value = jQuery( option ).val(); // We don't need an array for one selects if ( one ) { return value; } // Multi-Selects return an array values.push( value ); } } return values; }, set: function( elem, value ) { var optionSet, option, options = elem.options, values = jQuery.makeArray( value ), i = options.length; while ( i-- ) { option = options[ i ]; /* eslint-disable no-cond-assign */ if ( option.selected = jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 ) { optionSet = true; } /* eslint-enable no-cond-assign */ } // Force browsers to behave consistently when non-matching value is set if ( !optionSet ) { elem.selectedIndex = -1; } return values; } } } } ); // Radios and checkboxes getter/setter jQuery.each( [ "radio", "checkbox" ], function() { jQuery.valHooks[ this ] = { set: function( elem, value ) { if ( Array.isArray( value ) ) { return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); } } }; if ( !support.checkOn ) { jQuery.valHooks[ this ].get = function( elem ) { return elem.getAttribute( "value" ) === null ? "on" : elem.value; }; } } ); // Return jQuery for attributes-only inclusion support.focusin = "onfocusin" in window; var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, stopPropagationCallback = function( e ) { e.stopPropagation(); }; jQuery.extend( jQuery.event, { trigger: function( event, data, elem, onlyHandlers ) { var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, eventPath = [ elem || document ], type = hasOwn.call( event, "type" ) ? event.type : event, namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; cur = lastElement = tmp = elem = elem || document; // Don't do events on text and comment nodes if ( elem.nodeType === 3 || elem.nodeType === 8 ) { return; } // focus/blur morphs to focusin/out; ensure we're not firing them right now if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { return; } if ( type.indexOf( "." ) > -1 ) { // Namespaced trigger; create a regexp to match event type in handle() namespaces = type.split( "." ); type = namespaces.shift(); namespaces.sort(); } ontype = type.indexOf( ":" ) < 0 && "on" + type; // Caller can pass in a jQuery.Event object, Object, or just an event type string event = event[ jQuery.expando ] ? event : new jQuery.Event( type, typeof event === "object" && event ); // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) event.isTrigger = onlyHandlers ? 2 : 3; event.namespace = namespaces.join( "." ); event.rnamespace = event.namespace ? new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : null; // Clean up the event in case it is being reused event.result = undefined; if ( !event.target ) { event.target = elem; } // Clone any incoming data and prepend the event, creating the handler arg list data = data == null ? [ event ] : jQuery.makeArray( data, [ event ] ); // Allow special events to draw outside the lines special = jQuery.event.special[ type ] || {}; if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { return; } // Determine event propagation path in advance, per W3C events spec (#9951) // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { bubbleType = special.delegateType || type; if ( !rfocusMorph.test( bubbleType + type ) ) { cur = cur.parentNode; } for ( ; cur; cur = cur.parentNode ) { eventPath.push( cur ); tmp = cur; } // Only add window if we got to document (e.g., not plain obj or detached DOM) if ( tmp === ( elem.ownerDocument || document ) ) { eventPath.push( tmp.defaultView || tmp.parentWindow || window ); } } // Fire handlers on the event path i = 0; while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { lastElement = cur; event.type = i > 1 ? bubbleType : special.bindType || type; // jQuery handler handle = ( dataPriv.get( cur, "events" ) || Object.create( null ) )[ event.type ] && dataPriv.get( cur, "handle" ); if ( handle ) { handle.apply( cur, data ); } // Native handler handle = ontype && cur[ ontype ]; if ( handle && handle.apply && acceptData( cur ) ) { event.result = handle.apply( cur, data ); if ( event.result === false ) { event.preventDefault(); } } } event.type = type; // If nobody prevented the default action, do it now if ( !onlyHandlers && !event.isDefaultPrevented() ) { if ( ( !special._default || special._default.apply( eventPath.pop(), data ) === false ) && acceptData( elem ) ) { // Call a native DOM method on the target with the same name as the event. // Don't do default actions on window, that's where global variables be (#6170) if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { // Don't re-trigger an onFOO event when we call its FOO() method tmp = elem[ ontype ]; if ( tmp ) { elem[ ontype ] = null; } // Prevent re-triggering of the same event, since we already bubbled it above jQuery.event.triggered = type; if ( event.isPropagationStopped() ) { lastElement.addEventListener( type, stopPropagationCallback ); } elem[ type ](); if ( event.isPropagationStopped() ) { lastElement.removeEventListener( type, stopPropagationCallback ); } jQuery.event.triggered = undefined; if ( tmp ) { elem[ ontype ] = tmp; } } } } return event.result; }, // Piggyback on a donor event to simulate a different one // Used only for `focus(in | out)` events simulate: function( type, elem, event ) { var e = jQuery.extend( new jQuery.Event(), event, { type: type, isSimulated: true } ); jQuery.event.trigger( e, null, elem ); } } ); jQuery.fn.extend( { trigger: function( type, data ) { return this.each( function() { jQuery.event.trigger( type, data, this ); } ); }, triggerHandler: function( type, data ) { var elem = this[ 0 ]; if ( elem ) { return jQuery.event.trigger( type, data, elem, true ); } } } ); // Support: Firefox <=44 // Firefox doesn't have focus(in | out) events // Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 // // Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 // focus(in | out) events fire after focus & blur events, // which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order // Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 if ( !support.focusin ) { jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { // Attach a single capturing handler on the document while someone wants focusin/focusout var handler = function( event ) { jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); }; jQuery.event.special[ fix ] = { setup: function() { // Handle: regular nodes (via `this.ownerDocument`), window // (via `this.document`) & document (via `this`). var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access( doc, fix ); if ( !attaches ) { doc.addEventListener( orig, handler, true ); } dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); }, teardown: function() { var doc = this.ownerDocument || this.document || this, attaches = dataPriv.access( doc, fix ) - 1; if ( !attaches ) { doc.removeEventListener( orig, handler, true ); dataPriv.remove( doc, fix ); } else { dataPriv.access( doc, fix, attaches ); } } }; } ); } var location = window.location; var nonce = { guid: Date.now() }; var rquery = ( /\?/ ); // Cross-browser xml parsing jQuery.parseXML = function( data ) { var xml; if ( !data || typeof data !== "string" ) { return null; } // Support: IE 9 - 11 only // IE throws on parseFromString with invalid input. try { xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); } catch ( e ) { xml = undefined; } if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { jQuery.error( "Invalid XML: " + data ); } return xml; }; var rbracket = /\[\]$/, rCRLF = /\r?\n/g, rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, rsubmittable = /^(?:input|select|textarea|keygen)/i; function buildParams( prefix, obj, traditional, add ) { var name; if ( Array.isArray( obj ) ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { // Treat each array item as a scalar. add( prefix, v ); } else { // Item is non-scalar (array or object), encode its numeric index. buildParams( prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", v, traditional, add ); } } ); } else if ( !traditional && toType( obj ) === "object" ) { // Serialize object item. for ( name in obj ) { buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { // Serialize scalar item. add( prefix, obj ); } } // Serialize an array of form elements or a set of // key/values into a query string jQuery.param = function( a, traditional ) { var prefix, s = [], add = function( key, valueOrFunction ) { // If value is a function, invoke it and use its return value var value = isFunction( valueOrFunction ) ? valueOrFunction() : valueOrFunction; s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value == null ? "" : value ); }; if ( a == null ) { return ""; } // If an array was passed in, assume that it is an array of form elements. if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); } ); } else { // If traditional, encode the "old" way (the way 1.3.2 or older // did it), otherwise encode params recursively. for ( prefix in a ) { buildParams( prefix, a[ prefix ], traditional, add ); } } // Return the resulting serialization return s.join( "&" ); }; jQuery.fn.extend( { serialize: function() { return jQuery.param( this.serializeArray() ); }, serializeArray: function() { return this.map( function() { // Can add propHook for "elements" to filter or add form elements var elements = jQuery.prop( this, "elements" ); return elements ? jQuery.makeArray( elements ) : this; } ) .filter( function() { var type = this.type; // Use .is( ":disabled" ) so that fieldset[disabled] works return this.name && !jQuery( this ).is( ":disabled" ) && rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && ( this.checked || !rcheckableType.test( type ) ); } ) .map( function( _i, elem ) { var val = jQuery( this ).val(); if ( val == null ) { return null; } if ( Array.isArray( val ) ) { return jQuery.map( val, function( val ) { return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ); } return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; } ).get(); } } ); var r20 = /%20/g, rhash = /#.*$/, rantiCache = /([?&])_=[^&]*/, rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, // #7653, #8125, #8152: local protocol detection rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, rnoContent = /^(?:GET|HEAD)$/, rprotocol = /^\/\//, /* Prefilters * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) * 2) These are called: * - BEFORE asking for a transport * - AFTER param serialization (s.data is a string if s.processData is true) * 3) key is the dataType * 4) the catchall symbol "*" can be used * 5) execution will start with transport dataType and THEN continue down to "*" if needed */ prefilters = {}, /* Transports bindings * 1) key is the dataType * 2) the catchall symbol "*" can be used * 3) selection will start with transport dataType and THEN go to "*" if needed */ transports = {}, // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression allTypes = "*/".concat( "*" ), // Anchor tag for parsing the document origin originAnchor = document.createElement( "a" ); originAnchor.href = location.href; // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport function addToPrefiltersOrTransports( structure ) { // dataTypeExpression is optional and defaults to "*" return function( dataTypeExpression, func ) { if ( typeof dataTypeExpression !== "string" ) { func = dataTypeExpression; dataTypeExpression = "*"; } var dataType, i = 0, dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; if ( isFunction( func ) ) { // For each dataType in the dataTypeExpression while ( ( dataType = dataTypes[ i++ ] ) ) { // Prepend if requested if ( dataType[ 0 ] === "+" ) { dataType = dataType.slice( 1 ) || "*"; ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); // Otherwise append } else { ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); } } } }; } // Base inspection function for prefilters and transports function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { var inspected = {}, seekingTransport = ( structure === transports ); function inspect( dataType ) { var selected; inspected[ dataType ] = true; jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { options.dataTypes.unshift( dataTypeOrTransport ); inspect( dataTypeOrTransport ); return false; } else if ( seekingTransport ) { return !( selected = dataTypeOrTransport ); } } ); return selected; } return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); } // A special extend for ajax options // that takes "flat" options (not to be deep extended) // Fixes #9887 function ajaxExtend( target, src ) { var key, deep, flatOptions = jQuery.ajaxSettings.flatOptions || {}; for ( key in src ) { if ( src[ key ] !== undefined ) { ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; } } if ( deep ) { jQuery.extend( true, target, deep ); } return target; } /* Handles responses to an ajax request: * - finds the right dataType (mediates between content-type and expected dataType) * - returns the corresponding response */ function ajaxHandleResponses( s, jqXHR, responses ) { var ct, type, finalDataType, firstDataType, contents = s.contents, dataTypes = s.dataTypes; // Remove auto dataType and get content-type in the process while ( dataTypes[ 0 ] === "*" ) { dataTypes.shift(); if ( ct === undefined ) { ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); } } // Check if we're dealing with a known content-type if ( ct ) { for ( type in contents ) { if ( contents[ type ] && contents[ type ].test( ct ) ) { dataTypes.unshift( type ); break; } } } // Check to see if we have a response for the expected dataType if ( dataTypes[ 0 ] in responses ) { finalDataType = dataTypes[ 0 ]; } else { // Try convertible dataTypes for ( type in responses ) { if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { finalDataType = type; break; } if ( !firstDataType ) { firstDataType = type; } } // Or just use first one finalDataType = finalDataType || firstDataType; } // If we found a dataType // We add the dataType to the list if needed // and return the corresponding response if ( finalDataType ) { if ( finalDataType !== dataTypes[ 0 ] ) { dataTypes.unshift( finalDataType ); } return responses[ finalDataType ]; } } /* Chain conversions given the request and the original response * Also sets the responseXXX fields on the jqXHR instance */ function ajaxConvert( s, response, jqXHR, isSuccess ) { var conv2, current, conv, tmp, prev, converters = {}, // Work with a copy of dataTypes in case we need to modify it for conversion dataTypes = s.dataTypes.slice(); // Create converters map with lowercased keys if ( dataTypes[ 1 ] ) { for ( conv in s.converters ) { converters[ conv.toLowerCase() ] = s.converters[ conv ]; } } current = dataTypes.shift(); // Convert to each sequential dataType while ( current ) { if ( s.responseFields[ current ] ) { jqXHR[ s.responseFields[ current ] ] = response; } // Apply the dataFilter if provided if ( !prev && isSuccess && s.dataFilter ) { response = s.dataFilter( response, s.dataType ); } prev = current; current = dataTypes.shift(); if ( current ) { // There's only work to do if current dataType is non-auto if ( current === "*" ) { current = prev; // Convert response if prev dataType is non-auto and differs from current } else if ( prev !== "*" && prev !== current ) { // Seek a direct converter conv = converters[ prev + " " + current ] || converters[ "* " + current ]; // If none found, seek a pair if ( !conv ) { for ( conv2 in converters ) { // If conv2 outputs current tmp = conv2.split( " " ); if ( tmp[ 1 ] === current ) { // If prev can be converted to accepted input conv = converters[ prev + " " + tmp[ 0 ] ] || converters[ "* " + tmp[ 0 ] ]; if ( conv ) { // Condense equivalence converters if ( conv === true ) { conv = converters[ conv2 ]; // Otherwise, insert the intermediate dataType } else if ( converters[ conv2 ] !== true ) { current = tmp[ 0 ]; dataTypes.unshift( tmp[ 1 ] ); } break; } } } } // Apply converter (if not an equivalence) if ( conv !== true ) { // Unless errors are allowed to bubble, catch and return them if ( conv && s.throws ) { response = conv( response ); } else { try { response = conv( response ); } catch ( e ) { return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; } } } } } } return { state: "success", data: response }; } jQuery.extend( { // Counter for holding the number of active queries active: 0, // Last-Modified header cache for next request lastModified: {}, etag: {}, ajaxSettings: { url: location.href, type: "GET", isLocal: rlocalProtocol.test( location.protocol ), global: true, processData: true, async: true, contentType: "application/x-www-form-urlencoded; charset=UTF-8", /* timeout: 0, data: null, dataType: null, username: null, password: null, cache: null, throws: false, traditional: false, headers: {}, */ accepts: { "*": allTypes, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, // Data converters // Keys separate source (or catchall "*") and destination types with a single space converters: { // Convert anything to text "* text": String, // Text to html (true = no transformation) "text html": true, // Evaluate text as a json expression "text json": JSON.parse, // Parse text as xml "text xml": jQuery.parseXML }, // For options that shouldn't be deep extended: // you can add your own custom options here if // and when you create one that shouldn't be // deep extended (see ajaxExtend) flatOptions: { url: true, context: true } }, // Creates a full fledged settings object into target // with both ajaxSettings and settings fields. // If target is omitted, writes into ajaxSettings. ajaxSetup: function( target, settings ) { return settings ? // Building a settings object ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : // Extending ajaxSettings ajaxExtend( jQuery.ajaxSettings, target ); }, ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), ajaxTransport: addToPrefiltersOrTransports( transports ), // Main method ajax: function( url, options ) { // If url is an object, simulate pre-1.5 signature if ( typeof url === "object" ) { options = url; url = undefined; } // Force options to be an object options = options || {}; var transport, // URL without anti-cache param cacheURL, // Response headers responseHeadersString, responseHeaders, // timeout handle timeoutTimer, // Url cleanup var urlAnchor, // Request state (becomes false upon send and true upon completion) completed, // To know if global events are to be dispatched fireGlobals, // Loop variable i, // uncached part of the url uncached, // Create the final options object s = jQuery.ajaxSetup( {}, options ), // Callbacks context callbackContext = s.context || s, // Context for global events is callbackContext if it is a DOM node or jQuery collection globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? jQuery( callbackContext ) : jQuery.event, // Deferreds deferred = jQuery.Deferred(), completeDeferred = jQuery.Callbacks( "once memory" ), // Status-dependent callbacks statusCode = s.statusCode || {}, // Headers (they are sent all at once) requestHeaders = {}, requestHeadersNames = {}, // Default abort message strAbort = "canceled", // Fake xhr jqXHR = { readyState: 0, // Builds headers hashtable if needed getResponseHeader: function( key ) { var match; if ( completed ) { if ( !responseHeaders ) { responseHeaders = {}; while ( ( match = rheaders.exec( responseHeadersString ) ) ) { responseHeaders[ match[ 1 ].toLowerCase() + " " ] = ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) .concat( match[ 2 ] ); } } match = responseHeaders[ key.toLowerCase() + " " ]; } return match == null ? null : match.join( ", " ); }, // Raw string getAllResponseHeaders: function() { return completed ? responseHeadersString : null; }, // Caches the header setRequestHeader: function( name, value ) { if ( completed == null ) { name = requestHeadersNames[ name.toLowerCase() ] = requestHeadersNames[ name.toLowerCase() ] || name; requestHeaders[ name ] = value; } return this; }, // Overrides response content-type header overrideMimeType: function( type ) { if ( completed == null ) { s.mimeType = type; } return this; }, // Status-dependent callbacks statusCode: function( map ) { var code; if ( map ) { if ( completed ) { // Execute the appropriate callbacks jqXHR.always( map[ jqXHR.status ] ); } else { // Lazy-add the new callbacks in a way that preserves old ones for ( code in map ) { statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; } } } return this; }, // Cancel the request abort: function( statusText ) { var finalText = statusText || strAbort; if ( transport ) { transport.abort( finalText ); } done( 0, finalText ); return this; } }; // Attach deferreds deferred.promise( jqXHR ); // Add protocol if not provided (prefilters might expect it) // Handle falsy url in the settings object (#10093: consistency with old signature) // We also use the url parameter if available s.url = ( ( url || s.url || location.href ) + "" ) .replace( rprotocol, location.protocol + "//" ); // Alias method option to type as per ticket #12004 s.type = options.method || options.type || s.method || s.type; // Extract dataTypes list s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; // A cross-domain request is in order when the origin doesn't match the current origin. if ( s.crossDomain == null ) { urlAnchor = document.createElement( "a" ); // Support: IE <=8 - 11, Edge 12 - 15 // IE throws exception on accessing the href property if url is malformed, // e.g. http://example.com:80x/ try { urlAnchor.href = s.url; // Support: IE <=8 - 11 only // Anchor's host property isn't correctly set when s.url is relative urlAnchor.href = urlAnchor.href; s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host; } catch ( e ) { // If there is an error parsing the URL, assume it is crossDomain, // it can be rejected by the transport if it is invalid s.crossDomain = true; } } // Convert data if not already a string if ( s.data && s.processData && typeof s.data !== "string" ) { s.data = jQuery.param( s.data, s.traditional ); } // Apply prefilters inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); // If request was aborted inside a prefilter, stop there if ( completed ) { return jqXHR; } // We can fire global events as of now if asked to // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) fireGlobals = jQuery.event && s.global; // Watch for a new set of requests if ( fireGlobals && jQuery.active++ === 0 ) { jQuery.event.trigger( "ajaxStart" ); } // Uppercase the type s.type = s.type.toUpperCase(); // Determine if request has content s.hasContent = !rnoContent.test( s.type ); // Save the URL in case we're toying with the If-Modified-Since // and/or If-None-Match header later on // Remove hash to simplify url manipulation cacheURL = s.url.replace( rhash, "" ); // More options handling for requests with no content if ( !s.hasContent ) { // Remember the hash so we can put it back uncached = s.url.slice( cacheURL.length ); // If data is available and should be processed, append data to url if ( s.data && ( s.processData || typeof s.data === "string" ) ) { cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; // #9682: remove data so that it's not used in an eventual retry delete s.data; } // Add or update anti-cache param if needed if ( s.cache === false ) { cacheURL = cacheURL.replace( rantiCache, "$1" ); uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + uncached; } // Put hash and anti-cache on the URL that will be requested (gh-1732) s.url = cacheURL + uncached; // Change '%20' to '+' if this is encoded form body content (gh-2658) } else if ( s.data && s.processData && ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { s.data = s.data.replace( r20, "+" ); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { if ( jQuery.lastModified[ cacheURL ] ) { jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); } if ( jQuery.etag[ cacheURL ] ) { jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); } } // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { jqXHR.setRequestHeader( "Content-Type", s.contentType ); } // Set the Accepts header for the server, depending on the dataType jqXHR.setRequestHeader( "Accept", s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? s.accepts[ s.dataTypes[ 0 ] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : s.accepts[ "*" ] ); // Check for headers option for ( i in s.headers ) { jqXHR.setRequestHeader( i, s.headers[ i ] ); } // Allow custom headers/mimetypes and early abort if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { // Abort if not done already and return return jqXHR.abort(); } // Aborting is no longer a cancellation strAbort = "abort"; // Install callbacks on deferreds completeDeferred.add( s.complete ); jqXHR.done( s.success ); jqXHR.fail( s.error ); // Get transport transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); // If no transport, we auto-abort if ( !transport ) { done( -1, "No Transport" ); } else { jqXHR.readyState = 1; // Send global event if ( fireGlobals ) { globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); } // If request was aborted inside ajaxSend, stop there if ( completed ) { return jqXHR; } // Timeout if ( s.async && s.timeout > 0 ) { timeoutTimer = window.setTimeout( function() { jqXHR.abort( "timeout" ); }, s.timeout ); } try { completed = false; transport.send( requestHeaders, done ); } catch ( e ) { // Rethrow post-completion exceptions if ( completed ) { throw e; } // Propagate others as results done( -1, e ); } } // Callback for when everything is done function done( status, nativeStatusText, responses, headers ) { var isSuccess, success, error, response, modified, statusText = nativeStatusText; // Ignore repeat invocations if ( completed ) { return; } completed = true; // Clear timeout if it exists if ( timeoutTimer ) { window.clearTimeout( timeoutTimer ); } // Dereference transport for early garbage collection // (no matter how long the jqXHR object will be used) transport = undefined; // Cache response headers responseHeadersString = headers || ""; // Set readyState jqXHR.readyState = status > 0 ? 4 : 0; // Determine if successful isSuccess = status >= 200 && status < 300 || status === 304; // Get response data if ( responses ) { response = ajaxHandleResponses( s, jqXHR, responses ); } // Use a noop converter for missing script if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { s.converters[ "text script" ] = function() {}; } // Convert no matter what (that way responseXXX fields are always set) response = ajaxConvert( s, response, jqXHR, isSuccess ); // If successful, handle type chaining if ( isSuccess ) { // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { modified = jqXHR.getResponseHeader( "Last-Modified" ); if ( modified ) { jQuery.lastModified[ cacheURL ] = modified; } modified = jqXHR.getResponseHeader( "etag" ); if ( modified ) { jQuery.etag[ cacheURL ] = modified; } } // if no content if ( status === 204 || s.type === "HEAD" ) { statusText = "nocontent"; // if not modified } else if ( status === 304 ) { statusText = "notmodified"; // If we have data, let's convert it } else { statusText = response.state; success = response.data; error = response.error; isSuccess = !error; } } else { // Extract error from statusText and normalize for non-aborts error = statusText; if ( status || !statusText ) { statusText = "error"; if ( status < 0 ) { status = 0; } } } // Set data for the fake xhr object jqXHR.status = status; jqXHR.statusText = ( nativeStatusText || statusText ) + ""; // Success/Error if ( isSuccess ) { deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); } else { deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); } // Status-dependent callbacks jqXHR.statusCode( statusCode ); statusCode = undefined; if ( fireGlobals ) { globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", [ jqXHR, s, isSuccess ? success : error ] ); } // Complete completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); if ( fireGlobals ) { globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); // Handle the global AJAX counter if ( !( --jQuery.active ) ) { jQuery.event.trigger( "ajaxStop" ); } } } return jqXHR; }, getJSON: function( url, data, callback ) { return jQuery.get( url, data, callback, "json" ); }, getScript: function( url, callback ) { return jQuery.get( url, undefined, callback, "script" ); } } ); jQuery.each( [ "get", "post" ], function( _i, method ) { jQuery[ method ] = function( url, data, callback, type ) { // Shift arguments if data argument was omitted if ( isFunction( data ) ) { type = type || callback; callback = data; data = undefined; } // The url can be an options object (which then must have .url) return jQuery.ajax( jQuery.extend( { url: url, type: method, dataType: type, data: data, success: callback }, jQuery.isPlainObject( url ) && url ) ); }; } ); jQuery.ajaxPrefilter( function( s ) { var i; for ( i in s.headers ) { if ( i.toLowerCase() === "content-type" ) { s.contentType = s.headers[ i ] || ""; } } } ); jQuery._evalUrl = function( url, options, doc ) { return jQuery.ajax( { url: url, // Make this explicit, since user can override this through ajaxSetup (#11264) type: "GET", dataType: "script", cache: true, async: false, global: false, // Only evaluate the response if it is successful (gh-4126) // dataFilter is not invoked for failure responses, so using it instead // of the default converter is kludgy but it works. converters: { "text script": function() {} }, dataFilter: function( response ) { jQuery.globalEval( response, options, doc ); } } ); }; jQuery.fn.extend( { wrapAll: function( html ) { var wrap; if ( this[ 0 ] ) { if ( isFunction( html ) ) { html = html.call( this[ 0 ] ); } // The elements to wrap the target around wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); if ( this[ 0 ].parentNode ) { wrap.insertBefore( this[ 0 ] ); } wrap.map( function() { var elem = this; while ( elem.firstElementChild ) { elem = elem.firstElementChild; } return elem; } ).append( this ); } return this; }, wrapInner: function( html ) { if ( isFunction( html ) ) { return this.each( function( i ) { jQuery( this ).wrapInner( html.call( this, i ) ); } ); } return this.each( function() { var self = jQuery( this ), contents = self.contents(); if ( contents.length ) { contents.wrapAll( html ); } else { self.append( html ); } } ); }, wrap: function( html ) { var htmlIsFunction = isFunction( html ); return this.each( function( i ) { jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); } ); }, unwrap: function( selector ) { this.parent( selector ).not( "body" ).each( function() { jQuery( this ).replaceWith( this.childNodes ); } ); return this; } } ); jQuery.expr.pseudos.hidden = function( elem ) { return !jQuery.expr.pseudos.visible( elem ); }; jQuery.expr.pseudos.visible = function( elem ) { return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); }; jQuery.ajaxSettings.xhr = function() { try { return new window.XMLHttpRequest(); } catch ( e ) {} }; var xhrSuccessStatus = { // File protocol always yields status code 0, assume 200 0: 200, // Support: IE <=9 only // #1450: sometimes IE returns 1223 when it should be 204 1223: 204 }, xhrSupported = jQuery.ajaxSettings.xhr(); support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); support.ajax = xhrSupported = !!xhrSupported; jQuery.ajaxTransport( function( options ) { var callback, errorCallback; // Cross domain only allowed if supported through XMLHttpRequest if ( support.cors || xhrSupported && !options.crossDomain ) { return { send: function( headers, complete ) { var i, xhr = options.xhr(); xhr.open( options.type, options.url, options.async, options.username, options.password ); // Apply custom fields if provided if ( options.xhrFields ) { for ( i in options.xhrFields ) { xhr[ i ] = options.xhrFields[ i ]; } } // Override mime type if needed if ( options.mimeType && xhr.overrideMimeType ) { xhr.overrideMimeType( options.mimeType ); } // X-Requested-With header // For cross-domain requests, seeing as conditions for a preflight are // akin to a jigsaw puzzle, we simply never set it to be sure. // (it can always be set on a per-request basis or even using ajaxSetup) // For same-domain requests, won't change header if already provided. if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { headers[ "X-Requested-With" ] = "XMLHttpRequest"; } // Set headers for ( i in headers ) { xhr.setRequestHeader( i, headers[ i ] ); } // Callback callback = function( type ) { return function() { if ( callback ) { callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.ontimeout = xhr.onreadystatechange = null; if ( type === "abort" ) { xhr.abort(); } else if ( type === "error" ) { // Support: IE <=9 only // On a manual native abort, IE9 throws // errors on any property access that is not readyState if ( typeof xhr.status !== "number" ) { complete( 0, "error" ); } else { complete( // File: protocol always yields status 0; see #8605, #14207 xhr.status, xhr.statusText ); } } else { complete( xhrSuccessStatus[ xhr.status ] || xhr.status, xhr.statusText, // Support: IE <=9 only // IE9 has no XHR2 but throws on binary (trac-11426) // For XHR2 non-text, let the caller handle it (gh-2498) ( xhr.responseType || "text" ) !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders() ); } } }; }; // Listen to events xhr.onload = callback(); errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); // Support: IE 9 only // Use onreadystatechange to replace onabort // to handle uncaught aborts if ( xhr.onabort !== undefined ) { xhr.onabort = errorCallback; } else { xhr.onreadystatechange = function() { // Check readyState before timeout as it changes if ( xhr.readyState === 4 ) { // Allow onerror to be called first, // but that will not handle a native abort // Also, save errorCallback to a variable // as xhr.onerror cannot be accessed window.setTimeout( function() { if ( callback ) { errorCallback(); } } ); } }; } // Create the abort callback callback = callback( "abort" ); try { // Do send the request (this may raise an exception) xhr.send( options.hasContent && options.data || null ); } catch ( e ) { // #14683: Only rethrow if this hasn't been notified as an error yet if ( callback ) { throw e; } } }, abort: function() { if ( callback ) { callback(); } } }; } } ); // Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) jQuery.ajaxPrefilter( function( s ) { if ( s.crossDomain ) { s.contents.script = false; } } ); // Install script dataType jQuery.ajaxSetup( { accepts: { script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript" }, contents: { script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function( text ) { jQuery.globalEval( text ); return text; } } } ); // Handle cache's special case and crossDomain jQuery.ajaxPrefilter( "script", function( s ) { if ( s.cache === undefined ) { s.cache = false; } if ( s.crossDomain ) { s.type = "GET"; } } ); // Bind script tag hack transport jQuery.ajaxTransport( "script", function( s ) { // This transport only deals with cross domain or forced-by-attrs requests if ( s.crossDomain || s.scriptAttrs ) { var script, callback; return { send: function( _, complete ) { script = jQuery( "<script>" ) .attr( s.scriptAttrs || {} ) .prop( { charset: s.scriptCharset, src: s.url } ) .on( "load error", callback = function( evt ) { script.remove(); callback = null; if ( evt ) { complete( evt.type === "error" ? 404 : 200, evt.type ); } } ); // Use native DOM manipulation to avoid our domManip AJAX trickery document.head.appendChild( script[ 0 ] ); }, abort: function() { if ( callback ) { callback(); } } }; } } ); var oldCallbacks = [], rjsonp = /(=)\?(?=&|$)|\?\?/; // Default jsonp settings jQuery.ajaxSetup( { jsonp: "callback", jsonpCallback: function() { var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); this[ callback ] = true; return callback; } } ); // Detect, normalize options and install callbacks for jsonp requests jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { var callbackName, overwritten, responseContainer, jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? "url" : typeof s.data === "string" && ( s.contentType || "" ) .indexOf( "application/x-www-form-urlencoded" ) === 0 && rjsonp.test( s.data ) && "data" ); // Handle iff the expected data type is "jsonp" or we have a parameter to set if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { // Get callback name, remembering preexisting value associated with it callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? s.jsonpCallback() : s.jsonpCallback; // Insert callback into url or form data if ( jsonProp ) { s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); } else if ( s.jsonp !== false ) { s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; } // Use data converter to retrieve json after script execution s.converters[ "script json" ] = function() { if ( !responseContainer ) { jQuery.error( callbackName + " was not called" ); } return responseContainer[ 0 ]; }; // Force json dataType s.dataTypes[ 0 ] = "json"; // Install callback overwritten = window[ callbackName ]; window[ callbackName ] = function() { responseContainer = arguments; }; // Clean-up function (fires after converters) jqXHR.always( function() { // If previous value didn't exist - remove it if ( overwritten === undefined ) { jQuery( window ).removeProp( callbackName ); // Otherwise restore preexisting value } else { window[ callbackName ] = overwritten; } // Save back as free if ( s[ callbackName ] ) { // Make sure that re-using the options doesn't screw things around s.jsonpCallback = originalSettings.jsonpCallback; // Save the callback name for future use oldCallbacks.push( callbackName ); } // Call if it was a function and we have a response if ( responseContainer && isFunction( overwritten ) ) { overwritten( responseContainer[ 0 ] ); } responseContainer = overwritten = undefined; } ); // Delegate to script return "script"; } } ); // Support: Safari 8 only // In Safari 8 documents created via document.implementation.createHTMLDocument // collapse sibling forms: the second one becomes a child of the first one. // Because of that, this security measure has to be disabled in Safari 8. // https://bugs.webkit.org/show_bug.cgi?id=137337 support.createHTMLDocument = ( function() { var body = document.implementation.createHTMLDocument( "" ).body; body.innerHTML = "<form></form><form></form>"; return body.childNodes.length === 2; } )(); // Argument "data" should be string of html // context (optional): If specified, the fragment will be created in this context, // defaults to document // keepScripts (optional): If true, will include scripts passed in the html string jQuery.parseHTML = function( data, context, keepScripts ) { if ( typeof data !== "string" ) { return []; } if ( typeof context === "boolean" ) { keepScripts = context; context = false; } var base, parsed, scripts; if ( !context ) { // Stop scripts or inline event handlers from being executed immediately // by using document.implementation if ( support.createHTMLDocument ) { context = document.implementation.createHTMLDocument( "" ); // Set the base href for the created document // so any parsed elements with URLs // are based on the document's URL (gh-2965) base = context.createElement( "base" ); base.href = document.location.href; context.head.appendChild( base ); } else { context = document; } } parsed = rsingleTag.exec( data ); scripts = !keepScripts && []; // Single tag if ( parsed ) { return [ context.createElement( parsed[ 1 ] ) ]; } parsed = buildFragment( [ data ], context, scripts ); if ( scripts && scripts.length ) { jQuery( scripts ).remove(); } return jQuery.merge( [], parsed.childNodes ); }; /** * Load a url into a page */ jQuery.fn.load = function( url, params, callback ) { var selector, type, response, self = this, off = url.indexOf( " " ); if ( off > -1 ) { selector = stripAndCollapse( url.slice( off ) ); url = url.slice( 0, off ); } // If it's a function if ( isFunction( params ) ) { // We assume that it's the callback callback = params; params = undefined; // Otherwise, build a param string } else if ( params && typeof params === "object" ) { type = "POST"; } // If we have elements to modify, make the request if ( self.length > 0 ) { jQuery.ajax( { url: url, // If "type" variable is undefined, then "GET" method will be used. // Make value of this field explicit since // user can override it through ajaxSetup method type: type || "GET", dataType: "html", data: params } ).done( function( responseText ) { // Save response for use in complete callback response = arguments; self.html( selector ? // If a selector was specified, locate the right elements in a dummy div // Exclude scripts to avoid IE 'Permission Denied' errors jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : // Otherwise use the full result responseText ); // If the request succeeds, this function gets "data", "status", "jqXHR" // but they are ignored because response was set above. // If it fails, this function gets "jqXHR", "status", "error" } ).always( callback && function( jqXHR, status ) { self.each( function() { callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); } ); } ); } return this; }; jQuery.expr.pseudos.animated = function( elem ) { return jQuery.grep( jQuery.timers, function( fn ) { return elem === fn.elem; } ).length; }; jQuery.offset = { setOffset: function( elem, options, i ) { var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, position = jQuery.css( elem, "position" ), curElem = jQuery( elem ), props = {}; // Set position first, in-case top/left are set even on static elem if ( position === "static" ) { elem.style.position = "relative"; } curOffset = curElem.offset(); curCSSTop = jQuery.css( elem, "top" ); curCSSLeft = jQuery.css( elem, "left" ); calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; // Need to be able to calculate position if either // top or left is auto and position is either absolute or fixed if ( calculatePosition ) { curPosition = curElem.position(); curTop = curPosition.top; curLeft = curPosition.left; } else { curTop = parseFloat( curCSSTop ) || 0; curLeft = parseFloat( curCSSLeft ) || 0; } if ( isFunction( options ) ) { // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); } if ( options.top != null ) { props.top = ( options.top - curOffset.top ) + curTop; } if ( options.left != null ) { props.left = ( options.left - curOffset.left ) + curLeft; } if ( "using" in options ) { options.using.call( elem, props ); } else { if ( typeof props.top === "number" ) { props.top += "px"; } if ( typeof props.left === "number" ) { props.left += "px"; } curElem.css( props ); } } }; jQuery.fn.extend( { // offset() relates an element's border box to the document origin offset: function( options ) { // Preserve chaining for setter if ( arguments.length ) { return options === undefined ? this : this.each( function( i ) { jQuery.offset.setOffset( this, options, i ); } ); } var rect, win, elem = this[ 0 ]; if ( !elem ) { return; } // Return zeros for disconnected and hidden (display: none) elements (gh-2310) // Support: IE <=11 only // Running getBoundingClientRect on a // disconnected node in IE throws an error if ( !elem.getClientRects().length ) { return { top: 0, left: 0 }; } // Get document-relative position by adding viewport scroll to viewport-relative gBCR rect = elem.getBoundingClientRect(); win = elem.ownerDocument.defaultView; return { top: rect.top + win.pageYOffset, left: rect.left + win.pageXOffset }; }, // position() relates an element's margin box to its offset parent's padding box // This corresponds to the behavior of CSS absolute positioning position: function() { if ( !this[ 0 ] ) { return; } var offsetParent, offset, doc, elem = this[ 0 ], parentOffset = { top: 0, left: 0 }; // position:fixed elements are offset from the viewport, which itself always has zero offset if ( jQuery.css( elem, "position" ) === "fixed" ) { // Assume position:fixed implies availability of getBoundingClientRect offset = elem.getBoundingClientRect(); } else { offset = this.offset(); // Account for the *real* offset parent, which can be the document or its root element // when a statically positioned element is identified doc = elem.ownerDocument; offsetParent = elem.offsetParent || doc.documentElement; while ( offsetParent && ( offsetParent === doc.body || offsetParent === doc.documentElement ) && jQuery.css( offsetParent, "position" ) === "static" ) { offsetParent = offsetParent.parentNode; } if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { // Incorporate borders into its offset, since they are outside its content origin parentOffset = jQuery( offsetParent ).offset(); parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); } } // Subtract parent offsets and element margins return { top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) }; }, // This method will return documentElement in the following cases: // 1) For the element inside the iframe without offsetParent, this method will return // documentElement of the parent window // 2) For the hidden or detached element // 3) For body or html element, i.e. in case of the html node - it will return itself // // but those exceptions were never presented as a real life use-cases // and might be considered as more preferable results. // // This logic, however, is not guaranteed and can change at any point in the future offsetParent: function() { return this.map( function() { var offsetParent = this.offsetParent; while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { offsetParent = offsetParent.offsetParent; } return offsetParent || documentElement; } ); } } ); // Create scrollLeft and scrollTop methods jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { var top = "pageYOffset" === prop; jQuery.fn[ method ] = function( val ) { return access( this, function( elem, method, val ) { // Coalesce documents and windows var win; if ( isWindow( elem ) ) { win = elem; } else if ( elem.nodeType === 9 ) { win = elem.defaultView; } if ( val === undefined ) { return win ? win[ prop ] : elem[ method ]; } if ( win ) { win.scrollTo( !top ? val : win.pageXOffset, top ? val : win.pageYOffset ); } else { elem[ method ] = val; } }, method, val, arguments.length ); }; } ); // Support: Safari <=7 - 9.1, Chrome <=37 - 49 // Add the top/left cssHooks using jQuery.fn.position // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 // Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 // getComputedStyle returns percent when specified for top/left/bottom/right; // rather than make the css module depend on the offset module, just check for it here jQuery.each( [ "top", "left" ], function( _i, prop ) { jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, function( elem, computed ) { if ( computed ) { computed = curCSS( elem, prop ); // If curCSS returns percentage, fallback to offset return rnumnonpx.test( computed ) ? jQuery( elem ).position()[ prop ] + "px" : computed; } } ); } ); // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { // Margin is only for outerHeight, outerWidth jQuery.fn[ funcName ] = function( margin, value ) { var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); return access( this, function( elem, type, value ) { var doc; if ( isWindow( elem ) ) { // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) return funcName.indexOf( "outer" ) === 0 ? elem[ "inner" + name ] : elem.document.documentElement[ "client" + name ]; } // Get document width or height if ( elem.nodeType === 9 ) { doc = elem.documentElement; // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], // whichever is greatest return Math.max( elem.body[ "scroll" + name ], doc[ "scroll" + name ], elem.body[ "offset" + name ], doc[ "offset" + name ], doc[ "client" + name ] ); } return value === undefined ? // Get width or height on the element, requesting but not forcing parseFloat jQuery.css( elem, type, extra ) : // Set width or height on the element jQuery.style( elem, type, value, extra ); }, type, chainable ? margin : undefined, chainable ); }; } ); } ); jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( _i, type ) { jQuery.fn[ type ] = function( fn ) { return this.on( type, fn ); }; } ); jQuery.fn.extend( { bind: function( types, data, fn ) { return this.on( types, null, data, fn ); }, unbind: function( types, fn ) { return this.off( types, null, fn ); }, delegate: function( selector, types, data, fn ) { return this.on( types, selector, data, fn ); }, undelegate: function( selector, types, fn ) { // ( namespace ) or ( selector, types [, fn] ) return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); }, hover: function( fnOver, fnOut ) { return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); } } ); jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup contextmenu" ).split( " " ), function( _i, name ) { // Handle event binding jQuery.fn[ name ] = function( data, fn ) { return arguments.length > 0 ? this.on( name, null, data, fn ) : this.trigger( name ); }; } ); // Support: Android <=4.0 only // Make sure we trim BOM and NBSP var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; // Bind a function to a context, optionally partially applying any // arguments. // jQuery.proxy is deprecated to promote standards (specifically Function#bind) // However, it is not slated for removal any time soon jQuery.proxy = function( fn, context ) { var tmp, args, proxy; if ( typeof context === "string" ) { tmp = fn[ context ]; context = fn; fn = tmp; } // Quick check to determine if target is callable, in the spec // this throws a TypeError, but we will just return undefined. if ( !isFunction( fn ) ) { return undefined; } // Simulated bind args = slice.call( arguments, 2 ); proxy = function() { return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); }; // Set the guid of unique handler to the same of original handler, so it can be removed proxy.guid = fn.guid = fn.guid || jQuery.guid++; return proxy; }; jQuery.holdReady = function( hold ) { if ( hold ) { jQuery.readyWait++; } else { jQuery.ready( true ); } }; jQuery.isArray = Array.isArray; jQuery.parseJSON = JSON.parse; jQuery.nodeName = nodeName; jQuery.isFunction = isFunction; jQuery.isWindow = isWindow; jQuery.camelCase = camelCase; jQuery.type = toType; jQuery.now = Date.now; jQuery.isNumeric = function( obj ) { // As of jQuery 3.0, isNumeric is limited to // strings and numbers (primitives or objects) // that can be coerced to finite numbers (gh-2662) var type = jQuery.type( obj ); return ( type === "number" || type === "string" ) && // parseFloat NaNs numeric-cast false positives ("") // ...but misinterprets leading-number strings, particularly hex literals ("0x...") // subtraction forces infinities to NaN !isNaN( obj - parseFloat( obj ) ); }; jQuery.trim = function( text ) { return text == null ? "" : ( text + "" ).replace( rtrim, "" ); }; // Register as a named AMD module, since jQuery can be concatenated with other // files that may use define, but not via a proper concatenation script that // understands anonymous AMD modules. A named AMD is safest and most robust // way to register. Lowercase jquery is used because AMD module names are // derived from file names, and jQuery is normally delivered in a lowercase // file name. Do this after creating the global so that if an AMD module wants // to call noConflict to hide this version of jQuery, it will work. // Note that for maximum portability, libraries that are not jQuery should // declare themselves as anonymous modules, and avoid setting a global if an // AMD loader is present. jQuery is a special case. For more information, see // https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon if ( typeof define === "function" && define.amd ) { define( "jquery", [], function() { return jQuery; } ); } var // Map over jQuery in case of overwrite _jQuery = window.jQuery, // Map over the $ in case of overwrite _$ = window.$; jQuery.noConflict = function( deep ) { if ( window.$ === jQuery ) { window.$ = _$; } if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } return jQuery; }; // Expose jQuery and $ identifiers, even in AMD // (#7102#comment:10, https://github.com/jquery/jquery/pull/557) // and CommonJS for browser emulators (#13566) if ( typeof noGlobal === "undefined" ) { window.jQuery = window.$ = jQuery; } return jQuery; } ); },{}],349:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var DataView = getNative(root, 'DataView'); module.exports = DataView; },{"./_getNative":447,"./_root":494}],350:[function(require,module,exports){ var hashClear = require('./_hashClear'), hashDelete = require('./_hashDelete'), hashGet = require('./_hashGet'), hashHas = require('./_hashHas'), hashSet = require('./_hashSet'); /** * Creates a hash object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Hash(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `Hash`. Hash.prototype.clear = hashClear; Hash.prototype['delete'] = hashDelete; Hash.prototype.get = hashGet; Hash.prototype.has = hashHas; Hash.prototype.set = hashSet; module.exports = Hash; },{"./_hashClear":455,"./_hashDelete":456,"./_hashGet":457,"./_hashHas":458,"./_hashSet":459}],351:[function(require,module,exports){ var baseCreate = require('./_baseCreate'), baseLodash = require('./_baseLodash'); /** Used as references for the maximum length and index of an array. */ var MAX_ARRAY_LENGTH = 4294967295; /** * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. * * @private * @constructor * @param {*} value The value to wrap. */ function LazyWrapper(value) { this.__wrapped__ = value; this.__actions__ = []; this.__dir__ = 1; this.__filtered__ = false; this.__iteratees__ = []; this.__takeCount__ = MAX_ARRAY_LENGTH; this.__views__ = []; } // Ensure `LazyWrapper` is an instance of `baseLodash`. LazyWrapper.prototype = baseCreate(baseLodash.prototype); LazyWrapper.prototype.constructor = LazyWrapper; module.exports = LazyWrapper; },{"./_baseCreate":377,"./_baseLodash":399}],352:[function(require,module,exports){ var listCacheClear = require('./_listCacheClear'), listCacheDelete = require('./_listCacheDelete'), listCacheGet = require('./_listCacheGet'), listCacheHas = require('./_listCacheHas'), listCacheSet = require('./_listCacheSet'); /** * Creates an list cache object. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function ListCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `ListCache`. ListCache.prototype.clear = listCacheClear; ListCache.prototype['delete'] = listCacheDelete; ListCache.prototype.get = listCacheGet; ListCache.prototype.has = listCacheHas; ListCache.prototype.set = listCacheSet; module.exports = ListCache; },{"./_listCacheClear":470,"./_listCacheDelete":471,"./_listCacheGet":472,"./_listCacheHas":473,"./_listCacheSet":474}],353:[function(require,module,exports){ var baseCreate = require('./_baseCreate'), baseLodash = require('./_baseLodash'); /** * The base constructor for creating `lodash` wrapper objects. * * @private * @param {*} value The value to wrap. * @param {boolean} [chainAll] Enable explicit method chain sequences. */ function LodashWrapper(value, chainAll) { this.__wrapped__ = value; this.__actions__ = []; this.__chain__ = !!chainAll; this.__index__ = 0; this.__values__ = undefined; } LodashWrapper.prototype = baseCreate(baseLodash.prototype); LodashWrapper.prototype.constructor = LodashWrapper; module.exports = LodashWrapper; },{"./_baseCreate":377,"./_baseLodash":399}],354:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var Map = getNative(root, 'Map'); module.exports = Map; },{"./_getNative":447,"./_root":494}],355:[function(require,module,exports){ var mapCacheClear = require('./_mapCacheClear'), mapCacheDelete = require('./_mapCacheDelete'), mapCacheGet = require('./_mapCacheGet'), mapCacheHas = require('./_mapCacheHas'), mapCacheSet = require('./_mapCacheSet'); /** * Creates a map cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function MapCache(entries) { var index = -1, length = entries == null ? 0 : entries.length; this.clear(); while (++index < length) { var entry = entries[index]; this.set(entry[0], entry[1]); } } // Add methods to `MapCache`. MapCache.prototype.clear = mapCacheClear; MapCache.prototype['delete'] = mapCacheDelete; MapCache.prototype.get = mapCacheGet; MapCache.prototype.has = mapCacheHas; MapCache.prototype.set = mapCacheSet; module.exports = MapCache; },{"./_mapCacheClear":475,"./_mapCacheDelete":476,"./_mapCacheGet":477,"./_mapCacheHas":478,"./_mapCacheSet":479}],356:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var Promise = getNative(root, 'Promise'); module.exports = Promise; },{"./_getNative":447,"./_root":494}],357:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var Set = getNative(root, 'Set'); module.exports = Set; },{"./_getNative":447,"./_root":494}],358:[function(require,module,exports){ var MapCache = require('./_MapCache'), setCacheAdd = require('./_setCacheAdd'), setCacheHas = require('./_setCacheHas'); /** * * Creates an array cache object to store unique values. * * @private * @constructor * @param {Array} [values] The values to cache. */ function SetCache(values) { var index = -1, length = values == null ? 0 : values.length; this.__data__ = new MapCache; while (++index < length) { this.add(values[index]); } } // Add methods to `SetCache`. SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; SetCache.prototype.has = setCacheHas; module.exports = SetCache; },{"./_MapCache":355,"./_setCacheAdd":495,"./_setCacheHas":496}],359:[function(require,module,exports){ var ListCache = require('./_ListCache'), stackClear = require('./_stackClear'), stackDelete = require('./_stackDelete'), stackGet = require('./_stackGet'), stackHas = require('./_stackHas'), stackSet = require('./_stackSet'); /** * Creates a stack cache object to store key-value pairs. * * @private * @constructor * @param {Array} [entries] The key-value pairs to cache. */ function Stack(entries) { var data = this.__data__ = new ListCache(entries); this.size = data.size; } // Add methods to `Stack`. Stack.prototype.clear = stackClear; Stack.prototype['delete'] = stackDelete; Stack.prototype.get = stackGet; Stack.prototype.has = stackHas; Stack.prototype.set = stackSet; module.exports = Stack; },{"./_ListCache":352,"./_stackClear":502,"./_stackDelete":503,"./_stackGet":504,"./_stackHas":505,"./_stackSet":506}],360:[function(require,module,exports){ var root = require('./_root'); /** Built-in value references. */ var Symbol = root.Symbol; module.exports = Symbol; },{"./_root":494}],361:[function(require,module,exports){ var root = require('./_root'); /** Built-in value references. */ var Uint8Array = root.Uint8Array; module.exports = Uint8Array; },{"./_root":494}],362:[function(require,module,exports){ var getNative = require('./_getNative'), root = require('./_root'); /* Built-in method references that are verified to be native. */ var WeakMap = getNative(root, 'WeakMap'); module.exports = WeakMap; },{"./_getNative":447,"./_root":494}],363:[function(require,module,exports){ /** * A faster alternative to `Function#apply`, this function invokes `func` * with the `this` binding of `thisArg` and the arguments of `args`. * * @private * @param {Function} func The function to invoke. * @param {*} thisArg The `this` binding of `func`. * @param {Array} args The arguments to invoke `func` with. * @returns {*} Returns the result of `func`. */ function apply(func, thisArg, args) { switch (args.length) { case 0: return func.call(thisArg); case 1: return func.call(thisArg, args[0]); case 2: return func.call(thisArg, args[0], args[1]); case 3: return func.call(thisArg, args[0], args[1], args[2]); } return func.apply(thisArg, args); } module.exports = apply; },{}],364:[function(require,module,exports){ /** * A specialized version of `baseAggregator` for arrays. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform keys. * @param {Object} accumulator The initial aggregated object. * @returns {Function} Returns `accumulator`. */ function arrayAggregator(array, setter, iteratee, accumulator) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { var value = array[index]; setter(accumulator, value, iteratee(value), array); } return accumulator; } module.exports = arrayAggregator; },{}],365:[function(require,module,exports){ /** * A specialized version of `_.forEach` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns `array`. */ function arrayEach(array, iteratee) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (iteratee(array[index], index, array) === false) { break; } } return array; } module.exports = arrayEach; },{}],366:[function(require,module,exports){ /** * A specialized version of `_.filter` for arrays without support for * iteratee shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function arrayFilter(array, predicate) { var index = -1, length = array == null ? 0 : array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (predicate(value, index, array)) { result[resIndex++] = value; } } return result; } module.exports = arrayFilter; },{}],367:[function(require,module,exports){ var baseIndexOf = require('./_baseIndexOf'); /** * A specialized version of `_.includes` for arrays without support for * specifying an index to search from. * * @private * @param {Array} [array] The array to inspect. * @param {*} target The value to search for. * @returns {boolean} Returns `true` if `target` is found, else `false`. */ function arrayIncludes(array, value) { var length = array == null ? 0 : array.length; return !!length && baseIndexOf(array, value, 0) > -1; } module.exports = arrayIncludes; },{"./_baseIndexOf":389}],368:[function(require,module,exports){ /** * This function is like `arrayIncludes` except that it accepts a comparator. * * @private * @param {Array} [array] The array to inspect. * @param {*} target The value to search for. * @param {Function} comparator The comparator invoked per element. * @returns {boolean} Returns `true` if `target` is found, else `false`. */ function arrayIncludesWith(array, value, comparator) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (comparator(value, array[index])) { return true; } } return false; } module.exports = arrayIncludesWith; },{}],369:[function(require,module,exports){ var baseTimes = require('./_baseTimes'), isArguments = require('./isArguments'), isArray = require('./isArray'), isBuffer = require('./isBuffer'), isIndex = require('./_isIndex'), isTypedArray = require('./isTypedArray'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Creates an array of the enumerable property names of the array-like `value`. * * @private * @param {*} value The value to query. * @param {boolean} inherited Specify returning inherited property names. * @returns {Array} Returns the array of property names. */ function arrayLikeKeys(value, inherited) { var isArr = isArray(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length; for (var key in value) { if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && ( // Safari 9 has enumerable `arguments.length` in strict mode. key == 'length' || // Node.js 0.10 has enumerable non-index properties on buffers. (isBuff && (key == 'offset' || key == 'parent')) || // PhantomJS 2 has enumerable non-index properties on typed arrays. (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || // Skip index properties. isIndex(key, length) ))) { result.push(key); } } return result; } module.exports = arrayLikeKeys; },{"./_baseTimes":408,"./_isIndex":462,"./isArguments":526,"./isArray":527,"./isBuffer":530,"./isTypedArray":537}],370:[function(require,module,exports){ /** * A specialized version of `_.map` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function arrayMap(array, iteratee) { var index = -1, length = array == null ? 0 : array.length, result = Array(length); while (++index < length) { result[index] = iteratee(array[index], index, array); } return result; } module.exports = arrayMap; },{}],371:[function(require,module,exports){ /** * Appends the elements of `values` to `array`. * * @private * @param {Array} array The array to modify. * @param {Array} values The values to append. * @returns {Array} Returns `array`. */ function arrayPush(array, values) { var index = -1, length = values.length, offset = array.length; while (++index < length) { array[offset + index] = values[index]; } return array; } module.exports = arrayPush; },{}],372:[function(require,module,exports){ /** * A specialized version of `_.some` for arrays without support for iteratee * shorthands. * * @private * @param {Array} [array] The array to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {boolean} Returns `true` if any element passes the predicate check, * else `false`. */ function arraySome(array, predicate) { var index = -1, length = array == null ? 0 : array.length; while (++index < length) { if (predicate(array[index], index, array)) { return true; } } return false; } module.exports = arraySome; },{}],373:[function(require,module,exports){ var baseAssignValue = require('./_baseAssignValue'), eq = require('./eq'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Assigns `value` to `key` of `object` if the existing value is not equivalent * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * for equality comparisons. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function assignValue(object, key, value) { var objValue = object[key]; if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || (value === undefined && !(key in object))) { baseAssignValue(object, key, value); } } module.exports = assignValue; },{"./_baseAssignValue":376,"./eq":517}],374:[function(require,module,exports){ var eq = require('./eq'); /** * Gets the index at which the `key` is found in `array` of key-value pairs. * * @private * @param {Array} array The array to inspect. * @param {*} key The key to search for. * @returns {number} Returns the index of the matched value, else `-1`. */ function assocIndexOf(array, key) { var length = array.length; while (length--) { if (eq(array[length][0], key)) { return length; } } return -1; } module.exports = assocIndexOf; },{"./eq":517}],375:[function(require,module,exports){ var baseEach = require('./_baseEach'); /** * Aggregates elements of `collection` on `accumulator` with keys transformed * by `iteratee` and values set by `setter`. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} setter The function to set `accumulator` values. * @param {Function} iteratee The iteratee to transform keys. * @param {Object} accumulator The initial aggregated object. * @returns {Function} Returns `accumulator`. */ function baseAggregator(collection, setter, iteratee, accumulator) { baseEach(collection, function(value, key, collection) { setter(accumulator, value, iteratee(value), collection); }); return accumulator; } module.exports = baseAggregator; },{"./_baseEach":379}],376:[function(require,module,exports){ var defineProperty = require('./_defineProperty'); /** * The base implementation of `assignValue` and `assignMergeValue` without * value checks. * * @private * @param {Object} object The object to modify. * @param {string} key The key of the property to assign. * @param {*} value The value to assign. */ function baseAssignValue(object, key, value) { if (key == '__proto__' && defineProperty) { defineProperty(object, key, { 'configurable': true, 'enumerable': true, 'value': value, 'writable': true }); } else { object[key] = value; } } module.exports = baseAssignValue; },{"./_defineProperty":436}],377:[function(require,module,exports){ var isObject = require('./isObject'); /** Built-in value references. */ var objectCreate = Object.create; /** * The base implementation of `_.create` without support for assigning * properties to the created object. * * @private * @param {Object} proto The object to inherit from. * @returns {Object} Returns the new object. */ var baseCreate = (function() { function object() {} return function(proto) { if (!isObject(proto)) { return {}; } if (objectCreate) { return objectCreate(proto); } object.prototype = proto; var result = new object; object.prototype = undefined; return result; }; }()); module.exports = baseCreate; },{"./isObject":534}],378:[function(require,module,exports){ var SetCache = require('./_SetCache'), arrayIncludes = require('./_arrayIncludes'), arrayIncludesWith = require('./_arrayIncludesWith'), arrayMap = require('./_arrayMap'), baseUnary = require('./_baseUnary'), cacheHas = require('./_cacheHas'); /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** * The base implementation of methods like `_.difference` without support * for excluding multiple arrays or iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Array} values The values to exclude. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of filtered values. */ function baseDifference(array, values, iteratee, comparator) { var index = -1, includes = arrayIncludes, isCommon = true, length = array.length, result = [], valuesLength = values.length; if (!length) { return result; } if (iteratee) { values = arrayMap(values, baseUnary(iteratee)); } if (comparator) { includes = arrayIncludesWith; isCommon = false; } else if (values.length >= LARGE_ARRAY_SIZE) { includes = cacheHas; isCommon = false; values = new SetCache(values); } outer: while (++index < length) { var value = array[index], computed = iteratee == null ? value : iteratee(value); value = (comparator || value !== 0) ? value : 0; if (isCommon && computed === computed) { var valuesIndex = valuesLength; while (valuesIndex--) { if (values[valuesIndex] === computed) { continue outer; } } result.push(value); } else if (!includes(values, computed, comparator)) { result.push(value); } } return result; } module.exports = baseDifference; },{"./_SetCache":358,"./_arrayIncludes":367,"./_arrayIncludesWith":368,"./_arrayMap":370,"./_baseUnary":410,"./_cacheHas":414}],379:[function(require,module,exports){ var baseForOwn = require('./_baseForOwn'), createBaseEach = require('./_createBaseEach'); /** * The base implementation of `_.forEach` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array|Object} Returns `collection`. */ var baseEach = createBaseEach(baseForOwn); module.exports = baseEach; },{"./_baseForOwn":384,"./_createBaseEach":425}],380:[function(require,module,exports){ var baseEach = require('./_baseEach'); /** * The base implementation of `_.filter` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} predicate The function invoked per iteration. * @returns {Array} Returns the new filtered array. */ function baseFilter(collection, predicate) { var result = []; baseEach(collection, function(value, index, collection) { if (predicate(value, index, collection)) { result.push(value); } }); return result; } module.exports = baseFilter; },{"./_baseEach":379}],381:[function(require,module,exports){ /** * The base implementation of `_.findIndex` and `_.findLastIndex` without * support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Function} predicate The function invoked per iteration. * @param {number} fromIndex The index to search from. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseFindIndex(array, predicate, fromIndex, fromRight) { var length = array.length, index = fromIndex + (fromRight ? 1 : -1); while ((fromRight ? index-- : ++index < length)) { if (predicate(array[index], index, array)) { return index; } } return -1; } module.exports = baseFindIndex; },{}],382:[function(require,module,exports){ var arrayPush = require('./_arrayPush'), isFlattenable = require('./_isFlattenable'); /** * The base implementation of `_.flatten` with support for restricting flattening. * * @private * @param {Array} array The array to flatten. * @param {number} depth The maximum recursion depth. * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. * @param {Array} [result=[]] The initial result value. * @returns {Array} Returns the new flattened array. */ function baseFlatten(array, depth, predicate, isStrict, result) { var index = -1, length = array.length; predicate || (predicate = isFlattenable); result || (result = []); while (++index < length) { var value = array[index]; if (depth > 0 && predicate(value)) { if (depth > 1) { // Recursively flatten arrays (susceptible to call stack limits). baseFlatten(value, depth - 1, predicate, isStrict, result); } else { arrayPush(result, value); } } else if (!isStrict) { result[result.length] = value; } } return result; } module.exports = baseFlatten; },{"./_arrayPush":371,"./_isFlattenable":461}],383:[function(require,module,exports){ var createBaseFor = require('./_createBaseFor'); /** * The base implementation of `baseForOwn` which iterates over `object` * properties returned by `keysFunc` and invokes `iteratee` for each property. * Iteratee functions may exit iteration early by explicitly returning `false`. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @param {Function} keysFunc The function to get the keys of `object`. * @returns {Object} Returns `object`. */ var baseFor = createBaseFor(); module.exports = baseFor; },{"./_createBaseFor":426}],384:[function(require,module,exports){ var baseFor = require('./_baseFor'), keys = require('./keys'); /** * The base implementation of `_.forOwn` without support for iteratee shorthands. * * @private * @param {Object} object The object to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Object} Returns `object`. */ function baseForOwn(object, iteratee) { return object && baseFor(object, iteratee, keys); } module.exports = baseForOwn; },{"./_baseFor":383,"./keys":539}],385:[function(require,module,exports){ var castPath = require('./_castPath'), toKey = require('./_toKey'); /** * The base implementation of `_.get` without support for default values. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. * @returns {*} Returns the resolved value. */ function baseGet(object, path) { path = castPath(path, object); var index = 0, length = path.length; while (object != null && index < length) { object = object[toKey(path[index++])]; } return (index && index == length) ? object : undefined; } module.exports = baseGet; },{"./_castPath":416,"./_toKey":509}],386:[function(require,module,exports){ var arrayPush = require('./_arrayPush'), isArray = require('./isArray'); /** * The base implementation of `getAllKeys` and `getAllKeysIn` which uses * `keysFunc` and `symbolsFunc` to get the enumerable property names and * symbols of `object`. * * @private * @param {Object} object The object to query. * @param {Function} keysFunc The function to get the keys of `object`. * @param {Function} symbolsFunc The function to get the symbols of `object`. * @returns {Array} Returns the array of property names and symbols. */ function baseGetAllKeys(object, keysFunc, symbolsFunc) { var result = keysFunc(object); return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); } module.exports = baseGetAllKeys; },{"./_arrayPush":371,"./isArray":527}],387:[function(require,module,exports){ var Symbol = require('./_Symbol'), getRawTag = require('./_getRawTag'), objectToString = require('./_objectToString'); /** `Object#toString` result references. */ var nullTag = '[object Null]', undefinedTag = '[object Undefined]'; /** Built-in value references. */ var symToStringTag = Symbol ? Symbol.toStringTag : undefined; /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return (symToStringTag && symToStringTag in Object(value)) ? getRawTag(value) : objectToString(value); } module.exports = baseGetTag; },{"./_Symbol":360,"./_getRawTag":449,"./_objectToString":488}],388:[function(require,module,exports){ /** * The base implementation of `_.hasIn` without support for deep paths. * * @private * @param {Object} [object] The object to query. * @param {Array|string} key The key to check. * @returns {boolean} Returns `true` if `key` exists, else `false`. */ function baseHasIn(object, key) { return object != null && key in Object(object); } module.exports = baseHasIn; },{}],389:[function(require,module,exports){ var baseFindIndex = require('./_baseFindIndex'), baseIsNaN = require('./_baseIsNaN'), strictIndexOf = require('./_strictIndexOf'); /** * The base implementation of `_.indexOf` without `fromIndex` bounds checks. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. */ function baseIndexOf(array, value, fromIndex) { return value === value ? strictIndexOf(array, value, fromIndex) : baseFindIndex(array, baseIsNaN, fromIndex); } module.exports = baseIndexOf; },{"./_baseFindIndex":381,"./_baseIsNaN":394,"./_strictIndexOf":507}],390:[function(require,module,exports){ var baseGetTag = require('./_baseGetTag'), isObjectLike = require('./isObjectLike'); /** `Object#toString` result references. */ var argsTag = '[object Arguments]'; /** * The base implementation of `_.isArguments`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, */ function baseIsArguments(value) { return isObjectLike(value) && baseGetTag(value) == argsTag; } module.exports = baseIsArguments; },{"./_baseGetTag":387,"./isObjectLike":535}],391:[function(require,module,exports){ var baseIsEqualDeep = require('./_baseIsEqualDeep'), isObjectLike = require('./isObjectLike'); /** * The base implementation of `_.isEqual` which supports partial comparisons * and tracks traversed objects. * * @private * @param {*} value The value to compare. * @param {*} other The other value to compare. * @param {boolean} bitmask The bitmask flags. * 1 - Unordered comparison * 2 - Partial comparison * @param {Function} [customizer] The function to customize comparisons. * @param {Object} [stack] Tracks traversed `value` and `other` objects. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. */ function baseIsEqual(value, other, bitmask, customizer, stack) { if (value === other) { return true; } if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { return value !== value && other !== other; } return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack); } module.exports = baseIsEqual; },{"./_baseIsEqualDeep":392,"./isObjectLike":535}],392:[function(require,module,exports){ var Stack = require('./_Stack'), equalArrays = require('./_equalArrays'), equalByTag = require('./_equalByTag'), equalObjects = require('./_equalObjects'), getTag = require('./_getTag'), isArray = require('./isArray'), isBuffer = require('./isBuffer'), isTypedArray = require('./isTypedArray'); /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1; /** `Object#toString` result references. */ var argsTag = '[object Arguments]', arrayTag = '[object Array]', objectTag = '[object Object]'; /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * A specialized version of `baseIsEqual` for arrays and objects which performs * deep comparisons and tracks traversed objects enabling objects with circular * references to be compared. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} [stack] Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { var objIsArr = isArray(object), othIsArr = isArray(other), objTag = objIsArr ? arrayTag : getTag(object), othTag = othIsArr ? arrayTag : getTag(other); objTag = objTag == argsTag ? objectTag : objTag; othTag = othTag == argsTag ? objectTag : othTag; var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag; if (isSameTag && isBuffer(object)) { if (!isBuffer(other)) { return false; } objIsArr = true; objIsObj = false; } if (isSameTag && !objIsObj) { stack || (stack = new Stack); return (objIsArr || isTypedArray(object)) ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); } if (!(bitmask & COMPARE_PARTIAL_FLAG)) { var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); if (objIsWrapped || othIsWrapped) { var objUnwrapped = objIsWrapped ? object.value() : object, othUnwrapped = othIsWrapped ? other.value() : other; stack || (stack = new Stack); return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack); } } if (!isSameTag) { return false; } stack || (stack = new Stack); return equalObjects(object, other, bitmask, customizer, equalFunc, stack); } module.exports = baseIsEqualDeep; },{"./_Stack":359,"./_equalArrays":437,"./_equalByTag":438,"./_equalObjects":439,"./_getTag":451,"./isArray":527,"./isBuffer":530,"./isTypedArray":537}],393:[function(require,module,exports){ var Stack = require('./_Stack'), baseIsEqual = require('./_baseIsEqual'); /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; /** * The base implementation of `_.isMatch` without support for iteratee shorthands. * * @private * @param {Object} object The object to inspect. * @param {Object} source The object of property values to match. * @param {Array} matchData The property names, values, and compare flags to match. * @param {Function} [customizer] The function to customize comparisons. * @returns {boolean} Returns `true` if `object` is a match, else `false`. */ function baseIsMatch(object, source, matchData, customizer) { var index = matchData.length, length = index, noCustomizer = !customizer; if (object == null) { return !length; } object = Object(object); while (index--) { var data = matchData[index]; if ((noCustomizer && data[2]) ? data[1] !== object[data[0]] : !(data[0] in object) ) { return false; } } while (++index < length) { data = matchData[index]; var key = data[0], objValue = object[key], srcValue = data[1]; if (noCustomizer && data[2]) { if (objValue === undefined && !(key in object)) { return false; } } else { var stack = new Stack; if (customizer) { var result = customizer(objValue, srcValue, key, object, source, stack); } if (!(result === undefined ? baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, stack) : result )) { return false; } } } return true; } module.exports = baseIsMatch; },{"./_Stack":359,"./_baseIsEqual":391}],394:[function(require,module,exports){ /** * The base implementation of `_.isNaN` without support for number objects. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. */ function baseIsNaN(value) { return value !== value; } module.exports = baseIsNaN; },{}],395:[function(require,module,exports){ var isFunction = require('./isFunction'), isMasked = require('./_isMasked'), isObject = require('./isObject'), toSource = require('./_toSource'); /** * Used to match `RegExp` * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns). */ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; /** Used to detect host constructors (Safari). */ var reIsHostCtor = /^\[object .+?Constructor\]$/; /** Used for built-in method references. */ var funcProto = Function.prototype, objectProto = Object.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString = funcProto.toString; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** Used to detect if a method is native. */ var reIsNative = RegExp('^' + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); /** * The base implementation of `_.isNative` without bad shim checks. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a native function, * else `false`. */ function baseIsNative(value) { if (!isObject(value) || isMasked(value)) { return false; } var pattern = isFunction(value) ? reIsNative : reIsHostCtor; return pattern.test(toSource(value)); } module.exports = baseIsNative; },{"./_isMasked":467,"./_toSource":510,"./isFunction":532,"./isObject":534}],396:[function(require,module,exports){ var baseGetTag = require('./_baseGetTag'), isLength = require('./isLength'), isObjectLike = require('./isObjectLike'); /** `Object#toString` result references. */ var argsTag = '[object Arguments]', arrayTag = '[object Array]', boolTag = '[object Boolean]', dateTag = '[object Date]', errorTag = '[object Error]', funcTag = '[object Function]', mapTag = '[object Map]', numberTag = '[object Number]', objectTag = '[object Object]', regexpTag = '[object RegExp]', setTag = '[object Set]', stringTag = '[object String]', weakMapTag = '[object WeakMap]'; var arrayBufferTag = '[object ArrayBuffer]', dataViewTag = '[object DataView]', float32Tag = '[object Float32Array]', float64Tag = '[object Float64Array]', int8Tag = '[object Int8Array]', int16Tag = '[object Int16Array]', int32Tag = '[object Int32Array]', uint8Tag = '[object Uint8Array]', uint8ClampedTag = '[object Uint8ClampedArray]', uint16Tag = '[object Uint16Array]', uint32Tag = '[object Uint32Array]'; /** Used to identify `toStringTag` values of typed arrays. */ var typedArrayTags = {}; typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; /** * The base implementation of `_.isTypedArray` without Node.js optimizations. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. */ function baseIsTypedArray(value) { return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; } module.exports = baseIsTypedArray; },{"./_baseGetTag":387,"./isLength":533,"./isObjectLike":535}],397:[function(require,module,exports){ var baseMatches = require('./_baseMatches'), baseMatchesProperty = require('./_baseMatchesProperty'), identity = require('./identity'), isArray = require('./isArray'), property = require('./property'); /** * The base implementation of `_.iteratee`. * * @private * @param {*} [value=_.identity] The value to convert to an iteratee. * @returns {Function} Returns the iteratee. */ function baseIteratee(value) { // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. if (typeof value == 'function') { return value; } if (value == null) { return identity; } if (typeof value == 'object') { return isArray(value) ? baseMatchesProperty(value[0], value[1]) : baseMatches(value); } return property(value); } module.exports = baseIteratee; },{"./_baseMatches":401,"./_baseMatchesProperty":402,"./identity":525,"./isArray":527,"./property":544}],398:[function(require,module,exports){ var isPrototype = require('./_isPrototype'), nativeKeys = require('./_nativeKeys'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. */ function baseKeys(object) { if (!isPrototype(object)) { return nativeKeys(object); } var result = []; for (var key in Object(object)) { if (hasOwnProperty.call(object, key) && key != 'constructor') { result.push(key); } } return result; } module.exports = baseKeys; },{"./_isPrototype":468,"./_nativeKeys":486}],399:[function(require,module,exports){ /** * The function whose prototype chain sequence wrappers inherit from. * * @private */ function baseLodash() { // No operation performed. } module.exports = baseLodash; },{}],400:[function(require,module,exports){ var baseEach = require('./_baseEach'), isArrayLike = require('./isArrayLike'); /** * The base implementation of `_.map` without support for iteratee shorthands. * * @private * @param {Array|Object} collection The collection to iterate over. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the new mapped array. */ function baseMap(collection, iteratee) { var index = -1, result = isArrayLike(collection) ? Array(collection.length) : []; baseEach(collection, function(value, key, collection) { result[++index] = iteratee(value, key, collection); }); return result; } module.exports = baseMap; },{"./_baseEach":379,"./isArrayLike":528}],401:[function(require,module,exports){ var baseIsMatch = require('./_baseIsMatch'), getMatchData = require('./_getMatchData'), matchesStrictComparable = require('./_matchesStrictComparable'); /** * The base implementation of `_.matches` which doesn't clone `source`. * * @private * @param {Object} source The object of property values to match. * @returns {Function} Returns the new spec function. */ function baseMatches(source) { var matchData = getMatchData(source); if (matchData.length == 1 && matchData[0][2]) { return matchesStrictComparable(matchData[0][0], matchData[0][1]); } return function(object) { return object === source || baseIsMatch(object, source, matchData); }; } module.exports = baseMatches; },{"./_baseIsMatch":393,"./_getMatchData":446,"./_matchesStrictComparable":481}],402:[function(require,module,exports){ var baseIsEqual = require('./_baseIsEqual'), get = require('./get'), hasIn = require('./hasIn'), isKey = require('./_isKey'), isStrictComparable = require('./_isStrictComparable'), matchesStrictComparable = require('./_matchesStrictComparable'), toKey = require('./_toKey'); /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; /** * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. * * @private * @param {string} path The path of the property to get. * @param {*} srcValue The value to match. * @returns {Function} Returns the new spec function. */ function baseMatchesProperty(path, srcValue) { if (isKey(path) && isStrictComparable(srcValue)) { return matchesStrictComparable(toKey(path), srcValue); } return function(object) { var objValue = get(object, path); return (objValue === undefined && objValue === srcValue) ? hasIn(object, path) : baseIsEqual(srcValue, objValue, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG); }; } module.exports = baseMatchesProperty; },{"./_baseIsEqual":391,"./_isKey":464,"./_isStrictComparable":469,"./_matchesStrictComparable":481,"./_toKey":509,"./get":523,"./hasIn":524}],403:[function(require,module,exports){ /** * The base implementation of `_.property` without support for deep paths. * * @private * @param {string} key The key of the property to get. * @returns {Function} Returns the new accessor function. */ function baseProperty(key) { return function(object) { return object == null ? undefined : object[key]; }; } module.exports = baseProperty; },{}],404:[function(require,module,exports){ var baseGet = require('./_baseGet'); /** * A specialized version of `baseProperty` which supports deep paths. * * @private * @param {Array|string} path The path of the property to get. * @returns {Function} Returns the new accessor function. */ function basePropertyDeep(path) { return function(object) { return baseGet(object, path); }; } module.exports = basePropertyDeep; },{"./_baseGet":385}],405:[function(require,module,exports){ var identity = require('./identity'), overRest = require('./_overRest'), setToString = require('./_setToString'); /** * The base implementation of `_.rest` which doesn't validate or coerce arguments. * * @private * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @returns {Function} Returns the new function. */ function baseRest(func, start) { return setToString(overRest(func, start, identity), func + ''); } module.exports = baseRest; },{"./_overRest":490,"./_setToString":499,"./identity":525}],406:[function(require,module,exports){ var identity = require('./identity'), metaMap = require('./_metaMap'); /** * The base implementation of `setData` without support for hot loop shorting. * * @private * @param {Function} func The function to associate metadata with. * @param {*} data The metadata. * @returns {Function} Returns `func`. */ var baseSetData = !metaMap ? identity : function(func, data) { metaMap.set(func, data); return func; }; module.exports = baseSetData; },{"./_metaMap":484,"./identity":525}],407:[function(require,module,exports){ var constant = require('./constant'), defineProperty = require('./_defineProperty'), identity = require('./identity'); /** * The base implementation of `setToString` without support for hot loop shorting. * * @private * @param {Function} func The function to modify. * @param {Function} string The `toString` result. * @returns {Function} Returns `func`. */ var baseSetToString = !defineProperty ? identity : function(func, string) { return defineProperty(func, 'toString', { 'configurable': true, 'enumerable': false, 'value': constant(string), 'writable': true }); }; module.exports = baseSetToString; },{"./_defineProperty":436,"./constant":515,"./identity":525}],408:[function(require,module,exports){ /** * The base implementation of `_.times` without support for iteratee shorthands * or max array length checks. * * @private * @param {number} n The number of times to invoke `iteratee`. * @param {Function} iteratee The function invoked per iteration. * @returns {Array} Returns the array of results. */ function baseTimes(n, iteratee) { var index = -1, result = Array(n); while (++index < n) { result[index] = iteratee(index); } return result; } module.exports = baseTimes; },{}],409:[function(require,module,exports){ var Symbol = require('./_Symbol'), arrayMap = require('./_arrayMap'), isArray = require('./isArray'), isSymbol = require('./isSymbol'); /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0; /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, symbolToString = symbolProto ? symbolProto.toString : undefined; /** * The base implementation of `_.toString` which doesn't convert nullish * values to empty strings. * * @private * @param {*} value The value to process. * @returns {string} Returns the string. */ function baseToString(value) { // Exit early for strings to avoid a performance hit in some environments. if (typeof value == 'string') { return value; } if (isArray(value)) { // Recursively convert values (susceptible to call stack limits). return arrayMap(value, baseToString) + ''; } if (isSymbol(value)) { return symbolToString ? symbolToString.call(value) : ''; } var result = (value + ''); return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } module.exports = baseToString; },{"./_Symbol":360,"./_arrayMap":370,"./isArray":527,"./isSymbol":536}],410:[function(require,module,exports){ /** * The base implementation of `_.unary` without support for storing metadata. * * @private * @param {Function} func The function to cap arguments for. * @returns {Function} Returns the new capped function. */ function baseUnary(func) { return function(value) { return func(value); }; } module.exports = baseUnary; },{}],411:[function(require,module,exports){ var SetCache = require('./_SetCache'), arrayIncludes = require('./_arrayIncludes'), arrayIncludesWith = require('./_arrayIncludesWith'), cacheHas = require('./_cacheHas'), createSet = require('./_createSet'), setToArray = require('./_setToArray'); /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** * The base implementation of `_.uniqBy` without support for iteratee shorthands. * * @private * @param {Array} array The array to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new duplicate free array. */ function baseUniq(array, iteratee, comparator) { var index = -1, includes = arrayIncludes, length = array.length, isCommon = true, result = [], seen = result; if (comparator) { isCommon = false; includes = arrayIncludesWith; } else if (length >= LARGE_ARRAY_SIZE) { var set = iteratee ? null : createSet(array); if (set) { return setToArray(set); } isCommon = false; includes = cacheHas; seen = new SetCache; } else { seen = iteratee ? [] : result; } outer: while (++index < length) { var value = array[index], computed = iteratee ? iteratee(value) : value; value = (comparator || value !== 0) ? value : 0; if (isCommon && computed === computed) { var seenIndex = seen.length; while (seenIndex--) { if (seen[seenIndex] === computed) { continue outer; } } if (iteratee) { seen.push(computed); } result.push(value); } else if (!includes(seen, computed, comparator)) { if (seen !== result) { seen.push(computed); } result.push(value); } } return result; } module.exports = baseUniq; },{"./_SetCache":358,"./_arrayIncludes":367,"./_arrayIncludesWith":368,"./_cacheHas":414,"./_createSet":434,"./_setToArray":498}],412:[function(require,module,exports){ var arrayMap = require('./_arrayMap'); /** * The base implementation of `_.values` and `_.valuesIn` which creates an * array of `object` property values corresponding to the property names * of `props`. * * @private * @param {Object} object The object to query. * @param {Array} props The property names to get values for. * @returns {Object} Returns the array of property values. */ function baseValues(object, props) { return arrayMap(props, function(key) { return object[key]; }); } module.exports = baseValues; },{"./_arrayMap":370}],413:[function(require,module,exports){ var baseDifference = require('./_baseDifference'), baseFlatten = require('./_baseFlatten'), baseUniq = require('./_baseUniq'); /** * The base implementation of methods like `_.xor`, without support for * iteratee shorthands, that accepts an array of arrays to inspect. * * @private * @param {Array} arrays The arrays to inspect. * @param {Function} [iteratee] The iteratee invoked per element. * @param {Function} [comparator] The comparator invoked per element. * @returns {Array} Returns the new array of values. */ function baseXor(arrays, iteratee, comparator) { var length = arrays.length; if (length < 2) { return length ? baseUniq(arrays[0]) : []; } var index = -1, result = Array(length); while (++index < length) { var array = arrays[index], othIndex = -1; while (++othIndex < length) { if (othIndex != index) { result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); } } } return baseUniq(baseFlatten(result, 1), iteratee, comparator); } module.exports = baseXor; },{"./_baseDifference":378,"./_baseFlatten":382,"./_baseUniq":411}],414:[function(require,module,exports){ /** * Checks if a `cache` value for `key` exists. * * @private * @param {Object} cache The cache to query. * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function cacheHas(cache, key) { return cache.has(key); } module.exports = cacheHas; },{}],415:[function(require,module,exports){ var identity = require('./identity'); /** * Casts `value` to `identity` if it's not a function. * * @private * @param {*} value The value to inspect. * @returns {Function} Returns cast function. */ function castFunction(value) { return typeof value == 'function' ? value : identity; } module.exports = castFunction; },{"./identity":525}],416:[function(require,module,exports){ var isArray = require('./isArray'), isKey = require('./_isKey'), stringToPath = require('./_stringToPath'), toString = require('./toString'); /** * Casts `value` to a path array if it's not one. * * @private * @param {*} value The value to inspect. * @param {Object} [object] The object to query keys on. * @returns {Array} Returns the cast property path array. */ function castPath(value, object) { if (isArray(value)) { return value; } return isKey(value, object) ? [value] : stringToPath(toString(value)); } module.exports = castPath; },{"./_isKey":464,"./_stringToPath":508,"./isArray":527,"./toString":550}],417:[function(require,module,exports){ /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max; /** * Creates an array that is the composition of partially applied arguments, * placeholders, and provided arguments into a single array of arguments. * * @private * @param {Array} args The provided arguments. * @param {Array} partials The arguments to prepend to those provided. * @param {Array} holders The `partials` placeholder indexes. * @params {boolean} [isCurried] Specify composing for a curried function. * @returns {Array} Returns the new array of composed arguments. */ function composeArgs(args, partials, holders, isCurried) { var argsIndex = -1, argsLength = args.length, holdersLength = holders.length, leftIndex = -1, leftLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result = Array(leftLength + rangeLength), isUncurried = !isCurried; while (++leftIndex < leftLength) { result[leftIndex] = partials[leftIndex]; } while (++argsIndex < holdersLength) { if (isUncurried || argsIndex < argsLength) { result[holders[argsIndex]] = args[argsIndex]; } } while (rangeLength--) { result[leftIndex++] = args[argsIndex++]; } return result; } module.exports = composeArgs; },{}],418:[function(require,module,exports){ /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max; /** * This function is like `composeArgs` except that the arguments composition * is tailored for `_.partialRight`. * * @private * @param {Array} args The provided arguments. * @param {Array} partials The arguments to append to those provided. * @param {Array} holders The `partials` placeholder indexes. * @params {boolean} [isCurried] Specify composing for a curried function. * @returns {Array} Returns the new array of composed arguments. */ function composeArgsRight(args, partials, holders, isCurried) { var argsIndex = -1, argsLength = args.length, holdersIndex = -1, holdersLength = holders.length, rightIndex = -1, rightLength = partials.length, rangeLength = nativeMax(argsLength - holdersLength, 0), result = Array(rangeLength + rightLength), isUncurried = !isCurried; while (++argsIndex < rangeLength) { result[argsIndex] = args[argsIndex]; } var offset = argsIndex; while (++rightIndex < rightLength) { result[offset + rightIndex] = partials[rightIndex]; } while (++holdersIndex < holdersLength) { if (isUncurried || argsIndex < argsLength) { result[offset + holders[holdersIndex]] = args[argsIndex++]; } } return result; } module.exports = composeArgsRight; },{}],419:[function(require,module,exports){ /** * Copies the values of `source` to `array`. * * @private * @param {Array} source The array to copy values from. * @param {Array} [array=[]] The array to copy values to. * @returns {Array} Returns `array`. */ function copyArray(source, array) { var index = -1, length = source.length; array || (array = Array(length)); while (++index < length) { array[index] = source[index]; } return array; } module.exports = copyArray; },{}],420:[function(require,module,exports){ var assignValue = require('./_assignValue'), baseAssignValue = require('./_baseAssignValue'); /** * Copies properties of `source` to `object`. * * @private * @param {Object} source The object to copy properties from. * @param {Array} props The property identifiers to copy. * @param {Object} [object={}] The object to copy properties to. * @param {Function} [customizer] The function to customize copied values. * @returns {Object} Returns `object`. */ function copyObject(source, props, object, customizer) { var isNew = !object; object || (object = {}); var index = -1, length = props.length; while (++index < length) { var key = props[index]; var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined; if (newValue === undefined) { newValue = source[key]; } if (isNew) { baseAssignValue(object, key, newValue); } else { assignValue(object, key, newValue); } } return object; } module.exports = copyObject; },{"./_assignValue":373,"./_baseAssignValue":376}],421:[function(require,module,exports){ var root = require('./_root'); /** Used to detect overreaching core-js shims. */ var coreJsData = root['__core-js_shared__']; module.exports = coreJsData; },{"./_root":494}],422:[function(require,module,exports){ /** * Gets the number of `placeholder` occurrences in `array`. * * @private * @param {Array} array The array to inspect. * @param {*} placeholder The placeholder to search for. * @returns {number} Returns the placeholder count. */ function countHolders(array, placeholder) { var length = array.length, result = 0; while (length--) { if (array[length] === placeholder) { ++result; } } return result; } module.exports = countHolders; },{}],423:[function(require,module,exports){ var arrayAggregator = require('./_arrayAggregator'), baseAggregator = require('./_baseAggregator'), baseIteratee = require('./_baseIteratee'), isArray = require('./isArray'); /** * Creates a function like `_.groupBy`. * * @private * @param {Function} setter The function to set accumulator values. * @param {Function} [initializer] The accumulator object initializer. * @returns {Function} Returns the new aggregator function. */ function createAggregator(setter, initializer) { return function(collection, iteratee) { var func = isArray(collection) ? arrayAggregator : baseAggregator, accumulator = initializer ? initializer() : {}; return func(collection, setter, baseIteratee(iteratee, 2), accumulator); }; } module.exports = createAggregator; },{"./_arrayAggregator":364,"./_baseAggregator":375,"./_baseIteratee":397,"./isArray":527}],424:[function(require,module,exports){ var baseRest = require('./_baseRest'), isIterateeCall = require('./_isIterateeCall'); /** * Creates a function like `_.assign`. * * @private * @param {Function} assigner The function to assign values. * @returns {Function} Returns the new assigner function. */ function createAssigner(assigner) { return baseRest(function(object, sources) { var index = -1, length = sources.length, customizer = length > 1 ? sources[length - 1] : undefined, guard = length > 2 ? sources[2] : undefined; customizer = (assigner.length > 3 && typeof customizer == 'function') ? (length--, customizer) : undefined; if (guard && isIterateeCall(sources[0], sources[1], guard)) { customizer = length < 3 ? undefined : customizer; length = 1; } object = Object(object); while (++index < length) { var source = sources[index]; if (source) { assigner(object, source, index, customizer); } } return object; }); } module.exports = createAssigner; },{"./_baseRest":405,"./_isIterateeCall":463}],425:[function(require,module,exports){ var isArrayLike = require('./isArrayLike'); /** * Creates a `baseEach` or `baseEachRight` function. * * @private * @param {Function} eachFunc The function to iterate over a collection. * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new base function. */ function createBaseEach(eachFunc, fromRight) { return function(collection, iteratee) { if (collection == null) { return collection; } if (!isArrayLike(collection)) { return eachFunc(collection, iteratee); } var length = collection.length, index = fromRight ? length : -1, iterable = Object(collection); while ((fromRight ? index-- : ++index < length)) { if (iteratee(iterable[index], index, iterable) === false) { break; } } return collection; }; } module.exports = createBaseEach; },{"./isArrayLike":528}],426:[function(require,module,exports){ /** * Creates a base function for methods like `_.forIn` and `_.forOwn`. * * @private * @param {boolean} [fromRight] Specify iterating from right to left. * @returns {Function} Returns the new base function. */ function createBaseFor(fromRight) { return function(object, iteratee, keysFunc) { var index = -1, iterable = Object(object), props = keysFunc(object), length = props.length; while (length--) { var key = props[fromRight ? length : ++index]; if (iteratee(iterable[key], key, iterable) === false) { break; } } return object; }; } module.exports = createBaseFor; },{}],427:[function(require,module,exports){ var createCtor = require('./_createCtor'), root = require('./_root'); /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1; /** * Creates a function that wraps `func` to invoke it with the optional `this` * binding of `thisArg`. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {*} [thisArg] The `this` binding of `func`. * @returns {Function} Returns the new wrapped function. */ function createBind(func, bitmask, thisArg) { var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func); function wrapper() { var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; return fn.apply(isBind ? thisArg : this, arguments); } return wrapper; } module.exports = createBind; },{"./_createCtor":428,"./_root":494}],428:[function(require,module,exports){ var baseCreate = require('./_baseCreate'), isObject = require('./isObject'); /** * Creates a function that produces an instance of `Ctor` regardless of * whether it was invoked as part of a `new` expression or by `call` or `apply`. * * @private * @param {Function} Ctor The constructor to wrap. * @returns {Function} Returns the new wrapped function. */ function createCtor(Ctor) { return function() { // Use a `switch` statement to work with class constructors. See // http://ecma-international.org/ecma-262/7.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist // for more details. var args = arguments; switch (args.length) { case 0: return new Ctor; case 1: return new Ctor(args[0]); case 2: return new Ctor(args[0], args[1]); case 3: return new Ctor(args[0], args[1], args[2]); case 4: return new Ctor(args[0], args[1], args[2], args[3]); case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); } var thisBinding = baseCreate(Ctor.prototype), result = Ctor.apply(thisBinding, args); // Mimic the constructor's `return` behavior. // See https://es5.github.io/#x13.2.2 for more details. return isObject(result) ? result : thisBinding; }; } module.exports = createCtor; },{"./_baseCreate":377,"./isObject":534}],429:[function(require,module,exports){ var apply = require('./_apply'), createCtor = require('./_createCtor'), createHybrid = require('./_createHybrid'), createRecurry = require('./_createRecurry'), getHolder = require('./_getHolder'), replaceHolders = require('./_replaceHolders'), root = require('./_root'); /** * Creates a function that wraps `func` to enable currying. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {number} arity The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createCurry(func, bitmask, arity) { var Ctor = createCtor(func); function wrapper() { var length = arguments.length, args = Array(length), index = length, placeholder = getHolder(wrapper); while (index--) { args[index] = arguments[index]; } var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) ? [] : replaceHolders(args, placeholder); length -= holders.length; if (length < arity) { return createRecurry( func, bitmask, createHybrid, wrapper.placeholder, undefined, args, holders, undefined, undefined, arity - length); } var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; return apply(fn, this, args); } return wrapper; } module.exports = createCurry; },{"./_apply":363,"./_createCtor":428,"./_createHybrid":431,"./_createRecurry":433,"./_getHolder":444,"./_replaceHolders":493,"./_root":494}],430:[function(require,module,exports){ var baseIteratee = require('./_baseIteratee'), isArrayLike = require('./isArrayLike'), keys = require('./keys'); /** * Creates a `_.find` or `_.findLast` function. * * @private * @param {Function} findIndexFunc The function to find the collection index. * @returns {Function} Returns the new find function. */ function createFind(findIndexFunc) { return function(collection, predicate, fromIndex) { var iterable = Object(collection); if (!isArrayLike(collection)) { var iteratee = baseIteratee(predicate, 3); collection = keys(collection); predicate = function(key) { return iteratee(iterable[key], key, iterable); }; } var index = findIndexFunc(collection, predicate, fromIndex); return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; }; } module.exports = createFind; },{"./_baseIteratee":397,"./isArrayLike":528,"./keys":539}],431:[function(require,module,exports){ var composeArgs = require('./_composeArgs'), composeArgsRight = require('./_composeArgsRight'), countHolders = require('./_countHolders'), createCtor = require('./_createCtor'), createRecurry = require('./_createRecurry'), getHolder = require('./_getHolder'), reorder = require('./_reorder'), replaceHolders = require('./_replaceHolders'), root = require('./_root'); /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_FLAG = 8, WRAP_CURRY_RIGHT_FLAG = 16, WRAP_ARY_FLAG = 128, WRAP_FLIP_FLAG = 512; /** * Creates a function that wraps `func` to invoke it with optional `this` * binding of `thisArg`, partial application, and currying. * * @private * @param {Function|string} func The function or method name to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to prepend to those provided to * the new function. * @param {Array} [holders] The `partials` placeholder indexes. * @param {Array} [partialsRight] The arguments to append to those provided * to the new function. * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. * @param {Array} [argPos] The argument positions of the new function. * @param {number} [ary] The arity cap of `func`. * @param {number} [arity] The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { var isAry = bitmask & WRAP_ARY_FLAG, isBind = bitmask & WRAP_BIND_FLAG, isBindKey = bitmask & WRAP_BIND_KEY_FLAG, isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), isFlip = bitmask & WRAP_FLIP_FLAG, Ctor = isBindKey ? undefined : createCtor(func); function wrapper() { var length = arguments.length, args = Array(length), index = length; while (index--) { args[index] = arguments[index]; } if (isCurried) { var placeholder = getHolder(wrapper), holdersCount = countHolders(args, placeholder); } if (partials) { args = composeArgs(args, partials, holders, isCurried); } if (partialsRight) { args = composeArgsRight(args, partialsRight, holdersRight, isCurried); } length -= holdersCount; if (isCurried && length < arity) { var newHolders = replaceHolders(args, placeholder); return createRecurry( func, bitmask, createHybrid, wrapper.placeholder, thisArg, args, newHolders, argPos, ary, arity - length ); } var thisBinding = isBind ? thisArg : this, fn = isBindKey ? thisBinding[func] : func; length = args.length; if (argPos) { args = reorder(args, argPos); } else if (isFlip && length > 1) { args.reverse(); } if (isAry && ary < length) { args.length = ary; } if (this && this !== root && this instanceof wrapper) { fn = Ctor || createCtor(fn); } return fn.apply(thisBinding, args); } return wrapper; } module.exports = createHybrid; },{"./_composeArgs":417,"./_composeArgsRight":418,"./_countHolders":422,"./_createCtor":428,"./_createRecurry":433,"./_getHolder":444,"./_reorder":492,"./_replaceHolders":493,"./_root":494}],432:[function(require,module,exports){ var apply = require('./_apply'), createCtor = require('./_createCtor'), root = require('./_root'); /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1; /** * Creates a function that wraps `func` to invoke it with the `this` binding * of `thisArg` and `partials` prepended to the arguments it receives. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {*} thisArg The `this` binding of `func`. * @param {Array} partials The arguments to prepend to those provided to * the new function. * @returns {Function} Returns the new wrapped function. */ function createPartial(func, bitmask, thisArg, partials) { var isBind = bitmask & WRAP_BIND_FLAG, Ctor = createCtor(func); function wrapper() { var argsIndex = -1, argsLength = arguments.length, leftIndex = -1, leftLength = partials.length, args = Array(leftLength + argsLength), fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; while (++leftIndex < leftLength) { args[leftIndex] = partials[leftIndex]; } while (argsLength--) { args[leftIndex++] = arguments[++argsIndex]; } return apply(fn, isBind ? thisArg : this, args); } return wrapper; } module.exports = createPartial; },{"./_apply":363,"./_createCtor":428,"./_root":494}],433:[function(require,module,exports){ var isLaziable = require('./_isLaziable'), setData = require('./_setData'), setWrapToString = require('./_setWrapToString'); /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_BOUND_FLAG = 4, WRAP_CURRY_FLAG = 8, WRAP_PARTIAL_FLAG = 32, WRAP_PARTIAL_RIGHT_FLAG = 64; /** * Creates a function that wraps `func` to continue currying. * * @private * @param {Function} func The function to wrap. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @param {Function} wrapFunc The function to create the `func` wrapper. * @param {*} placeholder The placeholder value. * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to prepend to those provided to * the new function. * @param {Array} [holders] The `partials` placeholder indexes. * @param {Array} [argPos] The argument positions of the new function. * @param {number} [ary] The arity cap of `func`. * @param {number} [arity] The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { var isCurry = bitmask & WRAP_CURRY_FLAG, newHolders = isCurry ? holders : undefined, newHoldersRight = isCurry ? undefined : holders, newPartials = isCurry ? partials : undefined, newPartialsRight = isCurry ? undefined : partials; bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { bitmask &= ~(WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG); } var newData = [ func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, newHoldersRight, argPos, ary, arity ]; var result = wrapFunc.apply(undefined, newData); if (isLaziable(func)) { setData(result, newData); } result.placeholder = placeholder; return setWrapToString(result, func, bitmask); } module.exports = createRecurry; },{"./_isLaziable":466,"./_setData":497,"./_setWrapToString":500}],434:[function(require,module,exports){ var Set = require('./_Set'), noop = require('./noop'), setToArray = require('./_setToArray'); /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0; /** * Creates a set object of `values`. * * @private * @param {Array} values The values to add to the set. * @returns {Object} Returns the new set. */ var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { return new Set(values); }; module.exports = createSet; },{"./_Set":357,"./_setToArray":498,"./noop":542}],435:[function(require,module,exports){ var baseSetData = require('./_baseSetData'), createBind = require('./_createBind'), createCurry = require('./_createCurry'), createHybrid = require('./_createHybrid'), createPartial = require('./_createPartial'), getData = require('./_getData'), mergeData = require('./_mergeData'), setData = require('./_setData'), setWrapToString = require('./_setWrapToString'), toInteger = require('./toInteger'); /** Error message constants. */ var FUNC_ERROR_TEXT = 'Expected a function'; /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_FLAG = 8, WRAP_CURRY_RIGHT_FLAG = 16, WRAP_PARTIAL_FLAG = 32, WRAP_PARTIAL_RIGHT_FLAG = 64; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max; /** * Creates a function that either curries or invokes `func` with optional * `this` binding and partially applied arguments. * * @private * @param {Function|string} func The function or method name to wrap. * @param {number} bitmask The bitmask flags. * 1 - `_.bind` * 2 - `_.bindKey` * 4 - `_.curry` or `_.curryRight` of a bound function * 8 - `_.curry` * 16 - `_.curryRight` * 32 - `_.partial` * 64 - `_.partialRight` * 128 - `_.rearg` * 256 - `_.ary` * 512 - `_.flip` * @param {*} [thisArg] The `this` binding of `func`. * @param {Array} [partials] The arguments to be partially applied. * @param {Array} [holders] The `partials` placeholder indexes. * @param {Array} [argPos] The argument positions of the new function. * @param {number} [ary] The arity cap of `func`. * @param {number} [arity] The arity of `func`. * @returns {Function} Returns the new wrapped function. */ function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { var isBindKey = bitmask & WRAP_BIND_KEY_FLAG; if (!isBindKey && typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } var length = partials ? partials.length : 0; if (!length) { bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_PARTIAL_RIGHT_FLAG); partials = holders = undefined; } ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); arity = arity === undefined ? arity : toInteger(arity); length -= holders ? holders.length : 0; if (bitmask & WRAP_PARTIAL_RIGHT_FLAG) { var partialsRight = partials, holdersRight = holders; partials = holders = undefined; } var data = isBindKey ? undefined : getData(func); var newData = [ func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity ]; if (data) { mergeData(newData, data); } func = newData[0]; bitmask = newData[1]; thisArg = newData[2]; partials = newData[3]; holders = newData[4]; arity = newData[9] = newData[9] === undefined ? (isBindKey ? 0 : func.length) : nativeMax(newData[9] - length, 0); if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); } if (!bitmask || bitmask == WRAP_BIND_FLAG) { var result = createBind(func, bitmask, thisArg); } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { result = createCurry(func, bitmask, arity); } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_PARTIAL_FLAG)) && !holders.length) { result = createPartial(func, bitmask, thisArg, partials); } else { result = createHybrid.apply(undefined, newData); } var setter = data ? baseSetData : setData; return setWrapToString(setter(result, newData), func, bitmask); } module.exports = createWrap; },{"./_baseSetData":406,"./_createBind":427,"./_createCurry":429,"./_createHybrid":431,"./_createPartial":432,"./_getData":442,"./_mergeData":483,"./_setData":497,"./_setWrapToString":500,"./toInteger":548}],436:[function(require,module,exports){ var getNative = require('./_getNative'); var defineProperty = (function() { try { var func = getNative(Object, 'defineProperty'); func({}, '', {}); return func; } catch (e) {} }()); module.exports = defineProperty; },{"./_getNative":447}],437:[function(require,module,exports){ var SetCache = require('./_SetCache'), arraySome = require('./_arraySome'), cacheHas = require('./_cacheHas'); /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; /** * A specialized version of `baseIsEqualDeep` for arrays with support for * partial deep comparisons. * * @private * @param {Array} array The array to compare. * @param {Array} other The other array to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `array` and `other` objects. * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. */ function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array.length, othLength = other.length; if (arrLength != othLength && !(isPartial && othLength > arrLength)) { return false; } // Check that cyclic values are equal. var arrStacked = stack.get(array); var othStacked = stack.get(other); if (arrStacked && othStacked) { return arrStacked == other && othStacked == array; } var index = -1, result = true, seen = (bitmask & COMPARE_UNORDERED_FLAG) ? new SetCache : undefined; stack.set(array, other); stack.set(other, array); // Ignore non-index properties. while (++index < arrLength) { var arrValue = array[index], othValue = other[index]; if (customizer) { var compared = isPartial ? customizer(othValue, arrValue, index, other, array, stack) : customizer(arrValue, othValue, index, array, other, stack); } if (compared !== undefined) { if (compared) { continue; } result = false; break; } // Recursively compare arrays (susceptible to call stack limits). if (seen) { if (!arraySome(other, function(othValue, othIndex) { if (!cacheHas(seen, othIndex) && (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { return seen.push(othIndex); } })) { result = false; break; } } else if (!( arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack) )) { result = false; break; } } stack['delete'](array); stack['delete'](other); return result; } module.exports = equalArrays; },{"./_SetCache":358,"./_arraySome":372,"./_cacheHas":414}],438:[function(require,module,exports){ var Symbol = require('./_Symbol'), Uint8Array = require('./_Uint8Array'), eq = require('./eq'), equalArrays = require('./_equalArrays'), mapToArray = require('./_mapToArray'), setToArray = require('./_setToArray'); /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; /** `Object#toString` result references. */ var boolTag = '[object Boolean]', dateTag = '[object Date]', errorTag = '[object Error]', mapTag = '[object Map]', numberTag = '[object Number]', regexpTag = '[object RegExp]', setTag = '[object Set]', stringTag = '[object String]', symbolTag = '[object Symbol]'; var arrayBufferTag = '[object ArrayBuffer]', dataViewTag = '[object DataView]'; /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, symbolValueOf = symbolProto ? symbolProto.valueOf : undefined; /** * A specialized version of `baseIsEqualDeep` for comparing objects of * the same `toStringTag`. * * **Note:** This function only supports comparing values with tags of * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {string} tag The `toStringTag` of the objects to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalByTag(object, other, tag, bitmask, customizer, equalFunc, stack) { switch (tag) { case dataViewTag: if ((object.byteLength != other.byteLength) || (object.byteOffset != other.byteOffset)) { return false; } object = object.buffer; other = other.buffer; case arrayBufferTag: if ((object.byteLength != other.byteLength) || !equalFunc(new Uint8Array(object), new Uint8Array(other))) { return false; } return true; case boolTag: case dateTag: case numberTag: // Coerce booleans to `1` or `0` and dates to milliseconds. // Invalid dates are coerced to `NaN`. return eq(+object, +other); case errorTag: return object.name == other.name && object.message == other.message; case regexpTag: case stringTag: // Coerce regexes to strings and treat strings, primitives and objects, // as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring // for more details. return object == (other + ''); case mapTag: var convert = mapToArray; case setTag: var isPartial = bitmask & COMPARE_PARTIAL_FLAG; convert || (convert = setToArray); if (object.size != other.size && !isPartial) { return false; } // Assume cyclic values are equal. var stacked = stack.get(object); if (stacked) { return stacked == other; } bitmask |= COMPARE_UNORDERED_FLAG; // Recursively compare objects (susceptible to call stack limits). stack.set(object, other); var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, stack); stack['delete'](object); return result; case symbolTag: if (symbolValueOf) { return symbolValueOf.call(object) == symbolValueOf.call(other); } } return false; } module.exports = equalByTag; },{"./_Symbol":360,"./_Uint8Array":361,"./_equalArrays":437,"./_mapToArray":480,"./_setToArray":498,"./eq":517}],439:[function(require,module,exports){ var getAllKeys = require('./_getAllKeys'); /** Used to compose bitmasks for value comparisons. */ var COMPARE_PARTIAL_FLAG = 1; /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * A specialized version of `baseIsEqualDeep` for objects with support for * partial deep comparisons. * * @private * @param {Object} object The object to compare. * @param {Object} other The other object to compare. * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details. * @param {Function} customizer The function to customize comparisons. * @param {Function} equalFunc The function to determine equivalents of values. * @param {Object} stack Tracks traversed `object` and `other` objects. * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { var isPartial = bitmask & COMPARE_PARTIAL_FLAG, objProps = getAllKeys(object), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length; if (objLength != othLength && !isPartial) { return false; } var index = objLength; while (index--) { var key = objProps[index]; if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { return false; } } // Check that cyclic values are equal. var objStacked = stack.get(object); var othStacked = stack.get(other); if (objStacked && othStacked) { return objStacked == other && othStacked == object; } var result = true; stack.set(object, other); stack.set(other, object); var skipCtor = isPartial; while (++index < objLength) { key = objProps[index]; var objValue = object[key], othValue = other[key]; if (customizer) { var compared = isPartial ? customizer(othValue, objValue, key, other, object, stack) : customizer(objValue, othValue, key, object, other, stack); } // Recursively compare objects (susceptible to call stack limits). if (!(compared === undefined ? (objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack)) : compared )) { result = false; break; } skipCtor || (skipCtor = key == 'constructor'); } if (result && !skipCtor) { var objCtor = object.constructor, othCtor = other.constructor; // Non `Object` object instances with different constructors are not equal. if (objCtor != othCtor && ('constructor' in object && 'constructor' in other) && !(typeof objCtor == 'function' && objCtor instanceof objCtor && typeof othCtor == 'function' && othCtor instanceof othCtor)) { result = false; } } stack['delete'](object); stack['delete'](other); return result; } module.exports = equalObjects; },{"./_getAllKeys":441}],440:[function(require,module,exports){ (function (global){(function (){ /** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; module.exports = freeGlobal; }).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],441:[function(require,module,exports){ var baseGetAllKeys = require('./_baseGetAllKeys'), getSymbols = require('./_getSymbols'), keys = require('./keys'); /** * Creates an array of own enumerable property names and symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of property names and symbols. */ function getAllKeys(object) { return baseGetAllKeys(object, keys, getSymbols); } module.exports = getAllKeys; },{"./_baseGetAllKeys":386,"./_getSymbols":450,"./keys":539}],442:[function(require,module,exports){ var metaMap = require('./_metaMap'), noop = require('./noop'); /** * Gets metadata for `func`. * * @private * @param {Function} func The function to query. * @returns {*} Returns the metadata for `func`. */ var getData = !metaMap ? noop : function(func) { return metaMap.get(func); }; module.exports = getData; },{"./_metaMap":484,"./noop":542}],443:[function(require,module,exports){ var realNames = require('./_realNames'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Gets the name of `func`. * * @private * @param {Function} func The function to query. * @returns {string} Returns the function name. */ function getFuncName(func) { var result = (func.name + ''), array = realNames[result], length = hasOwnProperty.call(realNames, result) ? array.length : 0; while (length--) { var data = array[length], otherFunc = data.func; if (otherFunc == null || otherFunc == func) { return data.name; } } return result; } module.exports = getFuncName; },{"./_realNames":491}],444:[function(require,module,exports){ /** * Gets the argument placeholder value for `func`. * * @private * @param {Function} func The function to inspect. * @returns {*} Returns the placeholder value. */ function getHolder(func) { var object = func; return object.placeholder; } module.exports = getHolder; },{}],445:[function(require,module,exports){ var isKeyable = require('./_isKeyable'); /** * Gets the data for `map`. * * @private * @param {Object} map The map to query. * @param {string} key The reference key. * @returns {*} Returns the map data. */ function getMapData(map, key) { var data = map.__data__; return isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map; } module.exports = getMapData; },{"./_isKeyable":465}],446:[function(require,module,exports){ var isStrictComparable = require('./_isStrictComparable'), keys = require('./keys'); /** * Gets the property names, values, and compare flags of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the match data of `object`. */ function getMatchData(object) { var result = keys(object), length = result.length; while (length--) { var key = result[length], value = object[key]; result[length] = [key, value, isStrictComparable(value)]; } return result; } module.exports = getMatchData; },{"./_isStrictComparable":469,"./keys":539}],447:[function(require,module,exports){ var baseIsNative = require('./_baseIsNative'), getValue = require('./_getValue'); /** * Gets the native function at `key` of `object`. * * @private * @param {Object} object The object to query. * @param {string} key The key of the method to get. * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { var value = getValue(object, key); return baseIsNative(value) ? value : undefined; } module.exports = getNative; },{"./_baseIsNative":395,"./_getValue":452}],448:[function(require,module,exports){ var overArg = require('./_overArg'); /** Built-in value references. */ var getPrototype = overArg(Object.getPrototypeOf, Object); module.exports = getPrototype; },{"./_overArg":489}],449:[function(require,module,exports){ var Symbol = require('./_Symbol'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto.toString; /** Built-in value references. */ var symToStringTag = Symbol ? Symbol.toStringTag : undefined; /** * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. * * @private * @param {*} value The value to query. * @returns {string} Returns the raw `toStringTag`. */ function getRawTag(value) { var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag]; try { value[symToStringTag] = undefined; var unmasked = true; } catch (e) {} var result = nativeObjectToString.call(value); if (unmasked) { if (isOwn) { value[symToStringTag] = tag; } else { delete value[symToStringTag]; } } return result; } module.exports = getRawTag; },{"./_Symbol":360}],450:[function(require,module,exports){ var arrayFilter = require('./_arrayFilter'), stubArray = require('./stubArray'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Built-in value references. */ var propertyIsEnumerable = objectProto.propertyIsEnumerable; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeGetSymbols = Object.getOwnPropertySymbols; /** * Creates an array of the own enumerable symbols of `object`. * * @private * @param {Object} object The object to query. * @returns {Array} Returns the array of symbols. */ var getSymbols = !nativeGetSymbols ? stubArray : function(object) { if (object == null) { return []; } object = Object(object); return arrayFilter(nativeGetSymbols(object), function(symbol) { return propertyIsEnumerable.call(object, symbol); }); }; module.exports = getSymbols; },{"./_arrayFilter":366,"./stubArray":545}],451:[function(require,module,exports){ var DataView = require('./_DataView'), Map = require('./_Map'), Promise = require('./_Promise'), Set = require('./_Set'), WeakMap = require('./_WeakMap'), baseGetTag = require('./_baseGetTag'), toSource = require('./_toSource'); /** `Object#toString` result references. */ var mapTag = '[object Map]', objectTag = '[object Object]', promiseTag = '[object Promise]', setTag = '[object Set]', weakMapTag = '[object WeakMap]'; var dataViewTag = '[object DataView]'; /** Used to detect maps, sets, and weakmaps. */ var dataViewCtorString = toSource(DataView), mapCtorString = toSource(Map), promiseCtorString = toSource(Promise), setCtorString = toSource(Set), weakMapCtorString = toSource(WeakMap); /** * Gets the `toStringTag` of `value`. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ var getTag = baseGetTag; // Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6. if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || (Map && getTag(new Map) != mapTag) || (Promise && getTag(Promise.resolve()) != promiseTag) || (Set && getTag(new Set) != setTag) || (WeakMap && getTag(new WeakMap) != weakMapTag)) { getTag = function(value) { var result = baseGetTag(value), Ctor = result == objectTag ? value.constructor : undefined, ctorString = Ctor ? toSource(Ctor) : ''; if (ctorString) { switch (ctorString) { case dataViewCtorString: return dataViewTag; case mapCtorString: return mapTag; case promiseCtorString: return promiseTag; case setCtorString: return setTag; case weakMapCtorString: return weakMapTag; } } return result; }; } module.exports = getTag; },{"./_DataView":349,"./_Map":354,"./_Promise":356,"./_Set":357,"./_WeakMap":362,"./_baseGetTag":387,"./_toSource":510}],452:[function(require,module,exports){ /** * Gets the value at `key` of `object`. * * @private * @param {Object} [object] The object to query. * @param {string} key The key of the property to get. * @returns {*} Returns the property value. */ function getValue(object, key) { return object == null ? undefined : object[key]; } module.exports = getValue; },{}],453:[function(require,module,exports){ /** Used to match wrap detail comments. */ var reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, reSplitDetails = /,? & /; /** * Extracts wrapper details from the `source` body comment. * * @private * @param {string} source The source to inspect. * @returns {Array} Returns the wrapper details. */ function getWrapDetails(source) { var match = source.match(reWrapDetails); return match ? match[1].split(reSplitDetails) : []; } module.exports = getWrapDetails; },{}],454:[function(require,module,exports){ var castPath = require('./_castPath'), isArguments = require('./isArguments'), isArray = require('./isArray'), isIndex = require('./_isIndex'), isLength = require('./isLength'), toKey = require('./_toKey'); /** * Checks if `path` exists on `object`. * * @private * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @param {Function} hasFunc The function to check properties. * @returns {boolean} Returns `true` if `path` exists, else `false`. */ function hasPath(object, path, hasFunc) { path = castPath(path, object); var index = -1, length = path.length, result = false; while (++index < length) { var key = toKey(path[index]); if (!(result = object != null && hasFunc(object, key))) { break; } object = object[key]; } if (result || ++index != length) { return result; } length = object == null ? 0 : object.length; return !!length && isLength(length) && isIndex(key, length) && (isArray(object) || isArguments(object)); } module.exports = hasPath; },{"./_castPath":416,"./_isIndex":462,"./_toKey":509,"./isArguments":526,"./isArray":527,"./isLength":533}],455:[function(require,module,exports){ var nativeCreate = require('./_nativeCreate'); /** * Removes all key-value entries from the hash. * * @private * @name clear * @memberOf Hash */ function hashClear() { this.__data__ = nativeCreate ? nativeCreate(null) : {}; this.size = 0; } module.exports = hashClear; },{"./_nativeCreate":485}],456:[function(require,module,exports){ /** * Removes `key` and its value from the hash. * * @private * @name delete * @memberOf Hash * @param {Object} hash The hash to modify. * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function hashDelete(key) { var result = this.has(key) && delete this.__data__[key]; this.size -= result ? 1 : 0; return result; } module.exports = hashDelete; },{}],457:[function(require,module,exports){ var nativeCreate = require('./_nativeCreate'); /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED = '__lodash_hash_undefined__'; /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Gets the hash value for `key`. * * @private * @name get * @memberOf Hash * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function hashGet(key) { var data = this.__data__; if (nativeCreate) { var result = data[key]; return result === HASH_UNDEFINED ? undefined : result; } return hasOwnProperty.call(data, key) ? data[key] : undefined; } module.exports = hashGet; },{"./_nativeCreate":485}],458:[function(require,module,exports){ var nativeCreate = require('./_nativeCreate'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Checks if a hash value for `key` exists. * * @private * @name has * @memberOf Hash * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function hashHas(key) { var data = this.__data__; return nativeCreate ? (data[key] !== undefined) : hasOwnProperty.call(data, key); } module.exports = hashHas; },{"./_nativeCreate":485}],459:[function(require,module,exports){ var nativeCreate = require('./_nativeCreate'); /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED = '__lodash_hash_undefined__'; /** * Sets the hash `key` to `value`. * * @private * @name set * @memberOf Hash * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the hash instance. */ function hashSet(key, value) { var data = this.__data__; this.size += this.has(key) ? 0 : 1; data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; return this; } module.exports = hashSet; },{"./_nativeCreate":485}],460:[function(require,module,exports){ /** Used to match wrap detail comments. */ var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/; /** * Inserts wrapper `details` in a comment at the top of the `source` body. * * @private * @param {string} source The source to modify. * @returns {Array} details The details to insert. * @returns {string} Returns the modified source. */ function insertWrapDetails(source, details) { var length = details.length; if (!length) { return source; } var lastIndex = length - 1; details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; details = details.join(length > 2 ? ', ' : ' '); return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); } module.exports = insertWrapDetails; },{}],461:[function(require,module,exports){ var Symbol = require('./_Symbol'), isArguments = require('./isArguments'), isArray = require('./isArray'); /** Built-in value references. */ var spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; /** * Checks if `value` is a flattenable `arguments` object or array. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. */ function isFlattenable(value) { return isArray(value) || isArguments(value) || !!(spreadableSymbol && value && value[spreadableSymbol]); } module.exports = isFlattenable; },{"./_Symbol":360,"./isArguments":526,"./isArray":527}],462:[function(require,module,exports){ /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER = 9007199254740991; /** Used to detect unsigned integer values. */ var reIsUint = /^(?:0|[1-9]\d*)$/; /** * Checks if `value` is a valid array-like index. * * @private * @param {*} value The value to check. * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. */ function isIndex(value, length) { var type = typeof value; length = length == null ? MAX_SAFE_INTEGER : length; return !!length && (type == 'number' || (type != 'symbol' && reIsUint.test(value))) && (value > -1 && value % 1 == 0 && value < length); } module.exports = isIndex; },{}],463:[function(require,module,exports){ var eq = require('./eq'), isArrayLike = require('./isArrayLike'), isIndex = require('./_isIndex'), isObject = require('./isObject'); /** * Checks if the given arguments are from an iteratee call. * * @private * @param {*} value The potential iteratee value argument. * @param {*} index The potential iteratee index or key argument. * @param {*} object The potential iteratee object argument. * @returns {boolean} Returns `true` if the arguments are from an iteratee call, * else `false`. */ function isIterateeCall(value, index, object) { if (!isObject(object)) { return false; } var type = typeof index; if (type == 'number' ? (isArrayLike(object) && isIndex(index, object.length)) : (type == 'string' && index in object) ) { return eq(object[index], value); } return false; } module.exports = isIterateeCall; },{"./_isIndex":462,"./eq":517,"./isArrayLike":528,"./isObject":534}],464:[function(require,module,exports){ var isArray = require('./isArray'), isSymbol = require('./isSymbol'); /** Used to match property names within property paths. */ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, reIsPlainProp = /^\w*$/; /** * Checks if `value` is a property name and not a property path. * * @private * @param {*} value The value to check. * @param {Object} [object] The object to query keys on. * @returns {boolean} Returns `true` if `value` is a property name, else `false`. */ function isKey(value, object) { if (isArray(value)) { return false; } var type = typeof value; if (type == 'number' || type == 'symbol' || type == 'boolean' || value == null || isSymbol(value)) { return true; } return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || (object != null && value in Object(object)); } module.exports = isKey; },{"./isArray":527,"./isSymbol":536}],465:[function(require,module,exports){ /** * Checks if `value` is suitable for use as unique object key. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is suitable, else `false`. */ function isKeyable(value) { var type = typeof value; return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') ? (value !== '__proto__') : (value === null); } module.exports = isKeyable; },{}],466:[function(require,module,exports){ var LazyWrapper = require('./_LazyWrapper'), getData = require('./_getData'), getFuncName = require('./_getFuncName'), lodash = require('./wrapperLodash'); /** * Checks if `func` has a lazy counterpart. * * @private * @param {Function} func The function to check. * @returns {boolean} Returns `true` if `func` has a lazy counterpart, * else `false`. */ function isLaziable(func) { var funcName = getFuncName(func), other = lodash[funcName]; if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { return false; } if (func === other) { return true; } var data = getData(other); return !!data && func === data[0]; } module.exports = isLaziable; },{"./_LazyWrapper":351,"./_getData":442,"./_getFuncName":443,"./wrapperLodash":553}],467:[function(require,module,exports){ var coreJsData = require('./_coreJsData'); /** Used to detect methods masquerading as native. */ var maskSrcKey = (function() { var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); return uid ? ('Symbol(src)_1.' + uid) : ''; }()); /** * Checks if `func` has its source masked. * * @private * @param {Function} func The function to check. * @returns {boolean} Returns `true` if `func` is masked, else `false`. */ function isMasked(func) { return !!maskSrcKey && (maskSrcKey in func); } module.exports = isMasked; },{"./_coreJsData":421}],468:[function(require,module,exports){ /** Used for built-in method references. */ var objectProto = Object.prototype; /** * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype(value) { var Ctor = value && value.constructor, proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; return value === proto; } module.exports = isPrototype; },{}],469:[function(require,module,exports){ var isObject = require('./isObject'); /** * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` if suitable for strict * equality comparisons, else `false`. */ function isStrictComparable(value) { return value === value && !isObject(value); } module.exports = isStrictComparable; },{"./isObject":534}],470:[function(require,module,exports){ /** * Removes all key-value entries from the list cache. * * @private * @name clear * @memberOf ListCache */ function listCacheClear() { this.__data__ = []; this.size = 0; } module.exports = listCacheClear; },{}],471:[function(require,module,exports){ var assocIndexOf = require('./_assocIndexOf'); /** Used for built-in method references. */ var arrayProto = Array.prototype; /** Built-in value references. */ var splice = arrayProto.splice; /** * Removes `key` and its value from the list cache. * * @private * @name delete * @memberOf ListCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function listCacheDelete(key) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { return false; } var lastIndex = data.length - 1; if (index == lastIndex) { data.pop(); } else { splice.call(data, index, 1); } --this.size; return true; } module.exports = listCacheDelete; },{"./_assocIndexOf":374}],472:[function(require,module,exports){ var assocIndexOf = require('./_assocIndexOf'); /** * Gets the list cache value for `key`. * * @private * @name get * @memberOf ListCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function listCacheGet(key) { var data = this.__data__, index = assocIndexOf(data, key); return index < 0 ? undefined : data[index][1]; } module.exports = listCacheGet; },{"./_assocIndexOf":374}],473:[function(require,module,exports){ var assocIndexOf = require('./_assocIndexOf'); /** * Checks if a list cache value for `key` exists. * * @private * @name has * @memberOf ListCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function listCacheHas(key) { return assocIndexOf(this.__data__, key) > -1; } module.exports = listCacheHas; },{"./_assocIndexOf":374}],474:[function(require,module,exports){ var assocIndexOf = require('./_assocIndexOf'); /** * Sets the list cache `key` to `value`. * * @private * @name set * @memberOf ListCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the list cache instance. */ function listCacheSet(key, value) { var data = this.__data__, index = assocIndexOf(data, key); if (index < 0) { ++this.size; data.push([key, value]); } else { data[index][1] = value; } return this; } module.exports = listCacheSet; },{"./_assocIndexOf":374}],475:[function(require,module,exports){ var Hash = require('./_Hash'), ListCache = require('./_ListCache'), Map = require('./_Map'); /** * Removes all key-value entries from the map. * * @private * @name clear * @memberOf MapCache */ function mapCacheClear() { this.size = 0; this.__data__ = { 'hash': new Hash, 'map': new (Map || ListCache), 'string': new Hash }; } module.exports = mapCacheClear; },{"./_Hash":350,"./_ListCache":352,"./_Map":354}],476:[function(require,module,exports){ var getMapData = require('./_getMapData'); /** * Removes `key` and its value from the map. * * @private * @name delete * @memberOf MapCache * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function mapCacheDelete(key) { var result = getMapData(this, key)['delete'](key); this.size -= result ? 1 : 0; return result; } module.exports = mapCacheDelete; },{"./_getMapData":445}],477:[function(require,module,exports){ var getMapData = require('./_getMapData'); /** * Gets the map value for `key`. * * @private * @name get * @memberOf MapCache * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function mapCacheGet(key) { return getMapData(this, key).get(key); } module.exports = mapCacheGet; },{"./_getMapData":445}],478:[function(require,module,exports){ var getMapData = require('./_getMapData'); /** * Checks if a map value for `key` exists. * * @private * @name has * @memberOf MapCache * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function mapCacheHas(key) { return getMapData(this, key).has(key); } module.exports = mapCacheHas; },{"./_getMapData":445}],479:[function(require,module,exports){ var getMapData = require('./_getMapData'); /** * Sets the map `key` to `value`. * * @private * @name set * @memberOf MapCache * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the map cache instance. */ function mapCacheSet(key, value) { var data = getMapData(this, key), size = data.size; data.set(key, value); this.size += data.size == size ? 0 : 1; return this; } module.exports = mapCacheSet; },{"./_getMapData":445}],480:[function(require,module,exports){ /** * Converts `map` to its key-value pairs. * * @private * @param {Object} map The map to convert. * @returns {Array} Returns the key-value pairs. */ function mapToArray(map) { var index = -1, result = Array(map.size); map.forEach(function(value, key) { result[++index] = [key, value]; }); return result; } module.exports = mapToArray; },{}],481:[function(require,module,exports){ /** * A specialized version of `matchesProperty` for source values suitable * for strict equality comparisons, i.e. `===`. * * @private * @param {string} key The key of the property to get. * @param {*} srcValue The value to match. * @returns {Function} Returns the new spec function. */ function matchesStrictComparable(key, srcValue) { return function(object) { if (object == null) { return false; } return object[key] === srcValue && (srcValue !== undefined || (key in Object(object))); }; } module.exports = matchesStrictComparable; },{}],482:[function(require,module,exports){ var memoize = require('./memoize'); /** Used as the maximum memoize cache size. */ var MAX_MEMOIZE_SIZE = 500; /** * A specialized version of `_.memoize` which clears the memoized function's * cache when it exceeds `MAX_MEMOIZE_SIZE`. * * @private * @param {Function} func The function to have its output memoized. * @returns {Function} Returns the new memoized function. */ function memoizeCapped(func) { var result = memoize(func, function(key) { if (cache.size === MAX_MEMOIZE_SIZE) { cache.clear(); } return key; }); var cache = result.cache; return result; } module.exports = memoizeCapped; },{"./memoize":541}],483:[function(require,module,exports){ var composeArgs = require('./_composeArgs'), composeArgsRight = require('./_composeArgsRight'), replaceHolders = require('./_replaceHolders'); /** Used as the internal argument placeholder. */ var PLACEHOLDER = '__lodash_placeholder__'; /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_BOUND_FLAG = 4, WRAP_CURRY_FLAG = 8, WRAP_ARY_FLAG = 128, WRAP_REARG_FLAG = 256; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMin = Math.min; /** * Merges the function metadata of `source` into `data`. * * Merging metadata reduces the number of wrappers used to invoke a function. * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` * may be applied regardless of execution order. Methods like `_.ary` and * `_.rearg` modify function arguments, making the order in which they are * executed important, preventing the merging of metadata. However, we make * an exception for a safe combined case where curried functions have `_.ary` * and or `_.rearg` applied. * * @private * @param {Array} data The destination metadata. * @param {Array} source The source metadata. * @returns {Array} Returns `data`. */ function mergeData(data, source) { var bitmask = data[1], srcBitmask = source[1], newBitmask = bitmask | srcBitmask, isCommon = newBitmask < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); var isCombo = ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); // Exit early if metadata can't be merged. if (!(isCommon || isCombo)) { return data; } // Use source `thisArg` if available. if (srcBitmask & WRAP_BIND_FLAG) { data[2] = source[2]; // Set when currying a bound function. newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_CURRY_BOUND_FLAG; } // Compose partial arguments. var value = source[3]; if (value) { var partials = data[3]; data[3] = partials ? composeArgs(partials, value, source[4]) : value; data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; } // Compose partial right arguments. value = source[5]; if (value) { partials = data[5]; data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; } // Use source `argPos` if available. value = source[7]; if (value) { data[7] = value; } // Use source `ary` if it's smaller. if (srcBitmask & WRAP_ARY_FLAG) { data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); } // Use source `arity` if one is not provided. if (data[9] == null) { data[9] = source[9]; } // Use source `func` and merge bitmasks. data[0] = source[0]; data[1] = newBitmask; return data; } module.exports = mergeData; },{"./_composeArgs":417,"./_composeArgsRight":418,"./_replaceHolders":493}],484:[function(require,module,exports){ var WeakMap = require('./_WeakMap'); /** Used to store function metadata. */ var metaMap = WeakMap && new WeakMap; module.exports = metaMap; },{"./_WeakMap":362}],485:[function(require,module,exports){ var getNative = require('./_getNative'); /* Built-in method references that are verified to be native. */ var nativeCreate = getNative(Object, 'create'); module.exports = nativeCreate; },{"./_getNative":447}],486:[function(require,module,exports){ var overArg = require('./_overArg'); /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeKeys = overArg(Object.keys, Object); module.exports = nativeKeys; },{"./_overArg":489}],487:[function(require,module,exports){ var freeGlobal = require('./_freeGlobal'); /** Detect free variable `exports`. */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule && freeModule.exports === freeExports; /** Detect free variable `process` from Node.js. */ var freeProcess = moduleExports && freeGlobal.process; /** Used to access faster Node.js helpers. */ var nodeUtil = (function() { try { // Use `util.types` for Node.js 10+. var types = freeModule && freeModule.require && freeModule.require('util').types; if (types) { return types; } // Legacy `process.binding('util')` for Node.js < 10. return freeProcess && freeProcess.binding && freeProcess.binding('util'); } catch (e) {} }()); module.exports = nodeUtil; },{"./_freeGlobal":440}],488:[function(require,module,exports){ /** Used for built-in method references. */ var objectProto = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var nativeObjectToString = objectProto.toString; /** * Converts `value` to a string using `Object.prototype.toString`. * * @private * @param {*} value The value to convert. * @returns {string} Returns the converted string. */ function objectToString(value) { return nativeObjectToString.call(value); } module.exports = objectToString; },{}],489:[function(require,module,exports){ /** * Creates a unary function that invokes `func` with its argument transformed. * * @private * @param {Function} func The function to wrap. * @param {Function} transform The argument transform. * @returns {Function} Returns the new function. */ function overArg(func, transform) { return function(arg) { return func(transform(arg)); }; } module.exports = overArg; },{}],490:[function(require,module,exports){ var apply = require('./_apply'); /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max; /** * A specialized version of `baseRest` which transforms the rest array. * * @private * @param {Function} func The function to apply a rest parameter to. * @param {number} [start=func.length-1] The start position of the rest parameter. * @param {Function} transform The rest array transform. * @returns {Function} Returns the new function. */ function overRest(func, start, transform) { start = nativeMax(start === undefined ? (func.length - 1) : start, 0); return function() { var args = arguments, index = -1, length = nativeMax(args.length - start, 0), array = Array(length); while (++index < length) { array[index] = args[start + index]; } index = -1; var otherArgs = Array(start + 1); while (++index < start) { otherArgs[index] = args[index]; } otherArgs[start] = transform(array); return apply(func, this, otherArgs); }; } module.exports = overRest; },{"./_apply":363}],491:[function(require,module,exports){ /** Used to lookup unminified function names. */ var realNames = {}; module.exports = realNames; },{}],492:[function(require,module,exports){ var copyArray = require('./_copyArray'), isIndex = require('./_isIndex'); /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMin = Math.min; /** * Reorder `array` according to the specified indexes where the element at * the first index is assigned as the first element, the element at * the second index is assigned as the second element, and so on. * * @private * @param {Array} array The array to reorder. * @param {Array} indexes The arranged array indexes. * @returns {Array} Returns `array`. */ function reorder(array, indexes) { var arrLength = array.length, length = nativeMin(indexes.length, arrLength), oldArray = copyArray(array); while (length--) { var index = indexes[length]; array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; } return array; } module.exports = reorder; },{"./_copyArray":419,"./_isIndex":462}],493:[function(require,module,exports){ /** Used as the internal argument placeholder. */ var PLACEHOLDER = '__lodash_placeholder__'; /** * Replaces all `placeholder` elements in `array` with an internal placeholder * and returns an array of their indexes. * * @private * @param {Array} array The array to modify. * @param {*} placeholder The placeholder to replace. * @returns {Array} Returns the new array of placeholder indexes. */ function replaceHolders(array, placeholder) { var index = -1, length = array.length, resIndex = 0, result = []; while (++index < length) { var value = array[index]; if (value === placeholder || value === PLACEHOLDER) { array[index] = PLACEHOLDER; result[resIndex++] = index; } } return result; } module.exports = replaceHolders; },{}],494:[function(require,module,exports){ var freeGlobal = require('./_freeGlobal'); /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); module.exports = root; },{"./_freeGlobal":440}],495:[function(require,module,exports){ /** Used to stand-in for `undefined` hash values. */ var HASH_UNDEFINED = '__lodash_hash_undefined__'; /** * Adds `value` to the array cache. * * @private * @name add * @memberOf SetCache * @alias push * @param {*} value The value to cache. * @returns {Object} Returns the cache instance. */ function setCacheAdd(value) { this.__data__.set(value, HASH_UNDEFINED); return this; } module.exports = setCacheAdd; },{}],496:[function(require,module,exports){ /** * Checks if `value` is in the array cache. * * @private * @name has * @memberOf SetCache * @param {*} value The value to search for. * @returns {number} Returns `true` if `value` is found, else `false`. */ function setCacheHas(value) { return this.__data__.has(value); } module.exports = setCacheHas; },{}],497:[function(require,module,exports){ var baseSetData = require('./_baseSetData'), shortOut = require('./_shortOut'); /** * Sets metadata for `func`. * * **Note:** If this function becomes hot, i.e. is invoked a lot in a short * period of time, it will trip its breaker and transition to an identity * function to avoid garbage collection pauses in V8. See * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) * for more details. * * @private * @param {Function} func The function to associate metadata with. * @param {*} data The metadata. * @returns {Function} Returns `func`. */ var setData = shortOut(baseSetData); module.exports = setData; },{"./_baseSetData":406,"./_shortOut":501}],498:[function(require,module,exports){ /** * Converts `set` to an array of its values. * * @private * @param {Object} set The set to convert. * @returns {Array} Returns the values. */ function setToArray(set) { var index = -1, result = Array(set.size); set.forEach(function(value) { result[++index] = value; }); return result; } module.exports = setToArray; },{}],499:[function(require,module,exports){ var baseSetToString = require('./_baseSetToString'), shortOut = require('./_shortOut'); /** * Sets the `toString` method of `func` to return `string`. * * @private * @param {Function} func The function to modify. * @param {Function} string The `toString` result. * @returns {Function} Returns `func`. */ var setToString = shortOut(baseSetToString); module.exports = setToString; },{"./_baseSetToString":407,"./_shortOut":501}],500:[function(require,module,exports){ var getWrapDetails = require('./_getWrapDetails'), insertWrapDetails = require('./_insertWrapDetails'), setToString = require('./_setToString'), updateWrapDetails = require('./_updateWrapDetails'); /** * Sets the `toString` method of `wrapper` to mimic the source of `reference` * with wrapper details in a comment at the top of the source body. * * @private * @param {Function} wrapper The function to modify. * @param {Function} reference The reference function. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @returns {Function} Returns `wrapper`. */ function setWrapToString(wrapper, reference, bitmask) { var source = (reference + ''); return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); } module.exports = setWrapToString; },{"./_getWrapDetails":453,"./_insertWrapDetails":460,"./_setToString":499,"./_updateWrapDetails":511}],501:[function(require,module,exports){ /** Used to detect hot functions by number of calls within a span of milliseconds. */ var HOT_COUNT = 800, HOT_SPAN = 16; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeNow = Date.now; /** * Creates a function that'll short out and invoke `identity` instead * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` * milliseconds. * * @private * @param {Function} func The function to restrict. * @returns {Function} Returns the new shortable function. */ function shortOut(func) { var count = 0, lastCalled = 0; return function() { var stamp = nativeNow(), remaining = HOT_SPAN - (stamp - lastCalled); lastCalled = stamp; if (remaining > 0) { if (++count >= HOT_COUNT) { return arguments[0]; } } else { count = 0; } return func.apply(undefined, arguments); }; } module.exports = shortOut; },{}],502:[function(require,module,exports){ var ListCache = require('./_ListCache'); /** * Removes all key-value entries from the stack. * * @private * @name clear * @memberOf Stack */ function stackClear() { this.__data__ = new ListCache; this.size = 0; } module.exports = stackClear; },{"./_ListCache":352}],503:[function(require,module,exports){ /** * Removes `key` and its value from the stack. * * @private * @name delete * @memberOf Stack * @param {string} key The key of the value to remove. * @returns {boolean} Returns `true` if the entry was removed, else `false`. */ function stackDelete(key) { var data = this.__data__, result = data['delete'](key); this.size = data.size; return result; } module.exports = stackDelete; },{}],504:[function(require,module,exports){ /** * Gets the stack value for `key`. * * @private * @name get * @memberOf Stack * @param {string} key The key of the value to get. * @returns {*} Returns the entry value. */ function stackGet(key) { return this.__data__.get(key); } module.exports = stackGet; },{}],505:[function(require,module,exports){ /** * Checks if a stack value for `key` exists. * * @private * @name has * @memberOf Stack * @param {string} key The key of the entry to check. * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. */ function stackHas(key) { return this.__data__.has(key); } module.exports = stackHas; },{}],506:[function(require,module,exports){ var ListCache = require('./_ListCache'), Map = require('./_Map'), MapCache = require('./_MapCache'); /** Used as the size to enable large array optimizations. */ var LARGE_ARRAY_SIZE = 200; /** * Sets the stack `key` to `value`. * * @private * @name set * @memberOf Stack * @param {string} key The key of the value to set. * @param {*} value The value to set. * @returns {Object} Returns the stack cache instance. */ function stackSet(key, value) { var data = this.__data__; if (data instanceof ListCache) { var pairs = data.__data__; if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { pairs.push([key, value]); this.size = ++data.size; return this; } data = this.__data__ = new MapCache(pairs); } data.set(key, value); this.size = data.size; return this; } module.exports = stackSet; },{"./_ListCache":352,"./_Map":354,"./_MapCache":355}],507:[function(require,module,exports){ /** * A specialized version of `_.indexOf` which performs strict equality * comparisons of values, i.e. `===`. * * @private * @param {Array} array The array to inspect. * @param {*} value The value to search for. * @param {number} fromIndex The index to search from. * @returns {number} Returns the index of the matched value, else `-1`. */ function strictIndexOf(array, value, fromIndex) { var index = fromIndex - 1, length = array.length; while (++index < length) { if (array[index] === value) { return index; } } return -1; } module.exports = strictIndexOf; },{}],508:[function(require,module,exports){ var memoizeCapped = require('./_memoizeCapped'); /** Used to match property names within property paths. */ var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; /** Used to match backslashes in property paths. */ var reEscapeChar = /\\(\\)?/g; /** * Converts `string` to a property path array. * * @private * @param {string} string The string to convert. * @returns {Array} Returns the property path array. */ var stringToPath = memoizeCapped(function(string) { var result = []; if (string.charCodeAt(0) === 46 /* . */) { result.push(''); } string.replace(rePropName, function(match, number, quote, subString) { result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match)); }); return result; }); module.exports = stringToPath; },{"./_memoizeCapped":482}],509:[function(require,module,exports){ var isSymbol = require('./isSymbol'); /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0; /** * Converts `value` to a string key if it's not a string or symbol. * * @private * @param {*} value The value to inspect. * @returns {string|symbol} Returns the key. */ function toKey(value) { if (typeof value == 'string' || isSymbol(value)) { return value; } var result = (value + ''); return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } module.exports = toKey; },{"./isSymbol":536}],510:[function(require,module,exports){ /** Used for built-in method references. */ var funcProto = Function.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString = funcProto.toString; /** * Converts `func` to its source code. * * @private * @param {Function} func The function to convert. * @returns {string} Returns the source code. */ function toSource(func) { if (func != null) { try { return funcToString.call(func); } catch (e) {} try { return (func + ''); } catch (e) {} } return ''; } module.exports = toSource; },{}],511:[function(require,module,exports){ var arrayEach = require('./_arrayEach'), arrayIncludes = require('./_arrayIncludes'); /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1, WRAP_BIND_KEY_FLAG = 2, WRAP_CURRY_FLAG = 8, WRAP_CURRY_RIGHT_FLAG = 16, WRAP_PARTIAL_FLAG = 32, WRAP_PARTIAL_RIGHT_FLAG = 64, WRAP_ARY_FLAG = 128, WRAP_REARG_FLAG = 256, WRAP_FLIP_FLAG = 512; /** Used to associate wrap methods with their bit flags. */ var wrapFlags = [ ['ary', WRAP_ARY_FLAG], ['bind', WRAP_BIND_FLAG], ['bindKey', WRAP_BIND_KEY_FLAG], ['curry', WRAP_CURRY_FLAG], ['curryRight', WRAP_CURRY_RIGHT_FLAG], ['flip', WRAP_FLIP_FLAG], ['partial', WRAP_PARTIAL_FLAG], ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], ['rearg', WRAP_REARG_FLAG] ]; /** * Updates wrapper `details` based on `bitmask` flags. * * @private * @returns {Array} details The details to modify. * @param {number} bitmask The bitmask flags. See `createWrap` for more details. * @returns {Array} Returns `details`. */ function updateWrapDetails(details, bitmask) { arrayEach(wrapFlags, function(pair) { var value = '_.' + pair[0]; if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { details.push(value); } }); return details.sort(); } module.exports = updateWrapDetails; },{"./_arrayEach":365,"./_arrayIncludes":367}],512:[function(require,module,exports){ var LazyWrapper = require('./_LazyWrapper'), LodashWrapper = require('./_LodashWrapper'), copyArray = require('./_copyArray'); /** * Creates a clone of `wrapper`. * * @private * @param {Object} wrapper The wrapper to clone. * @returns {Object} Returns the cloned wrapper. */ function wrapperClone(wrapper) { if (wrapper instanceof LazyWrapper) { return wrapper.clone(); } var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); result.__actions__ = copyArray(wrapper.__actions__); result.__index__ = wrapper.__index__; result.__values__ = wrapper.__values__; return result; } module.exports = wrapperClone; },{"./_LazyWrapper":351,"./_LodashWrapper":353,"./_copyArray":419}],513:[function(require,module,exports){ var assignValue = require('./_assignValue'), copyObject = require('./_copyObject'), createAssigner = require('./_createAssigner'), isArrayLike = require('./isArrayLike'), isPrototype = require('./_isPrototype'), keys = require('./keys'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Assigns own enumerable string keyed properties of source objects to the * destination object. Source objects are applied from left to right. * Subsequent sources overwrite property assignments of previous sources. * * **Note:** This method mutates `object` and is loosely based on * [`Object.assign`](https://mdn.io/Object/assign). * * @static * @memberOf _ * @since 0.10.0 * @category Object * @param {Object} object The destination object. * @param {...Object} [sources] The source objects. * @returns {Object} Returns `object`. * @see _.assignIn * @example * * function Foo() { * this.a = 1; * } * * function Bar() { * this.c = 3; * } * * Foo.prototype.b = 2; * Bar.prototype.d = 4; * * _.assign({ 'a': 0 }, new Foo, new Bar); * // => { 'a': 1, 'c': 3 } */ var assign = createAssigner(function(object, source) { if (isPrototype(source) || isArrayLike(source)) { copyObject(source, keys(source), object); return; } for (var key in source) { if (hasOwnProperty.call(source, key)) { assignValue(object, key, source[key]); } } }); module.exports = assign; },{"./_assignValue":373,"./_copyObject":420,"./_createAssigner":424,"./_isPrototype":468,"./isArrayLike":528,"./keys":539}],514:[function(require,module,exports){ var baseRest = require('./_baseRest'), createWrap = require('./_createWrap'), getHolder = require('./_getHolder'), replaceHolders = require('./_replaceHolders'); /** Used to compose bitmasks for function metadata. */ var WRAP_BIND_FLAG = 1, WRAP_PARTIAL_FLAG = 32; /** * Creates a function that invokes `func` with the `this` binding of `thisArg` * and `partials` prepended to the arguments it receives. * * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, * may be used as a placeholder for partially applied arguments. * * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" * property of bound functions. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to bind. * @param {*} thisArg The `this` binding of `func`. * @param {...*} [partials] The arguments to be partially applied. * @returns {Function} Returns the new bound function. * @example * * function greet(greeting, punctuation) { * return greeting + ' ' + this.user + punctuation; * } * * var object = { 'user': 'fred' }; * * var bound = _.bind(greet, object, 'hi'); * bound('!'); * // => 'hi fred!' * * // Bound with placeholders. * var bound = _.bind(greet, object, _, '!'); * bound('hi'); * // => 'hi fred!' */ var bind = baseRest(function(func, thisArg, partials) { var bitmask = WRAP_BIND_FLAG; if (partials.length) { var holders = replaceHolders(partials, getHolder(bind)); bitmask |= WRAP_PARTIAL_FLAG; } return createWrap(func, bitmask, thisArg, partials, holders); }); // Assign default placeholders. bind.placeholder = {}; module.exports = bind; },{"./_baseRest":405,"./_createWrap":435,"./_getHolder":444,"./_replaceHolders":493}],515:[function(require,module,exports){ /** * Creates a function that returns `value`. * * @static * @memberOf _ * @since 2.4.0 * @category Util * @param {*} value The value to return from the new function. * @returns {Function} Returns the new constant function. * @example * * var objects = _.times(2, _.constant({ 'a': 1 })); * * console.log(objects); * // => [{ 'a': 1 }, { 'a': 1 }] * * console.log(objects[0] === objects[1]); * // => true */ function constant(value) { return function() { return value; }; } module.exports = constant; },{}],516:[function(require,module,exports){ var isObject = require('./isObject'), now = require('./now'), toNumber = require('./toNumber'); /** Error message constants. */ var FUNC_ERROR_TEXT = 'Expected a function'; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max, nativeMin = Math.min; /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel * delayed `func` invocations and a `flush` method to immediately invoke them. * Provide `options` to indicate whether `func` should be invoked on the * leading and/or trailing edge of the `wait` timeout. The `func` is invoked * with the last arguments provided to the debounced function. Subsequent * calls to the debounced function return the result of the last `func` * invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the debounced function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to debounce. * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=false] * Specify invoking on the leading edge of the timeout. * @param {number} [options.maxWait] * The maximum time `func` is allowed to be delayed before it's invoked. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = 'maxWait' in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = 'trailing' in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = undefined; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { // Reset any `maxWait` timer. lastInvokeTime = time; // Start the timer for the trailing edge. timerId = setTimeout(timerExpired, wait); // Invoke the leading edge. return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall; return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; // Either this is the first call, activity has stopped and we're at the // trailing edge, the system time has gone backwards and we're treating // it as the trailing edge, or we've hit the `maxWait` limit. return (lastCallTime === undefined || (timeSinceLastCall >= wait) || (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); } function timerExpired() { var time = now(); if (shouldInvoke(time)) { return trailingEdge(time); } // Restart the timer. timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = undefined; // Only invoke if we have `lastArgs` which means `func` has been // debounced at least once. if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = undefined; return result; } function cancel() { if (timerId !== undefined) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { return timerId === undefined ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === undefined) { return leadingEdge(lastCallTime); } if (maxing) { // Handle invocations in a tight loop. clearTimeout(timerId); timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === undefined) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } module.exports = debounce; },{"./isObject":534,"./now":543,"./toNumber":549}],517:[function(require,module,exports){ /** * Performs a * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) * comparison between two values to determine if they are equivalent. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to compare. * @param {*} other The other value to compare. * @returns {boolean} Returns `true` if the values are equivalent, else `false`. * @example * * var object = { 'a': 1 }; * var other = { 'a': 1 }; * * _.eq(object, object); * // => true * * _.eq(object, other); * // => false * * _.eq('a', 'a'); * // => true * * _.eq('a', Object('a')); * // => false * * _.eq(NaN, NaN); * // => true */ function eq(value, other) { return value === other || (value !== value && other !== other); } module.exports = eq; },{}],518:[function(require,module,exports){ var arrayFilter = require('./_arrayFilter'), baseFilter = require('./_baseFilter'), baseIteratee = require('./_baseIteratee'), isArray = require('./isArray'); /** * Iterates over elements of `collection`, returning an array of all elements * `predicate` returns truthy for. The predicate is invoked with three * arguments: (value, index|key, collection). * * **Note:** Unlike `_.remove`, this method returns a new array. * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @returns {Array} Returns the new filtered array. * @see _.reject * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': true }, * { 'user': 'fred', 'age': 40, 'active': false } * ]; * * _.filter(users, function(o) { return !o.active; }); * // => objects for ['fred'] * * // The `_.matches` iteratee shorthand. * _.filter(users, { 'age': 36, 'active': true }); * // => objects for ['barney'] * * // The `_.matchesProperty` iteratee shorthand. * _.filter(users, ['active', false]); * // => objects for ['fred'] * * // The `_.property` iteratee shorthand. * _.filter(users, 'active'); * // => objects for ['barney'] * * // Combining several predicates using `_.overEvery` or `_.overSome`. * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); * // => objects for ['fred', 'barney'] */ function filter(collection, predicate) { var func = isArray(collection) ? arrayFilter : baseFilter; return func(collection, baseIteratee(predicate, 3)); } module.exports = filter; },{"./_arrayFilter":366,"./_baseFilter":380,"./_baseIteratee":397,"./isArray":527}],519:[function(require,module,exports){ var createFind = require('./_createFind'), findIndex = require('./findIndex'); /** * Iterates over elements of `collection`, returning the first element * `predicate` returns truthy for. The predicate is invoked with three * arguments: (value, index|key, collection). * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=0] The index to search from. * @returns {*} Returns the matched element, else `undefined`. * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'active': true }, * { 'user': 'fred', 'age': 40, 'active': false }, * { 'user': 'pebbles', 'age': 1, 'active': true } * ]; * * _.find(users, function(o) { return o.age < 40; }); * // => object for 'barney' * * // The `_.matches` iteratee shorthand. * _.find(users, { 'age': 1, 'active': true }); * // => object for 'pebbles' * * // The `_.matchesProperty` iteratee shorthand. * _.find(users, ['active', false]); * // => object for 'fred' * * // The `_.property` iteratee shorthand. * _.find(users, 'active'); * // => object for 'barney' */ var find = createFind(findIndex); module.exports = find; },{"./_createFind":430,"./findIndex":520}],520:[function(require,module,exports){ var baseFindIndex = require('./_baseFindIndex'), baseIteratee = require('./_baseIteratee'), toInteger = require('./toInteger'); /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max; /** * This method is like `_.find` except that it returns the index of the first * element `predicate` returns truthy for instead of the element itself. * * @static * @memberOf _ * @since 1.1.0 * @category Array * @param {Array} array The array to inspect. * @param {Function} [predicate=_.identity] The function invoked per iteration. * @param {number} [fromIndex=0] The index to search from. * @returns {number} Returns the index of the found element, else `-1`. * @example * * var users = [ * { 'user': 'barney', 'active': false }, * { 'user': 'fred', 'active': false }, * { 'user': 'pebbles', 'active': true } * ]; * * _.findIndex(users, function(o) { return o.user == 'barney'; }); * // => 0 * * // The `_.matches` iteratee shorthand. * _.findIndex(users, { 'user': 'fred', 'active': false }); * // => 1 * * // The `_.matchesProperty` iteratee shorthand. * _.findIndex(users, ['active', false]); * // => 0 * * // The `_.property` iteratee shorthand. * _.findIndex(users, 'active'); * // => 2 */ function findIndex(array, predicate, fromIndex) { var length = array == null ? 0 : array.length; if (!length) { return -1; } var index = fromIndex == null ? 0 : toInteger(fromIndex); if (index < 0) { index = nativeMax(length + index, 0); } return baseFindIndex(array, baseIteratee(predicate, 3), index); } module.exports = findIndex; },{"./_baseFindIndex":381,"./_baseIteratee":397,"./toInteger":548}],521:[function(require,module,exports){ var baseFlatten = require('./_baseFlatten'); /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0; /** * Recursively flattens `array`. * * @static * @memberOf _ * @since 3.0.0 * @category Array * @param {Array} array The array to flatten. * @returns {Array} Returns the new flattened array. * @example * * _.flattenDeep([1, [2, [3, [4]], 5]]); * // => [1, 2, 3, 4, 5] */ function flattenDeep(array) { var length = array == null ? 0 : array.length; return length ? baseFlatten(array, INFINITY) : []; } module.exports = flattenDeep; },{"./_baseFlatten":382}],522:[function(require,module,exports){ var arrayEach = require('./_arrayEach'), baseEach = require('./_baseEach'), castFunction = require('./_castFunction'), isArray = require('./isArray'); /** * Iterates over elements of `collection` and invokes `iteratee` for each element. * The iteratee is invoked with three arguments: (value, index|key, collection). * Iteratee functions may exit iteration early by explicitly returning `false`. * * **Note:** As with other "Collections" methods, objects with a "length" * property are iterated like arrays. To avoid this behavior use `_.forIn` * or `_.forOwn` for object iteration. * * @static * @memberOf _ * @since 0.1.0 * @alias each * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array|Object} Returns `collection`. * @see _.forEachRight * @example * * _.forEach([1, 2], function(value) { * console.log(value); * }); * // => Logs `1` then `2`. * * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { * console.log(key); * }); * // => Logs 'a' then 'b' (iteration order is not guaranteed). */ function forEach(collection, iteratee) { var func = isArray(collection) ? arrayEach : baseEach; return func(collection, castFunction(iteratee)); } module.exports = forEach; },{"./_arrayEach":365,"./_baseEach":379,"./_castFunction":415,"./isArray":527}],523:[function(require,module,exports){ var baseGet = require('./_baseGet'); /** * Gets the value at `path` of `object`. If the resolved value is * `undefined`, the `defaultValue` is returned in its place. * * @static * @memberOf _ * @since 3.7.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path of the property to get. * @param {*} [defaultValue] The value returned for `undefined` resolved values. * @returns {*} Returns the resolved value. * @example * * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * * _.get(object, 'a[0].b.c'); * // => 3 * * _.get(object, ['a', '0', 'b', 'c']); * // => 3 * * _.get(object, 'a.b.c', 'default'); * // => 'default' */ function get(object, path, defaultValue) { var result = object == null ? undefined : baseGet(object, path); return result === undefined ? defaultValue : result; } module.exports = get; },{"./_baseGet":385}],524:[function(require,module,exports){ var baseHasIn = require('./_baseHasIn'), hasPath = require('./_hasPath'); /** * Checks if `path` is a direct or inherited property of `object`. * * @static * @memberOf _ * @since 4.0.0 * @category Object * @param {Object} object The object to query. * @param {Array|string} path The path to check. * @returns {boolean} Returns `true` if `path` exists, else `false`. * @example * * var object = _.create({ 'a': _.create({ 'b': 2 }) }); * * _.hasIn(object, 'a'); * // => true * * _.hasIn(object, 'a.b'); * // => true * * _.hasIn(object, ['a', 'b']); * // => true * * _.hasIn(object, 'b'); * // => false */ function hasIn(object, path) { return object != null && hasPath(object, path, baseHasIn); } module.exports = hasIn; },{"./_baseHasIn":388,"./_hasPath":454}],525:[function(require,module,exports){ /** * This method returns the first argument it receives. * * @static * @since 0.1.0 * @memberOf _ * @category Util * @param {*} value Any value. * @returns {*} Returns `value`. * @example * * var object = { 'a': 1 }; * * console.log(_.identity(object) === object); * // => true */ function identity(value) { return value; } module.exports = identity; },{}],526:[function(require,module,exports){ var baseIsArguments = require('./_baseIsArguments'), isObjectLike = require('./isObjectLike'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** Built-in value references. */ var propertyIsEnumerable = objectProto.propertyIsEnumerable; /** * Checks if `value` is likely an `arguments` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an `arguments` object, * else `false`. * @example * * _.isArguments(function() { return arguments; }()); * // => true * * _.isArguments([1, 2, 3]); * // => false */ var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); }; module.exports = isArguments; },{"./_baseIsArguments":390,"./isObjectLike":535}],527:[function(require,module,exports){ /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray = Array.isArray; module.exports = isArray; },{}],528:[function(require,module,exports){ var isFunction = require('./isFunction'), isLength = require('./isLength'); /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike(value) { return value != null && isLength(value.length) && !isFunction(value); } module.exports = isArrayLike; },{"./isFunction":532,"./isLength":533}],529:[function(require,module,exports){ var isArrayLike = require('./isArrayLike'), isObjectLike = require('./isObjectLike'); /** * This method is like `_.isArrayLike` except that it also checks if `value` * is an object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array-like object, * else `false`. * @example * * _.isArrayLikeObject([1, 2, 3]); * // => true * * _.isArrayLikeObject(document.body.children); * // => true * * _.isArrayLikeObject('abc'); * // => false * * _.isArrayLikeObject(_.noop); * // => false */ function isArrayLikeObject(value) { return isObjectLike(value) && isArrayLike(value); } module.exports = isArrayLikeObject; },{"./isArrayLike":528,"./isObjectLike":535}],530:[function(require,module,exports){ var root = require('./_root'), stubFalse = require('./stubFalse'); /** Detect free variable `exports`. */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; /** Detect free variable `module`. */ var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; /** Detect the popular CommonJS extension `module.exports`. */ var moduleExports = freeModule && freeModule.exports === freeExports; /** Built-in value references. */ var Buffer = moduleExports ? root.Buffer : undefined; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; /** * Checks if `value` is a buffer. * * @static * @memberOf _ * @since 4.3.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. * @example * * _.isBuffer(new Buffer(2)); * // => true * * _.isBuffer(new Uint8Array(2)); * // => false */ var isBuffer = nativeIsBuffer || stubFalse; module.exports = isBuffer; },{"./_root":494,"./stubFalse":546}],531:[function(require,module,exports){ var baseKeys = require('./_baseKeys'), getTag = require('./_getTag'), isArguments = require('./isArguments'), isArray = require('./isArray'), isArrayLike = require('./isArrayLike'), isBuffer = require('./isBuffer'), isPrototype = require('./_isPrototype'), isTypedArray = require('./isTypedArray'); /** `Object#toString` result references. */ var mapTag = '[object Map]', setTag = '[object Set]'; /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Checks if `value` is an empty object, collection, map, or set. * * Objects are considered empty if they have no own enumerable string keyed * properties. * * Array-like values such as `arguments` objects, arrays, buffers, strings, or * jQuery-like collections are considered empty if they have a `length` of `0`. * Similarly, maps and sets are considered empty if they have a `size` of `0`. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is empty, else `false`. * @example * * _.isEmpty(null); * // => true * * _.isEmpty(true); * // => true * * _.isEmpty(1); * // => true * * _.isEmpty([1, 2, 3]); * // => false * * _.isEmpty({ 'a': 1 }); * // => false */ function isEmpty(value) { if (value == null) { return true; } if (isArrayLike(value) && (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || isBuffer(value) || isTypedArray(value) || isArguments(value))) { return !value.length; } var tag = getTag(value); if (tag == mapTag || tag == setTag) { return !value.size; } if (isPrototype(value)) { return !baseKeys(value).length; } for (var key in value) { if (hasOwnProperty.call(value, key)) { return false; } } return true; } module.exports = isEmpty; },{"./_baseKeys":398,"./_getTag":451,"./_isPrototype":468,"./isArguments":526,"./isArray":527,"./isArrayLike":528,"./isBuffer":530,"./isTypedArray":537}],532:[function(require,module,exports){ var baseGetTag = require('./_baseGetTag'), isObject = require('./isObject'); /** `Object#toString` result references. */ var asyncTag = '[object AsyncFunction]', funcTag = '[object Function]', genTag = '[object GeneratorFunction]', proxyTag = '[object Proxy]'; /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction(value) { if (!isObject(value)) { return false; } // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 9 which returns 'object' for typed arrays and other constructors. var tag = baseGetTag(value); return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; } module.exports = isFunction; },{"./_baseGetTag":387,"./isObject":534}],533:[function(require,module,exports){ /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER = 9007199254740991; /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } module.exports = isLength; },{}],534:[function(require,module,exports){ /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return value != null && (type == 'object' || type == 'function'); } module.exports = isObject; },{}],535:[function(require,module,exports){ /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return value != null && typeof value == 'object'; } module.exports = isObjectLike; },{}],536:[function(require,module,exports){ var baseGetTag = require('./_baseGetTag'), isObjectLike = require('./isObjectLike'); /** `Object#toString` result references. */ var symbolTag = '[object Symbol]'; /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike(value) && baseGetTag(value) == symbolTag); } module.exports = isSymbol; },{"./_baseGetTag":387,"./isObjectLike":535}],537:[function(require,module,exports){ var baseIsTypedArray = require('./_baseIsTypedArray'), baseUnary = require('./_baseUnary'), nodeUtil = require('./_nodeUtil'); /* Node.js helper references. */ var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; /** * Checks if `value` is classified as a typed array. * * @static * @memberOf _ * @since 3.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. * @example * * _.isTypedArray(new Uint8Array); * // => true * * _.isTypedArray([]); * // => false */ var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; module.exports = isTypedArray; },{"./_baseIsTypedArray":396,"./_baseUnary":410,"./_nodeUtil":487}],538:[function(require,module,exports){ var baseAssignValue = require('./_baseAssignValue'), createAggregator = require('./_createAggregator'); /** * Creates an object composed of keys generated from the results of running * each element of `collection` thru `iteratee`. The corresponding value of * each key is the last element responsible for generating the key. The * iteratee is invoked with one argument: (value). * * @static * @memberOf _ * @since 4.0.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The iteratee to transform keys. * @returns {Object} Returns the composed aggregate object. * @example * * var array = [ * { 'dir': 'left', 'code': 97 }, * { 'dir': 'right', 'code': 100 } * ]; * * _.keyBy(array, function(o) { * return String.fromCharCode(o.code); * }); * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } * * _.keyBy(array, 'dir'); * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } */ var keyBy = createAggregator(function(result, value, key) { baseAssignValue(result, key, value); }); module.exports = keyBy; },{"./_baseAssignValue":376,"./_createAggregator":423}],539:[function(require,module,exports){ var arrayLikeKeys = require('./_arrayLikeKeys'), baseKeys = require('./_baseKeys'), isArrayLike = require('./isArrayLike'); /** * Creates an array of the own enumerable property names of `object`. * * **Note:** Non-object values are coerced to objects. See the * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) * for more details. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property names. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.keys(new Foo); * // => ['a', 'b'] (iteration order is not guaranteed) * * _.keys('hi'); * // => ['0', '1'] */ function keys(object) { return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); } module.exports = keys; },{"./_arrayLikeKeys":369,"./_baseKeys":398,"./isArrayLike":528}],540:[function(require,module,exports){ var arrayMap = require('./_arrayMap'), baseIteratee = require('./_baseIteratee'), baseMap = require('./_baseMap'), isArray = require('./isArray'); /** * Creates an array of values by running each element in `collection` thru * `iteratee`. The iteratee is invoked with three arguments: * (value, index|key, collection). * * Many lodash methods are guarded to work as iteratees for methods like * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. * * The guarded methods are: * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, * `template`, `trim`, `trimEnd`, `trimStart`, and `words` * * @static * @memberOf _ * @since 0.1.0 * @category Collection * @param {Array|Object} collection The collection to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @returns {Array} Returns the new mapped array. * @example * * function square(n) { * return n * n; * } * * _.map([4, 8], square); * // => [16, 64] * * _.map({ 'a': 4, 'b': 8 }, square); * // => [16, 64] (iteration order is not guaranteed) * * var users = [ * { 'user': 'barney' }, * { 'user': 'fred' } * ]; * * // The `_.property` iteratee shorthand. * _.map(users, 'user'); * // => ['barney', 'fred'] */ function map(collection, iteratee) { var func = isArray(collection) ? arrayMap : baseMap; return func(collection, baseIteratee(iteratee, 3)); } module.exports = map; },{"./_arrayMap":370,"./_baseIteratee":397,"./_baseMap":400,"./isArray":527}],541:[function(require,module,exports){ var MapCache = require('./_MapCache'); /** Error message constants. */ var FUNC_ERROR_TEXT = 'Expected a function'; /** * Creates a function that memoizes the result of `func`. If `resolver` is * provided, it determines the cache key for storing the result based on the * arguments provided to the memoized function. By default, the first argument * provided to the memoized function is used as the map cache key. The `func` * is invoked with the `this` binding of the memoized function. * * **Note:** The cache is exposed as the `cache` property on the memoized * function. Its creation may be customized by replacing the `_.memoize.Cache` * constructor with one whose instances implement the * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object) * method interface of `clear`, `delete`, `get`, `has`, and `set`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to have its output memoized. * @param {Function} [resolver] The function to resolve the cache key. * @returns {Function} Returns the new memoized function. * @example * * var object = { 'a': 1, 'b': 2 }; * var other = { 'c': 3, 'd': 4 }; * * var values = _.memoize(_.values); * values(object); * // => [1, 2] * * values(other); * // => [3, 4] * * object.a = 2; * values(object); * // => [1, 2] * * // Modify the result cache. * values.cache.set(object, ['a', 'b']); * values(object); * // => ['a', 'b'] * * // Replace `_.memoize.Cache`. * _.memoize.Cache = WeakMap; */ function memoize(func, resolver) { if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) { throw new TypeError(FUNC_ERROR_TEXT); } var memoized = function() { var args = arguments, key = resolver ? resolver.apply(this, args) : args[0], cache = memoized.cache; if (cache.has(key)) { return cache.get(key); } var result = func.apply(this, args); memoized.cache = cache.set(key, result) || cache; return result; }; memoized.cache = new (memoize.Cache || MapCache); return memoized; } // Expose `MapCache`. memoize.Cache = MapCache; module.exports = memoize; },{"./_MapCache":355}],542:[function(require,module,exports){ /** * This method returns `undefined`. * * @static * @memberOf _ * @since 2.3.0 * @category Util * @example * * _.times(2, _.noop); * // => [undefined, undefined] */ function noop() { // No operation performed. } module.exports = noop; },{}],543:[function(require,module,exports){ var root = require('./_root'); /** * Gets the timestamp of the number of milliseconds that have elapsed since * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ * @since 2.4.0 * @category Date * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); * // => Logs the number of milliseconds it took for the deferred invocation. */ var now = function() { return root.Date.now(); }; module.exports = now; },{"./_root":494}],544:[function(require,module,exports){ var baseProperty = require('./_baseProperty'), basePropertyDeep = require('./_basePropertyDeep'), isKey = require('./_isKey'), toKey = require('./_toKey'); /** * Creates a function that returns the value at `path` of a given object. * * @static * @memberOf _ * @since 2.4.0 * @category Util * @param {Array|string} path The path of the property to get. * @returns {Function} Returns the new accessor function. * @example * * var objects = [ * { 'a': { 'b': 2 } }, * { 'a': { 'b': 1 } } * ]; * * _.map(objects, _.property('a.b')); * // => [2, 1] * * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); * // => [1, 2] */ function property(path) { return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); } module.exports = property; },{"./_baseProperty":403,"./_basePropertyDeep":404,"./_isKey":464,"./_toKey":509}],545:[function(require,module,exports){ /** * This method returns a new empty array. * * @static * @memberOf _ * @since 4.13.0 * @category Util * @returns {Array} Returns the new empty array. * @example * * var arrays = _.times(2, _.stubArray); * * console.log(arrays); * // => [[], []] * * console.log(arrays[0] === arrays[1]); * // => false */ function stubArray() { return []; } module.exports = stubArray; },{}],546:[function(require,module,exports){ /** * This method returns `false`. * * @static * @memberOf _ * @since 4.13.0 * @category Util * @returns {boolean} Returns `false`. * @example * * _.times(2, _.stubFalse); * // => [false, false] */ function stubFalse() { return false; } module.exports = stubFalse; },{}],547:[function(require,module,exports){ var toNumber = require('./toNumber'); /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0, MAX_INTEGER = 1.7976931348623157e+308; /** * Converts `value` to a finite number. * * @static * @memberOf _ * @since 4.12.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted number. * @example * * _.toFinite(3.2); * // => 3.2 * * _.toFinite(Number.MIN_VALUE); * // => 5e-324 * * _.toFinite(Infinity); * // => 1.7976931348623157e+308 * * _.toFinite('3.2'); * // => 3.2 */ function toFinite(value) { if (!value) { return value === 0 ? value : 0; } value = toNumber(value); if (value === INFINITY || value === -INFINITY) { var sign = (value < 0 ? -1 : 1); return sign * MAX_INTEGER; } return value === value ? value : 0; } module.exports = toFinite; },{"./toNumber":549}],548:[function(require,module,exports){ var toFinite = require('./toFinite'); /** * Converts `value` to an integer. * * **Note:** This method is loosely based on * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {number} Returns the converted integer. * @example * * _.toInteger(3.2); * // => 3 * * _.toInteger(Number.MIN_VALUE); * // => 0 * * _.toInteger(Infinity); * // => 1.7976931348623157e+308 * * _.toInteger('3.2'); * // => 3 */ function toInteger(value) { var result = toFinite(value), remainder = result % 1; return result === result ? (remainder ? result - remainder : result) : 0; } module.exports = toInteger; },{"./toFinite":547}],549:[function(require,module,exports){ var isObject = require('./isObject'), isSymbol = require('./isSymbol'); /** Used as references for various `Number` constants. */ var NAN = 0 / 0; /** Used to match leading and trailing whitespace. */ var reTrim = /^\s+|\s+$/g; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt; /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim, ''); var isBinary = reIsBinary.test(value); return (isBinary || reIsOctal.test(value)) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex.test(value) ? NAN : +value); } module.exports = toNumber; },{"./isObject":534,"./isSymbol":536}],550:[function(require,module,exports){ var baseToString = require('./_baseToString'); /** * Converts `value` to a string. An empty string is returned for `null` * and `undefined` values. The sign of `-0` is preserved. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {string} Returns the converted string. * @example * * _.toString(null); * // => '' * * _.toString(-0); * // => '-0' * * _.toString([1, 2, 3]); * // => '1,2,3' */ function toString(value) { return value == null ? '' : baseToString(value); } module.exports = toString; },{"./_baseToString":409}],551:[function(require,module,exports){ var arrayEach = require('./_arrayEach'), baseCreate = require('./_baseCreate'), baseForOwn = require('./_baseForOwn'), baseIteratee = require('./_baseIteratee'), getPrototype = require('./_getPrototype'), isArray = require('./isArray'), isBuffer = require('./isBuffer'), isFunction = require('./isFunction'), isObject = require('./isObject'), isTypedArray = require('./isTypedArray'); /** * An alternative to `_.reduce`; this method transforms `object` to a new * `accumulator` object which is the result of running each of its own * enumerable string keyed properties thru `iteratee`, with each invocation * potentially mutating the `accumulator` object. If `accumulator` is not * provided, a new object with the same `[[Prototype]]` will be used. The * iteratee is invoked with four arguments: (accumulator, value, key, object). * Iteratee functions may exit iteration early by explicitly returning `false`. * * @static * @memberOf _ * @since 1.3.0 * @category Object * @param {Object} object The object to iterate over. * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [accumulator] The custom accumulator value. * @returns {*} Returns the accumulated value. * @example * * _.transform([2, 3, 4], function(result, n) { * result.push(n *= n); * return n % 2 == 0; * }, []); * // => [4, 9] * * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { * (result[value] || (result[value] = [])).push(key); * }, {}); * // => { '1': ['a', 'c'], '2': ['b'] } */ function transform(object, iteratee, accumulator) { var isArr = isArray(object), isArrLike = isArr || isBuffer(object) || isTypedArray(object); iteratee = baseIteratee(iteratee, 4); if (accumulator == null) { var Ctor = object && object.constructor; if (isArrLike) { accumulator = isArr ? new Ctor : []; } else if (isObject(object)) { accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; } else { accumulator = {}; } } (isArrLike ? arrayEach : baseForOwn)(object, function(value, index, object) { return iteratee(accumulator, value, index, object); }); return accumulator; } module.exports = transform; },{"./_arrayEach":365,"./_baseCreate":377,"./_baseForOwn":384,"./_baseIteratee":397,"./_getPrototype":448,"./isArray":527,"./isBuffer":530,"./isFunction":532,"./isObject":534,"./isTypedArray":537}],552:[function(require,module,exports){ var baseValues = require('./_baseValues'), keys = require('./keys'); /** * Creates an array of the own enumerable string keyed property values of `object`. * * **Note:** Non-object values are coerced to objects. * * @static * @since 0.1.0 * @memberOf _ * @category Object * @param {Object} object The object to query. * @returns {Array} Returns the array of property values. * @example * * function Foo() { * this.a = 1; * this.b = 2; * } * * Foo.prototype.c = 3; * * _.values(new Foo); * // => [1, 2] (iteration order is not guaranteed) * * _.values('hi'); * // => ['h', 'i'] */ function values(object) { return object == null ? [] : baseValues(object, keys(object)); } module.exports = values; },{"./_baseValues":412,"./keys":539}],553:[function(require,module,exports){ var LazyWrapper = require('./_LazyWrapper'), LodashWrapper = require('./_LodashWrapper'), baseLodash = require('./_baseLodash'), isArray = require('./isArray'), isObjectLike = require('./isObjectLike'), wrapperClone = require('./_wrapperClone'); /** Used for built-in method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * Creates a `lodash` object which wraps `value` to enable implicit method * chain sequences. Methods that operate on and return arrays, collections, * and functions can be chained together. Methods that retrieve a single value * or may return a primitive value will automatically end the chain sequence * and return the unwrapped value. Otherwise, the value must be unwrapped * with `_#value`. * * Explicit chain sequences, which must be unwrapped with `_#value`, may be * enabled using `_.chain`. * * The execution of chained methods is lazy, that is, it's deferred until * `_#value` is implicitly or explicitly called. * * Lazy evaluation allows several methods to support shortcut fusion. * Shortcut fusion is an optimization to merge iteratee calls; this avoids * the creation of intermediate arrays and can greatly reduce the number of * iteratee executions. Sections of a chain sequence qualify for shortcut * fusion if the section is applied to an array and iteratees accept only * one argument. The heuristic for whether a section qualifies for shortcut * fusion is subject to change. * * Chaining is supported in custom builds as long as the `_#value` method is * directly or indirectly included in the build. * * In addition to lodash methods, wrappers have `Array` and `String` methods. * * The wrapper `Array` methods are: * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` * * The wrapper `String` methods are: * `replace` and `split` * * The wrapper methods that support shortcut fusion are: * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` * * The chainable wrapper methods are: * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, * `zipObject`, `zipObjectDeep`, and `zipWith` * * The wrapper methods that are **not** chainable by default are: * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, * `upperFirst`, `value`, and `words` * * @name _ * @constructor * @category Seq * @param {*} value The value to wrap in a `lodash` instance. * @returns {Object} Returns the new `lodash` wrapper instance. * @example * * function square(n) { * return n * n; * } * * var wrapped = _([1, 2, 3]); * * // Returns an unwrapped value. * wrapped.reduce(_.add); * // => 6 * * // Returns a wrapped value. * var squares = wrapped.map(square); * * _.isArray(squares); * // => false * * _.isArray(squares.value()); * // => true */ function lodash(value) { if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { if (value instanceof LodashWrapper) { return value; } if (hasOwnProperty.call(value, '__wrapped__')) { return wrapperClone(value); } } return new LodashWrapper(value); } // Ensure wrappers are instances of `baseLodash`. lodash.prototype = baseLodash.prototype; lodash.prototype.constructor = lodash; module.exports = lodash; },{"./_LazyWrapper":351,"./_LodashWrapper":353,"./_baseLodash":399,"./_wrapperClone":512,"./isArray":527,"./isObjectLike":535}],554:[function(require,module,exports){ var arrayFilter = require('./_arrayFilter'), baseRest = require('./_baseRest'), baseXor = require('./_baseXor'), isArrayLikeObject = require('./isArrayLikeObject'); /** * Creates an array of unique values that is the * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) * of the given arrays. The order of result values is determined by the order * they occur in the arrays. * * @static * @memberOf _ * @since 2.4.0 * @category Array * @param {...Array} [arrays] The arrays to inspect. * @returns {Array} Returns the new array of filtered values. * @see _.difference, _.without * @example * * _.xor([2, 1], [2, 3]); * // => [1, 3] */ var xor = baseRest(function(arrays) { return baseXor(arrayFilter(arrays, isArrayLikeObject)); }); module.exports = xor; },{"./_arrayFilter":366,"./_baseRest":405,"./_baseXor":413,"./isArrayLikeObject":529}],555:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.flatten = flatten; exports.find = find; exports.findIndex = findIndex; exports.filter = filter; exports.forEach = forEach; exports.without = without; exports.reduce = reduce; exports.every = every; exports.some = some; exports.map = map; exports.keys = keys; exports.size = size; exports.values = values; exports.groupBy = groupBy; exports.uniqueBy = uniqueBy; exports.sortBy = sortBy; exports.matchPattern = matchPattern; exports.debounce = debounce; exports.throttle = throttle; exports.bind = bind; exports.isUndefined = isUndefined; exports.isDefined = isDefined; exports.isNil = isNil; exports.isArray = isArray; exports.isObject = isObject; exports.isNumber = isNumber; exports.isFunction = isFunction; exports.isString = isString; exports.ensureArray = ensureArray; exports.has = has; exports.assign = assign; exports.pick = pick; exports.omit = omit; exports.merge = merge; exports.unionBy = void 0; /** * Flatten array, one level deep. * * @param {Array<?>} arr * * @return {Array<?>} */ function flatten(arr) { return Array.prototype.concat.apply([], arr); } var nativeToString = Object.prototype.toString; var nativeHasOwnProperty = Object.prototype.hasOwnProperty; function isUndefined(obj) { return obj === undefined; } function isDefined(obj) { return obj !== undefined; } function isNil(obj) { return obj == null; } function isArray(obj) { return nativeToString.call(obj) === '[object Array]'; } function isObject(obj) { return nativeToString.call(obj) === '[object Object]'; } function isNumber(obj) { return nativeToString.call(obj) === '[object Number]'; } function isFunction(obj) { var tag = nativeToString.call(obj); return tag === '[object Function]' || tag === '[object AsyncFunction]' || tag === '[object GeneratorFunction]' || tag === '[object AsyncGeneratorFunction]' || tag === '[object Proxy]'; } function isString(obj) { return nativeToString.call(obj) === '[object String]'; } /** * Ensure collection is an array. * * @param {Object} obj */ function ensureArray(obj) { if (isArray(obj)) { return; } throw new Error('must supply array'); } /** * Return true, if target owns a property with the given key. * * @param {Object} target * @param {String} key * * @return {Boolean} */ function has(target, key) { return nativeHasOwnProperty.call(target, key); } /** * Find element in collection. * * @param {Array|Object} collection * @param {Function|Object} matcher * * @return {Object} */ function find(collection, matcher) { matcher = toMatcher(matcher); var match; forEach(collection, function (val, key) { if (matcher(val, key)) { match = val; return false; } }); return match; } /** * Find element index in collection. * * @param {Array|Object} collection * @param {Function} matcher * * @return {Object} */ function findIndex(collection, matcher) { matcher = toMatcher(matcher); var idx = isArray(collection) ? -1 : undefined; forEach(collection, function (val, key) { if (matcher(val, key)) { idx = key; return false; } }); return idx; } /** * Find element in collection. * * @param {Array|Object} collection * @param {Function} matcher * * @return {Array} result */ function filter(collection, matcher) { var result = []; forEach(collection, function (val, key) { if (matcher(val, key)) { result.push(val); } }); return result; } /** * Iterate over collection; returning something * (non-undefined) will stop iteration. * * @param {Array|Object} collection * @param {Function} iterator * * @return {Object} return result that stopped the iteration */ function forEach(collection, iterator) { var val, result; if (isUndefined(collection)) { return; } var convertKey = isArray(collection) ? toNum : identity; for (var key in collection) { if (has(collection, key)) { val = collection[key]; result = iterator(val, convertKey(key)); if (result === false) { return val; } } } } /** * Return collection without element. * * @param {Array} arr * @param {Function} matcher * * @return {Array} */ function without(arr, matcher) { if (isUndefined(arr)) { return []; } ensureArray(arr); matcher = toMatcher(matcher); return arr.filter(function (el, idx) { return !matcher(el, idx); }); } /** * Reduce collection, returning a single result. * * @param {Object|Array} collection * @param {Function} iterator * @param {Any} result * * @return {Any} result returned from last iterator */ function reduce(collection, iterator, result) { forEach(collection, function (value, idx) { result = iterator(result, value, idx); }); return result; } /** * Return true if every element in the collection * matches the criteria. * * @param {Object|Array} collection * @param {Function} matcher * * @return {Boolean} */ function every(collection, matcher) { return !!reduce(collection, function (matches, val, key) { return matches && matcher(val, key); }, true); } /** * Return true if some elements in the collection * match the criteria. * * @param {Object|Array} collection * @param {Function} matcher * * @return {Boolean} */ function some(collection, matcher) { return !!find(collection, matcher); } /** * Transform a collection into another collection * by piping each member through the given fn. * * @param {Object|Array} collection * @param {Function} fn * * @return {Array} transformed collection */ function map(collection, fn) { var result = []; forEach(collection, function (val, key) { result.push(fn(val, key)); }); return result; } /** * Get the collections keys. * * @param {Object|Array} collection * * @return {Array} */ function keys(collection) { return collection && Object.keys(collection) || []; } /** * Shorthand for `keys(o).length`. * * @param {Object|Array} collection * * @return {Number} */ function size(collection) { return keys(collection).length; } /** * Get the values in the collection. * * @param {Object|Array} collection * * @return {Array} */ function values(collection) { return map(collection, function (val) { return val; }); } /** * Group collection members by attribute. * * @param {Object|Array} collection * @param {Function} extractor * * @return {Object} map with { attrValue => [ a, b, c ] } */ function groupBy(collection, extractor) { var grouped = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; extractor = toExtractor(extractor); forEach(collection, function (val) { var discriminator = extractor(val) || '_'; var group = grouped[discriminator]; if (!group) { group = grouped[discriminator] = []; } group.push(val); }); return grouped; } function uniqueBy(extractor) { extractor = toExtractor(extractor); var grouped = {}; for (var _len = arguments.length, collections = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { collections[_key - 1] = arguments[_key]; } forEach(collections, function (c) { return groupBy(c, extractor, grouped); }); var result = map(grouped, function (val, key) { return val[0]; }); return result; } var unionBy = uniqueBy; /** * Sort collection by criteria. * * @param {Object|Array} collection * @param {String|Function} extractor * * @return {Array} */ exports.unionBy = unionBy; function sortBy(collection, extractor) { extractor = toExtractor(extractor); var sorted = []; forEach(collection, function (value, key) { var disc = extractor(value, key); var entry = { d: disc, v: value }; for (var idx = 0; idx < sorted.length; idx++) { var d = sorted[idx].d; if (disc < d) { sorted.splice(idx, 0, entry); return; } } // not inserted, append (!) sorted.push(entry); }); return map(sorted, function (e) { return e.v; }); } /** * Create an object pattern matcher. * * @example * * const matcher = matchPattern({ id: 1 }); * * var element = find(elements, matcher); * * @param {Object} pattern * * @return {Function} matcherFn */ function matchPattern(pattern) { return function (el) { return every(pattern, function (val, key) { return el[key] === val; }); }; } function toExtractor(extractor) { return isFunction(extractor) ? extractor : function (e) { return e[extractor]; }; } function toMatcher(matcher) { return isFunction(matcher) ? matcher : function (e) { return e === matcher; }; } function identity(arg) { return arg; } function toNum(arg) { return Number(arg); } /** * Debounce fn, calling it only once if * the given time elapsed between calls. * * @param {Function} fn * @param {Number} timeout * * @return {Function} debounced function */ function debounce(fn, timeout) { var timer; var lastArgs; var lastThis; var lastNow; function fire() { var now = Date.now(); var scheduledDiff = lastNow + timeout - now; if (scheduledDiff > 0) { return schedule(scheduledDiff); } fn.apply(lastThis, lastArgs); timer = lastNow = lastArgs = lastThis = undefined; } function schedule(timeout) { timer = setTimeout(fire, timeout); } return function () { lastNow = Date.now(); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } lastArgs = args; lastThis = this; // ensure an execution is scheduled if (!timer) { schedule(timeout); } }; } /** * Throttle fn, calling at most once * in the given interval. * * @param {Function} fn * @param {Number} interval * * @return {Function} throttled function */ function throttle(fn, interval) { var throttling = false; return function () { if (throttling) { return; } fn.apply(void 0, arguments); throttling = true; setTimeout(function () { throttling = false; }, interval); }; } /** * Bind function against target <this>. * * @param {Function} fn * @param {Object} target * * @return {Function} bound function */ function bind(fn, target) { return fn.bind(target); } function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } /** * Convenience wrapper for `Object.assign`. * * @param {Object} target * @param {...Object} others * * @return {Object} the target */ function assign(target) { for (var _len = arguments.length, others = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { others[_key - 1] = arguments[_key]; } return _extends.apply(void 0, [target].concat(others)); } /** * Pick given properties from the target object. * * @param {Object} target * @param {Array} properties * * @return {Object} target */ function pick(target, properties) { var result = {}; var obj = Object(target); forEach(properties, function (prop) { if (prop in obj) { result[prop] = target[prop]; } }); return result; } /** * Pick all target properties, excluding the given ones. * * @param {Object} target * @param {Array} properties * * @return {Object} target */ function omit(target, properties) { var result = {}; var obj = Object(target); forEach(obj, function (prop, key) { if (properties.indexOf(key) === -1) { result[key] = prop; } }); return result; } /** * Recursively merge `...sources` into given target. * * Does support merging objects; does not support merging arrays. * * @param {Object} target * @param {...Object} sources * * @return {Object} the target */ function merge(target) { for (var _len2 = arguments.length, sources = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { sources[_key2 - 1] = arguments[_key2]; } if (!sources.length) { return target; } forEach(sources, function (source) { // skip non-obj sources, i.e. null if (!source || !isObject(source)) { return; } forEach(source, function (sourceVal, key) { if (key === '__proto__') { return; } var targetVal = target[key]; if (isObject(sourceVal)) { if (!isObject(targetVal)) { // override target[key] with object targetVal = {}; } target[key] = merge(targetVal, sourceVal); } else { target[key] = sourceVal; } }); }); return target; } },{}],556:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.attr = attr; exports.classes = classes; exports.clear = clear; exports.closest = closest; exports.query = query; exports.queryAll = all; exports.remove = remove; exports.matches = exports.event = exports.domify = exports.delegate = void 0; /** * Set attribute `name` to `val`, or get attr `name`. * * @param {Element} el * @param {String} name * @param {String} [val] * @api public */ function attr(el, name, val) { // get if (arguments.length == 2) { return el.getAttribute(name); } // remove if (val === null) { return el.removeAttribute(name); } // set el.setAttribute(name, val); return el; } var indexOf = [].indexOf; var indexof = function (arr, obj) { if (indexOf) return arr.indexOf(obj); for (var i = 0; i < arr.length; ++i) { if (arr[i] === obj) return i; } return -1; }; /** * Taken from https://github.com/component/classes * * Without the component bits. */ /** * Whitespace regexp. */ var re = /\s+/; /** * toString reference. */ var toString = Object.prototype.toString; /** * Wrap `el` in a `ClassList`. * * @param {Element} el * @return {ClassList} * @api public */ function classes(el) { return new ClassList(el); } /** * Initialize a new ClassList for `el`. * * @param {Element} el * @api private */ function ClassList(el) { if (!el || !el.nodeType) { throw new Error('A DOM element reference is required'); } this.el = el; this.list = el.classList; } /** * Add class `name` if not already present. * * @param {String} name * @return {ClassList} * @api public */ ClassList.prototype.add = function (name) { // classList if (this.list) { this.list.add(name); return this; } // fallback var arr = this.array(); var i = indexof(arr, name); if (!~i) arr.push(name); this.el.className = arr.join(' '); return this; }; /** * Remove class `name` when present, or * pass a regular expression to remove * any which match. * * @param {String|RegExp} name * @return {ClassList} * @api public */ ClassList.prototype.remove = function (name) { if ('[object RegExp]' == toString.call(name)) { return this.removeMatching(name); } // classList if (this.list) { this.list.remove(name); return this; } // fallback var arr = this.array(); var i = indexof(arr, name); if (~i) arr.splice(i, 1); this.el.className = arr.join(' '); return this; }; /** * Remove all classes matching `re`. * * @param {RegExp} re * @return {ClassList} * @api private */ ClassList.prototype.removeMatching = function (re) { var arr = this.array(); for (var i = 0; i < arr.length; i++) { if (re.test(arr[i])) { this.remove(arr[i]); } } return this; }; /** * Toggle class `name`, can force state via `force`. * * For browsers that support classList, but do not support `force` yet, * the mistake will be detected and corrected. * * @param {String} name * @param {Boolean} force * @return {ClassList} * @api public */ ClassList.prototype.toggle = function (name, force) { // classList if (this.list) { if ('undefined' !== typeof force) { if (force !== this.list.toggle(name, force)) { this.list.toggle(name); // toggle again to correct } } else { this.list.toggle(name); } return this; } // fallback if ('undefined' !== typeof force) { if (!force) { this.remove(name); } else { this.add(name); } } else { if (this.has(name)) { this.remove(name); } else { this.add(name); } } return this; }; /** * Return an array of classes. * * @return {Array} * @api public */ ClassList.prototype.array = function () { var className = this.el.getAttribute('class') || ''; var str = className.replace(/^\s+|\s+$/g, ''); var arr = str.split(re); if ('' === arr[0]) arr.shift(); return arr; }; /** * Check if class `name` is present. * * @param {String} name * @return {ClassList} * @api public */ ClassList.prototype.has = ClassList.prototype.contains = function (name) { return this.list ? this.list.contains(name) : !!~indexof(this.array(), name); }; /** * Remove all children from the given element. */ function clear(el) { var c; while (el.childNodes.length) { c = el.childNodes[0]; el.removeChild(c); } return el; } var proto = typeof Element !== 'undefined' ? Element.prototype : {}; var vendor = proto.matches || proto.matchesSelector || proto.webkitMatchesSelector || proto.mozMatchesSelector || proto.msMatchesSelector || proto.oMatchesSelector; var matchesSelector = match; /** * Match `el` to `selector`. * * @param {Element} el * @param {String} selector * @return {Boolean} * @api public */ exports.matches = matchesSelector; function match(el, selector) { if (!el || el.nodeType !== 1) return false; if (vendor) return vendor.call(el, selector); var nodes = el.parentNode.querySelectorAll(selector); for (var i = 0; i < nodes.length; i++) { if (nodes[i] == el) return true; } return false; } /** * Closest * * @param {Element} el * @param {String} selector * @param {Boolean} checkYourSelf (optional) */ function closest(element, selector, checkYourSelf) { var currentElem = checkYourSelf ? element : element.parentNode; while (currentElem && currentElem.nodeType !== document.DOCUMENT_NODE && currentElem.nodeType !== document.DOCUMENT_FRAGMENT_NODE) { if (matchesSelector(currentElem, selector)) { return currentElem; } currentElem = currentElem.parentNode; } return matchesSelector(currentElem, selector) ? currentElem : null; } var bind = window.addEventListener ? 'addEventListener' : 'attachEvent', unbind = window.removeEventListener ? 'removeEventListener' : 'detachEvent', prefix = bind !== 'addEventListener' ? 'on' : ''; /** * Bind `el` event `type` to `fn`. * * @param {Element} el * @param {String} type * @param {Function} fn * @param {Boolean} capture * @return {Function} * @api public */ var bind_1 = function (el, type, fn, capture) { el[bind](prefix + type, fn, capture || false); return fn; }; /** * Unbind `el` event `type`'s callback `fn`. * * @param {Element} el * @param {String} type * @param {Function} fn * @param {Boolean} capture * @return {Function} * @api public */ var unbind_1 = function (el, type, fn, capture) { el[unbind](prefix + type, fn, capture || false); return fn; }; var componentEvent = { bind: bind_1, unbind: unbind_1 }; /** * Module dependencies. */ /** * Delegate event `type` to `selector` * and invoke `fn(e)`. A callback function * is returned which may be passed to `.unbind()`. * * @param {Element} el * @param {String} selector * @param {String} type * @param {Function} fn * @param {Boolean} capture * @return {Function} * @api public */ // Some events don't bubble, so we want to bind to the capture phase instead // when delegating. exports.event = componentEvent; var forceCaptureEvents = ['focus', 'blur']; function bind$1(el, selector, type, fn, capture) { if (forceCaptureEvents.indexOf(type) !== -1) { capture = true; } return componentEvent.bind(el, type, function (e) { var target = e.target || e.srcElement; e.delegateTarget = closest(target, selector, true, el); if (e.delegateTarget) { fn.call(el, e); } }, capture); } /** * Unbind event `type`'s callback `fn`. * * @param {Element} el * @param {String} type * @param {Function} fn * @param {Boolean} capture * @api public */ function unbind$1(el, type, fn, capture) { if (forceCaptureEvents.indexOf(type) !== -1) { capture = true; } return componentEvent.unbind(el, type, fn, capture); } var delegate = { bind: bind$1, unbind: unbind$1 }; /** * Expose `parse`. */ exports.delegate = delegate; var domify = parse; /** * Tests for browser support. */ exports.domify = domify; var innerHTMLBug = false; var bugTestDiv; if (typeof document !== 'undefined') { bugTestDiv = document.createElement('div'); // Setup bugTestDiv.innerHTML = ' <link/><table></table><a href="/a">a</a><input type="checkbox"/>'; // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE innerHTMLBug = !bugTestDiv.getElementsByTagName('link').length; bugTestDiv = undefined; } /** * Wrap map from jquery. */ var map = { legend: [1, '<fieldset>', '</fieldset>'], tr: [2, '<table><tbody>', '</tbody></table>'], col: [2, '<table><tbody></tbody><colgroup>', '</colgroup></table>'], // for script/link/style tags to work in IE6-8, you have to wrap // in a div with a non-whitespace character in front, ha! _default: innerHTMLBug ? [1, 'X<div>', '</div>'] : [0, '', ''] }; map.td = map.th = [3, '<table><tbody><tr>', '</tr></tbody></table>']; map.option = map.optgroup = [1, '<select multiple="multiple">', '</select>']; map.thead = map.tbody = map.colgroup = map.caption = map.tfoot = [1, '<table>', '</table>']; map.polyline = map.ellipse = map.polygon = map.circle = map.text = map.line = map.path = map.rect = map.g = [1, '<svg xmlns="http://www.w3.org/2000/svg" version="1.1">', '</svg>']; /** * Parse `html` and return a DOM Node instance, which could be a TextNode, * HTML DOM Node of some kind (<div> for example), or a DocumentFragment * instance, depending on the contents of the `html` string. * * @param {String} html - HTML string to "domify" * @param {Document} doc - The `document` instance to create the Node for * @return {DOMNode} the TextNode, DOM Node, or DocumentFragment instance * @api private */ function parse(html, doc) { if ('string' != typeof html) throw new TypeError('String expected'); // default to the global `document` object if (!doc) doc = document; // tag name var m = /<([\w:]+)/.exec(html); if (!m) return doc.createTextNode(html); html = html.replace(/^\s+|\s+$/g, ''); // Remove leading/trailing whitespace var tag = m[1]; // body support if (tag == 'body') { var el = doc.createElement('html'); el.innerHTML = html; return el.removeChild(el.lastChild); } // wrap map var wrap = map[tag] || map._default; var depth = wrap[0]; var prefix = wrap[1]; var suffix = wrap[2]; var el = doc.createElement('div'); el.innerHTML = prefix + html + suffix; while (depth--) el = el.lastChild; // one element if (el.firstChild == el.lastChild) { return el.removeChild(el.firstChild); } // several elements var fragment = doc.createDocumentFragment(); while (el.firstChild) { fragment.appendChild(el.removeChild(el.firstChild)); } return fragment; } function query(selector, el) { el = el || document; return el.querySelector(selector); } function all(selector, el) { el = el || document; return el.querySelectorAll(selector); } function remove(el) { el.parentNode && el.parentNode.removeChild(el); } },{}],557:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; // // An event handler can take an optional event argument // and should not return a value // An array of all currently registered event handlers for a type // A map of event types and their corresponding event handlers. /** Mitt: Tiny (~200b) functional event emitter / pubsub. * @name mitt * @returns {Mitt} */ function mitt(all) { all = all || Object.create(null); return { /** * Register an event handler for the given type. * * @param {String} type Type of event to listen for, or `"*"` for all events * @param {Function} handler Function to call in response to given event * @memberOf mitt */ on: function on(type, handler) { (all[type] || (all[type] = [])).push(handler); }, /** * Remove an event handler for the given type. * * @param {String} type Type of event to unregister `handler` from, or `"*"` * @param {Function} handler Handler function to remove * @memberOf mitt */ off: function off(type, handler) { if (all[type]) { all[type].splice(all[type].indexOf(handler) >>> 0, 1); } }, /** * Invoke all handlers for the given type. * If present, `"*"` handlers are invoked after type-matched handlers. * * @param {String} type The event type to invoke * @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler * @memberOf mitt */ emit: function emit(type, evt) { (all[type] || []).slice().map(function (handler) { handler(evt); }); (all['*'] || []).slice().map(function (handler) { handler(type, evt); }); } }; } var _default = mitt; exports.default = _default; },{}],558:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Reader = Reader; exports.Writer = Writer; var _minDash = require("min-dash"); var _saxen = require("saxen"); var _moddle = require("moddle"); function hasLowerCaseAlias(pkg) { return pkg.xml && pkg.xml.tagAlias === 'lowerCase'; } var DEFAULT_NS_MAP = { 'xsi': 'http://www.w3.org/2001/XMLSchema-instance', 'xml': 'http://www.w3.org/XML/1998/namespace' }; var XSI_TYPE = 'xsi:type'; function serializeFormat(element) { return element.xml && element.xml.serialize; } function serializeAsType(element) { return serializeFormat(element) === XSI_TYPE; } function serializeAsProperty(element) { return serializeFormat(element) === 'property'; } function capitalize(str) { return str.charAt(0).toUpperCase() + str.slice(1); } function aliasToName(aliasNs, pkg) { if (!hasLowerCaseAlias(pkg)) { return aliasNs.name; } return aliasNs.prefix + ':' + capitalize(aliasNs.localName); } function prefixedToName(nameNs, pkg) { var name = nameNs.name, localName = nameNs.localName; var typePrefix = pkg.xml && pkg.xml.typePrefix; if (typePrefix && localName.indexOf(typePrefix) === 0) { return nameNs.prefix + ':' + localName.slice(typePrefix.length); } else { return name; } } function normalizeXsiTypeName(name, model) { var nameNs = (0, _moddle.parseNameNS)(name); var pkg = model.getPackage(nameNs.prefix); return prefixedToName(nameNs, pkg); } function error(message) { return new Error(message); } /** * Get the moddle descriptor for a given instance or type. * * @param {ModdleElement|Function} element * * @return {Object} the moddle descriptor */ function getModdleDescriptor(element) { return element.$descriptor; } /** * A parse context. * * @class * * @param {Object} options * @param {ElementHandler} options.rootHandler the root handler for parsing a document * @param {boolean} [options.lax=false] whether or not to ignore invalid elements */ function Context(options) { /** * @property {ElementHandler} rootHandler */ /** * @property {Boolean} lax */ (0, _minDash.assign)(this, options); this.elementsById = {}; this.references = []; this.warnings = []; /** * Add an unresolved reference. * * @param {Object} reference */ this.addReference = function (reference) { this.references.push(reference); }; /** * Add a processed element. * * @param {ModdleElement} element */ this.addElement = function (element) { if (!element) { throw error('expected element'); } var elementsById = this.elementsById; var descriptor = getModdleDescriptor(element); var idProperty = descriptor.idProperty, id; if (idProperty) { id = element.get(idProperty.name); if (id) { // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar if (!/^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i.test(id)) { throw new Error('illegal ID <' + id + '>'); } if (elementsById[id]) { throw error('duplicate ID <' + id + '>'); } elementsById[id] = element; } } }; /** * Add an import warning. * * @param {Object} warning * @param {String} warning.message * @param {Error} [warning.error] */ this.addWarning = function (warning) { this.warnings.push(warning); }; } function BaseHandler() {} BaseHandler.prototype.handleEnd = function () {}; BaseHandler.prototype.handleText = function () {}; BaseHandler.prototype.handleNode = function () {}; /** * A simple pass through handler that does nothing except for * ignoring all input it receives. * * This is used to ignore unknown elements and * attributes. */ function NoopHandler() {} NoopHandler.prototype = Object.create(BaseHandler.prototype); NoopHandler.prototype.handleNode = function () { return this; }; function BodyHandler() {} BodyHandler.prototype = Object.create(BaseHandler.prototype); BodyHandler.prototype.handleText = function (text) { this.body = (this.body || '') + text; }; function ReferenceHandler(property, context) { this.property = property; this.context = context; } ReferenceHandler.prototype = Object.create(BodyHandler.prototype); ReferenceHandler.prototype.handleNode = function (node) { if (this.element) { throw error('expected no sub nodes'); } else { this.element = this.createReference(node); } return this; }; ReferenceHandler.prototype.handleEnd = function () { this.element.id = this.body; }; ReferenceHandler.prototype.createReference = function (node) { return { property: this.property.ns.name, id: '' }; }; function ValueHandler(propertyDesc, element) { this.element = element; this.propertyDesc = propertyDesc; } ValueHandler.prototype = Object.create(BodyHandler.prototype); ValueHandler.prototype.handleEnd = function () { var value = this.body || '', element = this.element, propertyDesc = this.propertyDesc; value = (0, _moddle.coerceType)(propertyDesc.type, value); if (propertyDesc.isMany) { element.get(propertyDesc.name).push(value); } else { element.set(propertyDesc.name, value); } }; function BaseElementHandler() {} BaseElementHandler.prototype = Object.create(BodyHandler.prototype); BaseElementHandler.prototype.handleNode = function (node) { var parser = this, element = this.element; if (!element) { element = this.element = this.createElement(node); this.context.addElement(element); } else { parser = this.handleChild(node); } return parser; }; /** * @class Reader.ElementHandler * */ function ElementHandler(model, typeName, context) { this.model = model; this.type = model.getType(typeName); this.context = context; } ElementHandler.prototype = Object.create(BaseElementHandler.prototype); ElementHandler.prototype.addReference = function (reference) { this.context.addReference(reference); }; ElementHandler.prototype.handleText = function (text) { var element = this.element, descriptor = getModdleDescriptor(element), bodyProperty = descriptor.bodyProperty; if (!bodyProperty) { throw error('unexpected body text <' + text + '>'); } BodyHandler.prototype.handleText.call(this, text); }; ElementHandler.prototype.handleEnd = function () { var value = this.body, element = this.element, descriptor = getModdleDescriptor(element), bodyProperty = descriptor.bodyProperty; if (bodyProperty && value !== undefined) { value = (0, _moddle.coerceType)(bodyProperty.type, value); element.set(bodyProperty.name, value); } }; /** * Create an instance of the model from the given node. * * @param {Element} node the xml node */ ElementHandler.prototype.createElement = function (node) { var attributes = node.attributes, Type = this.type, descriptor = getModdleDescriptor(Type), context = this.context, instance = new Type({}), model = this.model, propNameNs; (0, _minDash.forEach)(attributes, function (value, name) { var prop = descriptor.propertiesByName[name], values; if (prop && prop.isReference) { if (!prop.isMany) { context.addReference({ element: instance, property: prop.ns.name, id: value }); } else { // IDREFS: parse references as whitespace-separated list values = value.split(' '); (0, _minDash.forEach)(values, function (v) { context.addReference({ element: instance, property: prop.ns.name, id: v }); }); } } else { if (prop) { value = (0, _moddle.coerceType)(prop.type, value); } else if (name !== 'xmlns') { propNameNs = (0, _moddle.parseNameNS)(name, descriptor.ns.prefix); // check whether attribute is defined in a well-known namespace // if that is the case we emit a warning to indicate potential misuse if (model.getPackage(propNameNs.prefix)) { context.addWarning({ message: 'unknown attribute <' + name + '>', element: instance, property: name, value: value }); } } instance.set(name, value); } }); return instance; }; ElementHandler.prototype.getPropertyForNode = function (node) { var name = node.name; var nameNs = (0, _moddle.parseNameNS)(name); var type = this.type, model = this.model, descriptor = getModdleDescriptor(type); var propertyName = nameNs.name, property = descriptor.propertiesByName[propertyName], elementTypeName, elementType; // search for properties by name first if (property && !property.isAttr) { if (serializeAsType(property)) { elementTypeName = node.attributes[XSI_TYPE]; // xsi type is optional, if it does not exists the // default type is assumed if (elementTypeName) { // take possible type prefixes from XML // into account, i.e.: xsi:type="t{ActualType}" elementTypeName = normalizeXsiTypeName(elementTypeName, model); elementType = model.getType(elementTypeName); return (0, _minDash.assign)({}, property, { effectiveType: getModdleDescriptor(elementType).name }); } } // search for properties by name first return property; } var pkg = model.getPackage(nameNs.prefix); if (pkg) { elementTypeName = aliasToName(nameNs, pkg); elementType = model.getType(elementTypeName); // search for collection members later property = (0, _minDash.find)(descriptor.properties, function (p) { return !p.isVirtual && !p.isReference && !p.isAttribute && elementType.hasType(p.type); }); if (property) { return (0, _minDash.assign)({}, property, { effectiveType: getModdleDescriptor(elementType).name }); } } else { // parse unknown element (maybe extension) property = (0, _minDash.find)(descriptor.properties, function (p) { return !p.isReference && !p.isAttribute && p.type === 'Element'; }); if (property) { return property; } } throw error('unrecognized element <' + nameNs.name + '>'); }; ElementHandler.prototype.toString = function () { return 'ElementDescriptor[' + getModdleDescriptor(this.type).name + ']'; }; ElementHandler.prototype.valueHandler = function (propertyDesc, element) { return new ValueHandler(propertyDesc, element); }; ElementHandler.prototype.referenceHandler = function (propertyDesc) { return new ReferenceHandler(propertyDesc, this.context); }; ElementHandler.prototype.handler = function (type) { if (type === 'Element') { return new GenericElementHandler(this.model, type, this.context); } else { return new ElementHandler(this.model, type, this.context); } }; /** * Handle the child element parsing * * @param {Element} node the xml node */ ElementHandler.prototype.handleChild = function (node) { var propertyDesc, type, element, childHandler; propertyDesc = this.getPropertyForNode(node); element = this.element; type = propertyDesc.effectiveType || propertyDesc.type; if ((0, _moddle.isSimpleType)(type)) { return this.valueHandler(propertyDesc, element); } if (propertyDesc.isReference) { childHandler = this.referenceHandler(propertyDesc).handleNode(node); } else { childHandler = this.handler(type).handleNode(node); } var newElement = childHandler.element; // child handles may decide to skip elements // by not returning anything if (newElement !== undefined) { if (propertyDesc.isMany) { element.get(propertyDesc.name).push(newElement); } else { element.set(propertyDesc.name, newElement); } if (propertyDesc.isReference) { (0, _minDash.assign)(newElement, { element: element }); this.context.addReference(newElement); } else { // establish child -> parent relationship newElement.$parent = element; } } return childHandler; }; /** * An element handler that performs special validation * to ensure the node it gets initialized with matches * the handlers type (namespace wise). * * @param {Moddle} model * @param {String} typeName * @param {Context} context */ function RootElementHandler(model, typeName, context) { ElementHandler.call(this, model, typeName, context); } RootElementHandler.prototype = Object.create(ElementHandler.prototype); RootElementHandler.prototype.createElement = function (node) { var name = node.name, nameNs = (0, _moddle.parseNameNS)(name), model = this.model, type = this.type, pkg = model.getPackage(nameNs.prefix), typeName = pkg && aliasToName(nameNs, pkg) || name; // verify the correct namespace if we parse // the first element in the handler tree // // this ensures we don't mistakenly import wrong namespace elements if (!type.hasType(typeName)) { throw error('unexpected element <' + node.originalName + '>'); } return ElementHandler.prototype.createElement.call(this, node); }; function GenericElementHandler(model, typeName, context) { this.model = model; this.context = context; } GenericElementHandler.prototype = Object.create(BaseElementHandler.prototype); GenericElementHandler.prototype.createElement = function (node) { var name = node.name, ns = (0, _moddle.parseNameNS)(name), prefix = ns.prefix, uri = node.ns[prefix + '$uri'], attributes = node.attributes; return this.model.createAny(name, uri, attributes); }; GenericElementHandler.prototype.handleChild = function (node) { var handler = new GenericElementHandler(this.model, 'Element', this.context).handleNode(node), element = this.element; var newElement = handler.element, children; if (newElement !== undefined) { children = element.$children = element.$children || []; children.push(newElement); // establish child -> parent relationship newElement.$parent = element; } return handler; }; GenericElementHandler.prototype.handleEnd = function () { if (this.body) { this.element.$body = this.body; } }; /** * A reader for a meta-model * * @param {Object} options * @param {Model} options.model used to read xml files * @param {Boolean} options.lax whether to make parse errors warnings */ function Reader(options) { if (options instanceof _moddle.Moddle) { options = { model: options }; } (0, _minDash.assign)(this, { lax: false }, options); } /** * The fromXML result. * * @typedef {Object} ParseResult * * @property {ModdleElement} rootElement * @property {Array<Object>} references * @property {Array<Error>} warnings * @property {Object} elementsById - a mapping containing each ID -> ModdleElement */ /** * The fromXML result. * * @typedef {Error} ParseError * * @property {Array<Error>} warnings */ /** * Parse the given XML into a moddle document tree. * * @param {String} xml * @param {ElementHandler|Object} options or rootHandler * * @returns {Promise<ParseResult, ParseError>} */ Reader.prototype.fromXML = function (xml, options, done) { var rootHandler = options.rootHandler; if (options instanceof ElementHandler) { // root handler passed via (xml, { rootHandler: ElementHandler }, ...) rootHandler = options; options = {}; } else { if (typeof options === 'string') { // rootHandler passed via (xml, 'someString', ...) rootHandler = this.handler(options); options = {}; } else if (typeof rootHandler === 'string') { // rootHandler passed via (xml, { rootHandler: 'someString' }, ...) rootHandler = this.handler(rootHandler); } } var model = this.model, lax = this.lax; var context = new Context((0, _minDash.assign)({}, options, { rootHandler: rootHandler })), parser = new _saxen.Parser({ proxy: true }), stack = createStack(); rootHandler.context = context; // push root handler stack.push(rootHandler); /** * Handle error. * * @param {Error} err * @param {Function} getContext * @param {boolean} lax * * @return {boolean} true if handled */ function handleError(err, getContext, lax) { var ctx = getContext(); var line = ctx.line, column = ctx.column, data = ctx.data; // we receive the full context data here, // for elements trim down the information // to the tag name, only if (data.charAt(0) === '<' && data.indexOf(' ') !== -1) { data = data.slice(0, data.indexOf(' ')) + '>'; } var message = 'unparsable content ' + (data ? data + ' ' : '') + 'detected\n\t' + 'line: ' + line + '\n\t' + 'column: ' + column + '\n\t' + 'nested error: ' + err.message; if (lax) { context.addWarning({ message: message, error: err }); return true; } else { throw error(message); } } function handleWarning(err, getContext) { // just like handling errors in <lax=true> mode return handleError(err, getContext, true); } /** * Resolve collected references on parse end. */ function resolveReferences() { var elementsById = context.elementsById; var references = context.references; var i, r; for (i = 0; r = references[i]; i++) { var element = r.element; var reference = elementsById[r.id]; var property = getModdleDescriptor(element).propertiesByName[r.property]; if (!reference) { context.addWarning({ message: 'unresolved reference <' + r.id + '>', element: r.element, property: r.property, value: r.id }); } if (property.isMany) { var collection = element.get(property.name), idx = collection.indexOf(r); // we replace an existing place holder (idx != -1) or // append to the collection instead if (idx === -1) { idx = collection.length; } if (!reference) { // remove unresolvable reference collection.splice(idx, 1); } else { // add or update reference in collection collection[idx] = reference; } } else { element.set(property.name, reference); } } } function handleClose() { stack.pop().handleEnd(); } var PREAMBLE_START_PATTERN = /^<\?xml /i; var ENCODING_PATTERN = / encoding="([^"]+)"/i; var UTF_8_PATTERN = /^utf-8$/i; function handleQuestion(question) { if (!PREAMBLE_START_PATTERN.test(question)) { return; } var match = ENCODING_PATTERN.exec(question); var encoding = match && match[1]; if (!encoding || UTF_8_PATTERN.test(encoding)) { return; } context.addWarning({ message: 'unsupported document encoding <' + encoding + '>, ' + 'falling back to UTF-8' }); } function handleOpen(node, getContext) { var handler = stack.peek(); try { stack.push(handler.handleNode(node)); } catch (err) { if (handleError(err, getContext, lax)) { stack.push(new NoopHandler()); } } } function handleCData(text, getContext) { try { stack.peek().handleText(text); } catch (err) { handleWarning(err, getContext); } } function handleText(text, getContext) { // strip whitespace only nodes, i.e. before // <!CDATA[ ... ]> sections and in between tags text = text.trim(); if (!text) { return; } handleCData(text, getContext); } var uriMap = model.getPackages().reduce(function (uriMap, p) { uriMap[p.uri] = p.prefix; return uriMap; }, { 'http://www.w3.org/XML/1998/namespace': 'xml' // add default xml ns }); parser.ns(uriMap).on('openTag', function (obj, decodeStr, selfClosing, getContext) { // gracefully handle unparsable attributes (attrs=false) var attrs = obj.attrs || {}; var decodedAttrs = Object.keys(attrs).reduce(function (d, key) { var value = decodeStr(attrs[key]); d[key] = value; return d; }, {}); var node = { name: obj.name, originalName: obj.originalName, attributes: decodedAttrs, ns: obj.ns }; handleOpen(node, getContext); }).on('question', handleQuestion).on('closeTag', handleClose).on('cdata', handleCData).on('text', function (text, decodeEntities, getContext) { handleText(decodeEntities(text), getContext); }).on('error', handleError).on('warn', handleWarning); // async XML parsing to make sure the execution environment // (node or brower) is kept responsive and that certain optimization // strategies can kick in. return new Promise(function (resolve, reject) { var err; try { parser.parse(xml); resolveReferences(); } catch (e) { err = e; } var rootElement = rootHandler.element; if (!err && !rootElement) { err = error('failed to parse document as <' + rootHandler.type.$descriptor.name + '>'); } var warnings = context.warnings; var references = context.references; var elementsById = context.elementsById; if (err) { err.warnings = warnings; return reject(err); } else { return resolve({ rootElement: rootElement, elementsById: elementsById, references: references, warnings: warnings }); } }); }; Reader.prototype.handler = function (name) { return new RootElementHandler(this.model, name); }; // helpers ////////////////////////// function createStack() { var stack = []; Object.defineProperty(stack, 'peek', { value: function () { return this[this.length - 1]; } }); return stack; } var XML_PREAMBLE = '<?xml version="1.0" encoding="UTF-8"?>\n'; var ESCAPE_ATTR_CHARS = /<|>|'|"|&|\n\r|\n/g; var ESCAPE_CHARS = /<|>|&/g; function Namespaces(parent) { var prefixMap = {}; var uriMap = {}; var used = {}; var wellknown = []; var custom = []; // API this.byUri = function (uri) { return uriMap[uri] || parent && parent.byUri(uri); }; this.add = function (ns, isWellknown) { uriMap[ns.uri] = ns; if (isWellknown) { wellknown.push(ns); } else { custom.push(ns); } this.mapPrefix(ns.prefix, ns.uri); }; this.uriByPrefix = function (prefix) { return prefixMap[prefix || 'xmlns']; }; this.mapPrefix = function (prefix, uri) { prefixMap[prefix || 'xmlns'] = uri; }; this.getNSKey = function (ns) { return ns.prefix !== undefined ? ns.uri + '|' + ns.prefix : ns.uri; }; this.logUsed = function (ns) { var uri = ns.uri; var nsKey = this.getNSKey(ns); used[nsKey] = this.byUri(uri); // Inform parent recursively about the usage of this NS if (parent) { parent.logUsed(ns); } }; this.getUsed = function (ns) { function isUsed(ns) { var nsKey = self.getNSKey(ns); return used[nsKey]; } var self = this; var allNs = [].concat(wellknown, custom); return allNs.filter(isUsed); }; } function lower(string) { return string.charAt(0).toLowerCase() + string.slice(1); } function nameToAlias(name, pkg) { if (hasLowerCaseAlias(pkg)) { return lower(name); } else { return name; } } function inherits(ctor, superCtor) { ctor.super_ = superCtor; ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); } function nsName(ns) { if ((0, _minDash.isString)(ns)) { return ns; } else { return (ns.prefix ? ns.prefix + ':' : '') + ns.localName; } } function getNsAttrs(namespaces) { return (0, _minDash.map)(namespaces.getUsed(), function (ns) { var name = 'xmlns' + (ns.prefix ? ':' + ns.prefix : ''); return { name: name, value: ns.uri }; }); } function getElementNs(ns, descriptor) { if (descriptor.isGeneric) { return (0, _minDash.assign)({ localName: descriptor.ns.localName }, ns); } else { return (0, _minDash.assign)({ localName: nameToAlias(descriptor.ns.localName, descriptor.$pkg) }, ns); } } function getPropertyNs(ns, descriptor) { return (0, _minDash.assign)({ localName: descriptor.ns.localName }, ns); } function getSerializableProperties(element) { var descriptor = element.$descriptor; return (0, _minDash.filter)(descriptor.properties, function (p) { var name = p.name; if (p.isVirtual) { return false; } // do not serialize defaults if (!element.hasOwnProperty(name)) { return false; } var value = element[name]; // do not serialize default equals if (value === p.default) { return false; } // do not serialize null properties if (value === null) { return false; } return p.isMany ? value.length : true; }); } var ESCAPE_ATTR_MAP = { '\n': '#10', '\n\r': '#10', '"': '#34', '\'': '#39', '<': '#60', '>': '#62', '&': '#38' }; var ESCAPE_MAP = { '<': 'lt', '>': 'gt', '&': 'amp' }; function escape(str, charPattern, replaceMap) { // ensure we are handling strings here str = (0, _minDash.isString)(str) ? str : '' + str; return str.replace(charPattern, function (s) { return '&' + replaceMap[s] + ';'; }); } /** * Escape a string attribute to not contain any bad values (line breaks, '"', ...) * * @param {String} str the string to escape * @return {String} the escaped string */ function escapeAttr(str) { return escape(str, ESCAPE_ATTR_CHARS, ESCAPE_ATTR_MAP); } function escapeBody(str) { return escape(str, ESCAPE_CHARS, ESCAPE_MAP); } function filterAttributes(props) { return (0, _minDash.filter)(props, function (p) { return p.isAttr; }); } function filterContained(props) { return (0, _minDash.filter)(props, function (p) { return !p.isAttr; }); } function ReferenceSerializer(tagName) { this.tagName = tagName; } ReferenceSerializer.prototype.build = function (element) { this.element = element; return this; }; ReferenceSerializer.prototype.serializeTo = function (writer) { writer.appendIndent().append('<' + this.tagName + '>' + this.element.id + '</' + this.tagName + '>').appendNewLine(); }; function BodySerializer() {} BodySerializer.prototype.serializeValue = BodySerializer.prototype.serializeTo = function (writer) { writer.append(this.escape ? escapeBody(this.value) : this.value); }; BodySerializer.prototype.build = function (prop, value) { this.value = value; if (prop.type === 'String' && value.search(ESCAPE_CHARS) !== -1) { this.escape = true; } return this; }; function ValueSerializer(tagName) { this.tagName = tagName; } inherits(ValueSerializer, BodySerializer); ValueSerializer.prototype.serializeTo = function (writer) { writer.appendIndent().append('<' + this.tagName + '>'); this.serializeValue(writer); writer.append('</' + this.tagName + '>').appendNewLine(); }; function ElementSerializer(parent, propertyDescriptor) { this.body = []; this.attrs = []; this.parent = parent; this.propertyDescriptor = propertyDescriptor; } ElementSerializer.prototype.build = function (element) { this.element = element; var elementDescriptor = element.$descriptor, propertyDescriptor = this.propertyDescriptor; var otherAttrs, properties; var isGeneric = elementDescriptor.isGeneric; if (isGeneric) { otherAttrs = this.parseGeneric(element); } else { otherAttrs = this.parseNsAttributes(element); } if (propertyDescriptor) { this.ns = this.nsPropertyTagName(propertyDescriptor); } else { this.ns = this.nsTagName(elementDescriptor); } // compute tag name this.tagName = this.addTagName(this.ns); if (!isGeneric) { properties = getSerializableProperties(element); this.parseAttributes(filterAttributes(properties)); this.parseContainments(filterContained(properties)); } this.parseGenericAttributes(element, otherAttrs); return this; }; ElementSerializer.prototype.nsTagName = function (descriptor) { var effectiveNs = this.logNamespaceUsed(descriptor.ns); return getElementNs(effectiveNs, descriptor); }; ElementSerializer.prototype.nsPropertyTagName = function (descriptor) { var effectiveNs = this.logNamespaceUsed(descriptor.ns); return getPropertyNs(effectiveNs, descriptor); }; ElementSerializer.prototype.isLocalNs = function (ns) { return ns.uri === this.ns.uri; }; /** * Get the actual ns attribute name for the given element. * * @param {Object} element * @param {Boolean} [element.inherited=false] * * @return {Object} nsName */ ElementSerializer.prototype.nsAttributeName = function (element) { var ns; if ((0, _minDash.isString)(element)) { ns = (0, _moddle.parseNameNS)(element); } else { ns = element.ns; } // return just local name for inherited attributes if (element.inherited) { return { localName: ns.localName }; } // parse + log effective ns var effectiveNs = this.logNamespaceUsed(ns); // LOG ACTUAL namespace use this.getNamespaces().logUsed(effectiveNs); // strip prefix if same namespace like parent if (this.isLocalNs(effectiveNs)) { return { localName: ns.localName }; } else { return (0, _minDash.assign)({ localName: ns.localName }, effectiveNs); } }; ElementSerializer.prototype.parseGeneric = function (element) { var self = this, body = this.body; var attributes = []; (0, _minDash.forEach)(element, function (val, key) { var nonNsAttr; if (key === '$body') { body.push(new BodySerializer().build({ type: 'String' }, val)); } else if (key === '$children') { (0, _minDash.forEach)(val, function (child) { body.push(new ElementSerializer(self).build(child)); }); } else if (key.indexOf('$') !== 0) { nonNsAttr = self.parseNsAttribute(element, key, val); if (nonNsAttr) { attributes.push({ name: key, value: val }); } } }); return attributes; }; ElementSerializer.prototype.parseNsAttribute = function (element, name, value) { var model = element.$model; var nameNs = (0, _moddle.parseNameNS)(name); var ns; // parse xmlns:foo="http://foo.bar" if (nameNs.prefix === 'xmlns') { ns = { prefix: nameNs.localName, uri: value }; } // parse xmlns="http://foo.bar" if (!nameNs.prefix && nameNs.localName === 'xmlns') { ns = { uri: value }; } if (!ns) { return { name: name, value: value }; } if (model && model.getPackage(value)) { // register well known namespace this.logNamespace(ns, true, true); } else { // log custom namespace directly as used var actualNs = this.logNamespaceUsed(ns, true); this.getNamespaces().logUsed(actualNs); } }; /** * Parse namespaces and return a list of left over generic attributes * * @param {Object} element * @return {Array<Object>} */ ElementSerializer.prototype.parseNsAttributes = function (element, attrs) { var self = this; var genericAttrs = element.$attrs; var attributes = []; // parse namespace attributes first // and log them. push non namespace attributes to a list // and process them later (0, _minDash.forEach)(genericAttrs, function (value, name) { var nonNsAttr = self.parseNsAttribute(element, name, value); if (nonNsAttr) { attributes.push(nonNsAttr); } }); return attributes; }; ElementSerializer.prototype.parseGenericAttributes = function (element, attributes) { var self = this; (0, _minDash.forEach)(attributes, function (attr) { // do not serialize xsi:type attribute // it is set manually based on the actual implementation type if (attr.name === XSI_TYPE) { return; } try { self.addAttribute(self.nsAttributeName(attr.name), attr.value); } catch (e) { console.warn('missing namespace information for ', attr.name, '=', attr.value, 'on', element, e); } }); }; ElementSerializer.prototype.parseContainments = function (properties) { var self = this, body = this.body, element = this.element; (0, _minDash.forEach)(properties, function (p) { var value = element.get(p.name), isReference = p.isReference, isMany = p.isMany; if (!isMany) { value = [value]; } if (p.isBody) { body.push(new BodySerializer().build(p, value[0])); } else if ((0, _moddle.isSimpleType)(p.type)) { (0, _minDash.forEach)(value, function (v) { body.push(new ValueSerializer(self.addTagName(self.nsPropertyTagName(p))).build(p, v)); }); } else if (isReference) { (0, _minDash.forEach)(value, function (v) { body.push(new ReferenceSerializer(self.addTagName(self.nsPropertyTagName(p))).build(v)); }); } else { // allow serialization via type // rather than element name var asType = serializeAsType(p), asProperty = serializeAsProperty(p); (0, _minDash.forEach)(value, function (v) { var serializer; if (asType) { serializer = new TypeSerializer(self, p); } else if (asProperty) { serializer = new ElementSerializer(self, p); } else { serializer = new ElementSerializer(self); } body.push(serializer.build(v)); }); } }); }; ElementSerializer.prototype.getNamespaces = function (local) { var namespaces = this.namespaces, parent = this.parent, parentNamespaces; if (!namespaces) { parentNamespaces = parent && parent.getNamespaces(); if (local || !parentNamespaces) { this.namespaces = namespaces = new Namespaces(parentNamespaces); } else { namespaces = parentNamespaces; } } return namespaces; }; ElementSerializer.prototype.logNamespace = function (ns, wellknown, local) { var namespaces = this.getNamespaces(local); var nsUri = ns.uri, nsPrefix = ns.prefix; var existing = namespaces.byUri(nsUri); if (nsPrefix !== 'xml' && (!existing || local)) { namespaces.add(ns, wellknown); } namespaces.mapPrefix(nsPrefix, nsUri); return ns; }; ElementSerializer.prototype.logNamespaceUsed = function (ns, local) { var element = this.element, model = element.$model, namespaces = this.getNamespaces(local); // ns may be // // * prefix only // * prefix:uri // * localName only var prefix = ns.prefix, uri = ns.uri, newPrefix, idx, wellknownUri; // handle anonymous namespaces (elementForm=unqualified), cf. #23 if (!prefix && !uri) { return { localName: ns.localName }; } wellknownUri = DEFAULT_NS_MAP[prefix] || model && (model.getPackage(prefix) || {}).uri; uri = uri || wellknownUri || namespaces.uriByPrefix(prefix); if (!uri) { throw new Error('no namespace uri given for prefix <' + prefix + '>'); } ns = namespaces.byUri(uri); if (!ns) { newPrefix = prefix; idx = 1; // find a prefix that is not mapped yet while (namespaces.uriByPrefix(newPrefix)) { newPrefix = prefix + '_' + idx++; } ns = this.logNamespace({ prefix: newPrefix, uri: uri }, wellknownUri === uri); } if (prefix) { namespaces.mapPrefix(prefix, uri); } return ns; }; ElementSerializer.prototype.parseAttributes = function (properties) { var self = this, element = this.element; (0, _minDash.forEach)(properties, function (p) { var value = element.get(p.name); if (p.isReference) { if (!p.isMany) { value = value.id; } else { var values = []; (0, _minDash.forEach)(value, function (v) { values.push(v.id); }); // IDREFS is a whitespace-separated list of references. value = values.join(' '); } } self.addAttribute(self.nsAttributeName(p), value); }); }; ElementSerializer.prototype.addTagName = function (nsTagName) { var actualNs = this.logNamespaceUsed(nsTagName); this.getNamespaces().logUsed(actualNs); return nsName(nsTagName); }; ElementSerializer.prototype.addAttribute = function (name, value) { var attrs = this.attrs; if ((0, _minDash.isString)(value)) { value = escapeAttr(value); } attrs.push({ name: name, value: value }); }; ElementSerializer.prototype.serializeAttributes = function (writer) { var attrs = this.attrs, namespaces = this.namespaces; if (namespaces) { attrs = getNsAttrs(namespaces).concat(attrs); } (0, _minDash.forEach)(attrs, function (a) { writer.append(' ').append(nsName(a.name)).append('="').append(a.value).append('"'); }); }; ElementSerializer.prototype.serializeTo = function (writer) { var firstBody = this.body[0], indent = firstBody && firstBody.constructor !== BodySerializer; writer.appendIndent().append('<' + this.tagName); this.serializeAttributes(writer); writer.append(firstBody ? '>' : ' />'); if (firstBody) { if (indent) { writer.appendNewLine().indent(); } (0, _minDash.forEach)(this.body, function (b) { b.serializeTo(writer); }); if (indent) { writer.unindent().appendIndent(); } writer.append('</' + this.tagName + '>'); } writer.appendNewLine(); }; /** * A serializer for types that handles serialization of data types */ function TypeSerializer(parent, propertyDescriptor) { ElementSerializer.call(this, parent, propertyDescriptor); } inherits(TypeSerializer, ElementSerializer); TypeSerializer.prototype.parseNsAttributes = function (element) { // extracted attributes var attributes = ElementSerializer.prototype.parseNsAttributes.call(this, element); var descriptor = element.$descriptor; // only serialize xsi:type if necessary if (descriptor.name === this.propertyDescriptor.type) { return attributes; } var typeNs = this.typeNs = this.nsTagName(descriptor); this.getNamespaces().logUsed(this.typeNs); // add xsi:type attribute to represent the elements // actual type var pkg = element.$model.getPackage(typeNs.uri), typePrefix = pkg.xml && pkg.xml.typePrefix || ''; this.addAttribute(this.nsAttributeName(XSI_TYPE), (typeNs.prefix ? typeNs.prefix + ':' : '') + typePrefix + descriptor.ns.localName); return attributes; }; TypeSerializer.prototype.isLocalNs = function (ns) { return ns.uri === (this.typeNs || this.ns).uri; }; function SavingWriter() { this.value = ''; this.write = function (str) { this.value += str; }; } function FormatingWriter(out, format) { var indent = ['']; this.append = function (str) { out.write(str); return this; }; this.appendNewLine = function () { if (format) { out.write('\n'); } return this; }; this.appendIndent = function () { if (format) { out.write(indent.join(' ')); } return this; }; this.indent = function () { indent.push(''); return this; }; this.unindent = function () { indent.pop(); return this; }; } /** * A writer for meta-model backed document trees * * @param {Object} options output options to pass into the writer */ function Writer(options) { options = (0, _minDash.assign)({ format: false, preamble: true }, options || {}); function toXML(tree, writer) { var internalWriter = writer || new SavingWriter(); var formatingWriter = new FormatingWriter(internalWriter, options.format); if (options.preamble) { formatingWriter.append(XML_PREAMBLE); } new ElementSerializer().build(tree).serializeTo(formatingWriter); if (!writer) { return internalWriter.value; } } return { toXML: toXML }; } },{"min-dash":555,"moddle":559,"saxen":564}],559:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Moddle = Moddle; exports.coerceType = coerceType; exports.isBuiltInType = isBuiltIn; exports.isSimpleType = isSimple; exports.parseNameNS = parseName; var _minDash = require("min-dash"); /** * Moddle base element. */ function Base() {} Base.prototype.get = function (name) { return this.$model.properties.get(this, name); }; Base.prototype.set = function (name, value) { this.$model.properties.set(this, name, value); }; /** * A model element factory. * * @param {Moddle} model * @param {Properties} properties */ function Factory(model, properties) { this.model = model; this.properties = properties; } Factory.prototype.createType = function (descriptor) { var model = this.model; var props = this.properties, prototype = Object.create(Base.prototype); // initialize default values (0, _minDash.forEach)(descriptor.properties, function (p) { if (!p.isMany && p.default !== undefined) { prototype[p.name] = p.default; } }); props.defineModel(prototype, model); props.defineDescriptor(prototype, descriptor); var name = descriptor.ns.name; /** * The new type constructor */ function ModdleElement(attrs) { props.define(this, '$type', { value: name, enumerable: true }); props.define(this, '$attrs', { value: {} }); props.define(this, '$parent', { writable: true }); (0, _minDash.forEach)(attrs, (0, _minDash.bind)(function (val, key) { this.set(key, val); }, this)); } ModdleElement.prototype = prototype; ModdleElement.hasType = prototype.$instanceOf = this.model.hasType; // static links props.defineModel(ModdleElement, model); props.defineDescriptor(ModdleElement, descriptor); return ModdleElement; }; /** * Built-in moddle types */ var BUILTINS = { String: true, Boolean: true, Integer: true, Real: true, Element: true }; /** * Converters for built in types from string representations */ var TYPE_CONVERTERS = { String: function (s) { return s; }, Boolean: function (s) { return s === 'true'; }, Integer: function (s) { return parseInt(s, 10); }, Real: function (s) { return parseFloat(s, 10); } }; /** * Convert a type to its real representation */ function coerceType(type, value) { var converter = TYPE_CONVERTERS[type]; if (converter) { return converter(value); } else { return value; } } /** * Return whether the given type is built-in */ function isBuiltIn(type) { return !!BUILTINS[type]; } /** * Return whether the given type is simple */ function isSimple(type) { return !!TYPE_CONVERTERS[type]; } /** * Parses a namespaced attribute name of the form (ns:)localName to an object, * given a default prefix to assume in case no explicit namespace is given. * * @param {String} name * @param {String} [defaultPrefix] the default prefix to take, if none is present. * * @return {Object} the parsed name */ function parseName(name, defaultPrefix) { var parts = name.split(/:/), localName, prefix; // no prefix (i.e. only local name) if (parts.length === 1) { localName = name; prefix = defaultPrefix; } else // prefix + local name if (parts.length === 2) { localName = parts[1]; prefix = parts[0]; } else { throw new Error('expected <prefix:localName> or <localName>, got ' + name); } name = (prefix ? prefix + ':' : '') + localName; return { name: name, prefix: prefix, localName: localName }; } /** * A utility to build element descriptors. */ function DescriptorBuilder(nameNs) { this.ns = nameNs; this.name = nameNs.name; this.allTypes = []; this.allTypesByName = {}; this.properties = []; this.propertiesByName = {}; } DescriptorBuilder.prototype.build = function () { return (0, _minDash.pick)(this, ['ns', 'name', 'allTypes', 'allTypesByName', 'properties', 'propertiesByName', 'bodyProperty', 'idProperty']); }; /** * Add property at given index. * * @param {Object} p * @param {Number} [idx] * @param {Boolean} [validate=true] */ DescriptorBuilder.prototype.addProperty = function (p, idx, validate) { if (typeof idx === 'boolean') { validate = idx; idx = undefined; } this.addNamedProperty(p, validate !== false); var properties = this.properties; if (idx !== undefined) { properties.splice(idx, 0, p); } else { properties.push(p); } }; DescriptorBuilder.prototype.replaceProperty = function (oldProperty, newProperty, replace) { var oldNameNs = oldProperty.ns; var props = this.properties, propertiesByName = this.propertiesByName, rename = oldProperty.name !== newProperty.name; if (oldProperty.isId) { if (!newProperty.isId) { throw new Error('property <' + newProperty.ns.name + '> must be id property ' + 'to refine <' + oldProperty.ns.name + '>'); } this.setIdProperty(newProperty, false); } if (oldProperty.isBody) { if (!newProperty.isBody) { throw new Error('property <' + newProperty.ns.name + '> must be body property ' + 'to refine <' + oldProperty.ns.name + '>'); } // TODO: Check compatibility this.setBodyProperty(newProperty, false); } // validate existence and get location of old property var idx = props.indexOf(oldProperty); if (idx === -1) { throw new Error('property <' + oldNameNs.name + '> not found in property list'); } // remove old property props.splice(idx, 1); // replacing the named property is intentional // // * validate only if this is a "rename" operation // * add at specific index unless we "replace" // this.addProperty(newProperty, replace ? undefined : idx, rename); // make new property available under old name propertiesByName[oldNameNs.name] = propertiesByName[oldNameNs.localName] = newProperty; }; DescriptorBuilder.prototype.redefineProperty = function (p, targetPropertyName, replace) { var nsPrefix = p.ns.prefix; var parts = targetPropertyName.split('#'); var name = parseName(parts[0], nsPrefix); var attrName = parseName(parts[1], name.prefix).name; var redefinedProperty = this.propertiesByName[attrName]; if (!redefinedProperty) { throw new Error('refined property <' + attrName + '> not found'); } else { this.replaceProperty(redefinedProperty, p, replace); } delete p.redefines; }; DescriptorBuilder.prototype.addNamedProperty = function (p, validate) { var ns = p.ns, propsByName = this.propertiesByName; if (validate) { this.assertNotDefined(p, ns.name); this.assertNotDefined(p, ns.localName); } propsByName[ns.name] = propsByName[ns.localName] = p; }; DescriptorBuilder.prototype.removeNamedProperty = function (p) { var ns = p.ns, propsByName = this.propertiesByName; delete propsByName[ns.name]; delete propsByName[ns.localName]; }; DescriptorBuilder.prototype.setBodyProperty = function (p, validate) { if (validate && this.bodyProperty) { throw new Error('body property defined multiple times ' + '(<' + this.bodyProperty.ns.name + '>, <' + p.ns.name + '>)'); } this.bodyProperty = p; }; DescriptorBuilder.prototype.setIdProperty = function (p, validate) { if (validate && this.idProperty) { throw new Error('id property defined multiple times ' + '(<' + this.idProperty.ns.name + '>, <' + p.ns.name + '>)'); } this.idProperty = p; }; DescriptorBuilder.prototype.assertNotDefined = function (p, name) { var propertyName = p.name, definedProperty = this.propertiesByName[propertyName]; if (definedProperty) { throw new Error('property <' + propertyName + '> already defined; ' + 'override of <' + definedProperty.definedBy.ns.name + '#' + definedProperty.ns.name + '> by ' + '<' + p.definedBy.ns.name + '#' + p.ns.name + '> not allowed without redefines'); } }; DescriptorBuilder.prototype.hasProperty = function (name) { return this.propertiesByName[name]; }; DescriptorBuilder.prototype.addTrait = function (t, inherited) { var typesByName = this.allTypesByName, types = this.allTypes; var typeName = t.name; if (typeName in typesByName) { return; } (0, _minDash.forEach)(t.properties, (0, _minDash.bind)(function (p) { // clone property to allow extensions p = (0, _minDash.assign)({}, p, { name: p.ns.localName, inherited: inherited }); Object.defineProperty(p, 'definedBy', { value: t }); var replaces = p.replaces, redefines = p.redefines; // add replace/redefine support if (replaces || redefines) { this.redefineProperty(p, replaces || redefines, replaces); } else { if (p.isBody) { this.setBodyProperty(p); } if (p.isId) { this.setIdProperty(p); } this.addProperty(p); } }, this)); types.push(t); typesByName[typeName] = t; }; /** * A registry of Moddle packages. * * @param {Array<Package>} packages * @param {Properties} properties */ function Registry(packages, properties) { this.packageMap = {}; this.typeMap = {}; this.packages = []; this.properties = properties; (0, _minDash.forEach)(packages, (0, _minDash.bind)(this.registerPackage, this)); } Registry.prototype.getPackage = function (uriOrPrefix) { return this.packageMap[uriOrPrefix]; }; Registry.prototype.getPackages = function () { return this.packages; }; Registry.prototype.registerPackage = function (pkg) { // copy package pkg = (0, _minDash.assign)({}, pkg); var pkgMap = this.packageMap; ensureAvailable(pkgMap, pkg, 'prefix'); ensureAvailable(pkgMap, pkg, 'uri'); // register types (0, _minDash.forEach)(pkg.types, (0, _minDash.bind)(function (descriptor) { this.registerType(descriptor, pkg); }, this)); pkgMap[pkg.uri] = pkgMap[pkg.prefix] = pkg; this.packages.push(pkg); }; /** * Register a type from a specific package with us */ Registry.prototype.registerType = function (type, pkg) { type = (0, _minDash.assign)({}, type, { superClass: (type.superClass || []).slice(), extends: (type.extends || []).slice(), properties: (type.properties || []).slice(), meta: (0, _minDash.assign)(type.meta || {}) }); var ns = parseName(type.name, pkg.prefix), name = ns.name, propertiesByName = {}; // parse properties (0, _minDash.forEach)(type.properties, (0, _minDash.bind)(function (p) { // namespace property names var propertyNs = parseName(p.name, ns.prefix), propertyName = propertyNs.name; // namespace property types if (!isBuiltIn(p.type)) { p.type = parseName(p.type, propertyNs.prefix).name; } (0, _minDash.assign)(p, { ns: propertyNs, name: propertyName }); propertiesByName[propertyName] = p; }, this)); // update ns + name (0, _minDash.assign)(type, { ns: ns, name: name, propertiesByName: propertiesByName }); (0, _minDash.forEach)(type.extends, (0, _minDash.bind)(function (extendsName) { var extended = this.typeMap[extendsName]; extended.traits = extended.traits || []; extended.traits.push(name); }, this)); // link to package this.definePackage(type, pkg); // register this.typeMap[name] = type; }; /** * Traverse the type hierarchy from bottom to top, * calling iterator with (type, inherited) for all elements in * the inheritance chain. * * @param {Object} nsName * @param {Function} iterator * @param {Boolean} [trait=false] */ Registry.prototype.mapTypes = function (nsName, iterator, trait) { var type = isBuiltIn(nsName.name) ? { name: nsName.name } : this.typeMap[nsName.name]; var self = this; /** * Traverse the selected trait. * * @param {String} cls */ function traverseTrait(cls) { return traverseSuper(cls, true); } /** * Traverse the selected super type or trait * * @param {String} cls * @param {Boolean} [trait=false] */ function traverseSuper(cls, trait) { var parentNs = parseName(cls, isBuiltIn(cls) ? '' : nsName.prefix); self.mapTypes(parentNs, iterator, trait); } if (!type) { throw new Error('unknown type <' + nsName.name + '>'); } (0, _minDash.forEach)(type.superClass, trait ? traverseTrait : traverseSuper); // call iterator with (type, inherited=!trait) iterator(type, !trait); (0, _minDash.forEach)(type.traits, traverseTrait); }; /** * Returns the effective descriptor for a type. * * @param {String} type the namespaced name (ns:localName) of the type * * @return {Descriptor} the resulting effective descriptor */ Registry.prototype.getEffectiveDescriptor = function (name) { var nsName = parseName(name); var builder = new DescriptorBuilder(nsName); this.mapTypes(nsName, function (type, inherited) { builder.addTrait(type, inherited); }); var descriptor = builder.build(); // define package link this.definePackage(descriptor, descriptor.allTypes[descriptor.allTypes.length - 1].$pkg); return descriptor; }; Registry.prototype.definePackage = function (target, pkg) { this.properties.define(target, '$pkg', { value: pkg }); }; ///////// helpers //////////////////////////// function ensureAvailable(packageMap, pkg, identifierKey) { var value = pkg[identifierKey]; if (value in packageMap) { throw new Error('package with ' + identifierKey + ' <' + value + '> already defined'); } } /** * A utility that gets and sets properties of model elements. * * @param {Model} model */ function Properties(model) { this.model = model; } /** * Sets a named property on the target element. * If the value is undefined, the property gets deleted. * * @param {Object} target * @param {String} name * @param {Object} value */ Properties.prototype.set = function (target, name, value) { var property = this.model.getPropertyDescriptor(target, name); var propertyName = property && property.name; if (isUndefined(value)) { // unset the property, if the specified value is undefined; // delete from $attrs (for extensions) or the target itself if (property) { delete target[propertyName]; } else { delete target.$attrs[name]; } } else { // set the property, defining well defined properties on the fly // or simply updating them in target.$attrs (for extensions) if (property) { if (propertyName in target) { target[propertyName] = value; } else { defineProperty(target, property, value); } } else { target.$attrs[name] = value; } } }; /** * Returns the named property of the given element * * @param {Object} target * @param {String} name * * @return {Object} */ Properties.prototype.get = function (target, name) { var property = this.model.getPropertyDescriptor(target, name); if (!property) { return target.$attrs[name]; } var propertyName = property.name; // check if access to collection property and lazily initialize it if (!target[propertyName] && property.isMany) { defineProperty(target, property, []); } return target[propertyName]; }; /** * Define a property on the target element * * @param {Object} target * @param {String} name * @param {Object} options */ Properties.prototype.define = function (target, name, options) { Object.defineProperty(target, name, options); }; /** * Define the descriptor for an element */ Properties.prototype.defineDescriptor = function (target, descriptor) { this.define(target, '$descriptor', { value: descriptor }); }; /** * Define the model for an element */ Properties.prototype.defineModel = function (target, model) { this.define(target, '$model', { value: model }); }; function isUndefined(val) { return typeof val === 'undefined'; } function defineProperty(target, property, value) { Object.defineProperty(target, property.name, { enumerable: !property.isReference, writable: true, value: value, configurable: true }); } //// Moddle implementation ///////////////////////////////////////////////// /** * @class Moddle * * A model that can be used to create elements of a specific type. * * @example * * var Moddle = require('moddle'); * * var pkg = { * name: 'mypackage', * prefix: 'my', * types: [ * { name: 'Root' } * ] * }; * * var moddle = new Moddle([pkg]); * * @param {Array<Package>} packages the packages to contain */ function Moddle(packages) { this.properties = new Properties(this); this.factory = new Factory(this, this.properties); this.registry = new Registry(packages, this.properties); this.typeCache = {}; } /** * Create an instance of the specified type. * * @method Moddle#create * * @example * * var foo = moddle.create('my:Foo'); * var bar = moddle.create('my:Bar', { id: 'BAR_1' }); * * @param {String|Object} descriptor the type descriptor or name know to the model * @param {Object} attrs a number of attributes to initialize the model instance with * @return {Object} model instance */ Moddle.prototype.create = function (descriptor, attrs) { var Type = this.getType(descriptor); if (!Type) { throw new Error('unknown type <' + descriptor + '>'); } return new Type(attrs); }; /** * Returns the type representing a given descriptor * * @method Moddle#getType * * @example * * var Foo = moddle.getType('my:Foo'); * var foo = new Foo({ 'id' : 'FOO_1' }); * * @param {String|Object} descriptor the type descriptor or name know to the model * @return {Object} the type representing the descriptor */ Moddle.prototype.getType = function (descriptor) { var cache = this.typeCache; var name = (0, _minDash.isString)(descriptor) ? descriptor : descriptor.ns.name; var type = cache[name]; if (!type) { descriptor = this.registry.getEffectiveDescriptor(name); type = cache[name] = this.factory.createType(descriptor); } return type; }; /** * Creates an any-element type to be used within model instances. * * This can be used to create custom elements that lie outside the meta-model. * The created element contains all the meta-data required to serialize it * as part of meta-model elements. * * @method Moddle#createAny * * @example * * var foo = moddle.createAny('vendor:Foo', 'http://vendor', { * value: 'bar' * }); * * var container = moddle.create('my:Container', 'http://my', { * any: [ foo ] * }); * * // go ahead and serialize the stuff * * * @param {String} name the name of the element * @param {String} nsUri the namespace uri of the element * @param {Object} [properties] a map of properties to initialize the instance with * @return {Object} the any type instance */ Moddle.prototype.createAny = function (name, nsUri, properties) { var nameNs = parseName(name); var element = { $type: name, $instanceOf: function (type) { return type === this.$type; } }; var descriptor = { name: name, isGeneric: true, ns: { prefix: nameNs.prefix, localName: nameNs.localName, uri: nsUri } }; this.properties.defineDescriptor(element, descriptor); this.properties.defineModel(element, this); this.properties.define(element, '$parent', { enumerable: false, writable: true }); (0, _minDash.forEach)(properties, function (a, key) { if ((0, _minDash.isObject)(a) && a.value !== undefined) { element[a.name] = a.value; } else { element[key] = a; } }); return element; }; /** * Returns a registered package by uri or prefix * * @return {Object} the package */ Moddle.prototype.getPackage = function (uriOrPrefix) { return this.registry.getPackage(uriOrPrefix); }; /** * Returns a snapshot of all known packages * * @return {Object} the package */ Moddle.prototype.getPackages = function () { return this.registry.getPackages(); }; /** * Returns the descriptor for an element */ Moddle.prototype.getElementDescriptor = function (element) { return element.$descriptor; }; /** * Returns true if the given descriptor or instance * represents the given type. * * May be applied to this, if element is omitted. */ Moddle.prototype.hasType = function (element, type) { if (type === undefined) { type = element; element = this; } var descriptor = element.$model.getElementDescriptor(element); return type in descriptor.allTypesByName; }; /** * Returns the descriptor of an elements named property */ Moddle.prototype.getPropertyDescriptor = function (element, property) { return this.getElementDescriptor(element).propertiesByName[property]; }; /** * Returns a mapped type's descriptor */ Moddle.prototype.getTypeDescriptor = function (type) { return this.registry.typeMap[type]; }; },{"min-dash":555}],560:[function(require,module,exports){ module.exports = require('./lib/refs'); module.exports.Collection = require('./lib/collection'); },{"./lib/collection":561,"./lib/refs":562}],561:[function(require,module,exports){ 'use strict'; /** * An empty collection stub. Use {@link RefsCollection.extend} to extend a * collection with ref semantics. * * @class RefsCollection */ /** * Extends a collection with {@link Refs} aware methods * * @memberof RefsCollection * @static * * @param {Array<Object>} collection * @param {Refs} refs instance * @param {Object} property represented by the collection * @param {Object} target object the collection is attached to * * @return {RefsCollection<Object>} the extended array */ function extend(collection, refs, property, target) { var inverseProperty = property.inverse; /** * Removes the given element from the array and returns it. * * @method RefsCollection#remove * * @param {Object} element the element to remove */ Object.defineProperty(collection, 'remove', { value: function(element) { var idx = this.indexOf(element); if (idx !== -1) { this.splice(idx, 1); // unset inverse refs.unset(element, inverseProperty, target); } return element; } }); /** * Returns true if the collection contains the given element * * @method RefsCollection#contains * * @param {Object} element the element to check for */ Object.defineProperty(collection, 'contains', { value: function(element) { return this.indexOf(element) !== -1; } }); /** * Adds an element to the array, unless it exists already (set semantics). * * @method RefsCollection#add * * @param {Object} element the element to add * @param {Number} optional index to add element to * (possibly moving other elements around) */ Object.defineProperty(collection, 'add', { value: function(element, idx) { var currentIdx = this.indexOf(element); if (typeof idx === 'undefined') { if (currentIdx !== -1) { // element already in collection (!) return; } // add to end of array, as no idx is specified idx = this.length; } // handle already in collection if (currentIdx !== -1) { // remove element from currentIdx this.splice(currentIdx, 1); } // add element at idx this.splice(idx, 0, element); if (currentIdx === -1) { // set inverse, unless element was // in collection already refs.set(element, inverseProperty, target); } } }); // a simple marker, identifying this element // as being a refs collection Object.defineProperty(collection, '__refs_collection', { value: true }); return collection; } function isExtended(collection) { return collection.__refs_collection === true; } module.exports.extend = extend; module.exports.isExtended = isExtended; },{}],562:[function(require,module,exports){ 'use strict'; var Collection = require('./collection'); function hasOwnProperty(e, property) { return Object.prototype.hasOwnProperty.call(e, property.name || property); } function defineCollectionProperty(ref, property, target) { var collection = Collection.extend(target[property.name] || [], ref, property, target); Object.defineProperty(target, property.name, { enumerable: property.enumerable, value: collection }); if (collection.length) { collection.forEach(function(o) { ref.set(o, property.inverse, target); }); } } function defineProperty(ref, property, target) { var inverseProperty = property.inverse; var _value = target[property.name]; Object.defineProperty(target, property.name, { configurable: property.configurable, enumerable: property.enumerable, get: function() { return _value; }, set: function(value) { // return if we already performed all changes if (value === _value) { return; } var old = _value; // temporary set null _value = null; if (old) { ref.unset(old, inverseProperty, target); } // set new value _value = value; // set inverse value ref.set(_value, inverseProperty, target); } }); } /** * Creates a new references object defining two inversly related * attribute descriptors a and b. * * <p> * When bound to an object using {@link Refs#bind} the references * get activated and ensure that add and remove operations are applied * reversely, too. * </p> * * <p> * For attributes represented as collections {@link Refs} provides the * {@link RefsCollection#add}, {@link RefsCollection#remove} and {@link RefsCollection#contains} extensions * that must be used to properly hook into the inverse change mechanism. * </p> * * @class Refs * * @classdesc A bi-directional reference between two attributes. * * @param {Refs.AttributeDescriptor} a property descriptor * @param {Refs.AttributeDescriptor} b property descriptor * * @example * * var refs = Refs({ name: 'wheels', collection: true, enumerable: true }, { name: 'car' }); * * var car = { name: 'toyota' }; * var wheels = [{ pos: 'front-left' }, { pos: 'front-right' }]; * * refs.bind(car, 'wheels'); * * car.wheels // [] * car.wheels.add(wheels[0]); * car.wheels.add(wheels[1]); * * car.wheels // [{ pos: 'front-left' }, { pos: 'front-right' }] * * wheels[0].car // { name: 'toyota' }; * car.wheels.remove(wheels[0]); * * wheels[0].car // undefined */ function Refs(a, b) { if (!(this instanceof Refs)) { return new Refs(a, b); } // link a.inverse = b; b.inverse = a; this.props = {}; this.props[a.name] = a; this.props[b.name] = b; } /** * Binds one side of a bi-directional reference to a * target object. * * @memberOf Refs * * @param {Object} target * @param {String} property */ Refs.prototype.bind = function(target, property) { if (typeof property === 'string') { if (!this.props[property]) { throw new Error('no property <' + property + '> in ref'); } property = this.props[property]; } if (property.collection) { defineCollectionProperty(this, property, target); } else { defineProperty(this, property, target); } }; Refs.prototype.ensureRefsCollection = function(target, property) { var collection = target[property.name]; if (!Collection.isExtended(collection)) { defineCollectionProperty(this, property, target); } return collection; }; Refs.prototype.ensureBound = function(target, property) { if (!hasOwnProperty(target, property)) { this.bind(target, property); } }; Refs.prototype.unset = function(target, property, value) { if (target) { this.ensureBound(target, property); if (property.collection) { this.ensureRefsCollection(target, property).remove(value); } else { target[property.name] = undefined; } } }; Refs.prototype.set = function(target, property, value) { if (target) { this.ensureBound(target, property); if (property.collection) { this.ensureRefsCollection(target, property).add(value); } else { target[property.name] = value; } } }; module.exports = Refs; /** * An attribute descriptor to be used specify an attribute in a {@link Refs} instance * * @typedef {Object} Refs.AttributeDescriptor * @property {String} name * @property {boolean} [collection=false] * @property {boolean} [enumerable=false] */ },{"./collection":561}],563:[function(require,module,exports){ 'use strict'; /** * This file contains source code adapted from Snap.svg (licensed Apache-2.0). * * @see https://github.com/adobe-webplatform/Snap.svg/blob/master/src/path.js */ /* eslint no-fallthrough: "off" */ var p2s = /,?([a-z]),?/gi, toFloat = parseFloat, math = Math, PI = math.PI, mmin = math.min, mmax = math.max, pow = math.pow, abs = math.abs, pathCommand = /([a-z])[\s,]*((-?\d*\.?\d*(?:e[-+]?\d+)?[\s]*,?[\s]*)+)/ig, pathValues = /(-?\d*\.?\d*(?:e[-+]?\\d+)?)[\s]*,?[\s]*/ig; var isArray = Array.isArray || function(o) { return o instanceof Array; }; function hasProperty(obj, property) { return Object.prototype.hasOwnProperty.call(obj, property); } function clone(obj) { if (typeof obj == 'function' || Object(obj) !== obj) { return obj; } var res = new obj.constructor; for (var key in obj) { if (hasProperty(obj, key)) { res[key] = clone(obj[key]); } } return res; } function repush(array, item) { for (var i = 0, ii = array.length; i < ii; i++) if (array[i] === item) { return array.push(array.splice(i, 1)[0]); } } function cacher(f) { function newf() { var arg = Array.prototype.slice.call(arguments, 0), args = arg.join('\u2400'), cache = newf.cache = newf.cache || {}, count = newf.count = newf.count || []; if (hasProperty(cache, args)) { repush(count, args); return cache[args]; } count.length >= 1e3 && delete cache[count.shift()]; count.push(args); cache[args] = f.apply(0, arg); return cache[args]; } return newf; } function parsePathString(pathString) { if (!pathString) { return null; } var pth = paths(pathString); if (pth.arr) { return clone(pth.arr); } var paramCounts = { a: 7, c: 6, h: 1, l: 2, m: 2, q: 4, s: 4, t: 2, v: 1, z: 0 }, data = []; if (isArray(pathString) && isArray(pathString[0])) { // rough assumption data = clone(pathString); } if (!data.length) { String(pathString).replace(pathCommand, function(a, b, c) { var params = [], name = b.toLowerCase(); c.replace(pathValues, function(a, b) { b && params.push(+b); }); if (name == 'm' && params.length > 2) { data.push([b].concat(params.splice(0, 2))); name = 'l'; b = b == 'm' ? 'l' : 'L'; } while (params.length >= paramCounts[name]) { data.push([b].concat(params.splice(0, paramCounts[name]))); if (!paramCounts[name]) { break; } } }); } data.toString = paths.toString; pth.arr = clone(data); return data; } function paths(ps) { var p = paths.ps = paths.ps || {}; if (p[ps]) { p[ps].sleep = 100; } else { p[ps] = { sleep: 100 }; } setTimeout(function() { for (var key in p) { if (hasProperty(p, key) && key != ps) { p[key].sleep--; !p[key].sleep && delete p[key]; } } }); return p[ps]; } function rectBBox(x, y, width, height) { if (arguments.length === 1) { y = x.y; width = x.width; height = x.height; x = x.x; } return { x: x, y: y, width: width, height: height, x2: x + width, y2: y + height }; } function pathToString() { return this.join(',').replace(p2s, '$1'); } function pathClone(pathArray) { var res = clone(pathArray); res.toString = pathToString; return res; } function findDotsAtSegment(p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y, t) { var t1 = 1 - t, t13 = pow(t1, 3), t12 = pow(t1, 2), t2 = t * t, t3 = t2 * t, x = t13 * p1x + t12 * 3 * t * c1x + t1 * 3 * t * t * c2x + t3 * p2x, y = t13 * p1y + t12 * 3 * t * c1y + t1 * 3 * t * t * c2y + t3 * p2y; return { x: fixError(x), y: fixError(y) }; } function bezierBBox(points) { var bbox = curveBBox.apply(null, points); return rectBBox( bbox.x0, bbox.y0, bbox.x1 - bbox.x0, bbox.y1 - bbox.y0 ); } function isPointInsideBBox(bbox, x, y) { return x >= bbox.x && x <= bbox.x + bbox.width && y >= bbox.y && y <= bbox.y + bbox.height; } function isBBoxIntersect(bbox1, bbox2) { bbox1 = rectBBox(bbox1); bbox2 = rectBBox(bbox2); return isPointInsideBBox(bbox2, bbox1.x, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y) || isPointInsideBBox(bbox2, bbox1.x, bbox1.y2) || isPointInsideBBox(bbox2, bbox1.x2, bbox1.y2) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y) || isPointInsideBBox(bbox1, bbox2.x, bbox2.y2) || isPointInsideBBox(bbox1, bbox2.x2, bbox2.y2) || (bbox1.x < bbox2.x2 && bbox1.x > bbox2.x || bbox2.x < bbox1.x2 && bbox2.x > bbox1.x) && (bbox1.y < bbox2.y2 && bbox1.y > bbox2.y || bbox2.y < bbox1.y2 && bbox2.y > bbox1.y); } function base3(t, p1, p2, p3, p4) { var t1 = -3 * p1 + 9 * p2 - 9 * p3 + 3 * p4, t2 = t * t1 + 6 * p1 - 12 * p2 + 6 * p3; return t * t2 - 3 * p1 + 3 * p2; } function bezlen(x1, y1, x2, y2, x3, y3, x4, y4, z) { if (z == null) { z = 1; } z = z > 1 ? 1 : z < 0 ? 0 : z; var z2 = z / 2, n = 12, Tvalues = [-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816], Cvalues = [0.2491,0.2491,0.2335,0.2335,0.2032,0.2032,0.1601,0.1601,0.1069,0.1069,0.0472,0.0472], sum = 0; for (var i = 0; i < n; i++) { var ct = z2 * Tvalues[i] + z2, xbase = base3(ct, x1, x2, x3, x4), ybase = base3(ct, y1, y2, y3, y4), comb = xbase * xbase + ybase * ybase; sum += Cvalues[i] * math.sqrt(comb); } return z2 * sum; } function intersectLines(x1, y1, x2, y2, x3, y3, x4, y4) { if ( mmax(x1, x2) < mmin(x3, x4) || mmin(x1, x2) > mmax(x3, x4) || mmax(y1, y2) < mmin(y3, y4) || mmin(y1, y2) > mmax(y3, y4) ) { return; } var nx = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4), ny = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4), denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (!denominator) { return; } var px = fixError(nx / denominator), py = fixError(ny / denominator), px2 = +px.toFixed(2), py2 = +py.toFixed(2); if ( px2 < +mmin(x1, x2).toFixed(2) || px2 > +mmax(x1, x2).toFixed(2) || px2 < +mmin(x3, x4).toFixed(2) || px2 > +mmax(x3, x4).toFixed(2) || py2 < +mmin(y1, y2).toFixed(2) || py2 > +mmax(y1, y2).toFixed(2) || py2 < +mmin(y3, y4).toFixed(2) || py2 > +mmax(y3, y4).toFixed(2) ) { return; } return { x: px, y: py }; } function fixError(number) { return Math.round(number * 100000000000) / 100000000000; } function findBezierIntersections(bez1, bez2, justCount) { var bbox1 = bezierBBox(bez1), bbox2 = bezierBBox(bez2); if (!isBBoxIntersect(bbox1, bbox2)) { return justCount ? 0 : []; } // As an optimization, lines will have only 1 segment var l1 = bezlen.apply(0, bez1), l2 = bezlen.apply(0, bez2), n1 = isLine(bez1) ? 1 : ~~(l1 / 5) || 1, n2 = isLine(bez2) ? 1 : ~~(l2 / 5) || 1, dots1 = [], dots2 = [], xy = {}, res = justCount ? 0 : []; for (var i = 0; i < n1 + 1; i++) { var p = findDotsAtSegment.apply(0, bez1.concat(i / n1)); dots1.push({ x: p.x, y: p.y, t: i / n1 }); } for (i = 0; i < n2 + 1; i++) { p = findDotsAtSegment.apply(0, bez2.concat(i / n2)); dots2.push({ x: p.x, y: p.y, t: i / n2 }); } for (i = 0; i < n1; i++) { for (var j = 0; j < n2; j++) { var di = dots1[i], di1 = dots1[i + 1], dj = dots2[j], dj1 = dots2[j + 1], ci = abs(di1.x - di.x) < .01 ? 'y' : 'x', cj = abs(dj1.x - dj.x) < .01 ? 'y' : 'x', is = intersectLines(di.x, di.y, di1.x, di1.y, dj.x, dj.y, dj1.x, dj1.y), key; if (is) { key = is.x.toFixed(9) + '#' + is.y.toFixed(9); if (xy[key]) { continue; } xy[key] = true; var t1 = di.t + abs((is[ci] - di[ci]) / (di1[ci] - di[ci])) * (di1.t - di.t), t2 = dj.t + abs((is[cj] - dj[cj]) / (dj1[cj] - dj[cj])) * (dj1.t - dj.t); if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) { if (justCount) { res++; } else { res.push({ x: is.x, y: is.y, t1: t1, t2: t2 }); } } } } } return res; } /** * Find or counts the intersections between two SVG paths. * * Returns a number in counting mode and a list of intersections otherwise. * * A single intersection entry contains the intersection coordinates (x, y) * as well as additional information regarding the intersecting segments * on each path (segment1, segment2) and the relative location of the * intersection on these segments (t1, t2). * * The path may be an SVG path string or a list of path components * such as `[ [ 'M', 0, 10 ], [ 'L', 20, 0 ] ]`. * * @example * * var intersections = findPathIntersections( * 'M0,0L100,100', * [ [ 'M', 0, 100 ], [ 'L', 100, 0 ] ] * ); * * // intersections = [ * // { x: 50, y: 50, segment1: 1, segment2: 1, t1: 0.5, t2: 0.5 } * // ] * * @param {String|Array<PathDef>} path1 * @param {String|Array<PathDef>} path2 * @param {Boolean} [justCount=false] * * @return {Array<Intersection>|Number} */ function findPathIntersections(path1, path2, justCount) { path1 = pathToCurve(path1); path2 = pathToCurve(path2); var x1, y1, x2, y2, x1m, y1m, x2m, y2m, bez1, bez2, res = justCount ? 0 : []; for (var i = 0, ii = path1.length; i < ii; i++) { var pi = path1[i]; if (pi[0] == 'M') { x1 = x1m = pi[1]; y1 = y1m = pi[2]; } else { if (pi[0] == 'C') { bez1 = [x1, y1].concat(pi.slice(1)); x1 = bez1[6]; y1 = bez1[7]; } else { bez1 = [x1, y1, x1, y1, x1m, y1m, x1m, y1m]; x1 = x1m; y1 = y1m; } for (var j = 0, jj = path2.length; j < jj; j++) { var pj = path2[j]; if (pj[0] == 'M') { x2 = x2m = pj[1]; y2 = y2m = pj[2]; } else { if (pj[0] == 'C') { bez2 = [x2, y2].concat(pj.slice(1)); x2 = bez2[6]; y2 = bez2[7]; } else { bez2 = [x2, y2, x2, y2, x2m, y2m, x2m, y2m]; x2 = x2m; y2 = y2m; } var intr = findBezierIntersections(bez1, bez2, justCount); if (justCount) { res += intr; } else { for (var k = 0, kk = intr.length; k < kk; k++) { intr[k].segment1 = i; intr[k].segment2 = j; intr[k].bez1 = bez1; intr[k].bez2 = bez2; } res = res.concat(intr); } } } } } return res; } function pathToAbsolute(pathArray) { var pth = paths(pathArray); if (pth.abs) { return pathClone(pth.abs); } if (!isArray(pathArray) || !isArray(pathArray && pathArray[0])) { // rough assumption pathArray = parsePathString(pathArray); } if (!pathArray || !pathArray.length) { return [['M', 0, 0]]; } var res = [], x = 0, y = 0, mx = 0, my = 0, start = 0, pa0; if (pathArray[0][0] == 'M') { x = +pathArray[0][1]; y = +pathArray[0][2]; mx = x; my = y; start++; res[0] = ['M', x, y]; } for (var r, pa, i = start, ii = pathArray.length; i < ii; i++) { res.push(r = []); pa = pathArray[i]; pa0 = pa[0]; if (pa0 != pa0.toUpperCase()) { r[0] = pa0.toUpperCase(); switch (r[0]) { case 'A': r[1] = pa[1]; r[2] = pa[2]; r[3] = pa[3]; r[4] = pa[4]; r[5] = pa[5]; r[6] = +pa[6] + x; r[7] = +pa[7] + y; break; case 'V': r[1] = +pa[1] + y; break; case 'H': r[1] = +pa[1] + x; break; case 'M': mx = +pa[1] + x; my = +pa[2] + y; default: for (var j = 1, jj = pa.length; j < jj; j++) { r[j] = +pa[j] + ((j % 2) ? x : y); } } } else { for (var k = 0, kk = pa.length; k < kk; k++) { r[k] = pa[k]; } } pa0 = pa0.toUpperCase(); switch (r[0]) { case 'Z': x = +mx; y = +my; break; case 'H': x = r[1]; break; case 'V': y = r[1]; break; case 'M': mx = r[r.length - 2]; my = r[r.length - 1]; default: x = r[r.length - 2]; y = r[r.length - 1]; } } res.toString = pathToString; pth.abs = pathClone(res); return res; } function isLine(bez) { return ( bez[0] === bez[2] && bez[1] === bez[3] && bez[4] === bez[6] && bez[5] === bez[7] ); } function lineToCurve(x1, y1, x2, y2) { return [ x1, y1, x2, y2, x2, y2 ]; } function qubicToCurve(x1, y1, ax, ay, x2, y2) { var _13 = 1 / 3, _23 = 2 / 3; return [ _13 * x1 + _23 * ax, _13 * y1 + _23 * ay, _13 * x2 + _23 * ax, _13 * y2 + _23 * ay, x2, y2 ]; } function arcToCurve(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) { // for more information of where this math came from visit: // http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes var _120 = PI * 120 / 180, rad = PI / 180 * (+angle || 0), res = [], xy, rotate = cacher(function(x, y, rad) { var X = x * math.cos(rad) - y * math.sin(rad), Y = x * math.sin(rad) + y * math.cos(rad); return { x: X, y: Y }; }); if (!recursive) { xy = rotate(x1, y1, -rad); x1 = xy.x; y1 = xy.y; xy = rotate(x2, y2, -rad); x2 = xy.x; y2 = xy.y; var x = (x1 - x2) / 2, y = (y1 - y2) / 2; var h = (x * x) / (rx * rx) + (y * y) / (ry * ry); if (h > 1) { h = math.sqrt(h); rx = h * rx; ry = h * ry; } var rx2 = rx * rx, ry2 = ry * ry, k = (large_arc_flag == sweep_flag ? -1 : 1) * math.sqrt(abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))), cx = k * rx * y / ry + (x1 + x2) / 2, cy = k * -ry * x / rx + (y1 + y2) / 2, f1 = math.asin(((y1 - cy) / ry).toFixed(9)), f2 = math.asin(((y2 - cy) / ry).toFixed(9)); f1 = x1 < cx ? PI - f1 : f1; f2 = x2 < cx ? PI - f2 : f2; f1 < 0 && (f1 = PI * 2 + f1); f2 < 0 && (f2 = PI * 2 + f2); if (sweep_flag && f1 > f2) { f1 = f1 - PI * 2; } if (!sweep_flag && f2 > f1) { f2 = f2 - PI * 2; } } else { f1 = recursive[0]; f2 = recursive[1]; cx = recursive[2]; cy = recursive[3]; } var df = f2 - f1; if (abs(df) > _120) { var f2old = f2, x2old = x2, y2old = y2; f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1); x2 = cx + rx * math.cos(f2); y2 = cy + ry * math.sin(f2); res = arcToCurve(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]); } df = f2 - f1; var c1 = math.cos(f1), s1 = math.sin(f1), c2 = math.cos(f2), s2 = math.sin(f2), t = math.tan(df / 4), hx = 4 / 3 * rx * t, hy = 4 / 3 * ry * t, m1 = [x1, y1], m2 = [x1 + hx * s1, y1 - hy * c1], m3 = [x2 + hx * s2, y2 - hy * c2], m4 = [x2, y2]; m2[0] = 2 * m1[0] - m2[0]; m2[1] = 2 * m1[1] - m2[1]; if (recursive) { return [m2, m3, m4].concat(res); } else { res = [m2, m3, m4].concat(res).join().split(','); var newres = []; for (var i = 0, ii = res.length; i < ii; i++) { newres[i] = i % 2 ? rotate(res[i - 1], res[i], rad).y : rotate(res[i], res[i + 1], rad).x; } return newres; } } // Returns bounding box of cubic bezier curve. // Source: http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html // Original version: NISHIO Hirokazu // Modifications: https://github.com/timo22345 function curveBBox(x0, y0, x1, y1, x2, y2, x3, y3) { var tvalues = [], bounds = [[], []], a, b, c, t, t1, t2, b2ac, sqrtb2ac; for (var i = 0; i < 2; ++i) { if (i == 0) { b = 6 * x0 - 12 * x1 + 6 * x2; a = -3 * x0 + 9 * x1 - 9 * x2 + 3 * x3; c = 3 * x1 - 3 * x0; } else { b = 6 * y0 - 12 * y1 + 6 * y2; a = -3 * y0 + 9 * y1 - 9 * y2 + 3 * y3; c = 3 * y1 - 3 * y0; } if (abs(a) < 1e-12) { if (abs(b) < 1e-12) { continue; } t = -c / b; if (0 < t && t < 1) { tvalues.push(t); } continue; } b2ac = b * b - 4 * c * a; sqrtb2ac = math.sqrt(b2ac); if (b2ac < 0) { continue; } t1 = (-b + sqrtb2ac) / (2 * a); if (0 < t1 && t1 < 1) { tvalues.push(t1); } t2 = (-b - sqrtb2ac) / (2 * a); if (0 < t2 && t2 < 1) { tvalues.push(t2); } } var j = tvalues.length, jlen = j, mt; while (j--) { t = tvalues[j]; mt = 1 - t; bounds[0][j] = (mt * mt * mt * x0) + (3 * mt * mt * t * x1) + (3 * mt * t * t * x2) + (t * t * t * x3); bounds[1][j] = (mt * mt * mt * y0) + (3 * mt * mt * t * y1) + (3 * mt * t * t * y2) + (t * t * t * y3); } bounds[0][jlen] = x0; bounds[1][jlen] = y0; bounds[0][jlen + 1] = x3; bounds[1][jlen + 1] = y3; bounds[0].length = bounds[1].length = jlen + 2; return { x0: mmin.apply(0, bounds[0]), y0: mmin.apply(0, bounds[1]), x1: mmax.apply(0, bounds[0]), y1: mmax.apply(0, bounds[1]) }; } function pathToCurve(path) { var pth = paths(path); // return cached curve, if existing if (pth.curve) { return pathClone(pth.curve); } var curvedPath = pathToAbsolute(path), attrs = { x: 0, y: 0, bx: 0, by: 0, X: 0, Y: 0, qx: null, qy: null }, processPath = function(path, d, pathCommand) { var nx, ny; if (!path) { return ['C', d.x, d.y, d.x, d.y, d.x, d.y]; } !(path[0] in { T: 1, Q: 1 }) && (d.qx = d.qy = null); switch (path[0]) { case 'M': d.X = path[1]; d.Y = path[2]; break; case 'A': path = ['C'].concat(arcToCurve.apply(0, [d.x, d.y].concat(path.slice(1)))); break; case 'S': if (pathCommand == 'C' || pathCommand == 'S') { // In 'S' case we have to take into account, if the previous command is C/S. nx = d.x * 2 - d.bx; // And reflect the previous ny = d.y * 2 - d.by; // command's control point relative to the current point. } else { // or some else or nothing nx = d.x; ny = d.y; } path = ['C', nx, ny].concat(path.slice(1)); break; case 'T': if (pathCommand == 'Q' || pathCommand == 'T') { // In 'T' case we have to take into account, if the previous command is Q/T. d.qx = d.x * 2 - d.qx; // And make a reflection similar d.qy = d.y * 2 - d.qy; // to case 'S'. } else { // or something else or nothing d.qx = d.x; d.qy = d.y; } path = ['C'].concat(qubicToCurve(d.x, d.y, d.qx, d.qy, path[1], path[2])); break; case 'Q': d.qx = path[1]; d.qy = path[2]; path = ['C'].concat(qubicToCurve(d.x, d.y, path[1], path[2], path[3], path[4])); break; case 'L': path = ['C'].concat(lineToCurve(d.x, d.y, path[1], path[2])); break; case 'H': path = ['C'].concat(lineToCurve(d.x, d.y, path[1], d.y)); break; case 'V': path = ['C'].concat(lineToCurve(d.x, d.y, d.x, path[1])); break; case 'Z': path = ['C'].concat(lineToCurve(d.x, d.y, d.X, d.Y)); break; } return path; }, fixArc = function(pp, i) { if (pp[i].length > 7) { pp[i].shift(); var pi = pp[i]; while (pi.length) { pathCommands[i] = 'A'; // if created multiple C:s, their original seg is saved pp.splice(i++, 0, ['C'].concat(pi.splice(0, 6))); } pp.splice(i, 1); ii = curvedPath.length; } }, pathCommands = [], // path commands of original path p pfirst = '', // temporary holder for original path command pathCommand = ''; // holder for previous path command of original path for (var i = 0, ii = curvedPath.length; i < ii; i++) { curvedPath[i] && (pfirst = curvedPath[i][0]); // save current path command if (pfirst != 'C') // C is not saved yet, because it may be result of conversion { pathCommands[i] = pfirst; // Save current path command i && (pathCommand = pathCommands[i - 1]); // Get previous path command pathCommand } curvedPath[i] = processPath(curvedPath[i], attrs, pathCommand); // Previous path command is inputted to processPath if (pathCommands[i] != 'A' && pfirst == 'C') pathCommands[i] = 'C'; // A is the only command // which may produce multiple C:s // so we have to make sure that C is also C in original path fixArc(curvedPath, i); // fixArc adds also the right amount of A:s to pathCommands var seg = curvedPath[i], seglen = seg.length; attrs.x = seg[seglen - 2]; attrs.y = seg[seglen - 1]; attrs.bx = toFloat(seg[seglen - 4]) || attrs.x; attrs.by = toFloat(seg[seglen - 3]) || attrs.y; } // cache curve pth.curve = pathClone(curvedPath); return curvedPath; } module.exports = findPathIntersections; },{}],564:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Parser = Parser; exports.decode = decodeEntities; var fromCharCode = String.fromCharCode; var hasOwnProperty = Object.prototype.hasOwnProperty; var ENTITY_PATTERN = /&#(\d+);|&#x([0-9a-f]+);|&(\w+);/ig; var ENTITY_MAPPING = { 'amp': '&', 'apos': '\'', 'gt': '>', 'lt': '<', 'quot': '"' }; // map UPPERCASE variants of supported special chars Object.keys(ENTITY_MAPPING).forEach(function (k) { ENTITY_MAPPING[k.toUpperCase()] = ENTITY_MAPPING[k]; }); function replaceEntities(_, d, x, z) { // reserved names, i.e. if (z) { if (hasOwnProperty.call(ENTITY_MAPPING, z)) { return ENTITY_MAPPING[z]; } else { // fall back to original value return '&' + z + ';'; } } // decimal encoded char if (d) { return fromCharCode(d); } // hex encoded char return fromCharCode(parseInt(x, 16)); } /** * A basic entity decoder that can decode a minimal * sub-set of reserved names (&) as well as * hex (ય) and decimal (ӏ) encoded characters. * * @param {string} str * * @return {string} decoded string */ function decodeEntities(s) { if (s.length > 3 && s.indexOf('&') !== -1) { return s.replace(ENTITY_PATTERN, replaceEntities); } return s; } var XSI_URI = 'http://www.w3.org/2001/XMLSchema-instance'; var XSI_PREFIX = 'xsi'; var XSI_TYPE = 'xsi:type'; var NON_WHITESPACE_OUTSIDE_ROOT_NODE = 'non-whitespace outside of root node'; function error(msg) { return new Error(msg); } function missingNamespaceForPrefix(prefix) { return 'missing namespace for prefix <' + prefix + '>'; } function getter(getFn) { return { 'get': getFn, 'enumerable': true }; } function cloneNsMatrix(nsMatrix) { var clone = {}, key; for (key in nsMatrix) { clone[key] = nsMatrix[key]; } return clone; } function uriPrefix(prefix) { return prefix + '$uri'; } function buildNsMatrix(nsUriToPrefix) { var nsMatrix = {}, uri, prefix; for (uri in nsUriToPrefix) { prefix = nsUriToPrefix[uri]; nsMatrix[prefix] = prefix; nsMatrix[uriPrefix(prefix)] = uri; } return nsMatrix; } function noopGetContext() { return { 'line': 0, 'column': 0 }; } function throwFunc(err) { throw err; } /** * Creates a new parser with the given options. * * @constructor * * @param {!Object<string, ?>=} options */ function Parser(options) { if (!this) { return new Parser(options); } var proxy = options && options['proxy']; var onText, onOpenTag, onCloseTag, onCDATA, onError = throwFunc, onWarning, onComment, onQuestion, onAttention; var getContext = noopGetContext; /** * Do we need to parse the current elements attributes for namespaces? * * @type {boolean} */ var maybeNS = false; /** * Do we process namespaces at all? * * @type {boolean} */ var isNamespace = false; /** * The caught error returned on parse end * * @type {Error} */ var returnError = null; /** * Should we stop parsing? * * @type {boolean} */ var parseStop = false; /** * A map of { uri: prefix } used by the parser. * * This map will ensure we can normalize prefixes during processing; * for each uri, only one prefix will be exposed to the handlers. * * @type {!Object<string, string>}} */ var nsUriToPrefix; /** * Handle parse error. * * @param {string|Error} err */ function handleError(err) { if (!(err instanceof Error)) { err = error(err); } returnError = err; onError(err, getContext); } /** * Handle parse error. * * @param {string|Error} err */ function handleWarning(err) { if (!onWarning) { return; } if (!(err instanceof Error)) { err = error(err); } onWarning(err, getContext); } /** * Register parse listener. * * @param {string} name * @param {Function} cb * * @return {Parser} */ this['on'] = function (name, cb) { if (typeof cb !== 'function') { throw error('required args <name, cb>'); } switch (name) { case 'openTag': onOpenTag = cb; break; case 'text': onText = cb; break; case 'closeTag': onCloseTag = cb; break; case 'error': onError = cb; break; case 'warn': onWarning = cb; break; case 'cdata': onCDATA = cb; break; case 'attention': onAttention = cb; break; // <!XXXXX zzzz="eeee"> case 'question': onQuestion = cb; break; // <? .... ?> case 'comment': onComment = cb; break; default: throw error('unsupported event: ' + name); } return this; }; /** * Set the namespace to prefix mapping. * * @example * * parser.ns({ * 'http://foo': 'foo', * 'http://bar': 'bar' * }); * * @param {!Object<string, string>} nsMap * * @return {Parser} */ this['ns'] = function (nsMap) { if (typeof nsMap === 'undefined') { nsMap = {}; } if (typeof nsMap !== 'object') { throw error('required args <nsMap={}>'); } var _nsUriToPrefix = {}, k; for (k in nsMap) { _nsUriToPrefix[k] = nsMap[k]; } // FORCE default mapping for schema instance _nsUriToPrefix[XSI_URI] = XSI_PREFIX; isNamespace = true; nsUriToPrefix = _nsUriToPrefix; return this; }; /** * Parse xml string. * * @param {string} xml * * @return {Error} returnError, if not thrown */ this['parse'] = function (xml) { if (typeof xml !== 'string') { throw error('required args <xml=string>'); } returnError = null; parse(xml); getContext = noopGetContext; parseStop = false; return returnError; }; /** * Stop parsing. */ this['stop'] = function () { parseStop = true; }; /** * Parse string, invoking configured listeners on element. * * @param {string} xml */ function parse(xml) { var nsMatrixStack = isNamespace ? [] : null, nsMatrix = isNamespace ? buildNsMatrix(nsUriToPrefix) : null, _nsMatrix, nodeStack = [], anonymousNsCount = 0, tagStart = false, tagEnd = false, i = 0, j = 0, x, y, q, w, v, xmlns, elementName, _elementName, elementProxy; var attrsString = '', attrsStart = 0, cachedAttrs // false = parsed with errors, null = needs parsing ; /** * Parse attributes on demand and returns the parsed attributes. * * Return semantics: (1) `false` on attribute parse error, * (2) object hash on extracted attrs. * * @return {boolean|Object} */ function getAttrs() { if (cachedAttrs !== null) { return cachedAttrs; } var nsUri, nsUriPrefix, nsName, defaultAlias = isNamespace && nsMatrix['xmlns'], attrList = isNamespace && maybeNS ? [] : null, i = attrsStart, s = attrsString, l = s.length, hasNewMatrix, newalias, value, alias, name, attrs = {}, seenAttrs = {}, skipAttr, w, j; parseAttr: for (; i < l; i++) { skipAttr = false; w = s.charCodeAt(i); if (w === 32 || w < 14 && w > 8) { // WHITESPACE={ \f\n\r\t\v} continue; } // wait for non whitespace character if (w < 65 || w > 122 || w > 90 && w < 97) { if (w !== 95 && w !== 58) { // char 95"_" 58":" handleWarning('illegal first char attribute name'); skipAttr = true; } } // parse attribute name for (j = i + 1; j < l; j++) { w = s.charCodeAt(j); if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 46 || // '.' w === 45 || // '-' w === 95 // '_' ) { continue; } // unexpected whitespace if (w === 32 || w < 14 && w > 8) { // WHITESPACE handleWarning('missing attribute value'); i = j; continue parseAttr; } // expected "=" if (w === 61) { // "=" == 61 break; } handleWarning('illegal attribute name char'); skipAttr = true; } name = s.substring(i, j); if (name === 'xmlns:xmlns') { handleWarning('illegal declaration of xmlns'); skipAttr = true; } w = s.charCodeAt(j + 1); if (w === 34) { // '"' j = s.indexOf('"', i = j + 2); if (j === -1) { j = s.indexOf('\'', i); if (j !== -1) { handleWarning('attribute value quote missmatch'); skipAttr = true; } } } else if (w === 39) { // "'" j = s.indexOf('\'', i = j + 2); if (j === -1) { j = s.indexOf('"', i); if (j !== -1) { handleWarning('attribute value quote missmatch'); skipAttr = true; } } } else { handleWarning('missing attribute value quotes'); skipAttr = true; // skip to next space for (j = j + 1; j < l; j++) { w = s.charCodeAt(j + 1); if (w === 32 || w < 14 && w > 8) { // WHITESPACE break; } } } if (j === -1) { handleWarning('missing closing quotes'); j = l; skipAttr = true; } if (!skipAttr) { value = s.substring(i, j); } i = j; // ensure SPACE follows attribute // skip illegal content otherwise // example a="b"c for (; j + 1 < l; j++) { w = s.charCodeAt(j + 1); if (w === 32 || w < 14 && w > 8) { // WHITESPACE break; } // FIRST ILLEGAL CHAR if (i === j) { handleWarning('illegal character after attribute end'); skipAttr = true; } } // advance cursor to next attribute i = j + 1; if (skipAttr) { continue parseAttr; } // check attribute re-declaration if (name in seenAttrs) { handleWarning('attribute <' + name + '> already defined'); continue; } seenAttrs[name] = true; if (!isNamespace) { attrs[name] = value; continue; } // try to extract namespace information if (maybeNS) { newalias = name === 'xmlns' ? 'xmlns' : name.charCodeAt(0) === 120 && name.substr(0, 6) === 'xmlns:' ? name.substr(6) : null; // handle xmlns(:alias) assignment if (newalias !== null) { nsUri = decodeEntities(value); nsUriPrefix = uriPrefix(newalias); alias = nsUriToPrefix[nsUri]; if (!alias) { // no prefix defined or prefix collision if (newalias === 'xmlns' || nsUriPrefix in nsMatrix && nsMatrix[nsUriPrefix] !== nsUri) { // alocate free ns prefix do { alias = 'ns' + anonymousNsCount++; } while (typeof nsMatrix[alias] !== 'undefined'); } else { alias = newalias; } nsUriToPrefix[nsUri] = alias; } if (nsMatrix[newalias] !== alias) { if (!hasNewMatrix) { nsMatrix = cloneNsMatrix(nsMatrix); hasNewMatrix = true; } nsMatrix[newalias] = alias; if (newalias === 'xmlns') { nsMatrix[uriPrefix(alias)] = nsUri; defaultAlias = alias; } nsMatrix[nsUriPrefix] = nsUri; } // expose xmlns(:asd)="..." in attributes attrs[name] = value; continue; } // collect attributes until all namespace // declarations are processed attrList.push(name, value); continue; } /** end if (maybeNs) */ // handle attributes on element without // namespace declarations w = name.indexOf(':'); if (w === -1) { attrs[name] = value; continue; } // normalize ns attribute name if (!(nsName = nsMatrix[name.substring(0, w)])) { handleWarning(missingNamespaceForPrefix(name.substring(0, w))); continue; } name = defaultAlias === nsName ? name.substr(w + 1) : nsName + name.substr(w); // end: normalize ns attribute name // normalize xsi:type ns attribute value if (name === XSI_TYPE) { w = value.indexOf(':'); if (w !== -1) { nsName = value.substring(0, w); // handle default prefixes, i.e. xs:String gracefully nsName = nsMatrix[nsName] || nsName; value = nsName + value.substring(w); } else { value = defaultAlias + ':' + value; } } // end: normalize xsi:type ns attribute value attrs[name] = value; } // handle deferred, possibly namespaced attributes if (maybeNS) { // normalize captured attributes for (i = 0, l = attrList.length; i < l; i++) { name = attrList[i++]; value = attrList[i]; w = name.indexOf(':'); if (w !== -1) { // normalize ns attribute name if (!(nsName = nsMatrix[name.substring(0, w)])) { handleWarning(missingNamespaceForPrefix(name.substring(0, w))); continue; } name = defaultAlias === nsName ? name.substr(w + 1) : nsName + name.substr(w); // end: normalize ns attribute name // normalize xsi:type ns attribute value if (name === XSI_TYPE) { w = value.indexOf(':'); if (w !== -1) { nsName = value.substring(0, w); // handle default prefixes, i.e. xs:String gracefully nsName = nsMatrix[nsName] || nsName; value = nsName + value.substring(w); } else { value = defaultAlias + ':' + value; } } // end: normalize xsi:type ns attribute value } attrs[name] = value; } // end: normalize captured attributes } return cachedAttrs = attrs; } /** * Extract the parse context { line, column, part } * from the current parser position. * * @return {Object} parse context */ function getParseContext() { var splitsRe = /(\r\n|\r|\n)/g; var line = 0; var column = 0; var startOfLine = 0; var endOfLine = j; var match; var data; while (i >= startOfLine) { match = splitsRe.exec(xml); if (!match) { break; } // end of line = (break idx + break chars) endOfLine = match[0].length + match.index; if (endOfLine > i) { break; } // advance to next line line += 1; startOfLine = endOfLine; } // EOF errors if (i == -1) { column = endOfLine; data = xml.substring(j); } else // start errors if (j === 0) { data = xml.substring(j, i); } // other errors else { column = i - startOfLine; data = j == -1 ? xml.substring(i) : xml.substring(i, j + 1); } return { 'data': data, 'line': line, 'column': column }; } getContext = getParseContext; if (proxy) { elementProxy = Object.create({}, { 'name': getter(function () { return elementName; }), 'originalName': getter(function () { return _elementName; }), 'attrs': getter(getAttrs), 'ns': getter(function () { return nsMatrix; }) }); } // actual parse logic while (j !== -1) { if (xml.charCodeAt(j) === 60) { // "<" i = j; } else { i = xml.indexOf('<', j); } // parse end if (i === -1) { if (nodeStack.length) { return handleError('unexpected end of file'); } if (j === 0) { return handleError('missing start tag'); } if (j < xml.length) { if (xml.substring(j).trim()) { handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE); } } return; } // parse text if (j !== i) { if (nodeStack.length) { if (onText) { onText(xml.substring(j, i), decodeEntities, getContext); if (parseStop) { return; } } } else { if (xml.substring(j, i).trim()) { handleWarning(NON_WHITESPACE_OUTSIDE_ROOT_NODE); if (parseStop) { return; } } } } w = xml.charCodeAt(i + 1); // parse comments + CDATA if (w === 33) { // "!" q = xml.charCodeAt(i + 2); // CDATA section if (q === 91 && xml.substr(i + 3, 6) === 'CDATA[') { // 91 == "[" j = xml.indexOf(']]>', i); if (j === -1) { return handleError('unclosed cdata'); } if (onCDATA) { onCDATA(xml.substring(i + 9, j), getContext); if (parseStop) { return; } } j += 3; continue; } // comment if (q === 45 && xml.charCodeAt(i + 3) === 45) { // 45 == "-" j = xml.indexOf('-->', i); if (j === -1) { return handleError('unclosed comment'); } if (onComment) { onComment(xml.substring(i + 4, j), decodeEntities, getContext); if (parseStop) { return; } } j += 3; continue; } } // parse question <? ... ?> if (w === 63) { // "?" j = xml.indexOf('?>', i); if (j === -1) { return handleError('unclosed question'); } if (onQuestion) { onQuestion(xml.substring(i, j + 2), getContext); if (parseStop) { return; } } j += 2; continue; } // find matching closing tag for attention or standard tags // for that we must skip through attribute values // (enclosed in single or double quotes) for (x = i + 1;; x++) { v = xml.charCodeAt(x); if (isNaN(v)) { j = -1; return handleError('unclosed tag'); } // [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'" // skips the quoted string // (double quotes) does not appear in a literal enclosed by (double quotes) // (single quote) does not appear in a literal enclosed by (single quote) if (v === 34) { // '"' q = xml.indexOf('"', x + 1); x = q !== -1 ? q : x; } else if (v === 39) { // "'" q = xml.indexOf("'", x + 1); x = q !== -1 ? q : x; } else if (v === 62) { // '>' j = x; break; } } // parse attention <! ...> // previously comment and CDATA have already been parsed if (w === 33) { // "!" if (onAttention) { onAttention(xml.substring(i, j + 1), decodeEntities, getContext); if (parseStop) { return; } } j += 1; continue; } // don't process attributes; // there are none cachedAttrs = {}; // if (xml.charCodeAt(i+1) === 47) { // </... if (w === 47) { // </... tagStart = false; tagEnd = true; if (!nodeStack.length) { return handleError('missing open tag'); } // verify open <-> close tag match x = elementName = nodeStack.pop(); q = i + 2 + x.length; if (xml.substring(i + 2, q) !== x) { return handleError('closing tag mismatch'); } // verify chars in close tag for (; q < j; q++) { w = xml.charCodeAt(q); if (w === 32 || w > 8 && w < 14) { // \f\n\r\t\v space continue; } return handleError('close tag'); } } else { if (xml.charCodeAt(j - 1) === 47) { // .../> x = elementName = xml.substring(i + 1, j - 1); tagStart = true; tagEnd = true; } else { x = elementName = xml.substring(i + 1, j); tagStart = true; tagEnd = false; } if (!(w > 96 && w < 123 || w > 64 && w < 91 || w === 95 || w === 58)) { // char 95"_" 58":" return handleError('illegal first char nodeName'); } for (q = 1, y = x.length; q < y; q++) { w = x.charCodeAt(q); if (w > 96 && w < 123 || w > 64 && w < 91 || w > 47 && w < 59 || w === 45 || w === 95 || w == 46) { continue; } if (w === 32 || w < 14 && w > 8) { // \f\n\r\t\v space elementName = x.substring(0, q); // maybe there are attributes cachedAttrs = null; break; } return handleError('invalid nodeName'); } if (!tagEnd) { nodeStack.push(elementName); } } if (isNamespace) { _nsMatrix = nsMatrix; if (tagStart) { // remember old namespace // unless we're self-closing if (!tagEnd) { nsMatrixStack.push(_nsMatrix); } if (cachedAttrs === null) { // quick check, whether there may be namespace // declarations on the node; if that is the case // we need to eagerly parse the node attributes if (maybeNS = x.indexOf('xmlns', q) !== -1) { attrsStart = q; attrsString = x; getAttrs(); maybeNS = false; } } } _elementName = elementName; w = elementName.indexOf(':'); if (w !== -1) { xmlns = nsMatrix[elementName.substring(0, w)]; // prefix given; namespace must exist if (!xmlns) { return handleError('missing namespace on <' + _elementName + '>'); } elementName = elementName.substr(w + 1); } else { xmlns = nsMatrix['xmlns']; // if no default namespace is defined, // we'll import the element as anonymous. // // it is up to users to correct that to the document defined // targetNamespace, or whatever their undersanding of the // XML spec mandates. } // adjust namespace prefixs as configured if (xmlns) { elementName = xmlns + ':' + elementName; } } if (tagStart) { attrsStart = q; attrsString = x; if (onOpenTag) { if (proxy) { onOpenTag(elementProxy, decodeEntities, tagEnd, getContext); } else { onOpenTag(elementName, getAttrs, decodeEntities, tagEnd, getContext); } if (parseStop) { return; } } } if (tagEnd) { if (onCloseTag) { onCloseTag(proxy ? elementProxy : elementName, decodeEntities, tagStart, getContext); if (parseStop) { return; } } // restore old namespace if (isNamespace) { if (!tagStart) { nsMatrix = nsMatrixStack.pop(); } else { nsMatrix = _nsMatrix; } } } j += 1; } } /** end parse */ } },{}],565:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = create; var _minDom = require("min-dom"); var _minDash = require("min-dash"); var _mitt = _interopRequireDefault(require("mitt")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var DEFAULT_OPTIONS = { scrollSymbolLeft: '‹', scrollSymbolRight: '›' }; /** * This component adds the functionality to scroll over a list of tabs. * * It adds scroll buttons on the left and right side of the tabs container * if not all tabs are visible. It also adds a mouse wheel listener on the * container. * * If either a button is clicked or the mouse wheel is used over the tabs, * a 'scroll' event is being fired. This event contains the node elements * of the new and old active tab, and the direction in which the tab has * changed relative to the old active tab. * * @example: * (1) provide a tabs-container: * * var $el = ( * <div> * <!-- button added by scrollTabs --> * <span class="scroll-tabs-button scroll-tabs-left"></span> * <ul class="my-tabs-container"> * <li class="my-tab i-am-active"></li> * <li class="my-tab"></li> * <li class="my-tab ignore-me"></li> * </ul> * <!-- button added by scrollTabs --> * <span class="scroll-tabs-button scroll-tabs-right"></span> * </div> * ); * * * (2) initialize scrollTabs: * * var scroller = scrollTabs(tabBarNode, { * selectors: { * tabsContainer: '.my-tabs-container', * tab: '.my-tab', * ignore: '.ignore-me', * active: '.i-am-active' * } * }); * * * (3) listen to the scroll event: * * scroller.on('scroll', function(newActiveNode, oldActiveNode, direction) { * // direction is any of (-1: left, 1: right) * // activate the new active tab * }); * * * (4) update the scroller if tabs change and or the tab container resizes: * * scroller.update(); * * * @param {DOMElement} el * @param {Object} options * @param {Object} options.selectors * @param {String} options.selectors.tabsContainer the container all tabs are contained in * @param {String} options.selectors.tab a single tab inside the tab container * @param {String} options.selectors.ignore tabs that should be ignored during scroll left/right * @param {String} options.selectors.active selector for the current active tab * @param {String} [options.scrollSymbolLeft] * @param {String} [options.scrollSymbolRight] */ function ScrollTabs($el, options) { // we are an event emitter (0, _minDash.assign)(this, (0, _mitt.default)()); this.options = options = (0, _minDash.assign)({}, DEFAULT_OPTIONS, options); this.container = $el; this._createScrollButtons($el, options); this._bindEvents($el); } /** * Create a clickable scroll button * * @param {Object} options * @param {String} options.className * @param {String} options.label * @param {Number} options.direction * * @return {DOMElement} The created scroll button node */ ScrollTabs.prototype._createButton = function (parentNode, options) { var className = options.className, direction = options.direction; var button = (0, _minDom.query)('.' + className, parentNode); if (!button) { button = (0, _minDom.domify)('<span class="scroll-tabs-button ' + className + '">' + options.label + '</span>'); parentNode.insertBefore(button, parentNode.childNodes[0]); } (0, _minDom.attr)(button, 'data-direction', direction); return button; }; /** * Create both scroll buttons * * @param {DOMElement} parentNode * @param {Object} options * @param {String} options.scrollSymbolLeft * @param {String} options.scrollSymbolRight */ ScrollTabs.prototype._createScrollButtons = function (parentNode, options) { // Create a button that scrolls to the tab left to the currently active tab this._createButton(parentNode, { className: 'scroll-tabs-left', label: options.scrollSymbolLeft, direction: -1 }); // Create a button that scrolls to the tab right to the currently active tab this._createButton(parentNode, { className: 'scroll-tabs-right', label: options.scrollSymbolRight, direction: 1 }); }; /** * Get the current active tab * * @return {DOMElement} */ ScrollTabs.prototype.getActiveTabNode = function () { return (0, _minDom.query)(this.options.selectors.active, this.container); }; /** * Get the container all tabs are contained in * * @return {DOMElement} */ ScrollTabs.prototype.getTabsContainerNode = function () { return (0, _minDom.query)(this.options.selectors.tabsContainer, this.container); }; /** * Get all tabs (visible and invisible ones) * * @return {Array<DOMElement>} */ ScrollTabs.prototype.getAllTabNodes = function () { return (0, _minDom.queryAll)(this.options.selectors.tab, this.container); }; /** * Gets all tabs that don't have the ignore class set * * @return {Array<DOMElement>} */ ScrollTabs.prototype.getVisibleTabs = function () { var allTabs = this.getAllTabNodes(); var ignore = this.options.selectors.ignore; return (0, _minDash.filter)(allTabs, function (tabNode) { return !(0, _minDom.matches)(tabNode, ignore); }); }; /** * Get a tab relative to a reference tab. * * @param {DOMElement} referenceTabNode * @param {Number} n gets the nth tab next or previous to the reference tab * * @return {DOMElement} * * @example: * Visible tabs: [ A | B | C | D | E ] * Assume tab 'C' is the reference tab: * If direction === -1, it returns tab 'B', * if direction === 2, it returns tab 'E' */ ScrollTabs.prototype.getAdjacentTab = function (referenceTabNode, n) { var visibleTabs = this.getVisibleTabs(); var index = visibleTabs.indexOf(referenceTabNode); return visibleTabs[index + n]; }; ScrollTabs.prototype._bindEvents = function (node) { this._bindWheelEvent(node); this._bindTabClickEvents(node); this._bindScrollButtonEvents(node); }; /** * Bind a click listener to a DOM node. * Make sure a tab link is entirely visible after onClick. * * @param {DOMElement} node */ ScrollTabs.prototype._bindTabClickEvents = function (node) { var selector = this.options.selectors.tab; var self = this; _minDom.delegate.bind(node, selector, 'click', function onClick(event) { self.scrollToTabNode(event.delegateTarget); }); }; /** * Bind the wheel event listener to a DOM node * * @param {DOMElement} node */ ScrollTabs.prototype._bindWheelEvent = function (node) { var self = this; _minDom.event.bind(node, 'wheel', function (e) { // scroll direction (-1: left, 1: right) var direction = Math.sign(e.deltaY); var oldActiveTab = self.getActiveTabNode(); var newActiveTab = self.getAdjacentTab(oldActiveTab, direction); if (newActiveTab) { self.scrollToTabNode(newActiveTab); self.emit('scroll', newActiveTab, oldActiveTab, direction); } e.preventDefault(); }); }; /** * Bind scroll button events to a DOM node * * @param {DOMElement} node */ ScrollTabs.prototype._bindScrollButtonEvents = function (node) { var self = this; _minDom.delegate.bind(node, '.scroll-tabs-button', 'click', function (event) { var target = event.delegateTarget; // data-direction is either -1 or 1 var direction = parseInt((0, _minDom.attr)(target, 'data-direction'), 10); var oldActiveTabNode = self.getActiveTabNode(); var newActiveTabNode = self.getAdjacentTab(oldActiveTabNode, direction); if (newActiveTabNode) { self.scrollToTabNode(newActiveTabNode); self.emit('scroll', newActiveTabNode, oldActiveTabNode, direction); } event.preventDefault(); }); }; /** * Scroll to a tab if it is not entirely visible * * @param {DOMElement} tabNode tab node to scroll to */ ScrollTabs.prototype.scrollToTabNode = function (tabNode) { if (!tabNode) { return; } var tabsContainerNode = tabNode.parentNode; var tabWidth = tabNode.offsetWidth, tabOffsetLeft = tabNode.offsetLeft, tabOffsetRight = tabOffsetLeft + tabWidth, containerWidth = tabsContainerNode.offsetWidth, containerScrollLeft = tabsContainerNode.scrollLeft; if (containerScrollLeft > tabOffsetLeft) { // scroll to the left, if the tab is overflowing on the left side tabsContainerNode.scrollLeft = 0; } else if (tabOffsetRight > containerWidth) { // scroll to the right, if the tab is overflowing on the right side tabsContainerNode.scrollLeft = tabOffsetRight - containerWidth; } }; /** * React on tab changes from outside (resize/show/hide/add/remove), * update scroll button visibility. */ ScrollTabs.prototype.update = function () { var tabsContainerNode = this.getTabsContainerNode(); // check if tabs fit in container var overflow = tabsContainerNode.scrollWidth > tabsContainerNode.offsetWidth; // TODO(nikku): distinguish overflow left / overflow right? var overflowClass = 'scroll-tabs-overflow'; (0, _minDom.classes)(this.container).toggle(overflowClass, overflow); if (overflow) { // make sure the current active tab is always visible this.scrollToTabNode(this.getActiveTabNode()); } }; // exports //////////////// /** * Create a scrollTabs instance on the given element. * * @param {DOMElement} $el * @param {Object} options * * @return {ScrollTabs} */ function create($el, options) { var scrollTabs = get($el); if (!scrollTabs) { scrollTabs = new ScrollTabs($el, options); $el.__scrollTabs = scrollTabs; } return scrollTabs; } /** * Return the scrollTabs instance that has been previously * initialized on the element. * * @param {DOMElement} $el * @return {ScrollTabs} */ function get($el) { return $el.__scrollTabs; } create.get = get; },{"min-dash":555,"min-dom":556,"mitt":557}],566:[function(require,module,exports){ 'use strict'; /** * Calculate the selection update for the given * current and new input values. * * @param {Object} currentSelection as {start, end} * @param {String} currentValue * @param {String} newValue * * @return {Object} newSelection as {start, end} */ function calculateUpdate(currentSelection, currentValue, newValue) { var currentCursor = currentSelection.start, newCursor = currentCursor, diff = newValue.length - currentValue.length, idx; var lengthDelta = newValue.length - currentValue.length; var currentTail = currentValue.substring(currentCursor); // check if we can remove common ending from the equation // to be able to properly detect a selection change for // the following scenarios: // // * (AAATTT|TF) => (AAAT|TF) // * (AAAT|TF) => (AAATTT|TF) // if (newValue.lastIndexOf(currentTail) === newValue.length - currentTail.length) { currentValue = currentValue.substring(0, currentValue.length - currentTail.length); newValue = newValue.substring(0, newValue.length - currentTail.length); } // diff var diff = createDiff(currentValue, newValue); if (diff) { if (diff.type === 'remove') { newCursor = diff.newStart; } else { newCursor = diff.newEnd; } } return range(newCursor); } module.exports = calculateUpdate; function createDiff(currentValue, newValue) { var insert; var l_str, l_char, l_idx = 0, s_str, s_char, s_idx = 0; if (newValue.length > currentValue.length) { l_str = newValue; s_str = currentValue; } else { l_str = currentValue; s_str = newValue; } // assume there will be only one insert / remove and // detect that _first_ edit operation only while (l_idx < l_str.length) { l_char = l_str.charAt(l_idx); s_char = s_str.charAt(s_idx); // chars no not equal if (l_char !== s_char) { if (!insert) { insert = { l_start: l_idx, s_start: s_idx }; } l_idx++; } // chars equal (again?) else { if (insert && !insert.complete) { insert.l_end = l_idx; insert.s_end = s_idx; insert.complete = true; } s_idx++; l_idx++; } } if (insert && !insert.complete) { insert.complete = true; insert.s_end = s_str.length; insert.l_end = l_str.length; } // no diff if (!insert) { return; } if (newValue.length > currentValue.length) { return { newStart: insert.l_start, newEnd: insert.l_end, type: 'add' }; } else { return { newStart: insert.s_start, newEnd: insert.s_end, type: newValue.length < currentValue.length ? 'remove' : 'replace' }; } } /** * Utility method for creating a new selection range {start, end} object. * * @param {Number} start * @param {Number} [end] * * @return {Object} selection range as {start, end} */ function range(start, end) { return { start: start, end: end === undefined ? start : end }; } module.exports.range = range; function splitStr(str, position) { return { before: str.substring(0, position), after: str.substring(position) }; } },{}],567:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.append = append; exports.appendTo = appendTo; exports.attr = attr; exports.classes = classes; exports.clear = clear; exports.clone = clone; exports.create = create; exports.innerSVG = innerSVG; exports.prepend = prepend; exports.prependTo = prependTo; exports.remove = remove; exports.replace = replace; exports.transform = transform; exports.on = on; exports.off = off; exports.createPoint = createPoint; exports.createMatrix = createMatrix; exports.createTransform = createTransform; exports.select = select; exports.selectAll = selectAll; function ensureImported(element, target) { if (element.ownerDocument !== target.ownerDocument) { try { // may fail on webkit return target.ownerDocument.importNode(element, true); } catch (e) {// ignore } } return element; } /** * appendTo utility */ /** * Append a node to a target element and return the appended node. * * @param {SVGElement} element * @param {SVGElement} target * * @return {SVGElement} the appended node */ function appendTo(element, target) { return target.appendChild(ensureImported(element, target)); } /** * append utility */ /** * Append a node to an element * * @param {SVGElement} element * @param {SVGElement} node * * @return {SVGElement} the element */ function append(target, node) { appendTo(node, target); return target; } /** * attribute accessor utility */ var LENGTH_ATTR = 2; var CSS_PROPERTIES = { 'alignment-baseline': 1, 'baseline-shift': 1, 'clip': 1, 'clip-path': 1, 'clip-rule': 1, 'color': 1, 'color-interpolation': 1, 'color-interpolation-filters': 1, 'color-profile': 1, 'color-rendering': 1, 'cursor': 1, 'direction': 1, 'display': 1, 'dominant-baseline': 1, 'enable-background': 1, 'fill': 1, 'fill-opacity': 1, 'fill-rule': 1, 'filter': 1, 'flood-color': 1, 'flood-opacity': 1, 'font': 1, 'font-family': 1, 'font-size': LENGTH_ATTR, 'font-size-adjust': 1, 'font-stretch': 1, 'font-style': 1, 'font-variant': 1, 'font-weight': 1, 'glyph-orientation-horizontal': 1, 'glyph-orientation-vertical': 1, 'image-rendering': 1, 'kerning': 1, 'letter-spacing': 1, 'lighting-color': 1, 'marker': 1, 'marker-end': 1, 'marker-mid': 1, 'marker-start': 1, 'mask': 1, 'opacity': 1, 'overflow': 1, 'pointer-events': 1, 'shape-rendering': 1, 'stop-color': 1, 'stop-opacity': 1, 'stroke': 1, 'stroke-dasharray': 1, 'stroke-dashoffset': 1, 'stroke-linecap': 1, 'stroke-linejoin': 1, 'stroke-miterlimit': 1, 'stroke-opacity': 1, 'stroke-width': LENGTH_ATTR, 'text-anchor': 1, 'text-decoration': 1, 'text-rendering': 1, 'unicode-bidi': 1, 'visibility': 1, 'word-spacing': 1, 'writing-mode': 1 }; function getAttribute(node, name) { if (CSS_PROPERTIES[name]) { return node.style[name]; } else { return node.getAttributeNS(null, name); } } function setAttribute(node, name, value) { var hyphenated = name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); var type = CSS_PROPERTIES[hyphenated]; if (type) { // append pixel unit, unless present if (type === LENGTH_ATTR && typeof value === 'number') { value = String(value) + 'px'; } node.style[hyphenated] = value; } else { node.setAttributeNS(null, name, value); } } function setAttributes(node, attrs) { var names = Object.keys(attrs), i, name; for (i = 0, name; name = names[i]; i++) { setAttribute(node, name, attrs[name]); } } /** * Gets or sets raw attributes on a node. * * @param {SVGElement} node * @param {Object} [attrs] * @param {String} [name] * @param {String} [value] * * @return {String} */ function attr(node, name, value) { if (typeof name === 'string') { if (value !== undefined) { setAttribute(node, name, value); } else { return getAttribute(node, name); } } else { setAttributes(node, name); } return node; } /** * Clear utility */ function index(arr, obj) { if (arr.indexOf) { return arr.indexOf(obj); } for (var i = 0; i < arr.length; ++i) { if (arr[i] === obj) { return i; } } return -1; } var re = /\s+/; var toString = Object.prototype.toString; function defined(o) { return typeof o !== 'undefined'; } /** * Wrap `el` in a `ClassList`. * * @param {Element} el * @return {ClassList} * @api public */ function classes(el) { return new ClassList(el); } function ClassList(el) { if (!el || !el.nodeType) { throw new Error('A DOM element reference is required'); } this.el = el; this.list = el.classList; } /** * Add class `name` if not already present. * * @param {String} name * @return {ClassList} * @api public */ ClassList.prototype.add = function (name) { // classList if (this.list) { this.list.add(name); return this; } // fallback var arr = this.array(); var i = index(arr, name); if (!~i) { arr.push(name); } if (defined(this.el.className.baseVal)) { this.el.className.baseVal = arr.join(' '); } else { this.el.className = arr.join(' '); } return this; }; /** * Remove class `name` when present, or * pass a regular expression to remove * any which match. * * @param {String|RegExp} name * @return {ClassList} * @api public */ ClassList.prototype.remove = function (name) { if ('[object RegExp]' === toString.call(name)) { return this.removeMatching(name); } // classList if (this.list) { this.list.remove(name); return this; } // fallback var arr = this.array(); var i = index(arr, name); if (~i) { arr.splice(i, 1); } this.el.className.baseVal = arr.join(' '); return this; }; /** * Remove all classes matching `re`. * * @param {RegExp} re * @return {ClassList} * @api private */ ClassList.prototype.removeMatching = function (re) { var arr = this.array(); for (var i = 0; i < arr.length; i++) { if (re.test(arr[i])) { this.remove(arr[i]); } } return this; }; /** * Toggle class `name`, can force state via `force`. * * For browsers that support classList, but do not support `force` yet, * the mistake will be detected and corrected. * * @param {String} name * @param {Boolean} force * @return {ClassList} * @api public */ ClassList.prototype.toggle = function (name, force) { // classList if (this.list) { if (defined(force)) { if (force !== this.list.toggle(name, force)) { this.list.toggle(name); // toggle again to correct } } else { this.list.toggle(name); } return this; } // fallback if (defined(force)) { if (!force) { this.remove(name); } else { this.add(name); } } else { if (this.has(name)) { this.remove(name); } else { this.add(name); } } return this; }; /** * Return an array of classes. * * @return {Array} * @api public */ ClassList.prototype.array = function () { var className = this.el.getAttribute('class') || ''; var str = className.replace(/^\s+|\s+$/g, ''); var arr = str.split(re); if ('' === arr[0]) { arr.shift(); } return arr; }; /** * Check if class `name` is present. * * @param {String} name * @return {ClassList} * @api public */ ClassList.prototype.has = ClassList.prototype.contains = function (name) { return this.list ? this.list.contains(name) : !!~index(this.array(), name); }; function remove(element) { var parent = element.parentNode; if (parent) { parent.removeChild(element); } return element; } /** * Clear utility */ /** * Removes all children from the given element * * @param {DOMElement} element * @return {DOMElement} the element (for chaining) */ function clear(element) { var child; while (child = element.firstChild) { remove(child); } return element; } function clone(element) { return element.cloneNode(true); } var ns = { svg: 'http://www.w3.org/2000/svg' }; /** * DOM parsing utility */ var SVG_START = '<svg xmlns="' + ns.svg + '"'; function parse(svg) { var unwrap = false; // ensure we import a valid svg document if (svg.substring(0, 4) === '<svg') { if (svg.indexOf(ns.svg) === -1) { svg = SVG_START + svg.substring(4); } } else { // namespace svg svg = SVG_START + '>' + svg + '</svg>'; unwrap = true; } var parsed = parseDocument(svg); if (!unwrap) { return parsed; } var fragment = document.createDocumentFragment(); var parent = parsed.firstChild; while (parent.firstChild) { fragment.appendChild(parent.firstChild); } return fragment; } function parseDocument(svg) { var parser; // parse parser = new DOMParser(); parser.async = false; return parser.parseFromString(svg, 'text/xml'); } /** * Create utility for SVG elements */ /** * Create a specific type from name or SVG markup. * * @param {String} name the name or markup of the element * @param {Object} [attrs] attributes to set on the element * * @returns {SVGElement} */ function create(name, attrs) { var element; if (name.charAt(0) === '<') { element = parse(name).firstChild; element = document.importNode(element, true); } else { element = document.createElementNS(ns.svg, name); } if (attrs) { attr(element, attrs); } return element; } /** * Events handling utility */ function on(node, event, listener, useCapture) { node.addEventListener(event, listener, useCapture); } function off(node, event, listener, useCapture) { node.removeEventListener(event, listener, useCapture); } /** * Geometry helpers */ // fake node used to instantiate svg geometry elements var node = create('svg'); function extend(object, props) { var i, k, keys = Object.keys(props); for (i = 0; k = keys[i]; i++) { object[k] = props[k]; } return object; } function createPoint(x, y) { var point = node.createSVGPoint(); switch (arguments.length) { case 0: return point; case 2: x = { x: x, y: y }; break; } return extend(point, x); } /** * Create matrix via args. * * @example * * createMatrix({ a: 1, b: 1 }); * createMatrix(); * createMatrix(1, 2, 0, 0, 30, 20); * * @return {SVGMatrix} */ function createMatrix(a, b, c, d, e, f) { var matrix = node.createSVGMatrix(); switch (arguments.length) { case 0: return matrix; case 1: return extend(matrix, a); case 6: return extend(matrix, { a: a, b: b, c: c, d: d, e: e, f: f }); } } function createTransform(matrix) { if (matrix) { return node.createSVGTransformFromMatrix(matrix); } else { return node.createSVGTransform(); } } /** * Serialization util */ var TEXT_ENTITIES = /([&<>]{1})/g; var ATTR_ENTITIES = /([\n\r"]{1})/g; var ENTITY_REPLACEMENT = { '&': '&', '<': '<', '>': '>', '"': '\'' }; function escape(str, pattern) { function replaceFn(match, entity) { return ENTITY_REPLACEMENT[entity] || entity; } return str.replace(pattern, replaceFn); } function serialize(node, output) { var i, len, attrMap, attrNode, childNodes; switch (node.nodeType) { // TEXT case 3: // replace special XML characters output.push(escape(node.textContent, TEXT_ENTITIES)); break; // ELEMENT case 1: output.push('<', node.tagName); if (node.hasAttributes()) { attrMap = node.attributes; for (i = 0, len = attrMap.length; i < len; ++i) { attrNode = attrMap.item(i); output.push(' ', attrNode.name, '="', escape(attrNode.value, ATTR_ENTITIES), '"'); } } if (node.hasChildNodes()) { output.push('>'); childNodes = node.childNodes; for (i = 0, len = childNodes.length; i < len; ++i) { serialize(childNodes.item(i), output); } output.push('</', node.tagName, '>'); } else { output.push('/>'); } break; // COMMENT case 8: output.push('<!--', escape(node.nodeValue, TEXT_ENTITIES), '-->'); break; // CDATA case 4: output.push('<![CDATA[', node.nodeValue, ']]>'); break; default: throw new Error('unable to handle node ' + node.nodeType); } return output; } /** * innerHTML like functionality for SVG elements. * based on innerSVG (https://code.google.com/p/innersvg) */ function set(element, svg) { var parsed = parse(svg); // clear element contents clear(element); if (!svg) { return; } if (!isFragment(parsed)) { // extract <svg> from parsed document parsed = parsed.documentElement; } var nodes = slice(parsed.childNodes); // import + append each node for (var i = 0; i < nodes.length; i++) { appendTo(nodes[i], element); } } function get(element) { var child = element.firstChild, output = []; while (child) { serialize(child, output); child = child.nextSibling; } return output.join(''); } function isFragment(node) { return node.nodeName === '#document-fragment'; } function innerSVG(element, svg) { if (svg !== undefined) { try { set(element, svg); } catch (e) { throw new Error('error parsing SVG: ' + e.message); } return element; } else { return get(element); } } function slice(arr) { return Array.prototype.slice.call(arr); } /** * Selection utilities */ function select(node, selector) { return node.querySelector(selector); } function selectAll(node, selector) { var nodes = node.querySelectorAll(selector); return [].map.call(nodes, function (element) { return element; }); } /** * prependTo utility */ /** * Prepend a node to a target element and return the prepended node. * * @param {SVGElement} node * @param {SVGElement} target * * @return {SVGElement} the prepended node */ function prependTo(node, target) { return target.insertBefore(ensureImported(node, target), target.firstChild || null); } /** * prepend utility */ /** * Prepend a node to a target element * * @param {SVGElement} target * @param {SVGElement} node * * @return {SVGElement} the target element */ function prepend(target, node) { prependTo(node, target); return target; } /** * Replace utility */ function replace(element, replacement) { element.parentNode.replaceChild(ensureImported(replacement, element), element); return replacement; } /** * transform accessor utility */ function wrapMatrix(transformList, transform) { if (transform instanceof SVGMatrix) { return transformList.createSVGTransformFromMatrix(transform); } return transform; } function setTransforms(transformList, transforms) { var i, t; transformList.clear(); for (i = 0; t = transforms[i]; i++) { transformList.appendItem(wrapMatrix(transformList, t)); } } /** * Get or set the transforms on the given node. * * @param {SVGElement} node * @param {SVGTransform|SVGMatrix|Array<SVGTransform|SVGMatrix>} [transforms] * * @return {SVGTransform} the consolidated transform */ function transform(node, transforms) { var transformList = node.transform.baseVal; if (transforms) { if (!Array.isArray(transforms)) { transforms = [transforms]; } setTransforms(transformList, transforms); } return transformList.consolidate(); } },{}],568:[function(require,module,exports){ module.exports={ "name": "Activiti", "uri": "http://activiti.org/bpmn", "prefix": "activiti", "xml": { "tagAlias": "lowerCase" }, "associations": [], "types": [ { "name": "Definitions", "isAbstract": true, "extends": [ "bpmn:Definitions" ], "properties": [ { "name": "diagramRelationId", "isAttr": true, "type": "String" } ] }, { "name": "InOutBinding", "superClass": [ "Element" ], "isAbstract": true, "properties": [ { "name": "source", "isAttr": true, "type": "String" }, { "name": "sourceExpression", "isAttr": true, "type": "String" }, { "name": "target", "isAttr": true, "type": "String" }, { "name": "businessKey", "isAttr": true, "type": "String" }, { "name": "local", "isAttr": true, "type": "Boolean", "default": false }, { "name": "variables", "isAttr": true, "type": "String" } ] }, { "name": "In", "superClass": [ "InOutBinding" ], "meta": { "allowedIn": [ "bpmn:CallActivity" ] } }, { "name": "Out", "superClass": [ "InOutBinding" ], "meta": { "allowedIn": [ "bpmn:CallActivity" ] } }, { "name": "AsyncCapable", "isAbstract": true, "extends": [ "bpmn:Activity", "bpmn:Gateway", "bpmn:Event" ], "properties": [ { "name": "async", "isAttr": true, "type": "Boolean", "default": false }, { "name": "asyncBefore", "isAttr": true, "type": "Boolean", "default": false }, { "name": "asyncAfter", "isAttr": true, "type": "Boolean", "default": false }, { "name": "exclusive", "isAttr": true, "type": "Boolean", "default": true } ] }, { "name": "JobPriorized", "isAbstract": true, "extends": [ "bpmn:Process", "activiti:AsyncCapable" ], "properties": [ { "name": "jobPriority", "isAttr": true, "type": "String" } ] }, { "name": "SignalEventDefinition", "isAbstract": true, "extends": [ "bpmn:SignalEventDefinition" ], "properties": [ { "name": "async", "isAttr": true, "type": "Boolean", "default": false } ] }, { "name": "ErrorEventDefinition", "isAbstract": true, "extends": [ "bpmn:ErrorEventDefinition" ], "properties": [ { "name": "errorCodeVariable", "isAttr": true, "type": "String" }, { "name": "errorMessageVariable", "isAttr": true, "type": "String" } ] }, { "name": "Error", "isAbstract": true, "extends": [ "bpmn:Error" ], "properties": [ { "name": "activiti:errorMessage", "isAttr": true, "type": "String" } ] }, { "name": "PotentialStarter", "superClass": [ "Element" ], "properties": [ { "name": "resourceAssignmentExpression", "type": "bpmn:ResourceAssignmentExpression" } ] }, { "name": "FormSupported", "isAbstract": true, "extends": [ "bpmn:StartEvent", "bpmn:UserTask" ], "properties": [ { "name": "formHandlerClass", "isAttr": true, "type": "String" }, { "name": "formKey", "isAttr": true, "type": "String" } ] }, { "name": "TemplateSupported", "isAbstract": true, "extends": [ "bpmn:Process", "bpmn:FlowElement" ], "properties": [ { "name": "modelerTemplate", "isAttr": true, "type": "String" } ] }, { "name": "Initiator", "isAbstract": true, "extends": [ "bpmn:StartEvent" ], "properties": [ { "name": "initiator", "isAttr": true, "type": "String" } ] }, { "name": "ScriptTask", "isAbstract": true, "extends": [ "bpmn:ScriptTask" ], "properties": [ { "name": "resultVariable", "isAttr": true, "type": "String" }, { "name": "resource", "isAttr": true, "type": "String" } ] }, { "name": "Process", "isAbstract": true, "extends": [ "bpmn:Process" ], "properties": [ { "name": "candidateStarterConfiguration", "isAttr": true, "type": "String" }, { "name": "candidateStarterUsers", "isAttr": true, "type": "String" }, { "name": "versionTag", "isAttr": true, "type": "String" }, { "name": "historyTimeToLive", "isAttr": true, "type": "String" }, { "name": "isStartableInTasklist", "isAttr": true, "type": "Boolean", "default": true }, { "name": "process-is-executable", "isAttr": true, "type": "Boolean", "default": true } ] }, { "name": "EscalationEventDefinition", "isAbstract": true, "extends": [ "bpmn:EscalationEventDefinition" ], "properties": [ { "name": "escalationCodeVariable", "isAttr": true, "type": "String" } ] }, { "name": "FormalExpression", "isAbstract": true, "extends": [ "bpmn:FormalExpression" ], "properties": [ { "name": "resource", "isAttr": true, "type": "String" } ] }, { "name": "Assignable", "extends": [ "bpmn:UserTask" ], "properties": [ { "name": "assignee", "isAttr": true, "type": "String" }, { "name": "candidateUsers", "isAttr": true, "type": "String" }, { "name": "candidateGroups", "isAttr": true, "type": "String" }, { "name": "dueDate", "isAttr": true, "type": "String" }, { "name": "followUpDate", "isAttr": true, "type": "String" }, { "name": "priority", "isAttr": true, "type": "String" } ] }, { "name": "CallActivity", "extends": [ "bpmn:CallActivity" ], "properties": [ { "name": "calledElementBinding", "isAttr": true, "type": "String", "default": "latest" }, { "name": "calledElementVersion", "isAttr": true, "type": "String" }, { "name": "calledElementVersionTag", "isAttr": true, "type": "String" }, { "name": "calledElementTenantId", "isAttr": true, "type": "String" }, { "name": "caseRef", "isAttr": true, "type": "String" }, { "name": "caseBinding", "isAttr": true, "type": "String", "default": "latest" }, { "name": "caseVersion", "isAttr": true, "type": "String" }, { "name": "caseTenantId", "isAttr": true, "type": "String" }, { "name": "variableMappingClass", "isAttr": true, "type": "String" }, { "name": "variableMappingDelegateExpression", "isAttr": true, "type": "String" } ] }, { "name": "ServiceTaskLike", "extends": [ "bpmn:ServiceTask", "bpmn:BusinessRuleTask", "bpmn:SendTask", "bpmn:MessageEventDefinition" ], "properties": [ { "name": "expression", "isAttr": true, "type": "String" }, { "name": "class", "isAttr": true, "type": "String" }, { "name": "delegateExpression", "isAttr": true, "type": "String" }, { "name": "resultVariable", "isAttr": true, "type": "String" } ] }, { "name": "DmnCapable", "extends": [ "bpmn:BusinessRuleTask" ], "properties": [ { "name": "decisionRef", "isAttr": true, "type": "String" }, { "name": "decisionRefBinding", "isAttr": true, "type": "String", "default": "latest" }, { "name": "decisionRefVersion", "isAttr": true, "type": "String" }, { "name": "mapDecisionResult", "isAttr": true, "type": "String", "default": "resultList" }, { "name": "decisionRefTenantId", "isAttr": true, "type": "String" } ] }, { "name": "ExternalCapable", "extends": [ "activiti:ServiceTaskLike" ], "properties": [ { "name": "type", "isAttr": true, "type": "String" }, { "name": "topic", "isAttr": true, "type": "String" } ] }, { "name": "TaskPriorized", "extends": [ "bpmn:Process", "activiti:ExternalCapable" ], "properties": [ { "name": "taskPriority", "isAttr": true, "type": "String" } ] }, { "name": "Properties", "superClass": [ "Element" ], "meta": { "allowedIn": [ "*" ] }, "properties": [ { "name": "values", "type": "Property", "isMany": true } ] }, { "name": "Property", "superClass": [ "Element" ], "properties": [ { "name": "id", "type": "String", "isAttr": true }, { "name": "name", "type": "String", "isAttr": true }, { "name": "value", "type": "String", "isAttr": true } ] }, { "name": "Connector", "superClass": [ "Element" ], "meta": { "allowedIn": [ "activiti:ServiceTaskLike" ] }, "properties": [ { "name": "inputOutput", "type": "InputOutput" }, { "name": "connectorId", "type": "String" } ] }, { "name": "InputOutput", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:FlowNode", "activiti:Connector" ] }, "properties": [ { "name": "inputOutput", "type": "InputOutput" }, { "name": "connectorId", "type": "String" }, { "name": "inputParameters", "isMany": true, "type": "InputParameter" }, { "name": "outputParameters", "isMany": true, "type": "OutputParameter" } ] }, { "name": "InputOutputParameter", "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "value", "isBody": true, "type": "String" }, { "name": "definition", "type": "InputOutputParameterDefinition" } ] }, { "name": "InputOutputParameterDefinition", "isAbstract": true }, { "name": "List", "superClass": [ "InputOutputParameterDefinition" ], "properties": [ { "name": "items", "isMany": true, "type": "InputOutputParameterDefinition" } ] }, { "name": "Map", "superClass": [ "InputOutputParameterDefinition" ], "properties": [ { "name": "entries", "isMany": true, "type": "Entry" } ] }, { "name": "Entry", "properties": [ { "name": "key", "isAttr": true, "type": "String" }, { "name": "value", "isBody": true, "type": "String" }, { "name": "definition", "type": "InputOutputParameterDefinition" } ] }, { "name": "Value", "superClass": [ "InputOutputParameterDefinition" ], "properties": [ { "name": "id", "isAttr": true, "type": "String" }, { "name": "name", "isAttr": true, "type": "String" }, { "name": "value", "isBody": true, "type": "String" } ] }, { "name": "Script", "superClass": [ "InputOutputParameterDefinition" ], "properties": [ { "name": "scriptFormat", "isAttr": true, "type": "String" }, { "name": "resource", "isAttr": true, "type": "String" }, { "name": "value", "isBody": true, "type": "String" } ] }, { "name": "Field", "superClass": [ "Element" ], "meta": { "allowedIn": [ "activiti:ServiceTaskLike", "activiti:ExecutionListener", "activiti:TaskListener" ] }, "properties": [ { "name": "name", "isAttr": true, "type": "String" }, { "name": "expression", "type": "String" }, { "name": "stringValue", "isAttr": true, "type": "String" }, { "name": "string", "type": "String" } ] }, { "name": "InputParameter", "superClass": [ "InputOutputParameter" ] }, { "name": "OutputParameter", "superClass": [ "InputOutputParameter" ] }, { "name": "Collectable", "isAbstract": true, "extends": [ "bpmn:MultiInstanceLoopCharacteristics" ], "superClass": [ "activiti:AsyncCapable" ], "properties": [ { "name": "collection", "isAttr": true, "type": "String" }, { "name": "elementVariable", "isAttr": true, "type": "String" } ] }, { "name": "FailedJobRetryTimeCycle", "superClass": [ "Element" ], "meta": { "allowedIn": [ "activiti:AsyncCapable", "bpmn:MultiInstanceLoopCharacteristics" ] }, "properties": [ { "name": "body", "isBody": true, "type": "String" } ] }, { "name": "ExecutionListener", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:Task", "bpmn:ServiceTask", "bpmn:UserTask", "bpmn:BusinessRuleTask", "bpmn:ScriptTask", "bpmn:ReceiveTask", "bpmn:ManualTask", "bpmn:ExclusiveGateway", "bpmn:SequenceFlow", "bpmn:ParallelGateway", "bpmn:InclusiveGateway", "bpmn:EventBasedGateway", "bpmn:StartEvent", "bpmn:IntermediateCatchEvent", "bpmn:IntermediateThrowEvent", "bpmn:EndEvent", "bpmn:BoundaryEvent", "bpmn:CallActivity", "bpmn:SubProcess", "bpmn:Process" ] }, "properties": [ { "name": "expression", "isAttr": true, "type": "String" }, { "name": "class", "isAttr": true, "type": "String" }, { "name": "delegateExpression", "isAttr": true, "type": "String" }, { "name": "event", "isAttr": true, "type": "String" }, { "name": "script", "type": "Script" }, { "name": "fields", "type": "Field", "isMany": true } ] }, { "name": "TaskListener", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:UserTask" ] }, "properties": [ { "name": "expression", "isAttr": true, "type": "String" }, { "name": "class", "isAttr": true, "type": "String" }, { "name": "delegateExpression", "isAttr": true, "type": "String" }, { "name": "event", "isAttr": true, "type": "String" }, { "name": "script", "type": "Script" }, { "name": "fields", "type": "Field", "isMany": true }, { "name": "id", "type": "String", "isAttr": true }, { "name": "eventDefinitions", "type": "bpmn:TimerEventDefinition", "isMany": true } ] }, { "name": "FormProperty", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:StartEvent", "bpmn:UserTask" ] }, "properties": [ { "name": "id", "type": "String", "isAttr": true }, { "name": "name", "type": "String", "isAttr": true }, { "name": "type", "type": "String", "isAttr": true }, { "name": "required", "type": "String", "isAttr": true }, { "name": "readable", "type": "String", "isAttr": true }, { "name": "writable", "type": "String", "isAttr": true }, { "name": "variable", "type": "String", "isAttr": true }, { "name": "expression", "type": "String", "isAttr": true }, { "name": "datePattern", "type": "String", "isAttr": true }, { "name": "default", "type": "String", "isAttr": true }, { "name": "values", "type": "Value", "isMany": true } ] }, { "name": "FormData", "superClass": [ "Element" ], "meta": { "allowedIn": [ "bpmn:StartEvent", "bpmn:UserTask" ] }, "properties": [ { "name": "fields", "type": "FormField", "isMany": true }, { "name": "businessKey", "type": "String", "isAttr": true } ] }, { "name": "FormField", "superClass": [ "Element" ], "properties": [ { "name": "id", "type": "String", "isAttr": true }, { "name": "label", "type": "String", "isAttr": true }, { "name": "type", "type": "String", "isAttr": true }, { "name": "datePattern", "type": "String", "isAttr": true }, { "name": "defaultValue", "type": "String", "isAttr": true }, { "name": "properties", "type": "Properties" }, { "name": "validation", "type": "Validation" }, { "name": "values", "type": "Value", "isMany": true } ] }, { "name": "Validation", "superClass": [ "Element" ], "properties": [ { "name": "constraints", "type": "Constraint", "isMany": true } ] }, { "name": "Constraint", "superClass": [ "Element" ], "properties": [ { "name": "name", "type": "String", "isAttr": true }, { "name": "config", "type": "String", "isAttr": true } ] }, { "name": "ConditionalEventDefinition", "isAbstract": true, "extends": [ "bpmn:ConditionalEventDefinition" ], "properties": [ { "name": "variableName", "isAttr": true, "type": "String" }, { "name": "variableEvent", "isAttr": true, "type": "String" } ] } ], "emumerations": [ ] } },{}],569:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; class CustomContextPad { constructor(config, contextPad, create, elementFactory, injector, translate) { this.create = create; this.elementFactory = elementFactory; this.translate = translate; //自动摆放位置 if (config.autoPlace !== false) { this.autoPlace = injector.get('autoPlace', false); } //注册工具 contextPad.registerProvider(this); } getContextPadEntries(element) { const { autoPlace, create, elementFactory, translate } = this; function appendUserTask(event, element) { if (autoPlace) { const shape = elementFactory.createShape({ type: 'bpmn:UserTask' }); autoPlace.append(element, shape); } else { appendUserTaskStart(event, element); } } function appendUserTaskStart(event) { const shape = elementFactory.createShape({ type: 'bpmn:UserTask' }); create.start(event, shape, element); } function appendCallActivityStart(event) { const shape = elementFactory.createShape({ type: 'bpmn:CallActivity' }); create.start(event, shape, element); } function appendCallActivity(event, element) { if (autoPlace) { const shape = elementFactory.createShape({ type: 'bpmn:CallActivity' }); autoPlace.append(element, shape); } else { appendCallActivityStart(event, element); } } return { 'append.user-task': { group: 'model', className: 'bpmn-icon-user-task', title: translate('Append ServiceTask'), action: { click: appendUserTask, dragstart: appendUserTaskStart } }, 'append.call-activity': { group: 'model', className: 'bpmn-icon-call-activity', title: translate('Append CallActivity'), action: { click: appendCallActivity, dragstart: appendCallActivityStart } } }; } } exports.default = CustomContextPad; CustomContextPad.$inject = ['config', 'contextPad', 'create', 'elementFactory', 'injector', 'translate']; },{}],570:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; class CustomPalette { constructor(create, elementFactory, palette, translate) { this.create = create; this.elementFactory = elementFactory; this.translate = translate; palette.registerProvider(this); } getPaletteEntries(element) { const { create, elementFactory, translate } = this; function createServiceTask(event) { const shape = elementFactory.createShape({ type: 'bpmn:UserTask' }); create.start(event, shape); } function createCallActivity(event) { const shape = elementFactory.createShape({ type: 'bpmn:CallActivity' }); create.start(event, shape); } return { 'create.user-task': { group: 'activity', className: 'bpmn-icon-user-task', title: translate('Create UserTask'), action: { dragstart: createServiceTask, click: createServiceTask } }, 'create.call-activity': { group: 'activity', className: 'bpmn-icon-call-activity', title: translate('Create CallActivity'), action: { dragstart: createCallActivity, click: createCallActivity } } }; } } exports.default = CustomPalette; CustomPalette.$inject = ['create', 'elementFactory', 'palette', 'translate']; },{}],571:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _CustomContextPad = _interopRequireDefault(require("./CustomContextPad")); var _CustomPalette = _interopRequireDefault(require("./CustomPalette")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var _default = { __init__: ['customContextPad', 'customPalette'], customContextPad: ['type', _CustomContextPad.default], customPalette: ['type', _CustomPalette.default] }; exports.default = _default; },{"./CustomContextPad":569,"./CustomPalette":570}],572:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = customTranslate; var _translationsGerman = _interopRequireDefault(require("./translationsGerman")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function customTranslate(template, replacements) { replacements = replacements || {}; template = _translationsGerman.default[template] || template; return template.replace(/{([^}]+)}/g, function (_, key) { var str = replacements[key]; if (_translationsGerman.default[replacements[key]] != null && _translationsGerman.default[replacements[key]] != 'undefined') { str = _translationsGerman.default[replacements[key]]; } return str || '{' + key + '}'; }); } },{"./translationsGerman":573}],573:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _default = { // Labels 'Activate the global connect tool': '激活全局连接工具', 'Append {type}': '追加 {type}', 'Append EndEvent': '追加 结束事件 ', 'Append Task': '追加 任务', 'Append Gateway': '追加 网关', 'Append Intermediate/Boundary Event': '追加 中间/边界 事件', 'Add Lane above': '在上面添加道', 'Divide into two Lanes': '分割成两个道', 'Divide into three Lanes': '分割成三个道', 'Add Lane below': '在下面添加道', 'Append compensation activity': '追加补偿活动', 'Change type': '修改类型', 'Connect using Association': '使用关联连接', 'Connect using Sequence/MessageFlow or Association': '使用顺序/消息流或者关联连接', 'Connect using DataInputAssociation': '使用数据输入关联连接', 'Remove': '移除', 'Activate the hand tool': '激活抓手工具', 'Activate the lasso tool': '激活套索工具', 'Activate the create/remove space tool': '激活创建/删除空间工具', 'Create expanded SubProcess': '创建扩展子过程', 'Create IntermediateThrowEvent/BoundaryEvent': '创建中间抛出事件/边界事件', 'Create Pool/Participant': '创建池/参与者', 'Parallel Multi Instance': '并行多重事件', 'Sequential Multi Instance': '时序多重事件', 'DataObjectReference': '数据对象参考', 'DataStoreReference': '数据存储参考', 'Loop': '循环', 'Ad-hoc': '即席', 'Create {type}': '创建 {type}', 'Create Task': '创建任务', 'Create StartEvent': '创建开始事件', 'Create EndEvent': '创建结束事件', 'Create Group': '创建组', 'Task': '任务', 'Send Task': '发送任务', 'Receive Task': '接收任务', 'User Task': '用户任务', 'Manual Task': '手工任务', 'Business Rule Task': '业务规则任务', 'Service Task': '服务任务', 'Script Task': '脚本任务', 'Call Activity': '调用活动', 'Sub Process (collapsed)': '子流程(折叠的)', 'Sub Process (expanded)': '子流程(展开的)', 'Start Event': '开始事件', 'StartEvent': '开始事件', 'Intermediate Throw Event': '中间事件', 'End Event': '结束事件', 'EndEvent': '结束事件', 'Create Gateway': '创建网关', 'GateWay': '网关', 'Create Intermediate/Boundary Event': '创建中间/边界事件', 'Message Start Event': '消息开始事件', 'Timer Start Event': '定时开始事件', 'Conditional Start Event': '条件开始事件', 'Signal Start Event': '信号开始事件', 'Error Start Event': '错误开始事件', 'Escalation Start Event': '升级开始事件', 'Compensation Start Event': '补偿开始事件', 'Message Start Event (non-interrupting)': '消息开始事件(非中断)', 'Timer Start Event (non-interrupting)': '定时开始事件(非中断)', 'Conditional Start Event (non-interrupting)': '条件开始事件(非中断)', 'Signal Start Event (non-interrupting)': '信号开始事件(非中断)', 'Escalation Start Event (non-interrupting)': '升级开始事件(非中断)', 'Message Intermediate Catch Event': '消息中间捕获事件', 'Message Intermediate Throw Event': '消息中间抛出事件', 'Timer Intermediate Catch Event': '定时中间捕获事件', 'Escalation Intermediate Throw Event': '升级中间抛出事件', 'Conditional Intermediate Catch Event': '条件中间捕获事件', 'Link Intermediate Catch Event': '链接中间捕获事件', 'Link Intermediate Throw Event': '链接中间抛出事件', 'Compensation Intermediate Throw Event': '补偿中间抛出事件', 'Signal Intermediate Catch Event': '信号中间捕获事件', 'Signal Intermediate Throw Event': '信号中间抛出事件', 'Message End Event': '消息结束事件', 'Escalation End Event': '定时结束事件', 'Error End Event': '错误结束事件', 'Cancel End Event': '取消结束事件', 'Compensation End Event': '补偿结束事件', 'Signal End Event': '信号结束事件', 'Terminate End Event': '终止结束事件', 'Message Boundary Event': '消息边界事件', 'Message Boundary Event (non-interrupting)': '消息边界事件(非中断)', 'Timer Boundary Event': '定时边界事件', 'Timer Boundary Event (non-interrupting)': '定时边界事件(非中断)', 'Escalation Boundary Event': '升级边界事件', 'Escalation Boundary Event (non-interrupting)': '升级边界事件(非中断)', 'Conditional Boundary Event': '条件边界事件', 'Conditional Boundary Event (non-interrupting)': '条件边界事件(非中断)', 'Error Boundary Event': '错误边界事件', 'Cancel Boundary Event': '取消边界事件', 'Signal Boundary Event': '信号边界事件', 'Signal Boundary Event (non-interrupting)': '信号边界事件(非中断)', 'Compensation Boundary Event': '补偿边界事件', 'Exclusive Gateway': '互斥网关', 'Parallel Gateway': '并行网关', 'Inclusive Gateway': '相容网关', 'Complex Gateway': '复杂网关', 'Event based Gateway': '事件网关', 'Transaction': '转运', 'Sub Process': '子流程', 'Event Sub Process': '事件子流程', 'Collapsed Pool': '折叠池', 'Expanded Pool': '展开池', // Errors 'no parent for {element} in {parent}': '在{parent}里,{element}没有父类', 'no shape type specified': '没有指定的形状类型', 'flow elements must be children of pools/participants': '流元素必须是池/参与者的子类', 'out of bounds release': 'out of bounds release', 'more than {count} child lanes': '子道大于{count} ', 'element required': '元素不能为空', 'diagram not part of bpmn:Definitions': '流程图不符合bpmn规范', 'no diagram to display': '没有可展示的流程图', 'no process or collaboration to display': '没有可展示的流程/协作', 'element {element} referenced by {referenced}#{property} not yet drawn': '由{referenced}#{property}引用的{element}元素仍未绘制', 'already rendered {element}': '{element} 已被渲染', 'failed to import {element}': '导入{element}失败', //属性面板的参数 'Id': '编号', 'Name': '名称', 'General': '常规', 'Details': '详情', 'Message Name': '消息名称', 'Message': '消息', 'Initiator': '创建者', 'Asynchronous Continuations': '持续异步', 'Asynchronous Before': '异步前', 'Asynchronous After': '异步后', 'Job Configuration': '工作配置', 'Exclusive': '排除', 'Job Priority': '工作优先级', 'Retry Time Cycle': '重试时间周期', 'Documentation': '文档', 'Element Documentation': '元素文档', 'History Configuration': '历史配置', 'History Time To Live': '历史的生存时间', 'Forms': '表单', 'Form Key': '表单key', 'Form Fields': '表单字段', 'Business Key': '业务key', 'Form Field': '表单字段', 'ID': '编号', 'Type': '类型', 'Label': '名称', 'Default Value': '默认值', 'Validation': '校验', 'Add Constraint': '添加约束', 'Config': '配置', 'Properties': '属性', 'Add Property': '添加属性', 'Value': '值', 'Add': '添加', 'Values': '值', 'Add Value': '添加值', 'Listeners': '监听器', 'Execution Listener': '执行监听', 'Event Type': '事件类型', 'Listener Type': '监听器类型', 'Java Class': 'Java类', 'Expression': '表达式', 'Must provide a value': '必须提供一个值', 'Delegate Expression': '代理表达式', 'Script': '脚本', 'Script Format': '脚本格式', 'Script Type': '脚本类型', 'Inline Script': '内联脚本', 'External Script': '外部脚本', 'Resource': '资源', 'Field Injection': '字段注入', 'Extensions': '扩展', 'Input/Output': '输入/输出', 'Input Parameters': '输入参数', 'Output Parameters': '输出参数', 'Parameters': '参数', 'Output Parameter': '输出参数', 'Timer Definition Type': '定时器定义类型', 'Timer Definition': '定时器定义', 'Date': '日期', 'Duration': '持续', 'Cycle': '循环', 'Signal': '信号', 'Signal Name': '信号名称', 'Escalation': '升级', 'Error': '错误', 'Link Name': '链接名称', 'Condition': '条件名称', 'Variable Name': '变量名称', 'Variable Event': '变量事件', 'Specify more than one variable change event as a comma separated list.': '多个变量事件以逗号隔开', 'Wait for Completion': '等待完成', 'Activity Ref': '活动参考', 'Version Tag': '版本标签', 'Executable': '可执行文件', 'External Task Configuration': '扩展任务配置', 'Task Priority': '任务优先级', 'External': '外部', 'Connector': '连接器', 'Must configure Connector': '必须配置连接器', 'Connector Id': '连接器编号', 'Implementation': '实现方式', 'Field Injections': '字段注入', 'Fields': '字段', 'Result Variable': '结果变量', 'Topic': '主题', 'Configure Connector': '配置连接器', 'Input Parameter': '输入参数', 'Assignee': '代理人', 'Candidate Users': '候选用户', 'Candidate Groups': '候选组', 'Due Date': '到期时间', 'Follow Up Date': '跟踪日期', 'Priority': '优先级', 'The follow up date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)': '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00', 'The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)': '跟踪日期必须符合EL表达式,如: ${someDate} ,或者一个ISO标准日期,如:2015-06-26T09:54:00', 'Variables': '变量', 'Candidate Starter Configuration': '候选开始配置', 'Task Listener': '任务监听器', 'Candidate Starter Groups': '候选开始组', 'Candidate Starter Users': '候选开始用户', 'Tasklist Configuration': '任务列表配置', 'Startable': '启动', 'Specify more than one group as a comma separated list.': '指定多个组,用逗号分隔', 'Specify more than one user as a comma separated list.': '指定多个用户,用逗号分隔', 'This maps to the process definition key.': '这会映射为流程定义的键', 'CallActivity Type': '调用活动类型', 'Condition Type': '条件类型', 'Create UserTask': '创建用户任务', 'Create CallActivity': '创建调用活动', 'Called Element': '调用元素', 'Create DataObjectReference': '创建数据对象引用', 'Create DataStoreReference': '创建数据存储引用', 'Multi Instance': '多实例', 'Loop Cardinality': '实例数量', 'Collection': '任务参与人列表', 'Element Variable': '元素变量', 'Completion Condition': '完成条件' }; exports.default = _default; },{}],574:[function(require,module,exports){ module.exports = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<bpmn2:definitions xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:bpmn2=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:dc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:di=\"http://www.omg.org/spec/DD/20100524/DI\" xsi:schemaLocation=\"http://www.omg.org/spec/BPMN/20100524/MODEL BPMN20.xsd\" id=\"sample-diagram\" targetNamespace=\"http://activiti.org/bpmn\">\r\n <bpmn2:process id=\"Process_1\" isExecutable=\"true\">\r\n <bpmn2:startEvent id=\"StartEvent_1\"/>\r\n </bpmn2:process>\r\n <bpmndi:BPMNDiagram id=\"BPMNDiagram_1\">\r\n <bpmndi:BPMNPlane id=\"BPMNPlane_1\" bpmnElement=\"Process_1\">\r\n <bpmndi:BPMNShape id=\"_BPMNShape_StartEvent_2\" bpmnElement=\"StartEvent_1\">\r\n <dc:Bounds height=\"36.0\" width=\"36.0\" x=\"412.0\" y=\"240.0\"/>\r\n </bpmndi:BPMNShape>\r\n </bpmndi:BPMNPlane>\r\n </bpmndi:BPMNDiagram>\r\n</bpmn2:definitions>"; },{}],575:[function(require,module,exports){ 'use strict'; var DEFAULT_PRIORITY = 1000; /** * A component that decides upon the visibility / editable * state of properties in the properties panel. * * Implementors must subclass this component and override * {@link PropertiesActivator#isEntryVisible} and * {@link PropertiesActivator#isPropertyEditable} to provide * custom behavior. * * @class * @constructor * * @param {EventBus} eventBus * @param {Number} [priority] at which priority to hook into the activation */ function PropertiesActivator(eventBus, priority) { var self = this; priority = priority || DEFAULT_PRIORITY; eventBus.on('propertiesPanel.isEntryVisible', priority, function(e) { return self.isEntryVisible(e.entry, e.element); }); eventBus.on('propertiesPanel.isPropertyEditable', priority, function(e) { return self.isPropertyEditable(e.entry, e.propertyName, e.element); }); } PropertiesActivator.$inject = [ 'eventBus' ]; module.exports = PropertiesActivator; /** * Should the given entry be visible for the specified element. * * @method PropertiesActivator#isEntryVisible * * @param {EntryDescriptor} entry * @param {ModdleElement} element * * @returns {Boolean} */ PropertiesActivator.prototype.isEntryVisible = function(entry, element) { return true; }; /** * Should the given property be editable for the specified element * * @method PropertiesActivator#isPropertyEditable * * @param {EntryDescriptor} entry * @param {String} propertyName * @param {ModdleElement} element * * @returns {Boolean} */ PropertiesActivator.prototype.isPropertyEditable = function(entry, propertyName, element) { return true; }; },{}],576:[function(require,module,exports){ 'use strict'; var domQuery = require('min-dom').query, domClear = require('min-dom').clear, is = require('bpmn-js/lib/util/ModelUtil').is, forEach = require('lodash/forEach'), domify = require('min-dom').domify, Ids = require('ids').default; var SPACE_REGEX = /\s/; // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar var QNAME_REGEX = /^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i; // for ID validation as per BPMN Schema (QName - Namespace) var ID_REGEX = /^[a-z_][\w-.]*$/i; var PLACEHOLDER_REGEX = /\$\{([^}]*)\}/g; var HTML_ESCAPE_MAP = { '&': '&', '<': '<', '>': '>', '"': '"', '\'': ''' }; function selectedOption(selectBox) { if (selectBox.selectedIndex >= 0) { return selectBox.options[selectBox.selectedIndex].value; } } module.exports.selectedOption = selectedOption; function selectedType(elementSyntax, inputNode) { var typeSelect = domQuery(elementSyntax, inputNode); return selectedOption(typeSelect); } module.exports.selectedType = selectedType; /** * Retrieve the root element the document this * business object is contained in. * * @return {ModdleElement} */ function getRoot(businessObject) { var parent = businessObject; while (parent.$parent) { parent = parent.$parent; } return parent; } module.exports.getRoot = getRoot; /** * filters all elements in the list which have a given type. * removes a new list */ function filterElementsByType(objectList, type) { var list = objectList || []; var result = []; forEach(list, function(obj) { if (is(obj, type)) { result.push(obj); } }); return result; } module.exports.filterElementsByType = filterElementsByType; function findRootElementsByType(businessObject, referencedType) { var root = getRoot(businessObject); return filterElementsByType(root.rootElements, referencedType); } module.exports.findRootElementsByType = findRootElementsByType; function removeAllChildren(domElement) { while (domElement.firstChild) { domElement.removeChild(domElement.firstChild); } } module.exports.removeAllChildren = removeAllChildren; /** * adds an empty option to the list */ function addEmptyParameter(list) { return list.push({ 'label': '', 'value': '', 'name': '' }); } module.exports.addEmptyParameter = addEmptyParameter; /** * returns a list with all root elements for the given parameter 'referencedType' */ function refreshOptionsModel(businessObject, referencedType) { var model = []; var referableObjects = findRootElementsByType(businessObject, referencedType); forEach(referableObjects, function(obj) { model.push({ label: (obj.name || '') + ' (id='+obj.id+')', value: obj.id, name: obj.name }); }); return model; } module.exports.refreshOptionsModel = refreshOptionsModel; /** * fills the drop down with options */ function updateOptionsDropDown(domSelector, businessObject, referencedType, entryNode) { var options = refreshOptionsModel(businessObject, referencedType); addEmptyParameter(options); var selectBox = domQuery(domSelector, entryNode); domClear(selectBox); forEach(options, function(option) { var optionEntry = domify('<option value="' + escapeHTML(option.value) + '">' + escapeHTML(option.label) + '</option>'); selectBox.appendChild(optionEntry); }); return options; } module.exports.updateOptionsDropDown = updateOptionsDropDown; /** * checks whether the id value is valid * * @param {ModdleElement} bo * @param {String} idValue * @param {Function} translate * * @return {String} error message */ function isIdValid(bo, idValue, translate) { var assigned = bo.$model.ids.assigned(idValue); var idExists = assigned && assigned !== bo; if (!idValue || idExists) { return translate('Element must have an unique id.'); } return validateId(idValue, translate); } module.exports.isIdValid = isIdValid; function validateId(idValue, translate) { idValue = stripPlaceholders(idValue); if (containsSpace(idValue)) { return translate('Id must not contain spaces.'); } if (!ID_REGEX.test(idValue)) { if (QNAME_REGEX.test(idValue)) { return translate('Id must not contain prefix.'); } return translate('Id must be a valid QName.'); } } module.exports.validateId = validateId; function containsSpace(value) { return SPACE_REGEX.test(value); } module.exports.containsSpace = containsSpace; function stripPlaceholders(idValue) { // replace expression e.g. ${VERSION_TAG} // use only the content between ${} // for the REGEX check return idValue.replace(PLACEHOLDER_REGEX, '$1'); } /** * generate a semantic id with given prefix */ function nextId(prefix) { var ids = new Ids([32,32,1]); return ids.nextPrefixed(prefix); } module.exports.nextId = nextId; function triggerClickEvent(element) { var evt; var eventType = 'click'; if (document.createEvent) { try { // Chrome, Safari, Firefox evt = new MouseEvent((eventType), { view: window, bubbles: true, cancelable: true }); } catch (e) { // IE 11, PhantomJS (wat!) evt = document.createEvent('MouseEvent'); evt.initEvent((eventType), true, true); } return element.dispatchEvent(evt); } else { // Welcome IE evt = document.createEventObject(); return element.fireEvent('on' + eventType, evt); } } module.exports.triggerClickEvent = triggerClickEvent; function escapeHTML(str) { str = '' + str; return str && str.replace(/[&<>"']/g, function(match) { return HTML_ESCAPE_MAP[match]; }); } module.exports.escapeHTML = escapeHTML; },{"bpmn-js/lib/util/ModelUtil":141,"ids":346,"lodash/forEach":522,"min-dom":556}],577:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, cmdHelper = require('../helper/CmdHelper'), escapeHTML = require('../Utils').escapeHTML; var entryFieldDescription = require('./EntryFieldDescription'); var checkbox = function(options, defaultParameters) { var resource = defaultParameters, id = resource.id, label = options.label || id, canBeDisabled = !!options.disabled && typeof options.disabled === 'function', canBeHidden = !!options.hidden && typeof options.hidden === 'function', description = options.description; resource.html = '<input id="activiti-' + escapeHTML(id) + '" ' + 'type="checkbox" ' + 'name="' + escapeHTML(options.modelProperty) + '" ' + (canBeDisabled ? 'data-disable="isDisabled"' : '') + (canBeHidden ? 'data-show="isHidden"' : '') + ' />' + '<label for="activiti-' + escapeHTML(id) + '" ' + (canBeDisabled ? 'data-disable="isDisabled"' : '') + (canBeHidden ? 'data-show="isHidden"' : '') + '>' + escapeHTML(label) + '</label>'; // add description below checkbox entry field if (description) { resource.html += entryFieldDescription(description); } resource.get = function(element) { var bo = getBusinessObject(element), res = {}; res[options.modelProperty] = bo.get(options.modelProperty); return res; }; resource.set = function(element, values) { var res = {}; res[options.modelProperty] = !!values[options.modelProperty]; return cmdHelper.updateProperties(element, res); }; if (typeof options.set === 'function') { resource.set = options.set; } if (typeof options.get === 'function') { resource.get = options.get; } if (canBeDisabled) { resource.isDisabled = function() { return options.disabled.apply(resource, arguments); }; } if (canBeHidden) { resource.isHidden = function() { return !options.hidden.apply(resource, arguments); }; } resource.cssClasses = ['bpp-checkbox']; return resource; }; module.exports = checkbox; },{"../Utils":576,"../helper/CmdHelper":590,"./EntryFieldDescription":580,"bpmn-js/lib/util/ModelUtil":141}],578:[function(require,module,exports){ 'use strict'; var assign = require('lodash/assign'), find = require('lodash/find'); var domQuery = require('min-dom').query; var escapeHTML = require('../Utils').escapeHTML; var selectEntryFactory = require('./SelectEntryFactory'), entryFieldDescription = require('./EntryFieldDescription'); /** * The combo box is a special implementation of the select entry and adds the option 'custom' to the * select box. If 'custom' is selected, an additional text input field is shown which allows to define * a custom value. * * @param {Object} options * @param {string} options.id * @param {string} options.label * @param {Array<Object>} options.selectOptions list of name/value pairs * @param {string} options.modelProperty * @param {function} options.get * @param {function} options.set * @param {string} [options.customValue] custom select option value (default: 'custom') * @param {string} [options.customName] custom select option name visible in the select box (default: 'custom') * * @return {Object} */ var comboBox = function(options) { var selectOptions = options.selectOptions, modelProperty = options.modelProperty, customValue = options.customValue || 'custom', customName = options.customName || 'custom ' + modelProperty, description = options.description; // check if a value is not a built in value var isCustomValue = function(value) { if (typeof value[modelProperty] === 'undefined') { return false; } var isCustom = !find(selectOptions, function(option) { return value[modelProperty] === option.value; }); return isCustom; }; var comboOptions = assign({}, options); // true if the selected value in the select box is customValue comboOptions.showCustomInput = function(element, node) { var selectBox = domQuery('[data-entry="'+ options.id +'"] select', node.parentNode); if (selectBox) { return selectBox.value === customValue; } return false; }; comboOptions.get = function(element, node) { var value = options.get(element, node); var modifiedValues = {}; if (!isCustomValue(value)) { modifiedValues[modelProperty] = value[modelProperty] || ''; return modifiedValues; } modifiedValues[modelProperty] = customValue; modifiedValues['custom-'+modelProperty] = value[modelProperty]; return modifiedValues; }; comboOptions.set = function(element, values, node) { var modifiedValues = {}; // if the custom select option has been selected // take the value from the text input field if (values[modelProperty] === customValue) { modifiedValues[modelProperty] = values['custom-' + modelProperty] || ''; } else if (options.emptyParameter && values[modelProperty] === '') { modifiedValues[modelProperty] = undefined; } else { modifiedValues[modelProperty] = values[modelProperty]; } return options.set(element, modifiedValues, node); }; comboOptions.selectOptions.push({ name: customName, value: customValue }); var comboBoxEntry = assign({}, selectEntryFactory(comboOptions, comboOptions)); comboBoxEntry.html += '<div class="bpp-field-wrapper bpp-combo-input" ' + 'data-show="showCustomInput"' + '>' + '<input id="activiti-' + escapeHTML(options.id) + '-input" type="text" name="custom-' + escapeHTML(modelProperty) + '" ' + ' />' + '</div>'; // add description below combo box entry field if (description) { comboBoxEntry.html += entryFieldDescription(description); } return comboBoxEntry; }; module.exports = comboBox; },{"../Utils":576,"./EntryFieldDescription":580,"./SelectEntryFactory":583,"lodash/assign":513,"lodash/find":519,"min-dom":556}],579:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; // input entities var textInputField = require('./TextInputEntryFactory'), checkboxField = require('./CheckboxEntryFactory'), selectBoxField = require('./SelectEntryFactory'), comboBoxField = require('./ComboEntryFactory'), textBoxField = require('./TextBoxEntryFactory'), validationAwareTextInputField = require('./ValidationAwareTextInput'), tableField = require('./TableEntryFactory'), labelEntry = require('./LabelFactory'), link = require('./LinkEntryFactory'); var cmdHelper = require('../helper/CmdHelper'); // helpers //////////////////////////////////////// function ensureNotNull(prop) { if (!prop) { throw new Error(prop + ' must be set.'); } return prop; } /** * sets the default parameters which are needed to create an entry * * @param options * @returns {{id: *, description: (*|string), get: (*|Function), set: (*|Function), * validate: (*|Function), html: string}} */ var setDefaultParameters = function(options) { // default method to fetch the current value of the input field var defaultGet = function(element) { var bo = getBusinessObject(element), res = {}, prop = ensureNotNull(options.modelProperty); res[prop] = bo.get(prop); return res; }; // default method to set a new value to the input field var defaultSet = function(element, values) { var res = {}, prop = ensureNotNull(options.modelProperty); if (values[prop] !== '') { res[prop] = values[prop]; } else { res[prop] = undefined; } return cmdHelper.updateProperties(element, res); }; // default validation method var defaultValidate = function() { return {}; }; return { id : options.id, description : (options.description || ''), get : (options.get || defaultGet), set : (options.set || defaultSet), validate : (options.validate || defaultValidate), html: '' }; }; function EntryFactory() { } /** * Generates an text input entry object for a property panel. * options are: * - id: id of the entry - String * * - description: description of the property - String * * - label: label for the input field - String * * - set: setter method - Function * * - get: getter method - Function * * - validate: validation mehtod - Function * * - modelProperty: name of the model property - String * * - buttonAction: Object which contains the following properties: - Object * ---- name: name of the [data-action] callback - String * ---- method: callback function for [data-action] - Function * * - buttonShow: Object which contains the following properties: - Object * ---- name: name of the [data-show] callback - String * ---- method: callback function for [data-show] - Function * * @param options * @returns the propertyPanel entry resource object */ EntryFactory.textField = function(options) { return textInputField(options, setDefaultParameters(options)); }; EntryFactory.validationAwareTextField = function(options) { return validationAwareTextInputField(options, setDefaultParameters(options)); }; /** * Generates a checkbox input entry object for a property panel. * options are: * - id: id of the entry - String * * - description: description of the property - String * * - label: label for the input field - String * * - set: setter method - Function * * - get: getter method - Function * * - validate: validation method - Function * * - modelProperty: name of the model property - String * * @param options * @returns the propertyPanel entry resource object */ EntryFactory.checkbox = function(options) { return checkboxField(options, setDefaultParameters(options)); }; EntryFactory.textBox = function(options) { return textBoxField(options, setDefaultParameters(options)); }; EntryFactory.selectBox = function(options) { return selectBoxField(options, setDefaultParameters(options)); }; EntryFactory.comboBox = function(options) { return comboBoxField(options); }; EntryFactory.table = function(options) { return tableField(options); }; EntryFactory.label = function(options) { return labelEntry(options); }; EntryFactory.link = function(options) { return link(options); }; module.exports = EntryFactory; },{"../helper/CmdHelper":590,"./CheckboxEntryFactory":577,"./ComboEntryFactory":578,"./LabelFactory":581,"./LinkEntryFactory":582,"./SelectEntryFactory":583,"./TableEntryFactory":584,"./TextBoxEntryFactory":585,"./TextInputEntryFactory":586,"./ValidationAwareTextInput":587,"bpmn-js/lib/util/ModelUtil":141}],580:[function(require,module,exports){ 'use strict'; var escapeHTML = require('../Utils').escapeHTML; /** * Create a linkified and HTML escaped entry field description. * * As a special feature, this description may contain both markdown * and plain <a href> links. * * @param {String} description */ module.exports = function entryFieldDescription(description) { // we tokenize the description to extract text, HTML and markdown links // text and links are handled seperately var escaped = []; // match markdown [{TEXT}]({URL}) and HTML links <a href="{URL}">{TEXT}</a> var pattern = /(?:\[([^\]]+)\]\((https?:\/\/[^"<>\]]+)\))|(?:<a href="(https?:\/\/[^"<>]+)">([^<]*)<\/a>)/gi; var index = 0; var match; var link, text; while ((match = pattern.exec(description))) { // escape + insert text before match if (match.index > index) { escaped.push(escapeHTML(description.substring(index, match.index))); } link = match[2] || match[3]; text = match[1] || match[4]; // insert safe link escaped.push('<a href="' + link + '" target="_blank">' + escapeHTML(text) + '</a>'); index = match.index + match[0].length; } // escape and insert text after last match if (index < description.length) { escaped.push(escapeHTML(description.substring(index))); } return '<div class="bpp-field-description">' + escaped.join('') + '</div>'; }; },{"../Utils":576}],581:[function(require,module,exports){ 'use strict'; /** * The label factory provides a label entry. For the label text * it expects either a string provided by the options.labelText * parameter or it could be generated programmatically using a * function passed as the options.get parameter. * * @param {Object} options * @param {string} options.id * @param {string} [options.labelText] * @param {Function} [options.get] * @param {Function} [options.showLabel] * @param {Boolean} [options.divider] adds a divider at the top of the label if true; default: false */ var label = function(options) { return { id: options.id, html: '<label data-value="label" ' + 'data-show="showLabel" ' + 'class="entry-label' + (options.divider ? ' divider' : '') + '">' + '</label>', get: function(element, node) { if (typeof options.get === 'function') { return options.get(element, node); } return { label: options.labelText }; }, showLabel: function(element, node) { if (typeof options.showLabel === 'function') { return options.showLabel(element, node); } return true; } }; }; module.exports = label; },{}],582:[function(require,module,exports){ 'use strict'; var escapeHTML = require('../Utils').escapeHTML; var entryFieldDescription = require('./EntryFieldDescription'); var bind = require('lodash/bind'); /** * An entry that renders a clickable link. * * A passed {@link options#handleClick} handler is responsible * to process the click. * * The link may be conditionally shown or hidden. This can be * controlled via the {@link options.showLink}. * * @param {Object} options * @param {String} options.id * @param {String} [options.label] * @param {Function} options.handleClick * @param {Function} [options.showLink] returning false to hide link * @param {String} [options.description] * * @example * * var linkEntry = link({ * id: 'foo', * description: 'Some Description', * handleClick: function(element, node, event) { ... }, * showLink: function(element, node) { ... } * }); * * @return {Entry} the newly created entry */ function link(options) { var id = options.id, label = options.label || id, showLink = options.showLink, handleClick = options.handleClick, description = options.description; if (showLink && typeof showLink !== 'function') { throw new Error('options.showLink must be a function'); } if (typeof handleClick !== 'function') { throw new Error('options.handleClick must be a function'); } var resource = { id: id }; resource.html = '<a data-action="handleClick" ' + (showLink ? 'data-show="showLink" ' : '') + 'class="bpp-entry-link' + (options.cssClasses ? ' ' + escapeHTML(options.cssClasses) : '') + '">' + escapeHTML(label) + '</a>'; // add description below link entry field if (description) { resource.html += entryFieldDescription(description); } resource.handleClick = bind(handleClick, resource); if (typeof showLink === 'function') { resource.showLink = function() { return showLink.apply(resource, arguments); }; } return resource; } module.exports = link; },{"../Utils":576,"./EntryFieldDescription":580,"lodash/bind":514}],583:[function(require,module,exports){ 'use strict'; var escapeHTML = require('../Utils').escapeHTML; var domify = require('min-dom').domify; var forEach = require('lodash/forEach'); var entryFieldDescription = require('./EntryFieldDescription'); var isList = function(list) { return !(!list || Object.prototype.toString.call(list) !== '[object Array]'); }; var addEmptyParameter = function(list) { return list.concat([ { name: '', value: '' } ]); }; var createOption = function(option) { return '<option value="' + option.value + '">' + option.name + '</option>'; }; /** * @param {Object} options * @param {string} options.id * @param {string} [options.label] * @param {Array<Object>} options.selectOptions * @param {string} options.modelProperty * @param {boolean} options.emptyParameter * @param {function} options.disabled * @param {function} options.hidden * @param {Object} defaultParameters * * @return {Object} */ var selectbox = function(options, defaultParameters) { var resource = defaultParameters, label = options.label || resource.id, selectOptions = options.selectOptions || [ { name: '', value: '' } ], modelProperty = options.modelProperty, emptyParameter = options.emptyParameter, canBeDisabled = !!options.disabled && typeof options.disabled === 'function', canBeHidden = !!options.hidden && typeof options.hidden === 'function', description = options.description; if (emptyParameter) { selectOptions = addEmptyParameter(selectOptions); } resource.html = '<label for="activiti-' + escapeHTML(resource.id) + '"' + (canBeDisabled ? 'data-disable="isDisabled" ' : '') + (canBeHidden ? 'data-show="isHidden" ' : '') + '>' + escapeHTML(label) + '</label>' + '<select id="activiti-' + escapeHTML(resource.id) + '-select" name="' + escapeHTML(modelProperty) + '"' + (canBeDisabled ? 'data-disable="isDisabled" ' : '') + (canBeHidden ? 'data-show="isHidden" ' : '') + ' data-value>'; if (isList(selectOptions)) { forEach(selectOptions, function(option) { resource.html += '<option value="' + escapeHTML(option.value) + '">' + (option.name ? escapeHTML(option.name) : '') + '</option>'; }); } resource.html += '</select>'; // add description below select box entry field if (description && typeof options.showCustomInput !== 'function') { resource.html += entryFieldDescription(description); } /** * Fill the select box options dynamically. * * Calls the defined function #selectOptions in the entry to get the * values for the options and set the value to the inputNode. * * @param {djs.model.Base} element * @param {HTMLElement} entryNode * @param {EntryDescriptor} inputNode * @param {Object} inputName * @param {Object} newValue */ resource.setControlValue = function(element, entryNode, inputNode, inputName, newValue) { if (typeof selectOptions === 'function') { var options = selectOptions(element, inputNode); if (options) { // remove existing options while (inputNode.firstChild) { inputNode.removeChild(inputNode.firstChild); } // add options forEach(options, function(option) { var template = domify(createOption(option)); inputNode.appendChild(template); }); } } // set select value if (newValue !== undefined) { inputNode.value = newValue; } }; if (canBeDisabled) { resource.isDisabled = function() { return options.disabled.apply(resource, arguments); }; } if (canBeHidden) { resource.isHidden = function() { return !options.hidden.apply(resource, arguments); }; } resource.cssClasses = ['bpp-dropdown']; return resource; }; module.exports = selectbox; },{"../Utils":576,"./EntryFieldDescription":580,"lodash/forEach":522,"min-dom":556}],584:[function(require,module,exports){ 'use strict'; var escapeHTML = require('../Utils').escapeHTML; var cmdHelper = require('../helper/CmdHelper'); var domQuery = require('min-dom').query, domAttr = require('min-dom').attr, domClosest = require('min-dom').closest; var filter = require('lodash/filter'), forEach = require('lodash/forEach'), keys = require('lodash/keys'); var domify = require('min-dom').domify; var entryFieldDescription = require('./EntryFieldDescription'); var updateSelection = require('selection-update'); var TABLE_ROW_DIV_SNIPPET = '<div class="bpp-field-wrapper bpp-table-row">'; var DELETE_ROW_BUTTON_SNIPPET = '<button class="clear" data-action="deleteElement">' + '<span>X</span>' + '</button>'; function createInputRowTemplate(properties, canRemove) { var template = TABLE_ROW_DIV_SNIPPET; template += createInputTemplate(properties, canRemove); template += canRemove ? DELETE_ROW_BUTTON_SNIPPET : ''; template += '</div>'; return template; } function createInputTemplate(properties, canRemove) { var columns = properties.length; var template = ''; forEach(properties, function(prop) { template += '<input class="bpp-table-row-columns-' + columns + ' ' + (canRemove ? 'bpp-table-row-removable' : '') + '" ' + 'id="activiti-table-row-cell-input-value" ' + 'type="text" ' + 'name="' + escapeHTML(prop) + '" />'; }); return template; } function createLabelRowTemplate(labels) { var template = TABLE_ROW_DIV_SNIPPET; template += createLabelTemplate(labels); template += '</div>'; return template; } function createLabelTemplate(labels) { var columns = labels.length; var template = ''; forEach(labels, function(label) { template += '<label class="bpp-table-row-columns-' + columns + '">' + escapeHTML(label) + '</label>'; }); return template; } function pick(elements, properties) { return (elements || []).map(function(elem) { var newElement = {}; forEach(properties, function(prop) { newElement[prop] = elem[prop] || ''; }); return newElement; }); } function diff(element, node, values, oldValues, editable) { return filter(values, function(value, idx) { return !valueEqual(element, node, value, oldValues[idx], editable, idx); }); } function valueEqual(element, node, value, oldValue, editable, idx) { if (value && !oldValue) { return false; } var allKeys = keys(value).concat(keys(oldValue)); return allKeys.every(function(key) { var n = value[key] || undefined; var o = oldValue[key] || undefined; return !editable(element, node, key, idx) || n === o; }); } function getEntryNode(node) { return domClosest(node, '[data-entry]', true); } function getContainer(node) { return domQuery('div[data-list-entry-container]', node); } function getSelection(node) { return { start: node.selectionStart, end: node.selectionEnd }; } function setSelection(node, selection) { node.selectionStart = selection.start; node.selectionEnd = selection.end; } /** * @param {Object} options * @param {string} options.id * @param {string} options.description * @param {Array<string>} options.modelProperties * @param {Array<string>} options.labels * @param {Function} options.getElements - this callback function must return a list of business object items * @param {Function} options.removeElement * @param {Function} options.addElement * @param {Function} options.updateElement * @param {Function} options.editable * @param {Function} options.setControlValue * @param {Function} options.show * * @return {Object} */ module.exports = function(options) { var id = options.id, modelProperties = options.modelProperties, labels = options.labels, description = options.description; var labelRow = createLabelRowTemplate(labels); var getElements = options.getElements; var removeElement = options.removeElement, canRemove = typeof removeElement === 'function'; var addElement = options.addElement, canAdd = typeof addElement === 'function', addLabel = options.addLabel || 'Add Value'; var updateElement = options.updateElement, canUpdate = typeof updateElement === 'function'; var editable = options.editable || function() { return true; }, setControlValue = options.setControlValue; var show = options.show, canBeShown = typeof show === 'function'; var elements = function(element, node) { return pick(getElements(element, node), modelProperties); }; var factory = { id: id, html: (canAdd ? '<div class="bpp-table-add-row" ' + (canBeShown ? 'data-show="show"' : '') + '>' + '<label>' + escapeHTML(addLabel) + '</label>' + '<button class="add" data-action="addElement"><span>+</span></button>' + '</div>' : '') + '<div class="bpp-table" data-show="showTable">' + '<div class="bpp-field-wrapper bpp-table-row">' + labelRow + '</div>' + '<div data-list-entry-container>' + '</div>' + '</div>' + // add description below table entry field (description ? entryFieldDescription(description) : ''), get: function(element, node) { var boElements = elements(element, node, this.__invalidValues); var invalidValues = this.__invalidValues; delete this.__invalidValues; forEach(invalidValues, function(value, idx) { var element = boElements[idx]; forEach(modelProperties, function(prop) { element[prop] = value[prop]; }); }); return boElements; }, set: function(element, values, node) { var action = this.__action || {}; delete this.__action; if (action.id === 'delete-element') { return removeElement(element, node, action.idx); } else if (action.id === 'add-element') { return addElement(element, node); } else if (canUpdate) { var commands = [], valuesToValidate = values; if (typeof options.validate !== 'function') { valuesToValidate = diff(element, node, values, elements(element, node), editable); } var self = this; forEach(valuesToValidate, function(value) { var validationError, idx = values.indexOf(value); if (typeof options.validate === 'function') { validationError = options.validate(element, value, node, idx); } if (!validationError) { var cmd = updateElement(element, value, node, idx); if (cmd) { commands.push(cmd); } } else { // cache invalid value in an object by index as key self.__invalidValues = self.__invalidValues || {}; self.__invalidValues[idx] = value; // execute a command, which does not do anything commands.push(cmdHelper.updateProperties(element, {})); } }); return commands; } }, createListEntryTemplate: function(value, index, selectBox) { return createInputRowTemplate(modelProperties, canRemove); }, addElement: function(element, node, event, scopeNode) { var template = domify(createInputRowTemplate(modelProperties, canRemove)); var container = getContainer(node); container.appendChild(template); this.__action = { id: 'add-element' }; return true; }, deleteElement: function(element, node, event, scopeNode) { var container = getContainer(node); var rowToDelete = event.delegateTarget.parentNode; var idx = parseInt(domAttr(rowToDelete, 'data-index'), 10); container.removeChild(rowToDelete); this.__action = { id: 'delete-element', idx: idx }; return true; }, editable: function(element, rowNode, input, prop, value, idx) { var entryNode = domClosest(rowNode, '[data-entry]'); return editable(element, entryNode, prop, idx); }, show: function(element, entryNode, node, scopeNode) { entryNode = getEntryNode(entryNode); return show(element, entryNode, node, scopeNode); }, showTable: function(element, entryNode, node, scopeNode) { entryNode = getEntryNode(entryNode); var elems = elements(element, entryNode); return elems && elems.length && (!canBeShown || show(element, entryNode, node, scopeNode)); }, validateListItem: function(element, value, node, idx) { if (typeof options.validate === 'function') { return options.validate(element, value, node, idx); } } }; // Update/set the selection on the correct position. // It's the same code like for an input value in the PropertiesPanel.js. if (setControlValue) { factory.setControlValue = function(element, rowNode, input, prop, value, idx) { var entryNode = getEntryNode(rowNode); var isReadOnly = domAttr(input, 'readonly'); var oldValue = input.value; var selection; // prevents input fields from having the value 'undefined' if (value === undefined) { value = ''; } // when the attribute 'readonly' exists, ignore the comparison // with 'oldValue' and 'value' if (!!isReadOnly && oldValue === value) { return; } // update selection on undo/redo if (document.activeElement === input) { selection = updateSelection(getSelection(input), oldValue, value); } setControlValue(element, entryNode, input, prop, value, idx); if (selection) { setSelection(input, selection); } }; } return factory; }; },{"../Utils":576,"../helper/CmdHelper":590,"./EntryFieldDescription":580,"lodash/filter":518,"lodash/forEach":522,"lodash/keys":539,"min-dom":556,"selection-update":566}],585:[function(require,module,exports){ 'use strict'; var escapeHTML = require('../Utils').escapeHTML; var entryFieldDescription = require('./EntryFieldDescription'); var textBox = function(options, defaultParameters) { var resource = defaultParameters, label = options.label || resource.id, canBeShown = !!options.show && typeof options.show === 'function', description = options.description; resource.html = '<label for="activiti-' + escapeHTML(resource.id) + '" ' + (canBeShown ? 'data-show="isShown"' : '') + '>' + label + '</label>' + '<div class="bpp-field-wrapper" ' + (canBeShown ? 'data-show="isShown"' : '') + '>' + '<div contenteditable="true" id="activiti-' + escapeHTML(resource.id) + '" ' + 'name="' + escapeHTML(options.modelProperty) + '" style="height:91px"/>' + '</div>'; // add description below text box entry field if (description) { resource.html += entryFieldDescription(description); } if (canBeShown) { resource.isShown = function() { return options.show.apply(resource, arguments); }; } resource.cssClasses = ['bpp-textbox']; return resource; }; module.exports = textBox; },{"../Utils":576,"./EntryFieldDescription":580}],586:[function(require,module,exports){ 'use strict'; var escapeHTML = require('../Utils').escapeHTML; var domQuery = require('min-dom').query; var entryFieldDescription = require('./EntryFieldDescription'); var textField = function(options, defaultParameters) { // Default action for the button next to the input-field var defaultButtonAction = function(element, inputNode) { var input = domQuery('input[name="' + options.modelProperty + '"]', inputNode); input.value = ''; return true; }; // default method to determine if the button should be visible var defaultButtonShow = function(element, inputNode) { var input = domQuery('input[name="' + options.modelProperty + '"]', inputNode); return input.value !== ''; }; var resource = defaultParameters, label = options.label || resource.id, dataValueLabel = options.dataValueLabel, buttonLabel = (options.buttonLabel || 'X'), actionName = (typeof options.buttonAction != 'undefined') ? options.buttonAction.name : 'clear', actionMethod = (typeof options.buttonAction != 'undefined') ? options.buttonAction.method : defaultButtonAction, showName = (typeof options.buttonShow != 'undefined') ? options.buttonShow.name : 'canClear', showMethod = (typeof options.buttonShow != 'undefined') ? options.buttonShow.method : defaultButtonShow, canBeDisabled = !!options.disabled && typeof options.disabled === 'function', canBeHidden = !!options.hidden && typeof options.hidden === 'function', description = options.description; resource.html = '<label for="activiti-' + escapeHTML(resource.id) + '" ' + (canBeDisabled ? 'data-disable="isDisabled" ' : '') + (canBeHidden ? 'data-show="isHidden" ' : '') + (dataValueLabel ? 'data-value="' + escapeHTML(dataValueLabel) + '"' : '') + '>'+ escapeHTML(label) +'</label>' + '<div class="bpp-field-wrapper" ' + (canBeDisabled ? 'data-disable="isDisabled"' : '') + (canBeHidden ? 'data-show="isHidden"' : '') + '>' + '<input type="button" name="' + escapeHTML(options.modelProperty) + '" style="width: 100%;text-align: left;" />' + '<input id="activiti-' + escapeHTML(resource.id) + '" type="hidden" name="' + escapeHTML(options.modelProperty) + '" ' + (true ? 'data-disable="isDisabled"' : '') + (canBeHidden ? 'data-show="isHidden"' : '') + ' />' + // '<button class="' + escapeHTML(actionName) + '" data-action="' + escapeHTML(actionName) + '" data-show="' + escapeHTML(showName) + '" ' + // (canBeDisabled ? 'data-disable="isDisabled"' : '') + // (canBeHidden ? ' data-show="isHidden"' : '') + '>' + // '<span>' + escapeHTML(buttonLabel) + '</span>' + '</button>' + '</div>'; // add description below text input entry field if (description) { resource.html += entryFieldDescription(description); } resource[actionName] = actionMethod; resource[showName] = showMethod; if (canBeDisabled) { resource.isDisabled = function() { return options.disabled.apply(resource, arguments); }; } if (canBeHidden) { resource.isHidden = function() { return !options.hidden.apply(resource, arguments); }; } resource.cssClasses = ['bpp-textfield']; return resource; }; module.exports = textField; },{"../Utils":576,"./EntryFieldDescription":580,"min-dom":556}],587:[function(require,module,exports){ 'use strict'; var textField = require('./TextInputEntryFactory'); /** * This function is a wrapper around TextInputEntryFactory. * It adds functionality to cache an invalid value entered in the * text input, instead of setting it on the business object. */ var validationAwareTextField = function(options, defaultParameters) { var modelProperty = options.modelProperty; defaultParameters.get = function(element, node) { var value = this.__lastInvalidValue; delete this.__lastInvalidValue; var properties = {}; properties[modelProperty] = value !== undefined ? value : options.getProperty(element, node); return properties; }; defaultParameters.set = function(element, values, node) { var validationErrors = validate.apply(this, [ element, values, node ]), propertyValue = values[modelProperty]; // make sure we do not update the id if (validationErrors && validationErrors[modelProperty]) { this.__lastInvalidValue = propertyValue; return options.setProperty(element, {}, node); } else { var properties = {}; properties[modelProperty] = propertyValue; return options.setProperty(element, properties, node); } }; var validate = defaultParameters.validate = function(element, values, node) { var value = values[modelProperty] || this.__lastInvalidValue; var property = {}; property[modelProperty] = value; return options.validate(element, property, node); }; return textField(options, defaultParameters); }; module.exports = validationAwareTextField; },{"./TextInputEntryFactory":586}],588:[function(require,module,exports){ 'use strict'; var map = require('lodash/map'); var extensionElementsHelper = require('./ExtensionElementsHelper'); /** * Returns true if the attribute 'activiti:asyncBefore' is set * to true. * * @param {ModdleElement} bo * * @return {boolean} a boolean value */ function isAsyncBefore(bo) { return !!(bo.get('activiti:asyncBefore') || bo.get('activiti:async')); } module.exports.isAsyncBefore = isAsyncBefore; /** * Returns true if the attribute 'activiti:asyncAfter' is set * to true. * * @param {ModdleElement} bo * * @return {boolean} a boolean value */ function isAsyncAfter(bo) { return !!bo.get('activiti:asyncAfter'); } module.exports.isAsyncAfter = isAsyncAfter; /** * Returns true if the attribute 'activiti:exclusive' is set * to true. * * @param {ModdleElement} bo * * @return {boolean} a boolean value */ function isExclusive(bo) { return !!bo.get('activiti:exclusive'); } module.exports.isExclusive = isExclusive; /** * Get first 'activiti:FailedJobRetryTimeCycle' from the business object. * * @param {ModdleElement} bo * * @return {Array<ModdleElement>} a list of 'activiti:FailedJobRetryTimeCycle' */ function getFailedJobRetryTimeCycle(bo) { return (extensionElementsHelper.getExtensionElements(bo, 'activiti:FailedJobRetryTimeCycle') || [])[0]; } module.exports.getFailedJobRetryTimeCycle = getFailedJobRetryTimeCycle; /** * Removes all existing 'activiti:FailedJobRetryTimeCycle' from the business object * * @param {ModdleElement} bo * * @return {Array<ModdleElement>} a list of 'activiti:FailedJobRetryTimeCycle' */ function removeFailedJobRetryTimeCycle(bo, element) { var retryTimeCycles = extensionElementsHelper.getExtensionElements(bo, 'activiti:FailedJobRetryTimeCycle'); return map(retryTimeCycles, function(cycle) { return extensionElementsHelper.removeEntry(bo, element, cycle); }); } module.exports.removeFailedJobRetryTimeCycle = removeFailedJobRetryTimeCycle; },{"./ExtensionElementsHelper":593,"lodash/map":540}],589:[function(require,module,exports){ 'use strict'; var collectionAdd = require('diagram-js/lib/util/Collections').add, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var CategoryHelper = {}; module.exports = CategoryHelper; /** * Creates a new bpmn:CategoryValue inside a new bpmn:Category * * @param {ModdleElement} definitions * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} categoryValue. */ CategoryHelper.createCategoryValue = function(definitions, bpmnFactory) { var categoryValue = bpmnFactory.create('bpmn:CategoryValue'), category = bpmnFactory.create('bpmn:Category', { categoryValue: [ categoryValue ] }); // add to correct place collectionAdd(definitions.get('rootElements'), category); getBusinessObject(category).$parent = definitions; getBusinessObject(categoryValue).$parent = category; return categoryValue; }; },{"bpmn-js/lib/util/ModelUtil":141,"diagram-js/lib/util/Collections":339}],590:[function(require,module,exports){ 'use strict'; var CmdHelper = {}; module.exports = CmdHelper; CmdHelper.updateProperties = function(element, properties) { return { cmd: 'element.updateProperties', context: { element: element, properties: properties } }; }; CmdHelper.updateBusinessObject = function(element, businessObject, newProperties) { return { cmd: 'properties-panel.update-businessobject', context: { element: element, businessObject: businessObject, properties: newProperties } }; }; CmdHelper.addElementsTolist = function(element, businessObject, listPropertyName, objectsToAdd) { return { cmd: 'properties-panel.update-businessobject-list', context: { element: element, currentObject: businessObject, propertyName: listPropertyName, objectsToAdd: objectsToAdd } }; }; CmdHelper.removeElementsFromList = function(element, businessObject, listPropertyName, referencePropertyName, objectsToRemove) { return { cmd: 'properties-panel.update-businessobject-list', context: { element: element, currentObject: businessObject, propertyName: listPropertyName, referencePropertyName: referencePropertyName, objectsToRemove: objectsToRemove } }; }; CmdHelper.addAndRemoveElementsFromList = function(element, businessObject, listPropertyName, referencePropertyName, objectsToAdd, objectsToRemove) { return { cmd: 'properties-panel.update-businessobject-list', context: { element: element, currentObject: businessObject, propertyName: listPropertyName, referencePropertyName: referencePropertyName, objectsToAdd: objectsToAdd, objectsToRemove: objectsToRemove } }; }; CmdHelper.setList = function(element, businessObject, listPropertyName, updatedObjectList) { return { cmd: 'properties-panel.update-businessobject-list', context: { element: element, currentObject: businessObject, propertyName: listPropertyName, updatedObjectList: updatedObjectList } }; }; },{}],591:[function(require,module,exports){ 'use strict'; var ElementHelper = {}; module.exports = ElementHelper; /** * Creates a new element and set the parent to it * * @method ElementHelper#createElement * * @param {String} elementType of the new element * @param {Object} properties of the new element in key-value pairs * @param {moddle.object} parent of the new element * @param {BpmnFactory} factory which creates the new element * * @returns {djs.model.Base} element which is created */ ElementHelper.createElement = function(elementType, properties, parent, factory) { var element = factory.create(elementType, properties); element.$parent = parent; return element; }; },{}],592:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is, forEach = require('lodash/forEach'); var EventDefinitionHelper = {}; module.exports = EventDefinitionHelper; EventDefinitionHelper.getEventDefinition = function(element, eventType) { var bo = getBusinessObject(element), eventDefinition = null; if (bo.eventDefinitions) { forEach(bo.eventDefinitions, function(event) { if (is(event, eventType)) { eventDefinition = event; } }); } return eventDefinition; }; EventDefinitionHelper.getTimerEventDefinition = function(element) { return this.getEventDefinition(element, 'bpmn:TimerEventDefinition'); }; EventDefinitionHelper.getMessageEventDefinition = function(element) { return this.getEventDefinition(element, 'bpmn:MessageEventDefinition'); }; EventDefinitionHelper.getSignalEventDefinition = function(element) { return this.getEventDefinition(element, 'bpmn:SignalEventDefinition'); }; EventDefinitionHelper.getErrorEventDefinition = function(element) { return this.getEventDefinition(element, 'bpmn:ErrorEventDefinition'); }; EventDefinitionHelper.getEscalationEventDefinition = function(element) { return this.getEventDefinition(element, 'bpmn:EscalationEventDefinition'); }; EventDefinitionHelper.getCompensateEventDefinition = function(element) { return this.getEventDefinition(element, 'bpmn:CompensateEventDefinition'); }; EventDefinitionHelper.getLinkEventDefinition = function(element) { return this.getEventDefinition(element, 'bpmn:LinkEventDefinition'); }; EventDefinitionHelper.getConditionalEventDefinition = function(element) { return this.getEventDefinition(element, 'bpmn:ConditionalEventDefinition'); }; },{"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],593:[function(require,module,exports){ 'use strict'; var cmdHelper = require('./CmdHelper'), elementHelper = require('./ElementHelper'); var is = require('bpmn-js/lib/util/ModelUtil').is; var ExtensionElementsHelper = {}; var getExtensionElements = function(bo) { return bo.get('extensionElements'); }; ExtensionElementsHelper.getExtensionElements = function(bo, type) { var extensionElements = getExtensionElements(bo); if (typeof extensionElements !== 'undefined') { var extensionValues = extensionElements.get('values'); if (typeof extensionValues !== 'undefined') { var elements = extensionValues.filter(function(value) { return is(value, type); }); if (elements.length) { return elements; } } } }; ExtensionElementsHelper.addEntry = function(bo, element, entry, bpmnFactory) { var extensionElements = bo.get('extensionElements'); // if there is no extensionElements list, create one if (!extensionElements) { // TODO: Ask Daniel which operation costs more extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [entry] }, bo, bpmnFactory); return { extensionElements : extensionElements }; } else { // add new failedJobRetryExtensionElement to existing extensionElements list return cmdHelper.addElementsTolist(element, extensionElements, 'values', [entry]); } }; ExtensionElementsHelper.removeEntry = function(bo, element, entry) { var extensionElements = bo.get('extensionElements'); if (!extensionElements) { // return an empty command when there is no extensionElements list return {}; } return cmdHelper.removeElementsFromList(element, extensionElements, 'values', 'extensionElements', [entry]); }; module.exports = ExtensionElementsHelper; },{"./CmdHelper":590,"./ElementHelper":591,"bpmn-js/lib/util/ModelUtil":141}],594:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, getExtensionElements = require('./ExtensionElementsHelper').getExtensionElements; var FormHelper = {}; module.exports = FormHelper; /** * Return form data from business object or undefined if none exist * * @param {djs.model.Base} element * * @return {ModdleElement|undefined} formData * * 此方法废弃 * */ FormHelper.getFormData = function(element) { /* var bo = getBusinessObject(element); var formFields = getExtensionElements(bo, 'activiti:FormProperty'); var formData = {} if (typeof formData !== 'undefined') { return formData[0]; }*/ return {}; }; /** * Return all form fields existing in the business object, and * an empty array if none exist. * * @param {djs.model.Base} element * * @return {Array} a list of form field objects */ FormHelper.getFormFields = function(element) { /**直接获取 ExtensionElements的 activiti:FormProperty元素*/ var bo = getBusinessObject(element); var formFields = getExtensionElements(bo, 'activiti:FormProperty'); return formFields || []; }; /** * Get a form field from the business object at given index * * @param {djs.model.Base} element * @param {number} idx * * @return {ModdleElement} the form field */ FormHelper.getFormField = function(element, idx) { var formFields = this.getFormFields(element); return formFields[idx]; }; /** * Get all constraints for a specific form field from the business object * * @param {ModdleElement} formField * * @return {Array<ModdleElement>} a list of constraint objects */ FormHelper.getConstraints = function(formField) { if (formField && formField.validation && formField.validation.constraints) { return formField.validation.constraints; } return []; }; /** * Get all activiti:value objects for a specific form field from the business object * * @param {ModdleElement} formField * * @return {Array<ModdleElement>} a list of activiti:value objects */ FormHelper.getEnumValues = function(formField) { if (formField && formField.values) { return formField.values; } return []; }; },{"./ExtensionElementsHelper":593,"bpmn-js/lib/util/ModelUtil":141}],595:[function(require,module,exports){ 'use strict'; var ModelUtil = require('bpmn-js/lib/util/ModelUtil'), is = ModelUtil.is, getBusinessObject = ModelUtil.getBusinessObject; var eventDefinitionHelper = require('./EventDefinitionHelper'); var extensionsElementHelper = require('./ExtensionElementsHelper'); var ImplementationTypeHelper = {}; module.exports = ImplementationTypeHelper; /** * Returns 'true' if the given element is 'activiti:ServiceTaskLike' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isServiceTaskLike = function(element) { return is(element, 'activiti:ServiceTaskLike'); }; /** * Returns 'true' if the given element is 'activiti:DmnCapable' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isDmnCapable = function(element) { return is(element, 'activiti:DmnCapable'); }; /** * Returns 'true' if the given element is 'activiti:ExternalCapable' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isExternalCapable = function(element) { return is(element, 'activiti:ExternalCapable'); }; /** * Returns 'true' if the given element is 'activiti:TaskListener' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isTaskListener = function(element) { return is(element, 'activiti:TaskListener'); }; /** * Returns 'true' if the given element is 'activiti:ExecutionListener' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isExecutionListener = function(element) { return is(element, 'activiti:ExecutionListener'); }; /** * Returns 'true' if the given element is 'activiti:ExecutionListener' or * 'activiti:TaskListener' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isListener = function(element) { return this.isTaskListener(element) || this.isExecutionListener(element); }; /** * Returns 'true' if the given element is 'bpmn:SequenceFlow' * * @param {djs.model.Base} element * * @return {boolean} a boolean value */ ImplementationTypeHelper.isSequenceFlow = function(element) { return is(element, 'bpmn:SequenceFlow'); }; /** * Get a 'activiti:ServiceTaskLike' business object. * * If the given element is not a 'activiti:ServiceTaskLike', then 'false' * is returned. * * @param {djs.model.Base} element * * @return {ModdleElement} the 'activiti:ServiceTaskLike' business object */ ImplementationTypeHelper.getServiceTaskLikeBusinessObject = function(element) { if (is(element, 'bpmn:IntermediateThrowEvent') || is(element, 'bpmn:EndEvent')) { // change business object to 'messageEventDefinition' when // the element is a message intermediate throw event or message end event // because the activiti extensions (e.g. activiti:class) are in the message // event definition tag and not in the intermediate throw event or end event tag var messageEventDefinition = eventDefinitionHelper.getMessageEventDefinition(element); if (messageEventDefinition) { element = messageEventDefinition; } } return this.isServiceTaskLike(element) && getBusinessObject(element); }; /** * Returns the implementation type of the given element. * * Possible implementation types are: * - dmn * - connector * - external * - class * - expression * - delegateExpression * - script * - or undefined, when no matching implementation type is found * * @param {djs.model.Base} element * * @return {String} the implementation type */ ImplementationTypeHelper.getImplementationType = function(element) { var bo = this.getServiceTaskLikeBusinessObject(element); if (!bo) { if (this.isListener(element)) { bo = element; } else { return; } } if (this.isDmnCapable(bo)) { var decisionRef = bo.get('activiti:decisionRef'); if (typeof decisionRef !== 'undefined') { return 'dmn'; } } if (this.isServiceTaskLike(bo)) { var connectors = extensionsElementHelper.getExtensionElements(bo, 'activiti:Connector'); if (typeof connectors !== 'undefined') { return 'connector'; } } if (this.isExternalCapable(bo)) { var type = bo.get('activiti:type'); if (type === 'external') { return 'external'; } } var cls = bo.get('activiti:class'); if (typeof cls !== 'undefined') { return 'class'; } var expression = bo.get('activiti:expression'); if (typeof expression !== 'undefined') { return 'expression'; } var delegateExpression = bo.get('activiti:delegateExpression'); if (typeof delegateExpression !== 'undefined') { return 'delegateExpression'; } if (this.isListener(bo)) { var script = bo.get('script'); if (typeof script !== 'undefined') { return 'script'; } } }; },{"./EventDefinitionHelper":592,"./ExtensionElementsHelper":593,"bpmn-js/lib/util/ModelUtil":141}],596:[function(require,module,exports){ 'use strict'; var ModelUtil = require('bpmn-js/lib/util/ModelUtil'), is = ModelUtil.is, getBusinessObject = ModelUtil.getBusinessObject; var extensionElementsHelper = require('./ExtensionElementsHelper'), implementationTypeHelper = require('./ImplementationTypeHelper'); var InputOutputHelper = {}; module.exports = InputOutputHelper; function getElements(bo, type, prop) { var elems = extensionElementsHelper.getExtensionElements(bo, type) || []; return !prop ? elems : (elems[0] || {})[prop] || []; } function getParameters(element, prop, insideConnector) { var inputOutput = InputOutputHelper.getInputOutput(element, insideConnector); return (inputOutput && inputOutput.get(prop)) || []; } /** * Get a inputOutput from the business object * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {ModdleElement} the inputOutput object */ InputOutputHelper.getInputOutput = function(element, insideConnector) { if (!insideConnector) { var bo = getBusinessObject(element); return (getElements(bo, 'activiti:InputOutput') || [])[0]; } var connector = this.getConnector(element); return connector && connector.get('inputOutput'); }; /** * Get a connector from the business object * * @param {djs.model.Base} element * * @return {ModdleElement} the connector object */ InputOutputHelper.getConnector = function(element) { var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element); return bo && (getElements(bo, 'activiti:Connector') || [])[0]; }; /** * Return all input parameters existing in the business object, and * an empty array if none exist. * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {Array} a list of input parameter objects */ InputOutputHelper.getInputParameters = function(element, insideConnector) { return getParameters.apply(this, [ element, 'inputParameters', insideConnector ]); }; /** * Return all output parameters existing in the business object, and * an empty array if none exist. * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {Array} a list of output parameter objects */ InputOutputHelper.getOutputParameters = function(element, insideConnector) { return getParameters.apply(this, [ element, 'outputParameters', insideConnector ]); }; /** * Get a input parameter from the business object at given index * * @param {djs.model.Base} element * @param {boolean} insideConnector * @param {number} idx * * @return {ModdleElement} input parameter */ InputOutputHelper.getInputParameter = function(element, insideConnector, idx) { return this.getInputParameters(element, insideConnector)[idx]; }; /** * Get a output parameter from the business object at given index * * @param {djs.model.Base} element * @param {boolean} insideConnector * @param {number} idx * * @return {ModdleElement} output parameter */ InputOutputHelper.getOutputParameter = function(element, insideConnector, idx) { return this.getOutputParameters(element, insideConnector)[idx]; }; /** * Returns 'true' if the given element supports inputOutput * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {boolean} a boolean value */ InputOutputHelper.isInputOutputSupported = function(element, insideConnector) { if (insideConnector) { return true; } var bo = getBusinessObject(element); return ( is(bo, 'bpmn:FlowNode') && !( is(bo, 'bpmn:StartEvent') || is(bo, 'bpmn:Gateway') || is(bo, 'bpmn:BoundaryEvent') || ( is(bo, 'bpmn:SubProcess') && bo.get('triggeredByEvent') ) ) ); }; /** * Returns 'true' if the given element supports output parameters * * @param {djs.model.Base} element * @param {boolean} insideConnector * * @return {boolean} a boolean value */ InputOutputHelper.areOutputParametersSupported = function(element, insideConnector) { var bo = getBusinessObject(element); return insideConnector || (!is(bo, 'bpmn:EndEvent') && !bo.loopCharacteristics); }; },{"./ExtensionElementsHelper":593,"./ImplementationTypeHelper":595,"bpmn-js/lib/util/ModelUtil":141}],597:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, cmdHelper = require('./CmdHelper'); var ParticipantHelper = {}; module.exports = ParticipantHelper; ParticipantHelper.modifyProcessBusinessObject = function(element, property, values) { if (!is(element, 'bpmn:Participant')) { return {}; } var bo = getBusinessObject(element).get('processRef'), properties = {}; properties[property] = values[property]; return cmdHelper.updateBusinessObject(element, bo, properties); }; ParticipantHelper.getProcessBusinessObject = function(element, propertyName) { if (!is(element, 'bpmn:Participant')) { return {}; } var bo = getBusinessObject(element).get('processRef'), properties = {}; properties[propertyName] = bo.get(propertyName); return properties; }; },{"./CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141}],598:[function(require,module,exports){ 'use strict'; var inherits = require('inherits'); var PropertiesActivator = require('../../PropertiesActivator'); var asyncCapableHelper = require('../../helper/AsyncCapableHelper'), ImplementationTypeHelper = require('../../helper/ImplementationTypeHelper'); var is = require('bpmn-js/lib/util/ModelUtil').is; // bpmn properties var processProps = require('../../provider/bpmn/parts/ProcessProps'), eventProps = require('../../provider/bpmn/parts/EventProps'), linkProps = require('../../provider/bpmn/parts/LinkProps'), documentationProps = require('../../provider/bpmn/parts/DocumentationProps'), idProps = require('../../provider/bpmn/parts/IdProps'), nameProps = require('../../provider/bpmn/parts/NameProps'), executableProps = require('../../provider/bpmn/parts/ExecutableProps'); // activiti properties var serviceTaskDelegateProps = require('./parts/ServiceTaskDelegateProps'), userTaskProps = require('./parts/UserTaskProps'), asynchronousContinuationProps = require('./parts/AsynchronousContinuationProps'), callActivityProps = require('./parts/CallActivityProps'), multiInstanceProps = require('./parts/MultiInstanceLoopProps'), conditionalProps = require('./parts/ConditionalProps'), scriptProps = require('./parts/ScriptTaskProps'), errorProps = require('./parts/ErrorEventProps'), formProps = require('./parts/FormProps'), startEventInitiator = require('./parts/StartEventInitiator'), variableMapping = require('./parts/VariableMappingProps'), versionTag = require('./parts/VersionTagProps'); var listenerProps = require('./parts/ListenerProps'), listenerDetails = require('./parts/ListenerDetailProps'), listenerFields = require('./parts/ListenerFieldInjectionProps'); var elementTemplateChooserProps = require('./element-templates/parts/ChooserProps'), elementTemplateCustomProps = require('./element-templates/parts/CustomProps'); // Input/Output var inputOutput = require('./parts/InputOutputProps'), inputOutputParameter = require('./parts/InputOutputParameterProps'); // Connector var connectorDetails = require('./parts/ConnectorDetailProps'), connectorInputOutput = require('./parts/ConnectorInputOutputProps'), connectorInputOutputParameter = require('./parts/ConnectorInputOutputParameterProps'); // properties var properties = require('./parts/PropertiesProps'); // job configuration var jobConfiguration = require('./parts/JobConfigurationProps'); // history time to live var historyTimeToLive = require('./parts/HistoryTimeToLiveProps'); // candidate starter groups/users var candidateStarter = require('./parts/CandidateStarterProps'); // tasklist var tasklist = require('./parts/TasklistProps'); // external task configuration var externalTaskConfiguration = require('./parts/ExternalTaskConfigurationProps'); // field injection var fieldInjections = require('./parts/FieldInjectionProps'); var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, eventDefinitionHelper = require('../../helper/EventDefinitionHelper'), implementationTypeHelper = require('../../helper/ImplementationTypeHelper'); // helpers //////////////////////////////////////// var isExternalTaskPriorityEnabled = function(element) { var businessObject = getBusinessObject(element); // show only if element is a process, a participant ... if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { return true; } var externalBo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element), isExternalTask = ImplementationTypeHelper.getImplementationType(externalBo) === 'external'; // ... or an external task with selected external implementation type return !!ImplementationTypeHelper.isExternalCapable(externalBo) && isExternalTask; }; var isJobConfigEnabled = function(element) { var businessObject = getBusinessObject(element); if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { return true; } // async behavior var bo = getBusinessObject(element); if (asyncCapableHelper.isAsyncBefore(bo) || asyncCapableHelper.isAsyncAfter(bo)) { return true; } // timer definition if (is(element, 'bpmn:Event')) { return !!eventDefinitionHelper.getTimerEventDefinition(element); } return false; }; var getInputOutputParameterLabel = function(param, translate) { if (is(param, 'activiti:InputParameter')) { return translate('Input Parameter'); } if (is(param, 'activiti:OutputParameter')) { return translate('Output Parameter'); } return ''; }; var getListenerLabel = function(param, translate) { if (is(param, 'activiti:ExecutionListener')) { return translate('Execution Listener'); } if (is(param, 'activiti:TaskListener')) { return translate('Task Listener'); } return ''; }; var PROCESS_KEY_HINT = 'This maps to the process definition key.'; var TASK_KEY_HINT = 'This maps to the task definition key.'; function createGeneralTabGroups( element, canvas, bpmnFactory, elementRegistry, elementTemplates, translate) { // refer to target element for external labels element = element.labelTarget || element; var generalGroup = { id: 'general', label: translate('General'), entries: [] }; var idOptions; var processOptions; if (is(element, 'bpmn:Process')) { idOptions = { description: PROCESS_KEY_HINT }; } if (is(element, 'bpmn:UserTask')) { idOptions = { description: TASK_KEY_HINT }; } if (is(element, 'bpmn:Participant')) { processOptions = { processIdDescription: PROCESS_KEY_HINT }; } idProps(generalGroup, element, translate, idOptions); nameProps(generalGroup, element, bpmnFactory, canvas, translate); processProps(generalGroup, element, translate, processOptions); versionTag(generalGroup, element, translate); executableProps(generalGroup, element, translate); elementTemplateChooserProps(generalGroup, element, elementTemplates, translate); var customFieldsGroups = elementTemplateCustomProps(element, elementTemplates, bpmnFactory, translate); var detailsGroup = { id: 'details', label: translate('Details'), entries: [] }; serviceTaskDelegateProps(detailsGroup, element, bpmnFactory, translate); userTaskProps(detailsGroup, element, translate); scriptProps(detailsGroup, element, bpmnFactory, translate); linkProps(detailsGroup, element, translate); callActivityProps(detailsGroup, element, bpmnFactory, translate); eventProps(detailsGroup, element, bpmnFactory, elementRegistry, translate); errorProps(detailsGroup, element, bpmnFactory, translate); conditionalProps(detailsGroup, element, bpmnFactory, translate); startEventInitiator(detailsGroup, element, translate); // this must be the last element of the details group! var multiInstanceGroup = { id: 'multiInstance', label: translate('Multi Instance'), entries: [] }; multiInstanceProps(multiInstanceGroup, element, bpmnFactory, translate); var asyncGroup = { id : 'async', label: translate('Asynchronous Continuations'), entries : [] }; asynchronousContinuationProps(asyncGroup, element, bpmnFactory, translate); var jobConfigurationGroup = { id : 'jobConfiguration', label : translate('Job Configuration'), entries : [], enabled: isJobConfigEnabled }; jobConfiguration(jobConfigurationGroup, element, bpmnFactory, translate); var externalTaskGroup = { id : 'externalTaskConfiguration', label : translate('External Task Configuration'), entries : [], enabled: isExternalTaskPriorityEnabled }; externalTaskConfiguration(externalTaskGroup, element, bpmnFactory, translate); var candidateStarterGroup = { id: 'candidateStarterConfiguration', label: translate('Candidate Starter Configuration'), entries: [] }; candidateStarter(candidateStarterGroup, element, bpmnFactory, translate); var historyTimeToLiveGroup = { id: 'historyConfiguration', label: translate('History Configuration'), entries: [] }; historyTimeToLive(historyTimeToLiveGroup, element, bpmnFactory, translate); var tasklistGroup = { id: 'tasklist', label: translate('Tasklist Configuration'), entries: [] }; tasklist(tasklistGroup, element, bpmnFactory, translate); var documentationGroup = { id: 'documentation', label: translate('Documentation'), entries: [] }; documentationProps(documentationGroup, element, bpmnFactory, translate); var groups = []; groups.push(generalGroup); customFieldsGroups.forEach(function(group) { groups.push(group); }); groups.push(detailsGroup); groups.push(externalTaskGroup); groups.push(multiInstanceGroup); groups.push(asyncGroup); groups.push(jobConfigurationGroup); groups.push(candidateStarterGroup); groups.push(historyTimeToLiveGroup); groups.push(tasklistGroup); groups.push(documentationGroup); return groups; } function createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate) { var variablesGroup = { id : 'variables', label : translate('Variables'), entries: [] }; variableMapping(variablesGroup, element, bpmnFactory, translate); return [ variablesGroup ]; } function createFormsTabGroups(element, bpmnFactory, elementRegistry, translate) { var formGroup = { id : 'forms', label : translate('Forms'), entries: [] }; formProps(formGroup, element, bpmnFactory, translate); return [ formGroup ]; } function createListenersTabGroups(element, bpmnFactory, elementRegistry, translate) { var listenersGroup = { id : 'listeners', label: translate('Listeners'), entries: [] }; var options = listenerProps(listenersGroup, element, bpmnFactory, translate); var listenerDetailsGroup = { id: 'listener-details', entries: [], enabled: function(element, node) { return options.getSelectedListener(element, node); }, label: function(element, node) { var param = options.getSelectedListener(element, node); return getListenerLabel(param, translate); } }; listenerDetails(listenerDetailsGroup, element, bpmnFactory, options, translate); var listenerFieldsGroup = { id: 'listener-fields', label: translate('Field Injection'), entries: [], enabled: function(element, node) { return options.getSelectedListener(element, node); } }; listenerFields(listenerFieldsGroup, element, bpmnFactory, options, translate); return [ listenersGroup, listenerDetailsGroup, listenerFieldsGroup ]; } function createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate) { var inputOutputGroup = { id: 'input-output', label: translate('Parameters'), entries: [] }; var options = inputOutput(inputOutputGroup, element, bpmnFactory, translate); var inputOutputParameterGroup = { id: 'input-output-parameter', entries: [], enabled: function(element, node) { return options.getSelectedParameter(element, node); }, label: function(element, node) { var param = options.getSelectedParameter(element, node); return getInputOutputParameterLabel(param, translate); } }; inputOutputParameter(inputOutputParameterGroup, element, bpmnFactory, options, translate); return [ inputOutputGroup, inputOutputParameterGroup ]; } function createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate) { var connectorDetailsGroup = { id: 'connector-details', label: translate('Details'), entries: [] }; connectorDetails(connectorDetailsGroup, element, bpmnFactory, translate); var connectorInputOutputGroup = { id: 'connector-input-output', label: translate('Input/Output'), entries: [] }; var options = connectorInputOutput(connectorInputOutputGroup, element, bpmnFactory, translate); var connectorInputOutputParameterGroup = { id: 'connector-input-output-parameter', entries: [], enabled: function(element, node) { return options.getSelectedParameter(element, node); }, label: function(element, node) { var param = options.getSelectedParameter(element, node); return getInputOutputParameterLabel(param, translate); } }; connectorInputOutputParameter(connectorInputOutputParameterGroup, element, bpmnFactory, options, translate); return [ connectorDetailsGroup, connectorInputOutputGroup, connectorInputOutputParameterGroup ]; } function createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate) { var fieldGroup = { id: 'field-injections-properties', label: translate('Field Injections'), entries: [] }; fieldInjections(fieldGroup, element, bpmnFactory, translate); return [ fieldGroup ]; } function createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate) { var propertiesGroup = { id : 'extensionElements-properties', label: translate('Properties'), entries: [] }; properties(propertiesGroup, element, bpmnFactory, translate); return [ propertiesGroup ]; } // activiti Properties Provider ///////////////////////////////////// /** * A properties provider for activiti related properties. * * @param {EventBus} eventBus * @param {Canvas} canvas * @param {BpmnFactory} bpmnFactory * @param {ElementRegistry} elementRegistry * @param {ElementTemplates} elementTemplates * @param {Translate} translate */ function ActivitiPropertiesProvider( eventBus, canvas, bpmnFactory, elementRegistry, elementTemplates, translate) { PropertiesActivator.call(this, eventBus); this.getTabs = function(element) { var generalTab = { id: 'general', label: translate('General'), groups: createGeneralTabGroups( element, canvas, bpmnFactory, elementRegistry, elementTemplates, translate) }; var variablesTab = { id: 'variables', label: translate('Variables'), groups: createVariablesTabGroups(element, bpmnFactory, elementRegistry, translate) }; var formsTab = { id: 'forms', label: translate('Forms'), groups: createFormsTabGroups(element, bpmnFactory, elementRegistry, translate) }; var listenersTab = { id: 'listeners', label: translate('Listeners'), groups: createListenersTabGroups(element, bpmnFactory, elementRegistry, translate), enabled: function(element) { return !eventDefinitionHelper.getLinkEventDefinition(element) || (!is(element, 'bpmn:IntermediateThrowEvent') && eventDefinitionHelper.getLinkEventDefinition(element)); } }; var inputOutputTab = { id: 'input-output', label: translate('Input/Output'), groups: createInputOutputTabGroups(element, bpmnFactory, elementRegistry, translate) }; var connectorTab = { id: 'connector', label: translate('Connector'), groups: createConnectorTabGroups(element, bpmnFactory, elementRegistry, translate), enabled: function(element) { var bo = implementationTypeHelper.getServiceTaskLikeBusinessObject(element); return bo && implementationTypeHelper.getImplementationType(bo) === 'connector'; } }; var fieldInjectionsTab = { id: 'field-injections', label: translate('Field Injections'), groups: createFieldInjectionsTabGroups(element, bpmnFactory, elementRegistry, translate) }; var extensionsTab = { id: 'extensionElements', label: translate('Extensions'), groups: createExtensionElementsGroups(element, bpmnFactory, elementRegistry, translate) }; return [ generalTab, variablesTab, connectorTab, formsTab, listenersTab, inputOutputTab, fieldInjectionsTab, extensionsTab ]; }; } ActivitiPropertiesProvider.$inject = [ 'eventBus', 'canvas', 'bpmnFactory', 'elementRegistry', 'elementTemplates', 'translate' ]; inherits(ActivitiPropertiesProvider, PropertiesActivator); module.exports = ActivitiPropertiesProvider; },{"../../PropertiesActivator":575,"../../helper/AsyncCapableHelper":588,"../../helper/EventDefinitionHelper":592,"../../helper/ImplementationTypeHelper":595,"../../provider/bpmn/parts/DocumentationProps":659,"../../provider/bpmn/parts/EventProps":660,"../../provider/bpmn/parts/ExecutableProps":661,"../../provider/bpmn/parts/IdProps":662,"../../provider/bpmn/parts/LinkProps":663,"../../provider/bpmn/parts/NameProps":664,"../../provider/bpmn/parts/ProcessProps":665,"./element-templates/parts/ChooserProps":608,"./element-templates/parts/CustomProps":609,"./parts/AsynchronousContinuationProps":611,"./parts/CallActivityProps":612,"./parts/CandidateStarterProps":613,"./parts/ConditionalProps":614,"./parts/ConnectorDetailProps":615,"./parts/ConnectorInputOutputParameterProps":616,"./parts/ConnectorInputOutputProps":617,"./parts/ErrorEventProps":618,"./parts/ExternalTaskConfigurationProps":619,"./parts/FieldInjectionProps":620,"./parts/FormProps":621,"./parts/HistoryTimeToLiveProps":622,"./parts/InputOutputParameterProps":623,"./parts/InputOutputProps":624,"./parts/JobConfigurationProps":625,"./parts/ListenerDetailProps":626,"./parts/ListenerFieldInjectionProps":627,"./parts/ListenerProps":628,"./parts/MultiInstanceLoopProps":629,"./parts/PropertiesProps":630,"./parts/ScriptTaskProps":631,"./parts/ServiceTaskDelegateProps":632,"./parts/StartEventInitiator":633,"./parts/TasklistProps":634,"./parts/UserTaskProps":635,"./parts/VariableMappingProps":636,"./parts/VersionTagProps":637,"bpmn-js/lib/util/ModelUtil":141,"inherits":347}],599:[function(require,module,exports){ 'use strict'; var assign = require('lodash/assign'); /** * Create an input parameter representing the given * binding and value. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createInputParameter(binding, value, bpmnFactory) { var scriptFormat = binding.scriptFormat, parameterValue, parameterDefinition; if (scriptFormat) { parameterDefinition = bpmnFactory.create('activiti:Script', { scriptFormat: scriptFormat, value: value }); } else { parameterValue = value; } return bpmnFactory.create('activiti:InputParameter', { name: binding.name, value: parameterValue, definition: parameterDefinition }); } module.exports.createInputParameter = createInputParameter; /** * Create an output parameter representing the given * binding and value. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createOutputParameter(binding, value, bpmnFactory) { var scriptFormat = binding.scriptFormat, parameterValue, parameterDefinition; if (scriptFormat) { parameterDefinition = bpmnFactory.create('activiti:Script', { scriptFormat: scriptFormat, value: binding.source }); } else { parameterValue = binding.source; } return bpmnFactory.create('activiti:OutputParameter', { name: value, value: parameterValue, definition: parameterDefinition }); } module.exports.createOutputParameter = createOutputParameter; /** * Create activiti property from the given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createActivitiProperty(binding, value, bpmnFactory) { return bpmnFactory.create('activiti:Property', { name: binding.name, value: value || '' }); } module.exports.createActivitiProperty = createActivitiProperty; /** * Create activiti:in element from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createActivitiIn(binding, value, bpmnFactory) { var properties = createActivitiInOutAttrs(binding, value); return bpmnFactory.create('activiti:In', properties); } module.exports.createActivitiIn = createActivitiIn; /** * Create activiti:in with businessKey element from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createActivitiInWithBusinessKey(binding, value, bpmnFactory) { return bpmnFactory.create('activiti:In', { businessKey: value }); } module.exports.createActivitiInWithBusinessKey = createActivitiInWithBusinessKey; /** * Create activiti:out element from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createActivitiOut(binding, value, bpmnFactory) { var properties = createActivitiInOutAttrs(binding, value); return bpmnFactory.create('activiti:Out', properties); } module.exports.createActivitiOut = createActivitiOut; /** * Create activiti:executionListener element containing an inline script from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createActivitiExecutionListenerScript(binding, value, bpmnFactory) { var scriptFormat = binding.scriptFormat, parameterValue, parameterDefinition; if (scriptFormat) { parameterDefinition = bpmnFactory.create('activiti:Script', { scriptFormat: scriptFormat, value: value }); } else { parameterValue = value; } return bpmnFactory.create('activiti:ExecutionListener', { event: binding.event, value: parameterValue, script: parameterDefinition }); } module.exports.createActivitiExecutionListenerScript = createActivitiExecutionListenerScript; /** * Create activiti:field element containing string or expression from given binding. * * @param {PropertyBinding} binding * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement} */ function createActivitiFieldInjection(binding, value, bpmnFactory) { var DEFAULT_PROPS = { 'string': undefined, 'expression': undefined, 'name': undefined }; var props = assign({}, DEFAULT_PROPS); if (!binding.expression) { props.string = value; } else { props.expression = value; } props.name = binding.name; return bpmnFactory.create('activiti:Field', props); } module.exports.createActivitiFieldInjection = createActivitiFieldInjection; // helpers //////////////////////////// /** * Create properties for activiti:in and activiti:out types. */ function createActivitiInOutAttrs(binding, value) { var properties = {}; // activiti:in source(Expression) target if (binding.target) { properties.target = binding.target; if (binding.expression) { properties.sourceExpression = value; } else { properties.source = value; } } else // activiti:(in|out) variables local if (binding.variables) { properties.variables = 'all'; if (binding.variables === 'local') { properties.local = true; } } // activiti:out source(Expression) target else { properties.target = value; [ 'source', 'sourceExpression' ].forEach(function(k) { if (binding[k]) { properties[k] = binding[k]; } }); } return properties; } },{"lodash/assign":513}],600:[function(require,module,exports){ 'use strict'; var inherits = require('inherits'); var getTemplate = require('./Helper').getTemplate; var PropertiesActivator = require('../../../PropertiesActivator'); var HIGHER_PRIORITY = 1100; /** * Applies template visibility settings. * * Controlled using `entriesVisible` on template config object: * * ```json * "entriesVisible": { * "_all": true|false, * "entryName": true|false, * ... * } * ``` * * @param {EventBus} eventBus * @param {ElementTemplates} elementTemplates */ function CustomElementsPropertiesActivator(eventBus, elementTemplates) { PropertiesActivator.call(this, eventBus, HIGHER_PRIORITY); this.isEntryVisible = function(entry, element) { var template = getTemplate(element, elementTemplates); if (template && !isEntryVisible(entry, template)) { return false; } }; this.isPropertyEditable = function(entry, propertyName, element) { var template = getTemplate(element, elementTemplates); if (template && !isEntryEditable(entry, template)) { return false; } }; } CustomElementsPropertiesActivator.$inject = [ 'eventBus', 'elementTemplates' ]; inherits(CustomElementsPropertiesActivator, PropertiesActivator); module.exports = CustomElementsPropertiesActivator; // helpers //////////////////////////////////// var CUSTOM_PROPERTIES_PATTERN = /^custom-/; var DEFAULT_ENTRIES_VISIBLE = { _all: false, id: true, name: true }; function isCustomEntry(entry) { return CUSTOM_PROPERTIES_PATTERN.test(entry.id); } function isEntryVisible(entry, template) { var entryId = entry.id; if (entryId === 'elementTemplate-chooser' || isCustomEntry(entry)) { return true; } var entriesVisible = template.entriesVisible || DEFAULT_ENTRIES_VISIBLE; if (typeof entriesVisible === 'boolean') { return entriesVisible; } var defaultVisible = entriesVisible._all || false, entryVisible = entriesVisible[entryId]; // d = true, e = false => false // d = false, e = true => true // d = false, e = false return ( (defaultVisible === true && entryVisible !== false) || (defaultVisible === false && entryVisible === true) ); } function isEntryEditable(entry, template) { var property; if (isCustomEntry(entry)) { property = getProperty(template, entry); return property && property.editable !== false; } return true; } function getProperty(template, entry) { var index; var idx = entry.id.replace('custom-' + template.id + '-', ''); if (idx.indexOf('-') !== -1) { var indexes = idx.split('-'); if (indexes.length == 2) { var scopeName = indexes[0].replace(/_/g, ':'); index = parseInt(indexes[1], 10); if (scopeName && !isNaN(index)) { return template.scopes[scopeName].properties[index]; } } } else { index = parseInt(idx, 10); if (!isNaN(index)) { return template.properties[index]; } } throw new Error('cannot extract property index for entry <' + entry.id + '>'); } },{"../../../PropertiesActivator":575,"./Helper":603,"inherits":347}],601:[function(require,module,exports){ 'use strict'; var values = require('lodash/values'); /** * The guy knowing all configured element templates. * * This registry won't validate. Use the {@link Validator} * to verify a template is valid prior to adding it to * this registry. */ function ElementTemplates() { this._templates = {}; /** * Sets the known element templates. * * @param {Array<TemplateDescriptor>} descriptors * * @return {ElementTemplates} */ this.set = function(descriptors) { var templates = this._templates = {}; descriptors.forEach(function(descriptor) { templates[descriptor.id] = descriptor; }); return this; }; /** * Get template descriptor with given id. * * @param {String} id * * @return {TemplateDescriptor} */ this.get = function(id) { return this._templates[id]; }; /** * Return all known template descriptors. * * @return {Array<TemplateDescriptor>} */ this.getAll = function() { return values(this._templates); }; } module.exports = ElementTemplates; },{"lodash/values":552}],602:[function(require,module,exports){ 'use strict'; var Validator = require('./Validator'); /** * The guy responsible for template loading. * * Provide the actual templates via the `config.elementTemplates`. * * That configuration can either be an array of template * descriptors or a node style callback to retrieve * the templates asynchronously. * * @param {Array<TemplateDescriptor>|Function} loadTemplates * @param {EventBus} eventBus * @param {ElementTemplates} elementTemplates */ function ElementTemplatesLoader(loadTemplates, eventBus, elementTemplates) { this._loadTemplates = loadTemplates; this._eventBus = eventBus; this._elementTemplates = elementTemplates; var self = this; eventBus.on('diagram.init', function() { self.reload(); }); } module.exports = ElementTemplatesLoader; ElementTemplatesLoader.$inject = [ 'config.elementTemplates', 'eventBus', 'elementTemplates' ]; ElementTemplatesLoader.prototype.reload = function() { var self = this; var loadTemplates = this._loadTemplates; // no templates specified if (typeof loadTemplates === 'undefined') { return; } // template loader function specified if (typeof loadTemplates === 'function') { return loadTemplates(function(err, templates) { if (err) { return self.templateErrors([ err ]); } self.setTemplates(templates); }); } // templates array specified if (loadTemplates.length) { return this.setTemplates(loadTemplates); } }; ElementTemplatesLoader.prototype.setTemplates = function(templates) { var elementTemplates = this._elementTemplates; var validator = new Validator().addAll(templates); var errors = validator.getErrors(), validTemplates = validator.getValidTemplates(); elementTemplates.set(validTemplates); if (errors.length) { this.templateErrors(errors); } this.templatesChanged(); }; ElementTemplatesLoader.prototype.templatesChanged = function() { this._eventBus.fire('elementTemplates.changed'); }; ElementTemplatesLoader.prototype.templateErrors = function(errors) { this._eventBus.fire('elementTemplates.errors', { errors: errors }); }; },{"./Validator":604}],603:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var is = require('bpmn-js/lib/util/ModelUtil').is, isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny; var find = require('lodash/find'); var TEMPLATE_ATTR = 'activiti:modelerTemplate'; /** * The BPMN 2.0 extension attribute name under * which the element template is stored. * * @type {String} */ module.exports.TEMPLATE_ATTR = TEMPLATE_ATTR; /** * Get template id for a given diagram element. * * @param {djs.model.Base} element * * @return {String} */ function getTemplateId(element) { var bo = getBusinessObject(element); if (bo) { return bo.get(TEMPLATE_ATTR); } } module.exports.getTemplateId = getTemplateId; /** * Get template of a given element. * * @param {Element} element * @param {ElementTemplates} elementTemplates * * @return {TemplateDefinition} */ function getTemplate(element, elementTemplates) { var id = getTemplateId(element); return id && elementTemplates.get(id); } module.exports.getTemplate = getTemplate; /** * Get default template for a given element. * * @param {Element} element * @param {ElementTemplates} elementTemplates * * @return {TemplateDefinition} */ function getDefaultTemplate(element, elementTemplates) { // return first default template, if any exists return ( elementTemplates.getAll().filter(function(t) { return isAny(element, t.appliesTo) && t.isDefault; }) )[0]; } module.exports.getDefaultTemplate = getDefaultTemplate; /** * Find extension with given type in * BPMN element, diagram element or ExtensionElement. * * @param {ModdleElement|djs.model.Base} element * @param {String} type * * @return {ModdleElement} the extension */ function findExtension(element, type) { var bo = getBusinessObject(element); var extensionElements; if (is(bo, 'bpmn:ExtensionElements')) { extensionElements = bo; } else { extensionElements = bo.extensionElements; } if (!extensionElements) { return null; } return find(extensionElements.get('values'), function(e) { return is(e, type); }); } module.exports.findExtension = findExtension; function findExtensions(element, types) { var extensionElements = getExtensionElements(element); if (!extensionElements) { return []; } return extensionElements.get('values').filter(function(e) { return isAny(e, types); }); } module.exports.findExtensions = findExtensions; function findActivitiInOut(element, binding) { var extensionElements = getExtensionElements(element); if (!extensionElements) { return; } var matcher; if (binding.type === 'activiti:in') { matcher = function(e) { return is(e, 'activiti:In') && isInOut(e, binding); }; } else if (binding.type === 'activiti:out') { matcher = function(e) { return is(e, 'activiti:Out') && isInOut(e, binding); }; } else if (binding.type === 'activiti:in:businessKey') { matcher = function(e) { return is(e, 'activiti:In') && 'businessKey' in e; }; } return find(extensionElements.get('values'), matcher); } module.exports.findActivitiInOut = findActivitiInOut; function findActivitiProperty(activitiProperties, binding) { return find(activitiProperties.get('values'), function(p) { return p.name === binding.name; }); } module.exports.findActivitiProperty = findActivitiProperty; function findInputParameter(inputOutput, binding) { var parameters = inputOutput.get('inputParameters'); return find(parameters, function(p) { return p.name === binding.name; }); } module.exports.findInputParameter = findInputParameter; function findOutputParameter(inputOutput, binding) { var parameters = inputOutput.get('outputParameters'); return find(parameters, function(p) { var value = p.value; if (!binding.scriptFormat) { return value === binding.source; } var definition = p.definition; if (!definition || binding.scriptFormat !== definition.scriptFormat) { return false; } return definition.value === binding.source; }); } module.exports.findOutputParameter = findOutputParameter; // helpers ///////////////////////////////// function getExtensionElements(element) { var bo = getBusinessObject(element); if (is(bo, 'bpmn:ExtensionElements')) { return bo; } else { return bo.extensionElements; } } function isInOut(element, binding) { if (binding.type === 'activiti:in') { // find based on target attribute if (binding.target) { return element.target === binding.target; } } if (binding.type === 'activiti:out') { // find based on source / sourceExpression if (binding.source) { return element.source === binding.source; } if (binding.sourceExpression) { return element.sourceExpression === binding.sourceExpression; } } // find based variables / local combination if (binding.variables) { return element.variables === 'all' && ( binding.variables !== 'local' || element.local ); } } },{"bpmn-js/lib/features/modeling/util/ModelingUtil":112,"bpmn-js/lib/util/ModelUtil":141,"lodash/find":519}],604:[function(require,module,exports){ 'use strict'; var isArray = require('lodash/isArray'); var isObject = require('lodash/isObject'); var DROPDOWN_TYPE = 'Dropdown'; var VALID_TYPES = [ 'String', 'Text', 'Boolean', 'Hidden', DROPDOWN_TYPE ]; var PROPERTY_TYPE = 'property', ACTIVITI_PROPERTY_TYPE = 'activiti:property', ACTIVITI_INPUT_PARAMETER_TYPE = 'activiti:inputParameter', ACTIVITI_OUTPUT_PARAMETER_TYPE = 'activiti:outputParameter', ACTIVITI_IN_TYPE = 'activiti:in', ACTIVITI_OUT_TYPE = 'activiti:out', ACTIVITI_IN_BUSINESS_KEY_TYPE = 'activiti:in:businessKey', ACTIVITI_EXECUTION_LISTENER = 'activiti:executionListener', ACTIVITI_FIELD = 'activiti:field'; var VALID_BINDING_TYPES = [ PROPERTY_TYPE, ACTIVITI_PROPERTY_TYPE, ACTIVITI_INPUT_PARAMETER_TYPE, ACTIVITI_OUTPUT_PARAMETER_TYPE, ACTIVITI_IN_TYPE, ACTIVITI_OUT_TYPE, ACTIVITI_IN_BUSINESS_KEY_TYPE, ACTIVITI_EXECUTION_LISTENER, ACTIVITI_FIELD ]; /** * A element template validator. */ function Validator() { this._templatesById = {}; this._validTemplates = []; this._errors = []; /** * Adds the templates. * * @param {Array<TemplateDescriptor>} templates * * @return {Validator} self */ this.addAll = function(templates) { if (!isArray(templates)) { this._logError('templates must be []'); } else { templates.forEach(this.add, this); } return this; }; /** * Add the given element template, if it is valid. * * @param {TemplateDescriptor} template * * @return {Validator} self */ this.add = function(template) { var err = this._validateTemplate(template); if (!err) { this._templatesById[template.id] = template; this._validTemplates.push(template); } return this; }; /** * Validate given template and return error (if any). * * @param {TemplateDescriptor} template * * @return {Error} validation error, if any */ this._validateTemplate = function(template) { var err, id = template.id, appliesTo = template.appliesTo, properties = template.properties, scopes = template.scopes; if (!id) { return this._logError('missing template id'); } if (id in this._templatesById) { return this._logError('template id <' + id + '> already used'); } if (!isArray(appliesTo)) { err = this._logError('missing appliesTo=[]', template); } if (!isArray(properties)) { err = this._logError('missing properties=[]', template); } else { if (!this._validateProperties(properties)) { err = new Error('invalid properties'); } } if (scopes) { err = this._validateScopes(template, scopes); } return err; }; this._validateScopes = function(template, scopes) { var err, scope, scopeName; if (!isObject(scopes) || isArray(scopes)) { return this._logError('invalid scopes, should be scopes={}', template); } for (scopeName in scopes) { scope = scopes[scopeName]; if (!isObject(scope) || isArray(scope)) { err = this._logError('invalid scope, should be scope={}', template); } if (!isArray(scope.properties)) { err = this._logError( 'missing properties=[] in scope <' + scopeName + '>', template ); } else { if (!this._validateProperties(scope.properties)) { err = new Error('invalid properties in scope <' + scopeName + '>'); } } } return err; }; /** * Validate properties and return false if any is invalid. * * @param {Array<PropertyDescriptor>} properties * * @return {Boolean} true if all properties are valid */ this._validateProperties = function(properties) { var validProperties = properties.filter(this._validateProperty, this); return properties.length === validProperties.length; }; /** * Validate property and return false, if there was * a validation error. * * @param {PropertyDescriptor} property * * @return {Boolean} true if property is valid */ this._validateProperty = function(property) { var type = property.type, binding = property.binding; var err; var bindingType = binding.type; if (VALID_TYPES.indexOf(type) === -1) { err = this._logError( 'invalid property type <' + type + '>; ' + 'must be any of { ' + VALID_TYPES.join(', ') + ' }' ); } if (type === DROPDOWN_TYPE && bindingType !== ACTIVITI_EXECUTION_LISTENER) { if (!isArray(property.choices)) { err = this._logError( 'must provide choices=[] with ' + DROPDOWN_TYPE + ' type' ); } else if (!property.choices.every(isDropdownChoiceValid)) { err = this._logError( '{ name, value } must be specified for ' + DROPDOWN_TYPE + ' choices' ); } } if (!binding) { return this._logError('property missing binding'); } if (VALID_BINDING_TYPES.indexOf(bindingType) === -1) { err = this._logError( 'invalid property.binding type <' + bindingType + '>; ' + 'must be any of { ' + VALID_BINDING_TYPES.join(', ') + ' }' ); } if (bindingType === PROPERTY_TYPE || bindingType === ACTIVITI_PROPERTY_TYPE || bindingType === ACTIVITI_INPUT_PARAMETER_TYPE || bindingType === ACTIVITI_FIELD) { if (!binding.name) { err = this._logError( 'property.binding <' + bindingType + '> requires name' ); } } if (bindingType === ACTIVITI_OUTPUT_PARAMETER_TYPE) { if (!binding.source) { err = this._logError( 'property.binding <' + bindingType + '> requires source' ); } } if (bindingType === ACTIVITI_IN_TYPE) { if (!binding.variables && !binding.target) { err = this._logError( 'property.binding <' + bindingType + '> requires ' + 'variables or target' ); } } if (bindingType === ACTIVITI_OUT_TYPE) { if (!binding.variables && !binding.source && !binding.sourceExpression) { err = this._logError( 'property.binding <' + bindingType + '> requires ' + 'variables, sourceExpression or source' ); } } if (bindingType === ACTIVITI_EXECUTION_LISTENER) { if (type !== 'Hidden') { err = this._logError( 'invalid property type <' + type + '> for ' + ACTIVITI_EXECUTION_LISTENER + '; ' + 'must be <Hidden>' ); } } return !err; }; this._logError = function(err, template) { if (typeof err === 'string') { if (template) { err = 'template(id: ' + template.id + ') ' + err; } err = new Error(err); } this._errors.push(err); return err; }; this.getErrors = function() { return this._errors; }; this.getValidTemplates = function() { return this._validTemplates; }; } module.exports = Validator; // helpers /////////////////////////////////// function isDropdownChoiceValid(c) { return 'name' in c && 'value' in c; } },{"lodash/isArray":527,"lodash/isObject":534}],605:[function(require,module,exports){ 'use strict'; var findExtension = require('../Helper').findExtension, findExtensions = require('../Helper').findExtensions; var createActivitiProperty = require('../CreateHelper').createActivitiProperty, createInputParameter = require('../CreateHelper').createInputParameter, createOutputParameter = require('../CreateHelper').createOutputParameter, createActivitiIn = require('../CreateHelper').createActivitiIn, createActivitiOut = require('../CreateHelper').createActivitiOut, createActivitiInWithBusinessKey = require('../CreateHelper').createActivitiInWithBusinessKey, createActivitiExecutionListenerScript = require('../CreateHelper').createActivitiExecutionListenerScript, createActivitiFieldInjection = require('../CreateHelper').createActivitiFieldInjection; var forEach = require('lodash/forEach'); var ACTIVITI_SERVICE_TASK_LIKE = [ 'activiti:class', 'activiti:delegateExpression', 'activiti:expression' ]; /** * A handler that changes the modeling template of a BPMN element. */ function ChangeElementTemplateHandler(modeling, commandStack, bpmnFactory) { function getOrCreateExtensionElements(element) { var bo = element.businessObject; var extensionElements = bo.extensionElements; // add extension elements if (!extensionElements) { extensionElements = bpmnFactory.create('bpmn:ExtensionElements', { values: [] }); modeling.updateProperties(element, { extensionElements: extensionElements }); } return extensionElements; } function updateModelerTemplate(element, newTemplate) { modeling.updateProperties(element, { 'activiti:modelerTemplate': newTemplate && newTemplate.id }); } function updateIoMappings(element, newTemplate, context) { var newMappings = createInputOutputMappings(newTemplate, bpmnFactory), oldMappings; if (!newMappings) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { inputOutput: newMappings } }); } else { context = getOrCreateExtensionElements(element); oldMappings = findExtension(element, 'activiti:InputOutput'); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: [ newMappings ], objectsToRemove: oldMappings ? [ oldMappings ] : [] }); } } function updateActivitiField(element, newTemplate, context) { var newMappings = createActivitiFieldInjections(newTemplate, bpmnFactory), oldMappings; if (!newMappings) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { field: newMappings } }); } else { context = getOrCreateExtensionElements(element); oldMappings = findExtensions(element, ['activiti:Field']); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: newMappings, objectsToRemove: oldMappings ? oldMappings : [] }); } } function updateActivitiProperties(element, newTemplate, context) { var newProperties = createActivitiProperties(newTemplate, bpmnFactory), oldProperties; if (!newProperties) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { properties: newProperties } }); } else { context = getOrCreateExtensionElements(element); oldProperties = findExtension(element, 'activiti:Properties'); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: [ newProperties ], objectsToRemove: oldProperties ? [ oldProperties ] : [] }); } } function updateProperties(element, newTemplate, context) { var newProperties = createBpmnPropertyUpdates(newTemplate, bpmnFactory); var newPropertiesCount = Object.keys(newProperties).length; if (!newPropertiesCount) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: newProperties }); } else { modeling.updateProperties(element, newProperties); } } function updateInOut(element, newTemplate, context) { var newInOut = createActivitiInOut(newTemplate, bpmnFactory), oldInOut; if (!newInOut) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { inout: newInOut } }); } else { context = getOrCreateExtensionElements(element); oldInOut = findExtensions(context, [ 'activiti:In', 'activiti:Out' ]); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: newInOut, objectsToRemove: oldInOut }); } } function updateExecutionListener(element, newTemplate, context) { var newExecutionListeners = createActivitiExecutionListeners(newTemplate, bpmnFactory), oldExecutionsListeners; if (!newExecutionListeners.length) { return; } if (context) { commandStack.execute('properties-panel.update-businessobject', { element: element, businessObject: context, properties: { executionListener: newExecutionListeners } }); } else { context = getOrCreateExtensionElements(element); oldExecutionsListeners = findExtensions(context, [ 'activiti:ExecutionListener' ]); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: context, propertyName: 'values', objectsToAdd: newExecutionListeners, objectsToRemove: oldExecutionsListeners }); } } /** * Update / recreate a scoped element. * * @param {djs.model.Base} element the diagram parent element * @param {String} scopeName name of the scope, i.e. activiti:Connector * @param {Object} scopeDefinition */ function updateScopeElements(element, scopeName, scopeDefinition) { var scopeElement = bpmnFactory.create(scopeName); // update activiti:inputOutput updateIoMappings(element, scopeDefinition, scopeElement); // update activiti:field updateActivitiField(element, scopeDefinition, scopeElement); // update activiti:properties updateActivitiProperties(element, scopeDefinition, scopeElement); // update other properties (bpmn:condition, activiti:async, ...) updateProperties(element, scopeDefinition, scopeElement); // update activiti:in and activiti:out updateInOut(element, scopeDefinition, scopeElement); // update activiti:executionListener updateExecutionListener(element, scopeDefinition, scopeElement); var extensionElements = getOrCreateExtensionElements(element); var oldScope = findExtension(extensionElements, scopeName); commandStack.execute('properties-panel.update-businessobject-list', { element: element, currentObject: extensionElements, propertyName: 'values', objectsToAdd: [ scopeElement ], objectsToRemove: oldScope ? [ oldScope ] : [] }); } /** * Compose an element template change action, updating all * necessary underlying properties. * * @param {Object} context * @param {Object} context.element * @param {Object} context.oldTemplate * @param {Object} context.newTemplate */ this.preExecute = function(context) { var element = context.element, newTemplate = context.newTemplate; // update activiti:modelerTemplate attribute updateModelerTemplate(element, newTemplate); if (newTemplate) { // update activiti:inputOutput updateIoMappings(element, newTemplate); // update activiti:field updateActivitiField(element, newTemplate); // update activiti:properties updateActivitiProperties(element, newTemplate); // update other properties (bpmn:condition, activiti:async, ...) updateProperties(element, newTemplate); // update activiti:in and activiti:out updateInOut(element, newTemplate); // update activiti:executionListener updateExecutionListener(element, newTemplate); // loop on scopes properties forEach(newTemplate.scopes, function(scopeDefinition, scopeName) { updateScopeElements(element, scopeName, scopeDefinition); }); } }; } ChangeElementTemplateHandler.$inject = [ 'modeling', 'commandStack', 'bpmnFactory' ]; module.exports = ChangeElementTemplateHandler; // helpers ///////////////////////////// function createBpmnPropertyUpdates(template, bpmnFactory) { var propertyUpdates = {}; template.properties.forEach(function(p) { var binding = p.binding, bindingTarget = binding.name, propertyValue; if (binding.type === 'property') { if (bindingTarget === 'conditionExpression') { propertyValue = bpmnFactory.create('bpmn:FormalExpression', { body: p.value, language: binding.scriptFormat }); } else { propertyValue = p.value; } // assigning activiti:async to true|false // assigning bpmn:conditionExpression to { $type: 'bpmn:FormalExpression', ... } propertyUpdates[bindingTarget] = propertyValue; // make sure we unset other "implementation types" // when applying a activiti:class template onto a preconfigured // activiti:delegateExpression element if (ACTIVITI_SERVICE_TASK_LIKE.indexOf(bindingTarget) !== -1) { ACTIVITI_SERVICE_TASK_LIKE.forEach(function(prop) { if (prop !== bindingTarget) { propertyUpdates[prop] = undefined; } }); } } }); return propertyUpdates; } function createActivitiFieldInjections(template, bpmnFactory) { var injections = []; template.properties.forEach(function(p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'activiti:field') { injections.push(createActivitiFieldInjection( binding, p.value, bpmnFactory )); } }); if (injections.length) { return injections; } } function createActivitiProperties(template, bpmnFactory) { var properties = []; template.properties.forEach(function(p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'activiti:property') { properties.push(createActivitiProperty( binding, p.value, bpmnFactory )); } }); if (properties.length) { return bpmnFactory.create('activiti:Properties', { values: properties }); } } function createInputOutputMappings(template, bpmnFactory) { var inputParameters = [], outputParameters = []; template.properties.forEach(function(p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'activiti:inputParameter') { inputParameters.push(createInputParameter( binding, p.value, bpmnFactory )); } if (bindingType === 'activiti:outputParameter') { outputParameters.push(createOutputParameter( binding, p.value, bpmnFactory )); } }); // do we need to create new ioMappings (?) if (outputParameters.length || inputParameters.length) { return bpmnFactory.create('activiti:InputOutput', { inputParameters: inputParameters, outputParameters: outputParameters }); } } function createActivitiInOut(template, bpmnFactory) { var inOuts = []; template.properties.forEach(function(p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'activiti:in') { inOuts.push(createActivitiIn( binding, p.value, bpmnFactory )); } else if (bindingType === 'activiti:out') { inOuts.push(createActivitiOut( binding, p.value, bpmnFactory )); } else if (bindingType === 'activiti:in:businessKey') { inOuts.push(createActivitiInWithBusinessKey( binding, p.value, bpmnFactory )); } }); return inOuts; } function createActivitiExecutionListeners(template, bpmnFactory) { var executionListener = []; template.properties.forEach(function(p) { var binding = p.binding, bindingType = binding.type; if (bindingType === 'activiti:executionListener') { executionListener.push(createActivitiExecutionListenerScript( binding, p.value, bpmnFactory )); } }); return executionListener; } },{"../CreateHelper":599,"../Helper":603,"lodash/forEach":522}],606:[function(require,module,exports){ 'use strict'; var ChangeElementTemplateHandler = require('./ChangeElementTemplateHandler'); var getTemplate = require('../Helper').getTemplate, getDefaultTemplate = require('../Helper').getDefaultTemplate; function registerHandlers(commandStack, elementTemplates, eventBus, elementRegistry) { commandStack.registerHandler( 'propertiesPanel.activiti.changeTemplate', ChangeElementTemplateHandler ); // apply default element templates on shape creation eventBus.on([ 'commandStack.shape.create.postExecuted' ], function(context) { applyDefaultTemplate(context.context.shape, elementTemplates, commandStack); }); // apply default element templates on connection creation eventBus.on([ 'commandStack.connection.create.postExecuted' ], function(context) { applyDefaultTemplate(context.context.connection, elementTemplates, commandStack); }); } registerHandlers.$inject = [ 'commandStack', 'elementTemplates', 'eventBus', 'elementRegistry' ]; module.exports = { __init__: [ registerHandlers ] }; function applyDefaultTemplate(element, elementTemplates, commandStack) { if (!getTemplate(element, elementTemplates) && getDefaultTemplate(element, elementTemplates)) { var command = 'propertiesPanel.activiti.changeTemplate'; var commandContext = { element: element, newTemplate: getDefaultTemplate(element, elementTemplates) }; commandStack.execute(command, commandContext); } } },{"../Helper":603,"./ChangeElementTemplateHandler":605}],607:[function(require,module,exports){ module.exports = { __depends__: [ require('./cmd/index'), require('diagram-js/lib/i18n/translate').default ], __init__: [ 'customElementsPropertiesActivator', 'elementTemplatesLoader' ], customElementsPropertiesActivator: [ 'type', require('./CustomElementsPropertiesActivator') ], elementTemplates: [ 'type', require('./ElementTemplates') ], elementTemplatesLoader: [ 'type', require('./ElementTemplatesLoader') ] }; },{"./CustomElementsPropertiesActivator":600,"./ElementTemplates":601,"./ElementTemplatesLoader":602,"./cmd/index":606,"diagram-js/lib/i18n/translate":337}],608:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), is = require('bpmn-js/lib/util/ModelUtil').is, getTemplate = require('../Helper').getTemplate, getTemplateId = require('../Helper').getTemplateId; var find = require('lodash/find'); var TEMPLATE_ATTR = require('../Helper').TEMPLATE_ATTR; function isAny(element, types) { return types.reduce(function(result, type) { return result || is(element, type); }, false); } module.exports = function(group, element, elementTemplates, translate) { var options = getTemplateOptions(element, elementTemplates, translate); if (options.length === 1 && !options[0].isDefault) { return; } // select element template (via dropdown) group.entries.push(entryFactory.selectBox({ id: 'elementTemplate-chooser', label: translate('Element Template'), modelProperty: 'activiti:modelerTemplate', selectOptions: options, set: function(element, properties) { return applyTemplate(element, properties[TEMPLATE_ATTR], elementTemplates); }, disabled: function() { var template = getTemplate(element, elementTemplates); return template && isDefaultTemplate(template); } })); }; // helpers ////////////////////////////////////// function applyTemplate(element, newTemplateId, elementTemplates) { // cleanup // clear input output mappings // undo changes to properties defined in template // re-establish // set input output mappings // apply changes to properties as defined in new template var oldTemplate = getTemplate(element, elementTemplates), newTemplate = elementTemplates.get(newTemplateId); if (oldTemplate === newTemplate) { return; } return { cmd: 'propertiesPanel.activiti.changeTemplate', context: { element: element, oldTemplate: oldTemplate, newTemplate: newTemplate } }; } function getTemplateOptions(element, elementTemplates, translate) { var currentTemplateId = getTemplateId(element); var emptyOption = { name: '', value: '' }; var allOptions = elementTemplates.getAll().reduce(function(templates, t) { if (!isAny(element, t.appliesTo)) { return templates; } return templates.concat({ name: translate(t.name), value: t.id, isDefault: t.isDefault }); }, [ emptyOption ]); var defaultOption = find(allOptions, function(option) { return isDefaultTemplate(option); }); var currentOption = find(allOptions, function(option) { return option.value === currentTemplateId; }); if (currentTemplateId && !currentOption) { currentOption = unknownTemplate(currentTemplateId, translate); allOptions.push(currentOption); } if (!defaultOption) { // return all options, including empty // and optionally unknownTemplate option return allOptions; } // special limited handling for // default options var options = []; // current template not set if (!currentTemplateId) { options.push({ name: '', value: '' }); } // current template not default if (currentOption && currentOption !== defaultOption) { options.push(currentOption); } options.push(defaultOption); // [ (empty), (current), defaultOption ] return options; } function unknownTemplate(templateId, translate) { return { name: translate('[unknown template: {templateId}]', { templateId: templateId }), value: templateId }; } function isDefaultTemplate(elementTemplate) { return elementTemplate.isDefault; } },{"../../../../factory/EntryFactory":579,"../Helper":603,"bpmn-js/lib/util/ModelUtil":141,"lodash/find":519}],609:[function(require,module,exports){ 'use strict'; var assign = require('lodash/assign'); var entryFactory = require('../../../../factory/EntryFactory'), getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, getTemplate = require('../Helper').getTemplate, cmdHelper = require('../../../../helper/CmdHelper'), elementHelper = require('../../../../helper/ElementHelper'); var findExtension = require('../Helper').findExtension, findExtensions = require('../Helper').findExtensions, findInputParameter = require('../Helper').findInputParameter, findOutputParameter = require('../Helper').findOutputParameter, findActivitiProperty = require('../Helper').findActivitiProperty, findActivitiInOut = require('../Helper').findActivitiInOut; var createActivitiProperty = require('../CreateHelper').createActivitiProperty, createInputParameter = require('../CreateHelper').createInputParameter, createOutputParameter = require('../CreateHelper').createOutputParameter, createActivitiIn = require('../CreateHelper').createActivitiIn, createActivitiOut = require('../CreateHelper').createActivitiOut, createActivitiInWithBusinessKey = require('../CreateHelper').createActivitiInWithBusinessKey, createActivitiFieldInjection = require('../CreateHelper').createActivitiFieldInjection; var ACTIVITI_PROPERTY_TYPE = 'activiti:property', ACTIVITI_INPUT_PARAMETER_TYPE = 'activiti:inputParameter', ACTIVITI_OUTPUT_PARAMETER_TYPE = 'activiti:outputParameter', ACTIVITI_IN_TYPE = 'activiti:in', ACTIVITI_OUT_TYPE = 'activiti:out', ACTIVITI_IN_BUSINESS_KEY_TYPE = 'activiti:in:businessKey', ACTIVITI_EXECUTION_LISTENER_TYPE = 'activiti:executionListener', ACTIVITI_FIELD = 'activiti:field'; var BASIC_MODDLE_TYPES = [ 'Boolean', 'Integer', 'String' ]; var EXTENSION_BINDING_TYPES = [ ACTIVITI_PROPERTY_TYPE, ACTIVITI_INPUT_PARAMETER_TYPE, ACTIVITI_OUTPUT_PARAMETER_TYPE, ACTIVITI_IN_TYPE, ACTIVITI_OUT_TYPE, ACTIVITI_IN_BUSINESS_KEY_TYPE, ACTIVITI_FIELD ]; var IO_BINDING_TYPES = [ ACTIVITI_INPUT_PARAMETER_TYPE, ACTIVITI_OUTPUT_PARAMETER_TYPE ]; var IN_OUT_BINDING_TYPES = [ ACTIVITI_IN_TYPE, ACTIVITI_OUT_TYPE, ACTIVITI_IN_BUSINESS_KEY_TYPE ]; /** * Injects custom properties into the given group. * * @param {djs.model.Base} element * @param {ElementTemplates} elementTemplates * @param {BpmnFactory} bpmnFactory * @param {Function} translate */ module.exports = function(element, elementTemplates, bpmnFactory, translate) { var template = getTemplate(element, elementTemplates); if (!template) { return []; } var renderCustomField = function(id, p, idx) { var propertyType = p.type; var entryOptions = { id: id, description: p.description, label: p.label ? translate(p.label) : p.label, modelProperty: id, get: propertyGetter(id, p), set: propertySetter(id, p, bpmnFactory), validate: propertyValidator(id, p, translate) }; var entry; if (propertyType === 'Boolean') { entry = entryFactory.checkbox(entryOptions); } if (propertyType === 'String') { entry = entryFactory.textField(entryOptions); } if (propertyType === 'Text') { entry = entryFactory.textBox(entryOptions); } if (propertyType === 'Dropdown') { entryOptions.selectOptions = p.choices; entry = entryFactory.selectBox(entryOptions); } return entry; }; var groups = []; var id, entry; var customFieldsGroup = { id: 'customField', label: translate('Custom Fields'), entries: [] }; template.properties.forEach(function(p, idx) { id = 'custom-' + template.id + '-' + idx; entry = renderCustomField(id, p, idx); if (entry) { customFieldsGroup.entries.push(entry); } }); if (customFieldsGroup.entries.length > 0) { groups.push(customFieldsGroup); } if (template.scopes) { for (var scopeName in template.scopes) { var scope = template.scopes[scopeName]; var idScopeName = scopeName.replace(/:/g, '_'); var customScopeFieldsGroup = { id: 'customField-' + idScopeName, label: translate('Custom Fields for scope: ') + scopeName, entries: [] }; scope.properties.forEach(function(p, idx) { var propertyId = 'custom-' + template.id + '-' + idScopeName + '-' + idx; var scopedProperty = propertyWithScope(p, scopeName); entry = renderCustomField(propertyId, scopedProperty, idx); if (entry) { customScopeFieldsGroup.entries.push(entry); } }); if (customScopeFieldsGroup.entries.length > 0) { groups.push(customScopeFieldsGroup); } } } return groups; }; // getters, setters and validators /////////////// /** * Return a getter that retrieves the given property. * * @param {String} name * @param {PropertyDescriptor} property * * @return {Function} */ function propertyGetter(name, property) { /* getter */ return function get(element) { var value = getPropertyValue(element, property); return objectWithKey(name, value); }; } /** * Return a setter that updates the given property. * * @param {String} name * @param {PropertyDescriptor} property * @param {BpmnFactory} bpmnFactory * * @return {Function} */ function propertySetter(name, property, bpmnFactory) { /* setter */ return function set(element, values) { var value = values[name]; return setPropertyValue(element, property, value, bpmnFactory); }; } /** * Return a validator that ensures the property is ok. * * @param {String} name * @param {PropertyDescriptor} property * @param {Function} translate * * @return {Function} */ function propertyValidator(name, property, translate) { /* validator */ return function validate(element, values) { var value = values[name]; var error = validateValue(value, property, translate); if (error) { return objectWithKey(name, error); } }; } // get, set and validate helpers /////////////////// /** * Return the value of the specified property descriptor, * on the passed diagram element. * * @param {djs.model.Base} element * @param {PropertyDescriptor} property * * @return {Any} */ function getPropertyValue(element, property) { var bo = getBusinessObject(element); var binding = property.binding, scope = property.scope; var bindingType = binding.type, bindingName = binding.name; var propertyValue = property.value || ''; if (scope) { bo = findExtension(bo, scope.name); if (!bo) { return propertyValue; } } // property if (bindingType === 'property') { var value = bo.get(bindingName); if (bindingName === 'conditionExpression') { if (value) { return value.body; } else { // return defined default return propertyValue; } } else { // return value; default to defined default return typeof value !== 'undefined' ? value : propertyValue; } } var activitiProperties, activitiProperty; if (bindingType === ACTIVITI_PROPERTY_TYPE) { if (scope) { activitiProperties = bo.get('properties'); } else { activitiProperties = findExtension(bo, 'activiti:Properties'); } if (activitiProperties) { activitiProperty = findActivitiProperty(activitiProperties, binding); if (activitiProperty) { return activitiProperty.value; } } return propertyValue; } var inputOutput, ioParameter; if (IO_BINDING_TYPES.indexOf(bindingType) !== -1) { if (scope) { inputOutput = bo.get('inputOutput'); } else { inputOutput = findExtension(bo, 'activiti:InputOutput'); } if (!inputOutput) { // ioParameter cannot exist yet, return property value return propertyValue; } } // activiti input parameter if (bindingType === ACTIVITI_INPUT_PARAMETER_TYPE) { ioParameter = findInputParameter(inputOutput, binding); if (ioParameter) { if (binding.scriptFormat) { if (ioParameter.definition) { return ioParameter.definition.value; } } else { return ioParameter.value || ''; } } return propertyValue; } // activiti output parameter if (binding.type === ACTIVITI_OUTPUT_PARAMETER_TYPE) { ioParameter = findOutputParameter(inputOutput, binding); if (ioParameter) { return ioParameter.name; } return propertyValue; } var ioElement; if (IN_OUT_BINDING_TYPES.indexOf(bindingType) != -1) { ioElement = findActivitiInOut(bo, binding); if (ioElement) { if (bindingType === ACTIVITI_IN_BUSINESS_KEY_TYPE) { return ioElement.businessKey; } else if (bindingType === ACTIVITI_OUT_TYPE) { return ioElement.target; } else if (bindingType === ACTIVITI_IN_TYPE) { return ioElement[binding.expression ? 'sourceExpression' : 'source']; } } return propertyValue; } if (bindingType === ACTIVITI_EXECUTION_LISTENER_TYPE) { var executionListener; if (scope) { executionListener = bo.get('executionListener'); } else { executionListener = findExtension(bo, 'activiti:ExecutionListener'); } return executionListener.script.value; } var fieldInjection; if (ACTIVITI_FIELD === bindingType) { var fieldInjections = findExtensions(bo, [ 'activiti:Field' ]); fieldInjections.forEach(function(item) { if (item.name === binding.name) { fieldInjection = item; } }); if (fieldInjection) { return fieldInjection.string || fieldInjection.expression; } else { return ''; } } throw unknownPropertyBinding(property); } module.exports.getPropertyValue = getPropertyValue; /** * Return an update operation that changes the diagram * element's custom property to the given value. * * The response of this method will be processed via * {@link PropertiesPanel#applyChanges}. * * @param {djs.model.Base} element * @param {PropertyDescriptor} property * @param {String} value * @param {BpmnFactory} bpmnFactory * * @return {Object|Array<Object>} results to be processed */ function setPropertyValue(element, property, value, bpmnFactory) { var bo = getBusinessObject(element); var binding = property.binding, scope = property.scope; var bindingType = binding.type, bindingName = binding.name; var propertyValue; var updates = []; var extensionElements; if (EXTENSION_BINDING_TYPES.indexOf(bindingType) !== -1) { extensionElements = bo.get('extensionElements'); // create extension elements, if they do not exist (yet) if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', null, element, bpmnFactory); updates.push(cmdHelper.updateBusinessObject( element, bo, objectWithKey('extensionElements', extensionElements) )); } } if (scope) { bo = findExtension(bo, scope.name); if (!bo) { bo = elementHelper.createElement(scope.name, null, element, bpmnFactory); updates.push(cmdHelper.addElementsTolist( bo, extensionElements, 'values', [ bo ] )); } } // property if (bindingType === 'property') { if (bindingName === 'conditionExpression') { propertyValue = elementHelper.createElement('bpmn:FormalExpression', { body: value, language: binding.scriptFormat }, bo, bpmnFactory); } else { var moddlePropertyDescriptor = bo.$descriptor.propertiesByName[bindingName]; var moddleType = moddlePropertyDescriptor.type; // make sure we only update String, Integer, Real and // Boolean properties (do not accidentally override complex objects...) if (BASIC_MODDLE_TYPES.indexOf(moddleType) === -1) { throw new Error('cannot set moddle type <' + moddleType + '>'); } if (moddleType === 'Boolean') { propertyValue = !!value; } else if (moddleType === 'Integer') { propertyValue = parseInt(value, 10); if (isNaN(propertyValue)) { // do not write NaN value propertyValue = undefined; } } else { propertyValue = value; } } if (propertyValue !== undefined) { updates.push(cmdHelper.updateBusinessObject( element, bo, objectWithKey(bindingName, propertyValue) )); } } // activiti:property var activitiProperties, existingActivitiProperty, newActivitiProperty; if (bindingType === ACTIVITI_PROPERTY_TYPE) { if (scope) { activitiProperties = bo.get('properties'); } else { activitiProperties = findExtension(extensionElements, 'activiti:Properties'); } if (!activitiProperties) { activitiProperties = elementHelper.createElement('activiti:Properties', null, bo, bpmnFactory); if (scope) { updates.push(cmdHelper.updateBusinessObject( element, bo, { properties: activitiProperties } )); } else { updates.push(cmdHelper.addElementsTolist( element, extensionElements, 'values', [ activitiProperties ] )); } } existingActivitiProperty = findActivitiProperty(activitiProperties, binding); newActivitiProperty = createActivitiProperty(binding, value, bpmnFactory); updates.push(cmdHelper.addAndRemoveElementsFromList( element, activitiProperties, 'values', null, [ newActivitiProperty ], existingActivitiProperty ? [ existingActivitiProperty ] : [] )); } // activiti:inputParameter // activiti:outputParameter var inputOutput, existingIoParameter, newIoParameter; if (IO_BINDING_TYPES.indexOf(bindingType) !== -1) { if (scope) { inputOutput = bo.get('inputOutput'); } else { inputOutput = findExtension(extensionElements, 'activiti:InputOutput'); } // create inputOutput element, if it do not exist (yet) if (!inputOutput) { inputOutput = elementHelper.createElement('activiti:InputOutput', null, bo, bpmnFactory); if (scope) { updates.push(cmdHelper.updateBusinessObject( element, bo, { inputOutput: inputOutput } )); } else { updates.push(cmdHelper.addElementsTolist( element, extensionElements, 'values', inputOutput )); } } } if (bindingType === ACTIVITI_INPUT_PARAMETER_TYPE) { existingIoParameter = findInputParameter(inputOutput, binding); newIoParameter = createInputParameter(binding, value, bpmnFactory); updates.push(cmdHelper.addAndRemoveElementsFromList( element, inputOutput, 'inputParameters', null, [ newIoParameter ], existingIoParameter ? [ existingIoParameter ] : [] )); } if (bindingType === ACTIVITI_OUTPUT_PARAMETER_TYPE) { existingIoParameter = findOutputParameter(inputOutput, binding); newIoParameter = createOutputParameter(binding, value, bpmnFactory); updates.push(cmdHelper.addAndRemoveElementsFromList( element, inputOutput, 'outputParameters', null, [ newIoParameter ], existingIoParameter ? [ existingIoParameter ] : [] )); } // activiti:in // activiti:out // activiti:in:businessKey var existingInOut, newInOut; if (IN_OUT_BINDING_TYPES.indexOf(bindingType) !== -1) { existingInOut = findActivitiInOut(bo, binding); if (bindingType === ACTIVITI_IN_TYPE) { newInOut = createActivitiIn(binding, value, bpmnFactory); } else if (bindingType === ACTIVITI_OUT_TYPE) { newInOut = createActivitiOut(binding, value, bpmnFactory); } else { newInOut = createActivitiInWithBusinessKey(binding, value, bpmnFactory); } updates.push(cmdHelper.addAndRemoveElementsFromList( element, extensionElements, 'values', null, [ newInOut ], existingInOut ? [ existingInOut ] : [] )); } if (bindingType === ACTIVITI_FIELD) { var existingFieldInjections = findExtensions(bo, [ 'activiti:Field' ]); var newFieldInjections = []; if (existingFieldInjections.length > 0) { existingFieldInjections.forEach(function(item) { if (item.name === binding.name) { newFieldInjections.push(createActivitiFieldInjection(binding, value, bpmnFactory)); } else { newFieldInjections.push(item); } }); } else { newFieldInjections.push(createActivitiFieldInjection(binding, value, bpmnFactory)); } updates.push(cmdHelper.addAndRemoveElementsFromList( element, extensionElements, 'values', null, newFieldInjections, existingFieldInjections ? existingFieldInjections : [] )); } if (updates.length) { return updates; } // quick warning for better debugging console.warn('no update', element, property, value); } module.exports.setPropertyValue = setPropertyValue; /** * Validate value of a given property. * * @param {String} value * @param {PropertyDescriptor} property * @param {Function} translate * * @return {Object} with validation errors */ function validateValue(value, property, translate) { var constraints = property.constraints || {}; if (constraints.notEmpty && isEmpty(value)) { return translate('Must not be empty'); } if (constraints.maxLength && value.length > constraints.maxLength) { return translate('Must have max length {length}', { length: constraints.maxLength }); } if (constraints.minLength && value.length < constraints.minLength) { return translate('Must have min length {length}', { length: constraints.minLength }); } var pattern = constraints.pattern, message; if (pattern) { if (typeof pattern !== 'string') { message = pattern.message; pattern = pattern.value; } if (!matchesPattern(value, pattern)) { return message || translate('Must match pattern {pattern}', { pattern: pattern }); } } } // misc helpers /////////////////////////////// function propertyWithScope(property, scopeName) { if (!scopeName) { return property; } return assign({}, property, { scope: { name: scopeName } }); } /** * Return an object with a single key -> value association. * * @param {String} key * @param {Any} value * * @return {Object} */ function objectWithKey(key, value) { var obj = {}; obj[key] = value; return obj; } /** * Does the given string match the specified pattern? * * @param {String} str * @param {String} pattern * * @return {Boolean} */ function matchesPattern(str, pattern) { var regexp = new RegExp(pattern); return regexp.test(str); } function isEmpty(str) { return !str || /^\s*$/.test(str); } /** * Create a new {@link Error} indicating an unknown * property binding. * * @param {PropertyDescriptor} property * * @return {Error} */ function unknownPropertyBinding(property) { var binding = property.binding; return new Error('unknown binding: <' + binding.type + '>'); } },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../CreateHelper":599,"../Helper":603,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513}],610:[function(require,module,exports){ module.exports = { __depends__: [ require('./element-templates/index'), require('diagram-js/lib/i18n/translate').default ], __init__: [ 'propertiesProvider' ], propertiesProvider: [ 'type', require('./ActivitiPropertiesProvider') ] }; },{"./ActivitiPropertiesProvider":598,"./element-templates/index":607,"diagram-js/lib/i18n/translate":337}],611:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is, asyncContinuation = require('./implementation/AsyncContinuation'); module.exports = function(group, element, bpmnFactory, translate) { if (is(element, 'activiti:AsyncCapable')) { group.entries = group.entries.concat(asyncContinuation(element, bpmnFactory, { getBusinessObject: getBusinessObject }, translate)); } }; },{"./implementation/AsyncContinuation":638,"bpmn-js/lib/util/ModelUtil":141}],612:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is; var entryFactory = require('../../../factory/EntryFactory'); var callable = require('./implementation/Callable'); var cmdHelper = require('../../../helper/CmdHelper'); var flattenDeep = require('lodash/flattenDeep'); var assign = require('lodash/assign'); function getCallableType(element) { var bo = getBusinessObject(element); var boCalledElement = bo.get('calledElement'), boCaseRef = bo.get('activiti:caseRef'); var callActivityType = ''; if (typeof boCalledElement !== 'undefined') { callActivityType = 'bpmn'; } else if (typeof boCaseRef !== 'undefined') { callActivityType = 'cmmn'; } return callActivityType; } var DEFAULT_PROPS = { calledElement: undefined, 'activiti:calledElementBinding': 'latest', 'activiti:calledElementVersion': undefined, 'activiti:calledElementTenantId': undefined, 'activiti:variableMappingClass' : undefined, 'activiti:variableMappingDelegateExpression' : undefined, 'activiti:caseRef': undefined, 'activiti:caseBinding': 'latest', 'activiti:caseVersion': undefined, 'activiti:caseTenantId': undefined }; module.exports = function(group, element, bpmnFactory, translate) { if (!is(element, 'activiti:CallActivity')) { return; } group.entries.push(entryFactory.selectBox({ id : 'callActivity', label: translate('CallActivity Type'), selectOptions: [ { name: 'BPMN', value: 'bpmn' }, { name: 'CMMN', value: 'cmmn' } ], emptyParameter: true, modelProperty: 'callActivityType', get: function(element, node) { return { callActivityType: getCallableType(element) }; }, set: function(element, values, node) { var type = values.callActivityType; var props = assign({}, DEFAULT_PROPS); if (type === 'bpmn') { props.calledElement = ''; } else if (type === 'cmmn') { props['activiti:caseRef'] = ''; } return cmdHelper.updateProperties(element, props); } })); group.entries.push(callable(element, bpmnFactory, { getCallableType: getCallableType }, translate)); group.entries = flattenDeep(group.entries); }; },{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"./implementation/Callable":639,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513,"lodash/flattenDeep":521}],613:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var candidateStarter = require('./implementation/CandidateStarter'); module.exports = function(group, element, bpmnFactory, translate) { var businessObject = getBusinessObject(element); if (is(element, 'activiti:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { group.entries = group.entries.concat(candidateStarter(element, bpmnFactory, { getBusinessObject: function(element) { var bo = getBusinessObject(element); if (!is(bo, 'bpmn:Participant')) { return bo; } return bo.get('processRef'); } }, translate)); } }; },{"./implementation/CandidateStarter":640,"bpmn-js/lib/util/ModelUtil":141}],614:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, escapeHTML = require('../../../Utils').escapeHTML, domQuery = require('min-dom').query, cmdHelper = require('../../../helper/CmdHelper'), elementHelper = require('../../../helper/ElementHelper'), eventDefinitionHelper = require('../../../helper/EventDefinitionHelper'), scriptImplementation = require('./implementation/Script'); module.exports = function(group, element, bpmnFactory, translate) { var bo = getBusinessObject(element); if (!bo) { return; } var conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(element); if (!(is(element, 'bpmn:SequenceFlow') && isConditionalSource(element.source)) && !conditionalEventDefinition) { return; } var script = scriptImplementation('language', 'body', true, translate); group.entries.push({ id: 'condition', label: translate('Condition'), html: '<div class="bpp-row">' + '<label for="cam-condition-type">'+ escapeHTML(translate('Condition Type')) + '</label>' + '<div class="bpp-field-wrapper">' + '<select id="cam-condition-type" name="conditionType" data-value>' + '<option value="expression">'+ escapeHTML(translate('Expression')) + '</option>' + '<option value="script">'+ escapeHTML(translate('Script')) + '</option>' + '<option value="" selected></option>' + '</select>' + '</div>' + '</div>' + // expression '<div class="bpp-row">' + '<label for="cam-condition" data-show="isExpression">' + escapeHTML(translate('Expression')) + '</label>' + '<div class="bpp-field-wrapper" data-show="isExpression">' + '<input id="cam-condition" type="text" name="condition" />' + '<button class="clear" data-action="clear" data-show="canClear">' + '<span>X</span>' + '</button>' + '</div>' + '<div data-show="isScript">' + script.template + '</div>' + '</div>', get: function(element, propertyName) { var conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(element); var conditionExpression = conditionalEventDefinition ? conditionalEventDefinition.condition : bo.conditionExpression; var values = {}, conditionType = ''; if (conditionExpression) { var conditionLanguage = conditionExpression.language; if (typeof conditionLanguage !== 'undefined') { conditionType = 'script'; values = script.get(element, conditionExpression); } else { conditionType = 'expression'; values.condition = conditionExpression.get('body'); } } values.conditionType = conditionType; return values; }, set: function(element, values, containerElement) { var conditionType = values.conditionType; var commands = []; var conditionProps = { body: undefined }; if (conditionType === 'script') { conditionProps = script.set(element, values, containerElement); } else { var condition = values.condition; conditionProps.body = condition; } var conditionOrConditionExpression; if (conditionType) { conditionOrConditionExpression = elementHelper.createElement( 'bpmn:FormalExpression', conditionProps, conditionalEventDefinition || bo, bpmnFactory ); var source = element.source; // if default-flow, remove default-property from source if (source && source.businessObject.default === bo) { commands.push(cmdHelper.updateProperties(source, { 'default': undefined })); } } var update = conditionalEventDefinition ? { condition: conditionOrConditionExpression } : { conditionExpression: conditionOrConditionExpression }; commands.push(cmdHelper.updateBusinessObject(element, conditionalEventDefinition || bo, update)); return commands; }, validate: function(element, values) { var validationResult = {}; if (!values.condition && values.conditionType === 'expression') { validationResult.condition = translate('Must provide a value'); } else if (values.conditionType === 'script') { validationResult = script.validate(element, values); } return validationResult; }, isExpression: function(element, inputNode) { var conditionType = domQuery('select[name=conditionType]', inputNode); if (conditionType.selectedIndex >= 0) { return conditionType.options[conditionType.selectedIndex].value === 'expression'; } }, isScript: function(element, inputNode) { var conditionType = domQuery('select[name=conditionType]', inputNode); if (conditionType.selectedIndex >= 0) { return conditionType.options[conditionType.selectedIndex].value === 'script'; } }, clear: function(element, inputNode) { // clear text input domQuery('input[name=condition]', inputNode).value=''; return true; }, canClear: function(element, inputNode) { var input = domQuery('input[name=condition]', inputNode); return input.value !== ''; }, script : script, cssClasses: [ 'bpp-textfield' ] }); }; // utilities ////////////////////////// var CONDITIONAL_SOURCES = [ 'bpmn:Activity', 'bpmn:ExclusiveGateway', 'bpmn:InclusiveGateway', 'bpmn:ComplexGateway' ]; function isConditionalSource(element) { return isAny(element, CONDITIONAL_SOURCES); } },{"../../../Utils":576,"../../../helper/CmdHelper":590,"../../../helper/ElementHelper":591,"../../../helper/EventDefinitionHelper":592,"./implementation/Script":657,"bpmn-js/lib/features/modeling/util/ModelingUtil":112,"bpmn-js/lib/util/ModelUtil":141,"min-dom":556}],615:[function(require,module,exports){ 'use strict'; var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'), InputOutputHelper = require('../../../helper/InputOutputHelper'); var entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'); function getImplementationType(element) { return ImplementationTypeHelper.getImplementationType(element); } function getBusinessObject(element) { return ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element); } function getConnector(bo) { return InputOutputHelper.getConnector(bo); } function isConnector(element) { return getImplementationType(element) === 'connector'; } module.exports = function(group, element, bpmnFactory, translate) { group.entries.push(entryFactory.textField({ id: 'connectorId', label: translate('Connector Id'), modelProperty: 'connectorId', get: function(element, node) { var bo = getBusinessObject(element); var connector = bo && getConnector(bo); var value = connector && connector.get('connectorId'); return { connectorId: value }; }, set: function(element, values, node) { var bo = getBusinessObject(element); var connector = getConnector(bo); return cmdHelper.updateBusinessObject(element, connector, { connectorId: values.connectorId || undefined }); }, validate: function(element, values, node) { return isConnector(element) && !values.connectorId ? { connectorId: translate('Must provide a value') } : {}; }, hidden: function(element, node) { return !isConnector(element); } })); }; },{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"../../../helper/ImplementationTypeHelper":595,"../../../helper/InputOutputHelper":596}],616:[function(require,module,exports){ 'use strict'; var assign = require('lodash/assign'); var inputOutputParameter = require('./implementation/InputOutputParameter'); module.exports = function(group, element, bpmnFactory, options, translate) { options = assign({ idPrefix: 'connector-', insideConnector: true }, options); group.entries = group.entries.concat(inputOutputParameter(element, bpmnFactory, options, translate)); }; },{"./implementation/InputOutputParameter":650,"lodash/assign":513}],617:[function(require,module,exports){ 'use strict'; var inputOutput = require('./implementation/InputOutput'); module.exports = function(group, element, bpmnFactory, translate) { var inputOutputEntry = inputOutput(element, bpmnFactory, { idPrefix: 'connector-', insideConnector: true }, translate); group.entries = group.entries.concat(inputOutputEntry.entries); return { getSelectedParameter: inputOutputEntry.getSelectedParameter }; }; },{"./implementation/InputOutput":649}],618:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, eventDefinitionHelper = require('../../../helper/EventDefinitionHelper'), error = require('./implementation/ErrorEventDefinition'); var forEach = require('lodash/forEach'); module.exports = function(group, element, bpmnFactory, translate) { var errorEvents = [ 'bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:EndEvent' ]; forEach(errorEvents, function(event) { if (is(element, event)) { var errorEventDefinition = eventDefinitionHelper.getErrorEventDefinition(element); if (errorEventDefinition) { var isCatchingErrorEvent = is(element, 'bpmn:StartEvent') || is (element, 'bpmn:BoundaryEvent'); var showErrorCodeVariable = isCatchingErrorEvent, showErrorMessageVariable = isCatchingErrorEvent; error( group, element, bpmnFactory, errorEventDefinition, showErrorCodeVariable, showErrorMessageVariable, translate); } } }); }; },{"../../../helper/EventDefinitionHelper":592,"./implementation/ErrorEventDefinition":642,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],619:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'); var externalTaskPriority = require('./implementation/ExternalTaskPriority'); function getServiceTaskLikeBusinessObject(element) { var bo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element); // if the element is not a serviceTaskLike element, fetch the normal business object // This avoids the loss of the process / participant business object if (!bo) { bo = getBusinessObject(element); } return bo; } module.exports = function(group, element, bpmnFactory, translate) { var bo = getServiceTaskLikeBusinessObject(element); if (!bo) { return; } if (is(bo, 'activiti:TaskPriorized') || (is(bo, 'bpmn:Participant')) && bo.get('processRef')) { group.entries = group.entries.concat(externalTaskPriority(element, bpmnFactory, { getBusinessObject: function(element) { if (!is(bo, 'bpmn:Participant')) { return bo; } return bo.get('processRef'); } }, translate)); } }; },{"../../../helper/ImplementationTypeHelper":595,"./implementation/ExternalTaskPriority":645,"bpmn-js/lib/util/ModelUtil":141}],620:[function(require,module,exports){ 'use strict'; var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'); var fieldInjection = require('./implementation/FieldInjection'); module.exports = function(group, element, bpmnFactory, translate) { var bo = ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element); if (!bo) { return; } var fieldInjectionEntry = fieldInjection(element, bpmnFactory, translate, { businessObject: bo }); if (fieldInjectionEntry && fieldInjectionEntry.length > 0) { group.entries = group.entries.concat(fieldInjectionEntry); } }; },{"../../../helper/ImplementationTypeHelper":595,"./implementation/FieldInjection":646}],621:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, getExtensionElements = require('../../../helper/ExtensionElementsHelper').getExtensionElements, removeEntry = require('../../../helper/ExtensionElementsHelper').removeEntry, extensionElements = require('./implementation/ExtensionElements'), properties = require('./implementation/Properties'), entryFactory = require('../../../factory/EntryFactory'), elementHelper = require('../../../helper/ElementHelper'), cmdHelper = require('../../../helper/CmdHelper'), formHelper = require('../../../helper/FormHelper'), utils = require('../../../Utils'), is = require('bpmn-js/lib/util/ModelUtil').is, find = require('lodash/find'), each = require('lodash/forEach'); function generateValueId() { return utils.nextId('Value_'); } /** * Generate a form field specific textField using entryFactory. * * @param {string} options.id * @param {string} options.label * @param {string} options.modelProperty * @param {function} options.validate * * @return {Object} an entryFactory.textField object */ function formFieldTextField(options, getSelectedFormField) { var id = options.id, label = options.label, modelProperty = options.modelProperty, validate = options.validate; return entryFactory.textField({ id: id, label: label, modelProperty: modelProperty, get: function(element, node) { var selectedFormField = getSelectedFormField(element, node) || {}, values = {}; values[modelProperty] = selectedFormField[modelProperty]; return values; }, set: function(element, values, node) { var commands = []; if (typeof options.set === 'function') { var cmd = options.set(element, values, node); if (cmd) { commands.push(cmd); } } var formField = getSelectedFormField(element, node), properties = {}; properties[modelProperty] = values[modelProperty] || undefined; commands.push(cmdHelper.updateBusinessObject(element, formField, properties)); return commands; }, hidden: function(element, node) { return !getSelectedFormField(element, node); }, validate: validate }); } function ensureFormKeyAndDataSupported(element) { return ( is(element, 'bpmn:StartEvent') && !is(element.parent, 'bpmn:SubProcess') ) || is(element, 'bpmn:UserTask'); } module.exports = function(group, element, bpmnFactory, translate) { if (!ensureFormKeyAndDataSupported(element)) { return; } /** * Return the currently selected form field querying the form field select box * from the DOM. * * @param {djs.model.Base} element * @param {DOMElement} node - DOM element of any form field text input * * @return {ModdleElement} the currently selected form field */ function getSelectedFormField(element, node) { var selected = formFieldsEntry.getSelected(element, node.parentNode); if (selected.idx === -1) { return; } return formHelper.getFormField(element, selected.idx); } // [FormKey] form key text input field group.entries.push(entryFactory.textField({ id : 'form-key', label : translate('Form Key'), modelProperty: 'formKey', get: function(element, node) { var bo = getBusinessObject(element); return { formKey: bo.get('activiti:formKey') }; }, set: function(element, values, node) { var bo = getBusinessObject(element), formKey = values.formKey || undefined; return cmdHelper.updateBusinessObject(element, bo, { 'activiti:formKey': formKey }); } })); // [FormData] form field select box var formFieldsEntry = extensionElements(element, bpmnFactory, { id: 'form-fields', label: translate('Form Fields'), modelProperty: 'id', prefix: 'FormProperty', createExtensionElement: function(element, extensionElements, value) { var bo = getBusinessObject(element), commands = []; if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); commands.push(cmdHelper.updateProperties(element, { extensionElements: extensionElements })); } /* var formData = formHelper.getFormData(element); if (!formData) { formData = elementHelper.createElement('activiti:FormData', { fields: [] }, extensionElements, bpmnFactory); commands.push(cmdHelper.addAndRemoveElementsFromList( element, extensionElements, 'values', 'extensionElements', [formData], [] )); }*/ /**activiti 是向 extensionElements 下追加元素,而不是 formData 下,*/ var field = elementHelper.createElement('activiti:FormProperty', { id: value }, extensionElements, bpmnFactory); if (typeof extensionElements.values !== 'undefined') { commands.push(cmdHelper.addElementsTolist(element, extensionElements, 'values', [ field ])); } else { commands.push(cmdHelper.updateBusinessObject(element, extensionElements, { values: [ field ] })); } return commands; }, removeExtensionElement: function(element, extensionElements, value, idx) { var fields = formHelper.getFormFields(element); var entry = fields[idx], commands = []; if (fields.length < 2) { commands.push(removeEntry(getBusinessObject(element), element, extensionElements)); } else { commands.push(cmdHelper.removeElementsFromList(element, extensionElements, 'values', null, [entry])); /* if (entry.id === formData.get('businessKey')) { commands.push(cmdHelper.updateBusinessObject(element, extensionElements, { 'businessKey': undefined })); }*/ } return commands; }, getExtensionElements: function(element) { return formHelper.getFormFields(element); }, hideExtensionElements: function(element, node) { return false; } }); group.entries.push(formFieldsEntry); // [FormData] Form Field label group.entries.push(entryFactory.label({ id: 'form-field-header', labelText: translate('Form Field'), showLabel: function(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] form field id text input field group.entries.push(entryFactory.validationAwareTextField({ id: 'form-field-id', label: translate('ID'), modelProperty: 'id', getProperty: function(element, node) { var selectedFormField = getSelectedFormField(element, node) || {}; return selectedFormField.id; }, setProperty: function(element, properties, node) { var formField = getSelectedFormField(element, node); return cmdHelper.updateBusinessObject(element, formField, properties); }, hidden: function(element, node) { return !getSelectedFormField(element, node); }, validate: function(element, values, node) { var formField = getSelectedFormField(element, node); if (formField) { var idValue = values.id; if (!idValue || idValue.trim() === '') { return { id: 'Form field id must not be empty' }; } var formFields = formHelper.getFormFields(element); var existingFormField = find(formFields, function(f) { return f !== formField && f.id === idValue; }); if (existingFormField) { return { id: 'Form field id already used in form data.' }; } } } })); // [FormData] form field type combo box group.entries.push(entryFactory.comboBox({ id: 'form-field-type', label: translate('Type'), selectOptions: [ { name: 'string', value: 'string' }, { name: 'long', value: 'long' }, { name: 'boolean', value: 'boolean' }, { name: 'date', value: 'date' }, { name: 'enum', value: 'enum' } ], modelProperty: 'type', emptyParameter: true, get: function(element, node) { var selectedFormField = getSelectedFormField(element, node); if (selectedFormField) { return { type: selectedFormField.type }; } else { return {}; } }, set: function(element, values, node) { var selectedFormField = getSelectedFormField(element, node), commands = []; if (selectedFormField.type === 'enum' && values.type !== 'enum') { // delete activiti:value objects from formField.values when switching from type enum commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, { values: undefined })); } commands.push(cmdHelper.updateBusinessObject(element, selectedFormField, values)); return commands; }, hidden: function(element, node) { return !getSelectedFormField(element, node); } })); // [FormData] form field label text input field group.entries.push(formFieldTextField({ id: 'form-field-label', label: translate('Label'), modelProperty: 'label' }, getSelectedFormField)); // [FormData] form field defaultValue text input field group.entries.push(formFieldTextField({ id: 'form-field-defaultValue', label: translate('Default Value'), modelProperty: 'defaultValue' }, getSelectedFormField)); // [FormData] form field enum values label group.entries.push(entryFactory.label({ id: 'form-field-enum-values-header', labelText: translate('Values'), divider: true, showLabel: function(element, node) { var selectedFormField = getSelectedFormField(element, node); return selectedFormField && selectedFormField.type === 'enum'; } })); // [FormData] form field enum values table group.entries.push(entryFactory.table({ id: 'form-field-enum-values', labels: [ translate('Id'), translate('Name') ], modelProperties: [ 'id', 'name' ], addLabel:translate('Add Value'), show: function(element, node) { var selectedFormField = getSelectedFormField(element, node); return selectedFormField && selectedFormField.type === 'enum'; }, getElements: function(element, node) { var selectedFormField = getSelectedFormField(element, node); return formHelper.getEnumValues(selectedFormField); }, addElement: function(element, node) { var selectedFormField = getSelectedFormField(element, node), id = generateValueId(); var enumValue = elementHelper.createElement( 'activiti:Value', { id: id, name: undefined }, getBusinessObject(element), bpmnFactory ); return cmdHelper.addElementsTolist(element, selectedFormField, 'values', [enumValue]); }, removeElement: function(element, node, idx) { var selectedFormField = getSelectedFormField(element, node), enumValue = selectedFormField.values[idx]; return cmdHelper.removeElementsFromList(element, selectedFormField, 'values', null, [enumValue]); }, updateElement: function(element, value, node, idx) { var selectedFormField = getSelectedFormField(element, node), enumValue = selectedFormField.values[idx]; value.name = value.name || undefined; return cmdHelper.updateBusinessObject(element, enumValue, value); }, validate: function(element, value, node, idx) { var selectedFormField = getSelectedFormField(element, node), enumValue = selectedFormField.values[idx]; if (enumValue) { // check if id is valid var validationError = utils.isIdValid(enumValue, value.id, translate); if (validationError) { return { id: validationError }; } } } })); // [FormData] Validation label group.entries.push(entryFactory.label({ id: 'form-field-validation-header', labelText: translate('Validation'), divider: true, showLabel: function(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] form field constraints table group.entries.push(entryFactory.table({ id: 'constraints-list', modelProperties: [ 'name', 'config' ], labels: [ translate('Name'), translate('Config') ], addLabel: translate('Add Constraint'), getElements: function(element, node) { var formField = getSelectedFormField(element, node); return formHelper.getConstraints(formField); }, addElement: function(element, node) { var commands = [], formField = getSelectedFormField(element, node), validation = formField.validation; if (!validation) { // create validation business object and add it to form data, if it doesn't exist validation = elementHelper.createElement('activiti:Validation', {}, getBusinessObject(element), bpmnFactory); commands.push(cmdHelper.updateBusinessObject(element, formField, { 'validation': validation })); } var newConstraint = elementHelper.createElement( 'activiti:Constraint', { name: undefined, config: undefined }, validation, bpmnFactory ); commands.push(cmdHelper.addElementsTolist(element, validation, 'constraints', [ newConstraint ])); return commands; }, updateElement: function(element, value, node, idx) { var formField = getSelectedFormField(element, node), constraint = formHelper.getConstraints(formField)[idx]; value.name = value.name || undefined; value.config = value.config || undefined; return cmdHelper.updateBusinessObject(element, constraint, value); }, removeElement: function(element, node, idx) { var commands = [], formField = getSelectedFormField(element, node), constraints = formHelper.getConstraints(formField), currentConstraint = constraints[idx]; commands.push(cmdHelper.removeElementsFromList( element, formField.validation, 'constraints', null, [ currentConstraint ] )); if (constraints.length === 1) { // remove activiti:validation if the last existing constraint has been removed commands.push(cmdHelper.updateBusinessObject(element, formField, { validation: undefined })); } return commands; }, show: function(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] Properties label group.entries.push(entryFactory.label({ id: 'form-field-properties-header', labelText: translate('Properties'), divider: true, showLabel: function(element, node) { return !!getSelectedFormField(element, node); } })); // [FormData] activiti:properties table group.entries.push(properties(element, bpmnFactory, { id: 'form-field-properties', modelProperties: [ 'id', 'value' ], labels: [ translate('Id'), translate('Value') ], getParent: function(element, node) { return getSelectedFormField(element, node); }, show: function(element, node) { return !!getSelectedFormField(element, node); } }, translate)); }; },{"../../../Utils":576,"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"../../../helper/ElementHelper":591,"../../../helper/ExtensionElementsHelper":593,"../../../helper/FormHelper":594,"./implementation/ExtensionElements":643,"./implementation/Properties":655,"bpmn-js/lib/util/ModelUtil":141,"lodash/find":519,"lodash/forEach":522}],622:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var historyTimeToLive = require('./implementation/HistoryTimeToLive'); module.exports = function(group, element, bpmnFactory, translate) { var businessObject = getBusinessObject(element); if (is(element, 'activiti:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { group.entries = group.entries.concat(historyTimeToLive(element, bpmnFactory, { getBusinessObject: function(element) { var bo = getBusinessObject(element); if (!is(bo, 'bpmn:Participant')) { return bo; } return bo.get('processRef'); } }, translate)); } }; },{"./implementation/HistoryTimeToLive":647,"bpmn-js/lib/util/ModelUtil":141}],623:[function(require,module,exports){ 'use strict'; var inputOutputParameter = require('./implementation/InputOutputParameter'); var assign = require('lodash/assign'); module.exports = function(group, element, bpmnFactory, options, translate) { group.entries = group.entries.concat(inputOutputParameter(element, bpmnFactory, assign({}, options), translate)); }; },{"./implementation/InputOutputParameter":650,"lodash/assign":513}],624:[function(require,module,exports){ 'use strict'; var inputOutput = require('./implementation/InputOutput'); module.exports = function(group, element, bpmnFactory, translate) { var inputOutputEntry = inputOutput(element, bpmnFactory, {}, translate); group.entries = group.entries.concat(inputOutputEntry.entries); return { getSelectedParameter: inputOutputEntry.getSelectedParameter }; }; },{"./implementation/InputOutput":649}],625:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var jobPriority = require('./implementation/JobPriority'), jobRetryTimeCycle = require('./implementation/JobRetryTimeCycle'); module.exports = function(group, element, bpmnFactory, translate) { var businessObject = getBusinessObject(element); if (is(element, 'activiti:JobPriorized') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { group.entries = group.entries.concat(jobPriority(element, bpmnFactory, { getBusinessObject: function(element) { var bo = getBusinessObject(element); if (!is(bo, 'bpmn:Participant')) { return bo; } return bo.get('processRef'); } }, translate)); } if (is(element, 'activiti:AsyncCapable')) { group.entries = group.entries.concat(jobRetryTimeCycle(element, bpmnFactory, { getBusinessObject: getBusinessObject }, translate)); } }; },{"./implementation/JobPriority":651,"./implementation/JobRetryTimeCycle":652,"bpmn-js/lib/util/ModelUtil":141}],626:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'); var cmdHelper = require('../../../helper/CmdHelper'), ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'), scriptImplementation = require('./implementation/Script'); module.exports = function(group, element, bpmnFactory, options, translate) { var LISTENER_TYPE_LABEL = { class: translate('Java Class'), expression: translate('Expression'), delegateExpression: translate('Delegate Expression'), script: translate('Script') }; options = options || {}; var getSelectedListener = options.getSelectedListener; var classProp = 'class', expressionProp = 'expression', delegateExpressionProp = 'delegateExpression', scriptProp = 'script'; var executionListenerEventTypeOptions = ImplementationTypeHelper.isSequenceFlow(element) ? [ { name: translate('take'), value: 'take' } ] : [ { name: translate('start'), value: 'start' }, { name: translate('end'), value: 'end' } ]; var taskListenerEventTypeOptions = [ { name: translate('create'), value: 'create' }, { name: translate('assignment'), value: 'assignment' }, { name: translate('complete'), value: 'complete' }, { name: translate('delete'), value: 'delete' } ]; var isSelected = function(element, node) { return getSelectedListener(element, node); }; group.entries.push(entryFactory.selectBox({ id: 'listener-event-type', label: translate('Event Type'), modelProperty: 'eventType', emptyParameter: false, get: function(element, node) { var listener = getSelectedListener(element, node); var eventType = listener && listener.get('event'); return { eventType: eventType }; }, set: function(element, values, node) { var eventType = values.eventType; return cmdHelper.updateBusinessObject(element, getSelectedListener(element, node), { event: eventType }); }, selectOptions: function(element, node) { var eventTypeOptions; var selectedListener = getSelectedListener(element, node); if (ImplementationTypeHelper.isTaskListener(selectedListener)) { eventTypeOptions = taskListenerEventTypeOptions; } else if (ImplementationTypeHelper.isExecutionListener(selectedListener)) { eventTypeOptions = executionListenerEventTypeOptions; } return eventTypeOptions; }, hidden: function(element, node) { return !isSelected(element, node); } })); group.entries.push(entryFactory.selectBox({ id: 'listener-type', label: translate('Listener Type'), selectOptions: [ { value: classProp, name: translate('Java Class') }, { value: expressionProp, name: translate('Expression') }, { value: delegateExpressionProp, name: translate('Delegate Expression') }, { value: scriptProp, name: translate('Script') } ], modelProperty: 'listenerType', emptyParameter: false, get: function(element, node) { var listener = getSelectedListener(element, node); return { listenerType: ImplementationTypeHelper.getImplementationType(listener) }; }, set: function(element, values, node) { var listener = getSelectedListener(element, node), listenerType = values.listenerType || undefined, update = {}; update[classProp] = listenerType === classProp ? '' : undefined; update[expressionProp] = listenerType === expressionProp ? '' : undefined; update[delegateExpressionProp] = listenerType === delegateExpressionProp ? '' : undefined; update[scriptProp] = listenerType === scriptProp ? bpmnFactory.create('activiti:Script') : undefined; return cmdHelper.updateBusinessObject(element, listener, update); }, hidden: function(element, node) { return !isSelected(element, node); } })); group.entries.push(entryFactory.textField({ id: 'listener-value', dataValueLabel: 'listenerValueLabel', modelProperty: 'listenerValue', get: function(element, node) { var value = {}, listener = getSelectedListener(element, node), listenerType = ImplementationTypeHelper.getImplementationType(listener); value.listenerValueLabel = LISTENER_TYPE_LABEL[listenerType] || ''; value.listenerValue = (listener && listener.get(listenerType)) || undefined; return value; }, set: function(element, values, node) { var update = {}, listener = getSelectedListener(element, node), listenerType = ImplementationTypeHelper.getImplementationType(listener); update[listenerType] = values.listenerValue || ''; return cmdHelper.updateBusinessObject(element, listener, update); }, hidden: function(element, node) { var listener = getSelectedListener(element, node); return !listener || listener.script; }, validate: function(element, values) { var value = values.listenerValue, validate = {}; if (!value) { validate.listenerValue = translate('Must provide a value'); } return validate; } })); var script = scriptImplementation('scriptFormat', 'value', true, translate); group.entries.push({ id: 'listener-script-value', html: '<div data-show="isScript">' + script.template + '</div>', get: function(element, node) { var listener = getSelectedListener(element, node); return listener && listener.script ? script.get(element, listener.script) : {}; }, set: function(element, values, node) { var listener = getSelectedListener(element, node); var update = script.set(element, values, listener); return cmdHelper.updateBusinessObject(element, listener.script, update); }, validate: function(element, values, node) { var listener = getSelectedListener(element, node); return listener && listener.script ? script.validate(element, values) : {}; }, isScript: function(element, node) { var listener = getSelectedListener(element, node); return listener && listener.script; }, script: script }); }; },{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"../../../helper/ImplementationTypeHelper":595,"./implementation/Script":657}],627:[function(require,module,exports){ 'use strict'; var assign = require('lodash/assign'); var fieldInjection = require('./implementation/FieldInjection'); module.exports = function(group, element, bpmnFactory, options, translate) { options = assign({ idPrefix: 'listener-', insideListener: true }, options); var fieldInjectionEntry = fieldInjection(element, bpmnFactory, translate, options); if (fieldInjectionEntry && fieldInjectionEntry.length > 0) { group.entries = group.entries.concat(fieldInjectionEntry); } }; },{"./implementation/FieldInjection":646,"lodash/assign":513}],628:[function(require,module,exports){ 'use strict'; var listener = require('./implementation/Listener'); module.exports = function(group, element, bpmnFactory, translate) { var listenerEntry = listener(element, bpmnFactory, {}, translate); group.entries = group.entries.concat(listenerEntry.entries); return { getSelectedListener: listenerEntry.getSelectedListener }; }; },{"./implementation/Listener":653}],629:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is; var multiInstanceLoopCharacteristics = require('./implementation/MultiInstanceLoopCharacteristics'); var jobRetryTimeCycle = require('./implementation/JobRetryTimeCycle'), asyncContinuation = require('./implementation/AsyncContinuation'); function getLoopCharacteristics(element) { var bo = getBusinessObject(element); return bo.loopCharacteristics; } function ensureMultiInstanceSupported(element) { var loopCharacteristics = getLoopCharacteristics(element); return !!loopCharacteristics && is(loopCharacteristics, 'activiti:Collectable'); } module.exports = function(group, element, bpmnFactory, translate) { if (!ensureMultiInstanceSupported(element)) { return; } // multi instance properties group.entries = group.entries.concat(multiInstanceLoopCharacteristics(element, bpmnFactory, translate)); // async continuation /////////////////////////////////////////////////////// group.entries = group.entries.concat(asyncContinuation(element, bpmnFactory, { getBusinessObject: getLoopCharacteristics, idPrefix: 'multiInstance-', labelPrefix: translate('Multi Instance ') }, translate)); // retry time cycle ////////////////////////////////////////////////////////// group.entries = group.entries.concat(jobRetryTimeCycle(element, bpmnFactory, { getBusinessObject: getLoopCharacteristics, idPrefix: 'multiInstance-', labelPrefix: translate('Multi Instance ') }, translate)); }; },{"./implementation/AsyncContinuation":638,"./implementation/JobRetryTimeCycle":652,"./implementation/MultiInstanceLoopCharacteristics":654,"bpmn-js/lib/util/ModelUtil":141}],630:[function(require,module,exports){ 'use strict'; var properties = require('./implementation/Properties'), elementHelper = require('../../../helper/ElementHelper'), cmdHelper = require('../../../helper/CmdHelper'); module.exports = function(group, element, bpmnFactory, translate) { var propertiesEntry = properties(element, bpmnFactory, { id: 'properties', modelProperties: [ 'name', 'value' ], labels: [ translate('Name'), translate('Value') ], getParent: function(element, node, bo) { return bo.extensionElements; }, createParent: function(element, bo) { var parent = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); var cmd = cmdHelper.updateBusinessObject(element, bo, { extensionElements: parent }); return { cmd: cmd, parent: parent }; } }, translate); if (propertiesEntry) { group.entries.push(propertiesEntry); } }; },{"../../../helper/CmdHelper":590,"../../../helper/ElementHelper":591,"./implementation/Properties":655}],631:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is, entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'), scriptImplementation = require('./implementation/Script'); module.exports = function(group, element, bpmnFactory, translate) { var bo; if (is(element, 'bpmn:ScriptTask')) { bo = getBusinessObject(element); } if (!bo) { return; } var script = scriptImplementation('scriptFormat', 'script', false, translate); group.entries.push({ id: 'script-implementation', label: translate('Script'), html: script.template, get: function(element) { return script.get(element, bo); }, set: function(element, values, containerElement) { var properties = script.set(element, values, containerElement); return cmdHelper.updateProperties(element, properties); }, validate: function(element, values) { return script.validate(element, values); }, script : script, cssClasses: ['bpp-textfield'] }); group.entries.push(entryFactory.textField({ id : 'scriptResultVariable', label : translate('Result Variable'), modelProperty : 'scriptResultVariable', get: function(element, propertyName) { var boResultVariable = bo.get('activiti:resultVariable'); return { scriptResultVariable : boResultVariable }; }, set: function(element, values, containerElement) { return cmdHelper.updateProperties(element, { 'activiti:resultVariable': values.scriptResultVariable.length ? values.scriptResultVariable : undefined }); } })); }; },{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"./implementation/Script":657,"bpmn-js/lib/util/ModelUtil":141}],632:[function(require,module,exports){ 'use strict'; var ImplementationTypeHelper = require('../../../helper/ImplementationTypeHelper'), InputOutputHelper = require('../../../helper/InputOutputHelper'); var utils = require('../../../Utils'), escapeHTML = utils.escapeHTML, triggerClickEvent = utils.triggerClickEvent; var implementationType = require('./implementation/ImplementationType'), delegate = require('./implementation/Delegate'), external = require('./implementation/External'), callable = require('./implementation/Callable'), resultVariable = require('./implementation/ResultVariable'); var entryFactory = require('../../../factory/EntryFactory'); var domQuery = require('min-dom').query, domClosest = require('min-dom').closest, domClasses = require('min-dom').classes; function getImplementationType(element) { return ImplementationTypeHelper.getImplementationType(element); } function getBusinessObject(element) { return ImplementationTypeHelper.getServiceTaskLikeBusinessObject(element); } function isDmnCapable(element) { return ImplementationTypeHelper.isDmnCapable(element); } function isExternalCapable(element) { return ImplementationTypeHelper.isExternalCapable(element); } function isServiceTaskLike(element) { return ImplementationTypeHelper.isServiceTaskLike(element); } module.exports = function(group, element, bpmnFactory, translate) { if (!isServiceTaskLike(getBusinessObject(element))) { return; } var hasDmnSupport = isDmnCapable(element); var hasExternalSupport = isExternalCapable(getBusinessObject(element)); // implementation type //////////////////////////////////// group.entries = group.entries.concat(implementationType(element, bpmnFactory, { getBusinessObject: getBusinessObject, getImplementationType: getImplementationType, hasDmnSupport: hasDmnSupport, hasExternalSupport: hasExternalSupport, hasServiceTaskLikeSupport: true }, translate)); // delegate (class, expression, delegateExpression) ////////// group.entries = group.entries.concat(delegate(element, bpmnFactory, { getBusinessObject: getBusinessObject, getImplementationType: getImplementationType }, translate)); // result variable ///////////////////////////////////////// group.entries = group.entries.concat(resultVariable(element, bpmnFactory, { getBusinessObject: getBusinessObject, getImplementationType: getImplementationType, hideResultVariable: function(element, node) { return getImplementationType(element) !== 'expression'; } }, translate)); // external ////////////////////////////////////////////////// if (hasExternalSupport) { group.entries = group.entries.concat(external(element, bpmnFactory, { getBusinessObject: getBusinessObject, getImplementationType: getImplementationType }, translate)); } // dmn //////////////////////////////////////////////////////// if (hasDmnSupport) { group.entries = group.entries.concat(callable(element, bpmnFactory, { getCallableType: getImplementationType }, translate)); } // connector //////////////////////////////////////////////// var isConnector = function(element) { return getImplementationType(element) === 'connector'; }; group.entries.push(entryFactory.link({ id: 'configureConnectorLink', label: translate('Configure Connector'), handleClick: function(element, node, event) { var connectorTabEl = getTabNode(node, 'connector'); if (connectorTabEl) { triggerClickEvent(connectorTabEl); } // suppress actual link click return false; }, showLink: function(element, node) { var link = domQuery('a', node); link.textContent = ''; domClasses(link).remove('bpp-error-message'); if (isConnector(element)) { var connectorId = InputOutputHelper.getConnector(element).get('connectorId'); if (connectorId) { link.textContent = translate('Configure Connector'); } else { link.innerHTML = '<span class="bpp-icon-warning"></span> ' + escapeHTML(translate('Must configure Connector')); domClasses(link).add('bpp-error-message'); } return true; } return false; } })); }; // helpers /////////////////////////// function getTabNode(el, id) { var containerEl = domClosest(el, '.bpp-properties-panel'); return domQuery('a[data-tab-target="' + id + '"]', containerEl); } },{"../../../Utils":576,"../../../factory/EntryFactory":579,"../../../helper/ImplementationTypeHelper":595,"../../../helper/InputOutputHelper":596,"./implementation/Callable":639,"./implementation/Delegate":641,"./implementation/External":644,"./implementation/ImplementationType":648,"./implementation/ResultVariable":656,"min-dom":556}],633:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'), is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; module.exports = function(group, element, translate) { var bo = getBusinessObject(element); if (!bo) { return; } if (is(element, 'activiti:Initiator') && !is(element.parent, 'bpmn:SubProcess')) { group.entries.push(entryFactory.textField({ id: 'initiator', label: translate('Initiator'), modelProperty: 'initiator' })); } }; },{"../../../factory/EntryFactory":579,"bpmn-js/lib/util/ModelUtil":141}],634:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var tasklist = require('./implementation/Tasklist'); module.exports = function(group, element, bpmnFactory, translate) { var businessObject = getBusinessObject(element); if (is(element, 'activiti:Process') || is(element, 'bpmn:Participant') && businessObject.get('processRef')) { group.entries = group.entries.concat(tasklist(element, bpmnFactory, { getBusinessObject: function(element) { var bo = getBusinessObject(element); if (!is(bo, 'bpmn:Participant')) { return bo; } return bo.get('processRef'); } }, translate)); } }; },{"./implementation/Tasklist":658,"bpmn-js/lib/util/ModelUtil":141}],635:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, entryFactory = require('../../../factory/EntryFactory'); module.exports = function(group, element, translate) { if (is(element, 'activiti:Assignable')) { // Assignee group.entries.push(entryFactory.textField({ id : 'assignee', label : translate('Assignee'), modelProperty : 'assignee' })); // Candidate Users group.entries.push(entryFactory.textField({ id : 'candidateUsers', label : translate('Candidate Users'), modelProperty : 'candidateUsers' })); // Candidate Groups group.entries.push(entryFactory.textField({ id : 'candidateGroups', label : translate('Candidate Groups'), modelProperty : 'candidateGroups' })); // Due Date group.entries.push(entryFactory.textField({ id : 'dueDate', description : translate('The due date as an EL expression (e.g. ${someDate} or an ISO date (e.g. 2015-06-26T09:54:00)'), label : translate('Due Date'), modelProperty : 'dueDate' })); // FollowUp Date group.entries.push(entryFactory.textField({ id : 'followUpDate', description : translate('The follow up date as an EL expression (e.g. ${someDate} or an ' + 'ISO date (e.g. 2015-06-26T09:54:00)'), label : translate('Follow Up Date'), modelProperty : 'followUpDate' })); // priority group.entries.push(entryFactory.textField({ id : 'priority', label : translate('Priority'), modelProperty : 'priority' })); } }; },{"../../../factory/EntryFactory":579,"bpmn-js/lib/util/ModelUtil":141}],636:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var filter = require('lodash/filter'); var extensionElementsHelper = require('../../../helper/ExtensionElementsHelper'), cmdHelper = require('../../../helper/CmdHelper'), elementHelper = require('../../../helper/ElementHelper'), eventDefinitionHelper = require('../../../helper/EventDefinitionHelper'); var extensionElementsEntry = require('./implementation/ExtensionElements'); var entryFactory = require('../../../factory/EntryFactory'); /** * return depend on parameter 'type' activiti:in or activiti:out extension elements */ function getActivitiInOutMappings(element, type) { var bo = getBusinessObject(element); var signalEventDefinition = eventDefinitionHelper.getSignalEventDefinition(bo); return extensionElementsHelper.getExtensionElements(signalEventDefinition || bo, type) || []; } /** * return depend on parameter 'type' activiti:in or activiti:out extension elements * with source or sourceExpression attribute */ function getVariableMappings(element, type) { var activitiMappings = getActivitiInOutMappings(element, type); return filter(activitiMappings, function(mapping) { return !mapping.businessKey; }); } function getInOutType(mapping) { var inOutType = 'source'; if (mapping.variables === 'all') { inOutType = 'variables'; } else if (typeof mapping.source !== 'undefined') { inOutType = 'source'; } else if (typeof mapping.sourceExpression !== 'undefined') { inOutType = 'sourceExpression'; } return inOutType; } var ACTIVITI_IN_EXTENSION_ELEMENT = 'activiti:In', ACTIVITI_OUT_EXTENSION_ELEMENT = 'activiti:Out'; var WHITESPACE_REGEX = /\s/; module.exports = function(group, element, bpmnFactory, translate) { var inOutTypeOptions = [ { name: translate('Source'), value: 'source' }, { name: translate('Source Expression'), value: 'sourceExpression' }, { name: translate('All'), value: 'variables' } ]; var signalEventDefinition = eventDefinitionHelper.getSignalEventDefinition(element); if (!is(element, 'activiti:CallActivity') && !signalEventDefinition) { return; } if (signalEventDefinition && !(isAny(element, [ 'bpmn:IntermediateThrowEvent', 'bpmn:EndEvent' ]))) { return; } var isSelected = function(element, node) { return !!getSelected(element, node); }; var getSelected = function(element, node) { var parentNode = node.parentNode; var selection = inEntry.getSelected(element, parentNode); var parameter = getVariableMappings(element, ACTIVITI_IN_EXTENSION_ELEMENT)[selection.idx]; if (!parameter && outEntry) { selection = outEntry.getSelected(element, parentNode); parameter = getVariableMappings(element, ACTIVITI_OUT_EXTENSION_ELEMENT)[selection.idx]; } return parameter; }; var setOptionLabelValue = function(type) { return function(element, node, option, property, value, idx) { var variableMappings = getVariableMappings(element, type); var mappingValue = variableMappings[idx]; var label = (mappingValue.target || '<undefined>') + ' := '; var mappingType = getInOutType(mappingValue); if (mappingType === 'variables') { label = 'all'; } else if (mappingType === 'source') { label = label + (mappingValue.source || '<empty>'); } else if (mappingType === 'sourceExpression') { label = label + (mappingValue.sourceExpression || '<empty>'); } else { label = label + '<empty>'; } option.text = label; }; }; var newElement = function(type) { return function(element, extensionElements, value) { var newElem = elementHelper.createElement(type, { source: '' }, extensionElements, bpmnFactory); return cmdHelper.addElementsTolist(element, extensionElements, 'values', [ newElem ]); }; }; var removeElement = function(type) { return function(element, extensionElements, value, idx) { var variablesMappings= getVariableMappings(element, type); var mapping = variablesMappings[idx]; if (mapping) { return extensionElementsHelper .removeEntry(signalEventDefinition || getBusinessObject(element), element, mapping); } }; }; // in mapping for source and sourceExpression /////////////////////////////////////////////////////////////// var inEntry = extensionElementsEntry(element, bpmnFactory, { id: 'variableMapping-in', label: translate('In Mapping'), modelProperty: 'source', prefix: 'In', idGeneration: false, resizable: true, businessObject: signalEventDefinition || getBusinessObject(element), createExtensionElement: newElement(ACTIVITI_IN_EXTENSION_ELEMENT), removeExtensionElement: removeElement(ACTIVITI_IN_EXTENSION_ELEMENT), getExtensionElements: function(element) { return getVariableMappings(element, ACTIVITI_IN_EXTENSION_ELEMENT); }, onSelectionChange: function(element, node, event, scope) { outEntry && outEntry.deselect(element, node.parentNode); }, setOptionLabelValue: setOptionLabelValue(ACTIVITI_IN_EXTENSION_ELEMENT) }); group.entries.push(inEntry); // out mapping for source and sourceExpression /////////////////////////////////////////////////////// if (!signalEventDefinition) { var outEntry = extensionElementsEntry(element, bpmnFactory, { id: 'variableMapping-out', label: translate('Out Mapping'), modelProperty: 'source', prefix: 'Out', idGeneration: false, resizable: true, createExtensionElement: newElement(ACTIVITI_OUT_EXTENSION_ELEMENT), removeExtensionElement: removeElement(ACTIVITI_OUT_EXTENSION_ELEMENT), getExtensionElements: function(element) { return getVariableMappings(element, ACTIVITI_OUT_EXTENSION_ELEMENT); }, onSelectionChange: function(element, node, event, scope) { inEntry.deselect(element, node.parentNode); }, setOptionLabelValue: setOptionLabelValue(ACTIVITI_OUT_EXTENSION_ELEMENT) }); group.entries.push(outEntry); } // label for selected mapping /////////////////////////////////////////////////////// group.entries.push(entryFactory.label({ id: 'variableMapping-typeLabel', get: function(element, node) { var mapping = getSelected(element, node); var value = ''; if (is(mapping, ACTIVITI_IN_EXTENSION_ELEMENT)) { value = translate('In Mapping'); } else if (is(mapping, ACTIVITI_OUT_EXTENSION_ELEMENT)) { value = translate('Out Mapping'); } return { label: value }; }, showLabel: function(element, node) { return isSelected(element, node); } })); group.entries.push(entryFactory.selectBox({ id: 'variableMapping-inOutType', label: translate('Type'), selectOptions: inOutTypeOptions, modelProperty: 'inOutType', get: function(element, node) { var mapping = getSelected(element, node) || {}; return { inOutType: getInOutType(mapping) }; }, set: function(element, values, node) { var inOutType = values.inOutType; var props = { 'source' : undefined, 'sourceExpression' : undefined, 'variables' : undefined }; if (inOutType === 'source') { props.source = ''; } else if (inOutType === 'sourceExpression') { props.sourceExpression = ''; } else if (inOutType === 'variables') { props.variables = 'all'; props.target = undefined; } var mapping = getSelected(element, node); return cmdHelper.updateBusinessObject(element, mapping, props); }, hidden: function(element, node) { return !isSelected(element, node); } })); group.entries.push(entryFactory.textField({ id: 'variableMapping-source', dataValueLabel: 'sourceLabel', modelProperty: 'source', get: function(element, node) { var mapping = getSelected(element, node) || {}; var label = ''; var inOutType = getInOutType(mapping); if (inOutType === 'source') { label = translate('Source'); } else if (inOutType === 'sourceExpression') { label = translate('Source Expression'); } return { source: mapping[inOutType], sourceLabel: label }; }, set: function(element, values, node) { values.source = values.source || undefined; var mapping = getSelected(element, node); var inOutType = getInOutType(mapping); var props = {}; props[inOutType] = values.source || ''; return cmdHelper.updateBusinessObject(element, mapping, props); }, // one of both (source or sourceExpression) must have a value to make // the configuration easier and more understandable // it is not engine conform validate: function(element, values, node) { var mapping = getSelected(element, node); var validation = {}; if (mapping) { if (!values.source) { validation.source = validation.source = values.sourceLabel ? translate('Mapping must have a {value}', { value: values.sourceLabel.toLowerCase() }) : translate('Mapping must have a value'); } var inOutType = getInOutType(mapping); if (WHITESPACE_REGEX.test(values.source) && inOutType !== 'sourceExpression') { validation.source = translate('{label} must not contain whitespace', { label: values.sourceLabel }); } } return validation; }, hidden: function(element, node) { var selectedMapping = getSelected(element, node); return !selectedMapping || (selectedMapping && selectedMapping.variables); } })); group.entries.push(entryFactory.textField({ id: 'variableMapping-target', label: translate('Target'), modelProperty: 'target', get: function(element, node) { return { target: (getSelected(element, node) || {}).target }; }, set: function(element, values, node) { values.target = values.target || undefined; var mapping = getSelected(element, node); return cmdHelper.updateBusinessObject(element, mapping, values); }, validate: function(element, values, node) { var mapping = getSelected(element, node); var validation = {}; if (mapping) { var mappingType = getInOutType(mapping); if (!values.target && mappingType !== 'variables') { validation.target = translate('Mapping must have a target'); } if (values.target && WHITESPACE_REGEX.test(values.target) && mappingType !== 'variables') { validation.target = translate('Target must not contain whitespace'); } } return validation; }, hidden: function(element, node) { var selectedMapping = getSelected(element, node); return !selectedMapping || (selectedMapping && selectedMapping.variables); } })); group.entries.push(entryFactory.checkbox({ id: 'variableMapping-local', label: translate('Local'), modelProperty: 'local', get: function(element, node) { return { local: (getSelected(element, node) || {}).local }; }, set: function(element, values, node) { values.local = values.local || false; var mapping = getSelected(element, node); return cmdHelper.updateBusinessObject(element, mapping, values); }, hidden: function(element, node) { return !isSelected(element, node); } })); }; },{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"../../../helper/ElementHelper":591,"../../../helper/EventDefinitionHelper":592,"../../../helper/ExtensionElementsHelper":593,"./implementation/ExtensionElements":643,"bpmn-js/lib/features/modeling/util/ModelingUtil":112,"bpmn-js/lib/util/ModelUtil":141,"lodash/filter":518}],637:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'), is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; module.exports = function(group, element, translate) { var bo = getBusinessObject(element); if (!bo) { return; } if (is(element, 'bpmn:Process') || is(element, 'bpmn:Participant') && bo.get('processRef')) { var versionTagEntry = entryFactory.textField({ id: 'versionTag', label: translate('Version Tag'), modelProperty: 'versionTag' }); // in participants we have to change the default behavior of set and get if (is(element, 'bpmn:Participant')) { versionTagEntry.get = function(element) { var processBo = bo.get('processRef'); return { versionTag: processBo.get('activiti:versionTag') }; }; versionTagEntry.set = function(element, values) { var processBo = bo.get('processRef'); return cmdHelper.updateBusinessObject(element, processBo, { 'activiti:versionTag': values.versionTag || undefined }); }; } group.entries.push(versionTagEntry); } }; },{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141}],638:[function(require,module,exports){ 'use strict'; var assign = require('lodash/assign'); var entryFactory = require('../../../../factory/EntryFactory'); var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper'), eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'), cmdHelper = require('../../../../helper/CmdHelper'); function isAsyncBefore(bo) { return asyncCapableHelper.isAsyncBefore(bo); } function isAsyncAfter(bo) { return asyncCapableHelper.isAsyncAfter(bo); } function isExclusive(bo) { return asyncCapableHelper.isExclusive(bo); } function removeFailedJobRetryTimeCycle(bo, element) { return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element); } function canRemoveFailedJobRetryTimeCycle(element) { return !eventDefinitionHelper.getTimerEventDefinition(element); } module.exports = function(element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var idPrefix = options.idPrefix || '', labelPrefix = options.labelPrefix || ''; var asyncBeforeEntry = entryFactory.checkbox({ id: idPrefix + 'asyncBefore', label: labelPrefix + translate('Asynchronous Before'), modelProperty: 'asyncBefore', get: function(element, node) { var bo = getBusinessObject(element); return { asyncBefore: isAsyncBefore(bo) }; }, set: function(element, values) { var bo = getBusinessObject(element); var asyncBefore = !!values.asyncBefore; var props = { 'activiti:asyncBefore': asyncBefore, 'activiti:async': false }; var commands = []; if (!isAsyncAfter(bo) && !asyncBefore) { props = assign({ 'activiti:exclusive' : true }, props); if (canRemoveFailedJobRetryTimeCycle(element)) { commands.push(removeFailedJobRetryTimeCycle(bo, element)); } } commands.push(cmdHelper.updateBusinessObject(element, bo, props)); return commands; } }); var asyncAfterEntry = entryFactory.checkbox({ id: idPrefix + 'asyncAfter', label: labelPrefix + translate('Asynchronous After'), modelProperty: 'asyncAfter', get: function(element, node) { var bo = getBusinessObject(element); return { asyncAfter: isAsyncAfter(bo) }; }, set: function(element, values) { var bo = getBusinessObject(element); var asyncAfter = !!values.asyncAfter; var props = { 'activiti:asyncAfter': asyncAfter }; var commands = []; if (!isAsyncBefore(bo) && !asyncAfter) { props = assign({ 'activiti:exclusive' : true }, props); if (canRemoveFailedJobRetryTimeCycle(element)) { commands.push(removeFailedJobRetryTimeCycle(bo, element)); } } commands.push(cmdHelper.updateBusinessObject(element, bo, props)); return commands; } }); var exclusiveEntry = entryFactory.checkbox({ id: idPrefix + 'exclusive', label: labelPrefix + translate('Exclusive'), modelProperty: 'exclusive', get: function(element, node) { var bo = getBusinessObject(element); return { exclusive: isExclusive(bo) }; }, set: function(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'activiti:exclusive': !!values.exclusive }); }, hidden: function(element) { var bo = getBusinessObject(element); return bo && !isAsyncAfter(bo) && !isAsyncBefore(bo); } }); return [ asyncBeforeEntry, asyncAfterEntry, exclusiveEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/AsyncCapableHelper":588,"../../../../helper/CmdHelper":590,"../../../../helper/EventDefinitionHelper":592,"lodash/assign":513}],639:[function(require,module,exports){ 'use strict'; var cmdHelper = require('../../../../helper/CmdHelper'), entryFactory = require('../../../../factory/EntryFactory'), elementHelper = require('../../../../helper/ElementHelper'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'); var resultVariable = require('./ResultVariable'); var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var is = require('bpmn-js/lib/util/ModelUtil').is; var forEach = require('lodash/forEach'); var attributeInfo = { bpmn: { element: 'calledElement', binding: 'activiti:calledElementBinding', version: 'activiti:calledElementVersion', versionTag: 'activiti:calledElementVersionTag', tenantId: 'activiti:calledElementTenantId' }, cmmn: { element: 'activiti:caseRef', binding: 'activiti:caseBinding', version: 'activiti:caseVersion', tenantId: 'activiti:caseTenantId' }, dmn: { element: 'activiti:decisionRef', binding: 'activiti:decisionRefBinding', version: 'activiti:decisionRefVersion', versionTag: 'activiti:decisionRefVersionTag', tenantId: 'activiti:decisionRefTenantId' } }; var mapDecisionResultOptions = [ { name: 'singleEntry (TypedValue)', value: 'singleEntry' }, { name:'singleResult (Map<String, Object>)', value:'singleResult' }, { name:'collectEntries (List<Object>)', value:'collectEntries' }, { name:'resultList (List<Map<String, Object>>)', value:'resultList' } ]; var delegateVariableMappingOptions = [ { name: 'variableMappingClass', value: 'variableMappingClass' }, { name: 'variableMappingDelegateExpression', value: 'variableMappingDelegateExpression' } ]; function getActivitiInWithBusinessKey(element) { var activitiIn = [], bo = getBusinessObject(element); var activitiInParams = extensionElementsHelper.getExtensionElements(bo, 'activiti:In'); if (activitiInParams) { forEach(activitiInParams, function(param) { if (param.businessKey !== undefined) { activitiIn.push(param); } }); } return activitiIn; } function setBusinessKey(element, text, bpmnFactory) { var commands = []; var activitiInWithBusinessKey = getActivitiInWithBusinessKey(element); if (activitiInWithBusinessKey.length) { commands.push(cmdHelper.updateBusinessObject(element, activitiInWithBusinessKey[0], { businessKey: text })); } else { var bo = getBusinessObject(element), extensionElements = bo.extensionElements; if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); commands.push(cmdHelper.updateProperties(element, { extensionElements: extensionElements })); } var activitiIn = elementHelper.createElement( 'activiti:In', { 'businessKey': text }, extensionElements, bpmnFactory ); commands.push(cmdHelper.addAndRemoveElementsFromList( element, extensionElements, 'values', 'extensionElements', [ activitiIn ],[] )); } return commands; } function deleteBusinessKey(element) { var activitiInExtensions = getActivitiInWithBusinessKey(element); var commands = []; forEach(activitiInExtensions, function(elem) { commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, elem)); }); return commands; } function isSupportedCallableType(type) { return [ 'bpmn', 'cmmn', 'dmn' ].indexOf(type) !== -1; } module.exports = function(element, bpmnFactory, options, translate) { var bindingOptions = [ { name: translate('latest'), value: 'latest' }, { name: translate('deployment'), value: 'deployment' }, { name: translate('version'), value: 'version' }, { name: translate('versionTag'), value: 'versionTag' } ]; var getCallableType = options.getCallableType; var entries = []; function getAttribute(element, prop) { var type = getCallableType(element); return (attributeInfo[type] || {})[prop]; } function getCallActivityBindingValue(element) { var type = getCallableType(element); var bo = getBusinessObject(element); var attr = (attributeInfo[type] || {}).binding; return bo.get(attr); } function getDelegateVariableMappingType(element) { var bo = getBusinessObject(element); var boVariableMappingClass = bo.get('activiti:variableMappingClass'), boVariableMappingDelegateExpression = bo.get('activiti:variableMappingDelegateExpression'); var delegateVariableMappingType = ''; if (typeof boVariableMappingClass !== 'undefined') { delegateVariableMappingType = 'variableMappingClass'; } else if (typeof boVariableMappingDelegateExpression !== 'undefined') { delegateVariableMappingType = 'variableMappingDelegateExpression'; } return delegateVariableMappingType; } entries.push(entryFactory.textField({ id: 'callable-element-ref', dataValueLabel: 'callableElementLabel', modelProperty: 'callableElementRef', get: function(element, node) { var callableElementRef; var attr = getAttribute(element, 'element'); if (attr) { var bo = getBusinessObject(element); callableElementRef = bo.get(attr); } var label = ''; var type = getCallableType(element); if (type === 'bpmn') { label = translate('Called Element'); } else if (type === 'cmmn') { label = translate('Case Ref'); } else if (type === 'dmn') { label = translate('Decision Ref'); } return { callableElementRef: callableElementRef, callableElementLabel: label }; }, set: function(element, values, node) { var newCallableElementRef = values.callableElementRef; var attr = getAttribute(element, 'element'); var props = {}; props[attr] = newCallableElementRef || ''; return cmdHelper.updateProperties(element, props); }, validate: function(element, values, node) { var elementRef = values.callableElementRef; var type = getCallableType(element); return isSupportedCallableType(type) && !elementRef ? { callableElementRef: translate('Must provide a value') } : {}; }, hidden: function(element, node) { return !isSupportedCallableType(getCallableType(element)); } })); entries.push(entryFactory.selectBox({ id: 'callable-binding', label: translate('Binding'), selectOptions: function(element) { var type = getCallableType(element); var options; if (type === 'cmmn') { options = bindingOptions.filter(function(bindingOption) { return bindingOption.value !== 'versionTag'; }); } else { options = bindingOptions; } return options; }, modelProperty: 'callableBinding', get: function(element, node) { var callableBinding; var attr = getAttribute(element, 'binding'); if (attr) { var bo = getBusinessObject(element); callableBinding = bo.get(attr) || 'latest'; } return { callableBinding: callableBinding }; }, set: function(element, values, node) { var binding = values.callableBinding; var attr = getAttribute(element, 'binding'), attrVer = getAttribute(element, 'version'), attrVerTag = getAttribute(element, 'versionTag'); var props = {}; props[attr] = binding; // set version and versionTag values always to undefined to delete the existing value props[attrVer] = undefined; props[attrVerTag] = undefined; return cmdHelper.updateProperties(element, props); }, hidden: function(element, node) { return !isSupportedCallableType(getCallableType(element)); } })); entries.push(entryFactory.textField({ id: 'callable-version', label: translate('Version'), modelProperty: 'callableVersion', get: function(element, node) { var callableVersion; var attr = getAttribute(element, 'version'); if (attr) { var bo = getBusinessObject(element); callableVersion = bo.get(attr); } return { callableVersion: callableVersion }; }, set: function(element, values, node) { var version = values.callableVersion; var attr = getAttribute(element, 'version'); var props = {}; props[attr] = version || undefined; return cmdHelper.updateProperties(element, props); }, validate: function(element, values, node) { var version = values.callableVersion; var type = getCallableType(element); return ( isSupportedCallableType(type) && getCallActivityBindingValue(element) === 'version' && ( !version ? { callableVersion: translate('Must provide a value') } : {} ) ); }, hidden: function(element, node) { var type = getCallableType(element); return !isSupportedCallableType(type) || getCallActivityBindingValue(element) !== 'version'; } })); entries.push(entryFactory.textField({ id: 'callable-version-tag', label: translate('Version Tag'), modelProperty: 'versionTag', get: function(element, node) { var versionTag; var attr = getAttribute(element, 'versionTag'); if (attr) { var bo = getBusinessObject(element); versionTag = bo.get(attr); } return { versionTag: versionTag }; }, set: function(element, values, node) { var versionTag = values.versionTag; var attr = getAttribute(element, 'versionTag'); var props = {}; props[attr] = versionTag || undefined; return cmdHelper.updateProperties(element, props); }, validate: function(element, values, node) { var versionTag = values.versionTag; var type = getCallableType(element); return ( isSupportedCallableType(type) && getCallActivityBindingValue(element) === 'versionTag' && ( !versionTag ? { versionTag: translate('Must provide a value') } : {} ) ); }, hidden: function(element, node) { var type = getCallableType(element); return !isSupportedCallableType(type) || getCallActivityBindingValue(element) !== 'versionTag'; } })); entries.push(entryFactory.textField({ id: 'tenant-id', label: translate('Tenant Id'), modelProperty: 'tenantId', get: function(element, node) { var tenantId; var attr = getAttribute(element, 'tenantId'); if (attr) { var bo = getBusinessObject(element); tenantId = bo.get(attr); } return { tenantId: tenantId }; }, set: function(element, values, node) { var tenantId = values.tenantId; var attr = getAttribute(element, 'tenantId'); var props = {}; props[attr] = tenantId || undefined; return cmdHelper.updateProperties(element, props); }, hidden: function(element, node) { var type = getCallableType(element); return !isSupportedCallableType(type); } })); if (is(getBusinessObject(element), 'bpmn:CallActivity')) { entries.push(entryFactory.checkbox({ id: 'callable-business-key', label: translate('Business Key'), modelProperty: 'callableBusinessKey', get: function(element, node) { var activitiIn = getActivitiInWithBusinessKey(element); return { callableBusinessKey: !!(activitiIn && activitiIn.length > 0) }; }, set: function(element, values, node) { if (values.callableBusinessKey) { return setBusinessKey(element, '#{execution.processBusinessKey}', bpmnFactory); } else { return deleteBusinessKey(element); } } })); } entries.push(entryFactory.textField({ id: 'business-key-expression', label: translate('Business Key Expression'), modelProperty: 'businessKey', get: function(element, node) { var activitiInWithBusinessKey = getActivitiInWithBusinessKey(element); return { businessKey: ( activitiInWithBusinessKey.length ? activitiInWithBusinessKey[0].get('activiti:businessKey') : undefined ) }; }, set: function(element, values, node) { var businessKey = values.businessKey; return setBusinessKey(element, businessKey, bpmnFactory); }, validate: function(element, values, node) { var businessKey = values.businessKey; return businessKey === '' ? { businessKey: translate('Must provide a value') } : {}; }, hidden: function(element, node) { return !getActivitiInWithBusinessKey(element).length; } })); entries = entries.concat(resultVariable(element, bpmnFactory, { id: 'dmn-resultVariable', getBusinessObject: getBusinessObject, getImplementationType: getCallableType, hideResultVariable: function(element, node) { return getCallableType(element) !== 'dmn'; } }, translate)); entries.push(entryFactory.selectBox({ id: 'dmn-map-decision-result', label: translate('Map Decision Result'), selectOptions: mapDecisionResultOptions, modelProperty: 'mapDecisionResult', get: function(element, node) { var bo = getBusinessObject(element); return { mapDecisionResult: bo.get('activiti:mapDecisionResult') || 'resultList' }; }, set: function(element, values, node) { return cmdHelper.updateProperties(element, { 'activiti:mapDecisionResult': values.mapDecisionResult || 'resultList' }); }, hidden: function(element, node) { var bo = getBusinessObject(element); var resultVariable = bo.get('activiti:resultVariable'); return !(getCallableType(element) === 'dmn' && typeof resultVariable !== 'undefined'); } })); entries.push(entryFactory.selectBox({ id: 'delegateVariableMappingType', label: translate('Delegate Variable Mapping'), selectOptions: delegateVariableMappingOptions, emptyParameter: true, modelProperty: 'delegateVariableMappingType', get: function(element, node) { return { delegateVariableMappingType : getDelegateVariableMappingType(element) }; }, set: function(element, values, node) { var delegateVariableMappingType = values.delegateVariableMappingType; var props = { 'activiti:variableMappingClass' : undefined, 'activiti:variableMappingDelegateExpression' : undefined }; if (delegateVariableMappingType === 'variableMappingClass') { props['activiti:variableMappingClass'] = ''; } else if (delegateVariableMappingType === 'variableMappingDelegateExpression') { props['activiti:variableMappingDelegateExpression'] = ''; } return cmdHelper.updateProperties(element, props); }, hidden: function(element, node) { return (getCallableType(element) !== 'bpmn'); } })); entries.push(entryFactory.textField({ id: 'delegateVariableMapping', dataValueLabel: 'delegateVariableMappingLabel', modelProperty: 'delegateVariableMapping', get: function(element, node) { var bo = getBusinessObject(element); var label = ''; var delegateVariableMapping = undefined; var type = getDelegateVariableMappingType(element); if (type === 'variableMappingClass') { label = translate('Class'); delegateVariableMapping = bo.get('activiti:variableMappingClass'); } else if (type === 'variableMappingDelegateExpression') { label = translate('Delegate Expression'); delegateVariableMapping = bo.get('activiti:variableMappingDelegateExpression'); } return { delegateVariableMapping: delegateVariableMapping, delegateVariableMappingLabel: label }; }, set: function(element, values, node) { var delegateVariableMapping = values.delegateVariableMapping; var attr = 'activiti:' + getDelegateVariableMappingType(element); var props = {}; props[attr] = delegateVariableMapping || undefined; return cmdHelper.updateProperties(element, props); }, validate: function(element, values, node) { var delegateVariableMapping = values.delegateVariableMapping; return ( getCallableType(element) === 'bpmn' && ( !delegateVariableMapping ? { delegateVariableMapping: translate('Must provide a value') } : {} ) ); }, hidden: function(element, node) { return !(getCallableType(element) === 'bpmn' && getDelegateVariableMappingType(element) !== ''); } })); return entries; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"./ResultVariable":656,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],640:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function(element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var candidateStarterGroupsEntry = entryFactory.textField({ id: 'candidateStarterGroups', label: translate('Candidate Starter Groups'), modelProperty: 'candidateStarterGroups', description: translate('Specify more than one group as a comma separated list.'), get: function(element, node) { var bo = getBusinessObject(element); var candidateStarterGroups = bo.get('activiti:candidateStarterGroups'); return { candidateStarterGroups: candidateStarterGroups ? candidateStarterGroups : '' }; }, set: function(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'activiti:candidateStarterGroups': values.candidateStarterGroups || undefined }); } }); var candidateStarterUsersEntry = entryFactory.textField({ id: 'candidateStarterUsers', label: translate('Candidate Starter Users'), modelProperty: 'candidateStarterUsers', description: translate('Specify more than one user as a comma separated list.'), get: function(element, node) { var bo = getBusinessObject(element); var candidateStarterUsers = bo.get('activiti:candidateStarterUsers'); return { candidateStarterUsers: candidateStarterUsers ? candidateStarterUsers : '' }; }, set: function(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'activiti:candidateStarterUsers': values.candidateStarterUsers || undefined }); } }); return [ candidateStarterGroupsEntry, candidateStarterUsersEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],641:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); var DELEGATE_TYPES = [ 'class', 'expression', 'delegateExpression' ]; var PROPERTIES = { class: 'activiti:class', expression: 'activiti:expression', delegateExpression: 'activiti:delegateExpression' }; function isDelegate(type) { return DELEGATE_TYPES.indexOf(type) !== -1; } function getAttribute(type) { return PROPERTIES[type]; } module.exports = function(element, bpmnFactory, options, translate) { var getImplementationType = options.getImplementationType, getBusinessObject = options.getBusinessObject; function getDelegationLabel(type) { switch (type) { case 'class': return translate('Java Class'); case 'expression': return translate('Expression'); case 'delegateExpression': return translate('Delegate Expression'); default: return ''; } } var delegateEntry = entryFactory.textField({ id: 'delegate', label: translate('Value'), dataValueLabel: 'delegationLabel', modelProperty: 'delegate', get: function(element, node) { var bo = getBusinessObject(element); var type = getImplementationType(element); var attr = getAttribute(type); var label = getDelegationLabel(type); return { delegate: bo.get(attr), delegationLabel: label }; }, set: function(element, values, node) { var bo = getBusinessObject(element); var type = getImplementationType(element); var attr = getAttribute(type); var prop = {}; prop[attr] = values.delegate || ''; return cmdHelper.updateBusinessObject(element, bo, prop); }, validate: function(element, values, node) { return isDelegate(getImplementationType(element)) && !values.delegate ? { delegate: translate('Must provide a value') } : {}; }, hidden: function(element, node) { return !isDelegate(getImplementationType(element)); } }); return [ delegateEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],642:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'), elementReferenceProperty = require('../../../../provider/bpmn/parts/implementation/ElementReferenceProperty'); module.exports = function( group, element, bpmnFactory, errorEventDefinition, showErrorCodeVariable, showErrorMessageVariable, translate ) { var getValue = function(modelProperty) { return function(element) { var modelPropertyValue = errorEventDefinition.get('activiti:' + modelProperty); var value = {}; value[modelProperty] = modelPropertyValue; return value; }; }; var setValue = function(modelProperty) { return function(element, values) { var props = {}; props['activiti:' + modelProperty] = values[modelProperty] || undefined; return cmdHelper.updateBusinessObject(element, errorEventDefinition, props); }; }; group.entries = group.entries.concat( elementReferenceProperty(element, errorEventDefinition, bpmnFactory, { id: 'error-element-message', label: translate('Error Message'), referenceProperty: 'errorRef', modelProperty: 'errorMessage' }) ); if (showErrorCodeVariable) { group.entries.push(entryFactory.textField({ id: 'errorCodeVariable', label: translate('Error Code Variable'), modelProperty : 'errorCodeVariable', get: getValue('errorCodeVariable'), set: setValue('errorCodeVariable') })); } if (showErrorMessageVariable) { group.entries.push(entryFactory.textField({ id: 'errorMessageVariable', label: translate('Error Message Variable'), modelProperty: 'errorMessageVariable', get: getValue('errorMessageVariable'), set: setValue('errorMessageVariable') })); } }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../provider/bpmn/parts/implementation/ElementReferenceProperty":668}],643:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var domQuery = require('min-dom').query, domClosest = require('min-dom').closest, domify = require('min-dom').domify, forEach = require('lodash/forEach'); var elementHelper = require('../../../../helper/ElementHelper'), cmdHelper = require('../../../../helper/CmdHelper'), utils = require('../../../../Utils'), escapeHTML = utils.escapeHTML; function getSelectBox(node, id) { var currentTab = domClosest(node, 'div.bpp-properties-tab'); var query = 'select[name=selectedExtensionElement]' + (id ? '[id=cam-extensionElements-' + id + ']' : ''); return domQuery(query, currentTab); } function getSelected(node, id) { var selectBox = getSelectBox(node, id); return { value: (selectBox || {}).value, idx: (selectBox || {}).selectedIndex }; } function generateElementId(prefix) { prefix = prefix + '_'; return utils.nextId(prefix); } var CREATE_EXTENSION_ELEMENT_ACTION = 'create-extension-element', REMOVE_EXTENSION_ELEMENT_ACTION = 'remove-extension-element'; module.exports = function(element, bpmnFactory, options, translate) { var id = options.id, prefix = options.prefix || 'elem', label = options.label || id, idGeneration = (options.idGeneration === false) ? options.idGeneration : true, businessObject = options.businessObject || getBusinessObject(element); var modelProperty = options.modelProperty || 'id'; var getElements = options.getExtensionElements; var createElement = options.createExtensionElement, canCreate = typeof createElement === 'function'; var removeElement = options.removeExtensionElement, canRemove = typeof removeElement === 'function'; var onSelectionChange = options.onSelectionChange; var hideElements = options.hideExtensionElements, canBeHidden = typeof hideElements === 'function'; var setOptionLabelValue = options.setOptionLabelValue; var defaultSize = options.size || 5, resizable = options.resizable; var reference = options.reference || undefined; var selectionChanged = function(element, node, event, scope) { if (typeof onSelectionChange === 'function') { return onSelectionChange(element, node, event, scope); } }; var createOption = function(value) { return '<option value="' + escapeHTML(value) + '" data-value data-name="extensionElementValue">' + escapeHTML(value) + '</option>'; }; var initSelectionSize = function(selectBox, optionsLength) { if (resizable) { selectBox.size = optionsLength > defaultSize ? optionsLength : defaultSize; } }; return { id: id, html: '<div class="bpp-row bpp-element-list" ' + (canBeHidden ? 'data-show="hideElements"' : '') + '>' + '<label for="cam-extensionElements-' + escapeHTML(id) + '">' + escapeHTML(label) + '</label>' + '<div class="bpp-field-wrapper">' + '<select id="cam-extensionElements-' + escapeHTML(id) + '"' + 'name="selectedExtensionElement" ' + 'size="' + escapeHTML(defaultSize) + '" ' + 'data-list-entry-container ' + 'data-on-change="selectElement">' + '</select>' + (canCreate ? '<button class="add" ' + 'id="cam-extensionElements-create-' + escapeHTML(id) + '" ' + 'data-action="createElement">' + '<span>+</span>' + '</button>' : '') + (canRemove ? '<button class="clear" ' + 'id="cam-extensionElements-remove-' + escapeHTML(id) + '" ' + 'data-action="removeElement" ' + 'data-disable="disableRemove">' + '<span>-</span>' + '</button>' : '') + '</div>' + '</div>', get: function(element, node) { var elements = getElements(element, node); var result = []; forEach(elements, function(elem) { result.push({ extensionElementValue: elem.get(modelProperty) }); }); var selectBox = getSelectBox(node.parentNode, id); initSelectionSize(selectBox, result.length); return result; }, set: function(element, values, node) { var action = this.__action; delete this.__action; businessObject = businessObject || getBusinessObject(element); var bo = (reference && businessObject.get(reference)) ? businessObject.get(reference) : businessObject; var extensionElements = bo.get('extensionElements'); if (action.id === CREATE_EXTENSION_ELEMENT_ACTION) { var commands = []; if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements })); } commands.push(createElement(element, extensionElements, action.value, node)); return commands; } else if (action.id === REMOVE_EXTENSION_ELEMENT_ACTION) { return removeElement(element, extensionElements, action.value, action.idx, node); } }, createListEntryTemplate: function(value, index, selectBox) { initSelectionSize(selectBox, selectBox.options.length + 1); return createOption(value.extensionElementValue); }, deselect: function(element, node) { var selectBox = getSelectBox(node, id); selectBox.selectedIndex = -1; }, getSelected: function(element, node) { return getSelected(node, id); }, setControlValue: function(element, node, option, property, value, idx) { node.value = value; if (!setOptionLabelValue) { node.text = value; } else { setOptionLabelValue(element, node, option, property, value, idx); } }, createElement: function(element, node) { // create option template var generatedId; if (idGeneration) { generatedId = generateElementId(prefix); } var selectBox = getSelectBox(node, id); var template = domify(createOption(generatedId)); // add new empty option as last child element selectBox.appendChild(template); // select last child element selectBox.lastChild.selected = 'selected'; selectionChanged(element, node); // update select box size initSelectionSize(selectBox, selectBox.options.length); this.__action = { id: CREATE_EXTENSION_ELEMENT_ACTION, value: generatedId }; return true; }, removeElement: function(element, node) { var selection = getSelected(node, id); var selectBox = getSelectBox(node, id); selectBox.removeChild(selectBox.options[selection.idx]); // update select box size initSelectionSize(selectBox, selectBox.options.length); this.__action = { id: REMOVE_EXTENSION_ELEMENT_ACTION, value: selection.value, idx: selection.idx }; return true; }, hideElements: function(element, entryNode, node, scopeNode) { return !hideElements(element, entryNode, node, scopeNode); }, disableRemove: function(element, entryNode, node, scopeNode) { return (getSelected(entryNode, id) || {}).idx < 0; }, selectElement: selectionChanged }; }; },{"../../../../Utils":576,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522,"min-dom":556}],644:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function(element, bpmnFactory, options, translate) { var getImplementationType = options.getImplementationType, getBusinessObject = options.getBusinessObject; function isExternal(element) { return getImplementationType(element) === 'external'; } var topicEntry = entryFactory.textField({ id: 'externalTopic', label: translate('Topic'), modelProperty: 'externalTopic', get: function(element, node) { var bo = getBusinessObject(element); return { externalTopic: bo.get('activiti:topic') }; }, set: function(element, values, node) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'activiti:topic': values.externalTopic }); }, validate: function(element, values, node) { return isExternal(element) && !values.externalTopic ? { externalTopic: translate('Must provide a value') } : {}; }, hidden: function(element, node) { return !isExternal(element); } }); return [ topicEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],645:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function(element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var externalTaskPriorityEntry = entryFactory.textField({ id: 'externalTaskPriority', label: translate('Task Priority'), modelProperty: 'taskPriority', get: function(element, node) { var bo = getBusinessObject(element); return { taskPriority: bo.get('activiti:taskPriority') }; }, set: function(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'activiti:taskPriority': values.taskPriority || undefined }); } }); return [ externalTaskPriorityEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],646:[function(require,module,exports){ 'use strict'; var extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), elementHelper = require('../../../../helper/ElementHelper'), cmdHelper = require('../../../../helper/CmdHelper'); var utils = require('../../../../Utils'); var entryFactory = require('../../../../factory/EntryFactory'); var extensionElementsEntry = require('./ExtensionElements'); var ModelUtil = require('bpmn-js/lib/util/ModelUtil'), getBusinessObject = ModelUtil.getBusinessObject; var assign = require('lodash/assign'); var DEFAULT_PROPS = { 'stringValue': undefined, 'string': undefined, 'expression': undefined }; var ACTIVITI_FIELD_EXTENSION_ELEMENT = 'activiti:Field'; module.exports = function(element, bpmnFactory, translate, options) { options = options || {}; var insideListener = !!options.insideListener, idPrefix = options.idPrefix || '', getSelectedListener = options.getSelectedListener, businessObject = options.businessObject || getBusinessObject(element); var entries = []; var isSelected = function(element, node) { return getSelectedField(element, node); }; function getSelectedField(element, node) { var selected = fieldEntry.getSelected(element, node.parentNode); if (selected.idx === -1) { return; } var fields = getActivitiFields(element, node); return fields[selected.idx]; } function getActivitiFields(element, node) { if (!insideListener) { return ( businessObject && extensionElementsHelper.getExtensionElements(businessObject, ACTIVITI_FIELD_EXTENSION_ELEMENT) ) || []; } return getActivitiListenerFields(element, node); } function getActivitiListenerFields(element, node) { var selectedListener = getSelectedListener(element, node); return selectedListener && selectedListener.fields || []; } function getFieldType(bo) { var fieldType = 'string'; var expressionValue = bo && bo.expression; var stringValue = bo && (bo.string || bo.stringValue); if (typeof stringValue !== 'undefined') { fieldType = 'string'; } else if (typeof expressionValue !== 'undefined') { fieldType = 'expression'; } return fieldType; } var setOptionLabelValue = function() { return function(element, node, option, property, value, idx) { var activitiFields = getActivitiFields(element, node); var field = activitiFields[idx]; value = (field.name) ? field.name : '<empty>'; var label = idx + ' : ' + value; option.text = label; }; }; var newElement = function() { return function(element, extensionElements, value, node) { var props = { name: '', string: '' }; var newFieldElem; if (!insideListener) { newFieldElem = elementHelper.createElement(ACTIVITI_FIELD_EXTENSION_ELEMENT, props, extensionElements, bpmnFactory); return cmdHelper.addElementsTolist(element, extensionElements, 'values', [ newFieldElem ]); } else { var selectedListener = getSelectedListener(element, node); newFieldElem = elementHelper.createElement(ACTIVITI_FIELD_EXTENSION_ELEMENT, props, selectedListener, bpmnFactory); return cmdHelper.addElementsTolist(element, selectedListener, 'fields', [ newFieldElem ]); } }; }; var removeElement = function() { return function(element, extensionElements, value, idx, node) { var activitiFields= getActivitiFields(element, node); var field = activitiFields[idx]; if (field) { if (!insideListener) { return extensionElementsHelper.removeEntry(businessObject, element, field); } var selectedListener = getSelectedListener(element, node); return cmdHelper.removeElementsFromList(element, selectedListener, 'fields', null, [ field ]); } }; }; var fieldEntry = extensionElementsEntry(element, bpmnFactory, { id : idPrefix + 'fields', label : translate('Fields'), modelProperty: 'fieldName', idGeneration: 'false', businessObject: businessObject, createExtensionElement: newElement(), removeExtensionElement: removeElement(), getExtensionElements: function(element, node) { return getActivitiFields(element, node); }, setOptionLabelValue: setOptionLabelValue() }); entries.push(fieldEntry); entries.push(entryFactory.validationAwareTextField({ id: idPrefix + 'field-name', label: translate('Name'), modelProperty: 'fieldName', getProperty: function(element, node) { return (getSelectedField(element, node) || {}).name; }, setProperty: function(element, values, node) { var selectedField = getSelectedField(element, node); return cmdHelper.updateBusinessObject(element, selectedField, { name : values.fieldName }); }, validate: function(element, values, node) { var bo = getSelectedField(element, node); var validation = {}; if (bo) { var nameValue = values.fieldName; if (nameValue) { if (utils.containsSpace(nameValue)) { validation.fieldName = translate('Name must not contain spaces'); } } else { validation.fieldName = translate('Parameter must have a name'); } } return validation; }, hidden: function(element, node) { return !isSelected(element, node); } })); var fieldTypeOptions = [ { name: translate('String'), value: 'string' }, { name: translate('Expression'), value: 'expression' } ]; entries.push(entryFactory.selectBox({ id: idPrefix + 'field-type', label: translate('Type'), selectOptions: fieldTypeOptions, modelProperty: 'fieldType', get: function(element, node) { var bo = getSelectedField(element, node); var fieldType = getFieldType(bo); return { fieldType: fieldType }; }, set: function(element, values, node) { var props = assign({}, DEFAULT_PROPS); var fieldType = values.fieldType; if (fieldType === 'string') { props.string = ''; } else if (fieldType === 'expression') { props.expression = ''; } return cmdHelper.updateBusinessObject(element, getSelectedField(element, node), props); }, hidden: function(element, node) { return !isSelected(element, node); } })); entries.push(entryFactory.textBox({ id: idPrefix + 'field-value', label: translate('Value'), modelProperty: 'fieldValue', get: function(element, node) { var bo = getSelectedField(element, node); var fieldType = getFieldType(bo); var fieldValue; if (fieldType === 'string') { fieldValue = bo && (bo.string || bo.stringValue); } else if (fieldType === 'expression') { fieldValue = bo && bo.expression; } return { fieldValue: fieldValue }; }, set: function(element, values, node) { var bo = getSelectedField(element, node); var fieldType = getFieldType(bo); var props = assign({}, DEFAULT_PROPS); var fieldValue = values.fieldValue || undefined; if (fieldType === 'string') { props.string = fieldValue; } else if (fieldType === 'expression') { props.expression = fieldValue; } return cmdHelper.updateBusinessObject(element, bo, props); }, validate: function(element, values, node) { var bo = getSelectedField(element, node); var validation = {}; if (bo) { if (!values.fieldValue) { validation.fieldValue = translate('Must provide a value'); } } return validation; }, show: function(element, node) { return isSelected(element, node); } })); return entries; }; },{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"./ExtensionElements":643,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513}],647:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function(element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var historyTimeToLiveEntry = entryFactory.textField({ id: 'historyTimeToLive', label: translate('History Time To Live'), modelProperty: 'historyTimeToLive', get: function(element, node) { var bo = getBusinessObject(element); var historyTimeToLive = bo.get('activiti:historyTimeToLive'); return { historyTimeToLive: historyTimeToLive ? historyTimeToLive : '' }; }, set: function(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'activiti:historyTimeToLive': values.historyTimeToLive || undefined }); } }); return [ historyTimeToLiveEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],648:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), elementHelper = require('../../../../helper/ElementHelper'); var assign = require('lodash/assign'); var map = require('lodash/map'); var DEFAULT_DELEGATE_PROPS = [ 'class', 'expression', 'delegateExpression' ]; var DELEGATE_PROPS = { 'activiti:class': undefined, 'activiti:expression': undefined, 'activiti:delegateExpression': undefined, 'activiti:resultVariable': undefined }; var DMN_CAPABLE_PROPS = { 'activiti:decisionRef': undefined, 'activiti:decisionRefBinding': 'latest', 'activiti:decisionRefVersion': undefined, 'activiti:mapDecisionResult': 'resultList', 'activiti:decisionRefTenantId': undefined }; var EXTERNAL_CAPABLE_PROPS = { 'activiti:type': undefined, 'activiti:topic': undefined }; module.exports = function(element, bpmnFactory, options, translate) { var DEFAULT_OPTIONS = [ { value: 'class', name: translate('Java Class') }, { value: 'expression', name: translate('Expression') }, { value: 'delegateExpression', name: translate('Delegate Expression') } ]; var DMN_OPTION = [ { value: 'dmn', name: translate('DMN') } ]; var EXTERNAL_OPTION = [ { value: 'external', name: translate('External') } ]; var CONNECTOR_OPTION = [ { value: 'connector', name: translate('Connector') } ]; var SCRIPT_OPTION = [ { value: 'script', name: translate('Script') } ]; var getType = options.getImplementationType, getBusinessObject = options.getBusinessObject; var hasDmnSupport = options.hasDmnSupport, hasExternalSupport = options.hasExternalSupport, hasServiceTaskLikeSupport = options.hasServiceTaskLikeSupport, hasScriptSupport = options.hasScriptSupport; var entries = []; var selectOptions = DEFAULT_OPTIONS.concat([]); if (hasDmnSupport) { selectOptions = selectOptions.concat(DMN_OPTION); } if (hasExternalSupport) { selectOptions = selectOptions.concat(EXTERNAL_OPTION); } if (hasServiceTaskLikeSupport) { selectOptions = selectOptions.concat(CONNECTOR_OPTION); } if (hasScriptSupport) { selectOptions = selectOptions.concat(SCRIPT_OPTION); } selectOptions.push({ value: '' }); entries.push(entryFactory.selectBox({ id : 'implementation', label: translate('Implementation'), selectOptions: selectOptions, modelProperty: 'implType', get: function(element, node) { return { implType: getType(element) || '' }; }, set: function(element, values, node) { var bo = getBusinessObject(element); var oldType = getType(element); var newType = values.implType; var props = assign({}, DELEGATE_PROPS); if (DEFAULT_DELEGATE_PROPS.indexOf(newType) !== -1) { var newValue = ''; if (DEFAULT_DELEGATE_PROPS.indexOf(oldType) !== -1) { newValue = bo.get('activiti:' + oldType); } props['activiti:' + newType] = newValue; } if (hasDmnSupport) { props = assign(props, DMN_CAPABLE_PROPS); if (newType === 'dmn') { props['activiti:decisionRef'] = ''; } } if (hasExternalSupport) { props = assign(props, EXTERNAL_CAPABLE_PROPS); if (newType === 'external') { props['activiti:type'] = 'external'; props['activiti:topic'] = ''; } } if (hasScriptSupport) { props['activiti:script'] = undefined; if (newType === 'script') { props['activiti:script'] = elementHelper.createElement('activiti:Script', {}, bo, bpmnFactory); } } var commands = []; commands.push(cmdHelper.updateBusinessObject(element, bo, props)); if (hasServiceTaskLikeSupport) { var connectors = extensionElementsHelper.getExtensionElements(bo, 'activiti:Connector'); commands.push(map(connectors, function(connector) { return extensionElementsHelper.removeEntry(bo, element, connector); })); if (newType === 'connector') { var extensionElements = bo.get('extensionElements'); if (!extensionElements) { extensionElements = elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, bo, bpmnFactory); commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements })); } var connector = elementHelper.createElement('activiti:Connector', {}, extensionElements, bpmnFactory); commands.push(cmdHelper.addAndRemoveElementsFromList( element, extensionElements, 'values', 'extensionElements', [ connector ], [] )); } } return commands; } })); return entries; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"lodash/assign":513,"lodash/map":540}],649:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var elementHelper = require('../../../../helper/ElementHelper'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), inputOutputHelper = require('../../../../helper/InputOutputHelper'), cmdHelper = require('../../../../helper/CmdHelper'); var extensionElementsEntry = require('./ExtensionElements'); function getInputOutput(element, insideConnector) { return inputOutputHelper.getInputOutput(element, insideConnector); } function getConnector(element) { return inputOutputHelper.getConnector(element); } function getInputParameters(element, insideConnector) { return inputOutputHelper.getInputParameters(element, insideConnector); } function getOutputParameters(element, insideConnector) { return inputOutputHelper.getOutputParameters(element, insideConnector); } function getInputParameter(element, insideConnector, idx) { return inputOutputHelper.getInputParameter(element, insideConnector, idx); } function getOutputParameter(element, insideConnector, idx) { return inputOutputHelper.getOutputParameter(element, insideConnector, idx); } function createElement(type, parent, factory, properties) { return elementHelper.createElement(type, properties, parent, factory); } function createInputOutput(parent, bpmnFactory, properties) { return createElement('activiti:InputOutput', parent, bpmnFactory, properties); } function createParameter(type, parent, bpmnFactory, properties) { return createElement(type, parent, bpmnFactory, properties); } function ensureInputOutputSupported(element, insideConnector) { return inputOutputHelper.isInputOutputSupported(element, insideConnector); } function ensureOutparameterSupported(element, insideConnector) { return inputOutputHelper.areOutputParametersSupported(element, insideConnector); } module.exports = function(element, bpmnFactory, options, translate) { var TYPE_LABEL = { 'activiti:Map': translate('Map'), 'activiti:List': translate('List'), 'activiti:Script': translate('Script') }; options = options || {}; var insideConnector = !!options.insideConnector, idPrefix = options.idPrefix || ''; var getSelected = function(element, node) { var selection = (inputEntry && inputEntry.getSelected(element, node)) || { idx: -1 }; var parameter = getInputParameter(element, insideConnector, selection.idx); if (!parameter && outputEntry) { selection = outputEntry.getSelected(element, node); parameter = getOutputParameter(element, insideConnector, selection.idx); } return parameter; }; var result = { getSelectedParameter: getSelected }; var entries = result.entries = []; if (!ensureInputOutputSupported(element)) { return result; } var newElement = function(type, prop, factory) { return function(element, extensionElements, value) { var commands = []; var inputOutput = getInputOutput(element, insideConnector); if (!inputOutput) { var parent = !insideConnector ? extensionElements : getConnector(element); inputOutput = createInputOutput(parent, bpmnFactory, { inputParameters: [], outputParameters: [] }); if (!insideConnector) { commands.push(cmdHelper.addAndRemoveElementsFromList( element, extensionElements, 'values', 'extensionElements', [ inputOutput ], [] )); } else { commands.push(cmdHelper.updateBusinessObject(element, parent, { inputOutput: inputOutput })); } } var newElem = createParameter(type, inputOutput, bpmnFactory, { name: value }); commands.push(cmdHelper.addElementsTolist(element, inputOutput, prop, [ newElem ])); return commands; }; }; var removeElement = function(getter, prop, otherProp) { return function(element, extensionElements, value, idx) { var inputOutput = getInputOutput(element, insideConnector); var parameter = getter(element, insideConnector, idx); var commands = []; commands.push(cmdHelper.removeElementsFromList(element, inputOutput, prop, null, [ parameter ])); var firstLength = inputOutput.get(prop).length-1; var secondLength = (inputOutput.get(otherProp) || []).length; if (!firstLength && !secondLength) { if (!insideConnector) { commands.push(extensionElementsHelper.removeEntry(getBusinessObject(element), element, inputOutput)); } else { var connector = getConnector(element); commands.push(cmdHelper.updateBusinessObject(element, connector, { inputOutput: undefined })); } } return commands; }; }; var setOptionLabelValue = function(getter) { return function(element, node, option, property, value, idx) { var parameter = getter(element, insideConnector, idx); var suffix = 'Text'; var definition = parameter.get('definition'); if (typeof definition !== 'undefined') { var type = definition.$type; suffix = TYPE_LABEL[type]; } option.text = (value || '') + ' : ' + suffix; }; }; // input parameters /////////////////////////////////////////////////////////////// var inputEntry = extensionElementsEntry(element, bpmnFactory, { id: idPrefix + 'inputs', label: translate('Input Parameters'), modelProperty: 'name', prefix: 'Input', resizable: true, createExtensionElement: newElement('activiti:InputParameter', 'inputParameters'), removeExtensionElement: removeElement(getInputParameter, 'inputParameters', 'outputParameters'), getExtensionElements: function(element) { return getInputParameters(element, insideConnector); }, onSelectionChange: function(element, node, event, scope) { outputEntry && outputEntry.deselect(element, node); }, setOptionLabelValue: setOptionLabelValue(getInputParameter) }); entries.push(inputEntry); // output parameters /////////////////////////////////////////////////////// if (ensureOutparameterSupported(element, insideConnector)) { var outputEntry = extensionElementsEntry(element, bpmnFactory, { id: idPrefix + 'outputs', label: translate('Output Parameters'), modelProperty: 'name', prefix: 'Output', resizable: true, createExtensionElement: newElement('activiti:OutputParameter', 'outputParameters'), removeExtensionElement: removeElement(getOutputParameter, 'outputParameters', 'inputParameters'), getExtensionElements: function(element) { return getOutputParameters(element, insideConnector); }, onSelectionChange: function(element, node, event, scope) { inputEntry.deselect(element, node); }, setOptionLabelValue: setOptionLabelValue(getOutputParameter) }); entries.push(outputEntry); } return result; }; },{"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"../../../../helper/InputOutputHelper":596,"./ExtensionElements":643,"bpmn-js/lib/util/ModelUtil":141}],650:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is; var elementHelper = require('../../../../helper/ElementHelper'), inputOutputHelper = require('../../../../helper/InputOutputHelper'), cmdHelper = require('../../../../helper/CmdHelper'), utils = require('../../../../Utils'); var entryFactory = require('../../../../factory/EntryFactory'), scriptImplementation = require('./Script'); function createElement(type, parent, factory, properties) { return elementHelper.createElement(type, properties, parent, factory); } function isScript(elem) { return is(elem, 'activiti:Script'); } function isList(elem) { return is(elem, 'activiti:List'); } function isMap(elem) { return is(elem, 'activiti:Map'); } function ensureInputOutputSupported(element, insideConnector) { return inputOutputHelper.isInputOutputSupported(element, insideConnector); } module.exports = function(element, bpmnFactory, options, translate) { var typeInfo = { 'activiti:Map': { value: 'map', label: translate('Map') }, 'activiti:List': { value: 'list', label: translate('List') }, 'activiti:Script': { value: 'script', label: translate('Script') } }; options = options || {}; var insideConnector = !!options.insideConnector, idPrefix = options.idPrefix || ''; var getSelected = options.getSelectedParameter; if (!ensureInputOutputSupported(element, insideConnector)) { return []; } var entries = []; var isSelected = function(element, node) { return getSelected(element, node); }; // parameter name //////////////////////////////////////////////////////// entries.push(entryFactory.validationAwareTextField({ id: idPrefix + 'parameterName', label: translate('Name'), modelProperty: 'name', getProperty: function(element, node) { return (getSelected(element, node) || {}).name; }, setProperty: function(element, values, node) { var param = getSelected(element, node); return cmdHelper.updateBusinessObject(element, param, values); }, validate: function(element, values, node) { var bo = getSelected(element, node); var validation = {}; if (bo) { var nameValue = values.name; if (nameValue) { if (utils.containsSpace(nameValue)) { validation.name = translate('Name must not contain spaces'); } } else { validation.name = translate('Parameter must have a name'); } } return validation; }, hidden: function(element, node) { return !isSelected(element, node); } })); // parameter type ////////////////////////////////////////////////////// var selectOptions = [ { value: 'text', name: translate('Text') }, { value: 'script', name: translate('Script') }, { value: 'list', name: translate('List') }, { value: 'map', name: translate('Map') } ]; entries.push(entryFactory.selectBox({ id : idPrefix + 'parameterType', label: translate('Type'), selectOptions: selectOptions, modelProperty: 'parameterType', get: function(element, node) { var bo = getSelected(element, node); var parameterType = 'text'; if (typeof bo !== 'undefined') { var definition = bo.get('definition'); if (typeof definition !== 'undefined') { var type = definition.$type; parameterType = typeInfo[type].value; } } return { parameterType: parameterType }; }, set: function(element, values, node) { var bo = getSelected(element, node); var properties = { value: undefined, definition: undefined }; var createParameterTypeElem = function(type) { return createElement(type, bo, bpmnFactory); }; var parameterType = values.parameterType; if (parameterType === 'script') { properties.definition = createParameterTypeElem('activiti:Script'); } else if (parameterType === 'list') { properties.definition = createParameterTypeElem('activiti:List'); } else if (parameterType === 'map') { properties.definition = createParameterTypeElem('activiti:Map'); } return cmdHelper.updateBusinessObject(element, bo, properties); }, show: function(element, node) { return isSelected(element, node); } })); // parameter value (type = text) /////////////////////////////////////////////////////// entries.push(entryFactory.textBox({ id : idPrefix + 'parameterType-text', label : translate('Value'), modelProperty: 'value', get: function(element, node) { return { value: (getSelected(element, node) || {}).value }; }, set: function(element, values, node) { var param = getSelected(element, node); values.value = values.value || undefined; return cmdHelper.updateBusinessObject(element, param, values); }, show: function(element, node) { var bo = getSelected(element, node); return bo && !bo.definition; } })); // parameter value (type = script) /////////////////////////////////////////////////////// var script = scriptImplementation('scriptFormat', 'value', true, translate); entries.push({ id: idPrefix + 'parameterType-script', html: '<div data-show="isScript">' + script.template + '</div>', get: function(element, node) { var bo = getSelected(element, node); return bo && isScript(bo.definition) ? script.get(element, bo.definition) : {}; }, set: function(element, values, node) { var bo = getSelected(element, node); var update = script.set(element, values); return cmdHelper.updateBusinessObject(element, bo.definition, update); }, validate: function(element, values, node) { var bo = getSelected(element, node); return bo && isScript(bo.definition) ? script.validate(element, bo.definition) : {}; }, isScript: function(element, node) { var bo = getSelected(element, node); return bo && isScript(bo.definition); }, script: script }); // parameter value (type = list) /////////////////////////////////////////////////////// entries.push(entryFactory.table({ id: idPrefix + 'parameterType-list', modelProperties: [ 'value' ], labels: [ translate('Value') ], addLabel: translate('Add Value'), getElements: function(element, node) { var bo = getSelected(element, node); if (bo && isList(bo.definition)) { return bo.definition.items; } return []; }, updateElement: function(element, values, node, idx) { var bo = getSelected(element, node); var item = bo.definition.items[idx]; return cmdHelper.updateBusinessObject(element, item, values); }, addElement: function(element, node) { var bo = getSelected(element, node); var newValue = createElement('activiti:Value', bo.definition, bpmnFactory, { value: undefined }); return cmdHelper.addElementsTolist(element, bo.definition, 'items', [ newValue ]); }, removeElement: function(element, node, idx) { var bo = getSelected(element, node); return cmdHelper.removeElementsFromList(element, bo.definition, 'items', null, [ bo.definition.items[idx] ]); }, editable: function(element, node, prop, idx) { var bo = getSelected(element, node); var item = bo.definition.items[idx]; return !isMap(item) && !isList(item) && !isScript(item); }, setControlValue: function(element, node, input, prop, value, idx) { var bo = getSelected(element, node); var item = bo.definition.items[idx]; if (!isMap(item) && !isList(item) && !isScript(item)) { input.value = value; } else { input.value = typeInfo[item.$type].label; } }, show: function(element, node) { var bo = getSelected(element, node); return bo && bo.definition && isList(bo.definition); } })); // parameter value (type = map) /////////////////////////////////////////////////////// entries.push(entryFactory.table({ id: idPrefix + 'parameterType-map', modelProperties: [ 'key', 'value' ], labels: [ translate('Key'), translate('Value') ], addLabel: translate('Add Entry'), getElements: function(element, node) { var bo = getSelected(element, node); if (bo && isMap(bo.definition)) { return bo.definition.entries; } return []; }, updateElement: function(element, values, node, idx) { var bo = getSelected(element, node); var entry = bo.definition.entries[idx]; if (isMap(entry.definition) || isList(entry.definition) || isScript(entry.definition)) { values = { key: values.key }; } return cmdHelper.updateBusinessObject(element, entry, values); }, addElement: function(element, node) { var bo = getSelected(element, node); var newEntry = createElement('activiti:Entry', bo.definition, bpmnFactory, { key: undefined, value: undefined }); return cmdHelper.addElementsTolist(element, bo.definition, 'entries', [ newEntry ]); }, removeElement: function(element, node, idx) { var bo = getSelected(element, node); return cmdHelper.removeElementsFromList(element, bo.definition, 'entries', null, [ bo.definition.entries[idx] ]); }, editable: function(element, node, prop, idx) { var bo = getSelected(element, node); var entry = bo.definition.entries[idx]; return prop === 'key' || (!isMap(entry.definition) && !isList(entry.definition) && !isScript(entry.definition)); }, setControlValue: function(element, node, input, prop, value, idx) { var bo = getSelected(element, node); var entry = bo.definition.entries[idx]; if (prop === 'key' || (!isMap(entry.definition) && !isList(entry.definition) && !isScript(entry.definition))) { input.value = value; } else { input.value = typeInfo[entry.definition.$type].label; } }, show: function(element, node) { var bo = getSelected(element, node); return bo && bo.definition && isMap(bo.definition); } })); return entries; }; },{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/InputOutputHelper":596,"./Script":657,"bpmn-js/lib/util/ModelUtil":141}],651:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function(element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var jobPriorityEntry = entryFactory.textField({ id: 'jobPriority', label: translate('Job Priority'), modelProperty: 'jobPriority', get: function(element, node) { var bo = getBusinessObject(element); return { jobPriority: bo.get('activiti:jobPriority') }; }, set: function(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'activiti:jobPriority': values.jobPriority || undefined }); } }); return [ jobPriorityEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],652:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is; var entryFactory = require('../../../../factory/EntryFactory'); var asyncCapableHelper = require('../../../../helper/AsyncCapableHelper'); var elementHelper = require('../../../../helper/ElementHelper'), eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'), cmdHelper = require('../../../../helper/CmdHelper'); function isAsyncBefore(bo) { return asyncCapableHelper.isAsyncBefore(bo); } function isAsyncAfter(bo) { return asyncCapableHelper.isAsyncAfter(bo); } function getFailedJobRetryTimeCycle(bo) { return asyncCapableHelper.getFailedJobRetryTimeCycle(bo); } function removeFailedJobRetryTimeCycle(bo, element) { return asyncCapableHelper.removeFailedJobRetryTimeCycle(bo, element); } function createExtensionElements(parent, bpmnFactory) { return elementHelper.createElement('bpmn:ExtensionElements', { values: [] }, parent, bpmnFactory); } function createFailedJobRetryTimeCycle(parent, bpmnFactory, cycle) { return elementHelper.createElement('activiti:FailedJobRetryTimeCycle', { body: cycle }, parent, bpmnFactory); } module.exports = function(element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var idPrefix = options.idPrefix || '', labelPrefix = options.labelPrefix || ''; var retryTimeCycleEntry = entryFactory.textField({ id: idPrefix + 'retryTimeCycle', label: labelPrefix + translate('Retry Time Cycle'), modelProperty: 'cycle', get: function(element, node) { var retryTimeCycle = getFailedJobRetryTimeCycle(getBusinessObject(element)); var value = retryTimeCycle && retryTimeCycle.get('body'); return { cycle: value }; }, set: function(element, values, node) { var newCycle = values.cycle; var bo = getBusinessObject(element); if (newCycle === '' || typeof newCycle === 'undefined') { // remove retry time cycle element(s) return removeFailedJobRetryTimeCycle(bo, element); } var retryTimeCycle = getFailedJobRetryTimeCycle(bo); if (!retryTimeCycle) { // add new retry time cycle element var commands = []; var extensionElements = bo.get('extensionElements'); if (!extensionElements) { extensionElements = createExtensionElements(bo, bpmnFactory); commands.push(cmdHelper.updateBusinessObject(element, bo, { extensionElements: extensionElements })); } retryTimeCycle = createFailedJobRetryTimeCycle(extensionElements, bpmnFactory, newCycle); commands.push(cmdHelper.addAndRemoveElementsFromList( element, extensionElements, 'values', 'extensionElements', [ retryTimeCycle ], [] )); return commands; } // update existing retry time cycle element return cmdHelper.updateBusinessObject(element, retryTimeCycle, { body: newCycle }); }, hidden: function(element) { var bo = getBusinessObject(element); if (bo && (isAsyncBefore(bo) || isAsyncAfter(bo))) { return false; } if (is(element, 'bpmn:Event')) { return !eventDefinitionHelper.getTimerEventDefinition(element); } return true; } }); return [ retryTimeCycleEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/AsyncCapableHelper":588,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/EventDefinitionHelper":592,"bpmn-js/lib/util/ModelUtil":141}],653:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var extensionElementsEntry = require('./ExtensionElements'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), cmdHelper = require('../../../../helper/CmdHelper'), elementHelper = require('../../../../helper/ElementHelper'), ImplementationTypeHelper = require('../../../../helper/ImplementationTypeHelper'); function getListeners(bo, type) { return bo && extensionElementsHelper.getExtensionElements(bo, type) || []; } var ACTIVITI_EXECUTION_LISTENER_ELEMENT = 'activiti:ExecutionListener'; var ACTIVITI_TASK_LISTENER_ELEMENT = 'activiti:TaskListener'; module.exports = function(element, bpmnFactory, options, translate) { var LISTENER_TYPE_LABEL = { class: translate('Java Class'), expression: translate('Expression'), delegateExpression: translate('Delegate Expression'), script: translate('Script') }; var bo; var result = { getSelectedListener: getSelectedListener }; var entries = result.entries = []; var isSequenceFlow = ImplementationTypeHelper.isSequenceFlow(element); function getSelectedListener(element, node) { var selection = (executionListenerEntry && executionListenerEntry.getSelected(element, node)) || { idx: -1 }; var listener = getListeners(bo, ACTIVITI_EXECUTION_LISTENER_ELEMENT)[selection.idx]; if (!listener && taskListenerEntry) { selection = taskListenerEntry.getSelected(element, node); listener = getListeners(bo, ACTIVITI_TASK_LISTENER_ELEMENT)[selection.idx]; } return listener; } var setOptionLabelValue = function(type) { return function(element, node, option, property, value, idx) { var listeners = getListeners(bo, type); var listener = listeners[idx]; var listenerType = ImplementationTypeHelper.getImplementationType(listener); var event = (listener.get('event')) ? listener.get('event') : '<empty>'; var label = (event || '*') + ' : ' + (LISTENER_TYPE_LABEL[listenerType] || ''); option.text = label; }; }; var newElement = function(element, type, initialEvent) { return function(element, extensionElements, value) { var props = { event: initialEvent, class: '' }; var newElem = elementHelper.createElement(type, props, extensionElements, bpmnFactory); return cmdHelper.addElementsTolist(element, extensionElements, 'values', [ newElem ]); }; }; var removeElement = function(element, type) { return function(element, extensionElements, value, idx) { var listeners = getListeners(bo, type); var listener = listeners[idx]; if (listener) { return extensionElementsHelper.removeEntry(bo, element, listener); } }; }; // Execution Listener if (is(element, 'bpmn:FlowElement') || is(element, 'bpmn:Process') || is(element, 'bpmn:Participant')) { bo = getBusinessObject(element); if (is(element, 'bpmn:Participant')) { element = element.processRef; bo = bo.get('processRef'); } if (bo) { var executionListenerEntry = extensionElementsEntry(element, bpmnFactory, { id : 'executionListeners', label : translate('Execution Listener'), modelProperty: 'name', idGeneration: 'false', reference: 'processRef', createExtensionElement: newElement(element, ACTIVITI_EXECUTION_LISTENER_ELEMENT, (isSequenceFlow) ? 'take' : 'start'), removeExtensionElement: removeElement(element, ACTIVITI_EXECUTION_LISTENER_ELEMENT), getExtensionElements: function(element) { return getListeners(bo, ACTIVITI_EXECUTION_LISTENER_ELEMENT); }, onSelectionChange: function(element, node, event, scope) { taskListenerEntry && taskListenerEntry.deselect(element, node); }, setOptionLabelValue: setOptionLabelValue(ACTIVITI_EXECUTION_LISTENER_ELEMENT) }); entries.push(executionListenerEntry); } } // Task Listener if (is(element, 'bpmn:UserTask')) { bo = getBusinessObject(element); var taskListenerEntry = extensionElementsEntry(element, bpmnFactory, { id : 'taskListeners', label : translate('Task Listener'), modelProperty: 'name', idGeneration: 'false', createExtensionElement: newElement(element, ACTIVITI_TASK_LISTENER_ELEMENT, 'create'), removeExtensionElement: removeElement(element, ACTIVITI_TASK_LISTENER_ELEMENT), getExtensionElements: function(element) { return getListeners(bo, ACTIVITI_TASK_LISTENER_ELEMENT); }, onSelectionChange: function(element, node, event, scope) { executionListenerEntry.deselect(element, node); }, setOptionLabelValue: setOptionLabelValue(ACTIVITI_TASK_LISTENER_ELEMENT) }); entries.push(taskListenerEntry); } return result; }; },{"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"../../../../helper/ImplementationTypeHelper":595,"./ExtensionElements":643,"bpmn-js/lib/util/ModelUtil":141}],654:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, escapeHTML = require('../../../../Utils').escapeHTML; var entryFactory = require('../../../../factory/EntryFactory'); var elementHelper = require('../../../../helper/ElementHelper'), cmdHelper = require('../../../../helper/CmdHelper'); var domClasses = require('min-dom').classes; /** * Get a property value of the loop characteristics. * * @param {djs.model.Base} element * @param {string} propertyName * * @return {any} the property value */ function getProperty(element, propertyName) { var loopCharacteristics = getLoopCharacteristics(element); return loopCharacteristics && loopCharacteristics.get(propertyName); } /** * Get the body of a given expression. * * @param {ModdleElement<bpmn:FormalExpression>} expression * * @return {string} the body (value) of the expression */ function getBody(expression) { return expression && expression.get('body'); } /** * Get the loop characteristics of an element. * * @param {djs.model.Base} element * * @return {ModdleElement<bpmn:MultiInstanceLoopCharacteristics>} the loop characteristics */ function getLoopCharacteristics(element) { var bo = getBusinessObject(element); return bo.loopCharacteristics; } /** * Get the loop cardinality of the loop characteristics. * * @param {djs.model.Base} element * * @return {ModdleElement<bpmn:FormalExpression>} an expression representing the loop cardinality */ function getLoopCardinality(element) { return getProperty(element, 'loopCardinality'); } /** * Get the loop cardinality value of the loop characteristics. * * @param {djs.model.Base} element * * @return {string} the loop cardinality value */ function getLoopCardinalityValue(element) { var loopCardinality = getLoopCardinality(element); return getBody(loopCardinality); } /** * Get the completion condition of the loop characteristics. * * @param {djs.model.Base} element * * @return {ModdleElement<bpmn:FormalExpression>} an expression representing the completion condition */ function getCompletionCondition(element) { return getProperty(element, 'completionCondition'); } /** * Get the completion condition value of the loop characteristics. * * @param {djs.model.Base} element * * @return {string} the completion condition value */ function getCompletionConditionValue(element) { var completionCondition = getCompletionCondition(element); return getBody(completionCondition); } /** * Get the 'activiti:collection' attribute value of the loop characteristics. * * @param {djs.model.Base} element * * @return {string} the 'activiti:collection' value */ function getCollection(element) { return getProperty(element, 'activiti:collection'); } /** * Get the 'activiti:elementVariable' attribute value of the loop characteristics. * * @param {djs.model.Base} element * * @return {string} the 'activiti:elementVariable' value */ function getElementVariable(element) { return getProperty(element, 'activiti:elementVariable'); } /** * Creates 'bpmn:FormalExpression' element. * * @param {ModdleElement} parent * @param {string} body * @param {BpmnFactory} bpmnFactory * * @result {ModdleElement<bpmn:FormalExpression>} a formal expression */ function createFormalExpression(parent, body, bpmnFactory) { return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory); } /** * Updates a specific formal expression of the loop characteristics. * * @param {djs.model.Base} element * @param {string} propertyName * @param {string} newValue * @param {BpmnFactory} bpmnFactory */ function updateFormalExpression(element, propertyName, newValue, bpmnFactory) { var loopCharacteristics = getLoopCharacteristics(element); var expressionProps = {}; if (!newValue) { // remove formal expression expressionProps[propertyName] = undefined; return cmdHelper.updateBusinessObject(element, loopCharacteristics, expressionProps); } var existingExpression = loopCharacteristics.get(propertyName); if (!existingExpression) { // add formal expression expressionProps[propertyName] = createFormalExpression(loopCharacteristics, newValue, bpmnFactory); return cmdHelper.updateBusinessObject(element, loopCharacteristics, expressionProps); } // edit existing formal expression return cmdHelper.updateBusinessObject(element, existingExpression, { body: newValue }); } module.exports = function(element, bpmnFactory, translate) { var entries = []; // error message ///////////////////////////////////////////////////////////////// entries.push({ id: 'multiInstance-errorMessage', html: '<div data-show="isValid">' + '<span class="bpp-icon-warning"></span> ' + escapeHTML(translate('Must provide either loop cardinality or collection')) + '</div>', isValid: function(element, node, notification, scope) { var loopCharacteristics = getLoopCharacteristics(element); var isValid = true; if (loopCharacteristics) { var loopCardinality = getLoopCardinalityValue(element); var collection = getCollection(element); isValid = !loopCardinality && !collection; } domClasses(node).toggle('bpp-hidden', !isValid); domClasses(notification).toggle('bpp-error-message', isValid); return isValid; } }); // loop cardinality ////////////////////////////////////////////////////////////// entries.push(entryFactory.textField({ id: 'multiInstance-loopCardinality', label: translate('Loop Cardinality'), modelProperty: 'loopCardinality', get: function(element, node) { return { loopCardinality: getLoopCardinalityValue(element) }; }, set: function(element, values) { return updateFormalExpression(element, 'loopCardinality', values.loopCardinality, bpmnFactory); } })); // collection ////////////////////////////////////////////////////////////////// entries.push(entryFactory.textField({ id: 'multiInstance-collection', label: translate('Collection'), modelProperty: 'collection', get: function(element, node) { return { collection: getCollection(element) }; }, set: function(element, values) { var loopCharacteristics = getLoopCharacteristics(element); return cmdHelper.updateBusinessObject(element, loopCharacteristics, { 'activiti:collection': values.collection || undefined }); }, validate: function(element, values, node) { var collection = getCollection(element); var elementVariable = getElementVariable(element); if (!collection && elementVariable) { return { collection : 'Must provide a value' }; } } })); // element variable //////////////////////////////////////////////////////////// entries.push(entryFactory.textField({ id: 'multiInstance-elementVariable', label: translate('Element Variable'), modelProperty: 'elementVariable', get: function(element, node) { return { elementVariable: getElementVariable(element) }; }, set: function(element, values) { var loopCharacteristics = getLoopCharacteristics(element); return cmdHelper.updateBusinessObject(element, loopCharacteristics, { 'activiti:elementVariable': values.elementVariable || undefined }); } })); // Completion Condition ////////////////////////////////////////////////////// entries.push(entryFactory.textField({ id: 'multiInstance-completionCondition', label: translate('Completion Condition'), modelProperty: 'completionCondition', get: function(element) { return { completionCondition: getCompletionConditionValue(element) }; }, set: function(element, values) { return updateFormalExpression(element, 'completionCondition', values.completionCondition, bpmnFactory); } })); return entries; }; },{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"bpmn-js/lib/util/ModelUtil":141,"min-dom":556}],655:[function(require,module,exports){ 'use strict'; var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is; var factory = require('../../../../factory/EntryFactory'); var elementHelper = require('../../../../helper/ElementHelper'), extensionElementsHelper = require('../../../../helper/ExtensionElementsHelper'), cmdHelper = require('../../../../helper/CmdHelper'), utils = require('../../../../Utils'); var assign = require('lodash/assign'), forEach = require('lodash/forEach'), find = require('lodash/find'); function generatePropertyId() { return utils.nextId('Property_'); } /** * Get all activiti:property objects for a specific business object * * @param {ModdleElement} parent * * @return {Array<ModdleElement>} a list of activiti:property objects */ function getPropertyValues(parent) { var properties = parent && getPropertiesElement(parent); if (properties && properties.values) { return properties.values; } return []; } /** * Get all activiti:Properties object for a specific business object * * @param {ModdleElement} parent * * @return {ModdleElement} a activiti:Properties object */ function getPropertiesElement(element) { if (!isExtensionElements(element)) { return element.properties; } else { return getPropertiesElementInsideExtensionElements(element); } } /** * Get first activiti:Properties object for a specific bpmn:ExtensionElements * business object. * * @param {ModdleElement} extensionElements * * @return {ModdleElement} a activiti:Properties object */ function getPropertiesElementInsideExtensionElements(extensionElements) { return find(extensionElements.values, function(elem) { return is(elem, 'activiti:Properties'); }); } /** * Returns true, if the given business object is a bpmn:ExtensionElements. * * @param {ModdleElement} element * * @return {boolean} a boolean value */ function isExtensionElements(element) { return is(element, 'bpmn:ExtensionElements'); } /** * Create a activiti:property entry using tableEntryFactory * * @param {djs.model.Base} element * @param {BpmnFactory} bpmnFactory * @param {Object} options * @param {string} options.id * @param {Array<string>} options.modelProperties * @param {Array<string>} options.labels * @param {function} options.getParent Gets the parent business object * @param {function} options.show Indicate when the entry will be shown, should return boolean */ module.exports = function(element, bpmnFactory, options, translate) { var getParent = options.getParent; var modelProperties = options.modelProperties, createParent = options.createParent; var bo = getBusinessObject(element); if (is(element, 'bpmn:Participant')) { bo = bo.get('processRef'); } // build properties group only when the participant have a processRef if (!bo) { return; } assign(options, { addLabel: translate('Add Property'), getElements: function(element, node) { var parent = getParent(element, node, bo); return getPropertyValues(parent); }, addElement: function(element, node) { var commands = [], parent = getParent(element, node, bo); if (!parent && typeof createParent === 'function') { var result = createParent(element, bo); parent = result.parent; commands.push(result.cmd); } var properties = getPropertiesElement(parent); if (!properties) { properties = elementHelper.createElement('activiti:Properties', {}, parent, bpmnFactory); if (!isExtensionElements(parent)) { commands.push(cmdHelper.updateBusinessObject(element, parent, { 'properties': properties })); } else { commands.push(cmdHelper.addAndRemoveElementsFromList( element, parent, 'values', 'extensionElements', [ properties ], [] )); } } var propertyProps = {}; forEach(modelProperties, function(prop) { propertyProps[prop] = undefined; }); // create id if necessary if (modelProperties.indexOf('id') >= 0) { propertyProps.id = generatePropertyId(); } var property = elementHelper.createElement('activiti:Property', propertyProps, properties, bpmnFactory); commands.push(cmdHelper.addElementsTolist(element, properties, 'values', [ property ])); return commands; }, updateElement: function(element, value, node, idx) { var parent = getParent(element, node, bo), property = getPropertyValues(parent)[idx]; forEach(modelProperties, function(prop) { value[prop] = value[prop] || undefined; }); return cmdHelper.updateBusinessObject(element, property, value); }, validate: function(element, value, node, idx) { // validate id if necessary if (modelProperties.indexOf('id') >= 0) { var parent = getParent(element, node, bo), properties = getPropertyValues(parent), property = properties[idx]; if (property) { // check if id is valid var validationError = utils.isIdValid(property, value.id, translate); if (validationError) { return { id: validationError }; } } } }, removeElement: function(element, node, idx) { var commands = [], parent = getParent(element, node, bo), properties = getPropertiesElement(parent), propertyValues = getPropertyValues(parent), currentProperty = propertyValues[idx]; commands.push(cmdHelper.removeElementsFromList(element, properties, 'values', null, [ currentProperty ])); if (propertyValues.length === 1) { // remove activiti:properties if the last existing property has been removed if (!isExtensionElements(parent)) { commands.push(cmdHelper.updateBusinessObject(element, parent, { properties: undefined })); } else { forEach(parent.values, function(value) { if (is(value, 'activiti:Properties')) { commands.push(extensionElementsHelper.removeEntry(bo, element, value)); } }); } } return commands; } }); return factory.table(options); }; },{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"../../../../helper/ExtensionElementsHelper":593,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513,"lodash/find":519,"lodash/forEach":522}],656:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is; var assign = require('lodash/assign'); var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function(element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject, hideResultVariable = options.hideResultVariable, id = options.id || 'resultVariable'; var resultVariableEntry = entryFactory.textField({ id: id, label: translate('Result Variable'), modelProperty: 'resultVariable', get: function(element, node) { var bo = getBusinessObject(element); return { resultVariable: bo.get('activiti:resultVariable') }; }, set: function(element, values, node) { var bo = getBusinessObject(element); var resultVariable = values.resultVariable || undefined; var props = { 'activiti:resultVariable': resultVariable }; if (is(bo, 'activiti:DmnCapable') && !resultVariable) { props = assign({ 'activiti:mapDecisionResult': 'resultList' }, props); } return cmdHelper.updateBusinessObject(element, bo, props); }, hidden: function(element, node) { if (typeof hideResultVariable === 'function') { return hideResultVariable.apply(resultVariableEntry, arguments); } } }); return [ resultVariableEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141,"lodash/assign":513}],657:[function(require,module,exports){ 'use strict'; var domQuery = require('min-dom').query, escapeHTML = require('../../../../Utils').escapeHTML, utils = require('../../../../Utils'); function getScriptType(node) { return utils.selectedType('select[name=scriptType]', node.parentElement); } module.exports = function(scriptLanguagePropName, scriptValuePropName, isFormatRequired, translate) { return { template: '<div class="bpp-row bpp-textfield">' + '<label for="cam-script-format">' + escapeHTML(translate('Script Format')) + '</label>' + '<div class="bpp-field-wrapper">' + '<input id="cam-script-format" type="text" name="scriptFormat" />' + '<button class="clear" data-action="script.clearScriptFormat" data-show="script.canClearScriptFormat">' + '<span>X</span>' + '</button>' + '</div>' + '</div>' + '<div class="bpp-row">' + '<label for="cam-script-type">' + escapeHTML(translate('Script Type')) + '</label>' + '<div class="bpp-field-wrapper">' + '<select id="cam-script-type" name="scriptType" data-value>' + '<option value="script" selected>' + escapeHTML(translate('Inline Script')) + '</option>' + '<option value="scriptResource">' + escapeHTML(translate('External Resource')) + '</option>' + '</select>' + '</div>' + '</div>' + '<div class="bpp-row bpp-textfield">' + '<label for="cam-script-resource-val" data-show="script.isScriptResource">' + escapeHTML(translate('Resource')) + '</label>' + '<div class="bpp-field-wrapper" data-show="script.isScriptResource">' + '<input id="cam-script-resource-val" type="text" name="scriptResourceValue" />' + '<button class="clear" data-action="script.clearScriptResource" data-show="script.canClearScriptResource">' + '<span>X</span>' + '</button>' + '</div>' + '</div>' + '<div class="bpp-row">' + '<label for="cam-script-val" data-show="script.isScript">' + escapeHTML(translate('Script')) + '</label>' + '<div class="bpp-field-wrapper" data-show="script.isScript">' + '<textarea id="cam-script-val" type="text" name="scriptValue"></textarea>' + '</div>'+ '</div>', get: function(element, bo) { var values = {}; // read values from xml: var boScriptResource = bo.get('activiti:resource'), boScript = bo.get(scriptValuePropName), boScriptFormat = bo.get(scriptLanguagePropName); if (typeof boScriptResource !== 'undefined') { values.scriptResourceValue = boScriptResource; values.scriptType = 'scriptResource'; } else { values.scriptValue = boScript; values.scriptType = 'script'; } values.scriptFormat = boScriptFormat; return values; }, set: function(element, values, containerElement) { var scriptFormat = values.scriptFormat, scriptType = values.scriptType, scriptResourceValue = values.scriptResourceValue, scriptValue = values.scriptValue; // init update var update = { 'activiti:resource': undefined }; update[scriptValuePropName] = undefined; update[scriptLanguagePropName] = undefined; if (isFormatRequired) { // always set language update[scriptLanguagePropName] = scriptFormat || ''; } else // set language only when scriptFormat has a value if (scriptFormat !== '') { update[scriptLanguagePropName] = scriptFormat; } // set either inline script or resource if ('scriptResource' === scriptType) { update['activiti:resource'] = scriptResourceValue || ''; } else { update[scriptValuePropName] = scriptValue || ''; } return update; }, validate: function(element, values) { var validationResult = {}; if (values.scriptType === 'script' && !values.scriptValue) { validationResult.scriptValue = translate('Must provide a value'); } if (values.scriptType === 'scriptResource' && !values.scriptResourceValue) { validationResult.scriptResourceValue = translate('Must provide a value'); } if (isFormatRequired && (!values.scriptFormat || values.scriptFormat.length === 0)) { validationResult.scriptFormat = translate('Must provide a value'); } return validationResult; }, clearScriptFormat: function(element, inputNode, btnNode, scopeNode) { domQuery('input[name=scriptFormat]', scopeNode).value=''; return true; }, canClearScriptFormat: function(element, inputNode, btnNode, scopeNode) { var input = domQuery('input[name=scriptFormat]', scopeNode); return input.value !== ''; }, clearScriptResource: function(element, inputNode, btnNode, scopeNode) { domQuery('input[name=scriptResourceValue]', scopeNode).value=''; return true; }, canClearScriptResource: function(element, inputNode, btnNode, scopeNode) { var input = domQuery('input[name=scriptResourceValue]', scopeNode); return input.value !== ''; }, clearScript: function(element, inputNode, btnNode, scopeNode) { domQuery('textarea[name=scriptValue]', scopeNode).value=''; return true; }, canClearScript: function(element, inputNode, btnNode, scopeNode) { var input = domQuery('textarea[name=scriptValue]', scopeNode); return input.value !== ''; }, isScriptResource: function(element, inputNode, btnNode, scopeNode) { var scriptType = getScriptType(scopeNode); return scriptType === 'scriptResource'; }, isScript: function(element, inputNode, btnNode, scopeNode) { var scriptType = getScriptType(scopeNode); return scriptType === 'script'; } }; }; },{"../../../../Utils":576,"min-dom":556}],658:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); module.exports = function(element, bpmnFactory, options, translate) { var getBusinessObject = options.getBusinessObject; var isStartableInTasklistEntry = entryFactory.checkbox({ id: 'isStartableInTasklist', label: translate('Startable'), modelProperty: 'isStartableInTasklist', get: function(element, node) { var bo = getBusinessObject(element); var isStartableInTasklist = bo.get('activiti:isStartableInTasklist'); return { isStartableInTasklist: isStartableInTasklist ? isStartableInTasklist : '' }; }, set: function(element, values) { var bo = getBusinessObject(element); return cmdHelper.updateBusinessObject(element, bo, { 'activiti:isStartableInTasklist': !!values.isStartableInTasklist }); } }); return [ isStartableInTasklistEntry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],659:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'); var ModelUtil = require('bpmn-js/lib/util/ModelUtil'), is = ModelUtil.is, getBusinessObject = ModelUtil.getBusinessObject; module.exports = function(group, element, bpmnFactory, translate) { var getValue = function(businessObject) { return function(element) { var documentations = businessObject && businessObject.get('documentation'), text = (documentations && documentations.length > 0) ? documentations[0].text : ''; return { documentation: text }; }; }; var setValue = function(businessObject) { return function(element, values) { var newObjectList = []; if (typeof values.documentation !== 'undefined' && values.documentation !== '') { newObjectList.push(bpmnFactory.create('bpmn:Documentation', { text: values.documentation })); } return cmdHelper.setList(element, businessObject, 'documentation', newObjectList); }; }; // Element Documentation var elementDocuEntry = entryFactory.textBox({ id: 'documentation', label: translate('Element Documentation'), modelProperty: 'documentation' }); elementDocuEntry.set = setValue(getBusinessObject(element)); elementDocuEntry.get = getValue(getBusinessObject(element)); group.entries.push(elementDocuEntry); var processRef; // Process Documentation when having a Collaboration Diagram if (is(element, 'bpmn:Participant')) { processRef = getBusinessObject(element).processRef; // do not show for collapsed Pools/Participants if (processRef) { var processDocuEntry = entryFactory.textBox({ id: 'process-documentation', label: translate('Process Documentation'), modelProperty: 'documentation' }); processDocuEntry.set = setValue(processRef); processDocuEntry.get = getValue(processRef); group.entries.push(processDocuEntry); } } }; },{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141}],660:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, isAny = require('bpmn-js/lib/features/modeling/util/ModelingUtil').isAny, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, eventDefinitionHelper = require('../../../helper/EventDefinitionHelper'); var forEach = require('lodash/forEach'); var message = require('./implementation/MessageEventDefinition'), signal = require('./implementation/SignalEventDefinition'), error = require('./implementation/ErrorEventDefinition'), escalation = require('./implementation/EscalationEventDefinition'), timer = require('./implementation/TimerEventDefinition'), compensation = require('./implementation/CompensateEventDefinition'), condition = require('./implementation/ConditionalEventDefinition'); module.exports = function(group, element, bpmnFactory, elementRegistry, translate) { var events = [ 'bpmn:StartEvent', 'bpmn:EndEvent', 'bpmn:IntermediateThrowEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateCatchEvent' ]; // Message and Signal Event Definition forEach(events, function(event) { if (is(element, event)) { var messageEventDefinition = eventDefinitionHelper.getMessageEventDefinition(element), signalEventDefinition = eventDefinitionHelper.getSignalEventDefinition(element); if (messageEventDefinition) { message(group, element, bpmnFactory, messageEventDefinition, translate); } if (signalEventDefinition) { signal(group, element, bpmnFactory, signalEventDefinition, translate); } } }); // Special Case: Receive Task if (is(element, 'bpmn:ReceiveTask')) { message(group, element, bpmnFactory, getBusinessObject(element), translate); } // Error Event Definition var errorEvents = [ 'bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:EndEvent' ]; forEach(errorEvents, function(event) { if (is(element, event)) { var errorEventDefinition = eventDefinitionHelper.getErrorEventDefinition(element); if (errorEventDefinition) { error(group, element, bpmnFactory, errorEventDefinition, translate); } } }); // Escalation Event Definition var escalationEvents = [ 'bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateThrowEvent', 'bpmn:EndEvent' ]; forEach(escalationEvents, function(event) { if (is(element, event)) { var showEscalationCodeVariable = is(element, 'bpmn:StartEvent') || is(element, 'bpmn:BoundaryEvent'); // get business object var escalationEventDefinition = eventDefinitionHelper.getEscalationEventDefinition(element); if (escalationEventDefinition) { escalation(group, element, bpmnFactory, escalationEventDefinition, showEscalationCodeVariable, translate); } } }); // Timer Event Definition var timerEvents = [ 'bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateCatchEvent' ]; forEach(timerEvents, function(event) { if (is(element, event)) { // get business object var timerEventDefinition = eventDefinitionHelper.getTimerEventDefinition(element); if (timerEventDefinition) { timer(group, element, bpmnFactory, timerEventDefinition, translate); } } }); // Compensate Event Definition var compensationEvents = [ 'bpmn:EndEvent', 'bpmn:IntermediateThrowEvent' ]; forEach(compensationEvents, function(event) { if (is(element, event)) { // get business object var compensateEventDefinition = eventDefinitionHelper.getCompensateEventDefinition(element); if (compensateEventDefinition) { compensation(group, element, bpmnFactory, compensateEventDefinition, elementRegistry, translate); } } }); // Conditional Event Definition var conditionalEvents = [ 'bpmn:StartEvent', 'bpmn:BoundaryEvent', 'bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent' ]; if (isAny(element, conditionalEvents)) { // get business object var conditionalEventDefinition = eventDefinitionHelper.getConditionalEventDefinition(element); if (conditionalEventDefinition) { condition(group, element, bpmnFactory, conditionalEventDefinition, elementRegistry, translate); } } }; },{"../../../helper/EventDefinitionHelper":592,"./implementation/CompensateEventDefinition":666,"./implementation/ConditionalEventDefinition":667,"./implementation/ErrorEventDefinition":669,"./implementation/EscalationEventDefinition":670,"./implementation/MessageEventDefinition":672,"./implementation/SignalEventDefinition":674,"./implementation/TimerEventDefinition":675,"bpmn-js/lib/features/modeling/util/ModelingUtil":112,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],661:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; var entryFactory = require('../../../factory/EntryFactory'); var participantHelper = require('../../../helper/ParticipantHelper'); module.exports = function(group, element, translate) { var bo = getBusinessObject(element); if (!bo) { return; } if (is(element, 'bpmn:Process') || (is(element, 'bpmn:Participant') && bo.get('processRef'))) { var executableEntry = entryFactory.checkbox({ id: 'process-is-executable', label: translate('Executable'), modelProperty: 'isExecutable' }); // in participants we have to change the default behavior of set and get if (is(element, 'bpmn:Participant')) { executableEntry.get = function(element) { return participantHelper.getProcessBusinessObject(element, 'isExecutable'); }; executableEntry.set = function(element, values) { return participantHelper.modifyProcessBusinessObject(element, 'isExecutable', values); }; } group.entries.push(executableEntry); } }; },{"../../../factory/EntryFactory":579,"../../../helper/ParticipantHelper":597,"bpmn-js/lib/util/ModelUtil":141}],662:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../factory/EntryFactory'), getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, utils = require('../../../Utils'), cmdHelper = require('../../../helper/CmdHelper'); module.exports = function(group, element, translate, options) { var description = options && options.description; // Id group.entries.push(entryFactory.validationAwareTextField({ id: 'id', label: translate('Id'), description: description && translate(description), modelProperty: 'id', getProperty: function(element) { return getBusinessObject(element).id; }, setProperty: function(element, properties) { element = element.labelTarget || element; return cmdHelper.updateProperties(element, properties); }, validate: function(element, values) { var idValue = values.id; var bo = getBusinessObject(element); var idError = utils.isIdValid(bo, idValue, translate); return idError ? { id: idError } : {}; } })); }; },{"../../../Utils":576,"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141}],663:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, entryFactory = require('../../../factory/EntryFactory'), cmdHelper = require('../../../helper/CmdHelper'); var forEach = require('lodash/forEach'); function getLinkEventDefinition(element) { var bo = getBusinessObject(element); var linkEventDefinition = null; if (bo.eventDefinitions) { forEach(bo.eventDefinitions, function(eventDefinition) { if (is(eventDefinition, 'bpmn:LinkEventDefinition')) { linkEventDefinition = eventDefinition; } }); } return linkEventDefinition; } module.exports = function(group, element, translate) { var linkEvents = [ 'bpmn:IntermediateThrowEvent', 'bpmn:IntermediateCatchEvent' ]; forEach(linkEvents, function(event) { if (is(element, event)) { var linkEventDefinition = getLinkEventDefinition(element); if (linkEventDefinition) { var entry = entryFactory.textField({ id: 'link-event', label: translate('Link Name'), modelProperty: 'link-name' }); entry.get = function() { return { 'link-name': linkEventDefinition.get('name') }; }; entry.set = function(element, values) { var newProperties = { name: values['link-name'] }; return cmdHelper.updateBusinessObject(element, linkEventDefinition, newProperties); }; group.entries.push(entry); } } }); }; },{"../../../factory/EntryFactory":579,"../../../helper/CmdHelper":590,"bpmn-js/lib/util/ModelUtil":141,"lodash/forEach":522}],664:[function(require,module,exports){ 'use strict'; var nameEntryFactory = require('./implementation/Name'), createCategoryValue = require('../../../helper/CategoryHelper').createCategoryValue, is = require('bpmn-js/lib/util/ModelUtil').is, getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject; module.exports = function(group, element, bpmnFactory, canvas, translate) { function initializeCategory(semantic) { var rootElement = canvas.getRootElement(), definitions = getBusinessObject(rootElement).$parent, categoryValue = createCategoryValue(definitions, bpmnFactory); semantic.categoryValueRef = categoryValue; } function setGroupName(element, values) { var bo = getBusinessObject(element), categoryValueRef = bo.categoryValueRef; if (!categoryValueRef) { initializeCategory(bo); } // needs direct call to update categoryValue properly return { cmd: 'element.updateLabel', context: { element: element, newLabel: values.categoryValue } }; } function getGroupName(element) { var bo = getBusinessObject(element), value = (bo.categoryValueRef || {}).value; return { categoryValue: value }; } if (!is(element, 'bpmn:Collaboration')) { var options; if (is(element, 'bpmn:TextAnnotation')) { options = { modelProperty: 'text', label: translate('Text') }; } else if (is(element, 'bpmn:Group')) { options = { modelProperty: 'categoryValue', label: translate('Category Value'), get: getGroupName, set: setGroupName }; } // name group.entries = group.entries.concat(nameEntryFactory(element, options, translate)); } }; },{"../../../helper/CategoryHelper":589,"./implementation/Name":673,"bpmn-js/lib/util/ModelUtil":141}],665:[function(require,module,exports){ 'use strict'; var is = require('bpmn-js/lib/util/ModelUtil').is, entryFactory = require('../../../factory/EntryFactory'), participantHelper = require('../../../helper/ParticipantHelper'), getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, nameEntryFactory = require('./implementation/Name'), utils = require('../../../Utils'); module.exports = function(group, element, translate, options) { var businessObject = getBusinessObject(element); var processIdDescription = options && options.processIdDescription; if (is(element, 'bpmn:Process') || (is(element, 'bpmn:Participant') && businessObject.get('processRef'))) { /** * processId */ if (is(element, 'bpmn:Participant')) { var idEntry = entryFactory.validationAwareTextField({ id: 'process-id', label: translate('Process Id'), description: processIdDescription && translate(processIdDescription), modelProperty: 'processId' }); // in participants we have to change the default behavior of set and get idEntry.get = function(element) { var properties = participantHelper.getProcessBusinessObject(element, 'id'); return { processId: properties.id }; }; idEntry.set = function(element, values) { return participantHelper.modifyProcessBusinessObject(element, 'id', { id: values.processId }); }; idEntry.validate = function(element, values) { var idValue = values.processId; var bo = getBusinessObject(element); var processIdError = utils.isIdValid(bo.processRef, idValue, translate); return processIdError ? { processId: processIdError } : {}; }; group.entries.push(idEntry); /** * process name */ var processNameEntry = nameEntryFactory(element, { id: 'process-name', label: translate('Process Name') })[0]; // in participants we have to change the default behavior of set and get processNameEntry.get = function(element) { return participantHelper.getProcessBusinessObject(element, 'name'); }; processNameEntry.set = function(element, values) { return participantHelper.modifyProcessBusinessObject(element, 'name', values); }; group.entries.push(processNameEntry); } } }; },{"../../../Utils":576,"../../../factory/EntryFactory":579,"../../../helper/ParticipantHelper":597,"./implementation/Name":673,"bpmn-js/lib/util/ModelUtil":141}],666:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'), eventDefinitionHelper = require('../../../../helper/EventDefinitionHelper'), utils = require('../../../../Utils'); var getBusinessObject = require('bpmn-js/lib/util/ModelUtil').getBusinessObject, is = require('bpmn-js/lib/util/ModelUtil').is; var forEach = require('lodash/forEach'), find = require('lodash/find'), filter = require('lodash/filter'); function getContainedActivities(element) { return getFlowElements(element, 'bpmn:Activity'); } function getContainedBoundaryEvents(element) { return getFlowElements(element, 'bpmn:BoundaryEvent'); } function getFlowElements(element, type) { return utils.filterElementsByType(element.flowElements, type); } function isCompensationEventAttachedToActivity(activity, boundaryEvents) { var activityId = activity.id; var boundaryEvent = find(boundaryEvents, function(boundaryEvent) { var compensateEventDefinition = eventDefinitionHelper.getCompensateEventDefinition(boundaryEvent); var attachedToRef = boundaryEvent.attachedToRef; return compensateEventDefinition && attachedToRef && attachedToRef.id === activityId; }); return !!boundaryEvent; } // subprocess: only when it is not triggeredByEvent // activity: only when it attach a compensation boundary event // callActivity: no limitation function canActivityBeCompensated(activity, boundaryEvents) { return (is(activity, 'bpmn:SubProcess') && !activity.triggeredByEvent) || is(activity, 'bpmn:CallActivity') || isCompensationEventAttachedToActivity(activity, boundaryEvents); } function getActivitiesForCompensation(element) { var boundaryEvents = getContainedBoundaryEvents(element); return filter(getContainedActivities(element), function(activity) { return canActivityBeCompensated(activity, boundaryEvents); }); } function getActivitiesForActivityRef(element) { var bo = getBusinessObject(element); var parent = bo.$parent; var activitiesForActivityRef = getActivitiesForCompensation(parent); // if throwing compensation event is in an event sub process: // get also all activities outside of the event sub process if (is(parent, 'bpmn:SubProcess') && parent.triggeredByEvent) { parent = parent.$parent; if (parent) { activitiesForActivityRef = activitiesForActivityRef.concat(getActivitiesForCompensation(parent)); } } return activitiesForActivityRef; } function createActivityRefOptions(element) { var options = [ { value: '' } ]; var activities = getActivitiesForActivityRef(element); forEach(activities, function(activity) { var activityId = activity.id; var name = (activity.name ? (activity.name + ' ') : '') + '(id=' + activityId + ')'; options.push({ value: activityId, name: name }); }); return options; } module.exports = function(group, element, bpmnFactory, compensateEventDefinition, elementRegistry, translate) { group.entries.push(entryFactory.checkbox({ id: 'wait-for-completion', label: translate('Wait for Completion'), modelProperty: 'waitForCompletion', get: function(element, node) { return { waitForCompletion: compensateEventDefinition.waitForCompletion }; }, set: function(element, values) { values.waitForCompletion = values.waitForCompletion || false; return cmdHelper.updateBusinessObject(element, compensateEventDefinition, values); } })); group.entries.push(entryFactory.selectBox({ id: 'activity-ref', label: translate('Activity Ref'), selectOptions: createActivityRefOptions(element), modelProperty: 'activityRef', get: function(element, node) { var activityRef = compensateEventDefinition.activityRef; activityRef = activityRef && activityRef.id; return { activityRef: activityRef || '' }; }, set: function(element, values) { var activityRef = values.activityRef || undefined; activityRef = activityRef && getBusinessObject(elementRegistry.get(activityRef)); return cmdHelper.updateBusinessObject(element, compensateEventDefinition, { activityRef: activityRef }); } })); }; },{"../../../../Utils":576,"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/EventDefinitionHelper":592,"bpmn-js/lib/util/ModelUtil":141,"lodash/filter":518,"lodash/find":519,"lodash/forEach":522}],667:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); var is = require('bpmn-js/lib/util/ModelUtil').is, isEventSubProcess = require('bpmn-js/lib/util/DiUtil').isEventSubProcess; module.exports = function(group, element, bpmnFactory, conditionalEventDefinition, elementRegistry, translate) { var getValue = function(modelProperty) { return function(element) { var modelPropertyValue = conditionalEventDefinition.get('camunda:' + modelProperty); var value = {}; value[modelProperty] = modelPropertyValue; return value; }; }; var setValue = function(modelProperty) { return function(element, values) { var props = {}; props['camunda:' + modelProperty] = values[modelProperty] || undefined; return cmdHelper.updateBusinessObject(element, conditionalEventDefinition, props); }; }; group.entries.push(entryFactory.textField({ id: 'variableName', label: translate('Variable Name'), modelProperty : 'variableName', get: getValue('variableName'), set: setValue('variableName') })); var isConditionalStartEvent = is(element, 'bpmn:StartEvent') && !isEventSubProcess(element.parent); if (!isConditionalStartEvent) { group.entries.push(entryFactory.textField({ id: 'variableEvent', label: translate('Variable Event'), description: translate('Specify more than one variable change event as a comma separated list.'), modelProperty : 'variableEvent', get: getValue('variableEvent'), set: setValue('variableEvent') })); } }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"bpmn-js/lib/util/DiUtil":139,"bpmn-js/lib/util/ModelUtil":141}],668:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); var cmdHelper = require('../../../../helper/CmdHelper'); /** * Create an entry to modify a property of an element which * is referenced by a event definition. * * @param {djs.model.Base} element * @param {ModdleElement} definition * @param {BpmnFactory} bpmnFactory * @param {Object} options * @param {string} options.id the id of the entry * @param {string} options.label the label of the entry * @param {string} options.referenceProperty the name of referencing property * @param {string} options.modelProperty the name of property to modify * @param {string} options.shouldValidate a flag indicate whether to validate or not * * @return {Array<Object>} return an array containing the entries */ module.exports = function(element, definition, bpmnFactory, options) { var id = options.id || 'element-property'; var label = options.label; var referenceProperty = options.referenceProperty; var modelProperty = options.modelProperty || 'name'; var shouldValidate = options.shouldValidate || false; var entry = entryFactory.textField({ id: id, label: label, modelProperty: modelProperty, get: function(element, node) { var reference = definition.get(referenceProperty); var props = {}; props[modelProperty] = reference && reference.get(modelProperty); return props; }, set: function(element, values, node) { var reference = definition.get(referenceProperty); var props = {}; props[modelProperty] = values[modelProperty] || undefined; return cmdHelper.updateBusinessObject(element, reference, props); }, hidden: function(element, node) { return !definition.get(referenceProperty); } }); if (shouldValidate) { entry.validate = function(element, values, node) { var reference = definition.get(referenceProperty); if (reference && !values[modelProperty]) { var validationErrors = {}; validationErrors[modelProperty] = 'Must provide a value'; return validationErrors; } }; } return [ entry ]; }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590}],669:[function(require,module,exports){ 'use strict'; var eventDefinitionReference = require('./EventDefinitionReference'), elementReferenceProperty = require('./ElementReferenceProperty'); module.exports = function(group, element, bpmnFactory, errorEventDefinition, translate) { group.entries = group.entries.concat(eventDefinitionReference(element, errorEventDefinition, bpmnFactory, { label: translate('Error'), elementName: 'error', elementType: 'bpmn:Error', referenceProperty: 'errorRef', newElementIdPrefix: 'Error_' })); group.entries = group.entries.concat(elementReferenceProperty(element, errorEventDefinition, bpmnFactory, { id: 'error-element-name', label: translate('Error Name'), referenceProperty: 'errorRef', modelProperty: 'name', shouldValidate: true })); group.entries = group.entries.concat(elementReferenceProperty(element, errorEventDefinition, bpmnFactory, { id: 'error-element-code', label: translate('Error Code'), referenceProperty: 'errorRef', modelProperty: 'errorCode' })); }; },{"./ElementReferenceProperty":668,"./EventDefinitionReference":671}],670:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'), cmdHelper = require('../../../../helper/CmdHelper'); var eventDefinitionReference = require('./EventDefinitionReference'), elementReferenceProperty = require('./ElementReferenceProperty'); module.exports = function(group, element, bpmnFactory, escalationEventDefinition, showEscalationCodeVariable, translate) { group.entries = group.entries.concat(eventDefinitionReference(element, escalationEventDefinition, bpmnFactory, { label: translate('Escalation'), elementName: 'escalation', elementType: 'bpmn:Escalation', referenceProperty: 'escalationRef', newElementIdPrefix: 'Escalation_' })); group.entries = group.entries.concat(elementReferenceProperty(element, escalationEventDefinition, bpmnFactory, { id: 'escalation-element-name', label: translate('Escalation Name'), referenceProperty: 'escalationRef', modelProperty: 'name', shouldValidate: true })); group.entries = group.entries.concat(elementReferenceProperty(element, escalationEventDefinition, bpmnFactory, { id: 'escalation-element-code', label: translate('Escalation Code'), referenceProperty: 'escalationRef', modelProperty: 'escalationCode' })); if (showEscalationCodeVariable) { group.entries.push(entryFactory.textField({ id : 'escalationCodeVariable', label : translate('Escalation Code Variable'), modelProperty : 'escalationCodeVariable', get: function(element) { var codeVariable = escalationEventDefinition.get('camunda:escalationCodeVariable'); return { escalationCodeVariable: codeVariable }; }, set: function(element, values) { return cmdHelper.updateBusinessObject(element, escalationEventDefinition, { 'camunda:escalationCodeVariable': values.escalationCodeVariable || undefined }); } })); } }; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"./ElementReferenceProperty":668,"./EventDefinitionReference":671}],671:[function(require,module,exports){ 'use strict'; var cmdHelper = require('../../../../helper/CmdHelper'); var domQuery = require('min-dom').query, domify = require('min-dom').domify, domAttr = require('min-dom').attr; var forEach = require('lodash/forEach'), find = require('lodash/find'); var elementHelper = require('../../../../helper/ElementHelper'); var utils = require('../../../../Utils'), escapeHTML = utils.escapeHTML; var selector = 'select[name=selectedElement]'; /** * Get select box containing all elements. * * @param {DOMElement} node * * @return {DOMElement} the select box */ function getSelectBox(node) { return domQuery(selector, node.parentElement); } /** * Find element by given id. * * @param {ModdleElement} eventDefinition * * @return {ModdleElement} an element */ function findElementById(eventDefinition, type, id) { var elements = utils.findRootElementsByType(eventDefinition, type); return find(elements, function(element) { return element.id === id; }); } /** * Create an entry to modify the reference to an element from an * event definition. * * @param {djs.model.Base} element * @param {ModdleElement} definition * @param {BpmnFactory} bpmnFactory * @param {Object} options * @param {string} options.label the label of the entry * @param {string} options.description the description of the entry * @param {string} options.elementName the name of the element * @param {string} options.elementType the type of the element * @param {string} options.referenceProperty the name of referencing property * @param {string} options.newElementIdPrefix the prefix of a new created element * * @return {Array<Object>} return an array containing the entries */ module.exports = function(element, definition, bpmnFactory, options) { var elementName = options.elementName || '', elementType = options.elementType, referenceProperty = options.referenceProperty; var newElementIdPrefix = options.newElementIdPrefix || 'elem_'; var label = options.label || '', description = options.description || ''; var entries = []; entries.push({ id: 'event-definitions-' + elementName, description: description, html: '<div class="bpp-row bpp-select">' + '<label for="camunda-' + escapeHTML(elementName) + '">' + escapeHTML(label) + '</label>' + '<div class="bpp-field-wrapper">' + '<select id="camunda-' + escapeHTML(elementName) + '" name="selectedElement" data-value>' + '</select>' + '<button class="add" id="addElement" data-action="addElement"><span>+</span></button>' + '</div>' + '</div>', get: function(element, entryNode) { utils.updateOptionsDropDown(selector, definition, elementType, entryNode); var reference = definition.get(referenceProperty); return { selectedElement: (reference && reference.id) || '' }; }, set: function(element, values) { var selection = values.selectedElement; var props = {}; if (!selection || typeof selection === 'undefined') { // remove reference to element props[referenceProperty] = undefined; return cmdHelper.updateBusinessObject(element, definition, props); } var commands = []; var selectedElement = findElementById(definition, elementType, selection); if (!selectedElement) { var root = utils.getRoot(definition); // create a new element selectedElement = elementHelper.createElement(elementType, { name: selection }, root, bpmnFactory); commands.push(cmdHelper.addAndRemoveElementsFromList(element, root, 'rootElements', null, [ selectedElement ])); } // update reference to element props[referenceProperty] = selectedElement; commands.push(cmdHelper.updateBusinessObject(element, definition, props)); return commands; }, addElement: function(element, inputNode) { // note: this generated id will be used as name // of the element and not as id var id = utils.nextId(newElementIdPrefix); var optionTemplate = domify('<option value="' + escapeHTML(id) + '"> (id='+escapeHTML(id)+')' + '</option>'); // add new option var selectBox = getSelectBox(inputNode); selectBox.insertBefore(optionTemplate, selectBox.firstChild); // select new element in the select box forEach(selectBox, function(option) { if (option.value === id) { domAttr(option, 'selected', 'selected'); } else { domAttr(option, 'selected', null); } }); return true; } }); return entries; }; },{"../../../../Utils":576,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591,"lodash/find":519,"lodash/forEach":522,"min-dom":556}],672:[function(require,module,exports){ 'use strict'; var eventDefinitionReference = require('./EventDefinitionReference'), elementReferenceProperty = require('./ElementReferenceProperty'); module.exports = function(group, element, bpmnFactory, messageEventDefinition, translate) { group.entries = group.entries.concat(eventDefinitionReference(element, messageEventDefinition, bpmnFactory, { label: translate('Message'), elementName: 'message', elementType: 'bpmn:Message', referenceProperty: 'messageRef', newElementIdPrefix: 'Message_' })); group.entries = group.entries.concat(elementReferenceProperty(element, messageEventDefinition, bpmnFactory, { id: 'message-element-name', label: translate('Message Name'), referenceProperty: 'messageRef', modelProperty: 'name', shouldValidate: true })); }; },{"./ElementReferenceProperty":668,"./EventDefinitionReference":671}],673:[function(require,module,exports){ 'use strict'; var entryFactory = require('../../../../factory/EntryFactory'); /** * Create an entry to modify the name of an an element. * * @param {djs.model.Base} element * @param {Object} options * @param {string} options.id the id of the entry * @param {string} options.label the label of the entry * * @return {Array<Object>} return an array containing * the entry to modify the name */ module.exports = function(element, options, translate) { options = options || {}; var id = options.id || 'name', label = options.label || translate('Name'), modelProperty = options.modelProperty || 'name'; var nameEntry = entryFactory.textBox({ id: id, label: label, modelProperty: modelProperty, get: options.get, set: options.set }); return [ nameEntry ]; }; },{"../../../../factory/EntryFactory":579}],674:[function(require,module,exports){ 'use strict'; var eventDefinitionReference = require('./EventDefinitionReference'), elementReferenceProperty = require('./ElementReferenceProperty'); module.exports = function(group, element, bpmnFactory, signalEventDefinition, translate) { group.entries = group.entries.concat(eventDefinitionReference(element, signalEventDefinition, bpmnFactory, { label: translate('Signal'), elementName: 'signal', elementType: 'bpmn:Signal', referenceProperty: 'signalRef', newElementIdPrefix: 'Signal_' })); group.entries = group.entries.concat(elementReferenceProperty(element, signalEventDefinition, bpmnFactory, { id: 'signal-element-name', label: translate('Signal Name'), referenceProperty: 'signalRef', modelProperty: 'name', shouldValidate: true })); }; },{"./ElementReferenceProperty":668,"./EventDefinitionReference":671}],675:[function(require,module,exports){ 'use strict'; var elementHelper = require('../../../../helper/ElementHelper'), cmdHelper = require('../../../../helper/CmdHelper'); var entryFactory = require('../../../../factory/EntryFactory'); /** * Get the timer definition type for a given timer event definition. * * @param {ModdleElement<bpmn:TimerEventDefinition>} timer * * @return {string|undefined} the timer definition type */ function getTimerDefinitionType(timer) { var timeDate = timer.get('timeDate'); if (typeof timeDate !== 'undefined') { return 'timeDate'; } var timeCycle = timer.get('timeCycle'); if (typeof timeCycle !== 'undefined') { return 'timeCycle'; } var timeDuration = timer.get('timeDuration'); if (typeof timeDuration !== 'undefined') { return 'timeDuration'; } } /** * Creates 'bpmn:FormalExpression' element. * * @param {ModdleElement} parent * @param {string} body * @param {BpmnFactory} bpmnFactory * * @return {ModdleElement<bpmn:FormalExpression>} a formal expression */ function createFormalExpression(parent, body, bpmnFactory) { body = body || undefined; return elementHelper.createElement('bpmn:FormalExpression', { body: body }, parent, bpmnFactory); } function TimerEventDefinition(group, element, bpmnFactory, timerEventDefinition, translate) { var selectOptions = [ { value: 'timeDate', name: translate('Date') }, { value: 'timeDuration', name: translate('Duration') }, { value: 'timeCycle', name: translate('Cycle') } ]; group.entries.push(entryFactory.selectBox({ id: 'timer-event-definition-type', label: translate('Timer Definition Type'), selectOptions: selectOptions, emptyParameter: true, modelProperty: 'timerDefinitionType', get: function(element, node) { return { timerDefinitionType: getTimerDefinitionType(timerEventDefinition) || '' }; }, set: function(element, values) { var props = { timeDuration: undefined, timeDate: undefined, timeCycle: undefined }; var newType = values.timerDefinitionType; if (values.timerDefinitionType) { var oldType = getTimerDefinitionType(timerEventDefinition); var value; if (oldType) { var definition = timerEventDefinition.get(oldType); value = definition.get('body'); } props[newType] = createFormalExpression(timerEventDefinition, value, bpmnFactory); } return cmdHelper.updateBusinessObject(element, timerEventDefinition, props); } })); group.entries.push(entryFactory.textField({ id: 'timer-event-definition', label: translate('Timer Definition'), modelProperty: 'timerDefinition', get: function(element, node) { var type = getTimerDefinitionType(timerEventDefinition); var definition = type && timerEventDefinition.get(type); var value = definition && definition.get('body'); return { timerDefinition: value }; }, set: function(element, values) { var type = getTimerDefinitionType(timerEventDefinition); var definition = type && timerEventDefinition.get(type); if (definition) { return cmdHelper.updateBusinessObject(element, definition, { body: values.timerDefinition || undefined }); } }, validate: function(element) { var type = getTimerDefinitionType(timerEventDefinition); var definition = type && timerEventDefinition.get(type); if (definition) { var value = definition.get('body'); if (!value) { return { timerDefinition: translate('Must provide a value') }; } } }, hidden: function(element) { return !getTimerDefinitionType(timerEventDefinition); } })); } module.exports = TimerEventDefinition; },{"../../../../factory/EntryFactory":579,"../../../../helper/CmdHelper":590,"../../../../helper/ElementHelper":591}],676:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _jquery = _interopRequireDefault(require("jquery")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * @description 全局功能封装 * @author zr * @type {{registerFileDrop(*, *): void, saveBpmn(Object): void, handleDragOver(*): void, setColor(Object): void, downLoad(Object): void, upload(Object, Object, Object): void, handleFileSelect(*): void, setEncoded(Object, string, string): void, openFromUrl(Object, Object, Object, string): void, createDiagram(string, Object, Object): Promise<void>, getUrlParam: tools.getUrlParam}} */ const proHost = window.location.protocol + "//" + window.location.host; const href = window.location.href.split("bpmnjs")[0]; const key = href.split(window.location.host)[1]; const publicurl = proHost + key; const tools = { registerFileDrop(container, callback) { container.get(0).addEventListener('dragover', tools.handleDragOver, false); container.get(0).addEventListener('drop', tools.handleFileSelect, false); }, /** * 获取地址栏参数 * @param {string} value */ getUrlParam: function (url) { var object = {}; if (url.indexOf("?") != -1) { var str = url.split("?")[1]; var strs = str.split("&"); for (var i = 0; i < strs.length; i++) { object[strs[i].split("=")[0]] = strs[i].split("=")[1]; } return object; } return object[url]; }, /** * 通过xml创建bpmn * @param {string} xml 创建bpms xml * @param {object} bpmnModeler bpmn对象 * @param {object} container 容器对象 */ async createDiagram(xml, bpmnModeler, container) { try { await bpmnModeler.importXML(xml); container.removeClass('with-error').addClass('with-diagram'); } catch (err) { container.removeClass('with-diagram').addClass('with-error'); container.find('.error pre').text(err.message); console.error(err); } }, /** * 通过Json设置颜色 * @param {object} json json 字符串 */ setColor(json, bpmnModeler) { var modeling = bpmnModeler.get('modeling'); var elementRegistry = bpmnModeler.get('elementRegistry'); var elementToColor = elementRegistry.get(json.name); if (elementToColor) { modeling.setColor([elementToColor], { stroke: json.stroke, fill: json.fill }); } }, /** * 保存bpmn对象 * @param {object} bpmnModeler bpmn对象 */ saveBpmn(bpmnModeler,modelId) { bpmnModeler.saveXML({ format: true }, function (err, xml) { if (err) { return console.error('保存失败,请重试', err); } var param = { "stringBPMN": xml, "modelId":modelId }; _jquery.default.ajax({ url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/actModel/update', type: 'POST', dataType: "json", headers: { 'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'), }, data: param, //headers:{'Content-Type':'application/json;charset=utf8'}, success: function (result) { if (result.code === 200) { tools.syhide('alert'); alert(result.msg); } else { tools.syhide('alert'); alert(result.msg); } }, error: function (err) { console.log(err); } }); }); }, /** * 下载bpmn * @param {object} bpmnModeler bpmn对象 */ downLoad(bpmnModeler) { var downloadLink = (0, _jquery.default)("#downloadBpmn"); bpmnModeler.saveXML({ format: true }, function (err, xml) { if (err) { return console.error('could not save BPMN 2.0 diagram', err); } tools.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml); }); }, /** * 转码xml并下载 * @param {object} link 按钮 * @param {string} name 下载名称 * @param {string} data base64XML */ setEncoded(link, name, data) { var encodedData = encodeURIComponent(data); if (data) { link.addClass('active').attr({ 'href': 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData, 'download': name }); } else { link.removeClass('active'); } }, /** * 上传bpmn * @param {object} bpmnModeler bpmn对象 * @param {object} container 容器对象 */ upload(bpmnModeler, container) { var FileUpload = document.myForm.uploadFile.files[0]; var fm = new FormData(); fm.append('processFile', FileUpload); _jquery.default.ajax({ url: localStorage.getItem("VUE_APP_BASE_API") + '/saas-common/saas/common/processDefinition/upload', // url: 'http://localhost:8080/processDefinition/upload', type: 'POST', headers: { 'Blade-Auth': localStorage.getItem('BLADE_AUTH_TOKEN'), }, data: fm, async: false, contentType: false, //禁止设置请求类型 processData: false, //禁止jquery对DAta数据的处理,默认会处理 success: function (result) { var url = result.data.substr(0, 4) == "http" ? result.data : localStorage.getItem("VUE_APP_BASE_API") + result.data; tools.openFromUrl(bpmnModeler, container, url); }, error: function (err) { console.log(err); } }); }, /** * 打开xml Url 地址 * @param {object} bpmnModeler bpmn对象 * @param {object} container 容器对象 * @param {string} url url地址 */ openFromUrl(bpmnModeler, container, url) { _jquery.default.ajax(url, { dataType: 'text' }).done(async function (xml) { try { await bpmnModeler.importXML(xml); container.removeClass('with-error').addClass('with-diagram'); } catch (err) { console.error(err); } }); }, /** * 打开弹出框 * @param id */ syopen(id) { var dom = (0, _jquery.default)("#" + id); this.sycenter(dom); dom.addClass(name); dom.show(); var that = this; (0, _jquery.default)(".sy-mask").fadeIn(300); setTimeout(function () { dom.removeClass(name); }, 300); }, /** * 隐藏弹出框 * @param id */ syhide(id) { if (typeof id == "undefined") { var dom = (0, _jquery.default)(".sy-alert"); } else { var dom = (0, _jquery.default)("#" + id); } var name = dom.attr("sy-leave"); dom.addClass(name); (0, _jquery.default)(".sy-mask").fadeOut(300); setTimeout(function () { dom.hide(); dom.removeClass(name); }, 300); }, /** * 弹出框居中 * @param dom */ sycenter(dom) { var mgtop = parseFloat(dom.height() / 2); dom.css({ "top": "50%", "margin-top": "-" + mgtop + "px" }); }, /** * 判断是否是数组 * @param value * @returns {arg is Array<any>|boolean} */ isArrayFn(value) { if (typeof Array.isArray === "function") { return Array.isArray(value); } else { return Object.prototype.toString.call(value) === "[object Array]"; } }, /** * 根据数据设置颜色 * @param data * @returns {Array} */ getByColor(data) { var ColorJson = []; for (var k in data['highLine']) { var par = { "name": data['highLine'][k], "stroke": "green", "fill": "green" }; ColorJson.push(par); } for (var k in data['highPoint']) { var par = { "name": data['highPoint'][k], "stroke": "gray", "fill": "#eae9e9" }; ColorJson.push(par); } for (var k in data['iDo']) { var par = { "name": data['iDo'][k], "stroke": "green", "fill": "#a3d68e" }; ColorJson.push(par); } for (var k in data['waitingToDo']) { var par = { "name": data['waitingToDo'][k], "stroke": "green", "fill": "yellow" }; ColorJson.push(par); } return ColorJson; } }; var _default = tools; exports.default = _default; },{"jquery":348}]},{},[1]) //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJhcHAvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMtcHJvcGVydGllcy1wYW5lbC9saWIvUHJvcGVydGllc1BhbmVsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMtcHJvcGVydGllcy1wYW5lbC9saWIvVXRpbHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2xpYi9jbWQvQ3JlYXRlQW5kUmVmZXJlbmNlSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzLXByb3BlcnRpZXMtcGFuZWwvbGliL2NtZC9DcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMtcHJvcGVydGllcy1wYW5lbC9saWIvY21kL011bHRpQ29tbWFuZEhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2xpYi9jbWQvVXBkYXRlQnVzaW5lc3NPYmplY3RIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMtcHJvcGVydGllcy1wYW5lbC9saWIvY21kL1VwZGF0ZUJ1c2luZXNzT2JqZWN0TGlzdEhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2xpYi9jbWQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsL2xpYi9oZWxwZXIvRWxlbWVudEhlbHBlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzLXByb3BlcnRpZXMtcGFuZWwvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL0Jhc2VNb2RlbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL0Jhc2VWaWV3ZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvTW9kZWxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9OYXZpZ2F0ZWRWaWV3ZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvVmlld2VyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2NvcmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZHJhdy9CcG1uUmVuZGVyVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9kcmF3L0JwbW5SZW5kZXJlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9kcmF3L1BhdGhNYXAuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZHJhdy9UZXh0UmVuZGVyZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZHJhdy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXBsYWNlL0JwbW5BdXRvUGxhY2UuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvYXV0by1wbGFjZS9CcG1uQXV0b1BsYWNlVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXBsYWNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2F1dG8tcmVzaXplL0JwbW5BdXRvUmVzaXplLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2F1dG8tcmVzaXplL0JwbW5BdXRvUmVzaXplUHJvdmlkZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvYXV0by1yZXNpemUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvY29udGV4dC1wYWQvQ29udGV4dFBhZFByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2NvbnRleHQtcGFkL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2NvcHktcGFzdGUvQnBtbkNvcHlQYXN0ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9jb3B5LXBhc3RlL01vZGRsZUNvcHkuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvY29weS1wYXN0ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9kaS1vcmRlcmluZy9CcG1uRGlPcmRlcmluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9kaS1vcmRlcmluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9kaXN0cmlidXRlLWVsZW1lbnRzL0JwbW5EaXN0cmlidXRlRWxlbWVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9lZGl0b3ItYWN0aW9ucy9CcG1uRWRpdG9yQWN0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9lZGl0b3ItYWN0aW9ucy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL0JwbW5HcmlkU25hcHBpbmcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9iZWhhdmlvci9BdXRvUGxhY2VCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL2JlaGF2aW9yL0NyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9iZWhhdmlvci9MYXlvdXRDb25uZWN0aW9uQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9iZWhhdmlvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2ludGVyYWN0aW9uLWV2ZW50cy9CcG1uSW50ZXJhY3Rpb25FdmVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvaW50ZXJhY3Rpb24tZXZlbnRzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2tleWJvYXJkL0JwbW5LZXlib2FyZEJpbmRpbmdzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2tleWJvYXJkL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2xhYmVsLWVkaXRpbmcvTGFiZWxFZGl0aW5nUHJldmlldy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9sYWJlbC1lZGl0aW5nL0xhYmVsRWRpdGluZ1Byb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2xhYmVsLWVkaXRpbmcvTGFiZWxVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL2xhYmVsLWVkaXRpbmcvY21kL1VwZGF0ZUxhYmVsSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9sYWJlbC1lZGl0aW5nL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL0JwbW5GYWN0b3J5LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL0JwbW5MYXlvdXRlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9CcG1uVXBkYXRlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9FbGVtZW50RmFjdG9yeS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9Nb2RlbGluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9BZGFwdGl2ZUxhYmVsUG9zaXRpb25pbmdCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9BcHBlbmRCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9Bc3NvY2lhdGlvbkJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0F0dGFjaEV2ZW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvQm91bmRhcnlFdmVudEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0NyZWF0ZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0NyZWF0ZURhdGFPYmplY3RCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9DcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0RhdGFJbnB1dEFzc29jaWF0aW9uQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvRGF0YVN0b3JlQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvRGVsZXRlTGFuZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0RldGFjaEV2ZW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvRHJvcE9uRmxvd0JlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0V2ZW50QmFzZWRHYXRld2F5QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvRml4SG92ZXJCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9Hcm91cEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0ltcG9ydERvY2tpbmdGaXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvSXNIb3Jpem9udGFsRml4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL0xhYmVsQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvTW9kZWxpbmdGZWVkYmFjay5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9SZW1vdmVFbGVtZW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvUmVtb3ZlUGFydGljaXBhbnRCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9SZXBsYWNlQ29ubmVjdGlvbkJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1JlcGxhY2VFbGVtZW50QmVoYXZpb3VyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1Jlc2l6ZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1Jlc2l6ZUxhbmVCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9Sb290RWxlbWVudFJlZmVyZW5jZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1NwYWNlVG9vbEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1N1YlByb2Nlc3NTdGFydEV2ZW50QmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvVG9nZ2xlRWxlbWVudENvbGxhcHNlQmVoYXZpb3VyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1VuY2xhaW1JZEJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL1Vuc2V0RGVmYXVsdEZsb3dCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9VcGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci91dGlsL0NhdGVnb3J5VXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9iZWhhdmlvci91dGlsL0dlb21ldHJpY1V0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvdXRpbC9MYWJlbExheW91dFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvdXRpbC9MaW5lQXR0YWNobWVudFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvYmVoYXZpb3IvdXRpbC9MaW5lSW50ZXJzZWN0LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2JlaGF2aW9yL3V0aWwvUmVzaXplVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvQWRkTGFuZUhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL0lkQ2xhaW1IYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9SZXNpemVMYW5lSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvU2V0Q29sb3JIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9TcGxpdExhbmVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9VcGRhdGVDYW52YXNSb290SGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvVXBkYXRlRmxvd05vZGVSZWZzSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvVXBkYXRlUHJvcGVydGllc0hhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL1VwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy91dGlsL0xhbmVVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL29yZGVyaW5nL0JwbW5PcmRlcmluZ1Byb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL29yZGVyaW5nL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3BhbGV0dGUvUGFsZXR0ZVByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3BhbGV0dGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvcG9wdXAtbWVudS9SZXBsYWNlTWVudVByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3BvcHVwLW1lbnUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvcG9wdXAtbWVudS91dGlsL1R5cGVVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3JlcGxhY2UtcHJldmlldy9CcG1uUmVwbGFjZVByZXZpZXcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvcmVwbGFjZS1wcmV2aWV3L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3JlcGxhY2UvQnBtblJlcGxhY2UuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvcmVwbGFjZS9SZXBsYWNlT3B0aW9ucy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9yZXBsYWNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3J1bGVzL0JwbW5SdWxlcy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9ydWxlcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9zZWFyY2gvQnBtblNlYXJjaFByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3NlYXJjaC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9CcG1uQ29ubmVjdFNuYXBwaW5nLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ZlYXR1cmVzL3NuYXBwaW5nL0JwbW5DcmVhdGVNb3ZlU25hcHBpbmcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvZmVhdHVyZXMvc25hcHBpbmcvQnBtblNuYXBwaW5nVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9pbXBvcnQvQnBtbkltcG9ydGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL2ltcG9ydC9CcG1uVHJlZVdhbGtlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL2xpYi9pbXBvcnQvSW1wb3J0ZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvaW1wb3J0L1V0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvaW1wb3J0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbGliL3V0aWwvQ29tcGF0aWJpbGl0eVV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvdXRpbC9EaVV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvdXRpbC9MYWJlbFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9saWIvdXRpbC9Qb3dlcmVkQnlVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvRGlhZ3JhbS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRTdGFjay5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb21tYW5kL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2NvcmUvQ2FudmFzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2NvcmUvRWxlbWVudEZhY3RvcnkuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvY29yZS9FbGVtZW50UmVnaXN0cnkuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvY29yZS9FdmVudEJ1cy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb3JlL0dyYXBoaWNzRmFjdG9yeS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9jb3JlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2RyYXcvQmFzZVJlbmRlcmVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2RyYXcvRGVmYXVsdFJlbmRlcmVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2RyYXcvU3R5bGVzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2RyYXcvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYWxpZ24tZWxlbWVudHMvQWxpZ25FbGVtZW50cy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hbGlnbi1lbGVtZW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hdHRhY2gtc3VwcG9ydC9BdHRhY2hTdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F0dGFjaC1zdXBwb3J0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F1dG8tcGxhY2UvQXV0b1BsYWNlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F1dG8tcGxhY2UvQXV0b1BsYWNlU2VsZWN0aW9uQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1wbGFjZS9BdXRvUGxhY2VVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F1dG8tcGxhY2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1yZXNpemUvQXV0b1Jlc2l6ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXJlc2l6ZS9BdXRvUmVzaXplUHJvdmlkZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1zY3JvbGwvQXV0b1Njcm9sbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXNjcm9sbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9iZW5kcG9pbnRzL0JlbmRwb2ludE1vdmUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYmVuZHBvaW50cy9CZW5kcG9pbnRNb3ZlUHJldmlldy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9iZW5kcG9pbnRzL0JlbmRwb2ludFNuYXBwaW5nLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2JlbmRwb2ludHMvQmVuZHBvaW50VXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9iZW5kcG9pbnRzL0JlbmRwb2ludHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYmVuZHBvaW50cy9Db25uZWN0aW9uU2VnbWVudE1vdmUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYmVuZHBvaW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jaGFuZ2Utc3VwcG9ydC9DaGFuZ2VTdXBwb3J0LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NoYW5nZS1zdXBwb3J0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NsaXBib2FyZC9DbGlwYm9hcmQuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY2xpcGJvYXJkL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2Nvbm5lY3QvQ29ubmVjdC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jb25uZWN0L0Nvbm5lY3RQcmV2aWV3LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2Nvbm5lY3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY29ubmVjdGlvbi1wcmV2aWV3L0Nvbm5lY3Rpb25QcmV2aWV3LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2Nvbm5lY3Rpb24tcHJldmlldy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jb250ZXh0LXBhZC9Db250ZXh0UGFkLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvbnRleHQtcGFkL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvcHktcGFzdGUvQ29weVBhc3RlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvcHktcGFzdGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY3JlYXRlL0NyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jcmVhdGUvQ3JlYXRlUHJldmlldy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jcmVhdGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cy9EaXN0cmlidXRlRWxlbWVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9kcmFnZ2luZy9EcmFnZ2luZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9kcmFnZ2luZy9Ib3ZlckZpeC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9kcmFnZ2luZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9lZGl0b3ItYWN0aW9ucy9FZGl0b3JBY3Rpb25zLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2VkaXRvci1hY3Rpb25zL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2dsb2JhbC1jb25uZWN0L0dsb2JhbENvbm5lY3QuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZ2xvYmFsLWNvbm5lY3QvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9HcmlkU25hcHBpbmcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9HcmlkVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL2JlaGF2aW9yL1Jlc2l6ZUJlaGF2aW9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2dyaWQtc25hcHBpbmcvYmVoYXZpb3IvU3BhY2VUb29sQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZ3JpZC1zbmFwcGluZy9iZWhhdmlvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2hhbmQtdG9vbC9IYW5kVG9vbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9oYW5kLXRvb2wvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvaW50ZXJhY3Rpb24tZXZlbnRzL0ludGVyYWN0aW9uRXZlbnRzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2ludGVyYWN0aW9uLWV2ZW50cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9rZXlib2FyZC1tb3ZlLXNlbGVjdGlvbi9LZXlib2FyZE1vdmVTZWxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQtbW92ZS1zZWxlY3Rpb24vaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQvS2V5Ym9hcmQuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQvS2V5Ym9hcmRCaW5kaW5ncy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9rZXlib2FyZC9LZXlib2FyZFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbGFiZWwtc3VwcG9ydC9MYWJlbFN1cHBvcnQuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbGFiZWwtc3VwcG9ydC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9sYXNzby10b29sL0xhc3NvVG9vbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9sYXNzby10b29sL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL01vZGVsaW5nLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9BbGlnbkVsZW1lbnRzSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvQXBwZW5kU2hhcGVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9DcmVhdGVDb25uZWN0aW9uSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvQ3JlYXRlRWxlbWVudHNIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9DcmVhdGVMYWJlbEhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL0NyZWF0ZVNoYXBlSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL0RlbGV0ZUVsZW1lbnRzSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvRGVsZXRlU2hhcGVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9EaXN0cmlidXRlRWxlbWVudHNIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9MYXlvdXRDb25uZWN0aW9uSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvTW92ZUNvbm5lY3Rpb25IYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9Nb3ZlRWxlbWVudHNIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9Nb3ZlU2hhcGVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9SZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvUmVwbGFjZVNoYXBlSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvUmVzaXplU2hhcGVIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9TcGFjZVRvb2xIYW5kbGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9Ub2dnbGVTaGFwZUNvbGxhcHNlSGFuZGxlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy9jbWQvVXBkYXRlQXR0YWNobWVudEhhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL1VwZGF0ZVdheXBvaW50c0hhbmRsZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL2hlbHBlci9BbmNob3JzSGVscGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL2NtZC9oZWxwZXIvTW92ZUNsb3N1cmUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvY21kL2hlbHBlci9Nb3ZlSGVscGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdXNlL01vdXNlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdmUvTW92ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9tb3ZlL01vdmVQcmV2aWV3LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdmUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvb3JkZXJpbmcvT3JkZXJpbmdQcm92aWRlci5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9vdXRsaW5lL091dGxpbmUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvb3V0bGluZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9vdmVybGF5cy9PdmVybGF5cy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9vdmVybGF5cy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wYWxldHRlL1BhbGV0dGUuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcGFsZXR0ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wb3B1cC1tZW51L1BvcHVwTWVudS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wb3B1cC1tZW51L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3ByZXZpZXctc3VwcG9ydC9QcmV2aWV3U3VwcG9ydC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wcmV2aWV3LXN1cHBvcnQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcmVwbGFjZS9SZXBsYWNlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3JlcGxhY2UvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcmVzaXplL1Jlc2l6ZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvUmVzaXplSGFuZGxlcy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvUmVzaXplUHJldmlldy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvUmVzaXplVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcnVsZXMvUnVsZVByb3ZpZGVyLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3J1bGVzL1J1bGVzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3J1bGVzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NlYXJjaC1wYWQvU2VhcmNoUGFkLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NlYXJjaC1wYWQvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc2VsZWN0aW9uL1NlbGVjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zZWxlY3Rpb24vU2VsZWN0aW9uQmVoYXZpb3IuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc2VsZWN0aW9uL1NlbGVjdGlvblZpc3VhbHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc2VsZWN0aW9uL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NuYXBwaW5nL0NyZWF0ZU1vdmVTbmFwcGluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9SZXNpemVTbmFwcGluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwQ29udGV4dC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwcGluZy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zcGFjZS10b29sL1NwYWNlVG9vbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zcGFjZS10b29sL1NwYWNlVG9vbFByZXZpZXcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc3BhY2UtdG9vbC9TcGFjZVV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc3BhY2UtdG9vbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9mZWF0dXJlcy90b29sLW1hbmFnZXIvVG9vbE1hbmFnZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvdG9vbC1tYW5hZ2VyL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Rvb2x0aXBzL1Rvb2x0aXBzLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Rvb2x0aXBzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3RvdWNoL1RvdWNoRml4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3RvdWNoL1RvdWNoSW50ZXJhY3Rpb25FdmVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvdG91Y2gvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUvdHJhbnNsYXRlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2xheW91dC9CYXNlTGF5b3V0ZXIuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0Nyb3BwaW5nQ29ubmVjdGlvbkRvY2tpbmcuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbGF5b3V0L01hbmhhdHRhbkxheW91dC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9tb2RlbC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL2tleWJvYXJkLW1vdmUvS2V5Ym9hcmRNb3ZlLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL25hdmlnYXRpb24va2V5Ym9hcmQtbW92ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL21vdmVjYW52YXMvTW92ZUNhbnZhcy5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL21vdmVjYW52YXMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbmF2aWdhdGlvbi90b3VjaC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL3pvb21zY3JvbGwvWm9vbVNjcm9sbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL3pvb21zY3JvbGwvWm9vbVV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvbmF2aWdhdGlvbi96b29tc2Nyb2xsL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvQXR0YWNoVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0NsaWNrVHJhcC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvQ3Vyc29yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvRWxlbWVudHMuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvdXRpbC9Fc2NhcGVVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvRXZlbnQuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvdXRpbC9HZW9tZXRyeS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0dyYXBoaWNzVXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0lkR2VuZXJhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvTGluZUludGVyc2VjdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL01hdGguanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvdXRpbC9Nb3VzZS5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL1BsYXRmb3JtLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvUG9zaXRpb25VdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvUmVtb3ZhbC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLWpzL25vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL1JlbmRlclV0aWwuanMiLCJub2RlX21vZHVsZXMvYnBtbi1qcy9ub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvdXRpbC9TdmdUcmFuc2Zvcm1VdGlsLmpzIiwibm9kZV9tb2R1bGVzL2JwbW4tanMvbm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL3V0aWwvVGV4dC5qcyIsIm5vZGVfbW9kdWxlcy9icG1uLW1vZGRsZS9kaXN0L2luZGV4LmVzbS5qcyIsIm5vZGVfbW9kdWxlcy9jc3MuZXNjYXBlL2Nzcy5lc2NhcGUuanMiLCJub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy1kaXJlY3QtZWRpdGluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9kaWFncmFtLWpzLWRpcmVjdC1lZGl0aW5nL2xpYi9EaXJlY3RFZGl0aW5nLmpzIiwibm9kZV9tb2R1bGVzL2RpYWdyYW0tanMtZGlyZWN0LWVkaXRpbmcvbGliL1RleHRCb3guanMiLCJub2RlX21vZHVsZXMvZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvaW50ZXJhY3Rpb24tZXZlbnRzL0ludGVyYWN0aW9uRXZlbnRzLmpzIiwibm9kZV9tb2R1bGVzL2RpYWdyYW0tanMvbGliL2kxOG4vdHJhbnNsYXRlL3RyYW5zbGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9kaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zLmpzIiwibm9kZV9tb2R1bGVzL2RpZGkvZGlzdC9pbmRleC5lc20uanMiLCJub2RlX21vZHVsZXMvaGFtbWVyanMvaGFtbWVyLmpzIiwibm9kZV9tb2R1bGVzL2lkcy9ub2RlX21vZHVsZXMvaGF0L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2lkcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2pxdWVyeS9kaXN0L2pxdWVyeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX0RhdGFWaWV3LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fSGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX0xhenlXcmFwcGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fTGlzdENhY2hlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fTG9kYXNoV3JhcHBlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX01hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX01hcENhY2hlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fUHJvbWlzZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX1NldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX1NldENhY2hlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fU3RhY2suanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19TeW1ib2wuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19VaW50OEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fV2Vha01hcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2FwcGx5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlBZ2dyZWdhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlGaWx0ZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheUluY2x1ZGVzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlJbmNsdWRlc1dpdGguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheUxpa2VLZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYXJyYXlNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheVB1c2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hcnJheVNvbWUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19hc3NpZ25WYWx1ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Fzc29jSW5kZXhPZi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VBZ2dyZWdhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUFzc2lnblZhbHVlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUNyZWF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VEaWZmZXJlbmNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUVhY2guanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlRmlsdGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUZpbmRJbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VGbGF0dGVuLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUZvci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VGb3JPd24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlR2V0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUdldEFsbEtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlR2V0VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUhhc0luLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUluZGV4T2YuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlSXNBcmd1bWVudHMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlSXNFcXVhbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc0VxdWFsRGVlcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJc01hdGNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzTmFOLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzTmF0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUlzVHlwZWRBcnJheS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VJdGVyYXRlZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VLZXlzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZUxvZGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VNYXAuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlTWF0Y2hlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VNYXRjaGVzUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlUHJvcGVydHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlUHJvcGVydHlEZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZVJlc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19iYXNlU2V0RGF0YS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VTZXRUb1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VUaW1lcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VUb1N0cmluZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VVbmFyeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VVbmlxLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fYmFzZVZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Jhc2VYb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jYWNoZUhhcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nhc3RGdW5jdGlvbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2Nhc3RQYXRoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY29tcG9zZUFyZ3MuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jb21wb3NlQXJnc1JpZ2h0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY29weUFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY29weU9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NvcmVKc0RhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jb3VudEhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jcmVhdGVBZ2dyZWdhdG9yLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlQXNzaWduZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jcmVhdGVCYXNlRWFjaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NyZWF0ZUJhc2VGb3IuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jcmVhdGVCaW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlQ3Rvci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NyZWF0ZUN1cnJ5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlRmluZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NyZWF0ZUh5YnJpZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2NyZWF0ZVBhcnRpYWwuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19jcmVhdGVSZWN1cnJ5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlU2V0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fY3JlYXRlV3JhcC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2RlZmluZVByb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZXF1YWxBcnJheXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19lcXVhbEJ5VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZXF1YWxPYmplY3RzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZnJlZUdsb2JhbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldEFsbEtleXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19nZXREYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0RnVuY05hbWUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19nZXRIb2xkZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19nZXRNYXBEYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0TWF0Y2hEYXRhLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0TmF0aXZlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0UHJvdG90eXBlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0UmF3VGFnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0U3ltYm9scy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFRhZy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2dldFZhbHVlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fZ2V0V3JhcERldGFpbHMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19oYXNQYXRoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaENsZWFyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaERlbGV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2hhc2hHZXQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19oYXNoSGFzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faGFzaFNldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2luc2VydFdyYXBEZXRhaWxzLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faXNGbGF0dGVuYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2lzSW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19pc0l0ZXJhdGVlQ2FsbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2lzS2V5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faXNLZXlhYmxlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faXNMYXppYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2lzTWFza2VkLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9faXNQcm90b3R5cGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19pc1N0cmljdENvbXBhcmFibGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19saXN0Q2FjaGVDbGVhci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZURlbGV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZUdldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZUhhcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX2xpc3RDYWNoZVNldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlQ2xlYXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tYXBDYWNoZURlbGV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcENhY2hlR2V0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fbWFwQ2FjaGVIYXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tYXBDYWNoZVNldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX21hcFRvQXJyYXkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tYXRjaGVzU3RyaWN0Q29tcGFyYWJsZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX21lbW9pemVDYXBwZWQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tZXJnZURhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19tZXRhTWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fbmF0aXZlQ3JlYXRlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fbmF0aXZlS2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX25vZGVVdGlsLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fb2JqZWN0VG9TdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19vdmVyQXJnLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fb3ZlclJlc3QuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19yZWFsTmFtZXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19yZW9yZGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fcmVwbGFjZUhvbGRlcnMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19yb290LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fc2V0Q2FjaGVBZGQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zZXRDYWNoZUhhcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3NldERhdGEuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zZXRUb0FycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fc2V0VG9TdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zZXRXcmFwVG9TdHJpbmcuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zaG9ydE91dC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0YWNrQ2xlYXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja0RlbGV0ZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0YWNrR2V0LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fc3RhY2tIYXMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zdGFja1NldC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3N0cmljdEluZGV4T2YuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL19zdHJpbmdUb1BhdGguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL190b0tleS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvX3RvU291cmNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9fdXBkYXRlV3JhcERldGFpbHMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL193cmFwcGVyQ2xvbmUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2Fzc2lnbi5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvYmluZC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvY29uc3RhbnQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2RlYm91bmNlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9lcS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvZmlsdGVyLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9maW5kLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9maW5kSW5kZXguanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2ZsYXR0ZW5EZWVwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9mb3JFYWNoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9nZXQuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2hhc0luLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pZGVudGl0eS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNBcmd1bWVudHMuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzQXJyYXkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzQXJyYXlMaWtlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pc0FycmF5TGlrZU9iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNCdWZmZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzRW1wdHkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzRnVuY3Rpb24uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL2lzTGVuZ3RoLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pc09iamVjdC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNPYmplY3RMaWtlLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9pc1N5bWJvbC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvaXNUeXBlZEFycmF5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9rZXlCeS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gva2V5cy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvbWFwLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9tZW1vaXplLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9ub29wLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9ub3cuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3Byb3BlcnR5LmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC9zdHViQXJyYXkuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3N0dWJGYWxzZS5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvdG9GaW5pdGUuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3RvSW50ZWdlci5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvdG9OdW1iZXIuanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3RvU3RyaW5nLmpzIiwibm9kZV9tb2R1bGVzL2xvZGFzaC90cmFuc2Zvcm0uanMiLCJub2RlX21vZHVsZXMvbG9kYXNoL3ZhbHVlcy5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gvd3JhcHBlckxvZGFzaC5qcyIsIm5vZGVfbW9kdWxlcy9sb2Rhc2gveG9yLmpzIiwibm9kZV9tb2R1bGVzL21pbi1kYXNoL2Rpc3QvaW5kZXguZXNtLmpzIiwibm9kZV9tb2R1bGVzL21pbi1kb20vZGlzdC9pbmRleC5lc20uanMiLCJub2RlX21vZHVsZXMvbWl0dC9kaXN0L21pdHQuZXMuanMiLCJub2RlX21vZHVsZXMvbW9kZGxlLXhtbC9kaXN0L2luZGV4LmVzbS5qcyIsIm5vZGVfbW9kdWxlcy9tb2RkbGUvZGlzdC9pbmRleC5lc20uanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LXJlZnMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LXJlZnMvbGliL2NvbGxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvb2JqZWN0LXJlZnMvbGliL3JlZnMuanMiLCJub2RlX21vZHVsZXMvcGF0aC1pbnRlcnNlY3Rpb24vaW50ZXJzZWN0LmpzIiwibm9kZV9tb2R1bGVzL3NheGVuL2Rpc3QvaW5kZXguZXNtLmpzIiwibm9kZV9tb2R1bGVzL3Njcm9sbC10YWJzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL3NlbGVjdGlvbi11cGRhdGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvdGlueS1zdmcvZGlzdC9pbmRleC5lc20uanMiLCJyZXNvdXJjZXMvYWN0aXZpdGkuanNvbiIsInJlc291cmNlcy9jdXN0b21Db250cm9scy9DdXN0b21Db250ZXh0UGFkLmpzIiwicmVzb3VyY2VzL2N1c3RvbUNvbnRyb2xzL0N1c3RvbVBhbGV0dGUuanMiLCJyZXNvdXJjZXMvY3VzdG9tQ29udHJvbHMvaW5kZXguanMiLCJyZXNvdXJjZXMvY3VzdG9tVHJhbnNsYXRlL2N1c3RvbVRyYW5zbGF0ZS5qcyIsInJlc291cmNlcy9jdXN0b21UcmFuc2xhdGUvdHJhbnNsYXRpb25zR2VybWFuLmpzIiwicmVzb3VyY2VzL25ld0RpYWdyYW0uYnBtbiIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL1Byb3BlcnRpZXNBY3RpdmF0b3IuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9VdGlscy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL2ZhY3RvcnkvQ2hlY2tib3hFbnRyeUZhY3RvcnkuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9mYWN0b3J5L0NvbWJvRW50cnlGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9FbnRyeUZhY3RvcnkuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9mYWN0b3J5L0VudHJ5RmllbGREZXNjcmlwdGlvbi5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL2ZhY3RvcnkvTGFiZWxGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9MaW5rRW50cnlGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9TZWxlY3RFbnRyeUZhY3RvcnkuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9mYWN0b3J5L1RhYmxlRW50cnlGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9UZXh0Qm94RW50cnlGYWN0b3J5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvZmFjdG9yeS9UZXh0SW5wdXRFbnRyeUZhY3RvcnkuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9mYWN0b3J5L1ZhbGlkYXRpb25Bd2FyZVRleHRJbnB1dC5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL2hlbHBlci9Bc3luY0NhcGFibGVIZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9oZWxwZXIvQ2F0ZWdvcnlIZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9oZWxwZXIvQ21kSGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL0VsZW1lbnRIZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL0Zvcm1IZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9oZWxwZXIvSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL0lucHV0T3V0cHV0SGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvaGVscGVyL1BhcnRpY2lwYW50SGVscGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvQWN0aXZpdGlQcm9wZXJ0aWVzUHJvdmlkZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9DcmVhdGVIZWxwZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9DdXN0b21FbGVtZW50c1Byb3BlcnRpZXNBY3RpdmF0b3IuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9FbGVtZW50VGVtcGxhdGVzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvZWxlbWVudC10ZW1wbGF0ZXMvRWxlbWVudFRlbXBsYXRlc0xvYWRlci5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL2VsZW1lbnQtdGVtcGxhdGVzL0hlbHBlci5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL2VsZW1lbnQtdGVtcGxhdGVzL1ZhbGlkYXRvci5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL2VsZW1lbnQtdGVtcGxhdGVzL2NtZC9DaGFuZ2VFbGVtZW50VGVtcGxhdGVIYW5kbGVyLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvZWxlbWVudC10ZW1wbGF0ZXMvY21kL2luZGV4LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvZWxlbWVudC10ZW1wbGF0ZXMvaW5kZXguanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9wYXJ0cy9DaG9vc2VyUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9lbGVtZW50LXRlbXBsYXRlcy9wYXJ0cy9DdXN0b21Qcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL2luZGV4LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvQXN5bmNocm9ub3VzQ29udGludWF0aW9uUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9DYWxsQWN0aXZpdHlQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0NhbmRpZGF0ZVN0YXJ0ZXJQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0NvbmRpdGlvbmFsUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9Db25uZWN0b3JEZXRhaWxQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0Nvbm5lY3RvcklucHV0T3V0cHV0UGFyYW1ldGVyUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9Db25uZWN0b3JJbnB1dE91dHB1dFByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvRXJyb3JFdmVudFByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvRXh0ZXJuYWxUYXNrQ29uZmlndXJhdGlvblByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvRmllbGRJbmplY3Rpb25Qcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0Zvcm1Qcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0hpc3RvcnlUaW1lVG9MaXZlUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9JbnB1dE91dHB1dFBhcmFtZXRlclByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvSW5wdXRPdXRwdXRQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0pvYkNvbmZpZ3VyYXRpb25Qcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL0xpc3RlbmVyRGV0YWlsUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9MaXN0ZW5lckZpZWxkSW5qZWN0aW9uUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9MaXN0ZW5lclByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvTXVsdGlJbnN0YW5jZUxvb3BQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1Byb3BlcnRpZXNQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1NjcmlwdFRhc2tQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1NlcnZpY2VUYXNrRGVsZWdhdGVQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1N0YXJ0RXZlbnRJbml0aWF0b3IuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9UYXNrbGlzdFByb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvVXNlclRhc2tQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL1ZhcmlhYmxlTWFwcGluZ1Byb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvVmVyc2lvblRhZ1Byb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vQXN5bmNDb250aW51YXRpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9DYWxsYWJsZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0NhbmRpZGF0ZVN0YXJ0ZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9EZWxlZ2F0ZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0Vycm9yRXZlbnREZWZpbml0aW9uLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vRXh0ZW5zaW9uRWxlbWVudHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9FeHRlcm5hbC5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0V4dGVybmFsVGFza1ByaW9yaXR5LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vRmllbGRJbmplY3Rpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9IaXN0b3J5VGltZVRvTGl2ZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0ltcGxlbWVudGF0aW9uVHlwZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0lucHV0T3V0cHV0LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vSW5wdXRPdXRwdXRQYXJhbWV0ZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9Kb2JQcmlvcml0eS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL0pvYlJldHJ5VGltZUN5Y2xlLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGkvcGFydHMvaW1wbGVtZW50YXRpb24vTGlzdGVuZXIuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9NdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL1Byb3BlcnRpZXMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9hY3Rpdml0aS9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9SZXN1bHRWYXJpYWJsZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL1NjcmlwdC5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2FjdGl2aXRpL3BhcnRzL2ltcGxlbWVudGF0aW9uL1Rhc2tsaXN0LmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYnBtbi9wYXJ0cy9Eb2N1bWVudGF0aW9uUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL0V2ZW50UHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL0V4ZWN1dGFibGVQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvSWRQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvTGlua1Byb3BzLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYnBtbi9wYXJ0cy9OYW1lUHJvcHMuanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL1Byb2Nlc3NQcm9wcy5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vQ29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbi5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vQ29uZGl0aW9uYWxFdmVudERlZmluaXRpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL2ltcGxlbWVudGF0aW9uL0VsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vRXJyb3JFdmVudERlZmluaXRpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL2ltcGxlbWVudGF0aW9uL0VzY2FsYXRpb25FdmVudERlZmluaXRpb24uanMiLCJyZXNvdXJjZXMvcHJvcGVydGllcy1wYW5lbC9wcm92aWRlci9icG1uL3BhcnRzL2ltcGxlbWVudGF0aW9uL0V2ZW50RGVmaW5pdGlvblJlZmVyZW5jZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vTWVzc2FnZUV2ZW50RGVmaW5pdGlvbi5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vTmFtZS5qcyIsInJlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsL3Byb3ZpZGVyL2JwbW4vcGFydHMvaW1wbGVtZW50YXRpb24vU2lnbmFsRXZlbnREZWZpbml0aW9uLmpzIiwicmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYnBtbi9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9UaW1lckV2ZW50RGVmaW5pdGlvbi5qcyIsInJlc291cmNlcy90b29scy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0FDQ0E7O0FBQ0E7O0FBRUE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFQQTtBQVFBLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxRQUFQLENBQWdCLFFBQWhCLEdBQTJCLElBQTNCLEdBQWtDLE1BQU0sQ0FBQyxRQUFQLENBQWdCLElBQWxFO0FBQ0EsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLFFBQVAsQ0FBZ0IsSUFBaEIsQ0FBcUIsS0FBckIsQ0FBMkIsUUFBM0IsRUFBcUMsQ0FBckMsQ0FBYjtBQUNBLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFMLENBQVcsTUFBTSxDQUFDLFFBQVAsQ0FBZ0IsSUFBM0IsRUFBaUMsQ0FBakMsQ0FBWjtBQUNBLE1BQU0sU0FBUyxHQUFHLE9BQU8sR0FBRyxHQUE1QixDLENBRUE7O0FBQ0EsSUFBSSxxQkFBcUIsR0FBRztBQUN4QixFQUFBLFNBQVMsRUFBRSxDQUFDLE9BQUQsRUFBVSx3QkFBVjtBQURhLENBQTVCO0FBR0EsSUFBSSxTQUFTLEdBQUcscUJBQUUsZUFBRixDQUFoQjtBQUNBLElBQUksTUFBTSxHQUFHLHFCQUFFLFlBQUYsQ0FBYjtBQUNBLElBQUksV0FBVyxHQUFHLElBQUksZ0JBQUosQ0FBZ0I7QUFDOUIsRUFBQSxTQUFTLEVBQUUsTUFEbUI7QUFFOUIsRUFBQSxlQUFlLEVBQUU7QUFDYixJQUFBLE1BQU0sRUFBRTtBQURLLEdBRmE7QUFLOUIsRUFBQSxpQkFBaUIsRUFBRSxDQUNmLDhCQURlLEVBRWYsaUJBRmUsRUFHZix1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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcnZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbklBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7OztBQ1JBOztBQUVBOztBQUVBOzs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDZSxTQUFTLFdBQVQsQ0FBcUIsT0FBckIsRUFBOEI7QUFDM0Msc0JBQVcsSUFBWCxDQUFnQixJQUFoQixFQUFzQixPQUF0QixFQUQyQyxDQUczQzs7O0FBQ0EsT0FBSyxFQUFMLENBQVEs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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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QTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3huVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDMUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNOQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNiQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0pBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDek1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNB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QTtBQUNBO0FBQ0E7QUFDQTs7O0FBQ0EsU0FBUyxHQUFULENBQWEsR0FBYixFQUFrQjtBQUNoQixTQUFPLEdBQUcsQ0FBQyxZQUFYO0FBQ0Q7O0FBRUQsTUFBTSxDQUFDLEdBQVAsR0FBYSxHQUFiOzs7QUN4WUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUN0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O0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7Ozs7OztBQy9qQ2UsTUFBTSxnQkFBTixDQUF1QjtBQUNwQyxFQUFBLFdBQVcsQ0FBQyxNQUFELEVBQVMsVUFBVCxFQUFxQixNQUFyQixFQUE2QixjQUE3QixFQUE2QyxRQUE3QyxFQUF1RCxTQUF2RCxFQUFrRTtBQUMzRSxTQUFLLE1BQUwsR0FBYyxNQUFkO0FBQ0EsU0FBSyxjQUFMLEdBQXNCLGNBQXRCO0FBQ0EsU0FBSyxTQUFMLEdBQWlCLFNBQWpCLENBSDJFLENBSTNFOztBQUNBLFFBQUksTUFBTSxDQUFDLFNBQVAsS0FBcUIsS0FBekIsRUFBZ0M7QUFDOUIsV0FBSyxTQUFMLEdBQWlCLFFBQVEsQ0FBQyxHQUFULENBQWEsV0FBYixFQUEwQixLQUExQixDQUFqQjtBQUNELEtBUDBFLENBUTNFOzs7QUFDQSxJQUFBLFVBQVUsQ0FBQyxnQkFBWCxDQUE0QixJQUE1QjtBQUNEOztBQUNELEVBQUEsb0JBQW9CLENBQUMsT0FBRCxFQUFVO0FBQzVCLFVBQU07QUFDSixNQUFBLFNBREk7QUFFSixNQUFBLE1BRkk7QUFHSixNQUFBLGNBSEk7QUFJSixNQUFBO0FBSkksUUFLRixJQUxKOztBQU9BLGFBQVMsY0FBVCxDQUF3QixLQUF4QixFQUErQixPQUEvQixFQUF3QztBQUN0QyxVQUFJLFNBQUosRUFBZTtBQUNiLGNBQU0sS0FBSyxHQUFHLGNBQWMsQ0FBQyxXQUFmLENBQTJCO0FBQUUsVUFBQSxJQUFJLEVBQUU7QUFBUixTQUEzQixDQUFkO0FBQ0EsUUFBQSxTQUFTLENBQUMsTUFBVixDQUFpQixPQUFqQixFQUEwQixLQUExQjtBQUNELE9BSEQsTUFHTztBQUNMLFFBQUEsbUJBQW1CLENBQUMsS0FBRCxFQUFRLE9BQVIsQ0FBbkI7QUFDRDtBQUNGOztBQUVELGFBQVMsbUJBQVQsQ0FBNkIsS0FBN0IsRUFBb0M7QUFDOUIsWUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLFdBQWYsQ0FBMkI7QUFBRSxRQUFBLElBQUksRUFBRTtBQUFSLE9BQTNCLENBQWQ7QUFDQSxNQUFBLE1BQU0sQ0FBQyxLQUFQLENBQWEsS0FBYixFQUFvQixLQUFwQixFQUEyQixPQUEzQjtBQUNMOztBQUNELGFBQVMsdUJBQVQsQ0FBaUMsS0FBakMsRUFBd0M7QUFDdEMsWUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLFdBQWYsQ0FBMkI7QUFBRSxRQUFBLElBQUksRUFBRTtBQUFSLE9BQTNCLENBQWQ7QUFDQSxNQUFBLE1BQU0sQ0FBQyxLQUFQLENBQWEsS0FBYixFQUFvQixLQUFwQixFQUEyQixPQUEzQjtBQUNEOztBQUVELGFBQVMsa0JBQVQsQ0FBNEIsS0FBNUIsRUFBbUMsT0FBbkMsRUFBNEM7QUFDeEMsVUFBSSxTQUFKLEVBQWU7QUFDWCxjQUFNLEtBQUssR0FBRyxjQUFjLENBQUMsV0FBZixDQUEyQjtBQUFFLFVBQUEsSUFBSSxFQUFFO0FBQVIsU0FBM0IsQ0FBZDtBQUNBLFFBQUEsU0FBUyxDQUFDLE1BQVYsQ0FBaUIsT0FBakIsRUFBMEIsS0FBMUI7QUFDSCxPQUhELE1BR087QUFDSCxRQUFBLHVCQUF1QixDQUFDLEtBQUQsRUFBUSxPQUFSLENBQXZCO0FBQ0g7QUFDSjs7QUFDRCxXQUFPO0FBQ0wsMEJBQW9CO0FBQ2xCLFFBQUEsS0FBSyxFQUFFLE9BRFc7QUFFbEIsUUFBQSxTQUFTLEVBQUUscUJBRk87QUFHbEIsUUFBQSxLQUFLLEVBQUUsU0FBUyxDQUFDLG9CQUFELENBSEU7QUFJbEIsUUFBQSxNQUFNLEVBQUU7QUFDTixVQUFBLEtBQUssRUFBRSxjQUREO0FBRU4sVUFBQSxTQUFTLEVBQUU7QUFGTDtBQUpVLE9BRGY7QUFVTCw4QkFBdUI7QUFDbkIsUUFBQSxLQUFLLEVBQUUsT0FEWTtBQUVuQixRQUFBLFNBQVMsRUFBRSx5QkFGUTtBQUduQixRQUFBLEtBQUssRUFBRSxTQUFTLENBQUMscUJBQUQsQ0FIRztBQUluQixRQUFBLE1BQU0sRUFBRTtBQUNKLFVBQUEsS0FBSyxFQUFFLGtCQURIO0FBRUosVUFBQSxTQUFTLEVBQUU7QUFGUDtBQUpXO0FBVmxCLEtBQVA7QUFvQkQ7O0FBbEVtQzs7O0FBb0V0QyxnQkFBZ0IsQ0FBQyxPQUFqQixHQUEyQixDQUN6QixRQUR5QixFQUV6QixZQUZ5QixFQUd6QixRQUh5QixFQUl6QixnQkFKeUIsRUFLekIsVUFMeUIsRUFNekIsV0FOeUIsQ0FBM0I7Ozs7Ozs7Ozs7QUNwRWUsTUFBTSxhQUFOLENBQW9CO0FBQ2pDLEVBQUEsV0FBVyxDQUFDLE1BQUQsRUFBUyxjQUFULEVBQXlCLE9BQXpCLEVBQWtDLFNBQWxDLEVBQTZDO0FBQ3RELFNBQUssTUFBTCxHQUFjLE1BQWQ7QUFDQSxTQUFLLGNBQUwsR0FBc0IsY0FBdEI7QUFDQSxTQUFLLFNBQUwsR0FBaUIsU0FBakI7QUFDQSxJQUFBLE9BQU8sQ0FBQyxnQkFBUixDQUF5QixJQUF6QjtBQUNEOztBQUVELEVBQUEsaUJBQWlCLENBQUMsT0FBRCxFQUFVO0FBQ3pCLFVBQU07QUFDSixNQUFBLE1BREk7QUFFSixNQUFBLGNBRkk7QUFHSixNQUFBO0FBSEksUUFJRixJQUpKOztBQU1BLGFBQVMsaUJBQVQsQ0FBMkIsS0FBM0IsRUFBa0M7QUFDaEMsWUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLFdBQWYsQ0FBMkI7QUFBRSxRQUFBLElBQUksRUFBRTtBQUFSLE9BQTNCLENBQWQ7QUFDQSxNQUFBLE1BQU0sQ0FBQyxLQUFQLENBQWEsS0FBYixFQUFvQixLQUFwQjtBQUNEOztBQUNDLGFBQVMsa0JBQVQsQ0FBNEIsS0FBNUIsRUFBbUM7QUFDL0IsWUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLFdBQWYsQ0FBMkI7QUFBRSxRQUFBLElBQUksRUFBRTtBQUFSLE9BQTNCLENBQWQ7QUFDQSxNQUFBLE1BQU0sQ0FBQyxLQUFQLENBQWEsS0FBYixFQUFvQixLQUFwQjtBQUNIOztBQUdILFdBQU87QUFDTCwwQkFBb0I7QUFDbEIsUUFBQSxLQUFLLEVBQUUsVUFEVztBQUVsQixRQUFBLFNBQVMsRUFBRSxxQkFGTztBQUdsQixRQUFBLEtBQUssRUFBRSxTQUFTLENBQUMsaUJBQUQsQ0FIRTtBQUlsQixRQUFBLE1BQU0sRUFBRTtBQUNOLFVBQUEsU0FBUyxFQUFFLGlCQURMO0FBRU4sVUFBQSxLQUFLLEVBQUU7QUFGRDtBQUpVLE9BRGY7QUFVSCw4QkFBd0I7QUFDcEIsUUFBQSxLQUFLLEVBQUUsVUFEYTtBQUVwQixRQUFBLFNBQVMsRUFBRSx5QkFGUztBQUdwQixRQUFBLEtBQUssRUFBRSxTQUFTLENBQUMscUJBQUQsQ0FISTtBQUlwQixRQUFBLE1BQU0sRUFBRTtBQUNKLFVBQUEsU0FBUyxFQUFFLGtCQURQO0FBRUosVUFBQSxLQUFLLEVBQUU7QUFGSDtBQUpZO0FBVnJCLEtBQVA7QUFvQkQ7O0FBN0NnQzs7O0FBZ0RuQyxhQUFhLENBQUMsT0FBZCxHQUF3QixDQUN0QixRQURzQixFQUV0QixnQkFGc0IsRUFHdEIsU0FIc0IsRUFJdEIsV0FKc0IsQ0FBeEI7Ozs7Ozs7Ozs7QUNoREE7O0FBQ0E7Ozs7ZUFFZTtBQUNiLEVBQUEsUUFBUSxFQUFFLENBQUUsa0JBQUYsRUFBc0IsZUFBdEIsQ0FERztBQUViLEVBQUEsZ0JBQWdCLEVBQUUsQ0FBRSxNQUFGLEVBQVUseUJBQVYsQ0FGTDtBQUdiLEVBQUEsYUFBYSxFQUFFLENBQUUsTUFBRixFQUFVLHNCQUFWO0FBSEYsQzs7Ozs7Ozs7Ozs7QUNIZjs7OztBQUNlLFNBQVMsZUFBVCxDQUF5QixRQUF6QixFQUFtQyxZQUFuQyxFQUFpRDtBQUM5RCxFQUFBLFlBQVksR0FBRyxZQUFZLElBQUksRUFBL0I7QUFDQSxFQUFBLFFBQVEsR0FBRyw0QkFBYSxRQUFiLEtBQTBCLFFBQXJDO0FBQ0EsU0FBTyxRQUFRLENBQUMsT0FBVCxDQUFpQixZQUFqQixFQUErQixVQUFTLENBQVQsRUFBWSxHQUFaLEVBQWlCO0FBQ3ZELFFBQUksR0FBRyxHQUFHLFlBQVksQ0FBQyxHQUFELENBQXRCOztBQUNDLFFBQUcsNEJBQWEsWUFBWSxDQUFDLEdBQUQsQ0FBekIsS0FBbUMsSUFBbkMsSUFBMkMsNEJBQWMsWUFBWSxDQUFDLEdBQUQsQ0FBMUIsS0FBb0MsV0FBbEYsRUFBOEY7QUFDN0YsTUFBQSxHQUFHLEdBQUcsNEJBQWEsWUFBWSxDQUFDLEdBQUQsQ0FBekIsQ0FBTjtBQUNBOztBQUNBLFdBQVEsR0FBRyxJQUFJLE1BQU0sR0FBTixHQUFZLEdBQTNCO0FBQ0QsR0FOTSxDQUFQO0FBT0Q7Ozs7Ozs7OztlQ1hjO0FBQ1g7QUFDQSxzQ0FBcUMsVUFGMUI7QUFHWCxtQkFBaUIsV0FITjtBQUlYLHFCQUFtQixVQUpSO0FBS1gsaUJBQWMsT0FMSDtBQU1YLG9CQUFpQixPQU5OO0FBT1gsd0NBQXFDLGFBUDFCO0FBUVgsb0JBQWtCLFFBUlA7QUFTWCwyQkFBeUIsUUFUZDtBQVVYLDZCQUEyQixRQVZoQjtBQVdYLG9CQUFrQixRQVhQO0FBWVgsa0NBQWdDLFFBWnJCO0FBYVgsaUJBQWUsTUFiSjtBQWNYLCtCQUE2QixRQWRsQjtBQWVYLHVEQUFxRCxnQkFmMUM7QUFnQlgsd0NBQXNDLFlBaEIzQjtBQWlCWCxZQUFVLElBakJDO0FBa0JYLDRCQUEwQixRQWxCZjtBQW1CWCw2QkFBMkIsUUFuQmhCO0FBb0JYLDJDQUF5QyxhQXBCOUI7QUFxQlgsZ0NBQThCLFNBckJuQjtBQXNCWCxpREFBZ0QsZUF0QnJDO0FBdUJYLDZCQUEyQixTQXZCaEI7QUF3QlgsNkJBQTJCLFFBeEJoQjtBQXlCWCwrQkFBNkIsUUF6QmxCO0FBMEJYLHlCQUFzQixRQTFCWDtBQTJCWCx3QkFBcUIsUUEzQlY7QUE0QlgsVUFBUSxJQTVCRztBQTZCWCxZQUFVLElBN0JDO0FBOEJYLG1CQUFpQixXQTlCTjtBQStCWCxpQkFBYyxNQS9CSDtBQWdDWCx1QkFBb0IsUUFoQ1Q7QUFpQ1gscUJBQWtCLFFBakNQO0FBa0NYLGtCQUFlLEtBbENKO0FBbUNYLFVBQVEsSUFuQ0c7QUFvQ1gsZUFBYSxNQXBDRjtBQXFDWCxrQkFBZ0IsTUFyQ0w7QUFzQ1gsZUFBYSxNQXRDRjtBQXVDWCxpQkFBZSxNQXZDSjtBQXdDWCx3QkFBc0IsUUF4Q1g7QUF5Q1gsa0JBQWdCLE1BekNMO0FBMENYLGlCQUFlLE1BMUNKO0FBMkNYLG1CQUFpQixNQTNDTjtBQTRDWCw2QkFBMkIsVUE1Q2hCO0FBNkNYLDRCQUEwQixVQTdDZjtBQThDWCxpQkFBZSxNQTlDSjtBQStDWCxnQkFBYyxNQS9DSDtBQWdEWCw4QkFBNEIsTUFoRGpCO0FBaURYLGVBQWEsTUFqREY7QUFrRFgsY0FBWSxNQWxERDtBQW1EWCxvQkFBa0IsTUFuRFA7QUFvRFgsYUFBVSxJQXBEQztBQXFEWCx3Q0FBc0MsV0FyRDNCO0FBc0RYLHlCQUF1QixRQXREWjtBQXVEWCx1QkFBcUIsUUF2RFY7QUF3RFgsNkJBQTJCLFFBeERoQjtBQXlEWCx3QkFBc0IsUUF6RFg7QUEwRFgsdUJBQXFCLFFBMURWO0FBMkRYLDRCQUEwQixRQTNEZjtBQTREWCw4QkFBNEIsUUE1RGpCO0FBNkRYLDRDQUEwQyxhQTdEL0I7QUE4RFgsMENBQXdDLGFBOUQ3QjtBQStEWCxnREFBOEMsYUEvRG5DO0FBZ0VYLDJDQUF5QyxhQWhFOUI7QUFpRVgsK0NBQTZDLGFBakVsQztBQWtFWCxzQ0FBb0MsVUFsRXpCO0FBbUVYLHNDQUFvQyxVQW5FekI7QUFvRVgsb0NBQWtDLFVBcEV2QjtBQXFFWCx5Q0FBdUMsVUFyRTVCO0FBc0VYLDBDQUF3QyxVQXRFN0I7QUF1RVgsbUNBQWlDLFVBdkV0QjtBQXdFWCxtQ0FBaUMsVUF4RXRCO0FBeUVYLDJDQUF5QyxVQXpFOUI7QUEwRVgscUNBQW1DLFVBMUV4QjtBQTJFWCxxQ0FBbUMsVUEzRXhCO0FBNEVYLHVCQUFxQixRQTVFVjtBQTZFWCwwQkFBd0IsUUE3RWI7QUE4RVgscUJBQW1CLFFBOUVSO0FBK0VYLHNCQUFvQixRQS9FVDtBQWdGWCw0QkFBMEIsUUFoRmY7QUFpRlgsc0JBQW9CLFFBakZUO0FBa0ZYLHlCQUF1QixRQWxGWjtBQW1GWCw0QkFBMEIsUUFuRmY7QUFvRlgsK0NBQTZDLGFBcEZsQztBQXFGWCwwQkFBd0IsUUFyRmI7QUFzRlgsNkNBQTJDLGFBdEZoQztBQXVGWCwrQkFBNkIsUUF2RmxCO0FBd0ZYLGtEQUFnRCxhQXhGckM7QUF5RlgsZ0NBQThCLFFBekZuQjtBQTBGWCxtREFBaUQsYUExRnRDO0FBMkZYLDBCQUF3QixRQTNGYjtBQTRGWCwyQkFBeUIsUUE1RmQ7QUE2RlgsMkJBQXlCLFFBN0ZkO0FBOEZYLDhDQUE0QyxhQTlGakM7QUErRlgsaUNBQStCLFFBL0ZwQjtBQWdHWCx1QkFBcUIsTUFoR1Y7QUFpR1gsc0JBQW9CLE1BakdUO0FBa0dYLHVCQUFxQixNQWxHVjtBQW1HWCxxQkFBbUIsTUFuR1I7QUFvR1gseUJBQXVCLE1BcEdaO0FBcUdYLGlCQUFlLElBckdKO0FBc0dYLGlCQUFlLEtBdEdKO0FBdUdYLHVCQUFxQixPQXZHVjtBQXdHWCxvQkFBa0IsS0F4R1A7QUF5R1gsbUJBQWlCLEtBekdOO0FBMEdYO0FBQ0EseUNBQXVDLDBCQTNHNUI7QUE0R1gsNkJBQTJCLFdBNUdoQjtBQTZHWCwwREFBd0QsZ0JBN0c3QztBQThHWCwyQkFBeUIsdUJBOUdkO0FBK0dYLG1DQUFpQyxjQS9HdEI7QUFnSFgsc0JBQW9CLFFBaEhUO0FBaUhYLDBDQUF3QyxjQWpIN0I7QUFrSFgsMkJBQXlCLFdBbEhkO0FBbUhYLDRDQUEwQyxhQW5IL0I7QUFvSFgsMkVBQXlFLDRDQXBIOUQ7QUFxSFgsZ0NBQThCLGdCQXJIbkI7QUFzSFgsZ0NBQThCLGVBdEhuQjtBQXVIWDtBQUNBLFFBQUssSUF4SE07QUF5SFgsVUFBTyxJQXpISTtBQTBIWCxhQUFVLElBMUhDO0FBMkhYLGFBQVUsSUEzSEM7QUE0SFgsa0JBQWUsTUE1SEo7QUE2SFgsYUFBVSxJQTdIQztBQThIWCxlQUFZLEtBOUhEO0FBK0hYLGdDQUE2QixNQS9IbEI7QUFnSVgseUJBQXNCLEtBaElYO0FBaUlYLHdCQUFxQixLQWpJVjtBQWtJWCx1QkFBb0IsTUFsSVQ7QUFtSVgsZUFBWSxJQW5JRDtBQW9JWCxrQkFBZSxPQXBJSjtBQXFJWCxzQkFBbUIsUUFySVI7QUFzSVgsbUJBQWdCLElBdElMO0FBdUlYLDJCQUF3QixNQXZJYjtBQXdJWCwyQkFBd0IsTUF4SWI7QUF5SVgsMEJBQXVCLFNBeklaO0FBMElYLFdBQVEsSUExSUc7QUEySVgsY0FBVyxPQTNJQTtBQTRJWCxpQkFBYyxNQTVJSDtBQTZJWCxrQkFBZSxPQTdJSjtBQThJWCxnQkFBYSxNQTlJRjtBQStJWCxRQUFLLElBL0lNO0FBZ0pYLFVBQU8sSUFoSkk7QUFpSlgsV0FBUSxJQWpKRztBQWtKWCxtQkFBZ0IsS0FsSkw7QUFtSlgsZ0JBQWEsSUFuSkY7QUFvSlgsb0JBQWlCLE1BcEpOO0FBcUpYLFlBQVMsSUFySkU7QUFzSlgsZ0JBQWEsSUF0SkY7QUF1Slgsa0JBQWUsTUF2Sko7QUF3SlgsV0FBUSxHQXhKRztBQXlKWCxTQUFNLElBekpLO0FBMEpYLFlBQVMsR0ExSkU7QUEySlgsZUFBWSxLQTNKRDtBQTRKWCxlQUFZLEtBNUpEO0FBNkpYLHdCQUFxQixNQTdKVjtBQThKWCxnQkFBYSxNQTlKRjtBQStKWCxtQkFBZ0IsT0EvSkw7QUFnS1gsZ0JBQWEsT0FoS0Y7QUFpS1gsZ0JBQWEsS0FqS0Y7QUFrS1gsMEJBQXVCLFNBbEtaO0FBbUtYLHlCQUFzQixPQW5LWDtBQW9LWCxZQUFTLElBcEtFO0FBcUtYLG1CQUFnQixNQXJLTDtBQXNLWCxpQkFBYyxNQXRLSDtBQXVLWCxtQkFBZ0IsTUF2S0w7QUF3S1gscUJBQWtCLE1BeEtQO0FBeUtYLGNBQVcsSUF6S0E7QUEwS1gscUJBQWtCLE1BMUtQO0FBMktYLGdCQUFhLElBM0tGO0FBNEtYLGtCQUFlLE9BNUtKO0FBNktYLHNCQUFtQixNQTdLUjtBQThLWCx1QkFBb0IsTUE5S1Q7QUErS1gsZ0JBQWEsSUEvS0Y7QUFnTFgsc0JBQW1CLE1BaExSO0FBaUxYLDJCQUF3QixTQWpMYjtBQWtMWCxzQkFBbUIsT0FsTFI7QUFtTFgsVUFBTyxJQW5MSTtBQW9MWCxjQUFXLElBcExBO0FBcUxYLFdBQVEsSUFyTEc7QUFzTFgsWUFBUyxJQXRMRTtBQXVMWCxpQkFBYyxNQXZMSDtBQXdMWCxnQkFBYSxJQXhMRjtBQXlMWCxXQUFRLElBekxHO0FBMExYLGVBQVksTUExTEQ7QUEyTFgsZUFBWSxNQTNMRDtBQTRMWCxtQkFBZ0IsTUE1TEw7QUE2TFgsb0JBQWlCLE1BN0xOO0FBOExYLDRFQUF5RSxhQTlMOUQ7QUErTFgseUJBQXNCLE1BL0xYO0FBZ01YLGtCQUFlLE1BaE1KO0FBaU1YLGlCQUFjLE1Bak1IO0FBa01YLGdCQUFhLE9BbE1GO0FBbU1YLGlDQUE4QixRQW5NbkI7QUFvTVgsbUJBQWdCLE9BcE1MO0FBcU1YLGNBQVcsSUFyTUE7QUFzTVgsZUFBWSxLQXRNRDtBQXVNWCw4QkFBMkIsU0F2TWhCO0FBd01YLGtCQUFlLE9BeE1KO0FBeU1YLG9CQUFpQixNQXpNTjtBQTBNWCxzQkFBbUIsTUExTVI7QUEyTVgsWUFBUyxJQTNNRTtBQTRNWCxxQkFBa0IsTUE1TVA7QUE2TVgsV0FBUSxJQTdNRztBQThNWCx5QkFBc0IsT0E5TVg7QUErTVgscUJBQWtCLE1BL01QO0FBZ05YLGNBQVcsS0FoTkE7QUFpTlgscUJBQWtCLE1Bak5QO0FBa05YLHNCQUFtQixLQWxOUjtBQW1OWCxjQUFXLE1Bbk5BO0FBb05YLG9CQUFpQixNQXBOTjtBQXFOWCxjQUFXLEtBck5BO0FBc05YLHdHQUFxRyxpRUF0TjFGO0FBdU5YLGtHQUErRixpRUF2TnBGO0FBd05YLGVBQVksSUF4TkQ7QUF5TlgscUNBQWtDLFFBek52QjtBQTBOWCxtQkFBZ0IsT0ExTkw7QUEyTlgsOEJBQTJCLE9BM05oQjtBQTROWCw2QkFBMEIsUUE1TmY7QUE2TlgsNEJBQXlCLFFBN05kO0FBOE5YLGVBQVksSUE5TkQ7QUErTlgsNERBQXlELGFBL045QztBQWdPWCwyREFBd0QsY0FoTzdDO0FBaU9YLDhDQUEyQyxhQWpPaEM7QUFrT1gsdUJBQW9CLFFBbE9UO0FBbU9YLG9CQUFpQixNQW5PTjtBQW9PWCxxQkFBa0IsUUFwT1A7QUFxT1gseUJBQXNCLFFBck9YO0FBc09YLG9CQUFpQixNQXRPTjtBQXVPWCxnQ0FBNkIsVUF2T2xCO0FBd09YLCtCQUE0QixVQXhPakI7QUF5T1gsb0JBQWlCLEtBek9OO0FBME9YLHNCQUFtQixNQTFPUjtBQTJPWCxnQkFBYSxTQTNPRjtBQTRPWCxzQkFBbUIsTUE1T1I7QUE2T1gsMEJBQXVCO0FBN09aLEM7Ozs7QUNBZjtBQUNBOztBQ0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaE1BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5aEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcElBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9PQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdmRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDYkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsd0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVkQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaE5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDZkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM5Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN1lBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2puQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzNPQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdFRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqT0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1V0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xTQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDak5BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdLQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0SkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDL0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdEpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7Ozs7O0FDcklBOzs7O0FBTkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUdBLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxR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Q0FBQyxLQUFELENBQWpCLEVBQXlCO0FBQ3JCLFVBQUksR0FBRyxHQUFDO0FBQ0osZ0JBQVEsSUFBSSxDQUFDLEtBQUQsQ0FBSixDQUFZLENBQVosQ0FESjtBQUVKLGtCQUFTLE9BRkw7QUFHSixnQkFBTztBQUhILE9BQVI7QUFLQSxNQUFBLFNBQVMsQ0FBQyxJQUFWLENBQWUsR0FBZjtBQUNIOztBQUNELFNBQUksSUFBSSxDQUFSLElBQWEsSUFBSSxDQUFDLGFBQUQsQ0FBakIsRUFBaUM7QUFDN0IsVUFBSSxHQUFHLEdBQUM7QUFDSixnQkFBUSxJQUFJLENBQUMsYUFBRCxDQUFKLENBQW9CLENBQXBCLENBREo7QUFFSixrQkFBUyxPQUZMO0FBR0osZ0JBQU87QUFISCxPQUFSO0FBS0EsTUFBQSxTQUFTLENBQUMsSUFBVixDQUFlLEdBQWY7QUFDSDs7QUFDRCxXQUFPLFNBQVA7QUFDSDs7QUEvUFMsQ0FBZDtlQXFRZSxLIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiByKGUsbix0KXtmdW5jdGlvbiBvKGksZil7aWYoIW5baV0pe2lmKCFlW2ldKXt2YXIgYz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByZXF1aXJlJiZyZXF1aXJlO2lmKCFmJiZjKXJldHVybiBjKGksITApO2lmKHUpcmV0dXJuIHUoaSwhMCk7dmFyIGE9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitpK1wiJ1wiKTt0aHJvdyBhLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsYX12YXIgcD1uW2ldPXtleHBvcnRzOnt9fTtlW2ldWzBdLmNhbGwocC5leHBvcnRzLGZ1bmN0aW9uKHIpe3ZhciBuPWVbaV1bMV1bcl07cmV0dXJuIG8obnx8cil9LHAscC5leHBvcnRzLHIsZSxuLHQpfXJldHVybiBuW2ldLmV4cG9ydHN9Zm9yKHZhciB1PVwiZnVuY3Rpb25cIj09dHlwZW9mIHJlcXVpcmUmJnJlcXVpcmUsaT0wO2k8dC5sZW5ndGg7aSsrKW8odFtpXSk7cmV0dXJuIG99cmV0dXJuIHJ9KSgpIiwiXG5pbXBvcnQgJCBmcm9tICdqcXVlcnknO1xuaW1wb3J0IEJwbW5Nb2RlbGVyIGZyb20gJ2JwbW4tanMvbGliL01vZGVsZXInO1xuLy9pbXBvcnQgcHJvcGVydGllc1BhbmVsTW9kdWxlIGZyb20gJy4uL3Jlc291cmNlcy9wcm9wZXJ0aWVzLXBhbmVsJztcbmltcG9ydCBwcm9wZXJ0aWVzUGFuZWxNb2R1bGUgZnJvbSAnYnBtbi1qcy1wcm9wZXJ0aWVzLXBhbmVsJztcbmltcG9ydCBwcm9wZXJ0aWVzUHJvdmlkZXJNb2R1bGUgZnJvbSAnLi4vcmVzb3VyY2VzL3Byb3BlcnRpZXMtcGFuZWwvcHJvdmlkZXIvYWN0aXZpdGknO1xuaW1wb3J0IGFjdGl2aXRpTW9kZGxlRGVzY3JpcHRvciBmcm9tICcuLi9yZXNvdXJjZXMvYWN0aXZpdGkuanNvbic7XG5pbXBvcnQgY3VzdG9tVHJhbnNsYXRlIGZyb20gJy4uL3Jlc291cmNlcy9jdXN0b21UcmFuc2xhdGUvY3VzdG9tVHJhbnNsYXRlJztcbmltcG9ydCBjdXN0b21Db250cm9sc01vZHVsZSBmcm9tICcuLi9yZXNvdXJjZXMvY3VzdG9tQ29udHJvbHMnO1xuaW1wb3J0IHRvb2xzIGZyb20gJy4uL3Jlc291cmNlcy90b29scydcbmltcG9ydCBkaWFncmFtWE1MIGZyb20gJy4uL3Jlc291cmNlcy9uZXdEaWFncmFtLmJwbW4nO1xuY29uc3QgcHJvSG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0O1xuY29uc3QgaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KFwiYnBtbmpzXCIpWzBdO1xuY29uc3Qga2V5ID0gaHJlZi5zcGxpdCh3aW5kb3cubG9jYXRpb24uaG9zdClbMV07XG5jb25zdCBwdWJsaWN1cmwgPSBwcm9Ib3N0ICsga2V5O1xuXG4vLyDmt7vliqDnv7vor5Hnu4Tku7ZcbnZhciBjdXN0b21UcmFuc2xhdGVNb2R1bGUgPSB7XG4gICAgdHJhbnNsYXRlOiBbJ3ZhbHVlJywgY3VzdG9tVHJhbnNsYXRlXVxufTtcbnZhciBjb250YWluZXIgPSAkKCcjanMtZHJvcC16b25lJyk7XG52YXIgY2FudmFzID0gJCgnI2pzLWNhbnZhcycpO1xudmFyIGJwbW5Nb2RlbGVyID0gbmV3IEJwbW5Nb2RlbGVyKHtcbiAgICBjb250YWluZXI6IGNhbnZhcyxcbiAgICBwcm9wZXJ0aWVzUGFuZWw6IHtcbiAgICAgICAgcGFyZW50OiAnI2pzLXByb3BlcnRpZXMtcGFuZWwnXG4gICAgfSxcbiAgICBhZGRpdGlvbmFsTW9kdWxlczogW1xuICAgICAgICBwcm9wZXJ0aWVzUGFuZWxNb2R1bGUsXG4gICAgICAgIHByb3BlcnRpZXNQcm92aWRlck1vZHVsZSxcbiAgICAgICAgY3VzdG9tQ29udHJvbHNNb2R1bGUsXG4gICAgICAgIGN1c3RvbVRyYW5zbGF0ZU1vZHVsZVxuICAgIF0sXG4gICAgbW9kZGxlRXh0ZW5zaW9uczoge1xuICAgICAgICBhY3Rpdml0aTphY3Rpdml0aU1vZGRsZURlc2NyaXB0b3JcbiAgICB9XG59KTtcbmNvbnRhaW5lci5yZW1vdmVDbGFzcygnd2l0aC1kaWFncmFtJyk7XG4vLyDliKTmlq3mtY/op4jlmajmlK/mjIHnqIvluqZcbmlmICghd2luZG93LkZpbGVMaXN0IHx8ICF3aW5kb3cuRmlsZVJlYWRlcikge1xuICAgIHdpbmRvdy5hbGVydCgn6K+35L2/55So6LC35q2M44CB54Gr54uQ44CBSUUxMCvmtY/op4jlmagnKTtcbn0gZWxzZSB7XG4gICAgdG9vbHMucmVnaXN0ZXJGaWxlRHJvcChjb250YWluZXIsIHRvb2xzLmNyZWF0ZURpYWdyYW0oZGlhZ3JhbVhNTCwgYnBtbk1vZGVsZXIsIGNvbnRhaW5lcikpO1xufVxuXG5cbiQoZnVuY3Rpb24gKCkge1xuICAgIC8vIOWIm+W7umJwbW5cbiAgICB2YXIgcGFyYW0gPSB0b29scy5nZXRVcmxQYXJhbSh3aW5kb3cubG9jYXRpb24uaHJlZilcbiAgICAgICAgJCgnLml0ZW0nKS5zaG93KClcbiAgICBpZiAocGFyYW0udHlwZSA9PT0gJ2FkZEJwbW4nKSB7XG4gICAgICAgIHRvb2xzLmNyZWF0ZURpYWdyYW0oZGlhZ3JhbVhNTCwgYnBtbk1vZGVsZXIsIGNvbnRhaW5lcik7XG4gICAgfSBlbHNlIGlmIChwYXJhbS50eXBlID09PSAnbG9va0JwbW4nKSB7IC8v57yW6L6RYnBtblxuICAgICAgICAkKCcuaXRlbScpLmhpZGUoKVxuICAgICAgICAkKCcuZG93bmxvYWQnKS5zaG93KClcbiAgICAgICAgY29uc3QgSWQgPSBwYXJhbS5kZXBsb3ltZW50RmlsZVVVSUQgfHwgJzZkNGFmMmRjLWJhYjAtMTFlYS1iNTg0LTNjZjAxMWVhYWZjYSdcbiAgICAgICAgY29uc3QgTmFtZT1wYXJhbS5kZXBsb3ltZW50TmFtZSB8fCAnU3RyaW5nLmJwbW4nXG4gICAgICAgIGNvbnN0IGluc3RhbmNlSWQ9cGFyYW0uaW5zdGFuY2VJZFxuICAgICAgICB2YXIgcGFyYW09e1xuICAgICAgICAgICAgXCJkZXBsb3ltZW50SWRcIjpJZCxcbiAgICAgICAgICAgIFwicmVzb3VyY2VOYW1lXCI6ZGVjb2RlVVJJKE5hbWUpXG4gICAgICAgIH1cbiAgICAgICAgaWYoaW5zdGFuY2VJZCl7XG4gICAgICAgICAgICB2YXIgcGFyYW0xPXtcbiAgICAgICAgICAgICAgICBpbnN0YW5jZUlkXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJWVUVfQVBQX0JBU0VfQVBJXCIpKycvYWN0aXZpdGlIaXN0b3J5L2dldGhpZ2hMaW5lJyxcbiAgICAgICAgICAgICAgICAvLyB1cmw6ICdodHRwOi8vbG9jYWxob3N0OjgwODAvYWN0aXZpdGlIaXN0b3J5L2dldGhpZ2hMaW5lJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnR0VUJyxcbiAgICAgICAgICAgICAgICBkYXRhOiBwYXJhbTEsXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6J2pzb24nLFxuICAgICAgICAgICAgICAgIHN1Y2Nlc3M6IGZ1bmN0aW9uIChyZXN1bHQpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdClcbiAgICAgICAgICAgICAgICAgIHZhciBDb2xvckpzb249dG9vbHMuZ2V0QnlDb2xvcihyZXN1bHQuZGF0YSlcbiAgICAgICAgICAgICAgICAgICAgJC5hamF4KHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHVybDogbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJWVUVfQVBQX0JBU0VfQVBJXCIpKycvcHJvY2Vzc0RlZmluaXRpb24vZ2V0RGVmaW5pdGlvblhNTCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB1cmw6ICdodHRwOi8vbG9jYWxob3N0OjgwODAvcHJvY2Vzc0RlZmluaXRpb24vZ2V0RGVmaW5pdGlvblhNTCcsXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlOiAnR0VUJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IHBhcmFtLFxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YVR5cGU6J3RleHQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciBuZXdYbWxEYXRhID0gcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9vbHMuY3JlYXRlRGlhZ3JhbShuZXdYbWxEYXRhLCBicG1uTW9kZWxlciwgY29udGFpbmVyKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBDb2xvckpzb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xzLnNldENvbG9yKENvbG9ySnNvbltpXSxicG1uTW9kZWxlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIDIwMClcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycilcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1lbHNle1xuICAgICAgICAgICAgLy/liqDovb3lkI7lj7Dmlrnms5Xojrflj5Z4bWxcbiAgICAgICAgICAgICQuYWpheCh7XG4gICAgICAgICAgICAgICAgdXJsOiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcIlZVRV9BUFBfQkFTRV9BUElcIikrJy9wcm9jZXNzRGVmaW5pdGlvbi9nZXREZWZpbml0aW9uWE1MJyxcbiAgICAgICAgICAgICAgLy8gdXJsOiAnaHR0cDovL2xvY2FsaG9zdDo4MDgwL3Byb2Nlc3NEZWZpbml0aW9uL2dldERlZmluaXRpb25YTUwnLFxuICAgICAgICAgICAgICAgIHR5cGU6ICdHRVQnLFxuICAgICAgICAgICAgICAgIGRhdGE6IHBhcmFtLFxuICAgICAgICAgICAgICAgIGRhdGFUeXBlOid0ZXh0JyxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXdYbWxEYXRhID0gcmVzdWx0XG4gICAgICAgICAgICAgICAgICAgIHRvb2xzLmNyZWF0ZURpYWdyYW0obmV3WG1sRGF0YSwgYnBtbk1vZGVsZXIsIGNvbnRhaW5lcik7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYocGFyYW0udHlwZSA9PT0gXCJoaXN0b3J5QnBtblwiKSB7IC8vIGJwbW7ljoblj7JcbiAgICAgICAgJCgnLml0ZW0nKS5oaWRlKClcbiAgICAgICAgJCgnLmRvd25sb2FkJykuc2hvdygpXG4gICAgfVxuICAgIC8vIOeCueWHu+aWsOWinlxuICAgICQoJyNqcy1kb3dubG9hZC1kaWFncmFtJykub24oXCJjbGlja1wiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgdG9vbHMuc3lvcGVuKCdhbGVydCcpXG4gICAgfSlcblxuICAgIC8vIOeCueWHu+WPlua2iFxuICAgICQoJy5jYW5jZWwnKS5vbihcImNsaWNrXCIsZnVuY3Rpb24gKCkge1xuICAgICAgICB0b29scy5zeWhpZGUoJ2FsZXJ0JylcbiAgICB9KVxuICAgIC8vIOeCueWHu+ehruWumlxuICAgICQoJyNzdXJlJykub24oJ2NsaWNrJyxmdW5jdGlvbigpe1xuICAgICAgIC8vIGNvbnN0IHRleHQ9JChcIiNkZXBsb3ltZW50TmFtZVwiKS52YWwoKVxuICAgICAgICB0b29scy5zYXZlQnBtbihicG1uTW9kZWxlcilcbiAgICB9KVxuXG5cblxuICAgIC8vIOeCueWHu+S4i+i9vVxuICAgICQoXCIjZG93bmxvYWRCcG1uXCIpLm9uKFwiY2xpY2tcIiwgZnVuY3Rpb24gKCkge1xuICAgICAgICB0b29scy5kb3duTG9hZChicG1uTW9kZWxlcilcbiAgICB9KVxuICAgIC8vIOeCueWHu+S4iuS8oFxuICAgICQoXCIjdXBsb2FkRmlsZVwiKS5vbihcImNoYW5nZVwiLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRvb2xzLnVwbG9hZChicG1uTW9kZWxlcixjb250YWluZXIpXG4gICAgfSlcbn0pO1xuIiwibW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL2xpYicpO1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4vVXRpbHMnKS5lc2NhcGVIVE1MO1xuXG52YXIgZG9taWZ5ID0gcmVxdWlyZSgnbWluLWRvbScpLmRvbWlmeSxcbiAgICBkb21RdWVyeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeSxcbiAgICBkb21RdWVyeUFsbCA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeUFsbCxcbiAgICBkb21SZW1vdmUgPSByZXF1aXJlKCdtaW4tZG9tJykucmVtb3ZlLFxuICAgIGRvbUNsYXNzZXMgPSByZXF1aXJlKCdtaW4tZG9tJykuY2xhc3NlcyxcbiAgICBkb21DbG9zZXN0ID0gcmVxdWlyZSgnbWluLWRvbScpLmNsb3Nlc3QsXG4gICAgZG9tQXR0ciA9IHJlcXVpcmUoJ21pbi1kb20nKS5hdHRyLFxuICAgIGRvbURlbGVnYXRlID0gcmVxdWlyZSgnbWluLWRvbScpLmRlbGVnYXRlLFxuICAgIGRvbU1hdGNoZXMgPSByZXF1aXJlKCdtaW4tZG9tJykubWF0Y2hlcztcblxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpLFxuICAgIGZpbHRlciA9IHJlcXVpcmUoJ2xvZGFzaC9maWx0ZXInKSxcbiAgICBnZXQgPSByZXF1aXJlKCdsb2Rhc2gvZ2V0JyksXG4gICAga2V5cyA9IHJlcXVpcmUoJ2xvZGFzaC9rZXlzJyksXG4gICAgaXNFbXB0eSA9IHJlcXVpcmUoJ2xvZGFzaC9pc0VtcHR5JyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJ2xvZGFzaC9pc0FycmF5JyksXG4gICAgeG9yID0gcmVxdWlyZSgnbG9kYXNoL3hvcicpLFxuICAgIGRlYm91bmNlID0gcmVxdWlyZSgnbG9kYXNoL2RlYm91bmNlJyk7XG5cbnZhciB1cGRhdGVTZWxlY3Rpb24gPSByZXF1aXJlKCdzZWxlY3Rpb24tdXBkYXRlJyk7XG5cbnZhciBzY3JvbGxUYWJzID0gcmVxdWlyZSgnc2Nyb2xsLXRhYnMnKS5kZWZhdWx0O1xuXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xuXG52YXIgSElERV9DTEFTUyA9ICdicHAtaGlkZGVuJztcbnZhciBERUJPVU5DRV9ERUxBWSA9IDMwMDtcblxuXG5mdW5jdGlvbiBpc1RvZ2dsZShub2RlKSB7XG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdjaGVja2JveCcgfHwgbm9kZS50eXBlID09PSAncmFkaW8nO1xufVxuXG5mdW5jdGlvbiBpc1NlbGVjdChub2RlKSB7XG4gIHJldHVybiBub2RlLnR5cGUgPT09ICdzZWxlY3Qtb25lJztcbn1cblxuZnVuY3Rpb24gaXNDb250ZW50RWRpdGFibGUobm9kZSkge1xuICByZXR1cm4gZG9tQXR0cihub2RlLCAnY29udGVudGVkaXRhYmxlJyk7XG59XG5cbmZ1bmN0aW9uIGdldFByb3BlcnR5UGxhY2Vob2xkZXJzKG5vZGUpIHtcbiAgdmFyIHNlbGVjdG9yID0gJ2lucHV0W25hbWVdLCB0ZXh0YXJlYVtuYW1lXSwgW2RhdGEtdmFsdWVdLCBbY29udGVudGVkaXRhYmxlXSc7XG4gIHZhciBwbGFjZWhvbGRlcnMgPSBkb21RdWVyeUFsbChzZWxlY3Rvciwgbm9kZSk7XG4gIGlmICgoIXBsYWNlaG9sZGVycyB8fCAhcGxhY2Vob2xkZXJzLmxlbmd0aCkgJiYgZG9tTWF0Y2hlcyhub2RlLCBzZWxlY3RvcikpIHtcbiAgICBwbGFjZWhvbGRlcnMgPSBbIG5vZGUgXTtcbiAgfVxuICByZXR1cm4gcGxhY2Vob2xkZXJzO1xufVxuXG4vKipcbiAqIFJldHVybiBhbGwgYWN0aXZlIGZvcm0gY29udHJvbHMuXG4gKiBUaGlzIGV4Y2x1ZGVzIHRoZSBpbnZpc2libGUgY29udHJvbHMgdW5sZXNzIGFsbCBpcyB0cnVlXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBub2RlXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFthbGw9ZmFsc2VdXG4gKi9cbmZ1bmN0aW9uIGdldEZvcm1Db250cm9scyhub2RlLCBhbGwpIHtcbiAgdmFyIGNvbnRyb2xzID0gZG9tUXVlcnlBbGwoJ2lucHV0W25hbWVdLCB0ZXh0YXJlYVtuYW1lXSwgc2VsZWN0W25hbWVdLCBbY29udGVudGVkaXRhYmxlXScsIG5vZGUpO1xuXG4gIGlmICghY29udHJvbHMgfHwgIWNvbnRyb2xzLmxlbmd0aCkge1xuICAgIGNvbnRyb2xzID0gZG9tTWF0Y2hlcyhub2RlLCAnb3B0aW9uJykgPyBbIG5vZGUgXSA6IGNvbnRyb2xzO1xuICB9XG5cbiAgaWYgKCFhbGwpIHtcbiAgICBjb250cm9scyA9IGZpbHRlcihjb250cm9scywgZnVuY3Rpb24obm9kZSkge1xuICAgICAgcmV0dXJuICFkb21DbG9zZXN0KG5vZGUsICcuJyArIEhJREVfQ0xBU1MpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRyb2xzO1xufVxuXG5mdW5jdGlvbiBnZXRGb3JtQ29udHJvbFZhbHVlc0luU2NvcGUoZW50cnlOb2RlKSB7XG4gIHZhciB2YWx1ZXMgPSB7fTtcblxuICB2YXIgY29udHJvbE5vZGVzID0gZ2V0Rm9ybUNvbnRyb2xzKGVudHJ5Tm9kZSk7XG5cbiAgZm9yRWFjaChjb250cm9sTm9kZXMsIGZ1bmN0aW9uKGNvbnRyb2xOb2RlKSB7XG4gICAgdmFyIHZhbHVlID0gY29udHJvbE5vZGUudmFsdWU7XG5cbiAgICB2YXIgbmFtZSA9IGRvbUF0dHIoY29udHJvbE5vZGUsICduYW1lJykgfHwgZG9tQXR0cihjb250cm9sTm9kZSwgJ2RhdGEtbmFtZScpO1xuXG4gICAgLy8gdGFrZSB0b2dnbGUgc3RhdGUgaW50byBhY2NvdW50IGZvciByYWRpbyAvIGNoZWNrYm94ZXNcbiAgICBpZiAoaXNUb2dnbGUoY29udHJvbE5vZGUpKSB7XG4gICAgICBpZiAoY29udHJvbE5vZGUuY2hlY2tlZCkge1xuICAgICAgICBpZiAoIWRvbUF0dHIoY29udHJvbE5vZGUsICd2YWx1ZScpKSB7XG4gICAgICAgICAgdmFsdWUgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhbHVlID0gY29udHJvbE5vZGUudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlID0gbnVsbDtcbiAgICAgIH1cbiAgICB9IGVsc2VcbiAgICBpZiAoaXNDb250ZW50RWRpdGFibGUoY29udHJvbE5vZGUpKSB7XG4gICAgICB2YWx1ZSA9IGNvbnRyb2xOb2RlLmlubmVyVGV4dDtcbiAgICB9XG5cbiAgICBpZiAodmFsdWUgIT09IG51bGwpIHtcbiAgICAgIC8vIHJldHVybiB0aGUgYWN0dWFsIHZhbHVlXG4gICAgICAvLyBoYW5kbGUgc2VyaWFsaXphdGlvbiBpbiBlbnRyeSBwcm92aWRlclxuICAgICAgLy8gKGllLiBpZiBlbXB0eSBzdHJpbmcgc2hvdWxkIGJlIHNlcmlhbGl6ZWQgb3Igbm90KVxuICAgICAgdmFsdWVzW25hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gdmFsdWVzO1xuXG59XG5cbi8qKlxuICogRXh0cmFjdCBpbnB1dCB2YWx1ZXMgZnJvbSBlbnRyeSBub2RlXG4gKlxuICogQHBhcmFtICB7RE9NRWxlbWVudH0gZW50cnlOb2RlXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBnZXRGb3JtQ29udHJvbFZhbHVlcyhlbnRyeU5vZGUpIHtcblxuICB2YXIgdmFsdWVzO1xuXG4gIHZhciBsaXN0Q29udGFpbmVyID0gZG9tUXVlcnkoJ1tkYXRhLWxpc3QtZW50cnktY29udGFpbmVyXScsIGVudHJ5Tm9kZSk7XG4gIGlmIChsaXN0Q29udGFpbmVyKSB7XG4gICAgdmFsdWVzID0gW107XG4gICAgdmFyIGxpc3ROb2RlcyA9IGxpc3RDb250YWluZXIuY2hpbGRyZW4gfHwgW107XG4gICAgZm9yRWFjaChsaXN0Tm9kZXMsIGZ1bmN0aW9uKGxpc3ROb2RlKSB7XG4gICAgICB2YWx1ZXMucHVzaChnZXRGb3JtQ29udHJvbFZhbHVlc0luU2NvcGUobGlzdE5vZGUpKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB2YWx1ZXMgPSBnZXRGb3JtQ29udHJvbFZhbHVlc0luU2NvcGUoZW50cnlOb2RlKTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZXM7XG59XG5cbi8qKlxuICogUmV0dXJuIHRydWUgaWYgdGhlIGdpdmVuIGZvcm0gZXh0cmFjdGVkIHZhbHVlIGVxdWFsc1xuICogdG8gYW4gb2xkIGNhY2hlZCB2ZXJzaW9uLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB2YWx1ZVxuICogQHBhcmFtIHtPYmplY3R9IG9sZFZhbHVlXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiB2YWx1ZUVxdWFsKHZhbHVlLCBvbGRWYWx1ZSkge1xuXG4gIGlmICh2YWx1ZSAmJiAhb2xkVmFsdWUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgYWxsS2V5cyA9IGtleXModmFsdWUpLmNvbmNhdChrZXlzKG9sZFZhbHVlKSk7XG5cbiAgcmV0dXJuIGFsbEtleXMuZXZlcnkoZnVuY3Rpb24oa2V5KSB7XG4gICAgcmV0dXJuIHZhbHVlW2tleV0gPT09IG9sZFZhbHVlW2tleV07XG4gIH0pO1xufVxuXG4vKipcbiAqIFJldHVybiB0cnVlIGlmIHRoZSBnaXZlbiBmb3JtIGV4dHJhY3RlZCB2YWx1ZShzKVxuICogZXF1YWwgYW4gb2xkIGNhY2hlZCB2ZXJzaW9uLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0PnxPYmplY3R9IHZhbHVlc1xuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fE9iamVjdH0gb2xkVmFsdWVzXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiB2YWx1ZXNFcXVhbCh2YWx1ZXMsIG9sZFZhbHVlcykge1xuXG4gIGlmIChpc0FycmF5KHZhbHVlcykpIHtcblxuICAgIGlmICh2YWx1ZXMubGVuZ3RoICE9PSBvbGRWYWx1ZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcy5ldmVyeShmdW5jdGlvbih2LCBpZHgpIHtcbiAgICAgIHJldHVybiB2YWx1ZUVxdWFsKHYsIG9sZFZhbHVlc1tpZHhdKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZUVxdWFsKHZhbHVlcywgb2xkVmFsdWVzKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYSBtYXBwaW5nIG9mIHsgaWQ6IGVudHJ5IH0gZm9yIGFsbCBlbnRyaWVzIGluIHRoZSBnaXZlbiBncm91cHMgaW4gdGhlIGdpdmVuIHRhYnMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRhYnNcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZXh0cmFjdEVudHJpZXModGFicykge1xuICByZXR1cm4ga2V5QnkoZmxhdHRlbkRlZXAobWFwKGZsYXR0ZW5EZWVwKG1hcCh0YWJzLCAnZ3JvdXBzJykpLCAnZW50cmllcycpKSwgJ2lkJyk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgbWFwcGluZyBvZiB7IGlkOiBncm91cCB9IGZvciBhbGwgZ3JvdXBzIGluIHRoZSBnaXZlbiB0YWJzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YWJzXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RHcm91cHModGFicykge1xuICByZXR1cm4ga2V5QnkoZmxhdHRlbkRlZXAobWFwKHRhYnMsICdncm91cHMnKSksICdpZCcpO1xufVxuXG4vKipcbiAqIEEgcHJvcGVydGllcyBwYW5lbCBpbXBsZW1lbnRhdGlvbi5cbiAqXG4gKiBUbyB1c2UgaXQgcHJvdmlkZSBhIGBwcm9wZXJ0aWVzUHJvdmlkZXJgIGNvbXBvbmVudCB0aGF0IGtub3dzXG4gKiBhYm91dCB3aGljaCBwcm9wZXJ0aWVzIHRvIGRpc3BsYXkuXG4gKlxuICogUHJvcGVydGllcyBlZGl0IHN0YXRlIC8gdmlzaWJpbGl0eSBjYW4gYmUgaW50ZXJjZXB0ZWRcbiAqIHZpYSBhIGN1c3RvbSB7QGxpbmsgUHJvcGVydGllc0FjdGl2YXRvcn0uXG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqIEBwYXJhbSB7UHJvcGVydGllc1Byb3ZpZGVyfSBwcm9wZXJ0aWVzUHJvdmlkZXJcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7Q29tbWFuZFN0YWNrfSBjb21tYW5kU3RhY2tcbiAqL1xuZnVuY3Rpb24gUHJvcGVydGllc1BhbmVsKGNvbmZpZywgZXZlbnRCdXMsIG1vZGVsaW5nLCBwcm9wZXJ0aWVzUHJvdmlkZXIsIGNvbW1hbmRTdGFjaywgY2FudmFzKSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fY29tbWFuZFN0YWNrID0gY29tbWFuZFN0YWNrO1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX3Byb3BlcnRpZXNQcm92aWRlciA9IHByb3BlcnRpZXNQcm92aWRlcjtcblxuICB0aGlzLl9pbml0KGNvbmZpZyk7XG59XG5cblByb3BlcnRpZXNQYW5lbC4kaW5qZWN0ID0gW1xuICAnY29uZmlnLnByb3BlcnRpZXNQYW5lbCcsXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZycsXG4gICdwcm9wZXJ0aWVzUHJvdmlkZXInLFxuICAnY29tbWFuZFN0YWNrJyxcbiAgJ2NhbnZhcydcbl07XG5cbm1vZHVsZS5leHBvcnRzID0gUHJvcGVydGllc1BhbmVsO1xuXG5cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbihjb25maWcpIHtcblxuICB2YXIgY2FudmFzID0gdGhpcy5fY2FudmFzLFxuICAgICAgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgLyoqXG4gICAqIFNlbGVjdCB0aGUgcm9vdCBlbGVtZW50IG9uY2UgaXQgaXMgYWRkZWQgdG8gdGhlIGNhbnZhc1xuICAgKi9cbiAgZXZlbnRCdXMub24oJ3Jvb3QuYWRkZWQnLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBlLmVsZW1lbnQ7XG5cbiAgICBpZiAoaXNJbXBsaWNpdFJvb3QoZWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmLnVwZGF0ZShlbGVtZW50KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ3NlbGVjdGlvbi5jaGFuZ2VkJywgZnVuY3Rpb24oZSkge1xuICAgIHZhciBuZXdFbGVtZW50ID0gZS5uZXdTZWxlY3Rpb25bMF07XG5cbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKTtcblxuICAgIGlmIChpc0ltcGxpY2l0Um9vdChyb290RWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmLnVwZGF0ZShuZXdFbGVtZW50KTtcbiAgfSk7XG5cbiAgLy8gYWRkIC8gdXBkYXRlIHRhYi1iYXIgc2Nyb2xsaW5nXG4gIGV2ZW50QnVzLm9uKFtcbiAgICAncHJvcGVydGllc1BhbmVsLmNoYW5nZWQnLFxuICAgICdwcm9wZXJ0aWVzUGFuZWwucmVzaXplZCdcbiAgXSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciB0YWJCYXJOb2RlID0gZG9tUXVlcnkoJy5icHAtcHJvcGVydGllcy10YWItYmFyJywgc2VsZi5fY29udGFpbmVyKTtcblxuICAgIGlmICghdGFiQmFyTm9kZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBzY3JvbGxlciA9IHNjcm9sbFRhYnMuZ2V0KHRhYkJhck5vZGUpO1xuXG4gICAgaWYgKCFzY3JvbGxlcikge1xuXG4gICAgICAvLyB3ZSBkaWQgbm90IGluaXRpYWxpemUgeWV0LCBkbyB0aGF0XG4gICAgICAvLyBub3cgYW5kIG1ha2Ugc3VyZSB3ZSBzZWxlY3QgdGhlIGFjdGl2ZVxuICAgICAgLy8gdGFiIG9uIHNjcm9sbCB1cGRhdGVcbiAgICAgIHNjcm9sbGVyID0gc2Nyb2xsVGFicyh0YWJCYXJOb2RlLCB7XG4gICAgICAgIHNlbGVjdG9yczoge1xuICAgICAgICAgIHRhYnNDb250YWluZXI6ICcuYnBwLXByb3BlcnRpZXMtdGFicy1saW5rcycsXG4gICAgICAgICAgdGFiOiAnLmJwcC1wcm9wZXJ0aWVzLXRhYnMtbGlua3MgbGknLFxuICAgICAgICAgIGlnbm9yZTogJy5icHAtaGlkZGVuJyxcbiAgICAgICAgICBhY3RpdmU6ICcuYnBwLWFjdGl2ZSdcbiAgICAgICAgfVxuICAgICAgfSk7XG5cblxuICAgICAgc2Nyb2xsZXIub24oJ3Njcm9sbCcsIGZ1bmN0aW9uKG5ld0FjdGl2ZU5vZGUsIG9sZEFjdGl2ZU5vZGUsIGRpcmVjdGlvbikge1xuXG4gICAgICAgIHZhciBsaW5rTm9kZSA9IGRvbVF1ZXJ5KCdbZGF0YS10YWItdGFyZ2V0XScsIG5ld0FjdGl2ZU5vZGUpO1xuXG4gICAgICAgIHZhciB0YWJJZCA9IGRvbUF0dHIobGlua05vZGUsICdkYXRhLXRhYi10YXJnZXQnKTtcblxuICAgICAgICBzZWxmLmFjdGl2YXRlVGFiKHRhYklkKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIHJlYWN0IG9uIHRhYiBjaGFuZ2VzIGFuZCBvciB0YWJDb250YWluZXIgcmVzaXplXG4gICAgLy8gYW5kIG1ha2Ugc3VyZSB0aGUgYWN0aXZlIHRhYiBpcyBzaG93biBjb21wbGV0ZWx5XG4gICAgc2Nyb2xsZXIudXBkYXRlKCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50cy5jaGFuZ2VkJywgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGN1cnJlbnQgPSBzZWxmLl9jdXJyZW50O1xuICAgIHZhciBlbGVtZW50ID0gY3VycmVudCAmJiBjdXJyZW50LmVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgaWYgKGUuZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTEpIHtcbiAgICAgICAgc2VsZi51cGRhdGUoZWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudFRlbXBsYXRlcy5jaGFuZ2VkJywgZnVuY3Rpb24oKSB7XG4gICAgdmFyIGN1cnJlbnQgPSBzZWxmLl9jdXJyZW50O1xuICAgIHZhciBlbGVtZW50ID0gY3VycmVudCAmJiBjdXJyZW50LmVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudCkge1xuICAgICAgc2VsZi51cGRhdGUoZWxlbWVudCk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5kZXN0cm95JywgZnVuY3Rpb24oKSB7XG4gICAgc2VsZi5kZXRhY2goKTtcbiAgfSk7XG5cbiAgdGhpcy5fY29udGFpbmVyID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiYnBwLXByb3BlcnRpZXMtcGFuZWxcIj48L2Rpdj4nKTtcblxuICB0aGlzLl9iaW5kTGlzdGVuZXJzKHRoaXMuX2NvbnRhaW5lcik7XG5cbiAgaWYgKGNvbmZpZyAmJiBjb25maWcucGFyZW50KSB7XG4gICAgdGhpcy5hdHRhY2hUbyhjb25maWcucGFyZW50KTtcbiAgfVxufTtcblxuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLmF0dGFjaFRvID0gZnVuY3Rpb24ocGFyZW50Tm9kZSkge1xuXG4gIGlmICghcGFyZW50Tm9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncGFyZW50Tm9kZSByZXF1aXJlZCcpO1xuICB9XG5cbiAgLy8gZW5zdXJlIHdlIGRldGFjaCBmcm9tIHRoZVxuICAvLyBwcmV2aW91cywgb2xkIHBhcmVudFxuICB0aGlzLmRldGFjaCgpO1xuXG4gIC8vIHVud3JhcCBqUXVlcnkgaWYgcHJvdmlkZWRcbiAgaWYgKHBhcmVudE5vZGUuZ2V0ICYmIHBhcmVudE5vZGUuY29uc3RydWN0b3IucHJvdG90eXBlLmpxdWVyeSkge1xuICAgIHBhcmVudE5vZGUgPSBwYXJlbnROb2RlLmdldCgwKTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgcGFyZW50Tm9kZSA9PT0gJ3N0cmluZycpIHtcbiAgICBwYXJlbnROb2RlID0gZG9tUXVlcnkocGFyZW50Tm9kZSk7XG4gIH1cblxuICB2YXIgY29udGFpbmVyID0gdGhpcy5fY29udGFpbmVyO1xuXG4gIHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICB0aGlzLl9lbWl0KCdhdHRhY2gnKTtcbn07XG5cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuZGV0YWNoID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lcixcbiAgICAgIHBhcmVudE5vZGUgPSBjb250YWluZXIucGFyZW50Tm9kZTtcblxuICBpZiAoIXBhcmVudE5vZGUpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9lbWl0KCdkZXRhY2gnKTtcblxuICBwYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNvbnRhaW5lcik7XG59O1xuXG5cbi8qKlxuICogU2VsZWN0IHRoZSBnaXZlbiB0YWIgd2l0aGluIHRoZSBwcm9wZXJ0aWVzIHBhbmVsLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fFN0cmluZ30gdGFiXG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuYWN0aXZhdGVUYWIgPSBmdW5jdGlvbih0YWIpIHtcblxuICB2YXIgdGFiSWQgPSB0eXBlb2YgdGFiID09PSAnc3RyaW5nJyA/IHRhYiA6IHRhYi5pZDtcblxuICB2YXIgY3VycmVudCA9IHRoaXMuX2N1cnJlbnQ7XG5cbiAgdmFyIHBhbmVsTm9kZSA9IGN1cnJlbnQucGFuZWw7XG5cbiAgdmFyIGFsbFRhYk5vZGVzID0gZG9tUXVlcnlBbGwoJy5icHAtcHJvcGVydGllcy10YWInLCBwYW5lbE5vZGUpLFxuICAgICAgYWxsVGFiTGlua05vZGVzID0gZG9tUXVlcnlBbGwoJy5icHAtcHJvcGVydGllcy10YWItbGluaycsIHBhbmVsTm9kZSk7XG5cbiAgZm9yRWFjaChhbGxUYWJOb2RlcywgZnVuY3Rpb24odGFiTm9kZSkge1xuXG4gICAgdmFyIGN1cnJlbnRUYWJJZCA9IGRvbUF0dHIodGFiTm9kZSwgJ2RhdGEtdGFiJyk7XG5cbiAgICBkb21DbGFzc2VzKHRhYk5vZGUpLnRvZ2dsZSgnYnBwLWFjdGl2ZScsIHRhYklkID09PSBjdXJyZW50VGFiSWQpO1xuICB9KTtcblxuICBmb3JFYWNoKGFsbFRhYkxpbmtOb2RlcywgZnVuY3Rpb24odGFiTGlua05vZGUpIHtcblxuICAgIHZhciB0YWJMaW5rID0gZG9tUXVlcnkoJ1tkYXRhLXRhYi10YXJnZXRdJywgdGFiTGlua05vZGUpLFxuICAgICAgICBjdXJyZW50VGFiSWQgPSBkb21BdHRyKHRhYkxpbmssICdkYXRhLXRhYi10YXJnZXQnKTtcblxuICAgIGRvbUNsYXNzZXModGFiTGlua05vZGUpLnRvZ2dsZSgnYnBwLWFjdGl2ZScsIHRhYklkID09PSBjdXJyZW50VGFiSWQpO1xuICB9KTtcbn07XG5cbi8qKlxuICogVXBkYXRlIHRoZSBET00gcmVwcmVzZW50YXRpb24gb2YgdGhlIHByb3BlcnRpZXMgcGFuZWxcbiAqL1xuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5fY3VycmVudDtcblxuICAvLyBubyBhY3R1YWwgc2VsZWN0aW9uIGNoYW5nZVxuICB2YXIgbmVlZHNDcmVhdGUgPSB0cnVlO1xuXG4gIGlmICh0eXBlb2YgZWxlbWVudCA9PT0gJ3VuZGVmaW5lZCcpIHtcblxuICAgIC8vIHVzZSBSb290RWxlbWVudCBvZiBCUE1OIGRpYWdyYW0gdG8gZ2VuZXJhdGUgcHJvcGVydGllcyBwYW5lbCBpZiBubyBlbGVtZW50IGlzIHNlbGVjdGVkXG4gICAgZWxlbWVudCA9IHRoaXMuX2NhbnZhcy5nZXRSb290RWxlbWVudCgpO1xuICB9XG5cbiAgdmFyIG5ld1RhYnMgPSB0aGlzLl9wcm9wZXJ0aWVzUHJvdmlkZXIuZ2V0VGFicyhlbGVtZW50KTtcblxuICBpZiAoY3VycmVudCAmJiBjdXJyZW50LmVsZW1lbnQgPT09IGVsZW1lbnQpIHtcbiAgICAvLyBzZWUgaWYgd2UgY2FuIHJldXNlIHRoZSBleGlzdGluZyBwYW5lbFxuXG4gICAgbmVlZHNDcmVhdGUgPSB0aGlzLl9lbnRyaWVzQ2hhbmdlZChjdXJyZW50LCBuZXdUYWJzKTtcbiAgfVxuXG4gIGlmIChuZWVkc0NyZWF0ZSkge1xuXG4gICAgaWYgKGN1cnJlbnQpIHtcblxuICAgICAgLy8gZ2V0IGFjdGl2ZSB0YWIgZnJvbSB0aGUgZXhpc3RpbmcgcGFuZWwgYmVmb3JlIHJlbW92ZSBpdFxuICAgICAgdmFyIGFjdGl2ZVRhYk5vZGUgPSBkb21RdWVyeSgnLmJwcC1wcm9wZXJ0aWVzLXRhYi5icHAtYWN0aXZlJywgY3VycmVudC5wYW5lbCk7XG5cbiAgICAgIHZhciBhY3RpdmVUYWJJZDtcbiAgICAgIGlmIChhY3RpdmVUYWJOb2RlKSB7XG4gICAgICAgIGFjdGl2ZVRhYklkID0gZG9tQXR0cihhY3RpdmVUYWJOb2RlLCAnZGF0YS10YWInKTtcbiAgICAgIH1cblxuICAgICAgLy8gcmVtb3ZlIG9sZCBwYW5lbFxuICAgICAgZG9tUmVtb3ZlKGN1cnJlbnQucGFuZWwpO1xuICAgIH1cblxuICAgIHRoaXMuX2N1cnJlbnQgPSB0aGlzLl9jcmVhdGUoZWxlbWVudCwgbmV3VGFicyk7XG5cbiAgICAvLyBhY3RpdmF0ZSB0aGUgc2F2ZWQgYWN0aXZlIHRhYiBmcm9tIHRoZSByZW1vdmUgcGFuZWwgb3IgdGhlIGZpcnN0IHRhYlxuICAgIChhY3RpdmVUYWJJZCkgPyB0aGlzLmFjdGl2YXRlVGFiKGFjdGl2ZVRhYklkKSA6IHRoaXMuYWN0aXZhdGVUYWIodGhpcy5fY3VycmVudC50YWJzWzBdKTtcblxuICB9XG5cbiAgaWYgKHRoaXMuX2N1cnJlbnQpIHtcbiAgICAvLyBtYWtlIHN1cmUgY29ycmVjdCB0YWIgY29udGVudHMgYXJlIHZpc2libGVcbiAgICB0aGlzLl91cGRhdGVBY3RpdmF0aW9uKHRoaXMuX2N1cnJlbnQpO1xuXG4gIH1cblxuICB0aGlzLl9lbWl0KCdjaGFuZ2VkJyk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIG9uZSBvZiB0d28gZ3JvdXBzIGhhcyBkaWZmZXJlbnQgZW50cmllcyB0aGFuIHRoZSBvdGhlci5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGN1cnJlbnRcbiAqIEBwYXJhbSAge09iamVjdH0gbmV3VGFic1xuICogQHJldHVybiB7Qm9vbGVhbn1cbiAqL1xuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS5fZW50cmllc0NoYW5nZWQgPSBmdW5jdGlvbihjdXJyZW50LCBuZXdUYWJzKSB7XG5cbiAgdmFyIG9sZEVudHJ5SWRzID0ga2V5cyhjdXJyZW50LmVudHJpZXMpLFxuICAgICAgbmV3RW50cnlJZHMgPSBrZXlzKGV4dHJhY3RFbnRyaWVzKG5ld1RhYnMpKTtcblxuICByZXR1cm4gIWlzRW1wdHkoeG9yKG9sZEVudHJ5SWRzLCBuZXdFbnRyeUlkcykpO1xufTtcblxuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS5fZW1pdCA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3Byb3BlcnRpZXNQYW5lbC4nICsgZXZlbnQsIHsgcGFuZWw6IHRoaXMsIGN1cnJlbnQ6IHRoaXMuX2N1cnJlbnQgfSk7XG59O1xuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLl9iaW5kTGlzdGVuZXJzID0gZnVuY3Rpb24oY29udGFpbmVyKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vIGhhbmRsZXMgYSBjaGFuZ2UgZm9yIGEgZ2l2ZW4gZXZlbnRcbiAgdmFyIGhhbmRsZUNoYW5nZSA9IGZ1bmN0aW9uIGhhbmRsZUNoYW5nZShldmVudCkge1xuXG4gICAgLy8gc2VlIGlmIHdlIGhhbmRsZSBhIGNoYW5nZSBpbnNpZGUgYSBbZGF0YS1lbnRyeV0gZWxlbWVudC5cbiAgICAvLyBpZiBub3QsIGRyb3Agb3V0XG4gICAgdmFyIGlucHV0Tm9kZSA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0LFxuICAgICAgICBlbnRyeU5vZGUgPSBkb21DbG9zZXN0KGlucHV0Tm9kZSwgJ1tkYXRhLWVudHJ5XScpLFxuICAgICAgICBlbnRyeUlkLCBlbnRyeTtcblxuICAgIC8vIGNoYW5nZSBmcm9tIG91dHNpZGUgYSBbZGF0YS1lbnRyeV0gZWxlbWVudCwgc2ltcGx5IGlnbm9yZVxuICAgIGlmICghZW50cnlOb2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZW50cnlJZCA9IGRvbUF0dHIoZW50cnlOb2RlLCAnZGF0YS1lbnRyeScpO1xuICAgIGVudHJ5ID0gc2VsZi5nZXRFbnRyeShlbnRyeUlkKTtcblxuICAgIHZhciB2YWx1ZXMgPSBnZXRGb3JtQ29udHJvbFZhbHVlcyhlbnRyeU5vZGUpO1xuXG4gICAgaWYgKGV2ZW50LnR5cGUgPT09ICdjaGFuZ2UnKSB7XG5cbiAgICAgIC8vIC0gaWYgdGhlIFwiZGF0YS1vbi1jaGFuZ2VcIiBhdHRyaWJ1dGUgaXMgcHJlc2VudCBhbmQgYSB2YWx1ZSBpcyBjaGFuZ2VkLFxuICAgICAgLy8gICB0aGVuIHRoZSBhc3NvY2lhdGVkIGFjdGlvbiBpcyBwZXJmb3JtZWQuXG4gICAgICAvLyAtIGlmIHRoZSBhc3NvY2lhdGVkIGFjdGlvbiByZXR1cm5zIFwidHJ1ZVwiIHRoZW4gYW4gdXBkYXRlIHRvIHRoZSBidXNpbmVzc1xuICAgICAgLy8gICBvYmplY3QgaXMgZG9uZVxuICAgICAgLy8gLSBpZiBpdCBkb2VzIG5vdCByZXR1cm4gXCJ0cnVlXCIsIHRoZW4gb25seSB0aGUgRE9NIGNvbnRlbnQgaXMgdXBkYXRlZFxuICAgICAgdmFyIG9uQ2hhbmdlQWN0aW9uID0gZG9tQXR0cihpbnB1dE5vZGUsICdkYXRhLW9uLWNoYW5nZScpO1xuXG4gICAgICBpZiAob25DaGFuZ2VBY3Rpb24pIHtcbiAgICAgICAgdmFyIGlzRW50cnlEaXJ0eSA9IHNlbGYuZXhlY3V0ZUFjdGlvbihlbnRyeSwgZW50cnlOb2RlLCBvbkNoYW5nZUFjdGlvbiwgZXZlbnQpO1xuXG4gICAgICAgIGlmICghaXNFbnRyeURpcnR5KSB7XG4gICAgICAgICAgcmV0dXJuIHNlbGYudXBkYXRlKHNlbGYuX2N1cnJlbnQuZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgc2VsZi5hcHBseUNoYW5nZXMoZW50cnksIHZhbHVlcywgZW50cnlOb2RlKTtcbiAgICBzZWxmLnVwZGF0ZVN0YXRlKGVudHJ5LCBlbnRyeU5vZGUpO1xuICB9O1xuXG4gIC8vIGRlYm91bmNlIHVwZGF0ZSBvbmx5IGVsZW1lbnRzIHRoYXQgYXJlIHRhcmdldCBvZiBrZXkgZXZlbnRzLFxuICAvLyBpLmUuIElOUFVUIGFuZCBURVhUQVJFQS4gU0VMRUNUcyB3aWxsIHRyaWdnZXIgYW4gaW1tZWRpYXRlIHVwZGF0ZSBhbnl3YXkuXG4gIGRvbURlbGVnYXRlLmJpbmQoY29udGFpbmVyLCAnaW5wdXQsIHRleHRhcmVhLCBbY29udGVudGVkaXRhYmxlXScsICdpbnB1dCcsIGRlYm91bmNlKGhhbmRsZUNoYW5nZSwgREVCT1VOQ0VfREVMQVkpKTtcbiAgZG9tRGVsZWdhdGUuYmluZChjb250YWluZXIsICdpbnB1dCwgdGV4dGFyZWEsIHNlbGVjdCwgW2NvbnRlbnRlZGl0YWJsZV0nLCAnY2hhbmdlJywgaGFuZGxlQ2hhbmdlKTtcblxuICAvLyBoYW5kbGUga2V5IGV2ZW50c1xuICBkb21EZWxlZ2F0ZS5iaW5kKGNvbnRhaW5lciwgJ3NlbGVjdCcsICdrZXlkb3duJywgZnVuY3Rpb24oZSkge1xuXG4gICAgLy8gREVMXG4gICAgaWYgKGUua2V5Q29kZSA9PT0gNDYpIHtcbiAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9KTtcblxuICBkb21EZWxlZ2F0ZS5iaW5kKGNvbnRhaW5lciwgJ1tkYXRhLWFjdGlvbl0nLCAnY2xpY2snLCBmdW5jdGlvbiBvbkNsaWNrKGV2ZW50KSB7XG5cbiAgICAvLyB0cmlnZ2VycyBvbiBhbGwgaW5wdXRzXG4gICAgdmFyIGlucHV0Tm9kZSA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0LFxuICAgICAgICBlbnRyeU5vZGUgPSBkb21DbG9zZXN0KGlucHV0Tm9kZSwgJ1tkYXRhLWVudHJ5XScpO1xuXG4gICAgdmFyIGFjdGlvbklkID0gZG9tQXR0cihpbnB1dE5vZGUsICdkYXRhLWFjdGlvbicpLFxuICAgICAgICBlbnRyeUlkID0gZG9tQXR0cihlbnRyeU5vZGUsICdkYXRhLWVudHJ5Jyk7XG5cbiAgICB2YXIgZW50cnkgPSBzZWxmLmdldEVudHJ5KGVudHJ5SWQpO1xuXG4gICAgdmFyIGlzRW50cnlEaXJ0eSA9IHNlbGYuZXhlY3V0ZUFjdGlvbihlbnRyeSwgZW50cnlOb2RlLCBhY3Rpb25JZCwgZXZlbnQpO1xuXG4gICAgaWYgKGlzRW50cnlEaXJ0eSkge1xuICAgICAgdmFyIHZhbHVlcyA9IGdldEZvcm1Db250cm9sVmFsdWVzKGVudHJ5Tm9kZSk7XG5cbiAgICAgIHNlbGYuYXBwbHlDaGFuZ2VzKGVudHJ5LCB2YWx1ZXMsIGVudHJ5Tm9kZSk7XG4gICAgfVxuXG4gICAgc2VsZi51cGRhdGVTdGF0ZShlbnRyeSwgZW50cnlOb2RlKTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gaGFuZGxlSW5wdXQoZXZlbnQsIGVsZW1lbnQpIHtcbiAgICAvLyB0cmlnZ2VycyBvbiBhbGwgaW5wdXRzXG4gICAgdmFyIGlucHV0Tm9kZSA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0O1xuXG4gICAgdmFyIGVudHJ5Tm9kZSA9IGRvbUNsb3Nlc3QoaW5wdXROb2RlLCAnW2RhdGEtZW50cnldJyk7XG5cbiAgICAvLyBvbmx5IHdvcmsgb24gZGF0YSBlbnRyaWVzXG4gICAgaWYgKCFlbnRyeU5vZGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZXZlbnRIYW5kbGVySWQgPSBkb21BdHRyKGlucHV0Tm9kZSwgJ2RhdGEtYmx1cicpLFxuICAgICAgICBlbnRyeUlkID0gZG9tQXR0cihlbnRyeU5vZGUsICdkYXRhLWVudHJ5Jyk7XG5cbiAgICB2YXIgZW50cnkgPSBzZWxmLmdldEVudHJ5KGVudHJ5SWQpO1xuXG4gICAgdmFyIGlzRW50cnlEaXJ0eSA9IHNlbGYuZXhlY3V0ZUFjdGlvbihlbnRyeSwgZW50cnlOb2RlLCBldmVudEhhbmRsZXJJZCwgZXZlbnQpO1xuXG4gICAgaWYgKGlzRW50cnlEaXJ0eSkge1xuICAgICAgdmFyIHZhbHVlcyA9IGdldEZvcm1Db250cm9sVmFsdWVzKGVudHJ5Tm9kZSk7XG5cbiAgICAgIHNlbGYuYXBwbHlDaGFuZ2VzKGVudHJ5LCB2YWx1ZXMsIGVudHJ5Tm9kZSk7XG4gICAgfVxuXG4gICAgc2VsZi51cGRhdGVTdGF0ZShlbnRyeSwgZW50cnlOb2RlKTtcbiAgfVxuXG4gIGRvbURlbGVnYXRlLmJpbmQoY29udGFpbmVyLCAnW2RhdGEtYmx1cl0nLCAnYmx1cicsIGhhbmRsZUlucHV0LCB0cnVlKTtcblxuICAvLyBtYWtlIHRhYiBsaW5rcyBpbnRlcmFjdGl2ZVxuICBkb21EZWxlZ2F0ZS5iaW5kKGNvbnRhaW5lciwgJy5icHAtcHJvcGVydGllcy10YWJzLWxpbmtzIFtkYXRhLXRhYi10YXJnZXRdJywgJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgdmFyIGRlbGVnYXRlVGFyZ2V0ID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQ7XG5cbiAgICB2YXIgdGFiSWQgPSBkb21BdHRyKGRlbGVnYXRlVGFyZ2V0LCAnZGF0YS10YWItdGFyZ2V0Jyk7XG5cbiAgICAvLyBhY3RpdmF0ZSB0YWIgb24gbGluayBjbGlja1xuICAgIHNlbGYuYWN0aXZhdGVUYWIodGFiSWQpO1xuICB9KTtcblxufTtcblxuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS51cGRhdGVTdGF0ZSA9IGZ1bmN0aW9uKGVudHJ5LCBlbnRyeU5vZGUpIHtcbiAgdGhpcy51cGRhdGVTaG93KGVudHJ5LCBlbnRyeU5vZGUpO1xuICB0aGlzLnVwZGF0ZURpc2FibGUoZW50cnksIGVudHJ5Tm9kZSk7XG59O1xuXG4vKipcbiAqIFVwZGF0ZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGUgZW50cnkgbm9kZSBpbiB0aGUgRE9NXG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUudXBkYXRlU2hvdyA9IGZ1bmN0aW9uKGVudHJ5LCBub2RlKSB7XG5cbiAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50O1xuXG4gIGlmICghY3VycmVudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBzaG93Tm9kZXMgPSBkb21RdWVyeUFsbCgnW2RhdGEtc2hvd10nLCBub2RlKSB8fCBbXTtcblxuICBmb3JFYWNoKHNob3dOb2RlcywgZnVuY3Rpb24oc2hvd05vZGUpIHtcblxuICAgIHZhciBleHByID0gZG9tQXR0cihzaG93Tm9kZSwgJ2RhdGEtc2hvdycpO1xuICAgIHZhciBmbiA9IGdldChlbnRyeSwgZXhwcik7XG4gICAgaWYgKGZuKSB7XG4gICAgICB2YXIgc2NvcGUgPSBkb21DbG9zZXN0KHNob3dOb2RlLCAnW2RhdGEtc2NvcGVdJykgfHwgbm9kZTtcbiAgICAgIHZhciBzaG91bGRTaG93ID0gZm4oY3VycmVudC5lbGVtZW50LCBub2RlLCBzaG93Tm9kZSwgc2NvcGUpIHx8IGZhbHNlO1xuICAgICAgaWYgKHNob3VsZFNob3cpIHtcbiAgICAgICAgZG9tQ2xhc3NlcyhzaG93Tm9kZSkucmVtb3ZlKEhJREVfQ0xBU1MpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZG9tQ2xhc3NlcyhzaG93Tm9kZSkuYWRkKEhJREVfQ0xBU1MpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59O1xuXG4vKipcbiAqIEV2YWx1YXRlcyBhIGdpdmVuIGZ1bmN0aW9uLiBJZiBpdCByZXR1cm5zIHRydWUsIHRoZW4gdGhlXG4gKiBub2RlIGlzIG1hcmtlZCBhcyBcImRpc2FibGVkXCIuXG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUudXBkYXRlRGlzYWJsZSA9IGZ1bmN0aW9uKGVudHJ5LCBub2RlKSB7XG4gIHZhciBjdXJyZW50ID0gdGhpcy5fY3VycmVudDtcblxuICBpZiAoIWN1cnJlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbm9kZXMgPSBkb21RdWVyeUFsbCgnW2RhdGEtZGlzYWJsZV0nLCBub2RlKSB8fCBbXTtcblxuICBmb3JFYWNoKG5vZGVzLCBmdW5jdGlvbihjdXJyZW50Tm9kZSkge1xuICAgIHZhciBleHByID0gZG9tQXR0cihjdXJyZW50Tm9kZSwgJ2RhdGEtZGlzYWJsZScpO1xuICAgIHZhciBmbiA9IGdldChlbnRyeSwgZXhwcik7XG4gICAgaWYgKGZuKSB7XG4gICAgICB2YXIgc2NvcGUgPSBkb21DbG9zZXN0KGN1cnJlbnROb2RlLCAnW2RhdGEtc2NvcGVdJykgfHwgbm9kZTtcbiAgICAgIHZhciBzaG91bGREaXNhYmxlID0gZm4oY3VycmVudC5lbGVtZW50LCBub2RlLCBjdXJyZW50Tm9kZSwgc2NvcGUpIHx8IGZhbHNlO1xuICAgICAgZG9tQXR0cihjdXJyZW50Tm9kZSwgJ2Rpc2FibGVkJywgc2hvdWxkRGlzYWJsZSA/ICcnIDogbnVsbCk7XG4gICAgfVxuICB9KTtcbn07XG5cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuZXhlY3V0ZUFjdGlvbiA9IGZ1bmN0aW9uKGVudHJ5LCBlbnRyeU5vZGUsIGFjdGlvbklkLCBldmVudCkge1xuICB2YXIgY3VycmVudCA9IHRoaXMuX2N1cnJlbnQ7XG5cbiAgaWYgKCFjdXJyZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGZuID0gZ2V0KGVudHJ5LCBhY3Rpb25JZCk7XG4gIGlmIChmbikge1xuICAgIHZhciBzY29wZU5vZGUgPSBkb21DbG9zZXN0KGV2ZW50LnRhcmdldCwgJ1tkYXRhLXNjb3BlXScpIHx8IGVudHJ5Tm9kZTtcbiAgICByZXR1cm4gZm4uYXBwbHkoZW50cnksIFsgY3VycmVudC5lbGVtZW50LCBlbnRyeU5vZGUsIGV2ZW50LCBzY29wZU5vZGUgXSk7XG4gIH1cbn07XG5cbi8qKlxuICogQXBwbHkgY2hhbmdlcyB0byB0aGUgYnVzaW5lc3Mgb2JqZWN0IGJ5IGV4ZWN1dGluZyBhIGNvbW1hbmRcbiAqL1xuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS5hcHBseUNoYW5nZXMgPSBmdW5jdGlvbihlbnRyeSwgdmFsdWVzLCBjb250YWluZXJFbGVtZW50KSB7XG5cbiAgdmFyIGVsZW1lbnQgPSB0aGlzLl9jdXJyZW50LmVsZW1lbnQ7XG5cbiAgLy8gZW5zdXJlIHdlIG9ubHkgdXBkYXRlIHRoZSBtb2RlbCBpZiB3ZSBnb3QgZGlydHkgY2hhbmdlc1xuICBpZiAodmFsdWVzRXF1YWwodmFsdWVzLCBlbnRyeS5vbGRWYWx1ZXMpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGNvbW1hbmQgPSBlbnRyeS5zZXQoZWxlbWVudCwgdmFsdWVzLCBjb250YWluZXJFbGVtZW50KTtcblxuICB2YXIgY29tbWFuZFRvRXhlY3V0ZTtcblxuICBpZiAoaXNBcnJheShjb21tYW5kKSkge1xuICAgIGlmIChjb21tYW5kLmxlbmd0aCkge1xuICAgICAgY29tbWFuZFRvRXhlY3V0ZSA9IHtcbiAgICAgICAgY21kOiAncHJvcGVydGllcy1wYW5lbC5tdWx0aS1jb21tYW5kLWV4ZWN1dG9yJyxcbiAgICAgICAgY29udGV4dDogZmxhdHRlbkRlZXAoY29tbWFuZClcbiAgICAgIH07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGNvbW1hbmRUb0V4ZWN1dGUgPSBjb21tYW5kO1xuICB9XG5cbiAgaWYgKGNvbW1hbmRUb0V4ZWN1dGUpIHtcbiAgICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZShjb21tYW5kVG9FeGVjdXRlLmNtZCwgY29tbWFuZFRvRXhlY3V0ZS5jb250ZXh0IHx8IHsgZWxlbWVudCA6IGVsZW1lbnQgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy51cGRhdGUoZWxlbWVudCk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBhcHBseSB2YWxpZGF0aW9uIGVycm9ycyBpbiB0aGUgRE9NIGFuZCBzaG93IG9yIHJlbW92ZSBhbiBlcnJvciBtZXNzYWdlIG5lYXIgdGhlIGVudHJ5IG5vZGUuXG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuYXBwbHlWYWxpZGF0aW9uRXJyb3JzID0gZnVuY3Rpb24odmFsaWRhdGlvbkVycm9ycywgZW50cnlOb2RlKSB7XG5cbiAgdmFyIHZhbGlkID0gdHJ1ZTtcblxuICB2YXIgY29udHJvbE5vZGVzID0gZ2V0Rm9ybUNvbnRyb2xzKGVudHJ5Tm9kZSwgdHJ1ZSk7XG5cbiAgZm9yRWFjaChjb250cm9sTm9kZXMsIGZ1bmN0aW9uKGNvbnRyb2xOb2RlKSB7XG5cbiAgICB2YXIgbmFtZSA9IGRvbUF0dHIoY29udHJvbE5vZGUsICduYW1lJykgfHwgZG9tQXR0cihjb250cm9sTm9kZSwgJ2RhdGEtbmFtZScpO1xuXG4gICAgdmFyIGVycm9yID0gdmFsaWRhdGlvbkVycm9ycyAmJiB2YWxpZGF0aW9uRXJyb3JzW25hbWVdO1xuXG4gICAgdmFyIGVycm9yTWVzc2FnZU5vZGUgPSBkb21RdWVyeSgnLmJwcC1lcnJvci1tZXNzYWdlJywgY29udHJvbE5vZGUucGFyZW50Tm9kZSk7XG5cbiAgICBpZiAoZXJyb3IpIHtcbiAgICAgIHZhbGlkID0gZmFsc2U7XG5cbiAgICAgIGlmICghZXJyb3JNZXNzYWdlTm9kZSkge1xuICAgICAgICBlcnJvck1lc3NhZ2VOb2RlID0gZG9taWZ5KCc8ZGl2PjwvZGl2PicpO1xuXG4gICAgICAgIGRvbUNsYXNzZXMoZXJyb3JNZXNzYWdlTm9kZSkuYWRkKCdicHAtZXJyb3ItbWVzc2FnZScpO1xuXG4gICAgICAgIC8vIGluc2VydCBlcnJvck1lc3NhZ2VOb2RlIGFmdGVyIGNvbnRyb2xOb2RlXG4gICAgICAgIGNvbnRyb2xOb2RlLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVycm9yTWVzc2FnZU5vZGUsIGNvbnRyb2xOb2RlLm5leHRTaWJsaW5nKTtcbiAgICAgIH1cblxuICAgICAgZXJyb3JNZXNzYWdlTm9kZS50ZXh0Q29udGVudCA9IGVycm9yO1xuXG4gICAgICBkb21DbGFzc2VzKGNvbnRyb2xOb2RlKS5hZGQoJ2ludmFsaWQnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZG9tQ2xhc3Nlcyhjb250cm9sTm9kZSkucmVtb3ZlKCdpbnZhbGlkJyk7XG5cbiAgICAgIGlmIChlcnJvck1lc3NhZ2VOb2RlKSB7XG4gICAgICAgIGNvbnRyb2xOb2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZXJyb3JNZXNzYWdlTm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gdmFsaWQ7XG59O1xuXG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIGVudHJ5IGNvbnRhaW5zIHZhbGlkIGlucHV0XG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUudmFsaWRhdGUgPSBmdW5jdGlvbihlbnRyeSwgdmFsdWVzLCBlbnRyeU5vZGUpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBjdXJyZW50ID0gdGhpcy5fY3VycmVudDtcblxuICB2YXIgdmFsaWQgPSB0cnVlO1xuXG4gIGVudHJ5Tm9kZSA9IGVudHJ5Tm9kZSB8fCBkb21RdWVyeSgnW2RhdGEtZW50cnk9XCInICsgZW50cnkuaWQgKyAnXCJdJywgY3VycmVudC5wYW5lbCk7XG5cbiAgaWYgKHZhbHVlcyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgdmFyIGxpc3RDb250YWluZXIgPSBkb21RdWVyeSgnW2RhdGEtbGlzdC1lbnRyeS1jb250YWluZXJdJywgZW50cnlOb2RlKSxcbiAgICAgICAgbGlzdEVudHJ5Tm9kZXMgPSBsaXN0Q29udGFpbmVyLmNoaWxkcmVuIHx8IFtdO1xuXG4gICAgLy8gY3JlYXRlIG5ldyBlbGVtZW50c1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbGlzdFZhbHVlID0gdmFsdWVzW2ldO1xuXG4gICAgICBpZiAoZW50cnkudmFsaWRhdGVMaXN0SXRlbSkge1xuXG4gICAgICAgIHZhciB2YWxpZGF0aW9uRXJyb3JzID0gZW50cnkudmFsaWRhdGVMaXN0SXRlbShjdXJyZW50LmVsZW1lbnQsIGxpc3RWYWx1ZSwgZW50cnlOb2RlLCBpKSxcbiAgICAgICAgICAgIGxpc3RFbnRyeU5vZGUgPSBsaXN0RW50cnlOb2Rlc1tpXTtcblxuICAgICAgICB2YWxpZCA9IHNlbGYuYXBwbHlWYWxpZGF0aW9uRXJyb3JzKHZhbGlkYXRpb25FcnJvcnMsIGxpc3RFbnRyeU5vZGUpICYmIHZhbGlkO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAoZW50cnkudmFsaWRhdGUpIHtcbiAgICAgIHRoaXMudmFsaWRhdGlvbkVycm9ycyA9IGVudHJ5LnZhbGlkYXRlKGN1cnJlbnQuZWxlbWVudCwgdmFsdWVzLCBlbnRyeU5vZGUpO1xuXG4gICAgICB2YWxpZCA9IHNlbGYuYXBwbHlWYWxpZGF0aW9uRXJyb3JzKHRoaXMudmFsaWRhdGlvbkVycm9ycywgZW50cnlOb2RlKSAmJiB2YWxpZDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdmFsaWQ7XG59O1xuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLmdldEVudHJ5ID0gZnVuY3Rpb24oaWQpIHtcbiAgcmV0dXJuIHRoaXMuX2N1cnJlbnQgJiYgdGhpcy5fY3VycmVudC5lbnRyaWVzW2lkXTtcbn07XG5cbnZhciBmbGF0dGVuRGVlcCA9IHJlcXVpcmUoJ2xvZGFzaC9mbGF0dGVuRGVlcCcpLFxuICAgIGtleUJ5ID0gcmVxdWlyZSgnbG9kYXNoL2tleUJ5JyksXG4gICAgbWFwID0gcmVxdWlyZSgnbG9kYXNoL21hcCcpO1xuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLl9jcmVhdGUgPSBmdW5jdGlvbihlbGVtZW50LCB0YWJzKSB7XG5cbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgY29udGFpbmVyTm9kZSA9IHRoaXMuX2NvbnRhaW5lcjtcblxuICB2YXIgcGFuZWxOb2RlID0gdGhpcy5fY3JlYXRlUGFuZWwoZWxlbWVudCwgdGFicyk7XG5cbiAgY29udGFpbmVyTm9kZS5hcHBlbmRDaGlsZChwYW5lbE5vZGUpO1xuXG4gIHZhciBlbnRyaWVzID0gZXh0cmFjdEVudHJpZXModGFicyk7XG4gIHZhciBncm91cHMgPSBleHRyYWN0R3JvdXBzKHRhYnMpO1xuXG4gIHJldHVybiB7XG4gICAgdGFiczogdGFicyxcbiAgICBncm91cHM6IGdyb3VwcyxcbiAgICBlbnRyaWVzOiBlbnRyaWVzLFxuICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgcGFuZWw6IHBhbmVsTm9kZVxuICB9O1xufTtcblxuLyoqXG4gKiBVcGRhdGUgdmFyaWFibGUgcGFydHMgb2YgdGhlIGVudHJ5IG5vZGUgb24gZWxlbWVudCBjaGFuZ2VzLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSB7RW50cnlEZXNjcmlwdG9yfSBlbnRyeVxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlc1xuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZW50cnlOb2RlXG4gKiBAcGFyYW0ge051bWJlcn0gaWR4XG4gKi9cblByb3BlcnRpZXNQYW5lbC5wcm90b3R5cGUuX2JpbmRUZW1wbGF0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIGVudHJ5LCB2YWx1ZXMsIGVudHJ5Tm9kZSwgaWR4KSB7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgZnVuY3Rpb24gaXNQcm9wZXJ0eUVkaXRhYmxlKGVudHJ5LCBwcm9wZXJ0eU5hbWUpIHtcbiAgICByZXR1cm4gZXZlbnRCdXMuZmlyZSgncHJvcGVydGllc1BhbmVsLmlzUHJvcGVydHlFZGl0YWJsZScsIHtcbiAgICAgIGVudHJ5OiBlbnRyeSxcbiAgICAgIHByb3BlcnR5TmFtZTogcHJvcGVydHlOYW1lLFxuICAgICAgZWxlbWVudDogZWxlbWVudFxuICAgIH0pO1xuICB9XG5cbiAgdmFyIGlucHV0Tm9kZXMgPSBnZXRQcm9wZXJ0eVBsYWNlaG9sZGVycyhlbnRyeU5vZGUpO1xuXG4gIGZvckVhY2goaW5wdXROb2RlcywgZnVuY3Rpb24obm9kZSkge1xuXG4gICAgdmFyIG5hbWUsXG4gICAgICAgIG5ld1ZhbHVlLFxuICAgICAgICBlZGl0YWJsZTtcblxuICAgIC8vIHdlIGRlYWwgd2l0aCBhbiBpbnB1dCBlbGVtZW50XG4gICAgaWYgKCd2YWx1ZScgaW4gbm9kZSB8fCBpc0NvbnRlbnRFZGl0YWJsZShub2RlKSA9PT0gJ3RydWUnKSB7XG4gICAgICBuYW1lID0gZG9tQXR0cihub2RlLCAnbmFtZScpIHx8IGRvbUF0dHIobm9kZSwgJ2RhdGEtbmFtZScpO1xuICAgICAgbmV3VmFsdWUgPSB2YWx1ZXNbbmFtZV07XG5cbiAgICAgIGVkaXRhYmxlID0gaXNQcm9wZXJ0eUVkaXRhYmxlKGVudHJ5LCBuYW1lKTtcbiAgICAgIGlmIChlZGl0YWJsZSAmJiBlbnRyeS5lZGl0YWJsZSkge1xuICAgICAgICBlZGl0YWJsZSA9IGVudHJ5LmVkaXRhYmxlKGVsZW1lbnQsIGVudHJ5Tm9kZSwgbm9kZSwgbmFtZSwgbmV3VmFsdWUsIGlkeCk7XG4gICAgICB9XG5cbiAgICAgIGRvbUF0dHIobm9kZSwgJ3JlYWRvbmx5JywgZWRpdGFibGUgPyBudWxsIDogJycpO1xuICAgICAgZG9tQXR0cihub2RlLCAnZGlzYWJsZWQnLCBlZGl0YWJsZSA/IG51bGwgOiAnJyk7XG5cbiAgICAgIC8vIHRha2UgZnVsbCBjb250cm9sIG92ZXIgc2V0dGluZyB0aGUgdmFsdWVcbiAgICAgIC8vIGFuZCBwb3NzaWJseSB1cGRhdGluZyB0aGUgaW5wdXQgaW4gZW50cnkjc2V0Q29udHJvbFZhbHVlXG4gICAgICBpZiAoZW50cnkuc2V0Q29udHJvbFZhbHVlKSB7XG4gICAgICAgIGVudHJ5LnNldENvbnRyb2xWYWx1ZShlbGVtZW50LCBlbnRyeU5vZGUsIG5vZGUsIG5hbWUsIG5ld1ZhbHVlLCBpZHgpO1xuICAgICAgfSBlbHNlIGlmIChpc1RvZ2dsZShub2RlKSkge1xuICAgICAgICBzZXRUb2dnbGVWYWx1ZShub2RlLCBuZXdWYWx1ZSk7XG4gICAgICB9IGVsc2UgaWYgKGlzU2VsZWN0KG5vZGUpKSB7XG4gICAgICAgIHNldFNlbGVjdFZhbHVlKG5vZGUsIG5ld1ZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldElucHV0VmFsdWUobm9kZSwgbmV3VmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHdlIGRlYWwgd2l0aCBzb21lIG5vbi1lZGl0YWJsZSBodG1sIGVsZW1lbnRcbiAgICBlbHNlIHtcbiAgICAgIG5hbWUgPSBkb21BdHRyKG5vZGUsICdkYXRhLXZhbHVlJyk7XG4gICAgICBuZXdWYWx1ZSA9IHZhbHVlc1tuYW1lXTtcbiAgICAgIGlmIChlbnRyeS5zZXRDb250cm9sVmFsdWUpIHtcbiAgICAgICAgZW50cnkuc2V0Q29udHJvbFZhbHVlKGVsZW1lbnQsIGVudHJ5Tm9kZSwgbm9kZSwgbmFtZSwgbmV3VmFsdWUsIGlkeCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRUZXh0VmFsdWUobm9kZSwgbmV3VmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG59O1xuXG4vLyBUT0RPKG5pa2t1KTogV1RGIGZyZWFraW5nIG5hbWU/IENoYW5nZSAvIGNsYXJpZnkuXG5Qcm9wZXJ0aWVzUGFuZWwucHJvdG90eXBlLl91cGRhdGVBY3RpdmF0aW9uID0gZnVuY3Rpb24oY3VycmVudCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgdmFyIGVsZW1lbnQgPSBjdXJyZW50LmVsZW1lbnQ7XG5cbiAgZnVuY3Rpb24gaXNFbnRyeVZpc2libGUoZW50cnkpIHtcbiAgICByZXR1cm4gZXZlbnRCdXMuZmlyZSgncHJvcGVydGllc1BhbmVsLmlzRW50cnlWaXNpYmxlJywge1xuICAgICAgZW50cnk6IGVudHJ5LFxuICAgICAgZWxlbWVudDogZWxlbWVudFxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNHcm91cFZpc2libGUoZ3JvdXAsIGVsZW1lbnQsIGdyb3VwTm9kZSkge1xuICAgIGlmICh0eXBlb2YgZ3JvdXAuZW5hYmxlZCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgcmV0dXJuIGdyb3VwLmVuYWJsZWQoZWxlbWVudCwgZ3JvdXBOb2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaXNUYWJWaXNpYmxlKHRhYiwgZWxlbWVudCkge1xuICAgIGlmICh0eXBlb2YgdGFiLmVuYWJsZWQgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgIHJldHVybiB0YWIuZW5hYmxlZChlbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdG9nZ2xlVmlzaWJsZShub2RlLCB2aXNpYmxlKSB7XG4gICAgZG9tQ2xhc3Nlcyhub2RlKS50b2dnbGUoSElERV9DTEFTUywgIXZpc2libGUpO1xuICB9XG5cbiAgLy8gY2hlY2sgd2hldGhlciB0aGUgYWN0aXZlIHRhYiBpcyB2aXNpYmxlXG4gIC8vIGlmIG5vdDogc2V0IHRoZSBmaXJzdCB0YWIgYXMgYWN0aXZlIHRhYlxuICBmdW5jdGlvbiBjaGVja0FjdGl2ZVRhYlZpc2liaWxpdHkobm9kZSwgdmlzaWJsZSkge1xuICAgIHZhciBpc0FjdGl2ZSA9IGRvbUNsYXNzZXMobm9kZSkuaGFzKCdicHAtYWN0aXZlJyk7XG4gICAgaWYgKCF2aXNpYmxlICYmIGlzQWN0aXZlKSB7XG4gICAgICBzZWxmLmFjdGl2YXRlVGFiKGN1cnJlbnQudGFic1swXSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTGFiZWwoZWxlbWVudCwgc2VsZWN0b3IsIHRleHQpIHtcbiAgICB2YXIgbGFiZWxOb2RlID0gZG9tUXVlcnkoc2VsZWN0b3IsIGVsZW1lbnQpO1xuXG4gICAgaWYgKCFsYWJlbE5vZGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsYWJlbE5vZGUudGV4dENvbnRlbnQgPSB0ZXh0O1xuICB9XG5cbiAgdmFyIHBhbmVsTm9kZSA9IGN1cnJlbnQucGFuZWw7XG5cbiAgZm9yRWFjaChjdXJyZW50LnRhYnMsIGZ1bmN0aW9uKHRhYikge1xuXG4gICAgdmFyIHRhYk5vZGUgPSBkb21RdWVyeSgnW2RhdGEtdGFiPScgKyB0YWIuaWQgKyAnXScsIHBhbmVsTm9kZSk7XG4gICAgdmFyIHRhYkxpbmtOb2RlID0gZG9tUXVlcnkoJ1tkYXRhLXRhYi10YXJnZXQ9JyArIHRhYi5pZCArICddJywgcGFuZWxOb2RlKS5wYXJlbnROb2RlO1xuXG4gICAgdmFyIHRhYlZpc2libGUgPSBmYWxzZTtcblxuICAgIGZvckVhY2godGFiLmdyb3VwcywgZnVuY3Rpb24oZ3JvdXApIHtcblxuICAgICAgdmFyIGdyb3VwVmlzaWJsZSA9IGZhbHNlO1xuXG4gICAgICB2YXIgZ3JvdXBOb2RlID0gZG9tUXVlcnkoJ1tkYXRhLWdyb3VwPScgKyBncm91cC5pZCArICddJywgdGFiTm9kZSk7XG5cbiAgICAgIGZvckVhY2goZ3JvdXAuZW50cmllcywgZnVuY3Rpb24oZW50cnkpIHtcblxuICAgICAgICB2YXIgZW50cnlOb2RlID0gZG9tUXVlcnkoJ1tkYXRhLWVudHJ5PVwiJyArIGVudHJ5LmlkICsgJ1wiXScsIGdyb3VwTm9kZSk7XG5cbiAgICAgICAgdmFyIGVudHJ5VmlzaWJsZSA9IGlzRW50cnlWaXNpYmxlKGVudHJ5KTtcblxuICAgICAgICBncm91cFZpc2libGUgPSBncm91cFZpc2libGUgfHwgZW50cnlWaXNpYmxlO1xuXG4gICAgICAgIHRvZ2dsZVZpc2libGUoZW50cnlOb2RlLCBlbnRyeVZpc2libGUpO1xuXG4gICAgICAgIHZhciB2YWx1ZXMgPSAnZ2V0JyBpbiBlbnRyeSA/IGVudHJ5LmdldChlbGVtZW50LCBlbnRyeU5vZGUpIDoge307XG5cbiAgICAgICAgaWYgKHZhbHVlcyBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICAgICAgdmFyIGxpc3RFbnRyeUNvbnRhaW5lciA9IGRvbVF1ZXJ5KCdbZGF0YS1saXN0LWVudHJ5LWNvbnRhaW5lcl0nLCBlbnRyeU5vZGUpO1xuICAgICAgICAgIHZhciBleGlzdGluZ0VsZW1lbnRzID0gbGlzdEVudHJ5Q29udGFpbmVyLmNoaWxkcmVuIHx8IFtdO1xuXG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2YWx1ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBsaXN0VmFsdWUgPSB2YWx1ZXNbaV07XG4gICAgICAgICAgICB2YXIgbGlzdEl0ZW1Ob2RlID0gZXhpc3RpbmdFbGVtZW50c1tpXTtcbiAgICAgICAgICAgIGlmICghbGlzdEl0ZW1Ob2RlKSB7XG4gICAgICAgICAgICAgIGxpc3RJdGVtTm9kZSA9IGRvbWlmeShlbnRyeS5jcmVhdGVMaXN0RW50cnlUZW1wbGF0ZShsaXN0VmFsdWUsIGksIGxpc3RFbnRyeUNvbnRhaW5lcikpO1xuICAgICAgICAgICAgICBsaXN0RW50cnlDb250YWluZXIuYXBwZW5kQ2hpbGQobGlzdEl0ZW1Ob2RlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGRvbUF0dHIobGlzdEl0ZW1Ob2RlLCAnZGF0YS1pbmRleCcsIGkpO1xuXG4gICAgICAgICAgICBzZWxmLl9iaW5kVGVtcGxhdGUoZWxlbWVudCwgZW50cnksIGxpc3RWYWx1ZSwgbGlzdEl0ZW1Ob2RlLCBpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgZW50cmllc1RvUmVtb3ZlID0gZXhpc3RpbmdFbGVtZW50cy5sZW5ndGggLSB2YWx1ZXMubGVuZ3RoO1xuXG4gICAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBlbnRyaWVzVG9SZW1vdmU7IGorKykge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIG9ycGhhbmVkIGVsZW1lbnRcbiAgICAgICAgICAgIGxpc3RFbnRyeUNvbnRhaW5lci5yZW1vdmVDaGlsZChsaXN0RW50cnlDb250YWluZXIubGFzdENoaWxkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzZWxmLl9iaW5kVGVtcGxhdGUoZWxlbWVudCwgZW50cnksIHZhbHVlcywgZW50cnlOb2RlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHVwZGF0ZSBjb25kaXRpb25hbGx5IHZpc2libGUgZWxlbWVudHNcbiAgICAgICAgc2VsZi51cGRhdGVTdGF0ZShlbnRyeSwgZW50cnlOb2RlKTtcbiAgICAgICAgc2VsZi52YWxpZGF0ZShlbnRyeSwgdmFsdWVzLCBlbnRyeU5vZGUpO1xuXG4gICAgICAgIC8vIHJlbWVtYmVyIGluaXRpYWwgc3RhdGUgZm9yIGxhdGVyIGRpcnR5IGNoZWNraW5nXG4gICAgICAgIGVudHJ5Lm9sZFZhbHVlcyA9IGdldEZvcm1Db250cm9sVmFsdWVzKGVudHJ5Tm9kZSk7XG4gICAgICB9KTtcblxuICAgICAgaWYgKHR5cGVvZiBncm91cC5sYWJlbCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICB1cGRhdGVMYWJlbChncm91cE5vZGUsICcuZ3JvdXAtbGFiZWwnLCBncm91cC5sYWJlbChlbGVtZW50LCBncm91cE5vZGUpKTtcbiAgICAgIH1cblxuICAgICAgZ3JvdXBWaXNpYmxlID0gZ3JvdXBWaXNpYmxlICYmIGlzR3JvdXBWaXNpYmxlKGdyb3VwLCBlbGVtZW50LCBncm91cE5vZGUpO1xuXG4gICAgICB0YWJWaXNpYmxlID0gdGFiVmlzaWJsZSB8fCBncm91cFZpc2libGU7XG5cbiAgICAgIHRvZ2dsZVZpc2libGUoZ3JvdXBOb2RlLCBncm91cFZpc2libGUpO1xuICAgIH0pO1xuXG4gICAgdGFiVmlzaWJsZSA9IHRhYlZpc2libGUgJiYgaXNUYWJWaXNpYmxlKHRhYiwgZWxlbWVudCk7XG5cbiAgICB0b2dnbGVWaXNpYmxlKHRhYk5vZGUsIHRhYlZpc2libGUpO1xuICAgIHRvZ2dsZVZpc2libGUodGFiTGlua05vZGUsIHRhYlZpc2libGUpO1xuXG4gICAgY2hlY2tBY3RpdmVUYWJWaXNpYmlsaXR5KHRhYk5vZGUsIHRhYlZpc2libGUpO1xuICB9KTtcblxuICAvLyBpbmplY3QgZWxlbWVudHMgaWQgaW50byBoZWFkZXJcbiAgdXBkYXRlTGFiZWwocGFuZWxOb2RlLCAnW2RhdGEtbGFiZWwtaWRdJywgZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkuaWQgfHwgJycpO1xufTtcblxuUHJvcGVydGllc1BhbmVsLnByb3RvdHlwZS5fY3JlYXRlUGFuZWwgPSBmdW5jdGlvbihlbGVtZW50LCB0YWJzKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgcGFuZWxOb2RlID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiYnBwLXByb3BlcnRpZXNcIj48L2Rpdj4nKSxcbiAgICAgIGhlYWRlck5vZGUgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJicHAtcHJvcGVydGllcy1oZWFkZXJcIj4nICtcbiAgICAgICAgJzxkaXYgY2xhc3M9XCJsYWJlbFwiIGRhdGEtbGFiZWwtaWQ+PC9kaXY+JyArXG4gICAgICAgICc8ZGl2IGNsYXNzPVwic2VhcmNoXCI+JyArXG4gICAgICAgICAgJzxpbnB1dCB0eXBlPVwic2VhcmNoXCIgcGxhY2Vob2xkZXI9XCJTZWFyY2ggZm9yIHByb3BlcnR5XCIgLz4nICtcbiAgICAgICAgICAnPGJ1dHRvbj48c3Bhbj5TZWFyY2g8L3NwYW4+PC9idXR0b24+JyArXG4gICAgICAgICc8L2Rpdj4nICtcbiAgICAgICc8L2Rpdj4nKSxcbiAgICAgIHRhYkJhck5vZGUgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJicHAtcHJvcGVydGllcy10YWItYmFyXCI+PC9kaXY+JyksXG4gICAgICB0YWJMaW5rc05vZGUgPSBkb21pZnkoJzx1bCBjbGFzcz1cImJwcC1wcm9wZXJ0aWVzLXRhYnMtbGlua3NcIj48L3VsPicpLFxuICAgICAgdGFiQ29udGFpbmVyTm9kZSA9IGRvbWlmeSgnPGRpdiBjbGFzcz1cImJwcC1wcm9wZXJ0aWVzLXRhYnMtY29udGFpbmVyXCI+PC9kaXY+Jyk7XG5cbiAgcGFuZWxOb2RlLmFwcGVuZENoaWxkKGhlYWRlck5vZGUpO1xuXG4gIGZvckVhY2godGFicywgZnVuY3Rpb24odGFiLCB0YWJJbmRleCkge1xuXG4gICAgaWYgKCF0YWIuaWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcigndGFiIG11c3QgaGF2ZSBhbiBpZCcpO1xuICAgIH1cblxuICAgIHZhciB0YWJOb2RlID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiYnBwLXByb3BlcnRpZXMtdGFiXCIgZGF0YS10YWI9XCInICsgZXNjYXBlSFRNTCh0YWIuaWQpICsgJ1wiPjwvZGl2PicpLFxuICAgICAgICB0YWJMaW5rTm9kZSA9IGRvbWlmeSgnPGxpIGNsYXNzPVwiYnBwLXByb3BlcnRpZXMtdGFiLWxpbmtcIj4nICtcbiAgICAgICAgICAnPGEgaHJlZiBkYXRhLXRhYi10YXJnZXQ9XCInICsgZXNjYXBlSFRNTCh0YWIuaWQpICsgJ1wiPicgKyBlc2NhcGVIVE1MKHRhYi5sYWJlbCkgKyAnPC9hPicgK1xuICAgICAgICAnPC9saT4nKTtcblxuICAgIHZhciBncm91cHMgPSB0YWIuZ3JvdXBzO1xuXG4gICAgZm9yRWFjaChncm91cHMsIGZ1bmN0aW9uKGdyb3VwKSB7XG5cbiAgICAgIGlmICghZ3JvdXAuaWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdncm91cCBtdXN0IGhhdmUgYW4gaWQnKTtcbiAgICAgIH1cblxuICAgICAgdmFyIGdyb3VwTm9kZSA9IGRvbWlmeSgnPGRpdiBjbGFzcz1cImJwcC1wcm9wZXJ0aWVzLWdyb3VwXCIgZGF0YS1ncm91cD1cIicgKyBlc2NhcGVIVE1MKGdyb3VwLmlkKSArICdcIj4nICtcbiAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJncm91cC10b2dnbGVcIj48L3NwYW4+JyArXG4gICAgICAgICAgJzxzcGFuIGNsYXNzPVwiZ3JvdXAtbGFiZWxcIj4nICsgZXNjYXBlSFRNTChncm91cC5sYWJlbCkgKyAnPC9zcGFuPicgK1xuICAgICAgICAnPC9kaXY+Jyk7XG5cbiAgICAgIC8vIFRPRE8obnJlKTogdXNlIGV2ZW50IGRlbGVnYXRpb24gdG8gaGFuZGxlIHRoYXQuLi5cbiAgICAgIGdyb3VwTm9kZS5xdWVyeVNlbGVjdG9yKCcuZ3JvdXAtdG9nZ2xlJykuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihldnQpIHtcbiAgICAgICAgZG9tQ2xhc3Nlcyhncm91cE5vZGUpLnRvZ2dsZSgnZ3JvdXAtY2xvc2VkJyk7XG4gICAgICAgIGV2dC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBldnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9KTtcbiAgICAgIGdyb3VwTm9kZS5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIGZ1bmN0aW9uKGV2dCkge1xuICAgICAgICBpZiAoIWV2dC5kZWZhdWx0UHJldmVudGVkICYmIGRvbUNsYXNzZXMoZ3JvdXBOb2RlKS5oYXMoJ2dyb3VwLWNsb3NlZCcpKSB7XG4gICAgICAgICAgZG9tQ2xhc3Nlcyhncm91cE5vZGUpLnJlbW92ZSgnZ3JvdXAtY2xvc2VkJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBmb3JFYWNoKGdyb3VwLmVudHJpZXMsIGZ1bmN0aW9uKGVudHJ5KSB7XG5cbiAgICAgICAgaWYgKCFlbnRyeS5pZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignZW50cnkgbXVzdCBoYXZlIGFuIGlkJyk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaHRtbCA9IGVudHJ5Lmh0bWw7XG5cbiAgICAgICAgaWYgKHR5cGVvZiBodG1sID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGh0bWwgPSBkb21pZnkoaHRtbCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB1bndyYXAganF1ZXJ5XG4gICAgICAgIGlmIChodG1sLmdldCAmJiBodG1sLmNvbnN0cnVjdG9yLnByb3RvdHlwZS5qcXVlcnkpIHtcbiAgICAgICAgICBodG1sID0gaHRtbC5nZXQoMCk7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgZW50cnlOb2RlID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiYnBwLXByb3BlcnRpZXMtZW50cnlcIiBkYXRhLWVudHJ5PVwiJyArIGVzY2FwZUhUTUwoZW50cnkuaWQpICsgJ1wiPjwvZGl2PicpO1xuXG4gICAgICAgIGZvckVhY2goZW50cnkuY3NzQ2xhc3NlcyB8fCBbXSwgZnVuY3Rpb24oY3NzQ2xhc3MpIHtcbiAgICAgICAgICBkb21DbGFzc2VzKGVudHJ5Tm9kZSkuYWRkKGNzc0NsYXNzKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgZW50cnlOb2RlLmFwcGVuZENoaWxkKGh0bWwpO1xuXG4gICAgICAgIGdyb3VwTm9kZS5hcHBlbmRDaGlsZChlbnRyeU5vZGUpO1xuXG4gICAgICAgIC8vIHVwZGF0ZSBjb25kaXRpb25hbGx5IHZpc2libGUgZWxlbWVudHNcbiAgICAgICAgc2VsZi51cGRhdGVTdGF0ZShlbnRyeSwgZW50cnlOb2RlKTtcbiAgICAgIH0pO1xuXG4gICAgICB0YWJOb2RlLmFwcGVuZENoaWxkKGdyb3VwTm9kZSk7XG4gICAgfSk7XG5cbiAgICB0YWJMaW5rc05vZGUuYXBwZW5kQ2hpbGQodGFiTGlua05vZGUpO1xuICAgIHRhYkNvbnRhaW5lck5vZGUuYXBwZW5kQ2hpbGQodGFiTm9kZSk7XG4gIH0pO1xuXG4gIHRhYkJhck5vZGUuYXBwZW5kQ2hpbGQodGFiTGlua3NOb2RlKTtcblxuICBwYW5lbE5vZGUuYXBwZW5kQ2hpbGQodGFiQmFyTm9kZSk7XG4gIHBhbmVsTm9kZS5hcHBlbmRDaGlsZCh0YWJDb250YWluZXJOb2RlKTtcblxuICByZXR1cm4gcGFuZWxOb2RlO1xufTtcblxuXG5cbmZ1bmN0aW9uIHNldElucHV0VmFsdWUobm9kZSwgdmFsdWUpIHtcblxuICB2YXIgY29udGVudEVkaXRhYmxlID0gaXNDb250ZW50RWRpdGFibGUobm9kZSk7XG5cbiAgdmFyIG9sZFZhbHVlID0gY29udGVudEVkaXRhYmxlID8gbm9kZS5pbm5lclRleHQgOiBub2RlLnZhbHVlO1xuXG4gIHZhciBzZWxlY3Rpb247XG5cbiAgLy8gcHJldmVudHMgaW5wdXQgZmllbGRzIGZyb20gaGF2aW5nIHRoZSB2YWx1ZSAndW5kZWZpbmVkJ1xuICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgIHZhbHVlID0gJyc7XG4gIH1cblxuICBpZiAob2xkVmFsdWUgPT09IHZhbHVlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gdXBkYXRlIHNlbGVjdGlvbiBvbiB1bmRvL3JlZG9cbiAgaWYgKGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgPT09IG5vZGUpIHtcbiAgICBzZWxlY3Rpb24gPSB1cGRhdGVTZWxlY3Rpb24oZ2V0U2VsZWN0aW9uKG5vZGUpLCBvbGRWYWx1ZSwgdmFsdWUpO1xuICB9XG5cbiAgaWYgKGNvbnRlbnRFZGl0YWJsZSkge1xuICAgIG5vZGUuaW5uZXJUZXh0ID0gdmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgbm9kZS52YWx1ZSA9IHZhbHVlO1xuICB9XG5cbiAgaWYgKHNlbGVjdGlvbikge1xuICAgIHNldFNlbGVjdGlvbihub2RlLCBzZWxlY3Rpb24pO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNldFNlbGVjdFZhbHVlKG5vZGUsIHZhbHVlKSB7XG4gIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgbm9kZS52YWx1ZSA9IHZhbHVlO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNldFRvZ2dsZVZhbHVlKG5vZGUsIHZhbHVlKSB7XG4gIHZhciBub2RlVmFsdWUgPSBub2RlLnZhbHVlO1xuXG4gIG5vZGUuY2hlY2tlZCA9ICh2YWx1ZSA9PT0gbm9kZVZhbHVlKSB8fCAoIWRvbUF0dHIobm9kZSwgJ3ZhbHVlJykgJiYgdmFsdWUpO1xufVxuXG5mdW5jdGlvbiBzZXRUZXh0VmFsdWUobm9kZSwgdmFsdWUpIHtcbiAgbm9kZS50ZXh0Q29udGVudCA9IHZhbHVlO1xufVxuXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb24obm9kZSkge1xuXG4gIHJldHVybiBpc0NvbnRlbnRFZGl0YWJsZShub2RlKSA/IGdldENvbnRlbnRFZGl0YWJsZVNlbGVjdGlvbihub2RlKSA6IHtcbiAgICBzdGFydDogbm9kZS5zZWxlY3Rpb25TdGFydCxcbiAgICBlbmQ6IG5vZGUuc2VsZWN0aW9uRW5kXG4gIH07XG59XG5cbmZ1bmN0aW9uIGdldENvbnRlbnRFZGl0YWJsZVNlbGVjdGlvbihub2RlKSB7XG5cbiAgdmFyIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcblxuICB2YXIgZm9jdXNOb2RlID0gc2VsZWN0aW9uLmZvY3VzTm9kZSxcbiAgICAgIGZvY3VzT2Zmc2V0ID0gc2VsZWN0aW9uLmZvY3VzT2Zmc2V0LFxuICAgICAgYW5jaG9yT2Zmc2V0ID0gc2VsZWN0aW9uLmFuY2hvck9mZnNldDtcblxuICBpZiAoIWZvY3VzTm9kZSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbm90IHNlbGVjdGVkJyk7XG4gIH1cblxuICAvLyB2ZXJpZnkgd2UgaGF2ZSBzZWxlY3Rpb24gb24gdGhlIGN1cnJlbnQgZWxlbWVudFxuICBpZiAoIW5vZGUuY29udGFpbnMoZm9jdXNOb2RlKSkge1xuICAgIHRocm93IG5ldyBFcnJvcignbm90IHNlbGVjdGVkJyk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHN0YXJ0OiBNYXRoLm1pbihmb2N1c09mZnNldCwgYW5jaG9yT2Zmc2V0KSxcbiAgICBlbmQ6IE1hdGgubWF4KGZvY3VzT2Zmc2V0LCBhbmNob3JPZmZzZXQpXG4gIH07XG59XG5cbmZ1bmN0aW9uIHNldFNlbGVjdGlvbihub2RlLCBzZWxlY3Rpb24pIHtcblxuICBpZiAoaXNDb250ZW50RWRpdGFibGUobm9kZSkpIHtcbiAgICBzZXRDb250ZW50RWRpdGFibGVTZWxlY3Rpb24obm9kZSwgc2VsZWN0aW9uKTtcbiAgfSBlbHNlIHtcbiAgICBub2RlLnNlbGVjdGlvblN0YXJ0ID0gc2VsZWN0aW9uLnN0YXJ0O1xuICAgIG5vZGUuc2VsZWN0aW9uRW5kID0gc2VsZWN0aW9uLmVuZDtcbiAgfVxufVxuXG5mdW5jdGlvbiBzZXRDb250ZW50RWRpdGFibGVTZWxlY3Rpb24obm9kZSwgc2VsZWN0aW9uKSB7XG5cbiAgdmFyIGZvY3VzTm9kZSxcbiAgICAgIGRvbVJhbmdlLFxuICAgICAgZG9tU2VsZWN0aW9uO1xuXG4gIGZvY3VzTm9kZSA9IG5vZGUuZmlyc3RDaGlsZCB8fCBub2RlLFxuICBkb21SYW5nZSA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gIGRvbVJhbmdlLnNldFN0YXJ0KGZvY3VzTm9kZSwgc2VsZWN0aW9uLnN0YXJ0KTtcbiAgZG9tUmFuZ2Uuc2V0RW5kKGZvY3VzTm9kZSwgc2VsZWN0aW9uLmVuZCk7XG5cbiAgZG9tU2VsZWN0aW9uID0gd2luZG93LmdldFNlbGVjdGlvbigpO1xuICBkb21TZWxlY3Rpb24ucmVtb3ZlQWxsUmFuZ2VzKCk7XG4gIGRvbVNlbGVjdGlvbi5hZGRSYW5nZShkb21SYW5nZSk7XG59XG5cbmZ1bmN0aW9uIGlzSW1wbGljaXRSb290KGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQuaWQgPT09ICdfX2ltcGxpY2l0cm9vdCc7XG59XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBkb21RdWVyeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeSxcbiAgICBkb21DbGVhciA9IHJlcXVpcmUoJ21pbi1kb20nKS5jbGVhcixcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXG4gICAgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyksXG4gICAgZG9taWZ5ID0gcmVxdWlyZSgnbWluLWRvbScpLmRvbWlmeSxcbiAgICBJZHMgPSByZXF1aXJlKCdpZHMnKS5kZWZhdWx0O1xuXG52YXIgU1BBQ0VfUkVHRVggPSAvXFxzLztcblxuLy8gZm9yIFFOYW1lIHZhbGlkYXRpb24gYXMgcGVyIGh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwvI05ULU5hbWVDaGFyXG52YXIgUU5BTUVfUkVHRVggPSAvXihbYS16XVtcXHctLl0qOik/W2Etel9dW1xcdy0uXSokL2k7XG5cbi8vIGZvciBJRCB2YWxpZGF0aW9uIGFzIHBlciBCUE1OIFNjaGVtYSAoUU5hbWUgLSBOYW1lc3BhY2UpXG52YXIgSURfUkVHRVggPSAvXlthLXpfXVtcXHctLl0qJC9pO1xuXG52YXIgUExBQ0VIT0xERVJfUkVHRVggPSAvXFwkXFx7KFtefV0qKVxcfS9nO1xuXG52YXIgSFRNTF9FU0NBUEVfTUFQID0ge1xuICAnJic6ICcmYW1wOycsXG4gICc8JzogJyZsdDsnLFxuICAnPic6ICcmZ3Q7JyxcbiAgJ1wiJzogJyZxdW90OycsXG4gICdcXCcnOiAnJiMzOTsnXG59O1xuXG5mdW5jdGlvbiBzZWxlY3RlZE9wdGlvbihzZWxlY3RCb3gpIHtcbiAgaWYgKHNlbGVjdEJveC5zZWxlY3RlZEluZGV4ID49IDApIHtcbiAgICByZXR1cm4gc2VsZWN0Qm94Lm9wdGlvbnNbc2VsZWN0Qm94LnNlbGVjdGVkSW5kZXhdLnZhbHVlO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzLnNlbGVjdGVkT3B0aW9uID0gc2VsZWN0ZWRPcHRpb247XG5cblxuZnVuY3Rpb24gc2VsZWN0ZWRUeXBlKGVsZW1lbnRTeW50YXgsIGlucHV0Tm9kZSkge1xuICB2YXIgdHlwZVNlbGVjdCA9IGRvbVF1ZXJ5KGVsZW1lbnRTeW50YXgsIGlucHV0Tm9kZSk7XG4gIHJldHVybiBzZWxlY3RlZE9wdGlvbih0eXBlU2VsZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMuc2VsZWN0ZWRUeXBlID0gc2VsZWN0ZWRUeXBlO1xuXG5cbi8qKlxuICogUmV0cmlldmUgdGhlIHJvb3QgZWxlbWVudCB0aGUgZG9jdW1lbnQgdGhpc1xuICogYnVzaW5lc3Mgb2JqZWN0IGlzIGNvbnRhaW5lZCBpbi5cbiAqXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxuICovXG5mdW5jdGlvbiBnZXRSb290KGJ1c2luZXNzT2JqZWN0KSB7XG4gIHZhciBwYXJlbnQgPSBidXNpbmVzc09iamVjdDtcbiAgd2hpbGUgKHBhcmVudC4kcGFyZW50KSB7XG4gICAgcGFyZW50ID0gcGFyZW50LiRwYXJlbnQ7XG4gIH1cbiAgcmV0dXJuIHBhcmVudDtcbn1cblxubW9kdWxlLmV4cG9ydHMuZ2V0Um9vdCA9IGdldFJvb3Q7XG5cblxuLyoqXG4gKiBmaWx0ZXJzIGFsbCBlbGVtZW50cyBpbiB0aGUgbGlzdCB3aGljaCBoYXZlIGEgZ2l2ZW4gdHlwZS5cbiAqIHJlbW92ZXMgYSBuZXcgbGlzdFxuICovXG5mdW5jdGlvbiBmaWx0ZXJFbGVtZW50c0J5VHlwZShvYmplY3RMaXN0LCB0eXBlKSB7XG4gIHZhciBsaXN0ID0gb2JqZWN0TGlzdCB8fCBbXTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3JFYWNoKGxpc3QsIGZ1bmN0aW9uKG9iaikge1xuICAgIGlmIChpcyhvYmosIHR5cGUpKSB7XG4gICAgICByZXN1bHQucHVzaChvYmopO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzLmZpbHRlckVsZW1lbnRzQnlUeXBlID0gZmlsdGVyRWxlbWVudHNCeVR5cGU7XG5cblxuZnVuY3Rpb24gZmluZFJvb3RFbGVtZW50c0J5VHlwZShidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpIHtcbiAgdmFyIHJvb3QgPSBnZXRSb290KGJ1c2luZXNzT2JqZWN0KTtcblxuICByZXR1cm4gZmlsdGVyRWxlbWVudHNCeVR5cGUocm9vdC5yb290RWxlbWVudHMsIHJlZmVyZW5jZWRUeXBlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuZmluZFJvb3RFbGVtZW50c0J5VHlwZSA9IGZpbmRSb290RWxlbWVudHNCeVR5cGU7XG5cblxuZnVuY3Rpb24gcmVtb3ZlQWxsQ2hpbGRyZW4oZG9tRWxlbWVudCkge1xuICB3aGlsZSAoZG9tRWxlbWVudC5maXJzdENoaWxkKSB7XG4gICAgZG9tRWxlbWVudC5yZW1vdmVDaGlsZChkb21FbGVtZW50LmZpcnN0Q2hpbGQpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzLnJlbW92ZUFsbENoaWxkcmVuID0gcmVtb3ZlQWxsQ2hpbGRyZW47XG5cblxuLyoqXG4gKiBhZGRzIGFuIGVtcHR5IG9wdGlvbiB0byB0aGUgbGlzdFxuICovXG5mdW5jdGlvbiBhZGRFbXB0eVBhcmFtZXRlcihsaXN0KSB7XG4gIHJldHVybiBsaXN0LnB1c2goeyAnbGFiZWwnOiAnJywgJ3ZhbHVlJzogJycsICduYW1lJzogJycgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzLmFkZEVtcHR5UGFyYW1ldGVyID0gYWRkRW1wdHlQYXJhbWV0ZXI7XG5cblxuLyoqXG4gKiByZXR1cm5zIGEgbGlzdCB3aXRoIGFsbCByb290IGVsZW1lbnRzIGZvciB0aGUgZ2l2ZW4gcGFyYW1ldGVyICdyZWZlcmVuY2VkVHlwZSdcbiAqL1xuZnVuY3Rpb24gcmVmcmVzaE9wdGlvbnNNb2RlbChidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpIHtcbiAgdmFyIG1vZGVsID0gW107XG4gIHZhciByZWZlcmFibGVPYmplY3RzID0gZmluZFJvb3RFbGVtZW50c0J5VHlwZShidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpO1xuICBmb3JFYWNoKHJlZmVyYWJsZU9iamVjdHMsIGZ1bmN0aW9uKG9iaikge1xuICAgIG1vZGVsLnB1c2goe1xuICAgICAgbGFiZWw6IChvYmoubmFtZSB8fCAnJykgKyAnIChpZD0nK29iai5pZCsnKScsXG4gICAgICB2YWx1ZTogb2JqLmlkLFxuICAgICAgbmFtZTogb2JqLm5hbWVcbiAgICB9KTtcbiAgfSk7XG4gIHJldHVybiBtb2RlbDtcbn1cblxubW9kdWxlLmV4cG9ydHMucmVmcmVzaE9wdGlvbnNNb2RlbCA9IHJlZnJlc2hPcHRpb25zTW9kZWw7XG5cblxuLyoqXG4gKiBmaWxscyB0aGUgZHJvcCBkb3duIHdpdGggb3B0aW9uc1xuICovXG5mdW5jdGlvbiB1cGRhdGVPcHRpb25zRHJvcERvd24oZG9tU2VsZWN0b3IsIGJ1c2luZXNzT2JqZWN0LCByZWZlcmVuY2VkVHlwZSwgZW50cnlOb2RlKSB7XG4gIHZhciBvcHRpb25zID0gcmVmcmVzaE9wdGlvbnNNb2RlbChidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpO1xuICBhZGRFbXB0eVBhcmFtZXRlcihvcHRpb25zKTtcbiAgdmFyIHNlbGVjdEJveCA9IGRvbVF1ZXJ5KGRvbVNlbGVjdG9yLCBlbnRyeU5vZGUpO1xuICBkb21DbGVhcihzZWxlY3RCb3gpO1xuXG4gIGZvckVhY2gob3B0aW9ucywgZnVuY3Rpb24ob3B0aW9uKSB7XG4gICAgdmFyIG9wdGlvbkVudHJ5ID0gZG9taWZ5KCc8b3B0aW9uIHZhbHVlPVwiJyArIGVzY2FwZUhUTUwob3B0aW9uLnZhbHVlKSArICdcIj4nICsgZXNjYXBlSFRNTChvcHRpb24ubGFiZWwpICsgJzwvb3B0aW9uPicpO1xuICAgIHNlbGVjdEJveC5hcHBlbmRDaGlsZChvcHRpb25FbnRyeSk7XG4gIH0pO1xuICByZXR1cm4gb3B0aW9ucztcbn1cblxubW9kdWxlLmV4cG9ydHMudXBkYXRlT3B0aW9uc0Ryb3BEb3duID0gdXBkYXRlT3B0aW9uc0Ryb3BEb3duO1xuXG5cbi8qKlxuICogY2hlY2tzIHdoZXRoZXIgdGhlIGlkIHZhbHVlIGlzIHZhbGlkXG4gKlxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBib1xuICogQHBhcmFtIHtTdHJpbmd9IGlkVmFsdWVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHRyYW5zbGF0ZVxuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gZXJyb3IgbWVzc2FnZVxuICovXG5mdW5jdGlvbiBpc0lkVmFsaWQoYm8sIGlkVmFsdWUsIHRyYW5zbGF0ZSkge1xuICB2YXIgYXNzaWduZWQgPSBiby4kbW9kZWwuaWRzLmFzc2lnbmVkKGlkVmFsdWUpO1xuXG4gIHZhciBpZEV4aXN0cyA9IGFzc2lnbmVkICYmIGFzc2lnbmVkICE9PSBibztcblxuICBpZiAoIWlkVmFsdWUgfHwgaWRFeGlzdHMpIHtcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdFbGVtZW50IG11c3QgaGF2ZSBhbiB1bmlxdWUgaWQuJyk7XG4gIH1cblxuICByZXR1cm4gdmFsaWRhdGVJZChpZFZhbHVlLCB0cmFuc2xhdGUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cy5pc0lkVmFsaWQgPSBpc0lkVmFsaWQ7XG5cblxuZnVuY3Rpb24gdmFsaWRhdGVJZChpZFZhbHVlLCB0cmFuc2xhdGUpIHtcblxuICBpZFZhbHVlID0gc3RyaXBQbGFjZWhvbGRlcnMoaWRWYWx1ZSk7XG5cbiAgaWYgKGNvbnRhaW5zU3BhY2UoaWRWYWx1ZSkpIHtcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdJZCBtdXN0IG5vdCBjb250YWluIHNwYWNlcy4nKTtcbiAgfVxuXG4gIGlmICghSURfUkVHRVgudGVzdChpZFZhbHVlKSkge1xuXG4gICAgaWYgKFFOQU1FX1JFR0VYLnRlc3QoaWRWYWx1ZSkpIHtcbiAgICAgIHJldHVybiB0cmFuc2xhdGUoJ0lkIG11c3Qgbm90IGNvbnRhaW4gcHJlZml4LicpO1xuICAgIH1cblxuICAgIHJldHVybiB0cmFuc2xhdGUoJ0lkIG11c3QgYmUgYSB2YWxpZCBRTmFtZS4nKTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cy52YWxpZGF0ZUlkID0gdmFsaWRhdGVJZDtcblxuXG5mdW5jdGlvbiBjb250YWluc1NwYWNlKHZhbHVlKSB7XG4gIHJldHVybiBTUEFDRV9SRUdFWC50ZXN0KHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMuY29udGFpbnNTcGFjZSA9IGNvbnRhaW5zU3BhY2U7XG5cblxuZnVuY3Rpb24gc3RyaXBQbGFjZWhvbGRlcnMoaWRWYWx1ZSkge1xuXG4gIC8vIHJlcGxhY2UgZXhwcmVzc2lvbiBlLmcuICR7VkVSU0lPTl9UQUd9XG4gIC8vIHVzZSBvbmx5IHRoZSBjb250ZW50IGJldHdlZW4gJHt9XG4gIC8vIGZvciB0aGUgUkVHRVggY2hlY2tcbiAgcmV0dXJuIGlkVmFsdWUucmVwbGFjZShQTEFDRUhPTERFUl9SRUdFWCwgJyQxJyk7XG59XG5cbi8qKlxuICogZ2VuZXJhdGUgYSBzZW1hbnRpYyBpZCB3aXRoIGdpdmVuIHByZWZpeFxuICovXG5mdW5jdGlvbiBuZXh0SWQocHJlZml4KSB7XG4gIHZhciBpZHMgPSBuZXcgSWRzKFszMiwzMiwxXSk7XG5cbiAgcmV0dXJuIGlkcy5uZXh0UHJlZml4ZWQocHJlZml4KTtcbn1cblxubW9kdWxlLmV4cG9ydHMubmV4dElkID0gbmV4dElkO1xuXG5cbmZ1bmN0aW9uIHRyaWdnZXJDbGlja0V2ZW50KGVsZW1lbnQpIHtcbiAgdmFyIGV2dDtcbiAgdmFyIGV2ZW50VHlwZSA9ICdjbGljayc7XG5cbiAgaWYgKGRvY3VtZW50LmNyZWF0ZUV2ZW50KSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIENocm9tZSwgU2FmYXJpLCBGaXJlZm94XG4gICAgICBldnQgPSBuZXcgTW91c2VFdmVudCgoZXZlbnRUeXBlKSwgeyB2aWV3OiB3aW5kb3csIGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibGU6IHRydWUgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gSUUgMTEsIFBoYW50b21KUyAod2F0ISlcbiAgICAgIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50Jyk7XG5cbiAgICAgIGV2dC5pbml0RXZlbnQoKGV2ZW50VHlwZSksIHRydWUsIHRydWUpO1xuICAgIH1cbiAgICByZXR1cm4gZWxlbWVudC5kaXNwYXRjaEV2ZW50KGV2dCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gV2VsY29tZSBJRVxuICAgIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50T2JqZWN0KCk7XG5cbiAgICByZXR1cm4gZWxlbWVudC5maXJlRXZlbnQoJ29uJyArIGV2ZW50VHlwZSwgZXZ0KTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cy50cmlnZ2VyQ2xpY2tFdmVudCA9IHRyaWdnZXJDbGlja0V2ZW50O1xuXG5cbmZ1bmN0aW9uIGVzY2FwZUhUTUwoc3RyKSB7XG4gIHN0ciA9ICcnICsgc3RyO1xuXG4gIHJldHVybiBzdHIgJiYgc3RyLnJlcGxhY2UoL1smPD5cIiddL2csIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgcmV0dXJuIEhUTUxfRVNDQVBFX01BUFttYXRjaF07XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cy5lc2NhcGVIVE1MID0gZXNjYXBlSFRNTDsiLCIndXNlIHN0cmljdCc7XG5cbnZhciBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKTtcblxuLyoqXG4gKiBBIGhhbmRsZXIgY2FwYWJsZSBvZiBjcmVhdGluZyBhIG5ldyBlbGVtZW50IHVuZGVyIGEgcHJvdmlkZWQgcGFyZW50XG4gKiBhbmQgdXBkYXRpbmcgLyBjcmVhdGluZyBhIHJlZmVyZW5jZSB0byBpdCBpbiBvbmUgYXRvbWljIGFjdGlvbi5cbiAqXG4gKiBAY2xhc3NcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBDcmVhdGVBbmRSZWZlcmVuY2VFbGVtZW50SGFuZGxlcihlbGVtZW50UmVnaXN0cnksIGJwbW5GYWN0b3J5KSB7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbiAgdGhpcy5fYnBtbkZhY3RvcnkgPSBicG1uRmFjdG9yeTtcbn1cblxuQ3JlYXRlQW5kUmVmZXJlbmNlRWxlbWVudEhhbmRsZXIuJGluamVjdCA9IFsgJ2VsZW1lbnRSZWdpc3RyeScsICdicG1uRmFjdG9yeScgXTtcblxubW9kdWxlLmV4cG9ydHMgPSBDcmVhdGVBbmRSZWZlcmVuY2VFbGVtZW50SGFuZGxlcjtcblxuXG4vLyBhcGkgLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGVsZW1lbnQgdW5kZXIgYSBwcm92aWRlZCBwYXJlbnQgYW5kIHVwZGF0ZXMgLyBjcmVhdGVzIGEgcmVmZXJlbmNlIHRvIGl0IGluXG4gKiBvbmUgYXRvbWljIGFjdGlvbi5cbiAqXG4gKiBAbWV0aG9kICBDcmVhdGVBbmRSZWZlcmVuY2VFbGVtZW50SGFuZGxlciNleGVjdXRlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGNvbnRleHQuZWxlbWVudCB3aGljaCBpcyB0aGUgY29udGV4dCBmb3IgdGhlIHJlZmVyZW5jZVxuICogQHBhcmFtIHttb2RkbGUucmVmZXJlbmNpbmdPYmplY3R9IGNvbnRleHQucmVmZXJlbmNpbmdPYmplY3QgdGhlIG9iamVjdCB3aGljaCBjcmVhdGVzIHRoZSByZWZlcmVuY2VcbiAqIEBwYXJhbSB7U3RyaW5nfSBjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5IHRoZSBwcm9wZXJ0eSBvZiB0aGUgcmVmZXJlbmNpbmdPYmplY3Qgd2hpY2ggbWFrZXMgdGhlIHJlZmVyZW5jZVxuICogQHBhcmFtIHttb2RkbGUubmV3T2JqZWN0fSBjb250ZXh0Lm5ld09iamVjdCB0aGUgbmV3IG9iamVjdCB0byBhZGRcbiAqIEBwYXJhbSB7bW9kZGxlLm5ld09iamVjdENvbnRhaW5lcn0gY29udGV4dC5uZXdPYmplY3RDb250YWluZXIgdGhlIGNvbnRhaW5lciBmb3IgdGhlIG5ldyBvYmplY3RcbiAqXG4gKiBAcmV0dXJucyB7QXJyYXk8ZGpzLm1vZGUuQmFzZT59IHRoZSB1cGRhdGVkIGVsZW1lbnRcbiAqL1xuQ3JlYXRlQW5kUmVmZXJlbmNlRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHJlZmVyZW5jaW5nT2JqZWN0ID0gZW5zdXJlTm90TnVsbChjb250ZXh0LnJlZmVyZW5jaW5nT2JqZWN0LCAncmVmZXJlbmNpbmdPYmplY3QnKSxcbiAgICAgIHJlZmVyZW5jZVByb3BlcnR5ID0gZW5zdXJlTm90TnVsbChjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5LCAncmVmZXJlbmNlUHJvcGVydHknKSxcbiAgICAgIG5ld09iamVjdCA9IGVuc3VyZU5vdE51bGwoY29udGV4dC5uZXdPYmplY3QsICduZXdPYmplY3QnKSxcbiAgICAgIG5ld09iamVjdENvbnRhaW5lciA9IGVuc3VyZU5vdE51bGwoY29udGV4dC5uZXdPYmplY3RDb250YWluZXIsICduZXdPYmplY3RDb250YWluZXInKSxcbiAgICAgIG5ld09iamVjdFBhcmVudCA9IGVuc3VyZU5vdE51bGwoY29udGV4dC5uZXdPYmplY3RQYXJlbnQsICduZXdPYmplY3RQYXJlbnQnKSxcbiAgICAgIGNoYW5nZWQgPSBbIGNvbnRleHQuZWxlbWVudCBdOyAvLyB0aGlzIHdpbGwgbm90IGNoYW5nZSBhbnkgZGlhZ3JhbS1qcyBlbGVtZW50c1xuXG4gIC8vIGNyZWF0ZSBuZXcgb2JqZWN0XG4gIHZhciByZWZlcmVuY2VkT2JqZWN0ID0gZWxlbWVudEhlbHBlclxuICAgIC5jcmVhdGVFbGVtZW50KG5ld09iamVjdC50eXBlLCBuZXdPYmplY3QucHJvcGVydGllcywgbmV3T2JqZWN0UGFyZW50LCB0aGlzLl9icG1uRmFjdG9yeSk7XG4gIGNvbnRleHQucmVmZXJlbmNlZE9iamVjdCA9IHJlZmVyZW5jZWRPYmplY3Q7XG5cbiAgLy8gYWRkIHRvIGNvbnRhaW5pbmcgbGlzdFxuICBuZXdPYmplY3RDb250YWluZXIucHVzaChyZWZlcmVuY2VkT2JqZWN0KTtcblxuICAvLyBhZGp1c3QgcmVmZXJlbmNlIGF0dHJpYnV0ZVxuICBjb250ZXh0LnByZXZpb3VzUmVmZXJlbmNlID0gcmVmZXJlbmNpbmdPYmplY3RbcmVmZXJlbmNlUHJvcGVydHldO1xuICByZWZlcmVuY2luZ09iamVjdFtyZWZlcmVuY2VQcm9wZXJ0eV0gPSByZWZlcmVuY2VkT2JqZWN0O1xuXG4gIGNvbnRleHQuY2hhbmdlZCA9IGNoYW5nZWQ7XG5cbiAgLy8gaW5kaWNhdGUgY2hhbmdlZCBvbiBvYmplY3RzIGFmZmVjdGVkIGJ5IHRoZSB1cGRhdGVcbiAgcmV0dXJuIGNoYW5nZWQ7XG59O1xuXG4vKipcbiAqIFJldmVydHMgdGhlIHVwZGF0ZVxuICpcbiAqIEBtZXRob2QgIENyZWF0ZUFuZFJlZmVyZW5jZUVsZW1lbnRIYW5kbGVyI3JldmVydFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKlxuICogQHJldHVybnMge2Rqcy5tb2RlLkJhc2V9IHRoZSB1cGRhdGVkIGVsZW1lbnRcbiAqL1xuQ3JlYXRlQW5kUmVmZXJlbmNlRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgcmVmZXJlbmNpbmdPYmplY3QgPSBjb250ZXh0LnJlZmVyZW5jaW5nT2JqZWN0LFxuICAgICAgcmVmZXJlbmNlUHJvcGVydHkgPSBjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5LFxuICAgICAgcHJldmlvdXNSZWZlcmVuY2UgPSBjb250ZXh0LnByZXZpb3VzUmVmZXJlbmNlLFxuICAgICAgcmVmZXJlbmNlZE9iamVjdCA9IGNvbnRleHQucmVmZXJlbmNlZE9iamVjdCxcbiAgICAgIG5ld09iamVjdENvbnRhaW5lciA9IGNvbnRleHQubmV3T2JqZWN0Q29udGFpbmVyO1xuXG4gIC8vIHJlc2V0IHJlZmVyZW5jZVxuICByZWZlcmVuY2luZ09iamVjdC5zZXQocmVmZXJlbmNlUHJvcGVydHksIHByZXZpb3VzUmVmZXJlbmNlKTtcblxuICAvLyByZW1vdmUgbmV3IGVsZW1lbnRcbiAgbmV3T2JqZWN0Q29udGFpbmVyLnNwbGljZShuZXdPYmplY3RDb250YWluZXIuaW5kZXhPZihyZWZlcmVuY2VkT2JqZWN0KSwgMSk7XG5cbiAgcmV0dXJuIGNvbnRleHQuY2hhbmdlZDtcbn07XG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGVuc3VyZU5vdE51bGwocHJvcCwgbmFtZSkge1xuICBpZiAoIXByb3ApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IobmFtZSArICcgcmVxdWlyZWQnKTtcbiAgfVxuICByZXR1cm4gcHJvcDtcbn1cbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xuXG52YXIgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyk7XG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyBhIEJQTU4gMi4wIHByb3BlcnR5IHVwZGF0ZVxuICogZm9yIGJ1c2luZXNzIG9iamVjdHMgd2hpY2ggYXJlIG5vdCByZXByZXNlbnRlZCBpbiB0aGVcbiAqIGRpYWdyYW0uXG4gKlxuICogVGhpcyBpcyB1c2VmdWwgaW4gdGhlIGNvbnRleHQgb2YgdGhlIHByb3BlcnRpZXMgcGFuZWwgaW5cbiAqIG9yZGVyIHRvIHVwZGF0ZSBjaGlsZCBlbGVtZW50cyBvZiBlbGVtZW50cyB2aXNpYmxlIGluXG4gKiB0aGUgZGlhZ3JhbS5cbiAqXG4gKiBFeGFtcGxlOiBwZXJmb3JtIGFuIHVwZGF0ZSBvZiBhIHNwZWNpZmljIGV2ZW50IGRlZmluaXRpb25cbiAqIG9mIGFuIGludGVybWVkaWF0ZSBldmVudC5cbiAqXG4gKiBAY2xhc3NcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBDcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyKGVsZW1lbnRSZWdpc3RyeSwgYnBtbkZhY3RvcnkpIHtcbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9icG1uRmFjdG9yeSA9IGJwbW5GYWN0b3J5O1xufVxuXG5DcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLiRpbmplY3QgPSBbICdlbGVtZW50UmVnaXN0cnknLCAnYnBtbkZhY3RvcnknIF07XG5cbm1vZHVsZS5leHBvcnRzID0gQ3JlYXRlQnVzaW5lc3NPYmplY3RMaXN0SGFuZGxlcjtcblxuZnVuY3Rpb24gZW5zdXJlTm90TnVsbChwcm9wLCBuYW1lKSB7XG4gIGlmICghcHJvcCkge1xuICAgIHRocm93IG5ldyBFcnJvcihuYW1lICsgJyByZXF1aXJlZCcpO1xuICB9XG4gIHJldHVybiBwcm9wO1xuXG59XG5mdW5jdGlvbiBlbnN1cmVMaXN0KHByb3AsIG5hbWUpIHtcbiAgaWYgKCFwcm9wIHx8IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChwcm9wKSAhPT0gJ1tvYmplY3QgQXJyYXldJykge1xuICAgIHRocm93IG5ldyBFcnJvcihuYW1lICsgJyBuZWVkcyB0byBiZSBhIGxpc3QnKTtcbiAgfVxuICByZXR1cm4gcHJvcDtcbn1cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZWxlbWVudCB1bmRlciBhIHByb3ZpZGVkIHBhcmVudCBhbmQgdXBkYXRlcyAvIGNyZWF0ZXMgYSByZWZlcmVuY2UgdG8gaXQgaW5cbiAqIG9uZSBhdG9taWMgYWN0aW9uLlxuICpcbiAqIEBtZXRob2QgIENyZWF0ZUJ1c2luZXNzT2JqZWN0TGlzdEhhbmRsZXIjZXhlY3V0ZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBjb250ZXh0LmVsZW1lbnQgd2hpY2ggaXMgdGhlIGNvbnRleHQgZm9yIHRoZSByZWZlcmVuY2VcbiAqIEBwYXJhbSB7bW9kZGxlLnJlZmVyZW5jaW5nT2JqZWN0fSBjb250ZXh0LnJlZmVyZW5jaW5nT2JqZWN0IHRoZSBvYmplY3Qgd2hpY2ggY3JlYXRlcyB0aGUgcmVmZXJlbmNlXG4gKiBAcGFyYW0ge1N0cmluZ30gY29udGV4dC5yZWZlcmVuY2VQcm9wZXJ0eSB0aGUgcHJvcGVydHkgb2YgdGhlIHJlZmVyZW5jaW5nT2JqZWN0IHdoaWNoIG1ha2VzIHRoZSByZWZlcmVuY2VcbiAqIEBwYXJhbSB7bW9kZGxlLm5ld09iamVjdH0gY29udGV4dC5uZXdPYmplY3QgdGhlIG5ldyBvYmplY3QgdG8gYWRkXG4gKiBAcGFyYW0ge21vZGRsZS5uZXdPYmplY3RDb250YWluZXJ9IGNvbnRleHQubmV3T2JqZWN0Q29udGFpbmVyIHRoZSBjb250YWluZXIgZm9yIHRoZSBuZXcgb2JqZWN0XG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGUuQmFzZT59IHRoZSB1cGRhdGVkIGVsZW1lbnRcbiAqL1xuQ3JlYXRlQnVzaW5lc3NPYmplY3RMaXN0SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY3VycmVudE9iamVjdCA9IGVuc3VyZU5vdE51bGwoY29udGV4dC5jdXJyZW50T2JqZWN0LCAnY3VycmVudE9iamVjdCcpLFxuICAgICAgcHJvcGVydHlOYW1lID0gZW5zdXJlTm90TnVsbChjb250ZXh0LnByb3BlcnR5TmFtZSwgJ3Byb3BlcnR5TmFtZScpLFxuICAgICAgbmV3T2JqZWN0cyA9IGVuc3VyZUxpc3QoY29udGV4dC5uZXdPYmplY3RzLCAnbmV3T2JqZWN0cycpLFxuICAgICAgY2hhbmdlZCA9IFsgY29udGV4dC5lbGVtZW50IF07IC8vIHRoaXMgd2lsbCBub3QgY2hhbmdlIGFueSBkaWFncmFtLWpzIGVsZW1lbnRzXG5cblxuICB2YXIgY2hpbGRPYmplY3RzID0gW107XG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvLyBjcmVhdGUgbmV3IGFycmF5IG9mIGJ1c2luZXNzIG9iamVjdHNcbiAgZm9yRWFjaChuZXdPYmplY3RzLCBmdW5jdGlvbihvYmopIHtcbiAgICB2YXIgZWxlbWVudCA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudChvYmoudHlwZSwgb2JqLnByb3BlcnRpZXMsIGN1cnJlbnRPYmplY3QsIHNlbGYuX2JwbW5GYWN0b3J5KTtcblxuICAgIGNoaWxkT2JqZWN0cy5wdXNoKGVsZW1lbnQpO1xuICB9KTtcbiAgY29udGV4dC5jaGlsZE9iamVjdCA9IGNoaWxkT2JqZWN0cztcblxuICAvLyBhZGp1c3QgYXJyYXkgcmVmZXJlbmNlIGluIHRoZSBwYXJlbnQgYnVzaW5lc3Mgb2JqZWN0XG4gIGNvbnRleHQucHJldmlvdXNDaGlsZHMgPSBjdXJyZW50T2JqZWN0W3Byb3BlcnR5TmFtZV07XG4gIGN1cnJlbnRPYmplY3RbcHJvcGVydHlOYW1lXSA9IGNoaWxkT2JqZWN0cztcblxuICBjb250ZXh0LmNoYW5nZWQgPSBjaGFuZ2VkO1xuXG4gIC8vIGluZGljYXRlIGNoYW5nZWQgb24gb2JqZWN0cyBhZmZlY3RlZCBieSB0aGUgdXBkYXRlXG4gIHJldHVybiBjaGFuZ2VkO1xufTtcblxuLyoqXG4gKiBSZXZlcnRzIHRoZSB1cGRhdGVcbiAqXG4gKiBAbWV0aG9kICBDcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyI3JldmVydFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGUuQmFzZX0gdGhlIHVwZGF0ZWQgZWxlbWVudFxuICovXG5DcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGN1cnJlbnRPYmplY3QgPSBjb250ZXh0LmN1cnJlbnRPYmplY3QsXG4gICAgICBwcm9wZXJ0eU5hbWUgPSBjb250ZXh0LnByb3BlcnR5TmFtZSxcbiAgICAgIHByZXZpb3VzQ2hpbGRzID0gY29udGV4dC5wcmV2aW91c0NoaWxkcztcblxuICAvLyByZW1vdmUgbmV3IGVsZW1lbnRcbiAgY3VycmVudE9iamVjdC5zZXQocHJvcGVydHlOYW1lLCBwcmV2aW91c0NoaWxkcyk7XG5cbiAgcmV0dXJuIGNvbnRleHQuY2hhbmdlZDtcbn07XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKTtcblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBjb21iaW5lcyBhbmQgZXhlY3V0ZXMgbXVsdGlwbGUgY29tbWFuZHMuXG4gKlxuICogQWxsIHVwZGF0ZXMgYXJlIGJ1bmRsZWQgb24gdGhlIGNvbW1hbmQgc3RhY2sgYW5kIGV4ZWN1dGVkIGluIG9uZSBzdGVwLlxuICogVGhpcyBhbHNvIG1ha2VzIGl0IHBvc3NpYmxlIHRvIHJldmVydCB0aGUgY2hhbmdlcyBpbiBvbmUgc3RlcC5cbiAqXG4gKiBFeGFtcGxlIHVzZSBjYXNlOiByZW1vdmUgdGhlIGNhbXVuZGE6Zm9ybUtleSBhdHRyaWJ1dGUgYW5kIGluIGFkZGl0aW9uXG4gKiBhZGQgYWxsIGZvcm0gZmllbGRzIG5lZWRlZCBmb3IgdGhlIGNhbXVuZGE6Zm9ybURhdGEgcHJvcGVydHkuXG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gTXVsdGlDb21tYW5kSGFuZGxlcihjb21tYW5kU3RhY2spIHtcbiAgdGhpcy5fY29tbWFuZFN0YWNrID0gY29tbWFuZFN0YWNrO1xufVxuXG5NdWx0aUNvbW1hbmRIYW5kbGVyLiRpbmplY3QgPSBbICdjb21tYW5kU3RhY2snIF07XG5cbm1vZHVsZS5leHBvcnRzID0gTXVsdGlDb21tYW5kSGFuZGxlcjtcblxuTXVsdGlDb21tYW5kSGFuZGxlci5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY29tbWFuZFN0YWNrID0gdGhpcy5fY29tbWFuZFN0YWNrO1xuXG4gIGZvckVhY2goY29udGV4dCwgZnVuY3Rpb24oY29tbWFuZCkge1xuICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKGNvbW1hbmQuY21kLCBjb21tYW5kLmNvbnRleHQpO1xuICB9KTtcbn07IiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgcmVkdWNlID0gcmVxdWlyZSgnbG9kYXNoL3RyYW5zZm9ybScpLFxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcbiAgICBrZXlzID0gcmVxdWlyZSgnbG9kYXNoL2tleXMnKSxcbiAgICBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKTtcblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBpbXBsZW1lbnRzIGEgQlBNTiAyLjAgcHJvcGVydHkgdXBkYXRlXG4gKiBmb3IgYnVzaW5lc3Mgb2JqZWN0cyB3aGljaCBhcmUgbm90IHJlcHJlc2VudGVkIGluIHRoZVxuICogZGlhZ3JhbS5cbiAqXG4gKiBUaGlzIGlzIHVzZWZ1bCBpbiB0aGUgY29udGV4dCBvZiB0aGUgcHJvcGVydGllcyBwYW5lbCBpblxuICogb3JkZXIgdG8gdXBkYXRlIGNoaWxkIGVsZW1lbnRzIG9mIGVsZW1lbnRzIHZpc2libGUgaW5cbiAqIHRoZSBkaWFncmFtLlxuICpcbiAqIEV4YW1wbGU6IHBlcmZvcm0gYW4gdXBkYXRlIG9mIGEgc3BlY2lmaWMgZXZlbnQgZGVmaW5pdGlvblxuICogb2YgYW4gaW50ZXJtZWRpYXRlIGV2ZW50LlxuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIFVwZGF0ZUJ1c2luZXNzT2JqZWN0SGFuZGxlcihlbGVtZW50UmVnaXN0cnkpIHtcbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xufVxuXG5VcGRhdGVCdXNpbmVzc09iamVjdEhhbmRsZXIuJGluamVjdCA9IFsgJ2VsZW1lbnRSZWdpc3RyeScgXTtcblxubW9kdWxlLmV4cG9ydHMgPSBVcGRhdGVCdXNpbmVzc09iamVjdEhhbmRsZXI7XG5cbi8qKlxuICogcmV0dXJucyB0aGUgcm9vdCBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGdldFJvb3QoYnVzaW5lc3NPYmplY3QpIHtcbiAgdmFyIHBhcmVudCA9IGJ1c2luZXNzT2JqZWN0O1xuICB3aGlsZSAocGFyZW50LiRwYXJlbnQpIHtcbiAgICBwYXJlbnQgPSBwYXJlbnQuJHBhcmVudDtcbiAgfVxuICByZXR1cm4gcGFyZW50O1xufVxuXG5mdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBwcm9wZXJ0eU5hbWVzKSB7XG4gIHJldHVybiByZWR1Y2UocHJvcGVydHlOYW1lcywgZnVuY3Rpb24ocmVzdWx0LCBrZXkpIHtcbiAgICByZXN1bHRba2V5XSA9IGJ1c2luZXNzT2JqZWN0LmdldChrZXkpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sIHt9KTtcbn1cblxuXG5mdW5jdGlvbiBzZXRQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBwcm9wZXJ0aWVzKSB7XG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuICAgIGJ1c2luZXNzT2JqZWN0LnNldChrZXksIHZhbHVlKTtcbiAgfSk7XG59XG5cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIFVwZGF0ZXMgYSBidXNpbmVzcyBvYmplY3Qgd2l0aCBhIGxpc3Qgb2YgbmV3IHByb3BlcnRpZXNcbiAqXG4gKiBAbWV0aG9kICBVcGRhdGVCdXNpbmVzc09iamVjdEhhbmRsZXIjZXhlY3V0ZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBjb250ZXh0LmVsZW1lbnQgdGhlIGVsZW1lbnQgd2hpY2ggaGFzIGEgY2hpbGQgYnVzaW5lc3Mgb2JqZWN0IHVwZGF0ZWRcbiAqIEBwYXJhbSB7bW9kZGxlLmJ1c2luZXNzT2JqZWN0fSBjb250ZXh0LmJ1c2luZXNzT2JqZWN0IHRoZSBidXNpbmVzc09iamVjdCB0byB1cGRhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LnByb3BlcnRpZXMgYSBsaXN0IG9mIHByb3BlcnRpZXMgdG8gc2V0IG9uIHRoZSBidXNpbmVzc09iamVjdFxuICpcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlLkJhc2U+fSB0aGUgdXBkYXRlZCBlbGVtZW50XG4gKi9cblVwZGF0ZUJ1c2luZXNzT2JqZWN0SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcbiAgICAgIGJ1c2luZXNzT2JqZWN0ID0gY29udGV4dC5idXNpbmVzc09iamVjdCxcbiAgICAgIHJvb3RFbGVtZW50cyA9IGdldFJvb3QoYnVzaW5lc3NPYmplY3QpLnJvb3RFbGVtZW50cyxcbiAgICAgIHJlZmVyZW5jZVR5cGUgPSBjb250ZXh0LnJlZmVyZW5jZVR5cGUsXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eSA9IGNvbnRleHQucmVmZXJlbmNlUHJvcGVydHksXG4gICAgICBjaGFuZ2VkID0gWyBlbGVtZW50IF07IC8vIHRoaXMgd2lsbCBub3QgY2hhbmdlIGFueSBkaWFncmFtLWpzIGVsZW1lbnRzXG5cbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbGVtZW50IHJlcXVpcmVkJyk7XG4gIH1cblxuICBpZiAoIWJ1c2luZXNzT2JqZWN0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdidXNpbmVzc09iamVjdCByZXF1aXJlZCcpO1xuICB9XG5cbiAgdmFyIHByb3BlcnRpZXMgPSBjb250ZXh0LnByb3BlcnRpZXMsXG4gICAgICBvbGRQcm9wZXJ0aWVzID0gY29udGV4dC5vbGRQcm9wZXJ0aWVzIHx8IGdldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIGtleXMocHJvcGVydGllcykpO1xuXG4gIC8vIGNoZWNrIGlmIHRoZXJlIHRoZSB1cGRhdGUgbmVlZHMgYW4gZXh0ZXJuYWwgZWxlbWVudCBmb3IgcmVmZXJlbmNlXG4gIGlmICh0eXBlb2YgcmVmZXJlbmNlVHlwZSAhPT0gJ3VuZGVmaW5lZCcgJiYgdHlwZW9mIHJlZmVyZW5jZVByb3BlcnR5ICE9PSAndW5kZWZpbmVkJykge1xuICAgIGZvckVhY2gocm9vdEVsZW1lbnRzLCBmdW5jdGlvbihyb290RWxlbWVudCkge1xuICAgICAgaWYgKGlzKHJvb3RFbGVtZW50LCByZWZlcmVuY2VUeXBlKSkge1xuICAgICAgICBpZiAocm9vdEVsZW1lbnQuaWQgPT09IHByb3BlcnRpZXNbcmVmZXJlbmNlUHJvcGVydHldKSB7XG4gICAgICAgICAgcHJvcGVydGllc1tyZWZlcmVuY2VQcm9wZXJ0eV0gPSByb290RWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gdXBkYXRlIHByb3BlcnRpZXNcbiAgc2V0UHJvcGVydGllcyhidXNpbmVzc09iamVjdCwgcHJvcGVydGllcyk7XG5cbiAgLy8gc3RvcmUgb2xkIHZhbHVlc1xuICBjb250ZXh0Lm9sZFByb3BlcnRpZXMgPSBvbGRQcm9wZXJ0aWVzO1xuICBjb250ZXh0LmNoYW5nZWQgPSBjaGFuZ2VkO1xuXG4gIC8vIGluZGljYXRlIGNoYW5nZWQgb24gb2JqZWN0cyBhZmZlY3RlZCBieSB0aGUgdXBkYXRlXG4gIHJldHVybiBjaGFuZ2VkO1xufTtcblxuLyoqXG4gKiBSZXZlcnRzIHRoZSB1cGRhdGVcbiAqXG4gKiBAbWV0aG9kICBVcGRhdGVCdXNpbmVzc09iamVjdEhhbmRsZXIjcmV2ZXJ0XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqXG4gKiBAcmV0dXJuIHtkanMubW9kZS5CYXNlfSB0aGUgdXBkYXRlZCBlbGVtZW50XG4gKi9cblVwZGF0ZUJ1c2luZXNzT2JqZWN0SGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBvbGRQcm9wZXJ0aWVzID0gY29udGV4dC5vbGRQcm9wZXJ0aWVzLFxuICAgICAgYnVzaW5lc3NPYmplY3QgPSBjb250ZXh0LmJ1c2luZXNzT2JqZWN0O1xuXG4gIC8vIHVwZGF0ZSBwcm9wZXJ0aWVzXG4gIHNldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIG9sZFByb3BlcnRpZXMpO1xuXG4gIHJldHVybiBjb250ZXh0LmNoYW5nZWQ7XG59O1xuIiwiJ3VzZSBzdHJpY3QnO1xuXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyBhIEJQTU4gMi4wIHByb3BlcnR5IHVwZGF0ZVxuICogZm9yIGJ1c2luZXNzIG9iamVjdCBsaXN0cyB3aGljaCBhcmUgbm90IHJlcHJlc2VudGVkIGluIHRoZVxuICogZGlhZ3JhbS5cbiAqXG4gKiBUaGlzIGlzIHVzZWZ1bCBpbiB0aGUgY29udGV4dCBvZiB0aGUgcHJvcGVydGllcyBwYW5lbCBpblxuICogb3JkZXIgdG8gdXBkYXRlIGNoaWxkIGVsZW1lbnRzIG9mIGVsZW1lbnRzIHZpc2libGUgaW5cbiAqIHRoZSBkaWFncmFtLlxuICpcbiAqIEV4YW1wbGU6IHBlcmZvcm0gYW4gdXBkYXRlIG9mIGEgc3BlY2lmaWMgZXZlbnQgZGVmaW5pdGlvblxuICogb2YgYW4gaW50ZXJtZWRpYXRlIGV2ZW50LlxuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIFVwZGF0ZUJ1c2luZXNzT2JqZWN0TGlzdEhhbmRsZXIoZWxlbWVudFJlZ2lzdHJ5LCBicG1uRmFjdG9yeSkge1xuICB0aGlzLl9lbGVtZW50UmVnaXN0cnkgPSBlbGVtZW50UmVnaXN0cnk7XG4gIHRoaXMuX2JwbW5GYWN0b3J5ID0gYnBtbkZhY3Rvcnk7XG59XG5cblVwZGF0ZUJ1c2luZXNzT2JqZWN0TGlzdEhhbmRsZXIuJGluamVjdCA9IFsgJ2VsZW1lbnRSZWdpc3RyeScsICdicG1uRmFjdG9yeScgXTtcblxubW9kdWxlLmV4cG9ydHMgPSBVcGRhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyO1xuXG5mdW5jdGlvbiBlbnN1cmVOb3ROdWxsKHByb3AsIG5hbWUpIHtcbiAgaWYgKCFwcm9wKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKG5hbWUgKyAncmVxdWlyZWQnKTtcbiAgfVxuICByZXR1cm4gcHJvcDtcbn1cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIFVwZGF0ZXMgYSBlbGVtZW50IHVuZGVyIGEgcHJvdmlkZWQgcGFyZW50LlxuICovXG5VcGRhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjdXJyZW50T2JqZWN0ID0gZW5zdXJlTm90TnVsbChjb250ZXh0LmN1cnJlbnRPYmplY3QsICdjdXJyZW50T2JqZWN0JyksXG4gICAgICBwcm9wZXJ0eU5hbWUgPSBlbnN1cmVOb3ROdWxsKGNvbnRleHQucHJvcGVydHlOYW1lLCAncHJvcGVydHlOYW1lJyksXG4gICAgICB1cGRhdGVkT2JqZWN0TGlzdCA9IGNvbnRleHQudXBkYXRlZE9iamVjdExpc3QsXG4gICAgICBvYmplY3RzVG9SZW1vdmUgPSBjb250ZXh0Lm9iamVjdHNUb1JlbW92ZSB8fCBbXSxcbiAgICAgIG9iamVjdHNUb0FkZCA9IGNvbnRleHQub2JqZWN0c1RvQWRkIHx8IFtdLFxuICAgICAgY2hhbmdlZCA9IFsgY29udGV4dC5lbGVtZW50XSwgLy8gdGhpcyB3aWxsIG5vdCBjaGFuZ2UgYW55IGRpYWdyYW0tanMgZWxlbWVudHNcbiAgICAgIHJlZmVyZW5jZVByb3BlcnR5TmFtZTtcblxuICBpZiAoY29udGV4dC5yZWZlcmVuY2VQcm9wZXJ0eU5hbWUpIHtcbiAgICByZWZlcmVuY2VQcm9wZXJ0eU5hbWUgPSBjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5TmFtZTtcbiAgfVxuXG4gIHZhciBvYmplY3RMaXN0ID0gY3VycmVudE9iamVjdFtwcm9wZXJ0eU5hbWVdO1xuICAvLyBhZGp1c3QgYXJyYXkgcmVmZXJlbmNlIGluIHRoZSBwYXJlbnQgYnVzaW5lc3Mgb2JqZWN0XG4gIGNvbnRleHQucHJldmlvdXNMaXN0ID0gY3VycmVudE9iamVjdFtwcm9wZXJ0eU5hbWVdO1xuXG4gIGlmICh1cGRhdGVkT2JqZWN0TGlzdCkge1xuICAgIGN1cnJlbnRPYmplY3RbcHJvcGVydHlOYW1lXSA9IHVwZGF0ZWRPYmplY3RMaXN0O1xuICB9IGVsc2Uge1xuICAgIHZhciBsaXN0Q29weSA9IFtdO1xuICAgIC8vIHJlbW92ZSBhbGwgb2JqZWN0cyB3aGljaCBzaG91bGQgYmUgcmVtb3ZlZFxuICAgIGZvckVhY2gob2JqZWN0TGlzdCwgZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgICBpZiAob2JqZWN0c1RvUmVtb3ZlLmluZGV4T2Yob2JqZWN0KSA9PSAtMSkge1xuICAgICAgICBsaXN0Q29weS5wdXNoKG9iamVjdCk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gYWRkIGFsbCBvYmplY3RzIHdoaWNoIHNob3VsZCBiZSBhZGRlZFxuICAgIGxpc3RDb3B5ID0gbGlzdENvcHkuY29uY2F0KG9iamVjdHNUb0FkZCk7XG5cbiAgICAvLyBzZXQgcHJvcGVydHkgdG8gbmV3IGxpc3RcbiAgICBpZiAobGlzdENvcHkubGVuZ3RoID4gMCB8fCAhcmVmZXJlbmNlUHJvcGVydHlOYW1lKSB7XG5cbiAgICAgIC8vIGFzIGxvbmcgYXMgdGhlcmUgYXJlIGVsZW1lbnRzIGluIHRoZSBsaXN0IHVwZGF0ZSB0aGUgbGlzdFxuICAgICAgY3VycmVudE9iamVjdFtwcm9wZXJ0eU5hbWVdID0gbGlzdENvcHk7XG4gICAgfSBlbHNlIGlmIChyZWZlcmVuY2VQcm9wZXJ0eU5hbWUpIHtcblxuICAgICAgLy8gcmVtb3ZlIHRoZSBsaXN0IHdoZW4gaXQgaXMgZW1wdHlcbiAgICAgIHZhciBwYXJlbnRPYmplY3QgPSBjdXJyZW50T2JqZWN0LiRwYXJlbnQ7XG4gICAgICBwYXJlbnRPYmplY3Quc2V0KHJlZmVyZW5jZVByb3BlcnR5TmFtZSwgdW5kZWZpbmVkKTtcbiAgICB9XG4gIH1cblxuICBjb250ZXh0LmNoYW5nZWQgPSBjaGFuZ2VkO1xuXG4gIC8vIGluZGljYXRlIGNoYW5nZWQgb24gb2JqZWN0cyBhZmZlY3RlZCBieSB0aGUgdXBkYXRlXG4gIHJldHVybiBjaGFuZ2VkO1xufTtcblxuLyoqXG4gKiBSZXZlcnRzIHRoZSB1cGRhdGVcbiAqXG4gKiBAbWV0aG9kICBDcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyI3JldmVydFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGUuQmFzZX0gdGhlIHVwZGF0ZWQgZWxlbWVudFxuICovXG5VcGRhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGN1cnJlbnRPYmplY3QgPSBjb250ZXh0LmN1cnJlbnRPYmplY3QsXG4gICAgICBwcm9wZXJ0eU5hbWUgPSBjb250ZXh0LnByb3BlcnR5TmFtZSxcbiAgICAgIHByZXZpb3VzTGlzdCA9IGNvbnRleHQucHJldmlvdXNMaXN0LFxuICAgICAgcGFyZW50T2JqZWN0ID0gY3VycmVudE9iamVjdC4kcGFyZW50O1xuXG4gIGlmIChjb250ZXh0LnJlZmVyZW5jZVByb3BlcnR5TmFtZSkge1xuICAgIHBhcmVudE9iamVjdC5zZXQoY29udGV4dC5yZWZlcmVuY2VQcm9wZXJ0eU5hbWUsIGN1cnJlbnRPYmplY3QpO1xuICB9XG5cbiAgLy8gcmVtb3ZlIG5ldyBlbGVtZW50XG4gIGN1cnJlbnRPYmplY3Quc2V0KHByb3BlcnR5TmFtZSwgcHJldmlvdXNMaXN0KTtcblxuICByZXR1cm4gY29udGV4dC5jaGFuZ2VkO1xufTtcbiIsIid1c2Ugc3RyaWN0JztcblxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xuXG52YXIgSEFORExFUlMgPSB7XG4gICdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdCc6IHJlcXVpcmUoJy4vVXBkYXRlQnVzaW5lc3NPYmplY3RIYW5kbGVyJyksXG4gICdwcm9wZXJ0aWVzLXBhbmVsLmNyZWF0ZS1hbmQtcmVmZXJlbmNlJzogcmVxdWlyZSgnLi9DcmVhdGVBbmRSZWZlcmVuY2VIYW5kbGVyJyksXG4gICdwcm9wZXJ0aWVzLXBhbmVsLmNyZWF0ZS1idXNpbmVzc29iamVjdC1saXN0JzogcmVxdWlyZSgnLi9DcmVhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyJyksXG4gICdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0JzogcmVxdWlyZSgnLi9VcGRhdGVCdXNpbmVzc09iamVjdExpc3RIYW5kbGVyJyksXG4gICdwcm9wZXJ0aWVzLXBhbmVsLm11bHRpLWNvbW1hbmQtZXhlY3V0b3InOiByZXF1aXJlKCcuL011bHRpQ29tbWFuZEhhbmRsZXInKVxufTtcblxuXG5mdW5jdGlvbiBDb21tYW5kSW5pdGlhbGl6ZXIoZXZlbnRCdXMsIGNvbW1hbmRTdGFjaykge1xuXG4gIGV2ZW50QnVzLm9uKCdkaWFncmFtLmluaXQnLCBmdW5jdGlvbigpIHtcbiAgICBmb3JFYWNoKEhBTkRMRVJTLCBmdW5jdGlvbihoYW5kbGVyLCBpZCkge1xuICAgICAgY29tbWFuZFN0YWNrLnJlZ2lzdGVySGFuZGxlcihpZCwgaGFuZGxlcik7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5Db21tYW5kSW5pdGlhbGl6ZXIuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2NvbW1hbmRTdGFjaycgXTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIF9faW5pdF9fOiBbIENvbW1hbmRJbml0aWFsaXplciBdXG59OyIsIid1c2Ugc3RyaWN0JztcblxudmFyIEVsZW1lbnRIZWxwZXIgPSB7fTtcbm1vZHVsZS5leHBvcnRzID0gRWxlbWVudEhlbHBlcjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGVsZW1lbnQgYW5kIHNldCB0aGUgcGFyZW50IHRvIGl0XG4gKlxuICogQG1ldGhvZCBFbGVtZW50SGVscGVyI2NyZWF0ZUVsZW1lbnRcbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gZWxlbWVudFR5cGUgb2YgdGhlIG5ldyBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBvZiB0aGUgbmV3IGVsZW1lbnQgaW4ga2V5LXZhbHVlIHBhaXJzXG4gKiBAcGFyYW0ge21vZGRsZS5vYmplY3R9IHBhcmVudCBvZiB0aGUgbmV3IGVsZW1lbnRcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGZhY3Rvcnkgd2hpY2ggY3JlYXRlcyB0aGUgbmV3IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJucyB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnQgd2hpY2ggaXMgY3JlYXRlZFxuICovXG5FbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50VHlwZSwgcHJvcGVydGllcywgcGFyZW50LCBmYWN0b3J5KSB7XG4gIHZhciBlbGVtZW50ID0gZmFjdG9yeS5jcmVhdGUoZWxlbWVudFR5cGUsIHByb3BlcnRpZXMpO1xuICBlbGVtZW50LiRwYXJlbnQgPSBwYXJlbnQ7XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgcmVxdWlyZSgnLi9jbWQnKSxcbiAgICByZXF1aXJlKCdkaWFncmFtLWpzL2xpYi9pMThuL3RyYW5zbGF0ZScpLmRlZmF1bHRcbiAgXSxcbiAgX19pbml0X186IFsgJ3Byb3BlcnRpZXNQYW5lbCcgXSxcbiAgcHJvcGVydGllc1BhbmVsOiBbICd0eXBlJywgcmVxdWlyZSgnLi9Qcm9wZXJ0aWVzUGFuZWwnKSBdXG59O1xuIiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IElkcyBmcm9tICdpZHMnO1xuXG5pbXBvcnQgQmFzZVZpZXdlciBmcm9tICcuL0Jhc2VWaWV3ZXInO1xuXG5cbi8qKlxuICogQSBiYXNlIG1vZGVsZXIgZm9yIEJQTU4gMi4wIGRpYWdyYW1zLlxuICpcbiAqIEhhdmUgYSBsb29rIGF0IHtAbGluayBNb2RlbGVyfSBmb3IgYSBidW5kbGUgdGhhdCBpbmNsdWRlcyBhY3R1YWwgZmVhdHVyZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gcGFzcyB0byB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IFtvcHRpb25zLmNvbnRhaW5lcl0gdGhlIGNvbnRhaW5lciB0byByZW5kZXIgdGhlIHZpZXdlciBpbiwgZGVmYXVsdHMgdG8gYm9keS5cbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gW29wdGlvbnMud2lkdGhdIHRoZSB3aWR0aCBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IFtvcHRpb25zLmhlaWdodF0gdGhlIGhlaWdodCBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMubW9kZGxlRXh0ZW5zaW9uc10gZXh0ZW5zaW9uIHBhY2thZ2VzIHRvIHByb3ZpZGVcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5tb2R1bGVzXSBhIGxpc3Qgb2YgbW9kdWxlcyB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCBtb2R1bGVzXG4gKiBAcGFyYW0ge0FycmF5PGRpZGkuTW9kdWxlPn0gW29wdGlvbnMuYWRkaXRpb25hbE1vZHVsZXNdIGEgbGlzdCBvZiBtb2R1bGVzIHRvIHVzZSB3aXRoIHRoZSBkZWZhdWx0IG1vZHVsZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmFzZU1vZGVsZXIob3B0aW9ucykge1xuICBCYXNlVmlld2VyLmNhbGwodGhpcywgb3B0aW9ucyk7XG5cbiAgLy8gaG9vayBJRCBjb2xsZWN0aW9uIGludG8gdGhlIG1vZGVsZXJcbiAgdGhpcy5vbignaW1wb3J0LnBhcnNlLmNvbXBsZXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBpZiAoIWV2ZW50LmVycm9yKSB7XG4gICAgICB0aGlzLl9jb2xsZWN0SWRzKGV2ZW50LmRlZmluaXRpb25zLCBldmVudC5lbGVtZW50c0J5SWQpO1xuICAgIH1cbiAgfSwgdGhpcyk7XG5cbiAgdGhpcy5vbignZGlhZ3JhbS5kZXN0cm95JywgZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5nZXQoJ21vZGRsZScpLmlkcy5jbGVhcigpO1xuICB9LCB0aGlzKTtcbn1cblxuaW5oZXJpdHMoQmFzZU1vZGVsZXIsIEJhc2VWaWV3ZXIpO1xuXG5cbi8qKlxuICogQ3JlYXRlIGEgbW9kZGxlIGluc3RhbmNlLCBhdHRhY2hpbmcgaWRzIHRvIGl0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKi9cbkJhc2VNb2RlbGVyLnByb3RvdHlwZS5fY3JlYXRlTW9kZGxlID0gZnVuY3Rpb24ob3B0aW9ucykge1xuICB2YXIgbW9kZGxlID0gQmFzZVZpZXdlci5wcm90b3R5cGUuX2NyZWF0ZU1vZGRsZS5jYWxsKHRoaXMsIG9wdGlvbnMpO1xuXG4gIC8vIGF0dGFjaCBpZHMgdG8gbW9kZGxlIHRvIGJlIGFibGUgdG8gdHJhY2tcbiAgLy8gYW5kIHZhbGlkYXRlZCBpZHMgaW4gdGhlIEJQTU4gMi4wIFhNTCBkb2N1bWVudFxuICAvLyB0cmVlXG4gIG1vZGRsZS5pZHMgPSBuZXcgSWRzKFsgMzIsIDM2LCAxIF0pO1xuXG4gIHJldHVybiBtb2RkbGU7XG59O1xuXG4vKipcbiAqIENvbGxlY3QgaWRzIHByb2Nlc3NlZCBkdXJpbmcgcGFyc2luZyBvZiB0aGVcbiAqIGRlZmluaXRpb25zIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGRlZmluaXRpb25zXG4gKiBAcGFyYW0ge0NvbnRleHR9IGNvbnRleHRcbiAqL1xuQmFzZU1vZGVsZXIucHJvdG90eXBlLl9jb2xsZWN0SWRzID0gZnVuY3Rpb24oZGVmaW5pdGlvbnMsIGVsZW1lbnRzQnlJZCkge1xuXG4gIHZhciBtb2RkbGUgPSBkZWZpbml0aW9ucy4kbW9kZWwsXG4gICAgICBpZHMgPSBtb2RkbGUuaWRzLFxuICAgICAgaWQ7XG5cbiAgLy8gcmVtb3ZlIHJlZmVyZW5jZXMgZnJvbSBwcmV2aW91cyBpbXBvcnRcbiAgaWRzLmNsZWFyKCk7XG5cbiAgZm9yIChpZCBpbiBlbGVtZW50c0J5SWQpIHtcbiAgICBpZHMuY2xhaW0oaWQsIGVsZW1lbnRzQnlJZFtpZF0pO1xuICB9XG59O1xuIiwiLyoqXG4gKiBUaGUgY29kZSBpbiB0aGUgPHByb2plY3QtbG9nbz48L3Byb2plY3QtbG9nbz4gYXJlYVxuICogbXVzdCBub3QgYmUgY2hhbmdlZC5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9icG1uLmlvL2xpY2Vuc2UgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKi9cbmltcG9ydCB7XG4gIGFzc2lnbixcbiAgZmluZCxcbiAgaXNOdW1iZXIsXG4gIG9taXRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBkb21pZnksXG4gIHF1ZXJ5IGFzIGRvbVF1ZXJ5LFxuICByZW1vdmUgYXMgZG9tUmVtb3ZlXG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICBpbm5lclNWR1xufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCBEaWFncmFtIGZyb20gJ2RpYWdyYW0tanMnO1xuaW1wb3J0IEJwbW5Nb2RkbGUgZnJvbSAnYnBtbi1tb2RkbGUnO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQge1xuICBpbXBvcnRCcG1uRGlhZ3JhbVxufSBmcm9tICcuL2ltcG9ydC9JbXBvcnRlcic7XG5cbmltcG9ydCB7XG4gIHdyYXBGb3JDb21wYXRpYmlsaXR5XG59IGZyb20gJy4vdXRpbC9Db21wYXRpYmlsaXR5VXRpbCc7XG5cbi8qKlxuICogQSBiYXNlIHZpZXdlciBmb3IgQlBNTiAyLjAgZGlhZ3JhbXMuXG4gKlxuICogSGF2ZSBhIGxvb2sgYXQge0BsaW5rIFZpZXdlcn0sIHtAbGluayBOYXZpZ2F0ZWRWaWV3ZXJ9IG9yIHtAbGluayBNb2RlbGVyfSBmb3JcbiAqIGJ1bmRsZXMgdGhhdCBpbmNsdWRlIGFjdHVhbCBmZWF0dXJlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBwYXNzIHRvIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gW29wdGlvbnMuY29udGFpbmVyXSB0aGUgY29udGFpbmVyIHRvIHJlbmRlciB0aGUgdmlld2VyIGluLCBkZWZhdWx0cyB0byBib2R5LlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBbb3B0aW9ucy53aWR0aF0gdGhlIHdpZHRoIG9mIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gW29wdGlvbnMuaGVpZ2h0XSB0aGUgaGVpZ2h0IG9mIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5tb2RkbGVFeHRlbnNpb25zXSBleHRlbnNpb24gcGFja2FnZXMgdG8gcHJvdmlkZVxuICogQHBhcmFtIHtBcnJheTxkaWRpLk1vZHVsZT59IFtvcHRpb25zLm1vZHVsZXNdIGEgbGlzdCBvZiBtb2R1bGVzIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IG1vZHVsZXNcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5hZGRpdGlvbmFsTW9kdWxlc10gYSBsaXN0IG9mIG1vZHVsZXMgdG8gdXNlIHdpdGggdGhlIGRlZmF1bHQgbW9kdWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCYXNlVmlld2VyKG9wdGlvbnMpIHtcblxuICBvcHRpb25zID0gYXNzaWduKHt9LCBERUZBVUxUX09QVElPTlMsIG9wdGlvbnMpO1xuXG4gIHRoaXMuX21vZGRsZSA9IHRoaXMuX2NyZWF0ZU1vZGRsZShvcHRpb25zKTtcblxuICB0aGlzLl9jb250YWluZXIgPSB0aGlzLl9jcmVhdGVDb250YWluZXIob3B0aW9ucyk7XG5cbiAgLyogPHByb2plY3QtbG9nbz4gKi9cblxuICBhZGRQcm9qZWN0TG9nbyh0aGlzLl9jb250YWluZXIpO1xuXG4gIC8qIDwvcHJvamVjdC1sb2dvPiAqL1xuXG4gIHRoaXMuX2luaXQodGhpcy5fY29udGFpbmVyLCB0aGlzLl9tb2RkbGUsIG9wdGlvbnMpO1xufVxuXG5pbmhlcml0cyhCYXNlVmlld2VyLCBEaWFncmFtKTtcblxuLyoqXG4qIFRoZSBpbXBvcnRYTUwgcmVzdWx0LlxuKlxuKiBAdHlwZWRlZiB7T2JqZWN0fSBJbXBvcnRYTUxSZXN1bHRcbipcbiogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuKi9cblxuLyoqXG4qIFRoZSBpbXBvcnRYTUwgZXJyb3IuXG4qXG4qIEB0eXBlZGVmIHtFcnJvcn0gSW1wb3J0WE1MRXJyb3JcbipcbiogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuKi9cblxuLyoqXG4gKiBQYXJzZSBhbmQgcmVuZGVyIGEgQlBNTiAyLjAgZGlhZ3JhbS5cbiAqXG4gKiBPbmNlIGZpbmlzaGVkIHRoZSB2aWV3ZXIgcmVwb3J0cyBiYWNrIHRoZSByZXN1bHQgdG8gdGhlXG4gKiBwcm92aWRlZCBjYWxsYmFjayBmdW5jdGlvbiB3aXRoIChlcnIsIHdhcm5pbmdzKS5cbiAqXG4gKiAjIyBMaWZlLUN5Y2xlIEV2ZW50c1xuICpcbiAqIER1cmluZyBpbXBvcnQgdGhlIHZpZXdlciB3aWxsIGZpcmUgbGlmZS1jeWNsZSBldmVudHM6XG4gKlxuICogICAqIGltcG9ydC5wYXJzZS5zdGFydCAoYWJvdXQgdG8gcmVhZCBtb2RlbCBmcm9tIHhtbClcbiAqICAgKiBpbXBvcnQucGFyc2UuY29tcGxldGUgKG1vZGVsIHJlYWQ7IG1heSBoYXZlIHdvcmtlZCBvciBub3QpXG4gKiAgICogaW1wb3J0LnJlbmRlci5zdGFydCAoZ3JhcGhpY2FsIGltcG9ydCBzdGFydClcbiAqICAgKiBpbXBvcnQucmVuZGVyLmNvbXBsZXRlIChncmFwaGljYWwgaW1wb3J0IGZpbmlzaGVkKVxuICogICAqIGltcG9ydC5kb25lIChldmVyeXRoaW5nIGRvbmUpXG4gKlxuICogWW91IGNhbiB1c2UgdGhlc2UgZXZlbnRzIHRvIGhvb2sgaW50byB0aGUgbGlmZS1jeWNsZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30geG1sIHRoZSBCUE1OIDIuMCB4bWxcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxCUE1ORGlhZ3JhbT58c3RyaW5nfSBbYnBtbkRpYWdyYW1dIEJQTU4gZGlhZ3JhbSBvciBpZCBvZiBkaWFncmFtIHRvIHJlbmRlciAoaWYgbm90IHByb3ZpZGVkLCB0aGUgZmlyc3Qgb25lIHdpbGwgYmUgcmVuZGVyZWQpXG4gKlxuICogUmV0dXJucyB7UHJvbWlzZTxJbXBvcnRYTUxSZXN1bHQsIEltcG9ydFhNTEVycm9yPn1cbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUuaW1wb3J0WE1MID0gd3JhcEZvckNvbXBhdGliaWxpdHkoZnVuY3Rpb24gaW1wb3J0WE1MKHhtbCwgYnBtbkRpYWdyYW0pIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZnVuY3Rpb24gUGFyc2VDb21wbGV0ZUV2ZW50KGRhdGEpIHtcblxuICAgIHZhciBldmVudCA9IHNlbGYuZ2V0KCdldmVudEJ1cycpLmNyZWF0ZUV2ZW50KGRhdGEpO1xuXG4gICAgLy8gVE9ETyhuaWtrdSk6IHJlbW92ZSB3aXRoIGZ1dHVyZSBicG1uLWpzIHZlcnNpb25cbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoZXZlbnQsICdjb250ZXh0Jywge1xuICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgIGdldDogZnVuY3Rpb24oKSB7XG5cbiAgICAgICAgY29uc29sZS53YXJuKG5ldyBFcnJvcihcbiAgICAgICAgICAnaW1wb3J0LnBhcnNlLmNvbXBsZXRlIDxjb250ZXh0PiBpcyBkZXByZWNhdGVkICcgK1xuICAgICAgICAgICdhbmQgd2lsbCBiZSByZW1vdmVkIGluIGZ1dHVyZSBsaWJyYXJ5IHZlcnNpb25zJ1xuICAgICAgICApKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHdhcm5pbmdzOiBkYXRhLndhcm5pbmdzLFxuICAgICAgICAgIHJlZmVyZW5jZXM6IGRhdGEucmVmZXJlbmNlcyxcbiAgICAgICAgICBlbGVtZW50c0J5SWQ6IGRhdGEuZWxlbWVudHNCeUlkXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZXZlbnQ7XG4gIH1cblxuICByZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocmVzb2x2ZSwgcmVqZWN0KSB7XG5cbiAgICAvLyBob29rIGluIHByZS1wYXJzZSBsaXN0ZW5lcnMgK1xuICAgIC8vIGFsbG93IHhtbCBtYW5pcHVsYXRpb25cbiAgICB4bWwgPSBzZWxmLl9lbWl0KCdpbXBvcnQucGFyc2Uuc3RhcnQnLCB7IHhtbDogeG1sIH0pIHx8IHhtbDtcblxuICAgIHNlbGYuX21vZGRsZS5mcm9tWE1MKHhtbCwgJ2JwbW46RGVmaW5pdGlvbnMnKS50aGVuKGZ1bmN0aW9uKHJlc3VsdCkge1xuICAgICAgdmFyIGRlZmluaXRpb25zID0gcmVzdWx0LnJvb3RFbGVtZW50O1xuICAgICAgdmFyIHJlZmVyZW5jZXMgPSByZXN1bHQucmVmZXJlbmNlcztcbiAgICAgIHZhciBwYXJzZVdhcm5pbmdzID0gcmVzdWx0Lndhcm5pbmdzO1xuICAgICAgdmFyIGVsZW1lbnRzQnlJZCA9IHJlc3VsdC5lbGVtZW50c0J5SWQ7XG5cbiAgICAgIC8vIGhvb2sgaW4gcG9zdCBwYXJzZSBsaXN0ZW5lcnMgK1xuICAgICAgLy8gYWxsb3cgZGVmaW5pdGlvbnMgbWFuaXB1bGF0aW9uXG4gICAgICBkZWZpbml0aW9ucyA9IHNlbGYuX2VtaXQoJ2ltcG9ydC5wYXJzZS5jb21wbGV0ZScsIFBhcnNlQ29tcGxldGVFdmVudCh7XG4gICAgICAgIGVycm9yOiBudWxsLFxuICAgICAgICBkZWZpbml0aW9uczogZGVmaW5pdGlvbnMsXG4gICAgICAgIGVsZW1lbnRzQnlJZDogZWxlbWVudHNCeUlkLFxuICAgICAgICByZWZlcmVuY2VzOiByZWZlcmVuY2VzLFxuICAgICAgICB3YXJuaW5nczogcGFyc2VXYXJuaW5nc1xuICAgICAgfSkpIHx8IGRlZmluaXRpb25zO1xuXG4gICAgICBzZWxmLmltcG9ydERlZmluaXRpb25zKGRlZmluaXRpb25zLCBicG1uRGlhZ3JhbSkudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcbiAgICAgICAgdmFyIGFsbFdhcm5pbmdzID0gW10uY29uY2F0KHBhcnNlV2FybmluZ3MsIHJlc3VsdC53YXJuaW5ncyB8fCBbXSk7XG5cbiAgICAgICAgc2VsZi5fZW1pdCgnaW1wb3J0LmRvbmUnLCB7IGVycm9yOiBudWxsLCB3YXJuaW5nczogYWxsV2FybmluZ3MgfSk7XG5cbiAgICAgICAgcmV0dXJuIHJlc29sdmUoeyB3YXJuaW5nczogYWxsV2FybmluZ3MgfSk7XG4gICAgICB9KS5jYXRjaChmdW5jdGlvbihlcnIpIHtcbiAgICAgICAgdmFyIGFsbFdhcm5pbmdzID0gW10uY29uY2F0KHBhcnNlV2FybmluZ3MsIGVyci53YXJuaW5ncyB8fCBbXSk7XG5cbiAgICAgICAgc2VsZi5fZW1pdCgnaW1wb3J0LmRvbmUnLCB7IGVycm9yOiBlcnIsIHdhcm5pbmdzOiBhbGxXYXJuaW5ncyB9KTtcblxuICAgICAgICByZXR1cm4gcmVqZWN0KGFkZFdhcm5pbmdzVG9FcnJvcihlcnIsIGFsbFdhcm5pbmdzKSk7XG4gICAgICB9KTtcbiAgICB9KS5jYXRjaChmdW5jdGlvbihlcnIpIHtcblxuICAgICAgc2VsZi5fZW1pdCgnaW1wb3J0LnBhcnNlLmNvbXBsZXRlJywge1xuICAgICAgICBlcnJvcjogZXJyXG4gICAgICB9KTtcblxuICAgICAgZXJyID0gY2hlY2tWYWxpZGF0aW9uRXJyb3IoZXJyKTtcblxuICAgICAgc2VsZi5fZW1pdCgnaW1wb3J0LmRvbmUnLCB7IGVycm9yOiBlcnIsIHdhcm5pbmdzOiBlcnIud2FybmluZ3MgfSk7XG5cbiAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLyoqXG4qIFRoZSBpbXBvcnREZWZpbml0aW9ucyByZXN1bHQuXG4qXG4qIEB0eXBlZGVmIHtPYmplY3R9IEltcG9ydERlZmluaXRpb25zUmVzdWx0XG4qXG4qIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gd2FybmluZ3NcbiovXG5cbi8qKlxuKiBUaGUgaW1wb3J0RGVmaW5pdGlvbnMgZXJyb3IuXG4qXG4qIEB0eXBlZGVmIHtFcnJvcn0gSW1wb3J0RGVmaW5pdGlvbnNFcnJvclxuKlxuKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IHdhcm5pbmdzXG4qL1xuXG4vKipcbiAqIEltcG9ydCBwYXJzZWQgZGVmaW5pdGlvbnMgYW5kIHJlbmRlciBhIEJQTU4gMi4wIGRpYWdyYW0uXG4gKlxuICogT25jZSBmaW5pc2hlZCB0aGUgdmlld2VyIHJlcG9ydHMgYmFjayB0aGUgcmVzdWx0IHRvIHRoZVxuICogcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCAoZXJyLCB3YXJuaW5ncykuXG4gKlxuICogIyMgTGlmZS1DeWNsZSBFdmVudHNcbiAqXG4gKiBEdXJpbmcgaW1wb3J0IHRoZSB2aWV3ZXIgd2lsbCBmaXJlIGxpZmUtY3ljbGUgZXZlbnRzOlxuICpcbiAqICAgKiBpbXBvcnQucmVuZGVyLnN0YXJ0IChncmFwaGljYWwgaW1wb3J0IHN0YXJ0KVxuICogICAqIGltcG9ydC5yZW5kZXIuY29tcGxldGUgKGdyYXBoaWNhbCBpbXBvcnQgZmluaXNoZWQpXG4gKlxuICogWW91IGNhbiB1c2UgdGhlc2UgZXZlbnRzIHRvIGhvb2sgaW50byB0aGUgbGlmZS1jeWNsZS5cbiAqXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnQ8RGVmaW5pdGlvbnM+fSBkZWZpbml0aW9ucyBwYXJzZWQgQlBNTiAyLjAgZGVmaW5pdGlvbnNcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxCUE1ORGlhZ3JhbT58c3RyaW5nfSBbYnBtbkRpYWdyYW1dIEJQTU4gZGlhZ3JhbSBvciBpZCBvZiBkaWFncmFtIHRvIHJlbmRlciAoaWYgbm90IHByb3ZpZGVkLCB0aGUgZmlyc3Qgb25lIHdpbGwgYmUgcmVuZGVyZWQpXG4gKlxuICogUmV0dXJucyB7UHJvbWlzZTxJbXBvcnREZWZpbml0aW9uc1Jlc3VsdCwgSW1wb3J0RGVmaW5pdGlvbnNFcnJvcj59XG4gKi9cbkJhc2VWaWV3ZXIucHJvdG90eXBlLmltcG9ydERlZmluaXRpb25zID0gd3JhcEZvckNvbXBhdGliaWxpdHkoZnVuY3Rpb24gaW1wb3J0RGVmaW5pdGlvbnMoZGVmaW5pdGlvbnMsIGJwbW5EaWFncmFtKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcblxuICAgIHNlbGYuX3NldERlZmluaXRpb25zKGRlZmluaXRpb25zKTtcblxuICAgIHNlbGYub3BlbihicG1uRGlhZ3JhbSkudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcblxuICAgICAgdmFyIHdhcm5pbmdzID0gcmVzdWx0Lndhcm5pbmdzO1xuXG4gICAgICByZXR1cm4gcmVzb2x2ZSh7IHdhcm5pbmdzOiB3YXJuaW5ncyB9KTtcbiAgICB9KS5jYXRjaChmdW5jdGlvbihlcnIpIHtcblxuICAgICAgcmV0dXJuIHJlamVjdChlcnIpO1xuICAgIH0pO1xuICB9KTtcbn0pO1xuXG4vKipcbiAqIFRoZSBvcGVuIHJlc3VsdC5cbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBPcGVuUmVzdWx0XG4gKlxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuICovXG5cbi8qKlxuKiBUaGUgb3BlbiBlcnJvci5cbipcbiogQHR5cGVkZWYge0Vycm9yfSBPcGVuRXJyb3JcbipcbiogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuKi9cblxuLyoqXG4gKiBPcGVuIGRpYWdyYW0gb2YgcHJldmlvdXNseSBpbXBvcnRlZCBYTUwuXG4gKlxuICogT25jZSBmaW5pc2hlZCB0aGUgdmlld2VyIHJlcG9ydHMgYmFjayB0aGUgcmVzdWx0IHRvIHRoZVxuICogcHJvdmlkZWQgY2FsbGJhY2sgZnVuY3Rpb24gd2l0aCAoZXJyLCB3YXJuaW5ncykuXG4gKlxuICogIyMgTGlmZS1DeWNsZSBFdmVudHNcbiAqXG4gKiBEdXJpbmcgc3dpdGNoIHRoZSB2aWV3ZXIgd2lsbCBmaXJlIGxpZmUtY3ljbGUgZXZlbnRzOlxuICpcbiAqICAgKiBpbXBvcnQucmVuZGVyLnN0YXJ0IChncmFwaGljYWwgaW1wb3J0IHN0YXJ0KVxuICogICAqIGltcG9ydC5yZW5kZXIuY29tcGxldGUgKGdyYXBoaWNhbCBpbXBvcnQgZmluaXNoZWQpXG4gKlxuICogWW91IGNhbiB1c2UgdGhlc2UgZXZlbnRzIHRvIGhvb2sgaW50byB0aGUgbGlmZS1jeWNsZS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xNb2RkbGVFbGVtZW50PEJQTU5EaWFncmFtPn0gW2JwbW5EaWFncmFtT3JJZF0gaWQgb3IgdGhlIGRpYWdyYW0gdG8gb3BlblxuICpcbiAqIFJldHVybnMge1Byb21pc2U8T3BlblJlc3VsdCwgT3BlbkVycm9yPn1cbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUub3BlbiA9IHdyYXBGb3JDb21wYXRpYmlsaXR5KGZ1bmN0aW9uIG9wZW4oYnBtbkRpYWdyYW1PcklkKSB7XG5cbiAgdmFyIGRlZmluaXRpb25zID0gdGhpcy5fZGVmaW5pdGlvbnM7XG4gIHZhciBicG1uRGlhZ3JhbSA9IGJwbW5EaWFncmFtT3JJZDtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIGlmICghZGVmaW5pdGlvbnMpIHtcbiAgICAgIHZhciBlcnIxID0gbmV3IEVycm9yKCdubyBYTUwgaW1wb3J0ZWQnKTtcblxuICAgICAgcmV0dXJuIHJlamVjdChhZGRXYXJuaW5nc1RvRXJyb3IoZXJyMSwgW10pKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIGJwbW5EaWFncmFtT3JJZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIGJwbW5EaWFncmFtID0gZmluZEJQTU5EaWFncmFtKGRlZmluaXRpb25zLCBicG1uRGlhZ3JhbU9ySWQpO1xuXG4gICAgICBpZiAoIWJwbW5EaWFncmFtKSB7XG4gICAgICAgIHZhciBlcnIyID0gbmV3IEVycm9yKCdCUE1ORGlhZ3JhbSA8JyArIGJwbW5EaWFncmFtT3JJZCArICc+IG5vdCBmb3VuZCcpO1xuXG4gICAgICAgIHJldHVybiByZWplY3QoYWRkV2FybmluZ3NUb0Vycm9yKGVycjIsIFtdKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gY2xlYXIgZXhpc3RpbmcgcmVuZGVyZWQgZGlhZ3JhbVxuICAgIC8vIGNhdGNoIHN5bmNocm9ub3VzIGV4Y2VwdGlvbnMgZHVyaW5nICNjbGVhcigpXG4gICAgdHJ5IHtcbiAgICAgIHNlbGYuY2xlYXIoKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuXG4gICAgICByZXR1cm4gcmVqZWN0KGFkZFdhcm5pbmdzVG9FcnJvcihlcnJvciwgW10pKTtcbiAgICB9XG5cbiAgICAvLyBwZXJmb3JtIGdyYXBoaWNhbCBpbXBvcnRcbiAgICBpbXBvcnRCcG1uRGlhZ3JhbShzZWxmLCBkZWZpbml0aW9ucywgYnBtbkRpYWdyYW0pLnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XG5cbiAgICAgIHZhciB3YXJuaW5ncyA9IHJlc3VsdC53YXJuaW5ncztcblxuICAgICAgcmV0dXJuIHJlc29sdmUoeyB3YXJuaW5nczogd2FybmluZ3MgfSk7XG4gICAgfSkuY2F0Y2goZnVuY3Rpb24oZXJyKSB7XG5cbiAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLyoqXG4gKiBUaGUgc2F2ZVhNTCByZXN1bHQuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gU2F2ZVhNTFJlc3VsdFxuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB4bWxcbiAqL1xuXG4vKipcbiAqIEV4cG9ydCB0aGUgY3VycmVudGx5IGRpc3BsYXllZCBCUE1OIDIuMCBkaWFncmFtIGFzXG4gKiBhIEJQTU4gMi4wIFhNTCBkb2N1bWVudC5cbiAqXG4gKiAjIyBMaWZlLUN5Y2xlIEV2ZW50c1xuICpcbiAqIER1cmluZyBYTUwgc2F2aW5nIHRoZSB2aWV3ZXIgd2lsbCBmaXJlIGxpZmUtY3ljbGUgZXZlbnRzOlxuICpcbiAqICAgKiBzYXZlWE1MLnN0YXJ0IChiZWZvcmUgc2VyaWFsaXphdGlvbilcbiAqICAgKiBzYXZlWE1MLnNlcmlhbGl6ZWQgKGFmdGVyIHhtbCBnZW5lcmF0aW9uKVxuICogICAqIHNhdmVYTUwuZG9uZSAoZXZlcnl0aGluZyBkb25lKVxuICpcbiAqIFlvdSBjYW4gdXNlIHRoZXNlIGV2ZW50cyB0byBob29rIGludG8gdGhlIGxpZmUtY3ljbGUuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBleHBvcnQgb3B0aW9uc1xuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5mb3JtYXQ9ZmFsc2VdIG91dHB1dCBmb3JtYXR0ZWQgWE1MXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnByZWFtYmxlPXRydWVdIG91dHB1dCBwcmVhbWJsZVxuICpcbiAqIFJldHVybnMge1Byb21pc2U8U2F2ZVhNTFJlc3VsdCwgRXJyb3I+fVxuICovXG5CYXNlVmlld2VyLnByb3RvdHlwZS5zYXZlWE1MID0gd3JhcEZvckNvbXBhdGliaWxpdHkoZnVuY3Rpb24gc2F2ZVhNTChvcHRpb25zKSB7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBkZWZpbml0aW9ucyA9IHRoaXMuX2RlZmluaXRpb25zO1xuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcblxuICAgIGlmICghZGVmaW5pdGlvbnMpIHtcbiAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ25vIGRlZmluaXRpb25zIGxvYWRlZCcpO1xuXG4gICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgfVxuXG4gICAgLy8gYWxsb3cgdG8gZmlkZGxlIGFyb3VuZCB3aXRoIGRlZmluaXRpb25zXG4gICAgZGVmaW5pdGlvbnMgPSBzZWxmLl9lbWl0KCdzYXZlWE1MLnN0YXJ0Jywge1xuICAgICAgZGVmaW5pdGlvbnM6IGRlZmluaXRpb25zXG4gICAgfSkgfHwgZGVmaW5pdGlvbnM7XG5cbiAgICBzZWxmLl9tb2RkbGUudG9YTUwoZGVmaW5pdGlvbnMsIG9wdGlvbnMpLnRoZW4oZnVuY3Rpb24ocmVzdWx0KSB7XG5cbiAgICAgIHZhciB4bWwgPSByZXN1bHQueG1sO1xuXG4gICAgICB0cnkge1xuICAgICAgICB4bWwgPSBzZWxmLl9lbWl0KCdzYXZlWE1MLnNlcmlhbGl6ZWQnLCB7XG4gICAgICAgICAgZXJyb3I6IG51bGwsXG4gICAgICAgICAgeG1sOiB4bWxcbiAgICAgICAgfSkgfHwgeG1sO1xuXG4gICAgICAgIHNlbGYuX2VtaXQoJ3NhdmVYTUwuZG9uZScsIHtcbiAgICAgICAgICBlcnJvcjogbnVsbCxcbiAgICAgICAgICB4bWw6IHhtbFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignZXJyb3IgaW4gc2F2ZVhNTCBsaWZlLWN5Y2xlIGxpc3RlbmVyJywgZSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXNvbHZlKHsgeG1sOiB4bWwgfSk7XG4gICAgfSkuY2F0Y2goZnVuY3Rpb24oZXJyKSB7XG5cbiAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICB9KTtcbiAgfSk7XG59KTtcblxuLyoqXG4gKiBUaGUgc2F2ZVNWRyByZXN1bHQuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gU2F2ZVNWR1Jlc3VsdFxuICpcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzdmdcbiAqL1xuXG4vKipcbiAqIEV4cG9ydCB0aGUgY3VycmVudGx5IGRpc3BsYXllZCBCUE1OIDIuMCBkaWFncmFtIGFzXG4gKiBhbiBTVkcgaW1hZ2UuXG4gKlxuICogIyMgTGlmZS1DeWNsZSBFdmVudHNcbiAqXG4gKiBEdXJpbmcgU1ZHIHNhdmluZyB0aGUgdmlld2VyIHdpbGwgZmlyZSBsaWZlLWN5Y2xlIGV2ZW50czpcbiAqXG4gKiAgICogc2F2ZVNWRy5zdGFydCAoYmVmb3JlIHNlcmlhbGl6YXRpb24pXG4gKiAgICogc2F2ZVNWRy5kb25lIChldmVyeXRoaW5nIGRvbmUpXG4gKlxuICogWW91IGNhbiB1c2UgdGhlc2UgZXZlbnRzIHRvIGhvb2sgaW50byB0aGUgbGlmZS1jeWNsZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gKlxuICogUmV0dXJucyB7UHJvbWlzZTxTYXZlU1ZHUmVzdWx0LCBFcnJvcj59XG4gKi9cbkJhc2VWaWV3ZXIucHJvdG90eXBlLnNhdmVTVkcgPSB3cmFwRm9yQ29tcGF0aWJpbGl0eShmdW5jdGlvbiBzYXZlU1ZHKG9wdGlvbnMpIHtcblxuICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuXG4gICAgc2VsZi5fZW1pdCgnc2F2ZVNWRy5zdGFydCcpO1xuXG4gICAgdmFyIHN2ZywgZXJyO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhciBjYW52YXMgPSBzZWxmLmdldCgnY2FudmFzJyk7XG5cbiAgICAgIHZhciBjb250ZW50Tm9kZSA9IGNhbnZhcy5nZXREZWZhdWx0TGF5ZXIoKSxcbiAgICAgICAgICBkZWZzTm9kZSA9IGRvbVF1ZXJ5KCdkZWZzJywgY2FudmFzLl9zdmcpO1xuXG4gICAgICB2YXIgY29udGVudHMgPSBpbm5lclNWRyhjb250ZW50Tm9kZSksXG4gICAgICAgICAgZGVmcyA9IGRlZnNOb2RlID8gJzxkZWZzPicgKyBpbm5lclNWRyhkZWZzTm9kZSkgKyAnPC9kZWZzPicgOiAnJztcblxuICAgICAgdmFyIGJib3ggPSBjb250ZW50Tm9kZS5nZXRCQm94KCk7XG5cbiAgICAgIHN2ZyA9XG4gICAgICAgICc8P3htbCB2ZXJzaW9uPVwiMS4wXCIgZW5jb2Rpbmc9XCJ1dGYtOFwiPz5cXG4nICtcbiAgICAgICAgJzwhLS0gY3JlYXRlZCB3aXRoIGJwbW4tanMgLyBodHRwOi8vYnBtbi5pbyAtLT5cXG4nICtcbiAgICAgICAgJzwhRE9DVFlQRSBzdmcgUFVCTElDIFwiLS8vVzNDLy9EVEQgU1ZHIDEuMS8vRU5cIiBcImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZFwiPlxcbicgK1xuICAgICAgICAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgJyArXG4gICAgICAgICAgICAgJ3dpZHRoPVwiJyArIGJib3gud2lkdGggKyAnXCIgaGVpZ2h0PVwiJyArIGJib3guaGVpZ2h0ICsgJ1wiICcgK1xuICAgICAgICAgICAgICd2aWV3Qm94PVwiJyArIGJib3gueCArICcgJyArIGJib3gueSArICcgJyArIGJib3gud2lkdGggKyAnICcgKyBiYm94LmhlaWdodCArICdcIiB2ZXJzaW9uPVwiMS4xXCI+JyArXG4gICAgICAgICAgZGVmcyArIGNvbnRlbnRzICtcbiAgICAgICAgJzwvc3ZnPic7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZXJyID0gZTtcbiAgICB9XG5cbiAgICBzZWxmLl9lbWl0KCdzYXZlU1ZHLmRvbmUnLCB7XG4gICAgICBlcnJvcjogZXJyLFxuICAgICAgc3ZnOiBzdmdcbiAgICB9KTtcblxuICAgIGlmICghZXJyKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZSh7IHN2Zzogc3ZnIH0pO1xuICAgIH1cblxuICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgfSk7XG59KTtcblxuLyoqXG4gKiBHZXQgYSBuYW1lZCBkaWFncmFtIHNlcnZpY2UuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgZWxlbWVudFJlZ2lzdHJ5ID0gdmlld2VyLmdldCgnZWxlbWVudFJlZ2lzdHJ5Jyk7XG4gKiB2YXIgc3RhcnRFdmVudFNoYXBlID0gZWxlbWVudFJlZ2lzdHJ5LmdldCgnU3RhcnRFdmVudF8xJyk7XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGRpYWdyYW0gc2VydmljZSBpbnN0YW5jZVxuICpcbiAqIEBtZXRob2QgQmFzZVZpZXdlciNnZXRcbiAqL1xuXG4vKipcbiAqIEludm9rZSBhIGZ1bmN0aW9uIGluIHRoZSBjb250ZXh0IG9mIHRoaXMgdmlld2VyLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogdmlld2VyLmludm9rZShmdW5jdGlvbihlbGVtZW50UmVnaXN0cnkpIHtcbiAqICAgdmFyIHN0YXJ0RXZlbnRTaGFwZSA9IGVsZW1lbnRSZWdpc3RyeS5nZXQoJ1N0YXJ0RXZlbnRfMScpO1xuICogfSk7XG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gdG8gYmUgaW52b2tlZFxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIGZ1bmN0aW9ucyByZXR1cm4gdmFsdWVcbiAqXG4gKiBAbWV0aG9kIEJhc2VWaWV3ZXIjaW52b2tlXG4gKi9cblxuXG5CYXNlVmlld2VyLnByb3RvdHlwZS5fc2V0RGVmaW5pdGlvbnMgPSBmdW5jdGlvbihkZWZpbml0aW9ucykge1xuICB0aGlzLl9kZWZpbml0aW9ucyA9IGRlZmluaXRpb25zO1xufTtcblxuQmFzZVZpZXdlci5wcm90b3R5cGUuZ2V0TW9kdWxlcyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fbW9kdWxlcztcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFsbCBkcmF3biBlbGVtZW50cyBmcm9tIHRoZSB2aWV3ZXIuXG4gKlxuICogQWZ0ZXIgY2FsbGluZyB0aGlzIG1ldGhvZCB0aGUgdmlld2VyIGNhbiBzdGlsbFxuICogYmUgcmV1c2VkIGZvciBvcGVuaW5nIGFub3RoZXIgZGlhZ3JhbS5cbiAqXG4gKiBAbWV0aG9kIEJhc2VWaWV3ZXIjY2xlYXJcbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLmdldERlZmluaXRpb25zKCkpIHtcblxuICAgIC8vIG5vIGRpYWdyYW0gdG8gY2xlYXJcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyByZW1vdmUgYnVzaW5lc3NPYmplY3QjZGkgYmluZGluZ1xuICAvL1xuICAvLyB0aGlzIGlzIG5lY2Vzc2FyeSwgYXMgd2UgZXN0YWJsaXNoIHRoZSBiaW5kaW5nc1xuICAvLyBpbiB0aGUgQnBtblRyZWVXYWxrZXIgKGFuZCBhc3N1bWUgbm9uZSBhcmUgZ2l2ZW5cbiAgLy8gb24gcmVpbXBvcnQpXG4gIHRoaXMuZ2V0KCdlbGVtZW50UmVnaXN0cnknKS5mb3JFYWNoKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICB2YXIgYm8gPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgaWYgKGJvICYmIGJvLmRpKSB7XG4gICAgICBkZWxldGUgYm8uZGk7XG4gICAgfVxuICB9KTtcblxuICAvLyByZW1vdmUgZHJhd24gZWxlbWVudHNcbiAgRGlhZ3JhbS5wcm90b3R5cGUuY2xlYXIuY2FsbCh0aGlzKTtcbn07XG5cbi8qKlxuICogRGVzdHJveSB0aGUgdmlld2VyIGluc3RhbmNlIGFuZCByZW1vdmUgYWxsIGl0c1xuICogcmVtYWluZGVycyBmcm9tIHRoZSBkb2N1bWVudCB0cmVlLlxuICovXG5CYXNlVmlld2VyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG5cbiAgLy8gZGlhZ3JhbSBkZXN0cm95XG4gIERpYWdyYW0ucHJvdG90eXBlLmRlc3Ryb3kuY2FsbCh0aGlzKTtcblxuICAvLyBkb20gZGV0YWNoXG4gIGRvbVJlbW92ZSh0aGlzLl9jb250YWluZXIpO1xufTtcblxuLyoqXG4gKiBSZWdpc3RlciBhbiBldmVudCBsaXN0ZW5lclxuICpcbiAqIFJlbW92ZSBhIHByZXZpb3VzbHkgYWRkZWQgbGlzdGVuZXIgdmlhIHtAbGluayAjb2ZmKGV2ZW50LCBjYWxsYmFjayl9LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtudW1iZXJ9IFtwcmlvcml0eV1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcGFyYW0ge09iamVjdH0gW3RoYXRdXG4gKi9cbkJhc2VWaWV3ZXIucHJvdG90eXBlLm9uID0gZnVuY3Rpb24oZXZlbnQsIHByaW9yaXR5LCBjYWxsYmFjaywgdGFyZ2V0KSB7XG4gIHJldHVybiB0aGlzLmdldCgnZXZlbnRCdXMnKS5vbihldmVudCwgcHJpb3JpdHksIGNhbGxiYWNrLCB0YXJnZXQpO1xufTtcblxuLyoqXG4gKiBEZS1yZWdpc3RlciBhbiBldmVudCBsaXN0ZW5lclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24oZXZlbnQsIGNhbGxiYWNrKSB7XG4gIHRoaXMuZ2V0KCdldmVudEJ1cycpLm9mZihldmVudCwgY2FsbGJhY2spO1xufTtcblxuQmFzZVZpZXdlci5wcm90b3R5cGUuYXR0YWNoVG8gPSBmdW5jdGlvbihwYXJlbnROb2RlKSB7XG5cbiAgaWYgKCFwYXJlbnROb2RlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwYXJlbnROb2RlIHJlcXVpcmVkJyk7XG4gIH1cblxuICAvLyBlbnN1cmUgd2UgZGV0YWNoIGZyb20gdGhlXG4gIC8vIHByZXZpb3VzLCBvbGQgcGFyZW50XG4gIHRoaXMuZGV0YWNoKCk7XG5cbiAgLy8gdW53cmFwIGpRdWVyeSBpZiBwcm92aWRlZFxuICBpZiAocGFyZW50Tm9kZS5nZXQgJiYgcGFyZW50Tm9kZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGUuanF1ZXJ5KSB7XG4gICAgcGFyZW50Tm9kZSA9IHBhcmVudE5vZGUuZ2V0KDApO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJlbnROb2RlID09PSAnc3RyaW5nJykge1xuICAgIHBhcmVudE5vZGUgPSBkb21RdWVyeShwYXJlbnROb2RlKTtcbiAgfVxuXG4gIHBhcmVudE5vZGUuYXBwZW5kQ2hpbGQodGhpcy5fY29udGFpbmVyKTtcblxuICB0aGlzLl9lbWl0KCdhdHRhY2gnLCB7fSk7XG5cbiAgdGhpcy5nZXQoJ2NhbnZhcycpLnJlc2l6ZWQoKTtcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLmdldERlZmluaXRpb25zID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9kZWZpbml0aW9ucztcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLmRldGFjaCA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBjb250YWluZXIgPSB0aGlzLl9jb250YWluZXIsXG4gICAgICBwYXJlbnROb2RlID0gY29udGFpbmVyLnBhcmVudE5vZGU7XG5cbiAgaWYgKCFwYXJlbnROb2RlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fZW1pdCgnZGV0YWNoJywge30pO1xuXG4gIHBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoY29udGFpbmVyKTtcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24oY29udGFpbmVyLCBtb2RkbGUsIG9wdGlvbnMpIHtcblxuICB2YXIgYmFzZU1vZHVsZXMgPSBvcHRpb25zLm1vZHVsZXMgfHwgdGhpcy5nZXRNb2R1bGVzKCksXG4gICAgICBhZGRpdGlvbmFsTW9kdWxlcyA9IG9wdGlvbnMuYWRkaXRpb25hbE1vZHVsZXMgfHwgW10sXG4gICAgICBzdGF0aWNNb2R1bGVzID0gW1xuICAgICAgICB7XG4gICAgICAgICAgYnBtbmpzOiBbICd2YWx1ZScsIHRoaXMgXSxcbiAgICAgICAgICBtb2RkbGU6IFsgJ3ZhbHVlJywgbW9kZGxlIF1cbiAgICAgICAgfVxuICAgICAgXTtcblxuICB2YXIgZGlhZ3JhbU1vZHVsZXMgPSBbXS5jb25jYXQoc3RhdGljTW9kdWxlcywgYmFzZU1vZHVsZXMsIGFkZGl0aW9uYWxNb2R1bGVzKTtcblxuICB2YXIgZGlhZ3JhbU9wdGlvbnMgPSBhc3NpZ24ob21pdChvcHRpb25zLCBbICdhZGRpdGlvbmFsTW9kdWxlcycgXSksIHtcbiAgICBjYW52YXM6IGFzc2lnbih7fSwgb3B0aW9ucy5jYW52YXMsIHsgY29udGFpbmVyOiBjb250YWluZXIgfSksXG4gICAgbW9kdWxlczogZGlhZ3JhbU1vZHVsZXNcbiAgfSk7XG5cbiAgLy8gaW52b2tlIGRpYWdyYW0gY29uc3RydWN0b3JcbiAgRGlhZ3JhbS5jYWxsKHRoaXMsIGRpYWdyYW1PcHRpb25zKTtcblxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLmNvbnRhaW5lcikge1xuICAgIHRoaXMuYXR0YWNoVG8ob3B0aW9ucy5jb250YWluZXIpO1xuICB9XG59O1xuXG4vKipcbiAqIEVtaXQgYW4gZXZlbnQgb24gdGhlIHVuZGVybHlpbmcge0BsaW5rIEV2ZW50QnVzfVxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gdHlwZVxuICogQHBhcmFtICB7T2JqZWN0fSBldmVudFxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gZXZlbnQgcHJvY2Vzc2luZyByZXN1bHQgKGlmIGFueSlcbiAqL1xuQmFzZVZpZXdlci5wcm90b3R5cGUuX2VtaXQgPSBmdW5jdGlvbih0eXBlLCBldmVudCkge1xuICByZXR1cm4gdGhpcy5nZXQoJ2V2ZW50QnVzJykuZmlyZSh0eXBlLCBldmVudCk7XG59O1xuXG5CYXNlVmlld2VyLnByb3RvdHlwZS5fY3JlYXRlQ29udGFpbmVyID0gZnVuY3Rpb24ob3B0aW9ucykge1xuXG4gIHZhciBjb250YWluZXIgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJianMtY29udGFpbmVyXCI+PC9kaXY+Jyk7XG5cbiAgYXNzaWduKGNvbnRhaW5lci5zdHlsZSwge1xuICAgIHdpZHRoOiBlbnN1cmVVbml0KG9wdGlvbnMud2lkdGgpLFxuICAgIGhlaWdodDogZW5zdXJlVW5pdChvcHRpb25zLmhlaWdodCksXG4gICAgcG9zaXRpb246IG9wdGlvbnMucG9zaXRpb25cbiAgfSk7XG5cbiAgcmV0dXJuIGNvbnRhaW5lcjtcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLl9jcmVhdGVNb2RkbGUgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gIHZhciBtb2RkbGVPcHRpb25zID0gYXNzaWduKHt9LCB0aGlzLl9tb2RkbGVFeHRlbnNpb25zLCBvcHRpb25zLm1vZGRsZUV4dGVuc2lvbnMpO1xuXG4gIHJldHVybiBuZXcgQnBtbk1vZGRsZShtb2RkbGVPcHRpb25zKTtcbn07XG5cbkJhc2VWaWV3ZXIucHJvdG90eXBlLl9tb2R1bGVzID0gW107XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGFkZFdhcm5pbmdzVG9FcnJvcihlcnIsIHdhcm5pbmdzQXJ5KSB7XG4gIGVyci53YXJuaW5ncyA9IHdhcm5pbmdzQXJ5O1xuICByZXR1cm4gZXJyO1xufVxuXG5mdW5jdGlvbiBjaGVja1ZhbGlkYXRpb25FcnJvcihlcnIpIHtcblxuICAvLyBjaGVjayBpZiB3ZSBjYW4gaGVscCB0aGUgdXNlciBieSBpbmRpY2F0aW5nIHdyb25nIEJQTU4gMi4wIHhtbFxuICAvLyAoaW4gY2FzZSBoZSBvciB0aGUgZXhwb3J0aW5nIHRvb2wgZGlkIG5vdCBnZXQgdGhhdCByaWdodClcblxuICB2YXIgcGF0dGVybiA9IC91bnBhcnNhYmxlIGNvbnRlbnQgPChbXj5dKyk+IGRldGVjdGVkKFtcXHNcXFNdKikkLztcbiAgdmFyIG1hdGNoID0gcGF0dGVybi5leGVjKGVyci5tZXNzYWdlKTtcblxuICBpZiAobWF0Y2gpIHtcbiAgICBlcnIubWVzc2FnZSA9XG4gICAgICAndW5wYXJzYWJsZSBjb250ZW50IDwnICsgbWF0Y2hbMV0gKyAnPiBkZXRlY3RlZDsgJyArXG4gICAgICAndGhpcyBtYXkgaW5kaWNhdGUgYW4gaW52YWxpZCBCUE1OIDIuMCBkaWFncmFtIGZpbGUnICsgbWF0Y2hbMl07XG4gIH1cblxuICByZXR1cm4gZXJyO1xufVxuXG52YXIgREVGQVVMVF9PUFRJT05TID0ge1xuICB3aWR0aDogJzEwMCUnLFxuICBoZWlnaHQ6ICcxMDAlJyxcbiAgcG9zaXRpb246ICdyZWxhdGl2ZSdcbn07XG5cblxuLyoqXG4gKiBFbnN1cmUgdGhlIHBhc3NlZCBhcmd1bWVudCBpcyBhIHByb3BlciB1bml0IChkZWZhdWx0aW5nIHRvIHB4KVxuICovXG5mdW5jdGlvbiBlbnN1cmVVbml0KHZhbCkge1xuICByZXR1cm4gdmFsICsgKGlzTnVtYmVyKHZhbCkgPyAncHgnIDogJycpO1xufVxuXG5cbi8qKlxuICogRmluZCBCUE1ORGlhZ3JhbSBpbiBkZWZpbml0aW9ucyBieSBJRFxuICpcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxEZWZpbml0aW9ucz59IGRlZmluaXRpb25zXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlhZ3JhbUlkXG4gKlxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudDxCUE1ORGlhZ3JhbT58bnVsbH1cbiAqL1xuZnVuY3Rpb24gZmluZEJQTU5EaWFncmFtKGRlZmluaXRpb25zLCBkaWFncmFtSWQpIHtcbiAgaWYgKCFkaWFncmFtSWQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBmaW5kKGRlZmluaXRpb25zLmRpYWdyYW1zLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQuaWQgPT09IGRpYWdyYW1JZDtcbiAgfSkgfHwgbnVsbDtcbn1cblxuXG4vKiA8cHJvamVjdC1sb2dvPiAqL1xuXG5pbXBvcnQge1xuICBvcGVuIGFzIG9wZW5Qb3dlcmVkQnksXG4gIEJQTU5JT19JTUcsXG4gIExJTktfU1RZTEVTIGFzIEJQTU5JT19MSU5LX1NUWUxFU1xufSBmcm9tICcuL3V0aWwvUG93ZXJlZEJ5VXRpbCc7XG5cbmltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50XG59IGZyb20gJ21pbi1kb20nO1xuXG4vKipcbiAqIEFkZHMgdGhlIHByb2plY3QgbG9nbyB0byB0aGUgZGlhZ3JhbSBjb250YWluZXIgYXNcbiAqIHJlcXVpcmVkIGJ5IHRoZSBicG1uLmlvIGxpY2Vuc2UuXG4gKlxuICogQHNlZSBodHRwOi8vYnBtbi5pby9saWNlbnNlXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBjb250YWluZXJcbiAqL1xuZnVuY3Rpb24gYWRkUHJvamVjdExvZ28oY29udGFpbmVyKSB7XG4gIHZhciBpbWcgPSBCUE1OSU9fSU1HO1xuXG4gIHZhciBsaW5rTWFya3VwID1cbiAgICAnPGEgaHJlZj1cImh0dHA6Ly9icG1uLmlvXCIgJyArXG4gICAgICAgJ3RhcmdldD1cIl9ibGFua1wiICcgK1xuICAgICAgICdjbGFzcz1cImJqcy1wb3dlcmVkLWJ5XCIgJyArXG4gICAgICAgJ3RpdGxlPVwiUG93ZXJlZCBieSBicG1uLmlvXCIgJyArXG4gICAgICAgJ3N0eWxlPVwicG9zaXRpb246IGFic29sdXRlOyBib3R0b206IDE1cHg7IHJpZ2h0OiAxNXB4OyB6LWluZGV4OiAxMDA7ICcgKyBCUE1OSU9fTElOS19TVFlMRVMgKyAnXCI+JyArXG4gICAgICBpbWcgK1xuICAgICc8L2E+JztcblxuICB2YXIgbGlua0VsZW1lbnQgPSBkb21pZnkobGlua01hcmt1cCk7XG5cbiAgY29udGFpbmVyLmFwcGVuZENoaWxkKGxpbmtFbGVtZW50KTtcblxuICBkb21FdmVudC5iaW5kKGxpbmtFbGVtZW50LCAnY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgIG9wZW5Qb3dlcmVkQnkoKTtcblxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH0pO1xufVxuXG4vKiA8L3Byb2plY3QtbG9nbz4gKi9cbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBCYXNlTW9kZWxlciBmcm9tICcuL0Jhc2VNb2RlbGVyJztcblxuaW1wb3J0IFZpZXdlciBmcm9tICcuL1ZpZXdlcic7XG5pbXBvcnQgTmF2aWdhdGVkVmlld2VyIGZyb20gJy4vTmF2aWdhdGVkVmlld2VyJztcblxuaW1wb3J0IEtleWJvYXJkTW92ZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL2tleWJvYXJkLW1vdmUnO1xuaW1wb3J0IE1vdmVDYW52YXNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvbmF2aWdhdGlvbi9tb3ZlY2FudmFzJztcbmltcG9ydCBUb3VjaE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL3RvdWNoJztcbmltcG9ydCBab29tU2Nyb2xsTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL25hdmlnYXRpb24vem9vbXNjcm9sbCc7XG5cbmltcG9ydCBBbGlnbkVsZW1lbnRzTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2FsaWduLWVsZW1lbnRzJztcbmltcG9ydCBBdXRvUGxhY2VNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9hdXRvLXBsYWNlJztcbmltcG9ydCBBdXRvUmVzaXplTW9kdWxlIGZyb20gJy4vZmVhdHVyZXMvYXV0by1yZXNpemUnO1xuaW1wb3J0IEF1dG9TY3JvbGxNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1zY3JvbGwnO1xuaW1wb3J0IEJlbmRwb2ludHNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYmVuZHBvaW50cyc7XG5pbXBvcnQgQ29ubmVjdE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jb25uZWN0JztcbmltcG9ydCBDb25uZWN0aW9uUHJldmlld01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jb25uZWN0aW9uLXByZXZpZXcnO1xuaW1wb3J0IENvbnRleHRQYWRNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9jb250ZXh0LXBhZCc7XG5pbXBvcnQgQ29weVBhc3RlTW9kdWxlIGZyb20gJy4vZmVhdHVyZXMvY29weS1wYXN0ZSc7XG5pbXBvcnQgQ3JlYXRlTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NyZWF0ZSc7XG5pbXBvcnQgRGlzdHJpYnV0ZUVsZW1lbnRzTW9kdWxlIGZyb20gJy4vZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cyc7XG5pbXBvcnQgRWRpdG9yQWN0aW9uc01vZHVsZSBmcm9tICcuL2ZlYXR1cmVzL2VkaXRvci1hY3Rpb25zJztcbmltcG9ydCBHcmlkU25hcHBpbmdNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nJztcbmltcG9ydCBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSBmcm9tICcuL2ZlYXR1cmVzL2ludGVyYWN0aW9uLWV2ZW50cyc7XG5pbXBvcnQgS2V5Ym9hcmRNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9rZXlib2FyZCc7XG5pbXBvcnQgS2V5Ym9hcmRNb3ZlU2VsZWN0aW9uTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2tleWJvYXJkLW1vdmUtc2VsZWN0aW9uJztcbmltcG9ydCBMYWJlbEVkaXRpbmdNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9sYWJlbC1lZGl0aW5nJztcbmltcG9ydCBNb2RlbGluZ01vZHVsZSBmcm9tICcuL2ZlYXR1cmVzL21vZGVsaW5nJztcbmltcG9ydCBNb3ZlTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL21vdmUnO1xuaW1wb3J0IFBhbGV0dGVNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9wYWxldHRlJztcbmltcG9ydCBSZXBsYWNlUHJldmlld01vZHVsZSBmcm9tICcuL2ZlYXR1cmVzL3JlcGxhY2UtcHJldmlldyc7XG5pbXBvcnQgUmVzaXplTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Jlc2l6ZSc7XG5pbXBvcnQgU25hcHBpbmdNb2R1bGUgZnJvbSAnLi9mZWF0dXJlcy9zbmFwcGluZyc7XG5pbXBvcnQgU2VhcmNoTW9kdWxlIGZyb20gJy4vZmVhdHVyZXMvc2VhcmNoJztcblxuaW1wb3J0IHtcbiAgd3JhcEZvckNvbXBhdGliaWxpdHlcbn0gZnJvbSAnLi91dGlsL0NvbXBhdGliaWxpdHlVdGlsJztcblxudmFyIGluaXRpYWxEaWFncmFtID1cbiAgJzw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCI/PicgK1xuICAnPGJwbW46ZGVmaW5pdGlvbnMgeG1sbnM6eHNpPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2VcIiAnICtcbiAgICAgICAgICAgICAgICAgICAgJ3htbG5zOmJwbW49XCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9CUE1OLzIwMTAwNTI0L01PREVMXCIgJyArXG4gICAgICAgICAgICAgICAgICAgICd4bWxuczpicG1uZGk9XCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9CUE1OLzIwMTAwNTI0L0RJXCIgJyArXG4gICAgICAgICAgICAgICAgICAgICd4bWxuczpkYz1cImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0RELzIwMTAwNTI0L0RDXCIgJyArXG4gICAgICAgICAgICAgICAgICAgICd0YXJnZXROYW1lc3BhY2U9XCJodHRwOi8vYnBtbi5pby9zY2hlbWEvYnBtblwiICcgK1xuICAgICAgICAgICAgICAgICAgICAnaWQ9XCJEZWZpbml0aW9uc18xXCI+JyArXG4gICAgJzxicG1uOnByb2Nlc3MgaWQ9XCJQcm9jZXNzXzFcIiBpc0V4ZWN1dGFibGU9XCJmYWxzZVwiPicgK1xuICAgICAgJzxicG1uOnN0YXJ0RXZlbnQgaWQ9XCJTdGFydEV2ZW50XzFcIi8+JyArXG4gICAgJzwvYnBtbjpwcm9jZXNzPicgK1xuICAgICc8YnBtbmRpOkJQTU5EaWFncmFtIGlkPVwiQlBNTkRpYWdyYW1fMVwiPicgK1xuICAgICAgJzxicG1uZGk6QlBNTlBsYW5lIGlkPVwiQlBNTlBsYW5lXzFcIiBicG1uRWxlbWVudD1cIlByb2Nlc3NfMVwiPicgK1xuICAgICAgICAnPGJwbW5kaTpCUE1OU2hhcGUgaWQ9XCJfQlBNTlNoYXBlX1N0YXJ0RXZlbnRfMlwiIGJwbW5FbGVtZW50PVwiU3RhcnRFdmVudF8xXCI+JyArXG4gICAgICAgICAgJzxkYzpCb3VuZHMgaGVpZ2h0PVwiMzYuMFwiIHdpZHRoPVwiMzYuMFwiIHg9XCIxNzMuMFwiIHk9XCIxMDIuMFwiLz4nICtcbiAgICAgICAgJzwvYnBtbmRpOkJQTU5TaGFwZT4nICtcbiAgICAgICc8L2JwbW5kaTpCUE1OUGxhbmU+JyArXG4gICAgJzwvYnBtbmRpOkJQTU5EaWFncmFtPicgK1xuICAnPC9icG1uOmRlZmluaXRpb25zPic7XG5cblxuLyoqXG4gKiBBIG1vZGVsZXIgZm9yIEJQTU4gMi4wIGRpYWdyYW1zLlxuICpcbiAqXG4gKiAjIyBFeHRlbmRpbmcgdGhlIE1vZGVsZXJcbiAqXG4gKiBJbiBvcmRlciB0byBleHRlbmQgdGhlIHZpZXdlciBwYXNzIGV4dGVuc2lvbiBtb2R1bGVzIHRvIGJvb3RzdHJhcCB2aWEgdGhlXG4gKiBgYWRkaXRpb25hbE1vZHVsZXNgIG9wdGlvbi4gQW4gZXh0ZW5zaW9uIG1vZHVsZSBpcyBhbiBvYmplY3QgdGhhdCBleHBvc2VzXG4gKiBuYW1lZCBzZXJ2aWNlcy5cbiAqXG4gKiBUaGUgZm9sbG93aW5nIGV4YW1wbGUgZGVwaWN0cyB0aGUgaW50ZWdyYXRpb24gb2YgYSBzaW1wbGVcbiAqIGxvZ2dpbmcgY29tcG9uZW50IHRoYXQgaW50ZWdyYXRlcyB3aXRoIGludGVyYWN0aW9uIGV2ZW50czpcbiAqXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICpcbiAqIC8vIGxvZ2dpbmcgY29tcG9uZW50XG4gKiBmdW5jdGlvbiBJbnRlcmFjdGlvbkxvZ2dlcihldmVudEJ1cykge1xuICogICBldmVudEJ1cy5vbignZWxlbWVudC5ob3ZlcicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gKiAgICAgY29uc29sZS5sb2coKVxuICogICB9KVxuICogfVxuICpcbiAqIEludGVyYWN0aW9uTG9nZ2VyLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTsgLy8gbWluaWZpY2F0aW9uIHNhdmVcbiAqXG4gKiAvLyBleHRlbnNpb24gbW9kdWxlXG4gKiB2YXIgZXh0ZW5zaW9uTW9kdWxlID0ge1xuICogICBfX2luaXRfXzogWyAnaW50ZXJhY3Rpb25Mb2dnZXInIF0sXG4gKiAgIGludGVyYWN0aW9uTG9nZ2VyOiBbICd0eXBlJywgSW50ZXJhY3Rpb25Mb2dnZXIgXVxuICogfTtcbiAqXG4gKiAvLyBleHRlbmQgdGhlIHZpZXdlclxuICogdmFyIGJwbW5Nb2RlbGVyID0gbmV3IE1vZGVsZXIoeyBhZGRpdGlvbmFsTW9kdWxlczogWyBleHRlbnNpb25Nb2R1bGUgXSB9KTtcbiAqIGJwbW5Nb2RlbGVyLmltcG9ydFhNTCguLi4pO1xuICogYGBgXG4gKlxuICpcbiAqICMjIEN1c3RvbWl6aW5nIC8gUmVwbGFjaW5nIENvbXBvbmVudHNcbiAqXG4gKiBZb3UgY2FuIHJlcGxhY2UgaW5kaXZpZHVhbCBkaWFncmFtIGNvbXBvbmVudHMgYnkgcmVkZWZpbmluZyB0aGVtIGluIG92ZXJyaWRlIG1vZHVsZXMuXG4gKiBUaGlzIHdvcmtzIGZvciBhbGwgY29tcG9uZW50cywgaW5jbHVkaW5nIHRob3NlIGRlZmluZWQgaW4gdGhlIGNvcmUuXG4gKlxuICogUGFzcyBpbiBvdmVycmlkZSBtb2R1bGVzIHZpYSB0aGUgYG9wdGlvbnMuYWRkaXRpb25hbE1vZHVsZXNgIGZsYWcgbGlrZSB0aGlzOlxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGZ1bmN0aW9uIEN1c3RvbUNvbnRleHRQYWRQcm92aWRlcihjb250ZXh0UGFkKSB7XG4gKlxuICogICBjb250ZXh0UGFkLnJlZ2lzdGVyUHJvdmlkZXIodGhpcyk7XG4gKlxuICogICB0aGlzLmdldENvbnRleHRQYWRFbnRyaWVzID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICogICAgIC8vIG5vIGVudHJpZXMsIGVmZmVjdGl2ZWx5IGRpc2FibGUgdGhlIGNvbnRleHQgcGFkXG4gKiAgICAgcmV0dXJuIHt9O1xuICogICB9O1xuICogfVxuICpcbiAqIEN1c3RvbUNvbnRleHRQYWRQcm92aWRlci4kaW5qZWN0ID0gWyAnY29udGV4dFBhZCcgXTtcbiAqXG4gKiB2YXIgb3ZlcnJpZGVNb2R1bGUgPSB7XG4gKiAgIGNvbnRleHRQYWRQcm92aWRlcjogWyAndHlwZScsIEN1c3RvbUNvbnRleHRQYWRQcm92aWRlciBdXG4gKiB9O1xuICpcbiAqIHZhciBicG1uTW9kZWxlciA9IG5ldyBNb2RlbGVyKHsgYWRkaXRpb25hbE1vZHVsZXM6IFsgb3ZlcnJpZGVNb2R1bGUgXX0pO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBjb25maWd1cmF0aW9uIG9wdGlvbnMgdG8gcGFzcyB0byB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IFtvcHRpb25zLmNvbnRhaW5lcl0gdGhlIGNvbnRhaW5lciB0byByZW5kZXIgdGhlIHZpZXdlciBpbiwgZGVmYXVsdHMgdG8gYm9keS5cbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gW29wdGlvbnMud2lkdGhdIHRoZSB3aWR0aCBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IFtvcHRpb25zLmhlaWdodF0gdGhlIGhlaWdodCBvZiB0aGUgdmlld2VyXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMubW9kZGxlRXh0ZW5zaW9uc10gZXh0ZW5zaW9uIHBhY2thZ2VzIHRvIHByb3ZpZGVcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5tb2R1bGVzXSBhIGxpc3Qgb2YgbW9kdWxlcyB0byBvdmVycmlkZSB0aGUgZGVmYXVsdCBtb2R1bGVzXG4gKiBAcGFyYW0ge0FycmF5PGRpZGkuTW9kdWxlPn0gW29wdGlvbnMuYWRkaXRpb25hbE1vZHVsZXNdIGEgbGlzdCBvZiBtb2R1bGVzIHRvIHVzZSB3aXRoIHRoZSBkZWZhdWx0IG1vZHVsZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW9kZWxlcihvcHRpb25zKSB7XG4gIEJhc2VNb2RlbGVyLmNhbGwodGhpcywgb3B0aW9ucyk7XG59XG5cbmluaGVyaXRzKE1vZGVsZXIsIEJhc2VNb2RlbGVyKTtcblxuXG5Nb2RlbGVyLlZpZXdlciA9IFZpZXdlcjtcbk1vZGVsZXIuTmF2aWdhdGVkVmlld2VyID0gTmF2aWdhdGVkVmlld2VyO1xuXG4vKipcbiogVGhlIGNyZWF0ZURpYWdyYW0gcmVzdWx0LlxuKlxuKiBAdHlwZWRlZiB7T2JqZWN0fSBDcmVhdGVEaWFncmFtUmVzdWx0XG4qXG4qIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gd2FybmluZ3NcbiovXG5cbi8qKlxuKiBUaGUgY3JlYXRlRGlhZ3JhbSBlcnJvci5cbipcbiogQHR5cGVkZWYge0Vycm9yfSBDcmVhdGVEaWFncmFtRXJyb3JcbipcbiogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuKi9cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgZGlhZ3JhbSB0byBzdGFydCBtb2RlbGluZy5cbiAqXG4gKiBSZXR1cm5zIHtQcm9taXNlPENyZWF0ZURpYWdyYW1SZXN1bHQsIENyZWF0ZURpYWdyYW1FcnJvcj59XG4gKi9cbk1vZGVsZXIucHJvdG90eXBlLmNyZWF0ZURpYWdyYW0gPSB3cmFwRm9yQ29tcGF0aWJpbGl0eShmdW5jdGlvbiBjcmVhdGVEaWFncmFtKCkge1xuICByZXR1cm4gdGhpcy5pbXBvcnRYTUwoaW5pdGlhbERpYWdyYW0pO1xufSk7XG5cblxuTW9kZWxlci5wcm90b3R5cGUuX2ludGVyYWN0aW9uTW9kdWxlcyA9IFtcblxuICAvLyBub24tbW9kZWxpbmcgY29tcG9uZW50c1xuICBLZXlib2FyZE1vdmVNb2R1bGUsXG4gIE1vdmVDYW52YXNNb2R1bGUsXG4gIFRvdWNoTW9kdWxlLFxuICBab29tU2Nyb2xsTW9kdWxlXG5dO1xuXG5Nb2RlbGVyLnByb3RvdHlwZS5fbW9kZWxpbmdNb2R1bGVzID0gW1xuXG4gIC8vIG1vZGVsaW5nIGNvbXBvbmVudHNcbiAgQWxpZ25FbGVtZW50c01vZHVsZSxcbiAgQXV0b1BsYWNlTW9kdWxlLFxuICBBdXRvU2Nyb2xsTW9kdWxlLFxuICBBdXRvUmVzaXplTW9kdWxlLFxuICBCZW5kcG9pbnRzTW9kdWxlLFxuICBDb25uZWN0TW9kdWxlLFxuICBDb25uZWN0aW9uUHJldmlld01vZHVsZSxcbiAgQ29udGV4dFBhZE1vZHVsZSxcbiAgQ29weVBhc3RlTW9kdWxlLFxuICBDcmVhdGVNb2R1bGUsXG4gIERpc3RyaWJ1dGVFbGVtZW50c01vZHVsZSxcbiAgRWRpdG9yQWN0aW9uc01vZHVsZSxcbiAgR3JpZFNuYXBwaW5nTW9kdWxlLFxuICBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSxcbiAgS2V5Ym9hcmRNb2R1bGUsXG4gIEtleWJvYXJkTW92ZVNlbGVjdGlvbk1vZHVsZSxcbiAgTGFiZWxFZGl0aW5nTW9kdWxlLFxuICBNb2RlbGluZ01vZHVsZSxcbiAgTW92ZU1vZHVsZSxcbiAgUGFsZXR0ZU1vZHVsZSxcbiAgUmVwbGFjZVByZXZpZXdNb2R1bGUsXG4gIFJlc2l6ZU1vZHVsZSxcbiAgU25hcHBpbmdNb2R1bGUsXG4gIFNlYXJjaE1vZHVsZVxuXTtcblxuXG4vLyBtb2R1bGVzIHRoZSBtb2RlbGVyIGlzIGNvbXBvc2VkIG9mXG4vL1xuLy8gLSB2aWV3ZXIgbW9kdWxlc1xuLy8gLSBpbnRlcmFjdGlvbiBtb2R1bGVzXG4vLyAtIG1vZGVsaW5nIG1vZHVsZXNcblxuTW9kZWxlci5wcm90b3R5cGUuX21vZHVsZXMgPSBbXS5jb25jYXQoXG4gIFZpZXdlci5wcm90b3R5cGUuX21vZHVsZXMsXG4gIE1vZGVsZXIucHJvdG90eXBlLl9pbnRlcmFjdGlvbk1vZHVsZXMsXG4gIE1vZGVsZXIucHJvdG90eXBlLl9tb2RlbGluZ01vZHVsZXNcbik7XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgVmlld2VyIGZyb20gJy4vVmlld2VyJztcblxuaW1wb3J0IEtleWJvYXJkTW92ZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9uYXZpZ2F0aW9uL2tleWJvYXJkLW1vdmUnO1xuaW1wb3J0IE1vdmVDYW52YXNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvbmF2aWdhdGlvbi9tb3ZlY2FudmFzJztcbmltcG9ydCBab29tU2Nyb2xsTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL25hdmlnYXRpb24vem9vbXNjcm9sbCc7XG5cblxuLyoqXG4gKiBBIHZpZXdlciB0aGF0IGluY2x1ZGVzIG1vdXNlIG5hdmlnYXRpb24gZmFjaWxpdGllc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE5hdmlnYXRlZFZpZXdlcihvcHRpb25zKSB7XG4gIFZpZXdlci5jYWxsKHRoaXMsIG9wdGlvbnMpO1xufVxuXG5pbmhlcml0cyhOYXZpZ2F0ZWRWaWV3ZXIsIFZpZXdlcik7XG5cblxuTmF2aWdhdGVkVmlld2VyLnByb3RvdHlwZS5fbmF2aWdhdGlvbk1vZHVsZXMgPSBbXG4gIEtleWJvYXJkTW92ZU1vZHVsZSxcbiAgTW92ZUNhbnZhc01vZHVsZSxcbiAgWm9vbVNjcm9sbE1vZHVsZVxuXTtcblxuTmF2aWdhdGVkVmlld2VyLnByb3RvdHlwZS5fbW9kdWxlcyA9IFtdLmNvbmNhdChcbiAgVmlld2VyLnByb3RvdHlwZS5fbW9kdWxlcyxcbiAgTmF2aWdhdGVkVmlld2VyLnByb3RvdHlwZS5fbmF2aWdhdGlvbk1vZHVsZXNcbik7IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvcmVNb2R1bGUgZnJvbSAnLi9jb3JlJztcbmltcG9ydCBUcmFuc2xhdGVNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zZWxlY3Rpb24nO1xuaW1wb3J0IE92ZXJsYXlzTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL292ZXJsYXlzJztcblxuaW1wb3J0IEJhc2VWaWV3ZXIgZnJvbSAnLi9CYXNlVmlld2VyJztcblxuXG4vKipcbiAqIEEgdmlld2VyIGZvciBCUE1OIDIuMCBkaWFncmFtcy5cbiAqXG4gKiBIYXZlIGEgbG9vayBhdCB7QGxpbmsgTmF2aWdhdGVkVmlld2VyfSBvciB7QGxpbmsgTW9kZWxlcn0gZm9yIGJ1bmRsZXMgdGhhdCBpbmNsdWRlXG4gKiBhZGRpdGlvbmFsIGZlYXR1cmVzLlxuICpcbiAqXG4gKiAjIyBFeHRlbmRpbmcgdGhlIFZpZXdlclxuICpcbiAqIEluIG9yZGVyIHRvIGV4dGVuZCB0aGUgdmlld2VyIHBhc3MgZXh0ZW5zaW9uIG1vZHVsZXMgdG8gYm9vdHN0cmFwIHZpYSB0aGVcbiAqIGBhZGRpdGlvbmFsTW9kdWxlc2Agb3B0aW9uLiBBbiBleHRlbnNpb24gbW9kdWxlIGlzIGFuIG9iamVjdCB0aGF0IGV4cG9zZXNcbiAqIG5hbWVkIHNlcnZpY2VzLlxuICpcbiAqIFRoZSBmb2xsb3dpbmcgZXhhbXBsZSBkZXBpY3RzIHRoZSBpbnRlZ3JhdGlvbiBvZiBhIHNpbXBsZVxuICogbG9nZ2luZyBjb21wb25lbnQgdGhhdCBpbnRlZ3JhdGVzIHdpdGggaW50ZXJhY3Rpb24gZXZlbnRzOlxuICpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKlxuICogLy8gbG9nZ2luZyBjb21wb25lbnRcbiAqIGZ1bmN0aW9uIEludGVyYWN0aW9uTG9nZ2VyKGV2ZW50QnVzKSB7XG4gKiAgIGV2ZW50QnVzLm9uKCdlbGVtZW50LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgICBjb25zb2xlLmxvZygpXG4gKiAgIH0pXG4gKiB9XG4gKlxuICogSW50ZXJhY3Rpb25Mb2dnZXIuJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdOyAvLyBtaW5pZmljYXRpb24gc2F2ZVxuICpcbiAqIC8vIGV4dGVuc2lvbiBtb2R1bGVcbiAqIHZhciBleHRlbnNpb25Nb2R1bGUgPSB7XG4gKiAgIF9faW5pdF9fOiBbICdpbnRlcmFjdGlvbkxvZ2dlcicgXSxcbiAqICAgaW50ZXJhY3Rpb25Mb2dnZXI6IFsgJ3R5cGUnLCBJbnRlcmFjdGlvbkxvZ2dlciBdXG4gKiB9O1xuICpcbiAqIC8vIGV4dGVuZCB0aGUgdmlld2VyXG4gKiB2YXIgYnBtblZpZXdlciA9IG5ldyBWaWV3ZXIoeyBhZGRpdGlvbmFsTW9kdWxlczogWyBleHRlbnNpb25Nb2R1bGUgXSB9KTtcbiAqIGJwbW5WaWV3ZXIuaW1wb3J0WE1MKC4uLik7XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIGNvbmZpZ3VyYXRpb24gb3B0aW9ucyB0byBwYXNzIHRvIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gW29wdGlvbnMuY29udGFpbmVyXSB0aGUgY29udGFpbmVyIHRvIHJlbmRlciB0aGUgdmlld2VyIGluLCBkZWZhdWx0cyB0byBib2R5LlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBbb3B0aW9ucy53aWR0aF0gdGhlIHdpZHRoIG9mIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gW29wdGlvbnMuaGVpZ2h0XSB0aGUgaGVpZ2h0IG9mIHRoZSB2aWV3ZXJcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5tb2RkbGVFeHRlbnNpb25zXSBleHRlbnNpb24gcGFja2FnZXMgdG8gcHJvdmlkZVxuICogQHBhcmFtIHtBcnJheTxkaWRpLk1vZHVsZT59IFtvcHRpb25zLm1vZHVsZXNdIGEgbGlzdCBvZiBtb2R1bGVzIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IG1vZHVsZXNcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5hZGRpdGlvbmFsTW9kdWxlc10gYSBsaXN0IG9mIG1vZHVsZXMgdG8gdXNlIHdpdGggdGhlIGRlZmF1bHQgbW9kdWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBWaWV3ZXIob3B0aW9ucykge1xuICBCYXNlVmlld2VyLmNhbGwodGhpcywgb3B0aW9ucyk7XG59XG5cbmluaGVyaXRzKFZpZXdlciwgQmFzZVZpZXdlcik7XG5cbi8vIG1vZHVsZXMgdGhlIHZpZXdlciBpcyBjb21wb3NlZCBvZlxuVmlld2VyLnByb3RvdHlwZS5fbW9kdWxlcyA9IFtcbiAgQ29yZU1vZHVsZSxcbiAgVHJhbnNsYXRlTW9kdWxlLFxuICBTZWxlY3Rpb25Nb2R1bGUsXG4gIE92ZXJsYXlzTW9kdWxlXG5dO1xuXG4vLyBkZWZhdWx0IG1vZGRsZSBleHRlbnNpb25zIHRoZSB2aWV3ZXIgaXMgY29tcG9zZWQgb2ZcblZpZXdlci5wcm90b3R5cGUuX21vZGRsZUV4dGVuc2lvbnMgPSB7fTsiLCJpbXBvcnQgRHJhd01vZHVsZSBmcm9tICcuLi9kcmF3JztcbmltcG9ydCBJbXBvcnRNb2R1bGUgZnJvbSAnLi4vaW1wb3J0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIERyYXdNb2R1bGUsXG4gICAgSW1wb3J0TW9kdWxlXG4gIF1cbn07IiwiaW1wb3J0IHtcbiAgZXZlcnksXG4gIHNvbWVcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBjb21wb25lbnRzVG9QYXRoXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvUmVuZGVyVXRpbCc7XG5cblxuLy8gZWxlbWVudCB1dGlscyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQ2hlY2tzIGlmIGV2ZW50RGVmaW5pdGlvbiBvZiB0aGUgZ2l2ZW4gZWxlbWVudCBtYXRjaGVzIHdpdGggc2VtYW50aWMgdHlwZS5cbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIGVsZW1lbnQgaXMgb2YgdGhlIGdpdmVuIHNlbWFudGljIHR5cGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVHlwZWRFdmVudChldmVudCwgZXZlbnREZWZpbml0aW9uVHlwZSwgZmlsdGVyKSB7XG5cbiAgZnVuY3Rpb24gbWF0Y2hlcyhkZWZpbml0aW9uLCBmaWx0ZXIpIHtcbiAgICByZXR1cm4gZXZlcnkoZmlsdGVyLCBmdW5jdGlvbih2YWwsIGtleSkge1xuXG4gICAgICAvLyB3ZSB3YW50IGEgPT0gY29udmVyc2lvbiBoZXJlLCB0byBiZSBhYmxlIHRvIGNhdGNoXG4gICAgICAvLyB1bmRlZmluZWQgPT0gZmFsc2UgYW5kIGZyaWVuZHNcbiAgICAgIC8qIGpzaGludCAtVzExNiAqL1xuICAgICAgcmV0dXJuIGRlZmluaXRpb25ba2V5XSA9PSB2YWw7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gc29tZShldmVudC5ldmVudERlZmluaXRpb25zLCBmdW5jdGlvbihkZWZpbml0aW9uKSB7XG4gICAgcmV0dXJuIGRlZmluaXRpb24uJHR5cGUgPT09IGV2ZW50RGVmaW5pdGlvblR5cGUgJiYgbWF0Y2hlcyhldmVudCwgZmlsdGVyKTtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1Rocm93RXZlbnQoZXZlbnQpIHtcbiAgcmV0dXJuIChldmVudC4kdHlwZSA9PT0gJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcpIHx8IChldmVudC4kdHlwZSA9PT0gJ2JwbW46RW5kRXZlbnQnKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzQ29sbGVjdGlvbihlbGVtZW50KSB7XG4gIHZhciBkYXRhT2JqZWN0ID0gZWxlbWVudC5kYXRhT2JqZWN0UmVmO1xuXG4gIHJldHVybiBlbGVtZW50LmlzQ29sbGVjdGlvbiB8fCAoZGF0YU9iamVjdCAmJiBkYXRhT2JqZWN0LmlzQ29sbGVjdGlvbik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXREaShlbGVtZW50KSB7XG4gIHJldHVybiBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LmRpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U2VtYW50aWMoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudC5idXNpbmVzc09iamVjdDtcbn1cblxuXG4vLyBjb2xvciBhY2Nlc3MgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRDb2xvcikge1xuICByZXR1cm4gZ2V0RGkoZWxlbWVudCkuZ2V0KCdiaW9jOmZpbGwnKSB8fCBkZWZhdWx0Q29sb3IgfHwgJ3doaXRlJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRDb2xvcikge1xuICByZXR1cm4gZ2V0RGkoZWxlbWVudCkuZ2V0KCdiaW9jOnN0cm9rZScpIHx8IGRlZmF1bHRDb2xvciB8fCAnYmxhY2snO1xufVxuXG5cbi8vIGNyb3BwaW5nIHBhdGggY3VzdG9taXphdGlvbnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2lyY2xlUGF0aChzaGFwZSkge1xuXG4gIHZhciBjeCA9IHNoYXBlLnggKyBzaGFwZS53aWR0aCAvIDIsXG4gICAgICBjeSA9IHNoYXBlLnkgKyBzaGFwZS5oZWlnaHQgLyAyLFxuICAgICAgcmFkaXVzID0gc2hhcGUud2lkdGggLyAyO1xuXG4gIHZhciBjaXJjbGVQYXRoID0gW1xuICAgIFsnTScsIGN4LCBjeV0sXG4gICAgWydtJywgMCwgLXJhZGl1c10sXG4gICAgWydhJywgcmFkaXVzLCByYWRpdXMsIDAsIDEsIDEsIDAsIDIgKiByYWRpdXNdLFxuICAgIFsnYScsIHJhZGl1cywgcmFkaXVzLCAwLCAxLCAxLCAwLCAtMiAqIHJhZGl1c10sXG4gICAgWyd6J11cbiAgXTtcblxuICByZXR1cm4gY29tcG9uZW50c1RvUGF0aChjaXJjbGVQYXRoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJvdW5kUmVjdFBhdGgoc2hhcGUsIGJvcmRlclJhZGl1cykge1xuXG4gIHZhciB4ID0gc2hhcGUueCxcbiAgICAgIHkgPSBzaGFwZS55LFxuICAgICAgd2lkdGggPSBzaGFwZS53aWR0aCxcbiAgICAgIGhlaWdodCA9IHNoYXBlLmhlaWdodDtcblxuICB2YXIgcm91bmRSZWN0UGF0aCA9IFtcbiAgICBbJ00nLCB4ICsgYm9yZGVyUmFkaXVzLCB5XSxcbiAgICBbJ2wnLCB3aWR0aCAtIGJvcmRlclJhZGl1cyAqIDIsIDBdLFxuICAgIFsnYScsIGJvcmRlclJhZGl1cywgYm9yZGVyUmFkaXVzLCAwLCAwLCAxLCBib3JkZXJSYWRpdXMsIGJvcmRlclJhZGl1c10sXG4gICAgWydsJywgMCwgaGVpZ2h0IC0gYm9yZGVyUmFkaXVzICogMl0sXG4gICAgWydhJywgYm9yZGVyUmFkaXVzLCBib3JkZXJSYWRpdXMsIDAsIDAsIDEsIC1ib3JkZXJSYWRpdXMsIGJvcmRlclJhZGl1c10sXG4gICAgWydsJywgYm9yZGVyUmFkaXVzICogMiAtIHdpZHRoLCAwXSxcbiAgICBbJ2EnLCBib3JkZXJSYWRpdXMsIGJvcmRlclJhZGl1cywgMCwgMCwgMSwgLWJvcmRlclJhZGl1cywgLWJvcmRlclJhZGl1c10sXG4gICAgWydsJywgMCwgYm9yZGVyUmFkaXVzICogMiAtIGhlaWdodF0sXG4gICAgWydhJywgYm9yZGVyUmFkaXVzLCBib3JkZXJSYWRpdXMsIDAsIDAsIDEsIGJvcmRlclJhZGl1cywgLWJvcmRlclJhZGl1c10sXG4gICAgWyd6J11cbiAgXTtcblxuICByZXR1cm4gY29tcG9uZW50c1RvUGF0aChyb3VuZFJlY3RQYXRoKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldERpYW1vbmRQYXRoKHNoYXBlKSB7XG5cbiAgdmFyIHdpZHRoID0gc2hhcGUud2lkdGgsXG4gICAgICBoZWlnaHQgPSBzaGFwZS5oZWlnaHQsXG4gICAgICB4ID0gc2hhcGUueCxcbiAgICAgIHkgPSBzaGFwZS55LFxuICAgICAgaGFsZldpZHRoID0gd2lkdGggLyAyLFxuICAgICAgaGFsZkhlaWdodCA9IGhlaWdodCAvIDI7XG5cbiAgdmFyIGRpYW1vbmRQYXRoID0gW1xuICAgIFsnTScsIHggKyBoYWxmV2lkdGgsIHldLFxuICAgIFsnbCcsIGhhbGZXaWR0aCwgaGFsZkhlaWdodF0sXG4gICAgWydsJywgLWhhbGZXaWR0aCwgaGFsZkhlaWdodF0sXG4gICAgWydsJywgLWhhbGZXaWR0aCwgLWhhbGZIZWlnaHRdLFxuICAgIFsneiddXG4gIF07XG5cbiAgcmV0dXJuIGNvbXBvbmVudHNUb1BhdGgoZGlhbW9uZFBhdGgpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVjdFBhdGgoc2hhcGUpIHtcbiAgdmFyIHggPSBzaGFwZS54LFxuICAgICAgeSA9IHNoYXBlLnksXG4gICAgICB3aWR0aCA9IHNoYXBlLndpZHRoLFxuICAgICAgaGVpZ2h0ID0gc2hhcGUuaGVpZ2h0O1xuXG4gIHZhciByZWN0UGF0aCA9IFtcbiAgICBbJ00nLCB4LCB5XSxcbiAgICBbJ2wnLCB3aWR0aCwgMF0sXG4gICAgWydsJywgMCwgaGVpZ2h0XSxcbiAgICBbJ2wnLCAtd2lkdGgsIDBdLFxuICAgIFsneiddXG4gIF07XG5cbiAgcmV0dXJuIGNvbXBvbmVudHNUb1BhdGgocmVjdFBhdGgpO1xufSIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCB7XG4gIGlzT2JqZWN0LFxuICBhc3NpZ24sXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgQmFzZVJlbmRlcmVyIGZyb20gJ2RpYWdyYW0tanMvbGliL2RyYXcvQmFzZVJlbmRlcmVyJztcblxuaW1wb3J0IHtcbiAgaXNFeHBhbmRlZCxcbiAgaXNFdmVudFN1YlByb2Nlc3Ncbn0gZnJvbSAnLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRMYWJlbFxufSBmcm9tICcuLi9mZWF0dXJlcy9sYWJlbC1lZGl0aW5nL0xhYmVsVXRpbCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVMaW5lXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvUmVuZGVyVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzVHlwZWRFdmVudCxcbiAgaXNUaHJvd0V2ZW50LFxuICBpc0NvbGxlY3Rpb24sXG4gIGdldERpLFxuICBnZXRTZW1hbnRpYyxcbiAgZ2V0Q2lyY2xlUGF0aCxcbiAgZ2V0Um91bmRSZWN0UGF0aCxcbiAgZ2V0RGlhbW9uZFBhdGgsXG4gIGdldFJlY3RQYXRoLFxuICBnZXRGaWxsQ29sb3IsXG4gIGdldFN0cm9rZUNvbG9yXG59IGZyb20gJy4vQnBtblJlbmRlclV0aWwnO1xuXG5pbXBvcnQge1xuICBxdWVyeSBhcyBkb21RdWVyeVxufSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICBjbGFzc2VzIGFzIHN2Z0NsYXNzZXNcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICByb3RhdGUsXG4gIHRyYW5zZm9ybSxcbiAgdHJhbnNsYXRlXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvU3ZnVHJhbnNmb3JtVXRpbCc7XG5cbmltcG9ydCBJZHMgZnJvbSAnaWRzJztcblxudmFyIFJFTkRFUkVSX0lEUyA9IG5ldyBJZHMoKTtcblxudmFyIFRBU0tfQk9SREVSX1JBRElVUyA9IDEwO1xudmFyIElOTkVSX09VVEVSX0RJU1QgPSAzO1xuXG52YXIgREVGQVVMVF9GSUxMX09QQUNJVFkgPSAuOTUsXG4gICAgSElHSF9GSUxMX09QQUNJVFkgPSAuMzU7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtblJlbmRlcmVyKFxuICAgIGNvbmZpZywgZXZlbnRCdXMsIHN0eWxlcywgcGF0aE1hcCxcbiAgICBjYW52YXMsIHRleHRSZW5kZXJlciwgcHJpb3JpdHkpIHtcblxuICBCYXNlUmVuZGVyZXIuY2FsbCh0aGlzLCBldmVudEJ1cywgcHJpb3JpdHkpO1xuXG4gIHZhciBkZWZhdWx0RmlsbENvbG9yID0gY29uZmlnICYmIGNvbmZpZy5kZWZhdWx0RmlsbENvbG9yLFxuICAgICAgZGVmYXVsdFN0cm9rZUNvbG9yID0gY29uZmlnICYmIGNvbmZpZy5kZWZhdWx0U3Ryb2tlQ29sb3I7XG5cbiAgdmFyIHJlbmRlcmVySWQgPSBSRU5ERVJFUl9JRFMubmV4dCgpO1xuXG4gIHZhciBtYXJrZXJzID0ge307XG5cbiAgdmFyIGNvbXB1dGVTdHlsZSA9IHN0eWxlcy5jb21wdXRlU3R5bGU7XG5cbiAgZnVuY3Rpb24gYWRkTWFya2VyKGlkLCBvcHRpb25zKSB7XG4gICAgdmFyIGF0dHJzID0gYXNzaWduKHtcbiAgICAgIGZpbGw6ICdibGFjaycsXG4gICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgIHN0cm9rZUxpbmVjYXA6ICdyb3VuZCcsXG4gICAgICBzdHJva2VEYXNoYXJyYXk6ICdub25lJ1xuICAgIH0sIG9wdGlvbnMuYXR0cnMpO1xuXG4gICAgdmFyIHJlZiA9IG9wdGlvbnMucmVmIHx8IHsgeDogMCwgeTogMCB9O1xuXG4gICAgdmFyIHNjYWxlID0gb3B0aW9ucy5zY2FsZSB8fCAxO1xuXG4gICAgLy8gZml4IGZvciBzYWZhcmkgLyBjaHJvbWUgLyBmaXJlZm94IGJ1ZyBub3QgY29ycmVjdGx5XG4gICAgLy8gcmVzZXR0aW5nIHN0cm9rZSBkYXNoIGFycmF5XG4gICAgaWYgKGF0dHJzLnN0cm9rZURhc2hhcnJheSA9PT0gJ25vbmUnKSB7XG4gICAgICBhdHRycy5zdHJva2VEYXNoYXJyYXkgPSBbMTAwMDAsIDFdO1xuICAgIH1cblxuICAgIHZhciBtYXJrZXIgPSBzdmdDcmVhdGUoJ21hcmtlcicpO1xuXG4gICAgc3ZnQXR0cihvcHRpb25zLmVsZW1lbnQsIGF0dHJzKTtcblxuICAgIHN2Z0FwcGVuZChtYXJrZXIsIG9wdGlvbnMuZWxlbWVudCk7XG5cbiAgICBzdmdBdHRyKG1hcmtlciwge1xuICAgICAgaWQ6IGlkLFxuICAgICAgdmlld0JveDogJzAgMCAyMCAyMCcsXG4gICAgICByZWZYOiByZWYueCxcbiAgICAgIHJlZlk6IHJlZi55LFxuICAgICAgbWFya2VyV2lkdGg6IDIwICogc2NhbGUsXG4gICAgICBtYXJrZXJIZWlnaHQ6IDIwICogc2NhbGUsXG4gICAgICBvcmllbnQ6ICdhdXRvJ1xuICAgIH0pO1xuXG4gICAgdmFyIGRlZnMgPSBkb21RdWVyeSgnZGVmcycsIGNhbnZhcy5fc3ZnKTtcblxuICAgIGlmICghZGVmcykge1xuICAgICAgZGVmcyA9IHN2Z0NyZWF0ZSgnZGVmcycpO1xuXG4gICAgICBzdmdBcHBlbmQoY2FudmFzLl9zdmcsIGRlZnMpO1xuICAgIH1cblxuICAgIHN2Z0FwcGVuZChkZWZzLCBtYXJrZXIpO1xuXG4gICAgbWFya2Vyc1tpZF0gPSBtYXJrZXI7XG4gIH1cblxuICBmdW5jdGlvbiBjb2xvckVzY2FwZShzdHIpIHtcblxuICAgIC8vIG9ubHkgYWxsb3cgY2hhcmFjdGVycyBhbmQgbnVtYmVyc1xuICAgIHJldHVybiBzdHIucmVwbGFjZSgvW14wLTlhLXpBLXpdKy9nLCAnXycpO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFya2VyKHR5cGUsIGZpbGwsIHN0cm9rZSkge1xuICAgIHZhciBpZCA9IHR5cGUgKyAnLScgKyBjb2xvckVzY2FwZShmaWxsKSArICctJyArIGNvbG9yRXNjYXBlKHN0cm9rZSkgKyAnLScgKyByZW5kZXJlcklkO1xuXG4gICAgaWYgKCFtYXJrZXJzW2lkXSkge1xuICAgICAgY3JlYXRlTWFya2VyKGlkLCB0eXBlLCBmaWxsLCBzdHJva2UpO1xuICAgIH1cblxuICAgIHJldHVybiAndXJsKCMnICsgaWQgKyAnKSc7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVNYXJrZXIoaWQsIHR5cGUsIGZpbGwsIHN0cm9rZSkge1xuXG4gICAgaWYgKHR5cGUgPT09ICdzZXF1ZW5jZWZsb3ctZW5kJykge1xuICAgICAgdmFyIHNlcXVlbmNlZmxvd0VuZCA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuICAgICAgc3ZnQXR0cihzZXF1ZW5jZWZsb3dFbmQsIHsgZDogJ00gMSA1IEwgMTEgMTAgTCAxIDE1IFonIH0pO1xuXG4gICAgICBhZGRNYXJrZXIoaWQsIHtcbiAgICAgICAgZWxlbWVudDogc2VxdWVuY2VmbG93RW5kLFxuICAgICAgICByZWY6IHsgeDogMTEsIHk6IDEwIH0sXG4gICAgICAgIHNjYWxlOiAwLjUsXG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgZmlsbDogc3Ryb2tlLFxuICAgICAgICAgIHN0cm9rZTogc3Ryb2tlXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnbWVzc2FnZWZsb3ctc3RhcnQnKSB7XG4gICAgICB2YXIgbWVzc2FnZWZsb3dTdGFydCA9IHN2Z0NyZWF0ZSgnY2lyY2xlJyk7XG4gICAgICBzdmdBdHRyKG1lc3NhZ2VmbG93U3RhcnQsIHsgY3g6IDYsIGN5OiA2LCByOiAzLjUgfSk7XG5cbiAgICAgIGFkZE1hcmtlcihpZCwge1xuICAgICAgICBlbGVtZW50OiBtZXNzYWdlZmxvd1N0YXJ0LFxuICAgICAgICBhdHRyczoge1xuICAgICAgICAgIGZpbGw6IGZpbGwsXG4gICAgICAgICAgc3Ryb2tlOiBzdHJva2VcbiAgICAgICAgfSxcbiAgICAgICAgcmVmOiB7IHg6IDYsIHk6IDYgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdtZXNzYWdlZmxvdy1lbmQnKSB7XG4gICAgICB2YXIgbWVzc2FnZWZsb3dFbmQgPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICAgIHN2Z0F0dHIobWVzc2FnZWZsb3dFbmQsIHsgZDogJ20gMSA1IGwgMCAtMyBsIDcgMyBsIC03IDMgeicgfSk7XG5cbiAgICAgIGFkZE1hcmtlcihpZCwge1xuICAgICAgICBlbGVtZW50OiBtZXNzYWdlZmxvd0VuZCxcbiAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICBmaWxsOiBmaWxsLFxuICAgICAgICAgIHN0cm9rZTogc3Ryb2tlLFxuICAgICAgICAgIHN0cm9rZUxpbmVjYXA6ICdidXR0J1xuICAgICAgICB9LFxuICAgICAgICByZWY6IHsgeDogOC41LCB5OiA1IH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnYXNzb2NpYXRpb24tc3RhcnQnKSB7XG4gICAgICB2YXIgYXNzb2NpYXRpb25TdGFydCA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuICAgICAgc3ZnQXR0cihhc3NvY2lhdGlvblN0YXJ0LCB7IGQ6ICdNIDExIDUgTCAxIDEwIEwgMTEgMTUnIH0pO1xuXG4gICAgICBhZGRNYXJrZXIoaWQsIHtcbiAgICAgICAgZWxlbWVudDogYXNzb2NpYXRpb25TdGFydCxcbiAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICBmaWxsOiAnbm9uZScsXG4gICAgICAgICAgc3Ryb2tlOiBzdHJva2UsXG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IDEuNVxuICAgICAgICB9LFxuICAgICAgICByZWY6IHsgeDogMSwgeTogMTAgfSxcbiAgICAgICAgc2NhbGU6IDAuNVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdhc3NvY2lhdGlvbi1lbmQnKSB7XG4gICAgICB2YXIgYXNzb2NpYXRpb25FbmQgPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICAgIHN2Z0F0dHIoYXNzb2NpYXRpb25FbmQsIHsgZDogJ00gMSA1IEwgMTEgMTAgTCAxIDE1JyB9KTtcblxuICAgICAgYWRkTWFya2VyKGlkLCB7XG4gICAgICAgIGVsZW1lbnQ6IGFzc29jaWF0aW9uRW5kLFxuICAgICAgICBhdHRyczoge1xuICAgICAgICAgIGZpbGw6ICdub25lJyxcbiAgICAgICAgICBzdHJva2U6IHN0cm9rZSxcbiAgICAgICAgICBzdHJva2VXaWR0aDogMS41XG4gICAgICAgIH0sXG4gICAgICAgIHJlZjogeyB4OiAxMiwgeTogMTAgfSxcbiAgICAgICAgc2NhbGU6IDAuNVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHR5cGUgPT09ICdjb25kaXRpb25hbC1mbG93LW1hcmtlcicpIHtcbiAgICAgIHZhciBjb25kaXRpb25hbGZsb3dNYXJrZXIgPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICAgIHN2Z0F0dHIoY29uZGl0aW9uYWxmbG93TWFya2VyLCB7IGQ6ICdNIDAgMTAgTCA4IDYgTCAxNiAxMCBMIDggMTQgWicgfSk7XG5cbiAgICAgIGFkZE1hcmtlcihpZCwge1xuICAgICAgICBlbGVtZW50OiBjb25kaXRpb25hbGZsb3dNYXJrZXIsXG4gICAgICAgIGF0dHJzOiB7XG4gICAgICAgICAgZmlsbDogZmlsbCxcbiAgICAgICAgICBzdHJva2U6IHN0cm9rZVxuICAgICAgICB9LFxuICAgICAgICByZWY6IHsgeDogLTEsIHk6IDEwIH0sXG4gICAgICAgIHNjYWxlOiAwLjVcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSAnY29uZGl0aW9uYWwtZGVmYXVsdC1mbG93LW1hcmtlcicpIHtcbiAgICAgIHZhciBjb25kaXRpb25hbGRlZmF1bHRmbG93TWFya2VyID0gc3ZnQ3JlYXRlKCdwYXRoJyk7XG4gICAgICBzdmdBdHRyKGNvbmRpdGlvbmFsZGVmYXVsdGZsb3dNYXJrZXIsIHsgZDogJ00gNiA0IEwgMTAgMTYnIH0pO1xuXG4gICAgICBhZGRNYXJrZXIoaWQsIHtcbiAgICAgICAgZWxlbWVudDogY29uZGl0aW9uYWxkZWZhdWx0Zmxvd01hcmtlcixcbiAgICAgICAgYXR0cnM6IHtcbiAgICAgICAgICBzdHJva2U6IHN0cm9rZVxuICAgICAgICB9LFxuICAgICAgICByZWY6IHsgeDogMCwgeTogMTAgfSxcbiAgICAgICAgc2NhbGU6IDAuNVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZHJhd0NpcmNsZShwYXJlbnRHZngsIHdpZHRoLCBoZWlnaHQsIG9mZnNldCwgYXR0cnMpIHtcblxuICAgIGlmIChpc09iamVjdChvZmZzZXQpKSB7XG4gICAgICBhdHRycyA9IG9mZnNldDtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgfVxuXG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG5cbiAgICBhdHRycyA9IGNvbXB1dGVTdHlsZShhdHRycywge1xuICAgICAgc3Ryb2tlOiAnYmxhY2snLFxuICAgICAgc3Ryb2tlV2lkdGg6IDIsXG4gICAgICBmaWxsOiAnd2hpdGUnXG4gICAgfSk7XG5cbiAgICBpZiAoYXR0cnMuZmlsbCA9PT0gJ25vbmUnKSB7XG4gICAgICBkZWxldGUgYXR0cnMuZmlsbE9wYWNpdHk7XG4gICAgfVxuXG4gICAgdmFyIGN4ID0gd2lkdGggLyAyLFxuICAgICAgICBjeSA9IGhlaWdodCAvIDI7XG5cbiAgICB2YXIgY2lyY2xlID0gc3ZnQ3JlYXRlKCdjaXJjbGUnKTtcbiAgICBzdmdBdHRyKGNpcmNsZSwge1xuICAgICAgY3g6IGN4LFxuICAgICAgY3k6IGN5LFxuICAgICAgcjogTWF0aC5yb3VuZCgod2lkdGggKyBoZWlnaHQpIC8gNCAtIG9mZnNldClcbiAgICB9KTtcbiAgICBzdmdBdHRyKGNpcmNsZSwgYXR0cnMpO1xuXG4gICAgc3ZnQXBwZW5kKHBhcmVudEdmeCwgY2lyY2xlKTtcblxuICAgIHJldHVybiBjaXJjbGU7XG4gIH1cblxuICBmdW5jdGlvbiBkcmF3UmVjdChwYXJlbnRHZngsIHdpZHRoLCBoZWlnaHQsIHIsIG9mZnNldCwgYXR0cnMpIHtcblxuICAgIGlmIChpc09iamVjdChvZmZzZXQpKSB7XG4gICAgICBhdHRycyA9IG9mZnNldDtcbiAgICAgIG9mZnNldCA9IDA7XG4gICAgfVxuXG4gICAgb2Zmc2V0ID0gb2Zmc2V0IHx8IDA7XG5cbiAgICBhdHRycyA9IGNvbXB1dGVTdHlsZShhdHRycywge1xuICAgICAgc3Ryb2tlOiAnYmxhY2snLFxuICAgICAgc3Ryb2tlV2lkdGg6IDIsXG4gICAgICBmaWxsOiAnd2hpdGUnXG4gICAgfSk7XG5cbiAgICB2YXIgcmVjdCA9IHN2Z0NyZWF0ZSgncmVjdCcpO1xuICAgIHN2Z0F0dHIocmVjdCwge1xuICAgICAgeDogb2Zmc2V0LFxuICAgICAgeTogb2Zmc2V0LFxuICAgICAgd2lkdGg6IHdpZHRoIC0gb2Zmc2V0ICogMixcbiAgICAgIGhlaWdodDogaGVpZ2h0IC0gb2Zmc2V0ICogMixcbiAgICAgIHJ4OiByLFxuICAgICAgcnk6IHJcbiAgICB9KTtcbiAgICBzdmdBdHRyKHJlY3QsIGF0dHJzKTtcblxuICAgIHN2Z0FwcGVuZChwYXJlbnRHZngsIHJlY3QpO1xuXG4gICAgcmV0dXJuIHJlY3Q7XG4gIH1cblxuICBmdW5jdGlvbiBkcmF3RGlhbW9uZChwYXJlbnRHZngsIHdpZHRoLCBoZWlnaHQsIGF0dHJzKSB7XG5cbiAgICB2YXIgeF8yID0gd2lkdGggLyAyO1xuICAgIHZhciB5XzIgPSBoZWlnaHQgLyAyO1xuXG4gICAgdmFyIHBvaW50cyA9IFt7IHg6IHhfMiwgeTogMCB9LCB7IHg6IHdpZHRoLCB5OiB5XzIgfSwgeyB4OiB4XzIsIHk6IGhlaWdodCB9LCB7IHg6IDAsIHk6IHlfMiB9XTtcblxuICAgIHZhciBwb2ludHNTdHJpbmcgPSBwb2ludHMubWFwKGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgICByZXR1cm4gcG9pbnQueCArICcsJyArIHBvaW50Lnk7XG4gICAgfSkuam9pbignICcpO1xuXG4gICAgYXR0cnMgPSBjb21wdXRlU3R5bGUoYXR0cnMsIHtcbiAgICAgIHN0cm9rZTogJ2JsYWNrJyxcbiAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgZmlsbDogJ3doaXRlJ1xuICAgIH0pO1xuXG4gICAgdmFyIHBvbHlnb24gPSBzdmdDcmVhdGUoJ3BvbHlnb24nKTtcbiAgICBzdmdBdHRyKHBvbHlnb24sIHtcbiAgICAgIHBvaW50czogcG9pbnRzU3RyaW5nXG4gICAgfSk7XG4gICAgc3ZnQXR0cihwb2x5Z29uLCBhdHRycyk7XG5cbiAgICBzdmdBcHBlbmQocGFyZW50R2Z4LCBwb2x5Z29uKTtcblxuICAgIHJldHVybiBwb2x5Z29uO1xuICB9XG5cbiAgZnVuY3Rpb24gZHJhd0xpbmUocGFyZW50R2Z4LCB3YXlwb2ludHMsIGF0dHJzKSB7XG4gICAgYXR0cnMgPSBjb21wdXRlU3R5bGUoYXR0cnMsIFsgJ25vLWZpbGwnIF0sIHtcbiAgICAgIHN0cm9rZTogJ2JsYWNrJyxcbiAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgZmlsbDogJ25vbmUnXG4gICAgfSk7XG5cbiAgICB2YXIgbGluZSA9IGNyZWF0ZUxpbmUod2F5cG9pbnRzLCBhdHRycyk7XG5cbiAgICBzdmdBcHBlbmQocGFyZW50R2Z4LCBsaW5lKTtcblxuICAgIHJldHVybiBsaW5lO1xuICB9XG5cbiAgZnVuY3Rpb24gZHJhd1BhdGgocGFyZW50R2Z4LCBkLCBhdHRycykge1xuXG4gICAgYXR0cnMgPSBjb21wdXRlU3R5bGUoYXR0cnMsIFsgJ25vLWZpbGwnIF0sIHtcbiAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgc3Ryb2tlOiAnYmxhY2snXG4gICAgfSk7XG5cbiAgICB2YXIgcGF0aCA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuICAgIHN2Z0F0dHIocGF0aCwgeyBkOiBkIH0pO1xuICAgIHN2Z0F0dHIocGF0aCwgYXR0cnMpO1xuXG4gICAgc3ZnQXBwZW5kKHBhcmVudEdmeCwgcGF0aCk7XG5cbiAgICByZXR1cm4gcGF0aDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRyYXdNYXJrZXIodHlwZSwgcGFyZW50R2Z4LCBwYXRoLCBhdHRycykge1xuICAgIHJldHVybiBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGgsIGFzc2lnbih7ICdkYXRhLW1hcmtlcic6IHR5cGUgfSwgYXR0cnMpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFzKHR5cGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICByZXR1cm4gaGFuZGxlcnNbdHlwZV0ocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyZXIodHlwZSkge1xuICAgIHJldHVybiBoYW5kbGVyc1t0eXBlXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlckV2ZW50Q29udGVudChlbGVtZW50LCBwYXJlbnRHZngpIHtcblxuICAgIHZhciBldmVudCA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuICAgIHZhciBpc1Rocm93aW5nID0gaXNUaHJvd0V2ZW50KGV2ZW50KTtcblxuICAgIGlmIChldmVudC5ldmVudERlZmluaXRpb25zICYmIGV2ZW50LmV2ZW50RGVmaW5pdGlvbnMubGVuZ3RoPjEpIHtcbiAgICAgIGlmIChldmVudC5wYXJhbGxlbE11bHRpcGxlKSB7XG4gICAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpQYXJhbGxlbE11bHRpcGxlRXZlbnREZWZpbml0aW9uJykocGFyZW50R2Z4LCBlbGVtZW50LCBpc1Rocm93aW5nKTtcbiAgICAgIH1cbiAgICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46TXVsdGlwbGVFdmVudERlZmluaXRpb24nKShwYXJlbnRHZngsIGVsZW1lbnQsIGlzVGhyb3dpbmcpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChpc1R5cGVkRXZlbnQoZXZlbnQsICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKShwYXJlbnRHZngsIGVsZW1lbnQsIGlzVGhyb3dpbmcpO1xuICAgIH1cblxuICAgIGlmIChpc1R5cGVkRXZlbnQoZXZlbnQsICdicG1uOlRpbWVyRXZlbnREZWZpbml0aW9uJykpIHtcbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpUaW1lckV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJykocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICB9XG5cbiAgICBpZiAoaXNUeXBlZEV2ZW50KGV2ZW50LCAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicpKSB7XG4gICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpKSB7XG4gICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46RXJyb3JFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOkVycm9yRXZlbnREZWZpbml0aW9uJykocGFyZW50R2Z4LCBlbGVtZW50LCBpc1Rocm93aW5nKTtcbiAgICB9XG5cbiAgICBpZiAoaXNUeXBlZEV2ZW50KGV2ZW50LCAnYnBtbjpDYW5jZWxFdmVudERlZmluaXRpb24nKSkge1xuICAgICAgcmV0dXJuIHJlbmRlcmVyKCdicG1uOkNhbmNlbEV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46Q29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbicpKSB7XG4gICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46Q29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZyk7XG4gICAgfVxuXG4gICAgaWYgKGlzVHlwZWRFdmVudChldmVudCwgJ2JwbW46VGVybWluYXRlRXZlbnREZWZpbml0aW9uJykpIHtcbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpUZXJtaW5hdGVFdmVudERlZmluaXRpb24nKShwYXJlbnRHZngsIGVsZW1lbnQsIGlzVGhyb3dpbmcpO1xuICAgIH1cblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVuZGVyTGFiZWwocGFyZW50R2Z4LCBsYWJlbCwgb3B0aW9ucykge1xuXG4gICAgb3B0aW9ucyA9IGFzc2lnbih7XG4gICAgICBzaXplOiB7XG4gICAgICAgIHdpZHRoOiAxMDBcbiAgICAgIH1cbiAgICB9LCBvcHRpb25zKTtcblxuICAgIHZhciB0ZXh0ID0gdGV4dFJlbmRlcmVyLmNyZWF0ZVRleHQobGFiZWwgfHwgJycsIG9wdGlvbnMpO1xuXG4gICAgc3ZnQ2xhc3Nlcyh0ZXh0KS5hZGQoJ2Rqcy1sYWJlbCcpO1xuXG4gICAgc3ZnQXBwZW5kKHBhcmVudEdmeCwgdGV4dCk7XG5cbiAgICByZXR1cm4gdGV4dDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlckVtYmVkZGVkTGFiZWwocGFyZW50R2Z4LCBlbGVtZW50LCBhbGlnbikge1xuICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgcmV0dXJuIHJlbmRlckxhYmVsKHBhcmVudEdmeCwgc2VtYW50aWMubmFtZSwge1xuICAgICAgYm94OiBlbGVtZW50LFxuICAgICAgYWxpZ246IGFsaWduLFxuICAgICAgcGFkZGluZzogNSxcbiAgICAgIHN0eWxlOiB7XG4gICAgICAgIGZpbGw6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlckV4dGVybmFsTGFiZWwocGFyZW50R2Z4LCBlbGVtZW50KSB7XG5cbiAgICB2YXIgYm94ID0ge1xuICAgICAgd2lkdGg6IDkwLFxuICAgICAgaGVpZ2h0OiAzMCxcbiAgICAgIHg6IGVsZW1lbnQud2lkdGggLyAyICsgZWxlbWVudC54LFxuICAgICAgeTogZWxlbWVudC5oZWlnaHQgLyAyICsgZWxlbWVudC55XG4gICAgfTtcblxuICAgIHJldHVybiByZW5kZXJMYWJlbChwYXJlbnRHZngsIGdldExhYmVsKGVsZW1lbnQpLCB7XG4gICAgICBib3g6IGJveCxcbiAgICAgIGZpdEJveDogdHJ1ZSxcbiAgICAgIHN0eWxlOiBhc3NpZ24oXG4gICAgICAgIHt9LFxuICAgICAgICB0ZXh0UmVuZGVyZXIuZ2V0RXh0ZXJuYWxTdHlsZSgpLFxuICAgICAgICB7XG4gICAgICAgICAgZmlsbDogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgICB9XG4gICAgICApXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiByZW5kZXJMYW5lTGFiZWwocGFyZW50R2Z4LCB0ZXh0LCBlbGVtZW50KSB7XG4gICAgdmFyIHRleHRCb3ggPSByZW5kZXJMYWJlbChwYXJlbnRHZngsIHRleHQsIHtcbiAgICAgIGJveDoge1xuICAgICAgICBoZWlnaHQ6IDMwLFxuICAgICAgICB3aWR0aDogZWxlbWVudC5oZWlnaHRcbiAgICAgIH0sXG4gICAgICBhbGlnbjogJ2NlbnRlci1taWRkbGUnLFxuICAgICAgc3R5bGU6IHtcbiAgICAgICAgZmlsbDogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdmFyIHRvcCA9IC0xICogZWxlbWVudC5oZWlnaHQ7XG5cbiAgICB0cmFuc2Zvcm0odGV4dEJveCwgMCwgLXRvcCwgMjcwKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZVBhdGhGcm9tQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgdmFyIHdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzO1xuXG4gICAgdmFyIHBhdGhEYXRhID0gJ20gICcgKyB3YXlwb2ludHNbMF0ueCArICcsJyArIHdheXBvaW50c1swXS55O1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgd2F5cG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBwYXRoRGF0YSArPSAnTCcgKyB3YXlwb2ludHNbaV0ueCArICcsJyArIHdheXBvaW50c1tpXS55ICsgJyAnO1xuICAgIH1cbiAgICByZXR1cm4gcGF0aERhdGE7XG4gIH1cblxuICB2YXIgaGFuZGxlcnMgPSB0aGlzLmhhbmRsZXJzID0ge1xuICAgICdicG1uOkV2ZW50JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50LCBhdHRycykge1xuXG4gICAgICBpZiAoISgnZmlsbE9wYWNpdHknIGluIGF0dHJzKSkge1xuICAgICAgICBhdHRycy5maWxsT3BhY2l0eSA9IERFRkFVTFRfRklMTF9PUEFDSVRZO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZHJhd0NpcmNsZShwYXJlbnRHZngsIGVsZW1lbnQud2lkdGgsIGVsZW1lbnQuaGVpZ2h0LCBhdHRycyk7XG4gICAgfSxcbiAgICAnYnBtbjpTdGFydEV2ZW50JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgYXR0cnMgPSB7XG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9O1xuXG4gICAgICB2YXIgc2VtYW50aWMgPSBnZXRTZW1hbnRpYyhlbGVtZW50KTtcblxuICAgICAgaWYgKCFzZW1hbnRpYy5pc0ludGVycnVwdGluZykge1xuICAgICAgICBhdHRycyA9IHtcbiAgICAgICAgICBzdHJva2VEYXNoYXJyYXk6ICc2JyxcbiAgICAgICAgICBzdHJva2VMaW5lY2FwOiAncm91bmQnLFxuICAgICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgdmFyIGNpcmNsZSA9IHJlbmRlcmVyKCdicG1uOkV2ZW50JykocGFyZW50R2Z4LCBlbGVtZW50LCBhdHRycyk7XG5cbiAgICAgIHJlbmRlckV2ZW50Q29udGVudChlbGVtZW50LCBwYXJlbnRHZngpO1xuXG4gICAgICByZXR1cm4gY2lyY2xlO1xuICAgIH0sXG4gICAgJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbic6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCwgaXNUaHJvd2luZykge1xuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdFVkVOVF9NRVNTQUdFJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDAuOSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAwLjksXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjIzNSxcbiAgICAgICAgICBteTogMC4zMTVcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBmaWxsID0gaXNUaHJvd2luZyA/IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcikgOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvcik7XG4gICAgICB2YXIgc3Ryb2tlID0gaXNUaHJvd2luZyA/IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSA6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcik7XG5cbiAgICAgIHZhciBtZXNzYWdlUGF0aCA9IGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGZpbGwsXG4gICAgICAgIHN0cm9rZTogc3Ryb2tlXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIG1lc3NhZ2VQYXRoO1xuICAgIH0sXG4gICAgJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBjaXJjbGUgPSBkcmF3Q2lyY2xlKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIDAuMiAqIGVsZW1lbnQuaGVpZ2h0LCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnRVZFTlRfVElNRVJfV0gnLCB7XG4gICAgICAgIHhTY2FsZUZhY3RvcjogMC43NSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAwLjc1LFxuICAgICAgICBjb250YWluZXJXaWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBlbGVtZW50LmhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogMC41LFxuICAgICAgICAgIG15OiAwLjVcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDIsXG4gICAgICAgIHN0cm9rZUxpbmVjYXA6ICdzcXVhcmUnLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICBmb3IgKHZhciBpID0gMDtpIDwgMTI7IGkrKykge1xuXG4gICAgICAgIHZhciBsaW5lUGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX1RJTUVSX0xJTkUnLCB7XG4gICAgICAgICAgeFNjYWxlRmFjdG9yOiAwLjc1LFxuICAgICAgICAgIHlTY2FsZUZhY3RvcjogMC43NSxcbiAgICAgICAgICBjb250YWluZXJXaWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgICBteDogMC41LFxuICAgICAgICAgICAgbXk6IDAuNVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHdpZHRoID0gZWxlbWVudC53aWR0aCAvIDI7XG4gICAgICAgIHZhciBoZWlnaHQgPSBlbGVtZW50LmhlaWdodCAvIDI7XG5cbiAgICAgICAgZHJhd1BhdGgocGFyZW50R2Z4LCBsaW5lUGF0aERhdGEsIHtcbiAgICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgICBzdHJva2VMaW5lY2FwOiAnc3F1YXJlJyxcbiAgICAgICAgICB0cmFuc2Zvcm06ICdyb3RhdGUoJyArIChpICogMzApICsgJywnICsgaGVpZ2h0ICsgJywnICsgd2lkdGggKyAnKScsXG4gICAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2lyY2xlO1xuICAgIH0sXG4gICAgJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbic6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZXZlbnQsIGlzVGhyb3dpbmcpIHtcbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnRVZFTlRfRVNDQUxBVElPTicsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBldmVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBldmVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNSxcbiAgICAgICAgICBteTogMC4yXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZmlsbCA9IGlzVGhyb3dpbmcgPyBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSA6ICdub25lJztcblxuICAgICAgcmV0dXJuIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGZpbGwsXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50KSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX0NPTkRJVElPTkFMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGV2ZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGV2ZW50LmhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogMC41LFxuICAgICAgICAgIG15OiAwLjIyMlxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbic6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZXZlbnQsIGlzVGhyb3dpbmcpIHtcbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnRVZFTlRfTElOSycsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBldmVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBldmVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNTcsXG4gICAgICAgICAgbXk6IDAuMjYzXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZmlsbCA9IGlzVGhyb3dpbmcgPyBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSA6ICdub25lJztcblxuICAgICAgcmV0dXJuIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGZpbGwsXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgJ2JwbW46RXJyb3JFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50LCBpc1Rocm93aW5nKSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX0VSUk9SJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEuMSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAxLjEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBldmVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBldmVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuMixcbiAgICAgICAgICBteTogMC43MjJcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBmaWxsID0gaXNUaHJvd2luZyA/IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpIDogJ25vbmUnO1xuXG4gICAgICByZXR1cm4gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZmlsbCxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpDYW5jZWxFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50LCBpc1Rocm93aW5nKSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX0NBTkNFTF80NScsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLjAsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMS4wLFxuICAgICAgICBjb250YWluZXJXaWR0aDogZXZlbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZXZlbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjYzOCxcbiAgICAgICAgICBteTogLTAuMDU1XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZmlsbCA9IGlzVGhyb3dpbmcgPyBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSA6ICdub25lJztcblxuICAgICAgdmFyIHBhdGggPSBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBmaWxsLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcm90YXRlKHBhdGgsIDQ1KTtcblxuICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfSxcbiAgICAnYnBtbjpDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBldmVudCwgaXNUaHJvd2luZykge1xuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdFVkVOVF9DT01QRU5TQVRJT04nLCB7XG4gICAgICAgIHhTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAxLFxuICAgICAgICBjb250YWluZXJXaWR0aDogZXZlbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZXZlbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjIyLFxuICAgICAgICAgIG15OiAwLjVcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBmaWxsID0gaXNUaHJvd2luZyA/IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpIDogJ25vbmUnO1xuXG4gICAgICByZXR1cm4gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZmlsbCxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihldmVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50LCBpc1Rocm93aW5nKSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX1NJR05BTCcsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAwLjksXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMC45LFxuICAgICAgICBjb250YWluZXJXaWR0aDogZXZlbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZXZlbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjUsXG4gICAgICAgICAgbXk6IDAuMlxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdmFyIGZpbGwgPSBpc1Rocm93aW5nID8gZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcikgOiAnbm9uZSc7XG5cbiAgICAgIHJldHVybiBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBmaWxsLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdicG1uOk11bHRpcGxlRXZlbnREZWZpbml0aW9uJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBldmVudCwgaXNUaHJvd2luZykge1xuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdFVkVOVF9NVUxUSVBMRScsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLjEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMS4xLFxuICAgICAgICBjb250YWluZXJXaWR0aDogZXZlbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZXZlbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjIyMixcbiAgICAgICAgICBteTogMC4zNlxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdmFyIGZpbGwgPSBpc1Rocm93aW5nID8gZ2V0U3Ryb2tlQ29sb3IoZXZlbnQsIGRlZmF1bHRTdHJva2VDb2xvcikgOiAnbm9uZSc7XG5cbiAgICAgIHJldHVybiBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBmaWxsXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdicG1uOlBhcmFsbGVsTXVsdGlwbGVFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGV2ZW50KSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0VWRU5UX1BBUkFMTEVMX01VTFRJUExFJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEuMixcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAxLjIsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBldmVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBldmVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNDU4LFxuICAgICAgICAgIG15OiAwLjE5NFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGV2ZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdicG1uOkVuZEV2ZW50JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgY2lyY2xlID0gcmVuZGVyZXIoJ2JwbW46RXZlbnQnKShwYXJlbnRHZngsIGVsZW1lbnQsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDQsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmVuZGVyRXZlbnRDb250ZW50KGVsZW1lbnQsIHBhcmVudEdmeCwgdHJ1ZSk7XG5cbiAgICAgIHJldHVybiBjaXJjbGU7XG4gICAgfSxcbiAgICAnYnBtbjpUZXJtaW5hdGVFdmVudERlZmluaXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBjaXJjbGUgPSBkcmF3Q2lyY2xlKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIDgsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDQsXG4gICAgICAgIGZpbGw6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBjaXJjbGU7XG4gICAgfSxcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVFdmVudCc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIG91dGVyID0gcmVuZGVyZXIoJ2JwbW46RXZlbnQnKShwYXJlbnRHZngsIGVsZW1lbnQsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgLyogaW5uZXIgKi9cbiAgICAgIGRyYXdDaXJjbGUocGFyZW50R2Z4LCBlbGVtZW50LndpZHRoLCBlbGVtZW50LmhlaWdodCwgSU5ORVJfT1VURVJfRElTVCwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsICdub25lJyksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJlbmRlckV2ZW50Q29udGVudChlbGVtZW50LCBwYXJlbnRHZngpO1xuXG4gICAgICByZXR1cm4gb3V0ZXI7XG4gICAgfSxcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JzogYXMoJ2JwbW46SW50ZXJtZWRpYXRlRXZlbnQnKSxcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JzogYXMoJ2JwbW46SW50ZXJtZWRpYXRlRXZlbnQnKSxcblxuICAgICdicG1uOkFjdGl2aXR5JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50LCBhdHRycykge1xuXG4gICAgICBhdHRycyA9IGF0dHJzIHx8IHt9O1xuXG4gICAgICBpZiAoISgnZmlsbE9wYWNpdHknIGluIGF0dHJzKSkge1xuICAgICAgICBhdHRycy5maWxsT3BhY2l0eSA9IERFRkFVTFRfRklMTF9PUEFDSVRZO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZHJhd1JlY3QocGFyZW50R2Z4LCBlbGVtZW50LndpZHRoLCBlbGVtZW50LmhlaWdodCwgVEFTS19CT1JERVJfUkFESVVTLCBhdHRycyk7XG4gICAgfSxcblxuICAgICdicG1uOlRhc2snOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH07XG5cbiAgICAgIHZhciByZWN0ID0gcmVuZGVyZXIoJ2JwbW46QWN0aXZpdHknKShwYXJlbnRHZngsIGVsZW1lbnQsIGF0dHJzKTtcblxuICAgICAgcmVuZGVyRW1iZWRkZWRMYWJlbChwYXJlbnRHZngsIGVsZW1lbnQsICdjZW50ZXItbWlkZGxlJyk7XG4gICAgICBhdHRhY2hUYXNrTWFya2VycyhwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICByZXR1cm4gcmVjdDtcbiAgICB9LFxuICAgICdicG1uOlNlcnZpY2VUYXNrJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgdGFzayA9IHJlbmRlcmVyKCdicG1uOlRhc2snKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICB2YXIgcGF0aERhdGFCRyA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX1NFUlZJQ0UnLCB7XG4gICAgICAgIGFic3Bvczoge1xuICAgICAgICAgIHg6IDEyLFxuICAgICAgICAgIHk6IDE4XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKiBzZXJ2aWNlIGJnICovIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGFCRywge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZmlsbFBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdUQVNLX1RZUEVfU0VSVklDRV9GSUxMJywge1xuICAgICAgICBhYnNwb3M6IHtcbiAgICAgICAgICB4OiAxNy4yLFxuICAgICAgICAgIHk6IDE4XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKiBzZXJ2aWNlIGZpbGwgKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBmaWxsUGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDAsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX1NFUlZJQ0UnLCB7XG4gICAgICAgIGFic3Bvczoge1xuICAgICAgICAgIHg6IDE3LFxuICAgICAgICAgIHk6IDIyXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKiBzZXJ2aWNlICovIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRhc2s7XG4gICAgfSxcbiAgICAnYnBtbjpVc2VyVGFzayc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIHRhc2sgPSByZW5kZXJlcignYnBtbjpUYXNrJykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgdmFyIHggPSAxNTtcbiAgICAgIHZhciB5ID0gMTI7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX1VTRVJfMScsIHtcbiAgICAgICAgYWJzcG9zOiB7XG4gICAgICAgICAgeDogeCxcbiAgICAgICAgICB5OiB5XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICAvKiB1c2VyIHBhdGggKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgICBzdHJva2VXaWR0aDogMC41LFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBwYXRoRGF0YTIgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9VU0VSXzInLCB7XG4gICAgICAgIGFic3Bvczoge1xuICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgeTogeVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyogdXNlcjIgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhMiwge1xuICAgICAgICBzdHJva2VXaWR0aDogMC41LFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBwYXRoRGF0YTMgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9VU0VSXzMnLCB7XG4gICAgICAgIGFic3Bvczoge1xuICAgICAgICAgIHg6IHgsXG4gICAgICAgICAgeTogeVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyogdXNlcjMgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhMywge1xuICAgICAgICBzdHJva2VXaWR0aDogMC41LFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdGFzaztcbiAgICB9LFxuICAgICdicG1uOk1hbnVhbFRhc2snOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciB0YXNrID0gcmVuZGVyZXIoJ2JwbW46VGFzaycpKHBhcmVudEdmeCwgZWxlbWVudCk7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX01BTlVBTCcsIHtcbiAgICAgICAgYWJzcG9zOiB7XG4gICAgICAgICAgeDogMTcsXG4gICAgICAgICAgeTogMTVcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qIG1hbnVhbCBwYXRoICovIGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDAuNSwgLy8gMC4yNSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdGFzaztcbiAgICB9LFxuICAgICdicG1uOlNlbmRUYXNrJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgdGFzayA9IHJlbmRlcmVyKCdicG1uOlRhc2snKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9TRU5EJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IDIxLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IDE0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjI4NSxcbiAgICAgICAgICBteTogMC4zNTdcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qIHNlbmQgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0YXNrO1xuICAgIH0sXG4gICAgJ2JwbW46UmVjZWl2ZVRhc2snIDogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgc2VtYW50aWMgPSBnZXRTZW1hbnRpYyhlbGVtZW50KTtcblxuICAgICAgdmFyIHRhc2sgPSByZW5kZXJlcignYnBtbjpUYXNrJykocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICAgIHZhciBwYXRoRGF0YTtcblxuICAgICAgaWYgKHNlbWFudGljLmluc3RhbnRpYXRlKSB7XG4gICAgICAgIGRyYXdDaXJjbGUocGFyZW50R2Z4LCAyOCwgMjgsIDIwICogMC4yMiwgeyBzdHJva2VXaWR0aDogMSB9KTtcblxuICAgICAgICBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEFTS19UWVBFX0lOU1RBTlRJQVRJTkdfU0VORCcsIHtcbiAgICAgICAgICBhYnNwb3M6IHtcbiAgICAgICAgICAgIHg6IDcuNzcsXG4gICAgICAgICAgICB5OiA5LjUyXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9TRU5EJywge1xuICAgICAgICAgIHhTY2FsZUZhY3RvcjogMC45LFxuICAgICAgICAgIHlTY2FsZUZhY3RvcjogMC45LFxuICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiAyMSxcbiAgICAgICAgICBjb250YWluZXJIZWlnaHQ6IDE0LFxuICAgICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgICBteDogMC4zLFxuICAgICAgICAgICAgbXk6IDAuNFxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIC8qIHJlY2VpdmUgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0YXNrO1xuICAgIH0sXG4gICAgJ2JwbW46U2NyaXB0VGFzayc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIHRhc2sgPSByZW5kZXJlcignYnBtbjpUYXNrJykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdUQVNLX1RZUEVfU0NSSVBUJywge1xuICAgICAgICBhYnNwb3M6IHtcbiAgICAgICAgICB4OiAxNSxcbiAgICAgICAgICB5OiAyMFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyogc2NyaXB0IHBhdGggKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRhc2s7XG4gICAgfSxcbiAgICAnYnBtbjpCdXNpbmVzc1J1bGVUYXNrJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgdGFzayA9IHJlbmRlcmVyKCdicG1uOlRhc2snKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICB2YXIgaGVhZGVyUGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RBU0tfVFlQRV9CVVNJTkVTU19SVUxFX0hFQURFUicsIHtcbiAgICAgICAgYWJzcG9zOiB7XG4gICAgICAgICAgeDogOCxcbiAgICAgICAgICB5OiA4XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgYnVzaW5lc3NIZWFkZXJQYXRoID0gZHJhd1BhdGgocGFyZW50R2Z4LCBoZWFkZXJQYXRoRGF0YSk7XG4gICAgICBzdmdBdHRyKGJ1c2luZXNzSGVhZGVyUGF0aCwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsICcjYWFhYWFhJyksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBoZWFkZXJEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdUQVNLX1RZUEVfQlVTSU5FU1NfUlVMRV9NQUlOJywge1xuICAgICAgICBhYnNwb3M6IHtcbiAgICAgICAgICB4OiA4LFxuICAgICAgICAgIHk6IDhcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBidXNpbmVzc1BhdGggPSBkcmF3UGF0aChwYXJlbnRHZngsIGhlYWRlckRhdGEpO1xuICAgICAgc3ZnQXR0cihidXNpbmVzc1BhdGgsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0YXNrO1xuICAgIH0sXG4gICAgJ2JwbW46U3ViUHJvY2Vzcyc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCwgYXR0cnMpIHtcbiAgICAgIGF0dHJzID0gYXNzaWduKHtcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0sIGF0dHJzKTtcblxuICAgICAgdmFyIHJlY3QgPSByZW5kZXJlcignYnBtbjpBY3Rpdml0eScpKHBhcmVudEdmeCwgZWxlbWVudCwgYXR0cnMpO1xuXG4gICAgICB2YXIgZXhwYW5kZWQgPSBpc0V4cGFuZGVkKGVsZW1lbnQpO1xuXG4gICAgICBpZiAoaXNFdmVudFN1YlByb2Nlc3MoZWxlbWVudCkpIHtcbiAgICAgICAgc3ZnQXR0cihyZWN0LCB7XG4gICAgICAgICAgc3Ryb2tlRGFzaGFycmF5OiAnMSwyJ1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmVuZGVyRW1iZWRkZWRMYWJlbChwYXJlbnRHZngsIGVsZW1lbnQsIGV4cGFuZGVkID8gJ2NlbnRlci10b3AnIDogJ2NlbnRlci1taWRkbGUnKTtcblxuICAgICAgaWYgKGV4cGFuZGVkKSB7XG4gICAgICAgIGF0dGFjaFRhc2tNYXJrZXJzKHBhcmVudEdmeCwgZWxlbWVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhdHRhY2hUYXNrTWFya2VycyhwYXJlbnRHZngsIGVsZW1lbnQsIFsnU3ViUHJvY2Vzc01hcmtlciddKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlY3Q7XG4gICAgfSxcbiAgICAnYnBtbjpBZEhvY1N1YlByb2Nlc3MnOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpTdWJQcm9jZXNzJykocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICB9LFxuICAgICdicG1uOlRyYW5zYWN0aW9uJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgb3V0ZXIgPSByZW5kZXJlcignYnBtbjpTdWJQcm9jZXNzJykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgdmFyIGlubmVyQXR0cnMgPSBzdHlsZXMuc3R5bGUoWyAnbm8tZmlsbCcsICduby1ldmVudHMnIF0sIHtcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgLyogaW5uZXIgcGF0aCAqLyBkcmF3UmVjdChwYXJlbnRHZngsIGVsZW1lbnQud2lkdGgsIGVsZW1lbnQuaGVpZ2h0LCBUQVNLX0JPUkRFUl9SQURJVVMgLSAyLCBJTk5FUl9PVVRFUl9ESVNULCBpbm5lckF0dHJzKTtcblxuICAgICAgcmV0dXJuIG91dGVyO1xuICAgIH0sXG4gICAgJ2JwbW46Q2FsbEFjdGl2aXR5JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICByZXR1cm4gcmVuZGVyZXIoJ2JwbW46U3ViUHJvY2VzcycpKHBhcmVudEdmeCwgZWxlbWVudCwge1xuICAgICAgICBzdHJva2VXaWR0aDogNVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpQYXJ0aWNpcGFudCc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuXG4gICAgICB2YXIgYXR0cnMgPSB7XG4gICAgICAgIGZpbGxPcGFjaXR5OiBERUZBVUxUX0ZJTExfT1BBQ0lUWSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH07XG5cbiAgICAgIHZhciBsYW5lID0gcmVuZGVyZXIoJ2JwbW46TGFuZScpKHBhcmVudEdmeCwgZWxlbWVudCwgYXR0cnMpO1xuXG4gICAgICB2YXIgZXhwYW5kZWRQb29sID0gaXNFeHBhbmRlZChlbGVtZW50KTtcblxuICAgICAgaWYgKGV4cGFuZGVkUG9vbCkge1xuICAgICAgICBkcmF3TGluZShwYXJlbnRHZngsIFtcbiAgICAgICAgICB7IHg6IDMwLCB5OiAwIH0sXG4gICAgICAgICAgeyB4OiAzMCwgeTogZWxlbWVudC5oZWlnaHQgfVxuICAgICAgICBdLCB7XG4gICAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICAgIH0pO1xuICAgICAgICB2YXIgdGV4dCA9IGdldFNlbWFudGljKGVsZW1lbnQpLm5hbWU7XG4gICAgICAgIHJlbmRlckxhbmVMYWJlbChwYXJlbnRHZngsIHRleHQsIGVsZW1lbnQpO1xuICAgICAgfSBlbHNlIHtcblxuICAgICAgICAvLyBDb2xsYXBzZWQgcG9vbCBkcmF3IHRleHQgaW5saW5lXG4gICAgICAgIHZhciB0ZXh0MiA9IGdldFNlbWFudGljKGVsZW1lbnQpLm5hbWU7XG4gICAgICAgIHJlbmRlckxhYmVsKHBhcmVudEdmeCwgdGV4dDIsIHtcbiAgICAgICAgICBib3g6IGVsZW1lbnQsIGFsaWduOiAnY2VudGVyLW1pZGRsZScsXG4gICAgICAgICAgc3R5bGU6IHtcbiAgICAgICAgICAgIGZpbGw6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB2YXIgcGFydGljaXBhbnRNdWx0aXBsaWNpdHkgPSAhIShnZXRTZW1hbnRpYyhlbGVtZW50KS5wYXJ0aWNpcGFudE11bHRpcGxpY2l0eSk7XG5cbiAgICAgIGlmIChwYXJ0aWNpcGFudE11bHRpcGxpY2l0eSkge1xuICAgICAgICByZW5kZXJlcignUGFydGljaXBhbnRNdWx0aXBsaWNpdHlNYXJrZXInKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbGFuZTtcbiAgICB9LFxuICAgICdicG1uOkxhbmUnOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIGF0dHJzKSB7XG4gICAgICB2YXIgcmVjdCA9IGRyYXdSZWN0KHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIDAsIGFzc2lnbih7XG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgZmlsbE9wYWNpdHk6IEhJR0hfRklMTF9PUEFDSVRZLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0sIGF0dHJzKSk7XG5cbiAgICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgICBpZiAoc2VtYW50aWMuJHR5cGUgPT09ICdicG1uOkxhbmUnKSB7XG4gICAgICAgIHZhciB0ZXh0ID0gc2VtYW50aWMubmFtZTtcbiAgICAgICAgcmVuZGVyTGFuZUxhYmVsKHBhcmVudEdmeCwgdGV4dCwgZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZWN0O1xuICAgIH0sXG4gICAgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheSc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIGRpYW1vbmQgPSByZW5kZXJlcignYnBtbjpHYXRld2F5JykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgLyogY2lyY2xlIHBhdGggKi9cbiAgICAgIGRyYXdDaXJjbGUocGFyZW50R2Z4LCBlbGVtZW50LndpZHRoLCBlbGVtZW50LmhlaWdodCwgZWxlbWVudC5oZWlnaHQgKiAwLjI0LCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAyLjUsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGRpYW1vbmQ7XG4gICAgfSxcbiAgICAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgZGlhbW9uZCA9IHJlbmRlcmVyKCdicG1uOkdhdGV3YXknKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0dBVEVXQVlfRVhDTFVTSVZFJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDAuNCxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAwLjQsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjMyLFxuICAgICAgICAgIG15OiAwLjNcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGlmICgoZ2V0RGkoZWxlbWVudCkuaXNNYXJrZXJWaXNpYmxlKSkge1xuICAgICAgICBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgICAgZmlsbDogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSxcbiAgICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBkaWFtb25kO1xuICAgIH0sXG4gICAgJ2JwbW46Q29tcGxleEdhdGV3YXknOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBkaWFtb25kID0gcmVuZGVyZXIoJ2JwbW46R2F0ZXdheScpKHBhcmVudEdmeCwgZWxlbWVudCk7XG5cbiAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnR0FURVdBWV9DT01QTEVYJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDAuNSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOjAuNSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNDYsXG4gICAgICAgICAgbXk6IDAuMjZcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8qIGNvbXBsZXggcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gZGlhbW9uZDtcbiAgICB9LFxuICAgICdicG1uOlBhcmFsbGVsR2F0ZXdheSc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIGRpYW1vbmQgPSByZW5kZXJlcignYnBtbjpHYXRld2F5JykocGFyZW50R2Z4LCBlbGVtZW50KTtcblxuICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdHQVRFV0FZX1BBUkFMTEVMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDAuNixcbiAgICAgICAgeVNjYWxlRmFjdG9yOjAuNixcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuNDYsXG4gICAgICAgICAgbXk6IDAuMlxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgLyogcGFyYWxsZWwgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gZGlhbW9uZDtcbiAgICB9LFxuICAgICdicG1uOkV2ZW50QmFzZWRHYXRld2F5JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG5cbiAgICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgICB2YXIgZGlhbW9uZCA9IHJlbmRlcmVyKCdicG1uOkdhdGV3YXknKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICAvKiBvdXRlciBjaXJjbGUgcGF0aCAqLyBkcmF3Q2lyY2xlKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIGVsZW1lbnQuaGVpZ2h0ICogMC4yMCwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogJ25vbmUnLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgdHlwZSA9IHNlbWFudGljLmV2ZW50R2F0ZXdheVR5cGU7XG4gICAgICB2YXIgaW5zdGFudGlhdGUgPSAhIXNlbWFudGljLmluc3RhbnRpYXRlO1xuXG4gICAgICBmdW5jdGlvbiBkcmF3RXZlbnQoKSB7XG5cbiAgICAgICAgdmFyIHBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdHQVRFV0FZX0VWRU5UX0JBU0VEJywge1xuICAgICAgICAgIHhTY2FsZUZhY3RvcjogMC4xOCxcbiAgICAgICAgICB5U2NhbGVGYWN0b3I6IDAuMTgsXG4gICAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgICAgY29udGFpbmVySGVpZ2h0OiBlbGVtZW50LmhlaWdodCxcbiAgICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgICAgbXg6IDAuMzYsXG4gICAgICAgICAgICBteTogMC40NFxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIGF0dHJzID0ge1xuICAgICAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCAnbm9uZScpLFxuICAgICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qIGV2ZW50IHBhdGggKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwgYXR0cnMpO1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZSA9PT0gJ1BhcmFsbGVsJykge1xuXG4gICAgICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnR0FURVdBWV9QQVJBTExFTCcsIHtcbiAgICAgICAgICB4U2NhbGVGYWN0b3I6IDAuNCxcbiAgICAgICAgICB5U2NhbGVGYWN0b3I6MC40LFxuICAgICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICAgIG14OiAwLjQ3NCxcbiAgICAgICAgICAgIG15OiAwLjI5NlxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHBhcmFsbGVsUGF0aCA9IGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEpO1xuICAgICAgICBzdmdBdHRyKHBhcmFsbGVsUGF0aCwge1xuICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICAgIGZpbGw6ICdub25lJ1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ0V4Y2x1c2l2ZScpIHtcblxuICAgICAgICBpZiAoIWluc3RhbnRpYXRlKSB7XG4gICAgICAgICAgdmFyIGlubmVyQ2lyY2xlID0gZHJhd0NpcmNsZShwYXJlbnRHZngsIGVsZW1lbnQud2lkdGgsIGVsZW1lbnQuaGVpZ2h0LCBlbGVtZW50LmhlaWdodCAqIDAuMjYpO1xuICAgICAgICAgIHN2Z0F0dHIoaW5uZXJDaXJjbGUsIHtcbiAgICAgICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICAgICAgZmlsbDogJ25vbmUnLFxuICAgICAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBkcmF3RXZlbnQoKTtcbiAgICAgIH1cblxuXG4gICAgICByZXR1cm4gZGlhbW9uZDtcbiAgICB9LFxuICAgICdicG1uOkdhdGV3YXknOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBmaWxsT3BhY2l0eTogREVGQVVMVF9GSUxMX09QQUNJVFksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfTtcblxuICAgICAgcmV0dXJuIGRyYXdEaWFtb25kKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIGF0dHJzKTtcbiAgICB9LFxuICAgICdicG1uOlNlcXVlbmNlRmxvdyc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIHBhdGhEYXRhID0gY3JlYXRlUGF0aEZyb21Db25uZWN0aW9uKGVsZW1lbnQpO1xuXG4gICAgICB2YXIgZmlsbCA9IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgICBzdHJva2UgPSBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpO1xuXG4gICAgICB2YXIgYXR0cnMgPSB7XG4gICAgICAgIHN0cm9rZUxpbmVqb2luOiAncm91bmQnLFxuICAgICAgICBtYXJrZXJFbmQ6IG1hcmtlcignc2VxdWVuY2VmbG93LWVuZCcsIGZpbGwsIHN0cm9rZSksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfTtcblxuICAgICAgdmFyIHBhdGggPSBkcmF3UGF0aChwYXJlbnRHZngsIHBhdGhEYXRhLCBhdHRycyk7XG5cbiAgICAgIHZhciBzZXF1ZW5jZUZsb3cgPSBnZXRTZW1hbnRpYyhlbGVtZW50KTtcblxuICAgICAgdmFyIHNvdXJjZTtcblxuICAgICAgaWYgKGVsZW1lbnQuc291cmNlKSB7XG4gICAgICAgIHNvdXJjZSA9IGVsZW1lbnQuc291cmNlLmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgICAgIC8vIGNvbmRpdGlvbmFsIGZsb3cgbWFya2VyXG4gICAgICAgIGlmIChzZXF1ZW5jZUZsb3cuY29uZGl0aW9uRXhwcmVzc2lvbiAmJiBzb3VyY2UuJGluc3RhbmNlT2YoJ2JwbW46QWN0aXZpdHknKSkge1xuICAgICAgICAgIHN2Z0F0dHIocGF0aCwge1xuICAgICAgICAgICAgbWFya2VyU3RhcnQ6IG1hcmtlcignY29uZGl0aW9uYWwtZmxvdy1tYXJrZXInLCBmaWxsLCBzdHJva2UpXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBkZWZhdWx0IG1hcmtlclxuICAgICAgICBpZiAoc291cmNlLmRlZmF1bHQgJiYgKHNvdXJjZS4kaW5zdGFuY2VPZignYnBtbjpHYXRld2F5JykgfHwgc291cmNlLiRpbnN0YW5jZU9mKCdicG1uOkFjdGl2aXR5JykpICYmXG4gICAgICAgICAgICBzb3VyY2UuZGVmYXVsdCA9PT0gc2VxdWVuY2VGbG93KSB7XG4gICAgICAgICAgc3ZnQXR0cihwYXRoLCB7XG4gICAgICAgICAgICBtYXJrZXJTdGFydDogbWFya2VyKCdjb25kaXRpb25hbC1kZWZhdWx0LWZsb3ctbWFya2VyJywgZmlsbCwgc3Ryb2tlKVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXRoO1xuICAgIH0sXG4gICAgJ2JwbW46QXNzb2NpYXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIGF0dHJzKSB7XG5cbiAgICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgICB2YXIgZmlsbCA9IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgICBzdHJva2UgPSBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpO1xuXG4gICAgICBhdHRycyA9IGFzc2lnbih7XG4gICAgICAgIHN0cm9rZURhc2hhcnJheTogJzAuNSwgNScsXG4gICAgICAgIHN0cm9rZUxpbmVjYXA6ICdyb3VuZCcsXG4gICAgICAgIHN0cm9rZUxpbmVqb2luOiAncm91bmQnLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0sIGF0dHJzIHx8IHt9KTtcblxuICAgICAgaWYgKHNlbWFudGljLmFzc29jaWF0aW9uRGlyZWN0aW9uID09PSAnT25lJyB8fFxuICAgICAgICAgIHNlbWFudGljLmFzc29jaWF0aW9uRGlyZWN0aW9uID09PSAnQm90aCcpIHtcbiAgICAgICAgYXR0cnMubWFya2VyRW5kID0gbWFya2VyKCdhc3NvY2lhdGlvbi1lbmQnLCBmaWxsLCBzdHJva2UpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc2VtYW50aWMuYXNzb2NpYXRpb25EaXJlY3Rpb24gPT09ICdCb3RoJykge1xuICAgICAgICBhdHRycy5tYXJrZXJTdGFydCA9IG1hcmtlcignYXNzb2NpYXRpb24tc3RhcnQnLCBmaWxsLCBzdHJva2UpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gZHJhd0xpbmUocGFyZW50R2Z4LCBlbGVtZW50LndheXBvaW50cywgYXR0cnMpO1xuICAgIH0sXG4gICAgJ2JwbW46RGF0YUlucHV0QXNzb2NpYXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBmaWxsID0gZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICAgIHN0cm9rZSA9IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcik7XG5cbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpBc3NvY2lhdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwge1xuICAgICAgICBtYXJrZXJFbmQ6IG1hcmtlcignYXNzb2NpYXRpb24tZW5kJywgZmlsbCwgc3Ryb2tlKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpEYXRhT3V0cHV0QXNzb2NpYXRpb24nOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBmaWxsID0gZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICAgIHN0cm9rZSA9IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcik7XG5cbiAgICAgIHJldHVybiByZW5kZXJlcignYnBtbjpBc3NvY2lhdGlvbicpKHBhcmVudEdmeCwgZWxlbWVudCwge1xuICAgICAgICBtYXJrZXJFbmQ6IG1hcmtlcignYXNzb2NpYXRpb24tZW5kJywgZmlsbCwgc3Ryb2tlKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnYnBtbjpNZXNzYWdlRmxvdyc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuXG4gICAgICB2YXIgc2VtYW50aWMgPSBnZXRTZW1hbnRpYyhlbGVtZW50KSxcbiAgICAgICAgICBkaSA9IGdldERpKGVsZW1lbnQpO1xuXG4gICAgICB2YXIgZmlsbCA9IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgICBzdHJva2UgPSBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpO1xuXG4gICAgICB2YXIgcGF0aERhdGEgPSBjcmVhdGVQYXRoRnJvbUNvbm5lY3Rpb24oZWxlbWVudCk7XG5cbiAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgbWFya2VyRW5kOiBtYXJrZXIoJ21lc3NhZ2VmbG93LWVuZCcsIGZpbGwsIHN0cm9rZSksXG4gICAgICAgIG1hcmtlclN0YXJ0OiBtYXJrZXIoJ21lc3NhZ2VmbG93LXN0YXJ0JywgZmlsbCwgc3Ryb2tlKSxcbiAgICAgICAgc3Ryb2tlRGFzaGFycmF5OiAnMTAsIDEyJyxcbiAgICAgICAgc3Ryb2tlTGluZWNhcDogJ3JvdW5kJyxcbiAgICAgICAgc3Ryb2tlTGluZWpvaW46ICdyb3VuZCcsXG4gICAgICAgIHN0cm9rZVdpZHRoOiAnMS41cHgnLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH07XG5cbiAgICAgIHZhciBwYXRoID0gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwgYXR0cnMpO1xuXG4gICAgICBpZiAoc2VtYW50aWMubWVzc2FnZVJlZikge1xuICAgICAgICB2YXIgbWlkUG9pbnQgPSBwYXRoLmdldFBvaW50QXRMZW5ndGgocGF0aC5nZXRUb3RhbExlbmd0aCgpIC8gMik7XG5cbiAgICAgICAgdmFyIG1hcmtlclBhdGhEYXRhID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdNRVNTQUdFX0ZMT1dfTUFSS0VSJywge1xuICAgICAgICAgIGFic3Bvczoge1xuICAgICAgICAgICAgeDogbWlkUG9pbnQueCxcbiAgICAgICAgICAgIHk6IG1pZFBvaW50LnlcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHZhciBtZXNzYWdlQXR0cnMgPSB7IHN0cm9rZVdpZHRoOiAxIH07XG5cbiAgICAgICAgaWYgKGRpLm1lc3NhZ2VWaXNpYmxlS2luZCA9PT0gJ2luaXRpYXRpbmcnKSB7XG4gICAgICAgICAgbWVzc2FnZUF0dHJzLmZpbGwgPSAnd2hpdGUnO1xuICAgICAgICAgIG1lc3NhZ2VBdHRycy5zdHJva2UgPSAnYmxhY2snO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG1lc3NhZ2VBdHRycy5maWxsID0gJyM4ODgnO1xuICAgICAgICAgIG1lc3NhZ2VBdHRycy5zdHJva2UgPSAnd2hpdGUnO1xuICAgICAgICB9XG5cbiAgICAgICAgZHJhd1BhdGgocGFyZW50R2Z4LCBtYXJrZXJQYXRoRGF0YSwgbWVzc2FnZUF0dHJzKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHBhdGg7XG4gICAgfSxcbiAgICAnYnBtbjpEYXRhT2JqZWN0JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgcGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ0RBVEFfT0JKRUNUX1BBVEgnLCB7XG4gICAgICAgIHhTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgeVNjYWxlRmFjdG9yOiAxLFxuICAgICAgICBjb250YWluZXJXaWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBlbGVtZW50LmhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogMC40NzQsXG4gICAgICAgICAgbXk6IDAuMjk2XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZWxlbWVudE9iamVjdCA9IGRyYXdQYXRoKHBhcmVudEdmeCwgcGF0aERhdGEsIHtcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBmaWxsT3BhY2l0eTogREVGQVVMVF9GSUxMX09QQUNJVFksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIHZhciBzZW1hbnRpYyA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgICBpZiAoaXNDb2xsZWN0aW9uKHNlbWFudGljKSkge1xuICAgICAgICByZW5kZXJEYXRhSXRlbUNvbGxlY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGVsZW1lbnRPYmplY3Q7XG4gICAgfSxcbiAgICAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJzogYXMoJ2JwbW46RGF0YU9iamVjdCcpLFxuICAgICdicG1uOkRhdGFJbnB1dCc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuXG4gICAgICB2YXIgYXJyb3dQYXRoRGF0YSA9IHBhdGhNYXAuZ2V0UmF3UGF0aCgnREFUQV9BUlJPVycpO1xuXG4gICAgICAvLyBwYWdlXG4gICAgICB2YXIgZWxlbWVudE9iamVjdCA9IHJlbmRlcmVyKCdicG1uOkRhdGFPYmplY3QnKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICAvKiBpbnB1dCBhcnJvdyBwYXRoICovIGRyYXdQYXRoKHBhcmVudEdmeCwgYXJyb3dQYXRoRGF0YSwgeyBzdHJva2VXaWR0aDogMSB9KTtcblxuICAgICAgcmV0dXJuIGVsZW1lbnRPYmplY3Q7XG4gICAgfSxcbiAgICAnYnBtbjpEYXRhT3V0cHV0JzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgYXJyb3dQYXRoRGF0YSA9IHBhdGhNYXAuZ2V0UmF3UGF0aCgnREFUQV9BUlJPVycpO1xuXG4gICAgICAvLyBwYWdlXG4gICAgICB2YXIgZWxlbWVudE9iamVjdCA9IHJlbmRlcmVyKCdicG1uOkRhdGFPYmplY3QnKShwYXJlbnRHZngsIGVsZW1lbnQpO1xuXG4gICAgICAvKiBvdXRwdXQgYXJyb3cgcGF0aCAqLyBkcmF3UGF0aChwYXJlbnRHZngsIGFycm93UGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6ICdibGFjaydcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gZWxlbWVudE9iamVjdDtcbiAgICB9LFxuICAgICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZSc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgdmFyIERBVEFfU1RPUkVfUEFUSCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnREFUQV9TVE9SRScsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLFxuICAgICAgICAgIG15OiAwLjEzM1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgdmFyIGVsZW1lbnRTdG9yZSA9IGRyYXdQYXRoKHBhcmVudEdmeCwgREFUQV9TVE9SRV9QQVRILCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAyLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIGZpbGxPcGFjaXR5OiBERUZBVUxUX0ZJTExfT1BBQ0lUWSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIGVsZW1lbnRTdG9yZTtcbiAgICB9LFxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcblxuICAgICAgdmFyIHNlbWFudGljID0gZ2V0U2VtYW50aWMoZWxlbWVudCksXG4gICAgICAgICAgY2FuY2VsID0gc2VtYW50aWMuY2FuY2VsQWN0aXZpdHk7XG5cbiAgICAgIHZhciBhdHRycyA9IHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9O1xuXG4gICAgICBpZiAoIWNhbmNlbCkge1xuICAgICAgICBhdHRycy5zdHJva2VEYXNoYXJyYXkgPSAnNic7XG4gICAgICAgIGF0dHJzLnN0cm9rZUxpbmVjYXAgPSAncm91bmQnO1xuICAgICAgfVxuXG4gICAgICAvLyBhcHBseSBmaWxsT3BhY2l0eVxuICAgICAgdmFyIG91dGVyQXR0cnMgPSBhc3NpZ24oe30sIGF0dHJzLCB7XG4gICAgICAgIGZpbGxPcGFjaXR5OiAxXG4gICAgICB9KTtcblxuICAgICAgLy8gYXBwbHkgbm8tZmlsbFxuICAgICAgdmFyIGlubmVyQXR0cnMgPSBhc3NpZ24oe30sIGF0dHJzLCB7XG4gICAgICAgIGZpbGw6ICdub25lJ1xuICAgICAgfSk7XG5cbiAgICAgIHZhciBvdXRlciA9IHJlbmRlcmVyKCdicG1uOkV2ZW50JykocGFyZW50R2Z4LCBlbGVtZW50LCBvdXRlckF0dHJzKTtcblxuICAgICAgLyogaW5uZXIgcGF0aCAqLyBkcmF3Q2lyY2xlKHBhcmVudEdmeCwgZWxlbWVudC53aWR0aCwgZWxlbWVudC5oZWlnaHQsIElOTkVSX09VVEVSX0RJU1QsIGlubmVyQXR0cnMpO1xuXG4gICAgICByZW5kZXJFdmVudENvbnRlbnQoZWxlbWVudCwgcGFyZW50R2Z4KTtcblxuICAgICAgcmV0dXJuIG91dGVyO1xuICAgIH0sXG4gICAgJ2JwbW46R3JvdXAnOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcblxuICAgICAgdmFyIGdyb3VwID0gZHJhd1JlY3QocGFyZW50R2Z4LCBlbGVtZW50LndpZHRoLCBlbGVtZW50LmhlaWdodCwgVEFTS19CT1JERVJfUkFESVVTLCB7XG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKSxcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIHN0cm9rZURhc2hhcnJheTogJzgsMywxLDMnLFxuICAgICAgICBmaWxsOiAnbm9uZScsXG4gICAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJ1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiBncm91cDtcbiAgICB9LFxuICAgICdsYWJlbCc6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCkge1xuICAgICAgcmV0dXJuIHJlbmRlckV4dGVybmFsTGFiZWwocGFyZW50R2Z4LCBlbGVtZW50KTtcbiAgICB9LFxuICAgICdicG1uOlRleHRBbm5vdGF0aW9uJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgc3R5bGUgPSB7XG4gICAgICAgICdmaWxsJzogJ25vbmUnLFxuICAgICAgICAnc3Ryb2tlJzogJ25vbmUnXG4gICAgICB9O1xuXG4gICAgICB2YXIgdGV4dEVsZW1lbnQgPSBkcmF3UmVjdChwYXJlbnRHZngsIGVsZW1lbnQud2lkdGgsIGVsZW1lbnQuaGVpZ2h0LCAwLCAwLCBzdHlsZSk7XG5cbiAgICAgIHZhciB0ZXh0UGF0aERhdGEgPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ1RFWFRfQU5OT1RBVElPTicsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAwLjAsXG4gICAgICAgICAgbXk6IDAuMFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZHJhd1BhdGgocGFyZW50R2Z4LCB0ZXh0UGF0aERhdGEsIHtcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcblxuICAgICAgdmFyIHRleHQgPSBnZXRTZW1hbnRpYyhlbGVtZW50KS50ZXh0IHx8ICcnO1xuICAgICAgcmVuZGVyTGFiZWwocGFyZW50R2Z4LCB0ZXh0LCB7XG4gICAgICAgIGJveDogZWxlbWVudCxcbiAgICAgICAgYWxpZ246ICdsZWZ0LXRvcCcsXG4gICAgICAgIHBhZGRpbmc6IDUsXG4gICAgICAgIHN0eWxlOiB7XG4gICAgICAgICAgZmlsbDogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuIHRleHRFbGVtZW50O1xuICAgIH0sXG4gICAgJ1BhcnRpY2lwYW50TXVsdGlwbGljaXR5TWFya2VyJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgbWFya2VyUGF0aCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnTUFSS0VSX1BBUkFMTEVMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6ICgoZWxlbWVudC53aWR0aCAvIDIpIC8gZWxlbWVudC53aWR0aCksXG4gICAgICAgICAgbXk6IChlbGVtZW50LmhlaWdodCAtIDE1KSAvIGVsZW1lbnQuaGVpZ2h0XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBkcmF3TWFya2VyKCdwYXJ0aWNpcGFudC1tdWx0aXBsaWNpdHknLCBwYXJlbnRHZngsIG1hcmtlclBhdGgsIHtcbiAgICAgICAgc3Ryb2tlV2lkdGg6IDEsXG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdTdWJQcm9jZXNzTWFya2VyJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gICAgICB2YXIgbWFya2VyUmVjdCA9IGRyYXdSZWN0KHBhcmVudEdmeCwgMTQsIDE0LCAwLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG5cbiAgICAgIC8vIFByb2Nlc3MgbWFya2VyIGlzIHBsYWNlZCBpbiB0aGUgbWlkZGxlIG9mIHRoZSBib3hcbiAgICAgIC8vIHRoZXJlZm9yZSBmaXhlZCB2YWx1ZXMgY2FuIGJlIHVzZWQgaGVyZVxuICAgICAgdHJhbnNsYXRlKG1hcmtlclJlY3QsIGVsZW1lbnQud2lkdGggLyAyIC0gNy41LCBlbGVtZW50LmhlaWdodCAtIDIwKTtcblxuICAgICAgdmFyIG1hcmtlclBhdGggPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ01BUktFUl9TVUJfUFJPQ0VTUycsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLjUsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMS41LFxuICAgICAgICBjb250YWluZXJXaWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgY29udGFpbmVySGVpZ2h0OiBlbGVtZW50LmhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogKGVsZW1lbnQud2lkdGggLyAyIC0gNy41KSAvIGVsZW1lbnQud2lkdGgsXG4gICAgICAgICAgbXk6IChlbGVtZW50LmhlaWdodCAtIDIwKSAvIGVsZW1lbnQuaGVpZ2h0XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBkcmF3TWFya2VyKCdzdWItcHJvY2VzcycsIHBhcmVudEdmeCwgbWFya2VyUGF0aCwge1xuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnUGFyYWxsZWxNYXJrZXInOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIHBvc2l0aW9uKSB7XG4gICAgICB2YXIgbWFya2VyUGF0aCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnTUFSS0VSX1BBUkFMTEVMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6ICgoZWxlbWVudC53aWR0aCAvIDIgKyBwb3NpdGlvbi5wYXJhbGxlbCkgLyBlbGVtZW50LndpZHRoKSxcbiAgICAgICAgICBteTogKGVsZW1lbnQuaGVpZ2h0IC0gMjApIC8gZWxlbWVudC5oZWlnaHRcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGRyYXdNYXJrZXIoJ3BhcmFsbGVsJywgcGFyZW50R2Z4LCBtYXJrZXJQYXRoLCB7XG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdTZXF1ZW50aWFsTWFya2VyJzogZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50LCBwb3NpdGlvbikge1xuICAgICAgdmFyIG1hcmtlclBhdGggPSBwYXRoTWFwLmdldFNjYWxlZFBhdGgoJ01BUktFUl9TRVFVRU5USUFMJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6ICgoZWxlbWVudC53aWR0aCAvIDIgKyBwb3NpdGlvbi5zZXEpIC8gZWxlbWVudC53aWR0aCksXG4gICAgICAgICAgbXk6IChlbGVtZW50LmhlaWdodCAtIDE5KSAvIGVsZW1lbnQuaGVpZ2h0XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBkcmF3TWFya2VyKCdzZXF1ZW50aWFsJywgcGFyZW50R2Z4LCBtYXJrZXJQYXRoLCB7XG4gICAgICAgIGZpbGw6IGdldEZpbGxDb2xvcihlbGVtZW50LCBkZWZhdWx0RmlsbENvbG9yKSxcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpXG4gICAgICB9KTtcbiAgICB9LFxuICAgICdDb21wZW5zYXRpb25NYXJrZXInOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIHBvc2l0aW9uKSB7XG4gICAgICB2YXIgbWFya2VyTWF0aCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnTUFSS0VSX0NPTVBFTlNBVElPTicsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAoKGVsZW1lbnQud2lkdGggLyAyICsgcG9zaXRpb24uY29tcGVuc2F0aW9uKSAvIGVsZW1lbnQud2lkdGgpLFxuICAgICAgICAgIG15OiAoZWxlbWVudC5oZWlnaHQgLSAxMykgLyBlbGVtZW50LmhlaWdodFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZHJhd01hcmtlcignY29tcGVuc2F0aW9uJywgcGFyZW50R2Z4LCBtYXJrZXJNYXRoLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRGaWxsQ29sb3IoZWxlbWVudCwgZGVmYXVsdEZpbGxDb2xvciksXG4gICAgICAgIHN0cm9rZTogZ2V0U3Ryb2tlQ29sb3IoZWxlbWVudCwgZGVmYXVsdFN0cm9rZUNvbG9yKVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnTG9vcE1hcmtlcic6IGZ1bmN0aW9uKHBhcmVudEdmeCwgZWxlbWVudCwgcG9zaXRpb24pIHtcbiAgICAgIHZhciBtYXJrZXJQYXRoID0gcGF0aE1hcC5nZXRTY2FsZWRQYXRoKCdNQVJLRVJfTE9PUCcsIHtcbiAgICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgICB5U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIGNvbnRhaW5lcldpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIG14OiAoKGVsZW1lbnQud2lkdGggLyAyICsgcG9zaXRpb24ubG9vcCkgLyBlbGVtZW50LndpZHRoKSxcbiAgICAgICAgICBteTogKGVsZW1lbnQuaGVpZ2h0IC0gNykgLyBlbGVtZW50LmhlaWdodFxuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgICAgZHJhd01hcmtlcignbG9vcCcsIHBhcmVudEdmeCwgbWFya2VyUGF0aCwge1xuICAgICAgICBzdHJva2VXaWR0aDogMSxcbiAgICAgICAgZmlsbDogZ2V0RmlsbENvbG9yKGVsZW1lbnQsIGRlZmF1bHRGaWxsQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvciksXG4gICAgICAgIHN0cm9rZUxpbmVjYXA6ICdyb3VuZCcsXG4gICAgICAgIHN0cm9rZU1pdGVybGltaXQ6IDAuNVxuICAgICAgfSk7XG4gICAgfSxcbiAgICAnQWRob2NNYXJrZXInOiBmdW5jdGlvbihwYXJlbnRHZngsIGVsZW1lbnQsIHBvc2l0aW9uKSB7XG4gICAgICB2YXIgbWFya2VyUGF0aCA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnTUFSS0VSX0FESE9DJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6ICgoZWxlbWVudC53aWR0aCAvIDIgKyBwb3NpdGlvbi5hZGhvYykgLyBlbGVtZW50LndpZHRoKSxcbiAgICAgICAgICBteTogKGVsZW1lbnQuaGVpZ2h0IC0gMTUpIC8gZWxlbWVudC5oZWlnaHRcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIGRyYXdNYXJrZXIoJ2FkaG9jJywgcGFyZW50R2Z4LCBtYXJrZXJQYXRoLCB7XG4gICAgICAgIHN0cm9rZVdpZHRoOiAxLFxuICAgICAgICBmaWxsOiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0U3Ryb2tlQ29sb3IpLFxuICAgICAgICBzdHJva2U6IGdldFN0cm9rZUNvbG9yKGVsZW1lbnQsIGRlZmF1bHRTdHJva2VDb2xvcilcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBhdHRhY2hUYXNrTWFya2VycyhwYXJlbnRHZngsIGVsZW1lbnQsIHRhc2tNYXJrZXJzKSB7XG4gICAgdmFyIG9iaiA9IGdldFNlbWFudGljKGVsZW1lbnQpO1xuXG4gICAgdmFyIHN1YnByb2Nlc3MgPSB0YXNrTWFya2VycyAmJiB0YXNrTWFya2Vycy5pbmRleE9mKCdTdWJQcm9jZXNzTWFya2VyJykgIT09IC0xO1xuICAgIHZhciBwb3NpdGlvbjtcblxuICAgIGlmIChzdWJwcm9jZXNzKSB7XG4gICAgICBwb3NpdGlvbiA9IHtcbiAgICAgICAgc2VxOiAtMjEsXG4gICAgICAgIHBhcmFsbGVsOiAtMjIsXG4gICAgICAgIGNvbXBlbnNhdGlvbjogLTQyLFxuICAgICAgICBsb29wOiAtMTgsXG4gICAgICAgIGFkaG9jOiAxMFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgcG9zaXRpb24gPSB7XG4gICAgICAgIHNlcTogLTMsXG4gICAgICAgIHBhcmFsbGVsOiAtNixcbiAgICAgICAgY29tcGVuc2F0aW9uOiAtMjcsXG4gICAgICAgIGxvb3A6IDAsXG4gICAgICAgIGFkaG9jOiAxMFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBmb3JFYWNoKHRhc2tNYXJrZXJzLCBmdW5jdGlvbihtYXJrZXIpIHtcbiAgICAgIHJlbmRlcmVyKG1hcmtlcikocGFyZW50R2Z4LCBlbGVtZW50LCBwb3NpdGlvbik7XG4gICAgfSk7XG5cbiAgICBpZiAob2JqLmlzRm9yQ29tcGVuc2F0aW9uKSB7XG4gICAgICByZW5kZXJlcignQ29tcGVuc2F0aW9uTWFya2VyJykocGFyZW50R2Z4LCBlbGVtZW50LCBwb3NpdGlvbik7XG4gICAgfVxuXG4gICAgaWYgKG9iai4kdHlwZSA9PT0gJ2JwbW46QWRIb2NTdWJQcm9jZXNzJykge1xuICAgICAgcmVuZGVyZXIoJ0FkaG9jTWFya2VyJykocGFyZW50R2Z4LCBlbGVtZW50LCBwb3NpdGlvbik7XG4gICAgfVxuXG4gICAgdmFyIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSBvYmoubG9vcENoYXJhY3RlcmlzdGljcyxcbiAgICAgICAgaXNTZXF1ZW50aWFsID0gbG9vcENoYXJhY3RlcmlzdGljcyAmJiBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbDtcblxuICAgIGlmIChsb29wQ2hhcmFjdGVyaXN0aWNzKSB7XG5cbiAgICAgIGlmIChpc1NlcXVlbnRpYWwgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZW5kZXJlcignTG9vcE1hcmtlcicpKHBhcmVudEdmeCwgZWxlbWVudCwgcG9zaXRpb24pO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXNTZXF1ZW50aWFsID09PSBmYWxzZSkge1xuICAgICAgICByZW5kZXJlcignUGFyYWxsZWxNYXJrZXInKShwYXJlbnRHZngsIGVsZW1lbnQsIHBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzU2VxdWVudGlhbCA9PT0gdHJ1ZSkge1xuICAgICAgICByZW5kZXJlcignU2VxdWVudGlhbE1hcmtlcicpKHBhcmVudEdmeCwgZWxlbWVudCwgcG9zaXRpb24pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbmRlckRhdGFJdGVtQ29sbGVjdGlvbihwYXJlbnRHZngsIGVsZW1lbnQpIHtcblxuICAgIHZhciB5UG9zaXRpb24gPSAoZWxlbWVudC5oZWlnaHQgLSAxNikgLyBlbGVtZW50LmhlaWdodDtcblxuICAgIHZhciBwYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnREFUQV9PQkpFQ1RfQ09MTEVDVElPTl9QQVRIJywge1xuICAgICAgeFNjYWxlRmFjdG9yOiAxLFxuICAgICAgeVNjYWxlRmFjdG9yOiAxLFxuICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICBjb250YWluZXJIZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0LFxuICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgbXg6IDAuNDUxLFxuICAgICAgICBteTogeVBvc2l0aW9uXG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvKiBjb2xsZWN0aW9uIHBhdGggKi8gZHJhd1BhdGgocGFyZW50R2Z4LCBwYXRoRGF0YSwge1xuICAgICAgc3Ryb2tlV2lkdGg6IDJcbiAgICB9KTtcbiAgfVxuXG5cbiAgLy8gZXh0ZW5zaW9uIEFQSSwgdXNlIGF0IHlvdXIgb3duIHJpc2tcbiAgdGhpcy5fZHJhd1BhdGggPSBkcmF3UGF0aDtcblxufVxuXG5cbmluaGVyaXRzKEJwbW5SZW5kZXJlciwgQmFzZVJlbmRlcmVyKTtcblxuQnBtblJlbmRlcmVyLiRpbmplY3QgPSBbXG4gICdjb25maWcuYnBtblJlbmRlcmVyJyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ3N0eWxlcycsXG4gICdwYXRoTWFwJyxcbiAgJ2NhbnZhcycsXG4gICd0ZXh0UmVuZGVyZXInXG5dO1xuXG5cbkJwbW5SZW5kZXJlci5wcm90b3R5cGUuY2FuUmVuZGVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46QmFzZUVsZW1lbnQnKTtcbn07XG5cbkJwbW5SZW5kZXJlci5wcm90b3R5cGUuZHJhd1NoYXBlID0gZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gIHZhciB0eXBlID0gZWxlbWVudC50eXBlO1xuICB2YXIgaCA9IHRoaXMuaGFuZGxlcnNbdHlwZV07XG5cbiAgLyoganNoaW50IC1XMDQwICovXG4gIHJldHVybiBoKHBhcmVudEdmeCwgZWxlbWVudCk7XG59O1xuXG5CcG1uUmVuZGVyZXIucHJvdG90eXBlLmRyYXdDb25uZWN0aW9uID0gZnVuY3Rpb24ocGFyZW50R2Z4LCBlbGVtZW50KSB7XG4gIHZhciB0eXBlID0gZWxlbWVudC50eXBlO1xuICB2YXIgaCA9IHRoaXMuaGFuZGxlcnNbdHlwZV07XG5cbiAgLyoganNoaW50IC1XMDQwICovXG4gIHJldHVybiBoKHBhcmVudEdmeCwgZWxlbWVudCk7XG59O1xuXG5CcG1uUmVuZGVyZXIucHJvdG90eXBlLmdldFNoYXBlUGF0aCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSkge1xuICAgIHJldHVybiBnZXRDaXJjbGVQYXRoKGVsZW1lbnQpO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkFjdGl2aXR5JykpIHtcbiAgICByZXR1cm4gZ2V0Um91bmRSZWN0UGF0aChlbGVtZW50LCBUQVNLX0JPUkRFUl9SQURJVVMpO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkdhdGV3YXknKSkge1xuICAgIHJldHVybiBnZXREaWFtb25kUGF0aChlbGVtZW50KTtcbiAgfVxuXG4gIHJldHVybiBnZXRSZWN0UGF0aChlbGVtZW50KTtcbn07XG4iLCIvKipcbiAqIE1hcCBjb250YWluaW5nIFNWRyBwYXRocyBuZWVkZWQgYnkgQnBtblJlbmRlcmVyLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFBhdGhNYXAoKSB7XG5cbiAgLyoqXG4gICAqIENvbnRhaW5zIGEgbWFwIG9mIHBhdGggZWxlbWVudHNcbiAgICpcbiAgICogPGgxPlBhdGggZGVmaW5pdGlvbjwvaDE+XG4gICAqIEEgcGFyYW1ldGVyaXplZCBwYXRoIGlzIGRlZmluZWQgbGlrZSB0aGlzOlxuICAgKiA8cHJlPlxuICAgKiAnR0FURVdBWV9QQVJBTExFTCc6IHtcbiAgICogICBkOiAnbSB7bXh9LHtteX0ge2UueDB9LDAgMCx7ZS54MX0ge2UueDF9LDAgMCx7ZS55MH0gLXtlLngxfSwwIDAse2UueTF9ICcgK1xuICAgICAgICAgICcte2UueDB9LDAgMCwte2UueTF9IC17ZS54MX0sMCAwLC17ZS55MH0ge2UueDF9LDAgeicsXG4gICAqICAgaGVpZ2h0OiAxNy41LFxuICAgKiAgIHdpZHRoOiAgMTcuNSxcbiAgICogICBoZWlnaHRFbGVtZW50czogWzIuNSwgNy41XSxcbiAgICogICB3aWR0aEVsZW1lbnRzOiBbMi41LCA3LjVdXG4gICAqIH1cbiAgICogPC9wcmU+XG4gICAqIDxwPkl0J3MgaW1wb3J0YW50IHRvIHNwZWNpZnkgYSBjb3JyZWN0IDxiPmhlaWdodCBhbmQgd2lkdGg8L2I+IGZvciB0aGUgcGF0aCBhcyB0aGUgc2NhbGluZ1xuICAgKiBpcyBiYXNlZCBvbiB0aGUgcmF0aW8gYmV0d2VlbiB0aGUgc3BlY2lmaWVkIGhlaWdodCBhbmQgd2lkdGggaW4gdGhpcyBvYmplY3QgYW5kIHRoZVxuICAgKiBoZWlnaHQgYW5kIHdpZHRoIHRoYXQgaXMgc2V0IGFzIHNjYWxlIHRhcmdldCAoTm90ZSB4LHkgY29vcmRpbmF0ZXMgd2lsbCBiZSBzY2FsZWQgd2l0aFxuICAgKiBpbmRpdmlkdWFsIHJhdGlvcykuPC9wPlxuICAgKiA8cD5UaGUgJzxiPmhlaWdodEVsZW1lbnRzPC9iPicgYW5kICc8Yj53aWR0aEVsZW1lbnRzPC9iPicgYXJyYXkgbXVzdCBjb250YWluIHRoZSB2YWx1ZXMgdGhhdCB3aWxsIGJlIHNjYWxlZC5cbiAgICogVGhlIHNjYWxpbmcgaXMgYmFzZWQgb24gdGhlIGNvbXB1dGVkIHJhdGlvcy5cbiAgICogQ29vcmRpbmF0ZXMgb24gdGhlIHkgYXhpcyBzaG91bGQgYmUgaW4gdGhlIDxiPmhlaWdodEVsZW1lbnQ8L2I+J3MgYXJyYXksIHRoZXkgd2lsbCBiZSBzY2FsZWQgdXNpbmdcbiAgICogdGhlIGNvbXB1dGVkIHJhdGlvIGNvZWZmaWNpZW50LlxuICAgKiBJbiB0aGUgcGFyYW1ldGVyaXplZCBwYXRoIHRoZSBzY2FsZWQgdmFsdWVzIGNhbiBiZSBhY2Nlc3NlZCB0aHJvdWdoIHRoZSAnZScgb2JqZWN0IGluIHt9IGJyYWNrZXRzLlxuICAgKiAgIDx1bD5cbiAgICogICAgPGxpPlRoZSB2YWx1ZXMgZm9yIHRoZSB5IGF4aXMgY2FuIGJlIGFjY2Vzc2VkIGluIHRoZSBwYXRoIHN0cmluZyB1c2luZyB7ZS55MH0sIHtlLnkxfSwgLi4uLjwvbGk+XG4gICAqICAgIDxsaT5UaGUgdmFsdWVzIGZvciB0aGUgeCBheGlzIGNhbiBiZSBhY2Nlc3NlZCBpbiB0aGUgcGF0aCBzdHJpbmcgdXNpbmcge2UueDB9LCB7ZS54MX0sIC4uLi48L2xpPlxuICAgKiAgIDwvdWw+XG4gICAqICAgVGhlIG51bWJlcnMgeDAsIHgxIHJlc3BlY3RpdmVseSB5MCwgeTEsIC4uLiBtYXAgdG8gdGhlIGNvcnJlc3BvbmRpbmcgYXJyYXkgaW5kZXguXG4gICAqIDwvcD5cbiAgICovXG4gIHRoaXMucGF0aE1hcCA9IHtcbiAgICAnRVZFTlRfTUVTU0FHRSc6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSBsIDAse2UueTF9IGwge2UueDF9LDAgbCAwLC17ZS55MX0geiBsIHtlLngwfSx7ZS55MH0gbCB7ZS54MH0sLXtlLnkwfScsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6ICAzNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNiwgMTRdLFxuICAgICAgd2lkdGhFbGVtZW50czogWzEwLjUsIDIxXVxuICAgIH0sXG4gICAgJ0VWRU5UX1NJR05BTCc6IHtcbiAgICAgIGQ6ICdNIHtteH0se215fSBsIHtlLngwfSx7ZS55MH0gbCAte2UueDF9LDAgWicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6IDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFsxOF0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMTAsIDIwXVxuICAgIH0sXG4gICAgJ0VWRU5UX0VTQ0FMQVRJT04nOiB7XG4gICAgICBkOiAnTSB7bXh9LHtteX0gbCB7ZS54MH0se2UueTB9IGwgLXtlLngwfSwte2UueTF9IGwgLXtlLngwfSx7ZS55MX0gWicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6IDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFsyMCwgN10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbOF1cbiAgICB9LFxuICAgICdFVkVOVF9DT05ESVRJT05BTCc6IHtcbiAgICAgIGQ6ICdNIHtlLngwfSx7ZS55MH0gbCB7ZS54MX0sMCBsIDAse2UueTJ9IGwgLXtlLngxfSwwIFogJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTN9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTR9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTV9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTZ9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTd9IGwge2UueDB9LDAgJyArXG4gICAgICAgICAnTSB7ZS54Mn0se2UueTh9IGwge2UueDB9LDAgJyxcbiAgICAgIGhlaWdodDogMzYsXG4gICAgICB3aWR0aDogIDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFs4LjUsIDE0LjUsIDE4LCAxMS41LCAxNC41LCAxNy41LCAyMC41LCAyMy41LCAyNi41XSxcbiAgICAgIHdpZHRoRWxlbWVudHM6ICBbMTAuNSwgMTQuNSwgMTIuNV1cbiAgICB9LFxuICAgICdFVkVOVF9MSU5LJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IDAse2UueTB9IC17ZS54MX0sMCAwLHtlLnkxfSB7ZS54MX0sMCAwLHtlLnkwfSB7ZS54MH0sLXtlLnkyfSAte2UueDB9LC17ZS55Mn0geicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6IDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFs0LjQzNzUsIDYuNzUsIDcuODEyNV0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbOS44NDM3NSwgMTMuNV1cbiAgICB9LFxuICAgICdFVkVOVF9FUlJPUic6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSB7ZS54MH0sLXtlLnkwfSB7ZS54MX0sLXtlLnkxfSB7ZS54Mn0se2UueTJ9IHtlLngzfSwte2UueTN9IC17ZS54NH0se2UueTR9IC17ZS54NX0sLXtlLnk1fSB6JyxcbiAgICAgIGhlaWdodDogMzYsXG4gICAgICB3aWR0aDogMzYsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzAuMDIzLCA4LjczNywgOC4xNTEsIDE2LjU2NCwgMTAuNTkxLCA4LjcxNF0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMC4wODUsIDYuNjcyLCA2Ljk3LCA0LjI3MywgNS4zMzcsIDYuNjM2XVxuICAgIH0sXG4gICAgJ0VWRU5UX0NBTkNFTF80NSc6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSAte2UueDF9LDAgMCx7ZS54MH0ge2UueDF9LDAgMCx7ZS55MX0ge2UueDB9LDAgJyArXG4gICAgICAgICcwLC17ZS55MX0ge2UueDF9LDAgMCwte2UueTB9IC17ZS54MX0sMCAwLC17ZS55MX0gLXtlLngwfSwwIHonLFxuICAgICAgaGVpZ2h0OiAzNixcbiAgICAgIHdpZHRoOiAzNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNC43NSwgOC41XSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFs0Ljc1LCA4LjVdXG4gICAgfSxcbiAgICAnRVZFTlRfQ09NUEVOU0FUSU9OJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IHtlLngwfSwte2UueTB9IDAse2UueTF9IHogbSB7ZS54MX0sLXtlLnkyfSB7ZS54Mn0sLXtlLnkzfSAwLHtlLnkxfSAte2UueDJ9LC17ZS55M30geicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6IDM2LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFs2LjUsIDEzLCAwLjQsIDYuMV0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbOSwgOS4zLCA4LjddXG4gICAgfSxcbiAgICAnRVZFTlRfVElNRVJfV0gnOiB7XG4gICAgICBkOiAnTSB7bXh9LHtteX0gbCB7ZS54MH0sLXtlLnkwfSBtIC17ZS54MH0se2UueTB9IGwge2UueDF9LHtlLnkxfSAnLFxuICAgICAgaGVpZ2h0OiAzNixcbiAgICAgIHdpZHRoOiAgMzYsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzEwLCAyXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFszLCA3XVxuICAgIH0sXG4gICAgJ0VWRU5UX1RJTUVSX0xJTkUnOiB7XG4gICAgICBkOiAgJ00ge214fSx7bXl9ICcgK1xuICAgICAgICAgICdtIHtlLngwfSx7ZS55MH0gbCAte2UueDF9LHtlLnkxfSAnLFxuICAgICAgaGVpZ2h0OiAzNixcbiAgICAgIHdpZHRoOiAgMzYsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzEwLCAzXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFswLCAwXVxuICAgIH0sXG4gICAgJ0VWRU5UX01VTFRJUExFJzoge1xuICAgICAgZDonbSB7bXh9LHtteX0ge2UueDF9LC17ZS55MH0ge2UueDF9LHtlLnkwfSAte2UueDB9LHtlLnkxfSAte2UueDJ9LDAgeicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6ICAzNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNi4yODA5OSwgMTIuNTYxOTldLFxuICAgICAgd2lkdGhFbGVtZW50czogWzMuMTQwNSwgOS40MjE0OSwgMTIuNTYxOThdXG4gICAgfSxcbiAgICAnRVZFTlRfUEFSQUxMRUxfTVVMVElQTEUnOiB7XG4gICAgICBkOidtIHtteH0se215fSB7ZS54MH0sMCAwLHtlLnkxfSB7ZS54MX0sMCAwLHtlLnkwfSAte2UueDF9LDAgMCx7ZS55MX0gJyArXG4gICAgICAgICcte2UueDB9LDAgMCwte2UueTF9IC17ZS54MX0sMCAwLC17ZS55MH0ge2UueDF9LDAgeicsXG4gICAgICBoZWlnaHQ6IDM2LFxuICAgICAgd2lkdGg6ICAzNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbMi41NjIyOCwgNy42ODY4M10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMi41NjIyOCwgNy42ODY4M11cbiAgICB9LFxuICAgICdHQVRFV0FZX0VYQ0xVU0lWRSc6IHtcbiAgICAgIGQ6J20ge214fSx7bXl9IHtlLngwfSx7ZS55MH0ge2UueDF9LHtlLnkwfSB7ZS54Mn0sMCB7ZS54NH0se2UueTJ9ICcgK1xuICAgICAgICAgICAgICAgICAgICAne2UueDR9LHtlLnkxfSB7ZS54Mn0sMCB7ZS54MX0se2UueTN9IHtlLngwfSx7ZS55M30gJyArXG4gICAgICAgICAgICAgICAgICAgICd7ZS54M30sMCB7ZS54NX0se2UueTF9IHtlLng1fSx7ZS55Mn0ge2UueDN9LDAgeicsXG4gICAgICBoZWlnaHQ6IDE3LjUsXG4gICAgICB3aWR0aDogIDE3LjUsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzguNSwgNi41MzEyLCAtNi41MzEyLCAtOC41XSxcbiAgICAgIHdpZHRoRWxlbWVudHM6ICBbNi41LCAtNi41LCAzLCAtMywgNSwgLTVdXG4gICAgfSxcbiAgICAnR0FURVdBWV9QQVJBTExFTCc6IHtcbiAgICAgIGQ6J20ge214fSx7bXl9IDAse2UueTF9IC17ZS54MX0sMCAwLHtlLnkwfSB7ZS54MX0sMCAwLHtlLnkxfSB7ZS54MH0sMCAnICtcbiAgICAgICAgJzAsLXtlLnkxfSB7ZS54MX0sMCAwLC17ZS55MH0gLXtlLngxfSwwIDAsLXtlLnkxfSAte2UueDB9LDAgeicsXG4gICAgICBoZWlnaHQ6IDMwLFxuICAgICAgd2lkdGg6ICAzMCxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNSwgMTIuNV0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbNSwgMTIuNV1cbiAgICB9LFxuICAgICdHQVRFV0FZX0VWRU5UX0JBU0VEJzoge1xuICAgICAgZDonbSB7bXh9LHtteX0ge2UueDB9LHtlLnkwfSB7ZS54MH0se2UueTF9IHtlLngxfSx7ZS55Mn0ge2UueDJ9LDAgeicsXG4gICAgICBoZWlnaHQ6IDExLFxuICAgICAgd2lkdGg6ICAxMSxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbLTYsIDYsIDEyLCAtMTJdLFxuICAgICAgd2lkdGhFbGVtZW50czogWzksIC0zLCAtMTJdXG4gICAgfSxcbiAgICAnR0FURVdBWV9DT01QTEVYJzoge1xuICAgICAgZDonbSB7bXh9LHtteX0gMCx7ZS55MH0gLXtlLngwfSwte2UueTF9IC17ZS54MX0se2UueTJ9IHtlLngwfSx7ZS55MX0gLXtlLngyfSwwIDAse2UueTN9ICcgK1xuICAgICAgICAne2UueDJ9LDAgIC17ZS54MH0se2UueTF9IGwge2UueDF9LHtlLnkyfSB7ZS54MH0sLXtlLnkxfSAwLHtlLnkwfSB7ZS54M30sMCAwLC17ZS55MH0ge2UueDB9LHtlLnkxfSAnICtcbiAgICAgICAgJ3tlLngxfSwte2UueTJ9IC17ZS54MH0sLXtlLnkxfSB7ZS54Mn0sMCAwLC17ZS55M30gLXtlLngyfSwwIHtlLngwfSwte2UueTF9IC17ZS54MX0sLXtlLnkyfSAnICtcbiAgICAgICAgJy17ZS54MH0se2UueTF9IDAsLXtlLnkwfSAte2UueDN9LDAgeicsXG4gICAgICBoZWlnaHQ6IDE3LjEyNSxcbiAgICAgIHdpZHRoOiAgMTcuMTI1LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFs0Ljg3NSwgMy40Mzc1LCAyLjEyNSwgM10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMy40Mzc1LCAyLjEyNSwgNC44NzUsIDNdXG4gICAgfSxcbiAgICAnREFUQV9PQkpFQ1RfUEFUSCc6IHtcbiAgICAgIGQ6J20gMCwwIHtlLngxfSwwIHtlLngwfSx7ZS55MH0gMCx7ZS55MX0gLXtlLngyfSwwIDAsLXtlLnkyfSB7ZS54MX0sMCAwLHtlLnkwfSB7ZS54MH0sMCcsXG4gICAgICBoZWlnaHQ6IDYxLFxuICAgICAgd2lkdGg6ICA1MSxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbMTAsIDUwLCA2MF0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbMTAsIDQwLCA1MCwgNjBdXG4gICAgfSxcbiAgICAnREFUQV9PQkpFQ1RfQ09MTEVDVElPTl9QQVRIJzoge1xuICAgICAgZDonbSB7bXh9LCB7bXl9ICcgK1xuICAgICAgICAnbSAgMCAxNSAgbCAwIC0xNSAnICtcbiAgICAgICAgJ20gIDQgMTUgIGwgMCAtMTUgJyArXG4gICAgICAgICdtICA0IDE1ICBsIDAgLTE1ICcsXG4gICAgICBoZWlnaHQ6IDYxLFxuICAgICAgd2lkdGg6ICA1MSxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbMTJdLFxuICAgICAgd2lkdGhFbGVtZW50czogWzEsIDYsIDEyLCAxNV1cbiAgICB9LFxuICAgICdEQVRBX0FSUk9XJzoge1xuICAgICAgZDonbSA1LDkgOSwwIDAsLTMgNSw1IC01LDUgMCwtMyAtOSwwIHonLFxuICAgICAgaGVpZ2h0OiA2MSxcbiAgICAgIHdpZHRoOiAgNTEsXG4gICAgICBoZWlnaHRFbGVtZW50czogW10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbXVxuICAgIH0sXG4gICAgJ0RBVEFfU1RPUkUnOiB7XG4gICAgICBkOidtICB7bXh9LHtteX0gJyArXG4gICAgICAgICdsICAwLHtlLnkyfSAnICtcbiAgICAgICAgJ2MgIHtlLngwfSx7ZS55MX0ge2UueDF9LHtlLnkxfSAge2UueDJ9LDAgJyArXG4gICAgICAgICdsICAwLC17ZS55Mn0gJyArXG4gICAgICAgICdjIC17ZS54MH0sLXtlLnkxfSAte2UueDF9LC17ZS55MX0gLXtlLngyfSwwJyArXG4gICAgICAgICdjICB7ZS54MH0se2UueTF9IHtlLngxfSx7ZS55MX0gIHtlLngyfSwwICcgK1xuICAgICAgICAnbSAgLXtlLngyfSx7ZS55MH0nICtcbiAgICAgICAgJ2MgIHtlLngwfSx7ZS55MX0ge2UueDF9LHtlLnkxfSB7ZS54Mn0sMCcgK1xuICAgICAgICAnbSAgLXtlLngyfSx7ZS55MH0nICtcbiAgICAgICAgJ2MgIHtlLngwfSx7ZS55MX0ge2UueDF9LHtlLnkxfSAge2UueDJ9LDAnLFxuICAgICAgaGVpZ2h0OiA2MSxcbiAgICAgIHdpZHRoOiAgNjEsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzcsIDEwLCA0NV0sXG4gICAgICB3aWR0aEVsZW1lbnRzOiAgWzIsIDU4LCA2MF1cbiAgICB9LFxuICAgICdURVhUX0FOTk9UQVRJT04nOiB7XG4gICAgICBkOiAnbSB7bXh9LCB7bXl9IG0gMTAsMCBsIC0xMCwwIGwgMCx7ZS55MH0gbCAxMCwwJyxcbiAgICAgIGhlaWdodDogMzAsXG4gICAgICB3aWR0aDogMTAsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzMwXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFsxMF1cbiAgICB9LFxuICAgICdNQVJLRVJfU1VCX1BST0NFU1MnOiB7XG4gICAgICBkOiAnbXtteH0se215fSBtIDcsMiBsIDAsMTAgbSAtNSwtNSBsIDEwLDAnLFxuICAgICAgaGVpZ2h0OiAxMCxcbiAgICAgIHdpZHRoOiAxMCxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFtdXG4gICAgfSxcbiAgICAnTUFSS0VSX1BBUkFMTEVMJzoge1xuICAgICAgZDogJ217bXh9LHtteX0gbSAzLDIgbCAwLDEwIG0gMywtMTAgbCAwLDEwIG0gMywtMTAgbCAwLDEwJyxcbiAgICAgIGhlaWdodDogMTAsXG4gICAgICB3aWR0aDogMTAsXG4gICAgICBoZWlnaHRFbGVtZW50czogW10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbXVxuICAgIH0sXG4gICAgJ01BUktFUl9TRVFVRU5USUFMJzoge1xuICAgICAgZDogJ217bXh9LHtteX0gbSAwLDMgbCAxMCwwIG0gLTEwLDMgbCAxMCwwIG0gLTEwLDMgbCAxMCwwJyxcbiAgICAgIGhlaWdodDogMTAsXG4gICAgICB3aWR0aDogMTAsXG4gICAgICBoZWlnaHRFbGVtZW50czogW10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbXVxuICAgIH0sXG4gICAgJ01BUktFUl9DT01QRU5TQVRJT04nOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gNywtNSAwLDEwIHogbSA3LjEsLTAuMyA2LjksLTQuNyAwLDEwIC02LjksLTQuNyB6JyxcbiAgICAgIGhlaWdodDogMTAsXG4gICAgICB3aWR0aDogMjEsXG4gICAgICBoZWlnaHRFbGVtZW50czogW10sXG4gICAgICB3aWR0aEVsZW1lbnRzOiBbXVxuICAgIH0sXG4gICAgJ01BUktFUl9MT09QJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IGMgMy41MjY5NzksMCA2LjM4NjE2MSwtMi44Mjk4NTggNi4zODYxNjEsLTYuMzIwNjYxIDAsLTMuNDkwODA2IC0yLjg1OTE4MiwtNi4zMjA2NjEgJyArXG4gICAgICAgICctNi4zODYxNjEsLTYuMzIwNjYxIC0zLjUyNjk3OCwwIC02LjM4NjE2LDIuODI5ODU1IC02LjM4NjE2LDYuMzIwNjYxIDAsMS43NDU0MDIgJyArXG4gICAgICAgICcwLjcxNDc5NywzLjMyNTU2NyAxLjg3MDQ2Myw0LjQ2OTM4MSAwLjU3NzgzNCwwLjU3MTkwOCAxLjI2NTg4NSwxLjAzNDcyOCAyLjAyOTkxNiwxLjM1NDU3ICcgK1xuICAgICAgICAnbCAtMC43MTgxNjMsLTMuOTA5NzkzIG0gMC43MTgxNjMsMy45MDk3OTMgLTMuODg1MjExLDAuODAyOTAyJyxcbiAgICAgIGhlaWdodDogMTMuOSxcbiAgICAgIHdpZHRoOiAxMy43LFxuICAgICAgaGVpZ2h0RWxlbWVudHM6IFtdLFxuICAgICAgd2lkdGhFbGVtZW50czogW11cbiAgICB9LFxuICAgICdNQVJLRVJfQURIT0MnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gbSAwLjg0NDYxLDIuNjQ0MTEgYyAxLjA1NTMzLC0xLjIzNzgwOTk2IDIuNjQzMzcsLTIuMDc4ODIgNC4yOTY1MywtMS45Nzk5Nzk5NiAyLjA1MTYzLDAuMDgwNSAnICtcbiAgICAgICAgJzMuODU1NzksMS4xNTgwMyA1Ljc2MDgyLDEuNzkxMDcgMS4wNjM4NSwwLjM0MTM5OTk2IDIuMjQ0NTQsMC4xNDM4IDMuMTg3NTksLTAuNDM3NjcgMC42MTc0MywtMC4zMzY0MiAnICtcbiAgICAgICAgJzEuMjc3NSwtMC42NDA3OCAxLjc1NDIsLTEuMTc1MTEgMCwwLjU2MDIzIDAsMS4xMjA0NiAwLDEuNjgwNyAtMC45ODcwNiwwLjk2MjM3OTk2IC0yLjI5NzkyLDEuNjIzOTM5OTYgJyArXG4gICAgICAgICctMy42OTE4LDEuNjYxODE5OTYgLTEuMjQ0NTksMC4wOTI3IC0yLjQ2NjcxLC0wLjI0OTEgLTMuNTk1MDUsLTAuNzQ4MTIgLTEuMzU3ODksLTAuNTU5NjUgJyArXG4gICAgICAgICctMi43NTEzMywtMS4zMzQzNjk5NiAtNC4yNzAyNywtMS4xODEyMTk5NiAtMS4zNzc0MSwwLjE0NjAxIC0yLjQxODQyLDEuMTM2ODU5OTYgLTMuNDQyODgsMS45Njc4Mjk5NiB6JyxcbiAgICAgIGhlaWdodDogNCxcbiAgICAgIHdpZHRoOiAxNSxcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbXSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFtdXG4gICAgfSxcbiAgICAnVEFTS19UWVBFX1NFTkQnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gbCAwLHtlLnkxfSBsIHtlLngxfSwwIGwgMCwte2UueTF9IHogbCB7ZS54MH0se2UueTB9IGwge2UueDB9LC17ZS55MH0nLFxuICAgICAgaGVpZ2h0OiAxNCxcbiAgICAgIHdpZHRoOiAgMjEsXG4gICAgICBoZWlnaHRFbGVtZW50czogWzYsIDE0XSxcbiAgICAgIHdpZHRoRWxlbWVudHM6IFsxMC41LCAyMV1cbiAgICB9LFxuICAgICdUQVNLX1RZUEVfU0NSSVBUJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IGMgOS45NjY1NTMsLTYuMjcyNzYgLTguMDAwOTI2LC03LjkxOTMyIDIuOTY4OTY4LC0xNC45MzggbCAtOC44MDI3MjgsMCAnICtcbiAgICAgICAgJ2MgLTEwLjk2OTg5NCw3LjAxODY4IDYuOTk3NTg1LDguNjY1MjQgLTIuOTY4OTY3LDE0LjkzOCB6ICcgK1xuICAgICAgICAnbSAtNywtMTIgbCA1LDAgJyArXG4gICAgICAgICdtIC00LjUsMyBsIDQuNSwwICcgK1xuICAgICAgICAnbSAtMywzIGwgNSwwJyArXG4gICAgICAgICdtIC00LDMgbCA1LDAnLFxuICAgICAgaGVpZ2h0OiAxNSxcbiAgICAgIHdpZHRoOiAgMTIuNixcbiAgICAgIGhlaWdodEVsZW1lbnRzOiBbNiwgMTRdLFxuICAgICAgd2lkdGhFbGVtZW50czogWzEwLjUsIDIxXVxuICAgIH0sXG4gICAgJ1RBU0tfVFlQRV9VU0VSXzEnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gYyAwLjkwOSwtMC44NDUgMS41OTQsLTIuMDQ5IDEuNTk0LC0zLjM4NSAwLC0yLjU1NCAtMS44MDUsLTQuNjIxOTk5OTkgJyArXG4gICAgICAgICctNC4zNTcsLTQuNjIxOTk5OTkgLTIuNTUxOTk5OTgsMCAtNC4yODc5OTk5OCwyLjA2Nzk5OTk5IC00LjI4Nzk5OTk4LDQuNjIxOTk5OTkgMCwxLjM0OCAnICtcbiAgICAgICAgJzAuOTc0LDIuNTYyIDEuODk1OTk5OTgsMy40MDUgLTAuNTI4OTk5OTgsMC4xODcgLTUuNjY5LDIuMDk3IC01Ljc5NCw0Ljc1NjAwMDUgdiA2LjcxOCAnICtcbiAgICAgICAgJ2ggMTcgdiAtNi43MTggYyAwLC0yLjI5ODAwMDUgLTUuNTI3OTk5NiwtNC41OTUwMDA1IC02LjA1MDk5OTYsLTQuNzc2MDAwNSB6JyArXG4gICAgICAgICdtIC04LDYgbCAwLDUuNSBtIDExLDAgbCAwLC01J1xuICAgIH0sXG4gICAgJ1RBU0tfVFlQRV9VU0VSXzInOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gbSAyLjE2MiwxLjAwOSBjIDAsMi40NDcwMDA1IC0yLjE1OCw0LjQzMTAwMDUgLTQuODIxLDQuNDMxMDAwNSAnICtcbiAgICAgICAgJy0yLjY2NDk5OTk4LDAgLTQuODIyLC0xLjk4MSAtNC44MjIsLTQuNDMxMDAwNSAnXG4gICAgfSxcbiAgICAnVEFTS19UWVBFX1VTRVJfMyc6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSBtIC02LjksLTMuODAgYyAwLDAgMi4yNTA5OTk5OCwtMi4zNTggNC4yNzM5OTk5OCwtMS4xNzcgMi4wMjQsMS4xODEgNC4yMjEsMS41MzcgJyArXG4gICAgICAgICc0LjEyNCwwLjk2NSAtMC4wOTgsLTAuNTcgLTAuMTE3LC0zLjc5MDk5OTk5IC00LjE5MSwtNC4xMzU5OTk5OSAtMy41NzQ5OTk5OCwwLjAwMSAnICtcbiAgICAgICAgJy00LjIwNzk5OTk4LDMuMzY2OTk5OTkgLTQuMjA2OTk5OTgsNC4zNDc5OTk5OSB6J1xuICAgIH0sXG4gICAgJ1RBU0tfVFlQRV9NQU5VQUwnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gYyAwLjIzNCwtMC4wMSA1LjYwNCwwLjAwOCA4LjAyOSwwLjAwNCAwLjgwOCwwIDEuMjcxLC0wLjE3MiAxLjQxNywtMC43NTIgMC4yMjcsLTAuODk4ICcgK1xuICAgICAgICAnLTAuMzM0LC0xLjMxNCAtMS4zMzgsLTEuMzE2IC0yLjQ2NywtMC4wMSAtNy44ODYsLTAuMDA0IC04LjEwOCwtMC4wMDQgLTAuMDE0LC0wLjA3OSAwLjAxNiwtMC41MzMgMCwtMC42MSAnICtcbiAgICAgICAgJzAuMTk1LC0wLjA0MiA4LjUwNywwLjAwNiA5LjYxNiwwLjAwMiAwLjg3NywtMC4wMDcgMS4zNSwtMC40MzggMS4zNTMsLTEuMjA4IDAuMDAzLC0wLjc2OCAtMC40NzksLTEuMDkgJyArXG4gICAgICAgICctMS4zNSwtMS4wOTEgLTIuOTY4LC0wLjAwMiAtOS42MTksLTAuMDEzIC05LjYxOSwtMC4wMTMgdiAtMC41OTEgYyAwLDAgNS4wNTIsLTAuMDE2IDcuMjI1LC0wLjAxNiAnICtcbiAgICAgICAgJzAuODg4LC0wLjAwMiAxLjM1NCwtMC40MTYgMS4zNTEsLTEuMTkzIC0wLjAwNiwtMC43NjEgLTAuNDkyLC0xLjE5NiAtMS4zNjEsLTEuMTk2IC0zLjQ3MywtMC4wMDUgJyArXG4gICAgICAgICctMTAuODYsLTAuMDAzIC0xMS4wODI5OTk1LC0wLjAwMyAtMC4wMjIsLTAuMDQ3IC0wLjA0NSwtMC4wOTQgLTAuMDY5LC0wLjEzOSAwLjM5Mzk5OTUsLTAuMzE5ICcgK1xuICAgICAgICAnMi4wNDA5OTk1LC0xLjYyNiAyLjQxNDk5OTUsLTIuMDE3IDAuNDY5LC0wLjQ4NzAwMDUgMC41MTksLTEuMTY1MDAwNSAwLjE2MiwtMS42MDQwMDA1IC0wLjQxNCwtMC41MTEgJyArXG4gICAgICAgICctMC45NzMsLTAuNSAtMS40OCwtMC4yMzYgLTEuNDYwOTk5NSwwLjc2NCAtNi41OTk5OTk1LDMuNjQzMDAwNSAtNy43MzI5OTk1LDQuMjcxMDAwNSAtMC45LDAuNDk5ICcgK1xuICAgICAgICAnLTEuNTE2LDEuMjUzIC0xLjg4MiwyLjE5IC0wLjM3MDAwMDAyLDAuOTUgLTAuMTcsMi4wMSAtMC4xNjYsMi45NzkgMC4wMDQsMC43MTggLTAuMjczMDAwMDIsMS4zNDUgJyArXG4gICAgICAgICctMC4wNTUsMi4wNjMgMC42MjksMi4wODcgMi40MjUsMy4zMTIgNC44NTksMy4zMTggNC42MTc5OTk1LDAuMDE0IDkuMjM3OTk5NSwtMC4xMzkgMTMuODU2OTk5NSwtMC4xNTggJyArXG4gICAgICAgICcwLjc1NSwtMC4wMDQgMS4xNzEsLTAuMzAxIDEuMTgyLC0xLjAzMyAwLjAxMiwtMC43NTQgLTAuNDIzLC0wLjk2OSAtMS4xODMsLTAuOTczIC0xLjc3OCwtMC4wMSAnICtcbiAgICAgICAgJy01LjgyNCwtMC4wMDQgLTYuMDQsLTAuMDA0IDEwZS00LC0wLjA4NCAwLjAwMywtMC41ODYgMTBlLTQsLTAuNjcgeidcbiAgICB9LFxuICAgICdUQVNLX1RZUEVfSU5TVEFOVElBVElOR19TRU5EJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IGwgMCw4LjQgbCAxMi42LDAgbCAwLC04LjQgeiBsIDYuMywzLjYgbCA2LjMsLTMuNidcbiAgICB9LFxuICAgICdUQVNLX1RZUEVfU0VSVklDRSc6IHtcbiAgICAgIGQ6ICdtIHtteH0se215fSB2IC0xLjcxMzM1IGMgMC4zNTIzMjYsLTAuMDcwNSAwLjcwMzkzMiwtMC4xNzgzOCAxLjA0NzYyOCwtMC4zMjEzMyAnICtcbiAgICAgICAgJzAuMzQ0NDE2LC0wLjE0NDY1IDAuNjY1ODIyLC0wLjMyMTMzIDAuOTY2Mzc3LC0wLjUyMTQ1IGwgMS4xOTQzMSwxLjE4MDA1IDEuNTY3NDg3LC0xLjU3Njg4ICcgK1xuICAgICAgICAnLTEuMTk1MDI4LC0xLjE4MDE0IGMgMC40MDMzNzYsLTAuNjEzOTQgMC42ODMwNzksLTEuMjk5MDggMC44MjU0NDcsLTIuMDE4MjQgbCAxLjYyMjEzMywtMC4wMSAnICtcbiAgICAgICAgJ3YgLTIuMjE5NiBsIC0xLjYzNjUxNCwwLjAxIGMgLTAuMDczMzMsLTAuMzUxNTMgLTAuMTc4MzE5LC0wLjcwMDI0IC0wLjMyMzU2NCwtMS4wNDM3MiAnICtcbiAgICAgICAgJy0wLjE0NTI0NCwtMC4zNDQwNiAtMC4zMjE0MDcsLTAuNjY0NCAtMC41MjI3MzUsLTAuOTYyMTcgbCAxLjEzMTAzNSwtMS4xMzYzMSAtMS41ODMzMDUsLTEuNTYyOTMgJyArXG4gICAgICAgICctMS4xMjk1OTgsMS4xMzU4OSBjIC0wLjYxNDA1MiwtMC40MDEwOCAtMS4zMDI4ODMsLTAuNjgwOTMgLTIuMDIyNjMzLC0wLjgyMjQ3IGwgMC4wMDkzLC0xLjYxODUyICcgK1xuICAgICAgICAnaCAtMi4yNDExNzMgbCAwLjAwNDIsMS42MzEyNCBjIC0wLjM1Mzc2MywwLjA3MzYgLTAuNzA1MzY5LDAuMTc5NzcgLTEuMDQ5Nzg1LDAuMzIzNzEgLTAuMzQ0NDE1LDAuMTQ0MzcgJyArXG4gICAgICAgICctMC42NjUxMDIsMC4zMjA5MiAtMC45NjM1MDA2LDAuNTIwNDYgbCAtMS4xNjk4NjI4LC0xLjE1ODIzIC0xLjU2Njc2OTEsMS41NzkyIDEuMTY4NDI2NSwxLjE1NjY5ICcgK1xuICAgICAgICAnYyAtMC40MDI2NTczLDAuNjEyODMgLTAuNjgzMDgsMS4yOTc5NyAtMC44MjQ3Mjg3LDIuMDE3MTMgbCAtMS42NTg4MDQxLDAuMDAzIHYgMi4yMjE3NCAnICtcbiAgICAgICAgJ2wgMS42NzI0NjQ4LC0wLjAwNiBjIDAuMDczMzI3LDAuMzUwNzcgMC4xNzk3NTk4LDAuNzAyNDMgMC4zMjQyODUxLDEuMDQ0NzIgMC4xNDUyNDI4LDAuMzQ0NDggJyArXG4gICAgICAgICcwLjMyMTQwNjQsMC42NjQ0IDAuNTIyNzMzOSwwLjk2MDY2IGwgLTEuMTk5MzQzMSwxLjE5NzIzIDEuNTg0MDI1NiwxLjU2MDExIDEuMTk2NDY2OCwtMS4xOTM0OCAnICtcbiAgICAgICAgJ2MgMC42MTQwNTE3LDAuNDAzNDYgMS4zMDI4ODI3LDAuNjgyMzIgMi4wMjMzNTE3LDAuODIzMzEgbCA3LjE5ZS00LDEuNjk4OTIgaCAyLjIyNjg0OCB6ICcgK1xuICAgICAgICAnbSAwLjIyMTQ2MiwtMy45OTU3IGMgLTEuNzg4OTQ4LDAuNzUwMiAtMy44NTc2LC0wLjA5MjggLTQuNjA5NzA1NSwtMS44NzQzOCAtMC43NTIxMDY1LC0xLjc4MzIxICcgK1xuICAgICAgICAnMC4wOTA1OTgsLTMuODQ2MjcgMS44ODAyNjQ1LC00LjU5NjA0IDEuNzg4MjMsLTAuNzQ5MzYgMy44NTY4ODEsMC4wOTI5IDQuNjA4OTg3LDEuODc0MzcgJyArXG4gICAgICAgICcwLjc1MjEwNiwxLjc4MTY1IC0wLjA5MDYsMy44NDYxMiAtMS44Nzk1NDYsNC41OTYwNSB6J1xuICAgIH0sXG4gICAgJ1RBU0tfVFlQRV9TRVJWSUNFX0ZJTEwnOiB7XG4gICAgICBkOiAnbSB7bXh9LHtteX0gYyAtMS43ODg5NDgsMC43NTAyIC0zLjg1NzYsLTAuMDkyOCAtNC42MDk3MDU1LC0xLjg3NDM4IC0wLjc1MjEwNjUsLTEuNzgzMjEgJyArXG4gICAgICAgICcwLjA5MDU5OCwtMy44NDYyNyAxLjg4MDI2NDUsLTQuNTk2MDQgMS43ODgyMywtMC43NDkzNiAzLjg1Njg4MSwwLjA5MjkgNC42MDg5ODcsMS44NzQzNyAnICtcbiAgICAgICAgJzAuNzUyMTA2LDEuNzgxNjUgLTAuMDkwNiwzLjg0NjEyIC0xLjg3OTU0Niw0LjU5NjA1IHonXG4gICAgfSxcbiAgICAnVEFTS19UWVBFX0JVU0lORVNTX1JVTEVfSEVBREVSJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IDAsNCAyMCwwIDAsLTQgeidcbiAgICB9LFxuICAgICdUQVNLX1RZUEVfQlVTSU5FU1NfUlVMRV9NQUlOJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IDAsMTIgMjAsMCAwLC0xMiB6JyArXG4gICAgICAgICdtIDAsOCBsIDIwLDAgJyArXG4gICAgICAgICdtIC0xMywtNCBsIDAsOCdcbiAgICB9LFxuICAgICdNRVNTQUdFX0ZMT1dfTUFSS0VSJzoge1xuICAgICAgZDogJ20ge214fSx7bXl9IG0gLTEwLjUgLC03IGwgMCwxNCBsIDIxLDAgbCAwLC0xNCB6IGwgMTAuNSw2IGwgMTAuNSwtNidcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5nZXRSYXdQYXRoID0gZnVuY3Rpb24gZ2V0UmF3UGF0aChwYXRoSWQpIHtcbiAgICByZXR1cm4gdGhpcy5wYXRoTWFwW3BhdGhJZF0uZDtcbiAgfTtcblxuICAvKipcbiAgICogU2NhbGVzIHRoZSBwYXRoIHRvIHRoZSBnaXZlbiBoZWlnaHQgYW5kIHdpZHRoLlxuICAgKiA8aDE+VXNlIGNhc2U8L2gxPlxuICAgKiA8cD5Vc2UgY2FzZSBpcyB0byBzY2FsZSB0aGUgY29udGVudCBvZiBlbGVtZW50cyAoZXZlbnQsIGdhdGV3YXlzKSBiYXNlZFxuICAgKiBvbiB0aGUgZWxlbWVudCBib3VuZGluZyBib3gncyBzaXplLlxuICAgKiA8L3A+XG4gICAqIDxoMT5XaHkgbm90IHRyYW5zZm9ybTwvaDE+XG4gICAqIDxwPlNjYWxpbmcgYSBwYXRoIHdpdGggdHJhbnNmb3JtKCkgd2lsbCBhbHNvIHNjYWxlIHRoZSBzdHJva2UgYW5kIElFIGRvZXMgbm90IHN1cHBvcnRcbiAgICogdGhlIG9wdGlvbiAnbm9uLXNjYWxpbmctc3Ryb2tlJyB0byBwcmV2ZW50IHRoaXMuXG4gICAqIEFsc28gdGhlcmUgYXJlIHVzZSBjYXNlcyB3aGVyZSBvbmx5IHNvbWUgcGFydHMgb2YgYSBwYXRoIHNob3VsZCBiZVxuICAgKiBzY2FsZWQuPC9wPlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aElkIFRoZSBJRCBvZiB0aGUgcGF0aC5cbiAgICogQHBhcmFtIHtPYmplY3R9IHBhcmFtIDxwPlxuICAgKiAgIEV4YW1wbGUgcGFyYW0gb2JqZWN0IHNjYWxlcyB0aGUgcGF0aCB0byA2MCUgc2l6ZSBvZiB0aGUgY29udGFpbmVyIChkYXRhLndpZHRoLCBkYXRhLmhlaWdodCkuXG4gICAqICAgPHByZT5cbiAgICogICB7XG4gICAqICAgICB4U2NhbGVGYWN0b3I6IDAuNixcbiAgICogICAgIHlTY2FsZUZhY3RvcjowLjYsXG4gICAqICAgICBjb250YWluZXJXaWR0aDogZGF0YS53aWR0aCxcbiAgICogICAgIGNvbnRhaW5lckhlaWdodDogZGF0YS5oZWlnaHQsXG4gICAqICAgICBwb3NpdGlvbjoge1xuICAgKiAgICAgICBteDogMC40NixcbiAgICogICAgICAgbXk6IDAuMixcbiAgICogICAgIH1cbiAgICogICB9XG4gICAqICAgPC9wcmU+XG4gICAqICAgPHVsPlxuICAgKiAgICA8bGk+dGFyZ2V0cGF0aHdpZHRoID0geFNjYWxlRmFjdG9yICogY29udGFpbmVyV2lkdGg8L2xpPlxuICAgKiAgICA8bGk+dGFyZ2V0cGF0aGhlaWdodCA9IHlTY2FsZUZhY3RvciAqIGNvbnRhaW5lckhlaWdodDwvbGk+XG4gICAqICAgIDxsaT5Qb3NpdGlvbiBpcyB1c2VkIHRvIHNldCB0aGUgc3RhcnRpbmcgY29vcmRpbmF0ZSBvZiB0aGUgcGF0aC4gTSBpcyBjb21wdXRlZDpcbiAgICAqICAgIDx1bD5cbiAgICAqICAgICAgPGxpPnBvc2l0aW9uLnggKiBjb250YWluZXJXaWR0aDwvbGk+XG4gICAgKiAgICAgIDxsaT5wb3NpdGlvbi55ICogY29udGFpbmVySGVpZ2h0PC9saT5cbiAgICAqICAgIDwvdWw+XG4gICAgKiAgICBDZW50ZXIgb2YgdGhlIGNvbnRhaW5lciA8cHJlPiBwb3NpdGlvbjoge1xuICAgKiAgICAgICBteDogMC41LFxuICAgKiAgICAgICBteTogMC41LFxuICAgKiAgICAgfTwvcHJlPlxuICAgKiAgICAgVXBwZXIgbGVmdCBjb3JuZXIgb2YgdGhlIGNvbnRhaW5lclxuICAgKiAgICAgPHByZT4gcG9zaXRpb246IHtcbiAgICogICAgICAgbXg6IDAuMCxcbiAgICogICAgICAgbXk6IDAuMCxcbiAgICogICAgIH08L3ByZT5cbiAgICogICAgPC9saT5cbiAgICogICA8L3VsPlxuICAgKiA8L3A+XG4gICAqXG4gICAqL1xuICB0aGlzLmdldFNjYWxlZFBhdGggPSBmdW5jdGlvbiBnZXRTY2FsZWRQYXRoKHBhdGhJZCwgcGFyYW0pIHtcbiAgICB2YXIgcmF3UGF0aCA9IHRoaXMucGF0aE1hcFtwYXRoSWRdO1xuXG4gICAgLy8gcG9zaXRpb25pbmdcbiAgICAvLyBjb21wdXRlIHRoZSBzdGFydCBwb2ludCBvZiB0aGUgcGF0aFxuICAgIHZhciBteCwgbXk7XG5cbiAgICBpZiAocGFyYW0uYWJzcG9zKSB7XG4gICAgICBteCA9IHBhcmFtLmFic3Bvcy54O1xuICAgICAgbXkgPSBwYXJhbS5hYnNwb3MueTtcbiAgICB9IGVsc2Uge1xuICAgICAgbXggPSBwYXJhbS5jb250YWluZXJXaWR0aCAqIHBhcmFtLnBvc2l0aW9uLm14O1xuICAgICAgbXkgPSBwYXJhbS5jb250YWluZXJIZWlnaHQgKiBwYXJhbS5wb3NpdGlvbi5teTtcbiAgICB9XG5cbiAgICB2YXIgY29vcmRpbmF0ZXMgPSB7fTsgLy8gbWFwIGZvciB0aGUgc2NhbGVkIGNvb3JkaW5hdGVzXG4gICAgaWYgKHBhcmFtLnBvc2l0aW9uKSB7XG5cbiAgICAgIC8vIHBhdGhcbiAgICAgIHZhciBoZWlnaHRSYXRpbyA9IChwYXJhbS5jb250YWluZXJIZWlnaHQgLyByYXdQYXRoLmhlaWdodCkgKiBwYXJhbS55U2NhbGVGYWN0b3I7XG4gICAgICB2YXIgd2lkdGhSYXRpbyA9IChwYXJhbS5jb250YWluZXJXaWR0aCAvIHJhd1BhdGgud2lkdGgpICogcGFyYW0ueFNjYWxlRmFjdG9yO1xuXG5cbiAgICAgIC8vIEFwcGx5IGhlaWdodCByYXRpb1xuICAgICAgZm9yICh2YXIgaGVpZ2h0SW5kZXggPSAwOyBoZWlnaHRJbmRleCA8IHJhd1BhdGguaGVpZ2h0RWxlbWVudHMubGVuZ3RoOyBoZWlnaHRJbmRleCsrKSB7XG4gICAgICAgIGNvb3JkaW5hdGVzWyd5JyArIGhlaWdodEluZGV4XSA9IHJhd1BhdGguaGVpZ2h0RWxlbWVudHNbaGVpZ2h0SW5kZXhdICogaGVpZ2h0UmF0aW87XG4gICAgICB9XG5cbiAgICAgIC8vIEFwcGx5IHdpZHRoIHJhdGlvXG4gICAgICBmb3IgKHZhciB3aWR0aEluZGV4ID0gMDsgd2lkdGhJbmRleCA8IHJhd1BhdGgud2lkdGhFbGVtZW50cy5sZW5ndGg7IHdpZHRoSW5kZXgrKykge1xuICAgICAgICBjb29yZGluYXRlc1sneCcgKyB3aWR0aEluZGV4XSA9IHJhd1BhdGgud2lkdGhFbGVtZW50c1t3aWR0aEluZGV4XSAqIHdpZHRoUmF0aW87XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQXBwbHkgdmFsdWUgdG8gcmF3IHBhdGhcbiAgICB2YXIgcGF0aCA9IGZvcm1hdChcbiAgICAgIHJhd1BhdGguZCwge1xuICAgICAgICBteDogbXgsXG4gICAgICAgIG15OiBteSxcbiAgICAgICAgZTogY29vcmRpbmF0ZXNcbiAgICAgIH1cbiAgICApO1xuICAgIHJldHVybiBwYXRoO1xuICB9O1xufVxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLy8gY29waWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2Fkb2JlLXdlYnBsYXRmb3JtL1NuYXAuc3ZnL2Jsb2IvbWFzdGVyL3NyYy9zdmcuanNcbnZhciB0b2tlblJlZ2V4ID0gL1xceyhbXn1dKylcXH0vZyxcbiAgICBvYmpOb3RhdGlvblJlZ2V4ID0gLyg/Oig/Ol58XFwuKSguKz8pKD89XFxbfFxcLnwkfFxcKCl8XFxbKCd8XCIpKC4rPylcXDJcXF0pKFxcKFxcKSk/L2c7IC8vIG1hdGNoZXMgLnh4eHh4IG9yIFtcInh4eHh4XCJdIHRvIHJ1biBvdmVyIG9iamVjdCBwcm9wZXJ0aWVzXG5cbmZ1bmN0aW9uIHJlcGxhY2VyKGFsbCwga2V5LCBvYmopIHtcbiAgdmFyIHJlcyA9IG9iajtcbiAga2V5LnJlcGxhY2Uob2JqTm90YXRpb25SZWdleCwgZnVuY3Rpb24oYWxsLCBuYW1lLCBxdW90ZSwgcXVvdGVkTmFtZSwgaXNGdW5jKSB7XG4gICAgbmFtZSA9IG5hbWUgfHwgcXVvdGVkTmFtZTtcbiAgICBpZiAocmVzKSB7XG4gICAgICBpZiAobmFtZSBpbiByZXMpIHtcbiAgICAgICAgcmVzID0gcmVzW25hbWVdO1xuICAgICAgfVxuICAgICAgdHlwZW9mIHJlcyA9PSAnZnVuY3Rpb24nICYmIGlzRnVuYyAmJiAocmVzID0gcmVzKCkpO1xuICAgIH1cbiAgfSk7XG4gIHJlcyA9IChyZXMgPT0gbnVsbCB8fCByZXMgPT0gb2JqID8gYWxsIDogcmVzKSArICcnO1xuXG4gIHJldHVybiByZXM7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdChzdHIsIG9iaikge1xuICByZXR1cm4gU3RyaW5nKHN0cikucmVwbGFjZSh0b2tlblJlZ2V4LCBmdW5jdGlvbihhbGwsIGtleSkge1xuICAgIHJldHVybiByZXBsYWNlcihhbGwsIGtleSwgb2JqKTtcbiAgfSk7XG59XG4iLCJpbXBvcnQgeyBhc3NpZ24gfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCBUZXh0VXRpbCBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL1RleHQnO1xuXG52YXIgREVGQVVMVF9GT05UX1NJWkUgPSAxMjtcbnZhciBMSU5FX0hFSUdIVF9SQVRJTyA9IDEuMjtcblxudmFyIE1JTl9URVhUX0FOTk9UQVRJT05fSEVJR0hUID0gMzA7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVGV4dFJlbmRlcmVyKGNvbmZpZykge1xuXG4gIHZhciBkZWZhdWx0U3R5bGUgPSBhc3NpZ24oe1xuICAgIGZvbnRGYW1pbHk6ICdBcmlhbCwgc2Fucy1zZXJpZicsXG4gICAgZm9udFNpemU6IERFRkFVTFRfRk9OVF9TSVpFLFxuICAgIGZvbnRXZWlnaHQ6ICdub3JtYWwnLFxuICAgIGxpbmVIZWlnaHQ6IExJTkVfSEVJR0hUX1JBVElPXG4gIH0sIGNvbmZpZyAmJiBjb25maWcuZGVmYXVsdFN0eWxlIHx8IHt9KTtcblxuICB2YXIgZm9udFNpemUgPSBwYXJzZUludChkZWZhdWx0U3R5bGUuZm9udFNpemUsIDEwKSAtIDE7XG5cbiAgdmFyIGV4dGVybmFsU3R5bGUgPSBhc3NpZ24oe30sIGRlZmF1bHRTdHlsZSwge1xuICAgIGZvbnRTaXplOiBmb250U2l6ZVxuICB9LCBjb25maWcgJiYgY29uZmlnLmV4dGVybmFsU3R5bGUgfHwge30pO1xuXG4gIHZhciB0ZXh0VXRpbCA9IG5ldyBUZXh0VXRpbCh7XG4gICAgc3R5bGU6IGRlZmF1bHRTdHlsZVxuICB9KTtcblxuICAvKipcbiAgICogR2V0IHRoZSBuZXcgYm91bmRzIG9mIGFuIGV4dGVybmFsbHkgcmVuZGVyZWQsXG4gICAqIGxheW91dGVkIGxhYmVsLlxuICAgKlxuICAgKiBAcGFyYW0gIHtCb3VuZHN9IGJvdW5kc1xuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHRleHRcbiAgICpcbiAgICogQHJldHVybiB7Qm91bmRzfVxuICAgKi9cbiAgdGhpcy5nZXRFeHRlcm5hbExhYmVsQm91bmRzID0gZnVuY3Rpb24oYm91bmRzLCB0ZXh0KSB7XG5cbiAgICB2YXIgbGF5b3V0ZWREaW1lbnNpb25zID0gdGV4dFV0aWwuZ2V0RGltZW5zaW9ucyh0ZXh0LCB7XG4gICAgICBib3g6IHtcbiAgICAgICAgd2lkdGg6IDkwLFxuICAgICAgICBoZWlnaHQ6IDMwLFxuICAgICAgICB4OiBib3VuZHMud2lkdGggLyAyICsgYm91bmRzLngsXG4gICAgICAgIHk6IGJvdW5kcy5oZWlnaHQgLyAyICsgYm91bmRzLnlcbiAgICAgIH0sXG4gICAgICBzdHlsZTogZXh0ZXJuYWxTdHlsZVxuICAgIH0pO1xuXG4gICAgLy8gcmVzaXplIGxhYmVsIHNoYXBlIHRvIGZpdCBsYWJlbCB0ZXh0XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IE1hdGgucm91bmQoYm91bmRzLnggKyBib3VuZHMud2lkdGggLyAyIC0gbGF5b3V0ZWREaW1lbnNpb25zLndpZHRoIC8gMiksXG4gICAgICB5OiBNYXRoLnJvdW5kKGJvdW5kcy55KSxcbiAgICAgIHdpZHRoOiBNYXRoLmNlaWwobGF5b3V0ZWREaW1lbnNpb25zLndpZHRoKSxcbiAgICAgIGhlaWdodDogTWF0aC5jZWlsKGxheW91dGVkRGltZW5zaW9ucy5oZWlnaHQpXG4gICAgfTtcblxuICB9O1xuXG4gIC8qKlxuICAgKiBHZXQgdGhlIG5ldyBib3VuZHMgb2YgdGV4dCBhbm5vdGF0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gIHtCb3VuZHN9IGJvdW5kc1xuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHRleHRcbiAgICpcbiAgICogQHJldHVybiB7Qm91bmRzfVxuICAgKi9cbiAgdGhpcy5nZXRUZXh0QW5ub3RhdGlvbkJvdW5kcyA9IGZ1bmN0aW9uKGJvdW5kcywgdGV4dCkge1xuXG4gICAgdmFyIGxheW91dGVkRGltZW5zaW9ucyA9IHRleHRVdGlsLmdldERpbWVuc2lvbnModGV4dCwge1xuICAgICAgYm94OiBib3VuZHMsXG4gICAgICBzdHlsZTogZGVmYXVsdFN0eWxlLFxuICAgICAgYWxpZ246ICdsZWZ0LXRvcCcsXG4gICAgICBwYWRkaW5nOiA1XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgeDogYm91bmRzLngsXG4gICAgICB5OiBib3VuZHMueSxcbiAgICAgIHdpZHRoOiBib3VuZHMud2lkdGgsXG4gICAgICBoZWlnaHQ6IE1hdGgubWF4KE1JTl9URVhUX0FOTk9UQVRJT05fSEVJR0hULCBNYXRoLnJvdW5kKGxheW91dGVkRGltZW5zaW9ucy5oZWlnaHQpKVxuICAgIH07XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGxheW91dGVkIHRleHQgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSByZW5kZXJlZCB0ZXh0XG4gICAqL1xuICB0aGlzLmNyZWF0ZVRleHQgPSBmdW5jdGlvbih0ZXh0LCBvcHRpb25zKSB7XG4gICAgcmV0dXJuIHRleHRVdGlsLmNyZWF0ZVRleHQodGV4dCwgb3B0aW9ucyB8fCB7fSk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEdldCBkZWZhdWx0IHRleHQgc3R5bGUuXG4gICAqL1xuICB0aGlzLmdldERlZmF1bHRTdHlsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkZWZhdWx0U3R5bGU7XG4gIH07XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZXh0ZXJuYWwgdGV4dCBzdHlsZS5cbiAgICovXG4gIHRoaXMuZ2V0RXh0ZXJuYWxTdHlsZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBleHRlcm5hbFN0eWxlO1xuICB9O1xuXG59XG5cblRleHRSZW5kZXJlci4kaW5qZWN0ID0gW1xuICAnY29uZmlnLnRleHRSZW5kZXJlcidcbl07IiwiaW1wb3J0IEJwbW5SZW5kZXJlciBmcm9tICcuL0JwbW5SZW5kZXJlcic7XG5pbXBvcnQgVGV4dFJlbmRlcmVyIGZyb20gJy4vVGV4dFJlbmRlcmVyJztcblxuaW1wb3J0IFBhdGhNYXAgZnJvbSAnLi9QYXRoTWFwJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnYnBtblJlbmRlcmVyJyBdLFxuICBicG1uUmVuZGVyZXI6IFsgJ3R5cGUnLCBCcG1uUmVuZGVyZXIgXSxcbiAgdGV4dFJlbmRlcmVyOiBbICd0eXBlJywgVGV4dFJlbmRlcmVyIF0sXG4gIHBhdGhNYXA6IFsgJ3R5cGUnLCBQYXRoTWFwIF1cbn07XG4iLCJpbXBvcnQgeyBnZXROZXdTaGFwZVBvc2l0aW9uIH0gZnJvbSAnLi9CcG1uQXV0b1BsYWNlVXRpbCc7XG5cblxuLyoqXG4gKiBCUE1OIGF1dG8tcGxhY2UgYmVoYXZpb3IuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1BsYWNlKGV2ZW50QnVzKSB7XG4gIGV2ZW50QnVzLm9uKCdhdXRvUGxhY2UnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2U7XG5cbiAgICByZXR1cm4gZ2V0TmV3U2hhcGVQb3NpdGlvbihzb3VyY2UsIHNoYXBlKTtcbiAgfSk7XG59XG5cbkF1dG9QbGFjZS4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07IiwiaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5pbXBvcnQgeyBpc0FueSB9IGZyb20gJy4uL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0TWlkLFxuICBhc1RSQkwsXG4gIGdldE9yaWVudGF0aW9uXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgZmluZEZyZWVQb3NpdGlvbixcbiAgZ2VuZXJhdGVHZXROZXh0UG9zaXRpb24sXG4gIGdldENvbm5lY3RlZERpc3RhbmNlXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2F1dG8tcGxhY2UvQXV0b1BsYWNlVXRpbCc7XG5cblxuLyoqXG4gKiBGaW5kIHRoZSBuZXcgcG9zaXRpb24gZm9yIHRoZSB0YXJnZXQgZWxlbWVudCB0b1xuICogY29ubmVjdCB0byBzb3VyY2UuXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLlNoYXBlfSBzb3VyY2VcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5TaGFwZX0gZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmV3U2hhcGVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQpIHtcblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46VGV4dEFubm90YXRpb24nKSkge1xuICAgIHJldHVybiBnZXRUZXh0QW5ub3RhdGlvblBvc2l0aW9uKHNvdXJjZSwgZWxlbWVudCk7XG4gIH1cblxuICBpZiAoaXNBbnkoZWxlbWVudCwgWyAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJywgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJyBdKSkge1xuICAgIHJldHVybiBnZXREYXRhRWxlbWVudFBvc2l0aW9uKHNvdXJjZSwgZWxlbWVudCk7XG4gIH1cblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46Rmxvd05vZGUnKSkge1xuICAgIHJldHVybiBnZXRGbG93Tm9kZVBvc2l0aW9uKHNvdXJjZSwgZWxlbWVudCk7XG4gIH1cbn1cblxuLyoqXG4gKiBBbHdheXMgdHJ5IHRvIHBsYWNlIGVsZW1lbnQgcmlnaHQgb2Ygc291cmNlO1xuICogY29tcHV0ZSBhY3R1YWwgZGlzdGFuY2UgZnJvbSBwcmV2aW91cyBub2RlcyBpbiBmbG93LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rmxvd05vZGVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQpIHtcblxuICB2YXIgc291cmNlVHJibCA9IGFzVFJCTChzb3VyY2UpO1xuICB2YXIgc291cmNlTWlkID0gZ2V0TWlkKHNvdXJjZSk7XG5cbiAgdmFyIGhvcml6b250YWxEaXN0YW5jZSA9IGdldENvbm5lY3RlZERpc3RhbmNlKHNvdXJjZSwge1xuICAgIGZpbHRlcjogZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgcmV0dXJuIGlzKGNvbm5lY3Rpb24sICdicG1uOlNlcXVlbmNlRmxvdycpO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIG1hcmdpbiA9IDMwLFxuICAgICAgbWluRGlzdGFuY2UgPSA4MCxcbiAgICAgIG9yaWVudGF0aW9uID0gJ2xlZnQnO1xuXG4gIGlmIChpcyhzb3VyY2UsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSkge1xuICAgIG9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24oc291cmNlLCBzb3VyY2UuaG9zdCwgLTI1KTtcblxuICAgIGlmIChvcmllbnRhdGlvbi5pbmRleE9mKCd0b3AnKSAhPT0gLTEpIHtcbiAgICAgIG1hcmdpbiAqPSAtMTtcbiAgICB9XG4gIH1cblxuICB2YXIgcG9zaXRpb24gPSB7XG4gICAgeDogc291cmNlVHJibC5yaWdodCArIGhvcml6b250YWxEaXN0YW5jZSArIGVsZW1lbnQud2lkdGggLyAyLFxuICAgIHk6IHNvdXJjZU1pZC55ICsgZ2V0VmVydGljYWxEaXN0YW5jZShvcmllbnRhdGlvbiwgbWluRGlzdGFuY2UpXG4gIH07XG5cbiAgdmFyIG5leHRQb3NpdGlvbkRpcmVjdGlvbiA9IHtcbiAgICB5OiB7XG4gICAgICBtYXJnaW46IG1hcmdpbixcbiAgICAgIG1pbkRpc3RhbmNlOiBtaW5EaXN0YW5jZVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gZmluZEZyZWVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQsIHBvc2l0aW9uLCBnZW5lcmF0ZUdldE5leHRQb3NpdGlvbihuZXh0UG9zaXRpb25EaXJlY3Rpb24pKTtcbn1cblxuXG5mdW5jdGlvbiBnZXRWZXJ0aWNhbERpc3RhbmNlKG9yaWVudGF0aW9uLCBtaW5EaXN0YW5jZSkge1xuICBpZiAob3JpZW50YXRpb24uaW5kZXhPZigndG9wJykgIT0gLTEpIHtcbiAgICByZXR1cm4gLTEgKiBtaW5EaXN0YW5jZTtcbiAgfSBlbHNlIGlmIChvcmllbnRhdGlvbi5pbmRleE9mKCdib3R0b20nKSAhPSAtMSkge1xuICAgIHJldHVybiBtaW5EaXN0YW5jZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gMDtcbiAgfVxufVxuXG5cbi8qKlxuICogQWx3YXlzIHRyeSB0byBwbGFjZSB0ZXh0IGFubm90YXRpb25zIHRvcCByaWdodCBvZiBzb3VyY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUZXh0QW5ub3RhdGlvblBvc2l0aW9uKHNvdXJjZSwgZWxlbWVudCkge1xuXG4gIHZhciBzb3VyY2VUcmJsID0gYXNUUkJMKHNvdXJjZSk7XG5cbiAgdmFyIHBvc2l0aW9uID0ge1xuICAgIHg6IHNvdXJjZVRyYmwucmlnaHQgKyBlbGVtZW50LndpZHRoIC8gMixcbiAgICB5OiBzb3VyY2VUcmJsLnRvcCAtIDUwIC0gZWxlbWVudC5oZWlnaHQgLyAyXG4gIH07XG5cbiAgdmFyIG5leHRQb3NpdGlvbkRpcmVjdGlvbiA9IHtcbiAgICB5OiB7XG4gICAgICBtYXJnaW46IC0zMCxcbiAgICAgIG1pbkRpc3RhbmNlOiAyMFxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gZmluZEZyZWVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQsIHBvc2l0aW9uLCBnZW5lcmF0ZUdldE5leHRQb3NpdGlvbihuZXh0UG9zaXRpb25EaXJlY3Rpb24pKTtcbn1cblxuXG4vKipcbiAqIEFsd2F5cyBwdXQgZWxlbWVudCBib3R0b20gcmlnaHQgb2Ygc291cmNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGF0YUVsZW1lbnRQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQpIHtcblxuICB2YXIgc291cmNlVHJibCA9IGFzVFJCTChzb3VyY2UpO1xuXG4gIHZhciBwb3NpdGlvbiA9IHtcbiAgICB4OiBzb3VyY2VUcmJsLnJpZ2h0IC0gMTAgKyBlbGVtZW50LndpZHRoIC8gMixcbiAgICB5OiBzb3VyY2VUcmJsLmJvdHRvbSArIDQwICsgZWxlbWVudC53aWR0aCAvIDJcbiAgfTtcblxuICB2YXIgbmV4dFBvc2l0aW9uRGlyZWN0aW9uID0ge1xuICAgIHg6IHtcbiAgICAgIG1hcmdpbjogMzAsXG4gICAgICBtaW5EaXN0YW5jZTogMzBcbiAgICB9XG4gIH07XG5cbiAgcmV0dXJuIGZpbmRGcmVlUG9zaXRpb24oc291cmNlLCBlbGVtZW50LCBwb3NpdGlvbiwgZ2VuZXJhdGVHZXROZXh0UG9zaXRpb24obmV4dFBvc2l0aW9uRGlyZWN0aW9uKSk7XG59IiwiaW1wb3J0IEF1dG9QbGFjZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9hdXRvLXBsYWNlJztcblxuaW1wb3J0IEJwbW5BdXRvUGxhY2UgZnJvbSAnLi9CcG1uQXV0b1BsYWNlJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogWyBBdXRvUGxhY2VNb2R1bGUgXSxcbiAgX19pbml0X186IFsgJ2JwbW5BdXRvUGxhY2UnIF0sXG4gIGJwbW5BdXRvUGxhY2U6IFsgJ3R5cGUnLCBCcG1uQXV0b1BsYWNlIF1cbn07IiwiaW1wb3J0IEF1dG9SZXNpemUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1yZXNpemUvQXV0b1Jlc2l6ZSc7XG5cbmltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5cbi8qKlxuICogU3ViIGNsYXNzIG9mIHRoZSBBdXRvUmVzaXplIG1vZHVsZSB3aGljaCBpbXBsZW1lbnRzIGEgQlBNTlxuICogc3BlY2lmaWMgcmVzaXplIGZ1bmN0aW9uLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uQXV0b1Jlc2l6ZShpbmplY3Rvcikge1xuXG4gIGluamVjdG9yLmludm9rZShBdXRvUmVzaXplLCB0aGlzKTtcbn1cblxuQnBtbkF1dG9SZXNpemUuJGluamVjdCA9IFtcbiAgJ2luamVjdG9yJ1xuXTtcblxuaW5oZXJpdHMoQnBtbkF1dG9SZXNpemUsIEF1dG9SZXNpemUpO1xuXG5cbi8qKlxuICogUmVzaXplIHNoYXBlcyBhbmQgbGFuZXMuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHRhcmdldFxuICogQHBhcmFtIHtCb3VuZHN9IG5ld0JvdW5kc1xuICogQHBhcmFtIHtPYmplY3R9IGhpbnRzXG4gKi9cbkJwbW5BdXRvUmVzaXplLnByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbih0YXJnZXQsIG5ld0JvdW5kcywgaGludHMpIHtcblxuICBpZiAoaXModGFyZ2V0LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgdGhpcy5fbW9kZWxpbmcucmVzaXplTGFuZSh0YXJnZXQsIG5ld0JvdW5kcywgbnVsbCwgaGludHMpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuX21vZGVsaW5nLnJlc2l6ZVNoYXBlKHRhcmdldCwgbmV3Qm91bmRzLCBudWxsLCBoaW50cyk7XG4gIH1cbn07IiwiaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCBBdXRvUmVzaXplUHJvdmlkZXIgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXV0by1yZXNpemUvQXV0b1Jlc2l6ZVByb3ZpZGVyJztcblxuXG4vKipcbiAqIFRoaXMgbW9kdWxlIGlzIGEgcHJvdmlkZXIgZm9yIGF1dG9tYXRpY2FsbHkgcmVzaXppbmcgcGFyZW50IEJQTU4gZWxlbWVudHNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkF1dG9SZXNpemVQcm92aWRlcihldmVudEJ1cywgbW9kZWxpbmcpIHtcbiAgQXV0b1Jlc2l6ZVByb3ZpZGVyLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cbmluaGVyaXRzKEJwbW5BdXRvUmVzaXplUHJvdmlkZXIsIEF1dG9SZXNpemVQcm92aWRlcik7XG5cbkJwbW5BdXRvUmVzaXplUHJvdmlkZXIuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSBnaXZlbiB0YXJnZXQgY2FuIGJlIGV4cGFuZGVkXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLlNoYXBlfSB0YXJnZXRcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5CcG1uQXV0b1Jlc2l6ZVByb3ZpZGVyLnByb3RvdHlwZS5jYW5SZXNpemUgPSBmdW5jdGlvbihlbGVtZW50cywgdGFyZ2V0KSB7XG5cbiAgaWYgKCFpcyh0YXJnZXQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgIWlzKHRhcmdldCwgJ2JwbW46TGFuZScpICYmICEoaXModGFyZ2V0LCAnYnBtbjpTdWJQcm9jZXNzJykpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIGNhblJlc2l6ZSA9IHRydWU7XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkxhbmUnKSB8fCBlbGVtZW50LmxhYmVsVGFyZ2V0KSB7XG4gICAgICBjYW5SZXNpemUgPSBmYWxzZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBjYW5SZXNpemU7XG59O1xuIiwiaW1wb3J0IEJwbW5BdXRvUmVzaXplIGZyb20gJy4vQnBtbkF1dG9SZXNpemUnO1xuaW1wb3J0IEJwbW5BdXRvUmVzaXplUHJvdmlkZXIgZnJvbSAnLi9CcG1uQXV0b1Jlc2l6ZVByb3ZpZGVyJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbXG4gICAgJ2JwbW5BdXRvUmVzaXplJyxcbiAgICAnYnBtbkF1dG9SZXNpemVQcm92aWRlcidcbiAgXSxcbiAgYnBtbkF1dG9SZXNpemU6IFsgJ3R5cGUnLCBCcG1uQXV0b1Jlc2l6ZSBdLFxuICBicG1uQXV0b1Jlc2l6ZVByb3ZpZGVyOiBbICd0eXBlJywgQnBtbkF1dG9SZXNpemVQcm92aWRlciBdXG59O1xuIiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmb3JFYWNoLFxuICBpc0FycmF5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgaXNcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0V4cGFuZGVkLFxuICBpc0V2ZW50U3ViUHJvY2Vzc1xufSBmcm9tICcuLi8uLi91dGlsL0RpVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzQW55XG59IGZyb20gJy4uL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0Q2hpbGRMYW5lc1xufSBmcm9tICcuLi9tb2RlbGluZy91dGlsL0xhbmVVdGlsJztcblxuaW1wb3J0IHtcbiAgaGFzUHJpbWFyeU1vZGlmaWVyXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvTW91c2UnO1xuXG5cbi8qKlxuICogQSBwcm92aWRlciBmb3IgQlBNTiAyLjAgZWxlbWVudHMgY29udGV4dCBwYWRcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ29udGV4dFBhZFByb3ZpZGVyKFxuICAgIGNvbmZpZywgaW5qZWN0b3IsIGV2ZW50QnVzLFxuICAgIGNvbnRleHRQYWQsIG1vZGVsaW5nLCBlbGVtZW50RmFjdG9yeSxcbiAgICBjb25uZWN0LCBjcmVhdGUsIHBvcHVwTWVudSxcbiAgICBjYW52YXMsIHJ1bGVzLCB0cmFuc2xhdGUpIHtcblxuICBjb25maWcgPSBjb25maWcgfHwge307XG5cbiAgY29udGV4dFBhZC5yZWdpc3RlclByb3ZpZGVyKHRoaXMpO1xuXG4gIHRoaXMuX2NvbnRleHRQYWQgPSBjb250ZXh0UGFkO1xuXG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG5cbiAgdGhpcy5fZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcbiAgdGhpcy5fY29ubmVjdCA9IGNvbm5lY3Q7XG4gIHRoaXMuX2NyZWF0ZSA9IGNyZWF0ZTtcbiAgdGhpcy5fcG9wdXBNZW51ID0gcG9wdXBNZW51O1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX3J1bGVzID0gcnVsZXM7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcblxuICBpZiAoY29uZmlnLmF1dG9QbGFjZSAhPT0gZmFsc2UpIHtcbiAgICB0aGlzLl9hdXRvUGxhY2UgPSBpbmplY3Rvci5nZXQoJ2F1dG9QbGFjZScsIGZhbHNlKTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjcmVhdGUuZW5kJywgMjUwLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKCFoYXNQcmltYXJ5TW9kaWZpZXIoZXZlbnQpIHx8ICFjb250ZXh0UGFkLmlzT3BlbihzaGFwZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZW50cmllcyA9IGNvbnRleHRQYWQuZ2V0RW50cmllcyhzaGFwZSk7XG5cbiAgICBpZiAoZW50cmllcy5yZXBsYWNlKSB7XG4gICAgICBlbnRyaWVzLnJlcGxhY2UuYWN0aW9uLmNsaWNrKGV2ZW50LCBzaGFwZSk7XG4gICAgfVxuICB9KTtcbn1cblxuQ29udGV4dFBhZFByb3ZpZGVyLiRpbmplY3QgPSBbXG4gICdjb25maWcuY29udGV4dFBhZCcsXG4gICdpbmplY3RvcicsXG4gICdldmVudEJ1cycsXG4gICdjb250ZXh0UGFkJyxcbiAgJ21vZGVsaW5nJyxcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcbiAgJ2Nvbm5lY3QnLFxuICAnY3JlYXRlJyxcbiAgJ3BvcHVwTWVudScsXG4gICdjYW52YXMnLFxuICAncnVsZXMnLFxuICAndHJhbnNsYXRlJ1xuXTtcblxuXG5Db250ZXh0UGFkUHJvdmlkZXIucHJvdG90eXBlLmdldENvbnRleHRQYWRFbnRyaWVzID0gZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gIHZhciBjb250ZXh0UGFkID0gdGhpcy5fY29udGV4dFBhZCxcbiAgICAgIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmcsXG5cbiAgICAgIGVsZW1lbnRGYWN0b3J5ID0gdGhpcy5fZWxlbWVudEZhY3RvcnksXG4gICAgICBjb25uZWN0ID0gdGhpcy5fY29ubmVjdCxcbiAgICAgIGNyZWF0ZSA9IHRoaXMuX2NyZWF0ZSxcbiAgICAgIHBvcHVwTWVudSA9IHRoaXMuX3BvcHVwTWVudSxcbiAgICAgIGNhbnZhcyA9IHRoaXMuX2NhbnZhcyxcbiAgICAgIHJ1bGVzID0gdGhpcy5fcnVsZXMsXG4gICAgICBhdXRvUGxhY2UgPSB0aGlzLl9hdXRvUGxhY2UsXG4gICAgICB0cmFuc2xhdGUgPSB0aGlzLl90cmFuc2xhdGU7XG5cbiAgdmFyIGFjdGlvbnMgPSB7fTtcblxuICBpZiAoZWxlbWVudC50eXBlID09PSAnbGFiZWwnKSB7XG4gICAgcmV0dXJuIGFjdGlvbnM7XG4gIH1cblxuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0O1xuXG4gIGZ1bmN0aW9uIHN0YXJ0Q29ubmVjdChldmVudCwgZWxlbWVudCkge1xuICAgIGNvbm5lY3Quc3RhcnQoZXZlbnQsIGVsZW1lbnQpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVtb3ZlRWxlbWVudChlKSB7XG4gICAgbW9kZWxpbmcucmVtb3ZlRWxlbWVudHMoWyBlbGVtZW50IF0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0UmVwbGFjZU1lbnVQb3NpdGlvbihlbGVtZW50KSB7XG5cbiAgICB2YXIgWV9PRkZTRVQgPSA1O1xuXG4gICAgdmFyIGRpYWdyYW1Db250YWluZXIgPSBjYW52YXMuZ2V0Q29udGFpbmVyKCksXG4gICAgICAgIHBhZCA9IGNvbnRleHRQYWQuZ2V0UGFkKGVsZW1lbnQpLmh0bWw7XG5cbiAgICB2YXIgZGlhZ3JhbVJlY3QgPSBkaWFncmFtQ29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgICBwYWRSZWN0ID0gcGFkLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgdmFyIHRvcCA9IHBhZFJlY3QudG9wIC0gZGlhZ3JhbVJlY3QudG9wO1xuICAgIHZhciBsZWZ0ID0gcGFkUmVjdC5sZWZ0IC0gZGlhZ3JhbVJlY3QubGVmdDtcblxuICAgIHZhciBwb3MgPSB7XG4gICAgICB4OiBsZWZ0LFxuICAgICAgeTogdG9wICsgcGFkUmVjdC5oZWlnaHQgKyBZX09GRlNFVFxuICAgIH07XG5cbiAgICByZXR1cm4gcG9zO1xuICB9XG5cblxuICAvKipcbiAgICogQ3JlYXRlIGFuIGFwcGVuZCBhY3Rpb25cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAgICogQHBhcmFtIHtzdHJpbmd9IGNsYXNzTmFtZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3RpdGxlXVxuICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gICAqXG4gICAqIEByZXR1cm4ge09iamVjdH0gZGVzY3JpcHRvclxuICAgKi9cbiAgZnVuY3Rpb24gYXBwZW5kQWN0aW9uKHR5cGUsIGNsYXNzTmFtZSwgdGl0bGUsIG9wdGlvbnMpIHtcblxuICAgIGlmICh0eXBlb2YgdGl0bGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zID0gdGl0bGU7XG4gICAgICB0aXRsZSA9IHRyYW5zbGF0ZSgnQXBwZW5kIHt0eXBlfScsIHsgdHlwZTogdHlwZS5yZXBsYWNlKC9eYnBtbjovLCAnJykgfSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYXBwZW5kU3RhcnQoZXZlbnQsIGVsZW1lbnQpIHtcblxuICAgICAgdmFyIHNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoYXNzaWduKHsgdHlwZTogdHlwZSB9LCBvcHRpb25zKSk7XG4gICAgICBjcmVhdGUuc3RhcnQoZXZlbnQsIHNoYXBlLCB7XG4gICAgICAgIHNvdXJjZTogZWxlbWVudFxuICAgICAgfSk7XG4gICAgfVxuXG5cbiAgICB2YXIgYXBwZW5kID0gYXV0b1BsYWNlID8gZnVuY3Rpb24oZXZlbnQsIGVsZW1lbnQpIHtcbiAgICAgIHZhciBzaGFwZSA9IGVsZW1lbnRGYWN0b3J5LmNyZWF0ZVNoYXBlKGFzc2lnbih7IHR5cGU6IHR5cGUgfSwgb3B0aW9ucykpO1xuXG4gICAgICBhdXRvUGxhY2UuYXBwZW5kKGVsZW1lbnQsIHNoYXBlKTtcbiAgICB9IDogYXBwZW5kU3RhcnQ7XG5cblxuICAgIHJldHVybiB7XG4gICAgICBncm91cDogJ21vZGVsJyxcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgYWN0aW9uOiB7XG4gICAgICAgIGRyYWdzdGFydDogYXBwZW5kU3RhcnQsXG4gICAgICAgIGNsaWNrOiBhcHBlbmRcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gc3BsaXRMYW5lSGFuZGxlcihjb3VudCkge1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50LCBlbGVtZW50KSB7XG5cbiAgICAgIC8vIGFjdHVhbCBzcGxpdFxuICAgICAgbW9kZWxpbmcuc3BsaXRMYW5lKGVsZW1lbnQsIGNvdW50KTtcblxuICAgICAgLy8gcmVmcmVzaCBjb250ZXh0IHBhZCBhZnRlciBzcGxpdCB0b1xuICAgICAgLy8gZ2V0IHJpZCBvZiBzcGxpdCBpY29uc1xuICAgICAgY29udGV4dFBhZC5vcGVuKGVsZW1lbnQsIHRydWUpO1xuICAgIH07XG4gIH1cblxuXG4gIGlmIChpc0FueShidXNpbmVzc09iamVjdCwgWyAnYnBtbjpMYW5lJywgJ2JwbW46UGFydGljaXBhbnQnIF0pICYmIGlzRXhwYW5kZWQoYnVzaW5lc3NPYmplY3QpKSB7XG5cbiAgICB2YXIgY2hpbGRMYW5lcyA9IGdldENoaWxkTGFuZXMoZWxlbWVudCk7XG5cbiAgICBhc3NpZ24oYWN0aW9ucywge1xuICAgICAgJ2xhbmUtaW5zZXJ0LWFib3ZlJzoge1xuICAgICAgICBncm91cDogJ2xhbmUtaW5zZXJ0LWFib3ZlJyxcbiAgICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWxhbmUtaW5zZXJ0LWFib3ZlJyxcbiAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQWRkIExhbmUgYWJvdmUnKSxcbiAgICAgICAgYWN0aW9uOiB7XG4gICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uKGV2ZW50LCBlbGVtZW50KSB7XG4gICAgICAgICAgICBtb2RlbGluZy5hZGRMYW5lKGVsZW1lbnQsICd0b3AnKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGlmIChjaGlsZExhbmVzLmxlbmd0aCA8IDIpIHtcblxuICAgICAgaWYgKGVsZW1lbnQuaGVpZ2h0ID49IDEyMCkge1xuICAgICAgICBhc3NpZ24oYWN0aW9ucywge1xuICAgICAgICAgICdsYW5lLWRpdmlkZS10d28nOiB7XG4gICAgICAgICAgICBncm91cDogJ2xhbmUtZGl2aWRlJyxcbiAgICAgICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sYW5lLWRpdmlkZS10d28nLFxuICAgICAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnRGl2aWRlIGludG8gdHdvIExhbmVzJyksXG4gICAgICAgICAgICBhY3Rpb246IHtcbiAgICAgICAgICAgICAgY2xpY2s6IHNwbGl0TGFuZUhhbmRsZXIoMilcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICBpZiAoZWxlbWVudC5oZWlnaHQgPj0gMTgwKSB7XG4gICAgICAgIGFzc2lnbihhY3Rpb25zLCB7XG4gICAgICAgICAgJ2xhbmUtZGl2aWRlLXRocmVlJzoge1xuICAgICAgICAgICAgZ3JvdXA6ICdsYW5lLWRpdmlkZScsXG4gICAgICAgICAgICBjbGFzc05hbWU6ICdicG1uLWljb24tbGFuZS1kaXZpZGUtdGhyZWUnLFxuICAgICAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnRGl2aWRlIGludG8gdGhyZWUgTGFuZXMnKSxcbiAgICAgICAgICAgIGFjdGlvbjoge1xuICAgICAgICAgICAgICBjbGljazogc3BsaXRMYW5lSGFuZGxlcigzKVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdsYW5lLWluc2VydC1iZWxvdyc6IHtcbiAgICAgICAgZ3JvdXA6ICdsYW5lLWluc2VydC1iZWxvdycsXG4gICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sYW5lLWluc2VydC1iZWxvdycsXG4gICAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FkZCBMYW5lIGJlbG93JyksXG4gICAgICAgIGFjdGlvbjoge1xuICAgICAgICAgIGNsaWNrOiBmdW5jdGlvbihldmVudCwgZWxlbWVudCkge1xuICAgICAgICAgICAgbW9kZWxpbmcuYWRkTGFuZShlbGVtZW50LCAnYm90dG9tJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgfVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46Rmxvd05vZGUnKSkge1xuXG4gICAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpFdmVudEJhc2VkR2F0ZXdheScpKSB7XG5cbiAgICAgIGFzc2lnbihhY3Rpb25zLCB7XG4gICAgICAgICdhcHBlbmQucmVjZWl2ZS10YXNrJzogYXBwZW5kQWN0aW9uKFxuICAgICAgICAgICdicG1uOlJlY2VpdmVUYXNrJyxcbiAgICAgICAgICAnYnBtbi1pY29uLXJlY2VpdmUtdGFzaycsXG4gICAgICAgICAgdHJhbnNsYXRlKCdBcHBlbmQgUmVjZWl2ZVRhc2snKVxuICAgICAgICApLFxuICAgICAgICAnYXBwZW5kLm1lc3NhZ2UtaW50ZXJtZWRpYXRlLWV2ZW50JzogYXBwZW5kQWN0aW9uKFxuICAgICAgICAgICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnLFxuICAgICAgICAgICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW1lc3NhZ2UnLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIE1lc3NhZ2VJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyksXG4gICAgICAgICAgeyBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpNZXNzYWdlRXZlbnREZWZpbml0aW9uJyB9XG4gICAgICAgICksXG4gICAgICAgICdhcHBlbmQudGltZXItaW50ZXJtZWRpYXRlLWV2ZW50JzogYXBwZW5kQWN0aW9uKFxuICAgICAgICAgICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnLFxuICAgICAgICAgICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLXRpbWVyJyxcbiAgICAgICAgICB0cmFuc2xhdGUoJ0FwcGVuZCBUaW1lckludGVybWVkaWF0ZUNhdGNoRXZlbnQnKSxcbiAgICAgICAgICB7IGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlRpbWVyRXZlbnREZWZpbml0aW9uJyB9XG4gICAgICAgICksXG4gICAgICAgICdhcHBlbmQuY29uZGl0aW9uLWludGVybWVkaWF0ZS1ldmVudCc6IGFwcGVuZEFjdGlvbihcbiAgICAgICAgICAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyxcbiAgICAgICAgICAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb25kaXRpb24nLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIENvbmRpdGlvbkludGVybWVkaWF0ZUNhdGNoRXZlbnQnKSxcbiAgICAgICAgICB7IGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJyB9XG4gICAgICAgICksXG4gICAgICAgICdhcHBlbmQuc2lnbmFsLWludGVybWVkaWF0ZS1ldmVudCc6IGFwcGVuZEFjdGlvbihcbiAgICAgICAgICAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyxcbiAgICAgICAgICAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1zaWduYWwnLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIFNpZ25hbEludGVybWVkaWF0ZUNhdGNoRXZlbnQnKSxcbiAgICAgICAgICB7IGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbicgfVxuICAgICAgICApXG4gICAgICB9KTtcbiAgICB9IGVsc2VcblxuICAgIGlmIChpc0V2ZW50VHlwZShidXNpbmVzc09iamVjdCwgJ2JwbW46Qm91bmRhcnlFdmVudCcsICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nKSkge1xuXG4gICAgICBhc3NpZ24oYWN0aW9ucywge1xuICAgICAgICAnYXBwZW5kLmNvbXBlbnNhdGlvbi1hY3Rpdml0eSc6XG4gICAgICAgICAgICBhcHBlbmRBY3Rpb24oXG4gICAgICAgICAgICAgICdicG1uOlRhc2snLFxuICAgICAgICAgICAgICAnYnBtbi1pY29uLXRhc2snLFxuICAgICAgICAgICAgICB0cmFuc2xhdGUoJ0FwcGVuZCBjb21wZW5zYXRpb24gYWN0aXZpdHknKSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGlzRm9yQ29tcGVuc2F0aW9uOiB0cnVlXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIClcbiAgICAgIH0pO1xuICAgIH0gZWxzZVxuXG4gICAgaWYgKCFpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46RW5kRXZlbnQnKSAmJlxuICAgICAgICAhYnVzaW5lc3NPYmplY3QuaXNGb3JDb21wZW5zYXRpb24gJiZcbiAgICAgICAgIWlzRXZlbnRUeXBlKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JywgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpICYmXG4gICAgICAgICFpc0V2ZW50U3ViUHJvY2VzcyhidXNpbmVzc09iamVjdCkpIHtcblxuICAgICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICAgJ2FwcGVuZC5lbmQtZXZlbnQnOiBhcHBlbmRBY3Rpb24oXG4gICAgICAgICAgJ2JwbW46RW5kRXZlbnQnLFxuICAgICAgICAgICdicG1uLWljb24tZW5kLWV2ZW50LW5vbmUnLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIEVuZEV2ZW50JylcbiAgICAgICAgKSxcbiAgICAgICAgJ2FwcGVuZC5nYXRld2F5JzogYXBwZW5kQWN0aW9uKFxuICAgICAgICAgICdicG1uOkV4Y2x1c2l2ZUdhdGV3YXknLFxuICAgICAgICAgICdicG1uLWljb24tZ2F0ZXdheS1ub25lJyxcbiAgICAgICAgICB0cmFuc2xhdGUoJ0FwcGVuZCBHYXRld2F5JylcbiAgICAgICAgKSxcbiAgICAgICAgJ2FwcGVuZC5hcHBlbmQtdGFzayc6IGFwcGVuZEFjdGlvbihcbiAgICAgICAgICAnYnBtbjpUYXNrJyxcbiAgICAgICAgICAnYnBtbi1pY29uLXRhc2snLFxuICAgICAgICAgIHRyYW5zbGF0ZSgnQXBwZW5kIFRhc2snKVxuICAgICAgICApLFxuICAgICAgICAnYXBwZW5kLmludGVybWVkaWF0ZS1ldmVudCc6IGFwcGVuZEFjdGlvbihcbiAgICAgICAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcbiAgICAgICAgICAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1ub25lJyxcbiAgICAgICAgICB0cmFuc2xhdGUoJ0FwcGVuZCBJbnRlcm1lZGlhdGUvQm91bmRhcnkgRXZlbnQnKVxuICAgICAgICApXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXBvcHVwTWVudS5pc0VtcHR5KGVsZW1lbnQsICdicG1uLXJlcGxhY2UnKSkge1xuXG4gICAgLy8gUmVwbGFjZSBtZW51IGVudHJ5XG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdyZXBsYWNlJzoge1xuICAgICAgICBncm91cDogJ2VkaXQnLFxuICAgICAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc2NyZXctd3JlbmNoJyxcbiAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQ2hhbmdlIHR5cGUnKSxcbiAgICAgICAgYWN0aW9uOiB7XG4gICAgICAgICAgY2xpY2s6IGZ1bmN0aW9uKGV2ZW50LCBlbGVtZW50KSB7XG5cbiAgICAgICAgICAgIHZhciBwb3NpdGlvbiA9IGFzc2lnbihnZXRSZXBsYWNlTWVudVBvc2l0aW9uKGVsZW1lbnQpLCB7XG4gICAgICAgICAgICAgIGN1cnNvcjogeyB4OiBldmVudC54LCB5OiBldmVudC55IH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBwb3B1cE1lbnUub3BlbihlbGVtZW50LCAnYnBtbi1yZXBsYWNlJywgcG9zaXRpb24pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGlzQW55KGJ1c2luZXNzT2JqZWN0LCBbXG4gICAgJ2JwbW46Rmxvd05vZGUnLFxuICAgICdicG1uOkludGVyYWN0aW9uTm9kZScsXG4gICAgJ2JwbW46RGF0YU9iamVjdFJlZmVyZW5jZScsXG4gICAgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJ1xuICBdKSkge1xuXG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdhcHBlbmQudGV4dC1hbm5vdGF0aW9uJzogYXBwZW5kQWN0aW9uKCdicG1uOlRleHRBbm5vdGF0aW9uJywgJ2JwbW4taWNvbi10ZXh0LWFubm90YXRpb24nKSxcblxuICAgICAgJ2Nvbm5lY3QnOiB7XG4gICAgICAgIGdyb3VwOiAnY29ubmVjdCcsXG4gICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jb25uZWN0aW9uLW11bHRpJyxcbiAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQ29ubmVjdCB1c2luZyAnICtcbiAgICAgICAgICAgICAgICAgIChidXNpbmVzc09iamVjdC5pc0ZvckNvbXBlbnNhdGlvbiA/ICcnIDogJ1NlcXVlbmNlL01lc3NhZ2VGbG93IG9yICcpICtcbiAgICAgICAgICAgICAgICAgICdBc3NvY2lhdGlvbicpLFxuICAgICAgICBhY3Rpb246IHtcbiAgICAgICAgICBjbGljazogc3RhcnRDb25uZWN0LFxuICAgICAgICAgIGRyYWdzdGFydDogc3RhcnRDb25uZWN0XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChpc0FueShidXNpbmVzc09iamVjdCwgWyAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJywgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJyBdKSkge1xuICAgIGFzc2lnbihhY3Rpb25zLCB7XG4gICAgICAnY29ubmVjdCc6IHtcbiAgICAgICAgZ3JvdXA6ICdjb25uZWN0JyxcbiAgICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWNvbm5lY3Rpb24tbXVsdGknLFxuICAgICAgICB0aXRsZTogdHJhbnNsYXRlKCdDb25uZWN0IHVzaW5nIERhdGFJbnB1dEFzc29jaWF0aW9uJyksXG4gICAgICAgIGFjdGlvbjoge1xuICAgICAgICAgIGNsaWNrOiBzdGFydENvbm5lY3QsXG4gICAgICAgICAgZHJhZ3N0YXJ0OiBzdGFydENvbm5lY3RcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpHcm91cCcpKSB7XG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdhcHBlbmQudGV4dC1hbm5vdGF0aW9uJzogYXBwZW5kQWN0aW9uKCdicG1uOlRleHRBbm5vdGF0aW9uJywgJ2JwbW4taWNvbi10ZXh0LWFubm90YXRpb24nKVxuICAgIH0pO1xuICB9XG5cbiAgLy8gZGVsZXRlIGVsZW1lbnQgZW50cnksIG9ubHkgc2hvdyBpZiBhbGxvd2VkIGJ5IHJ1bGVzXG4gIHZhciBkZWxldGVBbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMuZGVsZXRlJywgeyBlbGVtZW50czogWyBlbGVtZW50IF0gfSk7XG5cbiAgaWYgKGlzQXJyYXkoZGVsZXRlQWxsb3dlZCkpIHtcblxuICAgIC8vIHdhcyB0aGUgZWxlbWVudCByZXR1cm5lZCBhcyBhIGRlbGV0aW9uIGNhbmRpZGF0ZT9cbiAgICBkZWxldGVBbGxvd2VkID0gZGVsZXRlQWxsb3dlZFswXSA9PT0gZWxlbWVudDtcbiAgfVxuXG4gIGlmIChkZWxldGVBbGxvd2VkKSB7XG4gICAgYXNzaWduKGFjdGlvbnMsIHtcbiAgICAgICdkZWxldGUnOiB7XG4gICAgICAgIGdyb3VwOiAnZWRpdCcsXG4gICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi10cmFzaCcsXG4gICAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ1JlbW92ZScpLFxuICAgICAgICBhY3Rpb246IHtcbiAgICAgICAgICBjbGljazogcmVtb3ZlRWxlbWVudFxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gYWN0aW9ucztcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNFdmVudFR5cGUoZXZlbnRCbywgdHlwZSwgZGVmaW5pdGlvbikge1xuXG4gIHZhciBpc1R5cGUgPSBldmVudEJvLiRpbnN0YW5jZU9mKHR5cGUpO1xuICB2YXIgaXNEZWZpbml0aW9uID0gZmFsc2U7XG5cbiAgdmFyIGRlZmluaXRpb25zID0gZXZlbnRCby5ldmVudERlZmluaXRpb25zIHx8IFtdO1xuICBmb3JFYWNoKGRlZmluaXRpb25zLCBmdW5jdGlvbihkZWYpIHtcbiAgICBpZiAoZGVmLiR0eXBlID09PSBkZWZpbml0aW9uKSB7XG4gICAgICBpc0RlZmluaXRpb24gPSB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGlzVHlwZSAmJiBpc0RlZmluaXRpb247XG59XG4iLCJpbXBvcnQgRGlyZWN0RWRpdGluZ01vZHVsZSBmcm9tICdkaWFncmFtLWpzLWRpcmVjdC1lZGl0aW5nJztcbmltcG9ydCBDb250ZXh0UGFkTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvbnRleHQtcGFkJztcbmltcG9ydCBTZWxlY3Rpb25Nb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc2VsZWN0aW9uJztcbmltcG9ydCBDb25uZWN0TW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2Nvbm5lY3QnO1xuaW1wb3J0IENyZWF0ZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jcmVhdGUnO1xuaW1wb3J0IFBvcHVwTWVudU1vZHVsZSBmcm9tICcuLi9wb3B1cC1tZW51JztcblxuaW1wb3J0IENvbnRleHRQYWRQcm92aWRlciBmcm9tICcuL0NvbnRleHRQYWRQcm92aWRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBEaXJlY3RFZGl0aW5nTW9kdWxlLFxuICAgIENvbnRleHRQYWRNb2R1bGUsXG4gICAgU2VsZWN0aW9uTW9kdWxlLFxuICAgIENvbm5lY3RNb2R1bGUsXG4gICAgQ3JlYXRlTW9kdWxlLFxuICAgIFBvcHVwTWVudU1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogWyAnY29udGV4dFBhZFByb3ZpZGVyJyBdLFxuICBjb250ZXh0UGFkUHJvdmlkZXI6IFsgJ3R5cGUnLCBDb250ZXh0UGFkUHJvdmlkZXIgXVxufTsiLCJpbXBvcnQge1xuICBnZXRCdXNpbmVzc09iamVjdCxcbiAgaXNcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBmb3JFYWNoLFxuICBpc0FycmF5LFxuICBpc1VuZGVmaW5lZCxcbiAgb21pdCxcbiAgcmVkdWNlXG59IGZyb20gJ21pbi1kYXNoJztcblxuZnVuY3Rpb24gY29weVByb3BlcnRpZXMoc291cmNlLCB0YXJnZXQsIHByb3BlcnRpZXMpIHtcbiAgaWYgKCFpc0FycmF5KHByb3BlcnRpZXMpKSB7XG4gICAgcHJvcGVydGllcyA9IFsgcHJvcGVydGllcyBdO1xuICB9XG5cbiAgZm9yRWFjaChwcm9wZXJ0aWVzLCBmdW5jdGlvbihwcm9wZXJ0eSkge1xuICAgIGlmICghaXNVbmRlZmluZWQoc291cmNlW3Byb3BlcnR5XSkpIHtcbiAgICAgIHRhcmdldFtwcm9wZXJ0eV0gPSBzb3VyY2VbcHJvcGVydHldO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVByb3BlcnRpZXMoZWxlbWVudCwgcHJvcGVydGllcykge1xuICBpZiAoIWlzQXJyYXkocHJvcGVydGllcykpIHtcbiAgICBwcm9wZXJ0aWVzID0gWyBwcm9wZXJ0aWVzIF07XG4gIH1cblxuICBmb3JFYWNoKHByb3BlcnRpZXMsIGZ1bmN0aW9uKHByb3BlcnR5KSB7XG4gICAgaWYgKGVsZW1lbnRbcHJvcGVydHldKSB7XG4gICAgICBkZWxldGUgZWxlbWVudFtwcm9wZXJ0eV07XG4gICAgfVxuICB9KTtcbn1cblxudmFyIExPV19QUklPUklUWSA9IDc1MDtcblxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uQ29weVBhc3RlKGJwbW5GYWN0b3J5LCBldmVudEJ1cywgbW9kZGxlQ29weSkge1xuXG4gIGV2ZW50QnVzLm9uKCdjb3B5UGFzdGUuY29weUVsZW1lbnQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZGVzY3JpcHRvciA9IGNvbnRleHQuZGVzY3JpcHRvcixcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudDtcblxuICAgIHZhciBidXNpbmVzc09iamVjdCA9IGRlc2NyaXB0b3Iub2xkQnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcblxuICAgIGRlc2NyaXB0b3IudHlwZSA9IGVsZW1lbnQudHlwZTtcblxuICAgIGNvcHlQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBkZXNjcmlwdG9yLCAnbmFtZScpO1xuXG4gICAgZGVzY3JpcHRvci5kaSA9IHt9O1xuXG4gICAgLy8gZmlsbCBhbmQgc3Ryb2tlIHdpbGwgYmUgc2V0IHRvIERJXG4gICAgY29weVByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QuZGksIGRlc2NyaXB0b3IuZGksIFtcbiAgICAgICdmaWxsJyxcbiAgICAgICdzdHJva2UnXG4gICAgXSk7XG5cbiAgICBjb3B5UHJvcGVydGllcyhidXNpbmVzc09iamVjdC5kaSwgZGVzY3JpcHRvciwgJ2lzRXhwYW5kZWQnKTtcblxuICAgIGlmIChpc0xhYmVsKGRlc2NyaXB0b3IpKSB7XG4gICAgICByZXR1cm4gZGVzY3JpcHRvcjtcbiAgICB9XG5cbiAgICAvLyBkZWZhdWx0IHNlcXVlbmNlIGZsb3dcbiAgICBpZiAoYnVzaW5lc3NPYmplY3QuZGVmYXVsdCkge1xuICAgICAgZGVzY3JpcHRvci5kZWZhdWx0ID0gYnVzaW5lc3NPYmplY3QuZGVmYXVsdC5pZDtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0eScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICAgIHByb3BlcnR5ID0gY29udGV4dC5wcm9wZXJ0eSxcbiAgICAgICAgcHJvcGVydHlOYW1lID0gY29udGV4dC5wcm9wZXJ0eU5hbWUsXG4gICAgICAgIGJwbW5Qcm9jZXNzO1xuXG4gICAgaWYgKFxuICAgICAgcHJvcGVydHlOYW1lID09PSAncHJvY2Vzc1JlZicgJiZcbiAgICAgIGlzKHBhcmVudCwgJ2JwbW46UGFydGljaXBhbnQnKSAmJlxuICAgICAgaXMocHJvcGVydHksICdicG1uOlByb2Nlc3MnKVxuICAgICkge1xuICAgICAgYnBtblByb2Nlc3MgPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46UHJvY2VzcycpO1xuXG4gICAgICAvLyByZXR1cm4gY29weSBvZiBwcm9jZXNzXG4gICAgICByZXR1cm4gbW9kZGxlQ29weS5jb3B5RWxlbWVudChwcm9wZXJ0eSwgYnBtblByb2Nlc3MpO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIHJlZmVyZW5jZXM7XG5cbiAgZnVuY3Rpb24gcmVzb2x2ZVJlZmVyZW5jZXMoZGVzY3JpcHRvciwgY2FjaGUpIHtcbiAgICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChkZXNjcmlwdG9yKTtcblxuICAgIC8vIGRlZmF1bHQgc2VxdWVuY2UgZmxvd3NcbiAgICBpZiAoZGVzY3JpcHRvci5kZWZhdWx0KSB7XG5cbiAgICAgIC8vIHJlbGF0aW9uc2hpcCBjYW5ub3QgYmUgcmVzb2x2ZWQgaW1tZWRpYXRlbHlcbiAgICAgIHJlZmVyZW5jZXNbIGRlc2NyaXB0b3IuZGVmYXVsdCBdID0ge1xuICAgICAgICBlbGVtZW50OiBidXNpbmVzc09iamVjdCxcbiAgICAgICAgcHJvcGVydHk6ICdkZWZhdWx0J1xuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyBib3VuZGFyeSBldmVudHNcbiAgICBpZiAoZGVzY3JpcHRvci5ob3N0KSB7XG5cbiAgICAgIC8vIHJlbGF0aW9uc2hpcCBjYW4gYmUgcmVzb2x2ZWQgaW1tZWRpYXRlbHlcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0KGRlc2NyaXB0b3IpLmF0dGFjaGVkVG9SZWYgPSBnZXRCdXNpbmVzc09iamVjdChjYWNoZVsgZGVzY3JpcHRvci5ob3N0IF0pO1xuICAgIH1cblxuICAgIHJlZmVyZW5jZXMgPSBvbWl0KHJlZmVyZW5jZXMsIHJlZHVjZShyZWZlcmVuY2VzLCBmdW5jdGlvbihhcnJheSwgcmVmZXJlbmNlLCBrZXkpIHtcbiAgICAgIHZhciBlbGVtZW50ID0gcmVmZXJlbmNlLmVsZW1lbnQsXG4gICAgICAgICAgcHJvcGVydHkgPSByZWZlcmVuY2UucHJvcGVydHk7XG5cbiAgICAgIGlmIChrZXkgPT09IGRlc2NyaXB0b3IuaWQpIHtcbiAgICAgICAgZWxlbWVudFsgcHJvcGVydHkgXSA9IGJ1c2luZXNzT2JqZWN0O1xuXG4gICAgICAgIGFycmF5LnB1c2goZGVzY3JpcHRvci5pZCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhcnJheTtcbiAgICB9LCBbXSkpO1xuICB9XG5cbiAgZXZlbnRCdXMub24oJ2NvcHlQYXN0ZS5wYXN0ZUVsZW1lbnRzJywgZnVuY3Rpb24oKSB7XG4gICAgcmVmZXJlbmNlcyA9IHt9O1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29weVBhc3RlLnBhc3RlRWxlbWVudCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgY2FjaGUgPSBjb250ZXh0LmNhY2hlLFxuICAgICAgICBkZXNjcmlwdG9yID0gY29udGV4dC5kZXNjcmlwdG9yLFxuICAgICAgICBvbGRCdXNpbmVzc09iamVjdCA9IGRlc2NyaXB0b3Iub2xkQnVzaW5lc3NPYmplY3QsXG4gICAgICAgIG5ld0J1c2luZXNzT2JqZWN0O1xuXG4gICAgLy8gZG8gTk9UIGNvcHkgYnVzaW5lc3Mgb2JqZWN0IGlmIGV4dGVybmFsIGxhYmVsXG4gICAgaWYgKGlzTGFiZWwoZGVzY3JpcHRvcikpIHtcbiAgICAgIGRlc2NyaXB0b3IuYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChjYWNoZVsgZGVzY3JpcHRvci5sYWJlbFRhcmdldCBdKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG5ld0J1c2luZXNzT2JqZWN0ID0gYnBtbkZhY3RvcnkuY3JlYXRlKG9sZEJ1c2luZXNzT2JqZWN0LiR0eXBlKTtcblxuICAgIGRlc2NyaXB0b3IuYnVzaW5lc3NPYmplY3QgPSBtb2RkbGVDb3B5LmNvcHlFbGVtZW50KFxuICAgICAgb2xkQnVzaW5lc3NPYmplY3QsXG4gICAgICBuZXdCdXNpbmVzc09iamVjdFxuICAgICk7XG5cbiAgICAvLyByZXNvbHZlIHJlZmVyZW5jZXMgZS5nLiBkZWZhdWx0IHNlcXVlbmNlIGZsb3dcbiAgICByZXNvbHZlUmVmZXJlbmNlcyhkZXNjcmlwdG9yLCBjYWNoZSk7XG5cbiAgICBjb3B5UHJvcGVydGllcyhkZXNjcmlwdG9yLCBuZXdCdXNpbmVzc09iamVjdCwgW1xuICAgICAgJ2lzRXhwYW5kZWQnLFxuICAgICAgJ25hbWUnXG4gICAgXSk7XG5cbiAgICByZW1vdmVQcm9wZXJ0aWVzKGRlc2NyaXB0b3IsICdvbGRCdXNpbmVzc09iamVjdCcpO1xuICB9KTtcblxufVxuXG5cbkJwbW5Db3B5UGFzdGUuJGluamVjdCA9IFtcbiAgJ2JwbW5GYWN0b3J5JyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGRsZUNvcHknXG5dO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNMYWJlbChlbGVtZW50KSB7XG4gIHJldHVybiAhIWVsZW1lbnQubGFiZWxUYXJnZXQ7XG59XG4iLCJpbXBvcnQge1xuICBmaW5kLFxuICBmb3JFYWNoLFxuICBpc0FycmF5LFxuICBpc0RlZmluZWQsXG4gIGlzT2JqZWN0LFxuICBtYXRjaFBhdHRlcm4sXG4gIHJlZHVjZSxcbiAgaGFzLFxuICBzb3J0Qnlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgRElTQUxMT1dFRF9QUk9QRVJUSUVTID0gW1xuICAnYXJ0aWZhY3RzJyxcbiAgJ2RhdGFJbnB1dEFzc29jaWF0aW9ucycsXG4gICdkYXRhT3V0cHV0QXNzb2NpYXRpb25zJyxcbiAgJ2RlZmF1bHQnLFxuICAnZmxvd0VsZW1lbnRzJyxcbiAgJ2xhbmVzJyxcbiAgJ2luY29taW5nJyxcbiAgJ291dGdvaW5nJ1xuXTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7RnVuY3Rpb259IDxtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0aWVzPiBsaXN0ZW5lclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IGNvbnRleHQucHJvcGVydHlOYW1lc1xuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBjb250ZXh0LnNvdXJjZUVsZW1lbnRcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gY29udGV4dC50YXJnZXRFbGVtZW50XG4gKlxuICogQHJldHVybnMge0FycmF5PHN0cmluZz58Ym9vbGVhbn0gLSBSZXR1cm4gcHJvcGVydGllcyB0byBiZSBjb3BpZWQgb3IgZmFsc2UgdG8gZGlzYWxsb3dcbiAqIGNvcHlpbmcuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7RnVuY3Rpb259IDxtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0eT4gbGlzdGVuZXJcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBjb250ZXh0LnBhcmVudFxuICogQHBhcmFtIHsqfSBjb250ZXh0LnByb3BlcnR5XG4gKiBAcGFyYW0ge3N0cmluZ30gY29udGV4dC5wcm9wZXJ0eU5hbWVcbiAqXG4gKiBAcmV0dXJucyB7Knxib29sZWFufSAtIFJldHVybiBjb3BpZWQgcHJvcGVydHkgb3IgZmFsc2UgdG8gZGlzYWxsb3dcbiAqIGNvcHlpbmcuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7RnVuY3Rpb259IDxtb2RkbGVDb3B5LmNhblNldENvcGllZFByb3BlcnR5PiBsaXN0ZW5lclxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGNvbnRleHQucGFyZW50XG4gKiBAcGFyYW0geyp9IGNvbnRleHQucHJvcGVydHlcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZXh0LnByb3BlcnR5TmFtZVxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufSAtIFJldHVybiBmYWxzZSB0byBkaXNhbGxvd1xuICogc2V0dGluZyBjb3BpZWQgcHJvcGVydHkuXG4gKi9cblxuLyoqXG4gKiBVdGlsaXR5IGZvciBjb3B5aW5nIG1vZGVsIHByb3BlcnRpZXMgZnJvbSBzb3VyY2UgZWxlbWVudCB0byB0YXJnZXQgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcbiAqIEBwYXJhbSB7QnBtbk1vZGRsZX0gbW9kZGxlXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1vZGRsZUNvcHkoZXZlbnRCdXMsIGJwbW5GYWN0b3J5LCBtb2RkbGUpIHtcbiAgdGhpcy5fYnBtbkZhY3RvcnkgPSBicG1uRmFjdG9yeTtcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fbW9kZGxlID0gbW9kZGxlO1xuXG4gIC8vIGNvcHkgZXh0ZW5zaW9uIGVsZW1lbnRzIGxhc3RcbiAgZXZlbnRCdXMub24oJ21vZGRsZUNvcHkuY2FuQ29weVByb3BlcnRpZXMnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHByb3BlcnR5TmFtZXMgPSBjb250ZXh0LnByb3BlcnR5TmFtZXM7XG5cbiAgICBpZiAoIXByb3BlcnR5TmFtZXMgfHwgIXByb3BlcnR5TmFtZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIHNvcnRCeShwcm9wZXJ0eU5hbWVzLCBmdW5jdGlvbihwcm9wZXJ0eU5hbWUpIHtcbiAgICAgIHJldHVybiBwcm9wZXJ0eU5hbWUgPT09ICdleHRlbnNpb25FbGVtZW50cyc7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIGRlZmF1bHQgY2hlY2sgd2hldGhlciBwcm9wZXJ0eSBjYW4gYmUgY29waWVkXG4gIGV2ZW50QnVzLm9uKCdtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0eScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICAgIHBhcmVudERlc2NyaXB0b3IgPSBpc09iamVjdChwYXJlbnQpICYmIHBhcmVudC4kZGVzY3JpcHRvcixcbiAgICAgICAgcHJvcGVydHlOYW1lID0gY29udGV4dC5wcm9wZXJ0eU5hbWU7XG5cbiAgICBpZiAocHJvcGVydHlOYW1lICYmIERJU0FMTE9XRURfUFJPUEVSVElFUy5pbmRleE9mKHByb3BlcnR5TmFtZSkgIT09IC0xKSB7XG5cbiAgICAgIC8vIGRpc2FsbG93IGNvcHlpbmcgcHJvcGVydHlcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAocHJvcGVydHlOYW1lICYmXG4gICAgICBwYXJlbnREZXNjcmlwdG9yICYmXG4gICAgICAhZmluZChwYXJlbnREZXNjcmlwdG9yLnByb3BlcnRpZXMsIG1hdGNoUGF0dGVybih7IG5hbWU6IHByb3BlcnR5TmFtZSB9KSkpIHtcblxuICAgICAgLy8gZGlzYWxsb3cgY29weWluZyBwcm9wZXJ0eVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gZG8gTk9UIGFsbG93IHRvIGNvcHkgZW1wdHkgZXh0ZW5zaW9uIGVsZW1lbnRzXG4gIGV2ZW50QnVzLm9uKCdtb2RkbGVDb3B5LmNhblNldENvcGllZFByb3BlcnR5JywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBwcm9wZXJ0eSA9IGNvbnRleHQucHJvcGVydHk7XG5cbiAgICBpZiAoaXMocHJvcGVydHksICdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJykgJiYgKCFwcm9wZXJ0eS52YWx1ZXMgfHwgIXByb3BlcnR5LnZhbHVlcy5sZW5ndGgpKSB7XG5cbiAgICAgIC8vIGRpc2FsbG93IHNldHRpbmcgY29waWVkIHByb3BlcnR5XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbn1cblxuTW9kZGxlQ29weS4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnYnBtbkZhY3RvcnknLFxuICAnbW9kZGxlJ1xuXTtcblxuLyoqXG4gKiBDb3B5IG1vZGVsIHByb3BlcnRpZXMgb2Ygc291cmNlIGVsZW1lbnQgdG8gdGFyZ2V0IGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBzb3VyY2VFbGVtZW50XG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IHRhcmdldEVsZW1lbnRcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gW3Byb3BlcnR5TmFtZXNdXG4gKlxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fVxuICovXG5Nb2RkbGVDb3B5LnByb3RvdHlwZS5jb3B5RWxlbWVudCA9IGZ1bmN0aW9uKHNvdXJjZUVsZW1lbnQsIHRhcmdldEVsZW1lbnQsIHByb3BlcnR5TmFtZXMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGlmIChwcm9wZXJ0eU5hbWVzICYmICFpc0FycmF5KHByb3BlcnR5TmFtZXMpKSB7XG4gICAgcHJvcGVydHlOYW1lcyA9IFsgcHJvcGVydHlOYW1lcyBdO1xuICB9XG5cbiAgcHJvcGVydHlOYW1lcyA9IHByb3BlcnR5TmFtZXMgfHwgZ2V0UHJvcGVydHlOYW1lcyhzb3VyY2VFbGVtZW50LiRkZXNjcmlwdG9yKTtcblxuICB2YXIgY2FuQ29weVByb3BlcnRpZXMgPSB0aGlzLl9ldmVudEJ1cy5maXJlKCdtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0aWVzJywge1xuICAgIHByb3BlcnR5TmFtZXM6IHByb3BlcnR5TmFtZXMsXG4gICAgc291cmNlRWxlbWVudDogc291cmNlRWxlbWVudCxcbiAgICB0YXJnZXRFbGVtZW50OiB0YXJnZXRFbGVtZW50XG4gIH0pO1xuXG4gIGlmIChjYW5Db3B5UHJvcGVydGllcyA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm4gdGFyZ2V0RWxlbWVudDtcbiAgfVxuXG4gIGlmIChpc0FycmF5KGNhbkNvcHlQcm9wZXJ0aWVzKSkge1xuICAgIHByb3BlcnR5TmFtZXMgPSBjYW5Db3B5UHJvcGVydGllcztcbiAgfVxuXG4gIC8vIGNvcHkgcHJvcGVydGllc1xuICBmb3JFYWNoKHByb3BlcnR5TmFtZXMsIGZ1bmN0aW9uKHByb3BlcnR5TmFtZSkge1xuICAgIHZhciBzb3VyY2VQcm9wZXJ0eTtcblxuICAgIGlmIChoYXMoc291cmNlRWxlbWVudCwgcHJvcGVydHlOYW1lKSkge1xuICAgICAgc291cmNlUHJvcGVydHkgPSBzb3VyY2VFbGVtZW50LmdldChwcm9wZXJ0eU5hbWUpO1xuICAgIH1cblxuICAgIHZhciBjb3BpZWRQcm9wZXJ0eSA9IHNlbGYuY29weVByb3BlcnR5KHNvdXJjZVByb3BlcnR5LCB0YXJnZXRFbGVtZW50LCBwcm9wZXJ0eU5hbWUpO1xuXG4gICAgdmFyIGNhblNldFByb3BlcnR5ID0gc2VsZi5fZXZlbnRCdXMuZmlyZSgnbW9kZGxlQ29weS5jYW5TZXRDb3BpZWRQcm9wZXJ0eScsIHtcbiAgICAgIHBhcmVudDogdGFyZ2V0RWxlbWVudCxcbiAgICAgIHByb3BlcnR5OiBjb3BpZWRQcm9wZXJ0eSxcbiAgICAgIHByb3BlcnR5TmFtZTogcHJvcGVydHlOYW1lXG4gICAgfSk7XG5cbiAgICBpZiAoY2FuU2V0UHJvcGVydHkgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGlzRGVmaW5lZChjb3BpZWRQcm9wZXJ0eSkpIHtcbiAgICAgIHRhcmdldEVsZW1lbnQuc2V0KHByb3BlcnR5TmFtZSwgY29waWVkUHJvcGVydHkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHRhcmdldEVsZW1lbnQ7XG59O1xuXG4vKipcbiAqIENvcHkgbW9kZWwgcHJvcGVydHkuXG4gKlxuICogQHBhcmFtIHsqfSBwcm9wZXJ0eVxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBwYXJlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eU5hbWVcbiAqXG4gKiBAcmV0dXJucyB7Kn1cbiAqL1xuTW9kZGxlQ29weS5wcm90b3R5cGUuY29weVByb3BlcnR5ID0gZnVuY3Rpb24ocHJvcGVydHksIHBhcmVudCwgcHJvcGVydHlOYW1lKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvLyBhbGxvdyBvdGhlcnMgdG8gY29weSBwcm9wZXJ0eVxuICB2YXIgY29waWVkUHJvcGVydHkgPSB0aGlzLl9ldmVudEJ1cy5maXJlKCdtb2RkbGVDb3B5LmNhbkNvcHlQcm9wZXJ0eScsIHtcbiAgICBwYXJlbnQ6IHBhcmVudCxcbiAgICBwcm9wZXJ0eTogcHJvcGVydHksXG4gICAgcHJvcGVydHlOYW1lOiBwcm9wZXJ0eU5hbWVcbiAgfSk7XG5cbiAgLy8gcmV0dXJuIGlmIGNvcHlpbmcgaXMgTk9UIGFsbG93ZWRcbiAgaWYgKGNvcGllZFByb3BlcnR5ID09PSBmYWxzZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChjb3BpZWRQcm9wZXJ0eSkge1xuICAgIGlmIChpc09iamVjdChjb3BpZWRQcm9wZXJ0eSkgJiYgY29waWVkUHJvcGVydHkuJHR5cGUgJiYgIWNvcGllZFByb3BlcnR5LiRwYXJlbnQpIHtcbiAgICAgIGNvcGllZFByb3BlcnR5LiRwYXJlbnQgPSBwYXJlbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvcGllZFByb3BlcnR5O1xuICB9XG5cbiAgdmFyIHByb3BlcnR5RGVzY3JpcHRvciA9IHRoaXMuX21vZGRsZS5nZXRQcm9wZXJ0eURlc2NyaXB0b3IocGFyZW50LCBwcm9wZXJ0eU5hbWUpO1xuXG4gIC8vIGRvIE5PVCBjb3B5IElkcyBhbmQgcmVmZXJlbmNlc1xuICBpZiAocHJvcGVydHlEZXNjcmlwdG9yLmlzSWQgfHwgcHJvcGVydHlEZXNjcmlwdG9yLmlzUmVmZXJlbmNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gY29weSBhcnJheXNcbiAgaWYgKGlzQXJyYXkocHJvcGVydHkpKSB7XG4gICAgcmV0dXJuIHJlZHVjZShwcm9wZXJ0eSwgZnVuY3Rpb24oY2hpbGRQcm9wZXJ0aWVzLCBjaGlsZFByb3BlcnR5KSB7XG5cbiAgICAgIC8vIHJlY3Vyc2lvblxuICAgICAgY29waWVkUHJvcGVydHkgPSBzZWxmLmNvcHlQcm9wZXJ0eShjaGlsZFByb3BlcnR5LCBwYXJlbnQsIHByb3BlcnR5TmFtZSk7XG5cbiAgICAgIC8vIGNvcHlpbmcgbWlnaHQgTk9UIGJlIGFsbG93ZWRcbiAgICAgIGlmIChjb3BpZWRQcm9wZXJ0eSkge1xuICAgICAgICBjb3BpZWRQcm9wZXJ0eS4kcGFyZW50ID0gcGFyZW50O1xuXG4gICAgICAgIHJldHVybiBjaGlsZFByb3BlcnRpZXMuY29uY2F0KGNvcGllZFByb3BlcnR5KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNoaWxkUHJvcGVydGllcztcbiAgICB9LCBbXSk7XG4gIH1cblxuICAvLyBjb3B5IG1vZGVsIGVsZW1lbnRzXG4gIGlmIChpc09iamVjdChwcm9wZXJ0eSkgJiYgcHJvcGVydHkuJHR5cGUpIHtcbiAgICBpZiAodGhpcy5fbW9kZGxlLmdldEVsZW1lbnREZXNjcmlwdG9yKHByb3BlcnR5KS5pc0dlbmVyaWMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb3BpZWRQcm9wZXJ0eSA9IHNlbGYuX2JwbW5GYWN0b3J5LmNyZWF0ZShwcm9wZXJ0eS4kdHlwZSk7XG5cbiAgICBjb3BpZWRQcm9wZXJ0eS4kcGFyZW50ID0gcGFyZW50O1xuXG4gICAgLy8gcmVjdXJzaW9uXG4gICAgY29waWVkUHJvcGVydHkgPSBzZWxmLmNvcHlFbGVtZW50KHByb3BlcnR5LCBjb3BpZWRQcm9wZXJ0eSk7XG5cbiAgICByZXR1cm4gY29waWVkUHJvcGVydHk7XG4gIH1cblxuICAvLyBjb3B5IHByaW1pdGl2ZSBwcm9wZXJ0aWVzXG4gIHJldHVybiBwcm9wZXJ0eTtcbn07XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJvcGVydHlOYW1lcyhkZXNjcmlwdG9yLCBrZWVwRGVmYXVsdFByb3BlcnRpZXMpIHtcbiAgcmV0dXJuIHJlZHVjZShkZXNjcmlwdG9yLnByb3BlcnRpZXMsIGZ1bmN0aW9uKHByb3BlcnRpZXMsIHByb3BlcnR5KSB7XG5cbiAgICBpZiAoa2VlcERlZmF1bHRQcm9wZXJ0aWVzICYmIHByb3BlcnR5LmRlZmF1bHQpIHtcbiAgICAgIHJldHVybiBwcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIHJldHVybiBwcm9wZXJ0aWVzLmNvbmNhdChwcm9wZXJ0eS5uYW1lKTtcbiAgfSwgW10pO1xufVxuXG5mdW5jdGlvbiBpcyhlbGVtZW50LCB0eXBlKSB7XG4gIHJldHVybiBlbGVtZW50ICYmICh0eXBlb2YgZWxlbWVudC4kaW5zdGFuY2VPZiA9PT0gJ2Z1bmN0aW9uJykgJiYgZWxlbWVudC4kaW5zdGFuY2VPZih0eXBlKTtcbn0iLCJpbXBvcnQgQ29weVBhc3RlTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2NvcHktcGFzdGUnO1xuXG5pbXBvcnQgQnBtbkNvcHlQYXN0ZSBmcm9tICcuL0JwbW5Db3B5UGFzdGUnO1xuaW1wb3J0IE1vZGRsZUNvcHkgZnJvbSAnLi9Nb2RkbGVDb3B5JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIENvcHlQYXN0ZU1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogWyAnYnBtbkNvcHlQYXN0ZScsICdtb2RkbGVDb3B5JyBdLFxuICBicG1uQ29weVBhc3RlOiBbICd0eXBlJywgQnBtbkNvcHlQYXN0ZSBdLFxuICBtb2RkbGVDb3B5OiBbICd0eXBlJywgTW9kZGxlQ29weSBdXG59O1xuIiwiaW1wb3J0IHsgZ2V0RGkgfSBmcm9tICcuLi8uLi9kcmF3L0JwbW5SZW5kZXJVdGlsJztcbmltcG9ydCB7IGdldEJ1c2luZXNzT2JqZWN0IH0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBmaWx0ZXIsXG4gIG1hcFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IHNlbGZBbmRBbGxDaGlsZHJlbiB9IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvRWxlbWVudHMnO1xuXG5cbnZhciBISUdIX1BSSU9SSVRZID0gMjAwMDtcblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkRpT3JkZXJpbmcoZXZlbnRCdXMsIGNhbnZhcykge1xuXG4gIGV2ZW50QnVzLm9uKCdzYXZlWE1MLnN0YXJ0JywgSElHSF9QUklPUklUWSwgb3JkZXJEaSk7XG5cbiAgZnVuY3Rpb24gb3JkZXJEaSgpIHtcbiAgICB2YXIgcm9vdCA9IGNhbnZhcy5nZXRSb290RWxlbWVudCgpLFxuICAgICAgICByb290RGkgPSBnZXRCdXNpbmVzc09iamVjdChyb290KS5kaSxcbiAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIGRpRWxlbWVudHM7XG5cbiAgICBlbGVtZW50cyA9IHNlbGZBbmRBbGxDaGlsZHJlbihbIHJvb3QgXSwgZmFsc2UpO1xuXG4gICAgLy8gb25seSBicG1uZGk6U2hhcGUgYW5kIGJwbW5kaTpFZGdlIGNhbiBiZSBkaXJlY3QgY2hpbGRyZW4gb2YgYnBtbmRpOlBsYW5lXG4gICAgZWxlbWVudHMgPSBmaWx0ZXIoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgIHJldHVybiBlbGVtZW50ICE9PSByb290ICYmICFlbGVtZW50LmxhYmVsVGFyZ2V0O1xuICAgIH0pO1xuXG4gICAgZGlFbGVtZW50cyA9IG1hcChlbGVtZW50cywgZ2V0RGkpO1xuXG4gICAgcm9vdERpLnNldCgncGxhbmVFbGVtZW50JywgZGlFbGVtZW50cyk7XG4gIH1cbn1cblxuQnBtbkRpT3JkZXJpbmcuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2NhbnZhcycgXTtcbiIsImltcG9ydCBCcG1uRGlPcmRlcmluZyBmcm9tICcuLi9kaS1vcmRlcmluZy9CcG1uRGlPcmRlcmluZyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFtcbiAgICAnYnBtbkRpT3JkZXJpbmcnXG4gIF0sXG4gIGJwbW5EaU9yZGVyaW5nOiBbICd0eXBlJywgQnBtbkRpT3JkZXJpbmcgXVxufTsiLCJpbXBvcnQge1xuICBmaWx0ZXJcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBpc0FueVxufSBmcm9tICcuLi9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCc7XG5cblxuLyoqXG4gKiBSZWdpc3RlcnMgZWxlbWVudCBleGNsdWRlIGZpbHRlcnMgZm9yIGVsZW1lbnRzIHRoYXRcbiAqIGN1cnJlbnRseSBkbyBub3Qgc3VwcG9ydCBkaXN0cmlidXRpb24uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5EaXN0cmlidXRlRWxlbWVudHMoZGlzdHJpYnV0ZUVsZW1lbnRzKSB7XG5cbiAgZGlzdHJpYnV0ZUVsZW1lbnRzLnJlZ2lzdGVyRmlsdGVyKGZ1bmN0aW9uKGVsZW1lbnRzKSB7XG4gICAgcmV0dXJuIGZpbHRlcihlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgdmFyIGNhbm5vdERpc3RyaWJ1dGUgPSBpc0FueShlbGVtZW50LCBbXG4gICAgICAgICdicG1uOkFzc29jaWF0aW9uJyxcbiAgICAgICAgJ2JwbW46Qm91bmRhcnlFdmVudCcsXG4gICAgICAgICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJyxcbiAgICAgICAgJ2JwbW46RGF0YU91dHB1dEFzc29jaWF0aW9uJyxcbiAgICAgICAgJ2JwbW46TGFuZScsXG4gICAgICAgICdicG1uOk1lc3NhZ2VGbG93JyxcbiAgICAgICAgJ2JwbW46UGFydGljaXBhbnQnLFxuICAgICAgICAnYnBtbjpTZXF1ZW5jZUZsb3cnLFxuICAgICAgICAnYnBtbjpUZXh0QW5ub3RhdGlvbidcbiAgICAgIF0pO1xuXG4gICAgICByZXR1cm4gIShlbGVtZW50LmxhYmVsVGFyZ2V0IHx8IGNhbm5vdERpc3RyaWJ1dGUpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuQnBtbkRpc3RyaWJ1dGVFbGVtZW50cy4kaW5qZWN0ID0gWyAnZGlzdHJpYnV0ZUVsZW1lbnRzJyBdOyIsImltcG9ydCBEaXN0cmlidXRlRWxlbWVudHNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZGlzdHJpYnV0ZS1lbGVtZW50cyc7XG5cbmltcG9ydCBCcG1uRGlzdHJpYnV0ZUVsZW1lbnRzIGZyb20gJy4vQnBtbkRpc3RyaWJ1dGVFbGVtZW50cyc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIERpc3RyaWJ1dGVFbGVtZW50c01vZHVsZVxuICBdLFxuICBfX2luaXRfXzogWyAnYnBtbkRpc3RyaWJ1dGVFbGVtZW50cycgXSxcbiAgYnBtbkRpc3RyaWJ1dGVFbGVtZW50czogWyAndHlwZScsIEJwbW5EaXN0cmlidXRlRWxlbWVudHMgXVxufTtcbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBFZGl0b3JBY3Rpb25zIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2VkaXRvci1hY3Rpb25zL0VkaXRvckFjdGlvbnMnO1xuXG5pbXBvcnQgeyBmaWx0ZXIgfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRCQm94XG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvRWxlbWVudHMnO1xuXG5cbi8qKlxuICogUmVnaXN0ZXJzIGFuZCBleGVjdXRlcyBCUE1OIHNwZWNpZmljIGVkaXRvciBhY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5FZGl0b3JBY3Rpb25zKGluamVjdG9yKSB7XG4gIGluamVjdG9yLmludm9rZShFZGl0b3JBY3Rpb25zLCB0aGlzKTtcbn1cblxuaW5oZXJpdHMoQnBtbkVkaXRvckFjdGlvbnMsIEVkaXRvckFjdGlvbnMpO1xuXG5CcG1uRWRpdG9yQWN0aW9ucy4kaW5qZWN0ID0gW1xuICAnaW5qZWN0b3InXG5dO1xuXG4vKipcbiAqIFJlZ2lzdGVyIGRlZmF1bHQgYWN0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge0luamVjdG9yfSBpbmplY3RvclxuICovXG5CcG1uRWRpdG9yQWN0aW9ucy5wcm90b3R5cGUuX3JlZ2lzdGVyRGVmYXVsdEFjdGlvbnMgPSBmdW5jdGlvbihpbmplY3Rvcikge1xuXG4gIC8vICgwKSBpbnZva2Ugc3VwZXIgbWV0aG9kXG5cbiAgRWRpdG9yQWN0aW9ucy5wcm90b3R5cGUuX3JlZ2lzdGVyRGVmYXVsdEFjdGlvbnMuY2FsbCh0aGlzLCBpbmplY3Rvcik7XG5cbiAgLy8gKDEpIHJldHJpZXZlIG9wdGlvbmFsIGNvbXBvbmVudHMgdG8gaW50ZWdyYXRlIHdpdGhcblxuICB2YXIgY2FudmFzID0gaW5qZWN0b3IuZ2V0KCdjYW52YXMnLCBmYWxzZSk7XG4gIHZhciBlbGVtZW50UmVnaXN0cnkgPSBpbmplY3Rvci5nZXQoJ2VsZW1lbnRSZWdpc3RyeScsIGZhbHNlKTtcbiAgdmFyIHNlbGVjdGlvbiA9IGluamVjdG9yLmdldCgnc2VsZWN0aW9uJywgZmFsc2UpO1xuICB2YXIgc3BhY2VUb29sID0gaW5qZWN0b3IuZ2V0KCdzcGFjZVRvb2wnLCBmYWxzZSk7XG4gIHZhciBsYXNzb1Rvb2wgPSBpbmplY3Rvci5nZXQoJ2xhc3NvVG9vbCcsIGZhbHNlKTtcbiAgdmFyIGhhbmRUb29sID0gaW5qZWN0b3IuZ2V0KCdoYW5kVG9vbCcsIGZhbHNlKTtcbiAgdmFyIGdsb2JhbENvbm5lY3QgPSBpbmplY3Rvci5nZXQoJ2dsb2JhbENvbm5lY3QnLCBmYWxzZSk7XG4gIHZhciBkaXN0cmlidXRlRWxlbWVudHMgPSBpbmplY3Rvci5nZXQoJ2Rpc3RyaWJ1dGVFbGVtZW50cycsIGZhbHNlKTtcbiAgdmFyIGFsaWduRWxlbWVudHMgPSBpbmplY3Rvci5nZXQoJ2FsaWduRWxlbWVudHMnLCBmYWxzZSk7XG4gIHZhciBkaXJlY3RFZGl0aW5nID0gaW5qZWN0b3IuZ2V0KCdkaXJlY3RFZGl0aW5nJywgZmFsc2UpO1xuICB2YXIgc2VhcmNoUGFkID0gaW5qZWN0b3IuZ2V0KCdzZWFyY2hQYWQnLCBmYWxzZSk7XG4gIHZhciBtb2RlbGluZyA9IGluamVjdG9yLmdldCgnbW9kZWxpbmcnLCBmYWxzZSk7XG5cbiAgLy8gKDIpIGNoZWNrIGNvbXBvbmVudHMgYW5kIHJlZ2lzdGVyIGFjdGlvbnNcblxuICBpZiAoY2FudmFzICYmIGVsZW1lbnRSZWdpc3RyeSAmJiBzZWxlY3Rpb24pIHtcbiAgICB0aGlzLl9yZWdpc3RlckFjdGlvbignc2VsZWN0RWxlbWVudHMnLCBmdW5jdGlvbigpIHtcblxuICAgICAgLy8gc2VsZWN0IGFsbCBlbGVtZW50cyBleGNlcHQgZm9yIHRoZSBpbnZpc2libGVcbiAgICAgIC8vIHJvb3QgZWxlbWVudFxuICAgICAgdmFyIHJvb3RFbGVtZW50ID0gY2FudmFzLmdldFJvb3RFbGVtZW50KCk7XG5cbiAgICAgIHZhciBlbGVtZW50cyA9IGVsZW1lbnRSZWdpc3RyeS5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gZWxlbWVudCAhPT0gcm9vdEVsZW1lbnQ7XG4gICAgICB9KTtcblxuICAgICAgc2VsZWN0aW9uLnNlbGVjdChlbGVtZW50cyk7XG5cbiAgICAgIHJldHVybiBlbGVtZW50cztcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChzcGFjZVRvb2wpIHtcbiAgICB0aGlzLl9yZWdpc3RlckFjdGlvbignc3BhY2VUb29sJywgZnVuY3Rpb24oKSB7XG4gICAgICBzcGFjZVRvb2wudG9nZ2xlKCk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAobGFzc29Ub29sKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2xhc3NvVG9vbCcsIGZ1bmN0aW9uKCkge1xuICAgICAgbGFzc29Ub29sLnRvZ2dsZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGhhbmRUb29sKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2hhbmRUb29sJywgZnVuY3Rpb24oKSB7XG4gICAgICBoYW5kVG9vbC50b2dnbGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChnbG9iYWxDb25uZWN0KSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2dsb2JhbENvbm5lY3RUb29sJywgZnVuY3Rpb24oKSB7XG4gICAgICBnbG9iYWxDb25uZWN0LnRvZ2dsZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHNlbGVjdGlvbiAmJiBkaXN0cmlidXRlRWxlbWVudHMpIHtcbiAgICB0aGlzLl9yZWdpc3RlckFjdGlvbignZGlzdHJpYnV0ZUVsZW1lbnRzJywgZnVuY3Rpb24ob3B0cykge1xuICAgICAgdmFyIGN1cnJlbnRTZWxlY3Rpb24gPSBzZWxlY3Rpb24uZ2V0KCksXG4gICAgICAgICAgdHlwZSA9IG9wdHMudHlwZTtcblxuICAgICAgaWYgKGN1cnJlbnRTZWxlY3Rpb24ubGVuZ3RoKSB7XG4gICAgICAgIGRpc3RyaWJ1dGVFbGVtZW50cy50cmlnZ2VyKGN1cnJlbnRTZWxlY3Rpb24sIHR5cGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKHNlbGVjdGlvbiAmJiBhbGlnbkVsZW1lbnRzKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2FsaWduRWxlbWVudHMnLCBmdW5jdGlvbihvcHRzKSB7XG4gICAgICB2YXIgY3VycmVudFNlbGVjdGlvbiA9IHNlbGVjdGlvbi5nZXQoKSxcbiAgICAgICAgICBhbGlnbmVhYmxlRWxlbWVudHMgPSBbXSxcbiAgICAgICAgICB0eXBlID0gb3B0cy50eXBlO1xuXG4gICAgICBpZiAoY3VycmVudFNlbGVjdGlvbi5sZW5ndGgpIHtcbiAgICAgICAgYWxpZ25lYWJsZUVsZW1lbnRzID0gZmlsdGVyKGN1cnJlbnRTZWxlY3Rpb24sIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgICByZXR1cm4gIWlzKGVsZW1lbnQsICdicG1uOkxhbmUnKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgYWxpZ25FbGVtZW50cy50cmlnZ2VyKGFsaWduZWFibGVFbGVtZW50cywgdHlwZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBpZiAoc2VsZWN0aW9uICYmIG1vZGVsaW5nKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ3NldENvbG9yJywgZnVuY3Rpb24ob3B0cykge1xuICAgICAgdmFyIGN1cnJlbnRTZWxlY3Rpb24gPSBzZWxlY3Rpb24uZ2V0KCk7XG5cbiAgICAgIGlmIChjdXJyZW50U2VsZWN0aW9uLmxlbmd0aCkge1xuICAgICAgICBtb2RlbGluZy5zZXRDb2xvcihjdXJyZW50U2VsZWN0aW9uLCBvcHRzKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChzZWxlY3Rpb24gJiYgZGlyZWN0RWRpdGluZykge1xuICAgIHRoaXMuX3JlZ2lzdGVyQWN0aW9uKCdkaXJlY3RFZGl0aW5nJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgY3VycmVudFNlbGVjdGlvbiA9IHNlbGVjdGlvbi5nZXQoKTtcblxuICAgICAgaWYgKGN1cnJlbnRTZWxlY3Rpb24ubGVuZ3RoKSB7XG4gICAgICAgIGRpcmVjdEVkaXRpbmcuYWN0aXZhdGUoY3VycmVudFNlbGVjdGlvblswXSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBpZiAoc2VhcmNoUGFkKSB7XG4gICAgdGhpcy5fcmVnaXN0ZXJBY3Rpb24oJ2ZpbmQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHNlYXJjaFBhZC50b2dnbGUoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChjYW52YXMgJiYgbW9kZWxpbmcpIHtcbiAgICB0aGlzLl9yZWdpc3RlckFjdGlvbignbW92ZVRvT3JpZ2luJywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgICAgICBib3VuZGluZ0JveCxcbiAgICAgICAgICBlbGVtZW50cztcblxuICAgICAgaWYgKGlzKHJvb3RFbGVtZW50LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykpIHtcbiAgICAgICAgZWxlbWVudHMgPSBlbGVtZW50UmVnaXN0cnkuZmlsdGVyKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgICByZXR1cm4gaXMoZWxlbWVudC5wYXJlbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBlbGVtZW50cyA9IGVsZW1lbnRSZWdpc3RyeS5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICAgIHJldHVybiBlbGVtZW50ICE9PSByb290RWxlbWVudCAmJiAhaXMoZWxlbWVudC5wYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGJvdW5kaW5nQm94ID0gZ2V0QkJveChlbGVtZW50cyk7XG5cbiAgICAgIG1vZGVsaW5nLm1vdmVFbGVtZW50cyhcbiAgICAgICAgZWxlbWVudHMsXG4gICAgICAgIHsgeDogLWJvdW5kaW5nQm94LngsIHk6IC1ib3VuZGluZ0JveC55IH0sXG4gICAgICAgIHJvb3RFbGVtZW50XG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbn07IiwiaW1wb3J0IEVkaXRvckFjdGlvbnNNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvZWRpdG9yLWFjdGlvbnMnO1xuXG5pbXBvcnQgQnBtbkVkaXRvckFjdGlvbnMgZnJvbSAnLi9CcG1uRWRpdG9yQWN0aW9ucyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBFZGl0b3JBY3Rpb25zTW9kdWxlXG4gIF0sXG4gIGVkaXRvckFjdGlvbnM6IFsgJ3R5cGUnLCBCcG1uRWRpdG9yQWN0aW9ucyBdXG59O1xuIiwiaW1wb3J0IHsgaXNBbnkgfSBmcm9tICcuLi9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uR3JpZFNuYXBwaW5nKGV2ZW50QnVzKSB7XHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2NyZWF0ZS5pbml0JyxcclxuICAgICdzaGFwZS5tb3ZlLmluaXQnXHJcbiAgXSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBzaGFwZSA9IGV2ZW50LnNoYXBlO1xyXG5cclxuICAgIGlmIChpc0FueShzaGFwZSwgW1xyXG4gICAgICAnYnBtbjpQYXJ0aWNpcGFudCcsXHJcbiAgICAgICdicG1uOlN1YlByb2Nlc3MnLFxyXG4gICAgICAnYnBtbjpUZXh0QW5ub3RhdGlvbidcclxuICAgIF0pKSB7XHJcbiAgICAgIGlmICghY29udGV4dC5ncmlkU25hcHBpbmdDb250ZXh0KSB7XHJcbiAgICAgICAgY29udGV4dC5ncmlkU25hcHBpbmdDb250ZXh0ID0ge307XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnRleHQuZ3JpZFNuYXBwaW5nQ29udGV4dC5zbmFwTG9jYXRpb24gPSAndG9wLWxlZnQnO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5CcG1uR3JpZFNuYXBwaW5nLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTsiLCJpbXBvcnQgeyBnZXROZXdTaGFwZVBvc2l0aW9uIH0gZnJvbSAnLi4vLi4vYXV0by1wbGFjZS9CcG1uQXV0b1BsYWNlVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBnZXRNaWQgfSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XHJcbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xyXG5cclxudmFyIEhJR0hfUFJJT1JJVFkgPSAyMDAwO1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEF1dG9QbGFjZUJlaGF2aW9yKGV2ZW50QnVzLCBncmlkU25hcHBpbmcpIHtcclxuICBldmVudEJ1cy5vbignYXV0b1BsYWNlJywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oY29udGV4dCkge1xyXG4gICAgdmFyIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxyXG4gICAgICAgIHNvdXJjZU1pZCA9IGdldE1pZChzb3VyY2UpLFxyXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZTtcclxuXHJcbiAgICB2YXIgcG9zaXRpb24gPSBnZXROZXdTaGFwZVBvc2l0aW9uKHNvdXJjZSwgc2hhcGUpO1xyXG5cclxuICAgIFsgJ3gnLCAneScgXS5mb3JFYWNoKGZ1bmN0aW9uKGF4aXMpIHtcclxuICAgICAgdmFyIG9wdGlvbnMgPSB7fTtcclxuXHJcbiAgICAgIC8vIGRvIG5vdCBzbmFwIGlmIHgveSBlcXVhbFxyXG4gICAgICBpZiAocG9zaXRpb25bIGF4aXMgXSA9PT0gc291cmNlTWlkWyBheGlzIF0pIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChwb3NpdGlvblsgYXhpcyBdID4gc291cmNlTWlkWyBheGlzIF0pIHtcclxuICAgICAgICBvcHRpb25zLm1pbiA9IHBvc2l0aW9uWyBheGlzIF07XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgb3B0aW9ucy5tYXggPSBwb3NpdGlvblsgYXhpcyBdO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXMoc2hhcGUsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcclxuXHJcbiAgICAgICAgaWYgKGlzSG9yaXpvbnRhbChheGlzKSkge1xyXG4gICAgICAgICAgb3B0aW9ucy5vZmZzZXQgPSAtc2hhcGUud2lkdGggLyAyO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBvcHRpb25zLm9mZnNldCA9IC1zaGFwZS5oZWlnaHQgLyAyO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHBvc2l0aW9uWyBheGlzIF0gPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKHBvc2l0aW9uWyBheGlzIF0sIG9wdGlvbnMpO1xyXG5cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIG11c3QgYmUgcmV0dXJuZWQgdG8gYmUgY29uc2lkZXJlZCBieSBhdXRvIHBsYWNlXHJcbiAgICByZXR1cm4gcG9zaXRpb247XHJcbiAgfSk7XHJcbn1cclxuXHJcbkF1dG9QbGFjZUJlaGF2aW9yLiRpbmplY3QgPSBbXHJcbiAgJ2V2ZW50QnVzJyxcclxuICAnZ3JpZFNuYXBwaW5nJ1xyXG5dO1xyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBpc0hvcml6b250YWwoYXhpcykge1xyXG4gIHJldHVybiBheGlzID09PSAneCc7XHJcbn0iLCJpbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcclxuXHJcbnZhciBISUdIRVJfUFJJT1JJVFkgPSAxNzUwO1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IoY2FudmFzLCBldmVudEJ1cywgZ3JpZFNuYXBwaW5nKSB7XHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2NyZWF0ZS5zdGFydCcsXHJcbiAgICAnc2hhcGUubW92ZS5zdGFydCdcclxuICBdLCBISUdIRVJfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxyXG4gICAgICAgIHJvb3RFbGVtZW50ID0gY2FudmFzLmdldFJvb3RFbGVtZW50KCk7XHJcblxyXG4gICAgaWYgKCFpcyhzaGFwZSwgJ2JwbW46UGFydGljaXBhbnQnKSB8fFxyXG4gICAgICAhaXMocm9vdEVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSB8fFxyXG4gICAgICAhcm9vdEVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgY3JlYXRlQ29uc3RyYWludHMgPSBjb250ZXh0LmNyZWF0ZUNvbnN0cmFpbnRzO1xyXG5cclxuICAgIGlmICghY3JlYXRlQ29uc3RyYWludHMpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHNoYXBlLndpZHRoID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShzaGFwZS53aWR0aCwgeyBtaW46IHNoYXBlLndpZHRoIH0pO1xyXG4gICAgc2hhcGUuaGVpZ2h0ID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShzaGFwZS5oZWlnaHQsIHsgbWluOiBzaGFwZS5oZWlnaHQgfSk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbkNyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IuJGluamVjdCA9IFtcclxuICAnY2FudmFzJyxcclxuICAnZXZlbnRCdXMnLFxyXG4gICdncmlkU25hcHBpbmcnXHJcbl07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7IHBvaW50c0FsaWduZWQgfSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0dlb21ldHJ5JztcblxuaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIEhJR0hfUFJJT1JJVFkgPSAzMDAwO1xuXG5cbi8qKlxuICogU25hcHMgY29ubmVjdGlvbnMgd2l0aCBNYW5oYXR0YW4gbGF5b3V0LlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBMYXlvdXRDb25uZWN0aW9uQmVoYXZpb3IoZXZlbnRCdXMsIGdyaWRTbmFwcGluZywgbW9kZWxpbmcpIHtcbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuX2dyaWRTbmFwcGluZyA9IGdyaWRTbmFwcGluZztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoW1xuICAgICdjb25uZWN0aW9uLmNyZWF0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubGF5b3V0J1xuICBdLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cztcblxuICAgIGlmIChoaW50cy5jb25uZWN0aW9uU3RhcnQgfHwgaGludHMuY29ubmVjdGlvbkVuZCB8fCBoaW50cy5jcmVhdGVFbGVtZW50c0JlaGF2aW9yID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghaGFzTWlkZGxlU2VnbWVudHMod2F5cG9pbnRzKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG1vZGVsaW5nLnVwZGF0ZVdheXBvaW50cyhjb25uZWN0aW9uLCBzZWxmLnNuYXBNaWRkbGVTZWdtZW50cyh3YXlwb2ludHMpKTtcbiAgfSk7XG59XG5cbkxheW91dENvbm5lY3Rpb25CZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZ3JpZFNuYXBwaW5nJyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuaW5oZXJpdHMoTGF5b3V0Q29ubmVjdGlvbkJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG4vKipcbiAqIFNuYXAgbWlkZGxlIHNlZ21lbnRzIG9mIGEgZ2l2ZW4gY29ubmVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PFBvaW50Pn0gd2F5cG9pbnRzXG4gKlxuICogQHJldHVybnMge0FycmF5PFBvaW50Pn1cbiAqL1xuTGF5b3V0Q29ubmVjdGlvbkJlaGF2aW9yLnByb3RvdHlwZS5zbmFwTWlkZGxlU2VnbWVudHMgPSBmdW5jdGlvbih3YXlwb2ludHMpIHtcbiAgdmFyIGdyaWRTbmFwcGluZyA9IHRoaXMuX2dyaWRTbmFwcGluZyxcbiAgICAgIHNuYXBwZWQ7XG5cbiAgd2F5cG9pbnRzID0gd2F5cG9pbnRzLnNsaWNlKCk7XG5cbiAgZm9yICh2YXIgaSA9IDE7IGkgPCB3YXlwb2ludHMubGVuZ3RoIC0gMjsgaSsrKSB7XG5cbiAgICBzbmFwcGVkID0gc25hcFNlZ21lbnQoZ3JpZFNuYXBwaW5nLCB3YXlwb2ludHNbaV0sIHdheXBvaW50c1tpICsgMV0pO1xuXG4gICAgd2F5cG9pbnRzW2ldID0gc25hcHBlZFswXTtcbiAgICB3YXlwb2ludHNbaSArIDFdID0gc25hcHBlZFsxXTtcbiAgfVxuXG4gIHJldHVybiB3YXlwb2ludHM7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgYSBjb25uZWN0aW9uIGhhcyBhIG1pZGRsZSBzZWdtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5fSB3YXlwb2ludHNcbiAqXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaGFzTWlkZGxlU2VnbWVudHMod2F5cG9pbnRzKSB7XG4gIHJldHVybiB3YXlwb2ludHMubGVuZ3RoID4gMztcbn1cblxuLyoqXG4gKiBDaGVjayB3aGV0aGVyIGFuIGFsaWdubWVudCBpcyBob3Jpem9udGFsLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhbGlnbmVkXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGhvcml6b250YWxseUFsaWduZWQoYWxpZ25lZCkge1xuICByZXR1cm4gYWxpZ25lZCA9PT0gJ2gnO1xufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgYW4gYWxpZ25tZW50IGlzIHZlcnRpY2FsLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBhbGlnbmVkXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIHZlcnRpY2FsbHlBbGlnbmVkKGFsaWduZWQpIHtcbiAgcmV0dXJuIGFsaWduZWQgPT09ICd2Jztcbn1cblxuLyoqXG4gKiBHZXQgbWlkZGxlIHNlZ21lbnRzIGZyb20gYSBnaXZlbiBjb25uZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7QXJyYXl9IHdheXBvaW50c1xuICpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gc25hcFNlZ21lbnQoZ3JpZFNuYXBwaW5nLCBzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQpIHtcblxuICB2YXIgYWxpZ25lZCA9IHBvaW50c0FsaWduZWQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKTtcblxuICB2YXIgc25hcHBlZCA9IHt9O1xuXG4gIGlmIChob3Jpem9udGFsbHlBbGlnbmVkKGFsaWduZWQpKSB7XG5cbiAgICAvLyBzbmFwIGhvcml6b250YWxseVxuICAgIHNuYXBwZWQueSA9IGdyaWRTbmFwcGluZy5zbmFwVmFsdWUoc2VnbWVudFN0YXJ0LnkpO1xuICB9XG5cbiAgaWYgKHZlcnRpY2FsbHlBbGlnbmVkKGFsaWduZWQpKSB7XG5cbiAgICAvLyBzbmFwIHZlcnRpY2FsbHlcbiAgICBzbmFwcGVkLnggPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKHNlZ21lbnRTdGFydC54KTtcbiAgfVxuXG4gIGlmICgneCcgaW4gc25hcHBlZCB8fCAneScgaW4gc25hcHBlZCkge1xuICAgIHNlZ21lbnRTdGFydCA9IGFzc2lnbih7fSwgc2VnbWVudFN0YXJ0LCBzbmFwcGVkKTtcbiAgICBzZWdtZW50RW5kID0gYXNzaWduKHt9LCBzZWdtZW50RW5kLCBzbmFwcGVkKTtcbiAgfVxuXG4gIHJldHVybiBbIHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCBdO1xufSIsImltcG9ydCBBdXRvUGxhY2VCZWhhdmlvciBmcm9tICcuL0F1dG9QbGFjZUJlaGF2aW9yJztcclxuaW1wb3J0IENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IgZnJvbSAnLi9DcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yJztcclxuaW1wb3J0IExheW91dENvbm5lY3Rpb25CZWhhdmlvciBmcm9tICcuL0xheW91dENvbm5lY3Rpb25CZWhhdmlvcic7XHJcblxyXG5leHBvcnQgZGVmYXVsdCB7XHJcbiAgX19pbml0X186IFtcclxuICAgICdncmlkU25hcHBpbmdBdXRvUGxhY2VCZWhhdmlvcicsXHJcbiAgICAnZ3JpZFNuYXBwaW5nQ3JlYXRlUGFydGljaXBhbnRCZWhhdmlvcicsXHJcbiAgICAnZ3JpZFNuYXBwaW5nTGF5b3V0Q29ubmVjdGlvbkJlaGF2aW9yJyxcclxuICBdLFxyXG4gIGdyaWRTbmFwcGluZ0F1dG9QbGFjZUJlaGF2aW9yOiBbICd0eXBlJywgQXV0b1BsYWNlQmVoYXZpb3IgXSxcclxuICBncmlkU25hcHBpbmdDcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yOiBbICd0eXBlJywgQ3JlYXRlUGFydGljaXBhbnRCZWhhdmlvciBdLFxyXG4gIGdyaWRTbmFwcGluZ0xheW91dENvbm5lY3Rpb25CZWhhdmlvcjogWyAndHlwZScsIExheW91dENvbm5lY3Rpb25CZWhhdmlvciBdXHJcbn07IiwiaW1wb3J0IEJwbW5HcmlkU25hcHBpbmcgZnJvbSAnLi9CcG1uR3JpZFNuYXBwaW5nJztcclxuaW1wb3J0IEdyaWRTbmFwcGluZ01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9ncmlkLXNuYXBwaW5nJztcclxuXHJcbmltcG9ydCBHcmlkU25hcHBpbmdCZWhhdmlvck1vZHVsZSBmcm9tICcuL2JlaGF2aW9yJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBfX2RlcGVuZHNfXzogW1xyXG4gICAgR3JpZFNuYXBwaW5nTW9kdWxlLFxyXG4gICAgR3JpZFNuYXBwaW5nQmVoYXZpb3JNb2R1bGVcclxuICBdLFxyXG4gIF9faW5pdF9fOiBbICdicG1uR3JpZFNuYXBwaW5nJyBdLFxyXG4gIGJwbW5HcmlkU25hcHBpbmc6IFsgJ3R5cGUnLCBCcG1uR3JpZFNuYXBwaW5nIF1cclxufTsiLCJpbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHsgaXNFeHBhbmRlZCB9IGZyb20gJy4uLy4uL3V0aWwvRGlVdGlsJztcblxudmFyIExBQkVMX1dJRFRIID0gMzAsXG4gICAgTEFCRUxfSEVJR0hUID0gMzA7XG5cblxuLyoqXG4gKiBCUE1OLXNwZWNpZmljIGhpdCB6b25lcyBhbmQgaW50ZXJhY3Rpb24gZml4ZXMuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7SW50ZXJhY3Rpb25FdmVudHN9IGludGVyYWN0aW9uRXZlbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5JbnRlcmFjdGlvbkV2ZW50cyhldmVudEJ1cywgaW50ZXJhY3Rpb25FdmVudHMpIHtcblxuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cyA9IGludGVyYWN0aW9uRXZlbnRzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbihbXG4gICAgJ2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUhpdCcsXG4gICAgJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCdcbiAgXSwgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBnZnggPSBjb250ZXh0LmdmeDtcblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpMYW5lJykpIHtcbiAgICAgIHJldHVybiBzZWxmLmNyZWF0ZVBhcnRpY2lwYW50SGl0KGVsZW1lbnQsIGdmeCk7XG4gICAgfSBlbHNlXG5cbiAgICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuICAgICAgaWYgKGlzRXhwYW5kZWQoZWxlbWVudCkpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuY3JlYXRlUGFydGljaXBhbnRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgICAgIH1cbiAgICB9IGVsc2VcblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpTdWJQcm9jZXNzJykpIHtcbiAgICAgIGlmIChpc0V4cGFuZGVkKGVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZVN1YlByb2Nlc3NIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBzZWxmLmNyZWF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG59XG5cbkJwbW5JbnRlcmFjdGlvbkV2ZW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnaW50ZXJhY3Rpb25FdmVudHMnXG5dO1xuXG5cbkJwbW5JbnRlcmFjdGlvbkV2ZW50cy5wcm90b3R5cGUuY3JlYXRlRGVmYXVsdEhpdCA9IGZ1bmN0aW9uKGVsZW1lbnQsIGdmeCkge1xuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cy5yZW1vdmVIaXRzKGdmeCk7XG5cbiAgdGhpcy5faW50ZXJhY3Rpb25FdmVudHMuY3JlYXRlRGVmYXVsdEhpdChlbGVtZW50LCBnZngpO1xuXG4gIC8vIGluZGljYXRlIHRoYXQgd2UgY3JlYXRlZCBhIGhpdFxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkJwbW5JbnRlcmFjdGlvbkV2ZW50cy5wcm90b3R5cGUuY3JlYXRlUGFydGljaXBhbnRIaXQgPSBmdW5jdGlvbihlbGVtZW50LCBnZngpIHtcblxuICAvLyByZW1vdmUgZXhpc3RpbmcgaGl0c1xuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cy5yZW1vdmVIaXRzKGdmeCk7XG5cbiAgLy8gYWRkIG91dGxpbmUgaGl0XG4gIHRoaXMuX2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUJveEhpdChnZngsICdjbGljay1zdHJva2UnLCB7XG4gICAgd2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICB9KTtcblxuICAvLyBhZGQgbGFiZWwgaGl0XG4gIHRoaXMuX2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUJveEhpdChnZngsICdhbGwnLCB7XG4gICAgd2lkdGg6IExBQkVMX1dJRFRILFxuICAgIGhlaWdodDogZWxlbWVudC5oZWlnaHRcbiAgfSk7XG5cbiAgLy8gaW5kaWNhdGUgdGhhdCB3ZSBjcmVhdGVkIGEgaGl0XG4gIHJldHVybiB0cnVlO1xufTtcblxuQnBtbkludGVyYWN0aW9uRXZlbnRzLnByb3RvdHlwZS5jcmVhdGVTdWJQcm9jZXNzSGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG5cbiAgLy8gcmVtb3ZlIGV4aXN0aW5nIGhpdHNcbiAgdGhpcy5faW50ZXJhY3Rpb25FdmVudHMucmVtb3ZlSGl0cyhnZngpO1xuXG4gIC8vIGFkZCBvdXRsaW5lIGhpdFxuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cy5jcmVhdGVCb3hIaXQoZ2Z4LCAnY2xpY2stc3Ryb2tlJywge1xuICAgIHdpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgIGhlaWdodDogZWxlbWVudC5oZWlnaHRcbiAgfSk7XG5cbiAgLy8gYWRkIGxhYmVsIGhpdFxuICB0aGlzLl9pbnRlcmFjdGlvbkV2ZW50cy5jcmVhdGVCb3hIaXQoZ2Z4LCAnYWxsJywge1xuICAgIHdpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgIGhlaWdodDogTEFCRUxfSEVJR0hUXG4gIH0pO1xuXG4gIC8vIGluZGljYXRlIHRoYXQgd2UgY3JlYXRlZCBhIGhpdFxuICByZXR1cm4gdHJ1ZTtcbn07IiwiaW1wb3J0IEJwbW5JbnRlcmFjdGlvbkV2ZW50cyBmcm9tICcuL0JwbW5JbnRlcmFjdGlvbkV2ZW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2JwbW5JbnRlcmFjdGlvbkV2ZW50cycgXSxcbiAgYnBtbkludGVyYWN0aW9uRXZlbnRzOiBbICd0eXBlJywgQnBtbkludGVyYWN0aW9uRXZlbnRzIF1cbn07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IEtleWJvYXJkQmluZGluZ3MgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMva2V5Ym9hcmQvS2V5Ym9hcmRCaW5kaW5ncyc7XG5cblxuLyoqXG4gKiBCUE1OIDIuMCBzcGVjaWZpYyBrZXlib2FyZCBiaW5kaW5ncy5cbiAqXG4gKiBAcGFyYW0ge0luamVjdG9yfSBpbmplY3RvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uS2V5Ym9hcmRCaW5kaW5ncyhpbmplY3Rvcikge1xuICBpbmplY3Rvci5pbnZva2UoS2V5Ym9hcmRCaW5kaW5ncywgdGhpcyk7XG59XG5cbmluaGVyaXRzKEJwbW5LZXlib2FyZEJpbmRpbmdzLCBLZXlib2FyZEJpbmRpbmdzKTtcblxuQnBtbktleWJvYXJkQmluZGluZ3MuJGluamVjdCA9IFtcbiAgJ2luamVjdG9yJ1xuXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVyIGF2YWlsYWJsZSBrZXlib2FyZCBiaW5kaW5ncy5cbiAqXG4gKiBAcGFyYW0ge0tleWJvYXJkfSBrZXlib2FyZFxuICogQHBhcmFtIHtFZGl0b3JBY3Rpb25zfSBlZGl0b3JBY3Rpb25zXG4gKi9cbkJwbW5LZXlib2FyZEJpbmRpbmdzLnByb3RvdHlwZS5yZWdpc3RlckJpbmRpbmdzID0gZnVuY3Rpb24oa2V5Ym9hcmQsIGVkaXRvckFjdGlvbnMpIHtcblxuICAvLyBpbmhlcml0IGRlZmF1bHQgYmluZGluZ3NcbiAgS2V5Ym9hcmRCaW5kaW5ncy5wcm90b3R5cGUucmVnaXN0ZXJCaW5kaW5ncy5jYWxsKHRoaXMsIGtleWJvYXJkLCBlZGl0b3JBY3Rpb25zKTtcblxuICAvKipcbiAgICogQWRkIGtleWJvYXJkIGJpbmRpbmcgaWYgcmVzcGVjdGl2ZSBlZGl0b3IgYWN0aW9uXG4gICAqIGlzIHJlZ2lzdGVyZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhY3Rpb24gbmFtZVxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiB0aGF0IGltcGxlbWVudHMgdGhlIGtleSBiaW5kaW5nXG4gICAqL1xuICBmdW5jdGlvbiBhZGRMaXN0ZW5lcihhY3Rpb24sIGZuKSB7XG5cbiAgICBpZiAoZWRpdG9yQWN0aW9ucy5pc1JlZ2lzdGVyZWQoYWN0aW9uKSkge1xuICAgICAga2V5Ym9hcmQuYWRkTGlzdGVuZXIoZm4pO1xuICAgIH1cbiAgfVxuXG4gIC8vIHNlbGVjdCBhbGwgZWxlbWVudHNcbiAgLy8gQ1RSTCArIEFcbiAgYWRkTGlzdGVuZXIoJ3NlbGVjdEVsZW1lbnRzJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGV2ZW50ID0gY29udGV4dC5rZXlFdmVudDtcblxuICAgIGlmIChrZXlib2FyZC5pc0tleShbJ2EnLCAnQSddLCBldmVudCkgJiYga2V5Ym9hcmQuaXNDbWQoZXZlbnQpKSB7XG4gICAgICBlZGl0b3JBY3Rpb25zLnRyaWdnZXIoJ3NlbGVjdEVsZW1lbnRzJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gc2VhcmNoIGxhYmVsc1xuICAvLyBDVFJMICsgRlxuICBhZGRMaXN0ZW5lcignZmluZCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoa2V5Ym9hcmQuaXNLZXkoWydmJywgJ0YnXSwgZXZlbnQpICYmIGtleWJvYXJkLmlzQ21kKGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdmaW5kJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWN0aXZhdGUgc3BhY2UgdG9vbFxuICAvLyBTXG4gIGFkZExpc3RlbmVyKCdzcGFjZVRvb2wnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGtleWJvYXJkLmhhc01vZGlmaWVyKGV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChrZXlib2FyZC5pc0tleShbJ3MnLCAnUyddLCBldmVudCkpIHtcbiAgICAgIGVkaXRvckFjdGlvbnMudHJpZ2dlcignc3BhY2VUb29sJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWN0aXZhdGUgbGFzc28gdG9vbFxuICAvLyBMXG4gIGFkZExpc3RlbmVyKCdsYXNzb1Rvb2wnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGtleWJvYXJkLmhhc01vZGlmaWVyKGV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChrZXlib2FyZC5pc0tleShbJ2wnLCAnTCddLCBldmVudCkpIHtcbiAgICAgIGVkaXRvckFjdGlvbnMudHJpZ2dlcignbGFzc29Ub29sJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWN0aXZhdGUgaGFuZCB0b29sXG4gIC8vIEhcbiAgYWRkTGlzdGVuZXIoJ2hhbmRUb29sJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGV2ZW50ID0gY29udGV4dC5rZXlFdmVudDtcblxuICAgIGlmIChrZXlib2FyZC5oYXNNb2RpZmllcihldmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoa2V5Ym9hcmQuaXNLZXkoWydoJywgJ0gnXSwgZXZlbnQpKSB7XG4gICAgICBlZGl0b3JBY3Rpb25zLnRyaWdnZXIoJ2hhbmRUb29sJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWN0aXZhdGUgZ2xvYmFsIGNvbm5lY3QgdG9vbFxuICAvLyBDXG4gIGFkZExpc3RlbmVyKCdnbG9iYWxDb25uZWN0VG9vbCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoa2V5Ym9hcmQuaGFzTW9kaWZpZXIoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGtleWJvYXJkLmlzS2V5KFsnYycsICdDJ10sIGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdnbG9iYWxDb25uZWN0VG9vbCcpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIGFjdGl2YXRlIGRpcmVjdCBlZGl0aW5nXG4gIC8vIEVcbiAgYWRkTGlzdGVuZXIoJ2RpcmVjdEVkaXRpbmcnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGtleWJvYXJkLmhhc01vZGlmaWVyKGV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChrZXlib2FyZC5pc0tleShbJ2UnLCAnRSddLCBldmVudCkpIHtcbiAgICAgIGVkaXRvckFjdGlvbnMudHJpZ2dlcignZGlyZWN0RWRpdGluZycpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG59OyIsImltcG9ydCBLZXlib2FyZE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9rZXlib2FyZCc7XG5cbmltcG9ydCBCcG1uS2V5Ym9hcmRCaW5kaW5ncyBmcm9tICcuL0JwbW5LZXlib2FyZEJpbmRpbmdzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIEtleWJvYXJkTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdrZXlib2FyZEJpbmRpbmdzJyBdLFxuICBrZXlib2FyZEJpbmRpbmdzOiBbICd0eXBlJywgQnBtbktleWJvYXJkQmluZGluZ3MgXVxufTtcbiIsImltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY3JlYXRlIGFzIHN2Z0NyZWF0ZSxcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIHRyYW5zbGF0ZVxufSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL1N2Z1RyYW5zZm9ybVV0aWwnO1xuXG52YXIgTUFSS0VSX0hJRERFTiA9ICdkanMtZWxlbWVudC1oaWRkZW4nLFxuICAgIE1BUktFUl9MQUJFTF9ISURERU4gPSAnZGpzLWxhYmVsLWhpZGRlbic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGFiZWxFZGl0aW5nUHJldmlldyhcbiAgICBldmVudEJ1cywgY2FudmFzLCBlbGVtZW50UmVnaXN0cnksXG4gICAgcGF0aE1hcCkge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgZGVmYXVsdExheWVyID0gY2FudmFzLmdldERlZmF1bHRMYXllcigpO1xuXG4gIHZhciBlbGVtZW50LCBhYnNvbHV0ZUVsZW1lbnRCQm94LCBnZng7XG5cbiAgZXZlbnRCdXMub24oJ2RpcmVjdEVkaXRpbmcuYWN0aXZhdGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIGFjdGl2ZVByb3ZpZGVyID0gY29udGV4dC5hY3RpdmU7XG5cbiAgICBlbGVtZW50ID0gYWN0aXZlUHJvdmlkZXIuZWxlbWVudC5sYWJlbCB8fCBhY3RpdmVQcm92aWRlci5lbGVtZW50O1xuXG4gICAgLy8gdGV4dCBhbm5vdGF0aW9uXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcbiAgICAgIGFic29sdXRlRWxlbWVudEJCb3ggPSBjYW52YXMuZ2V0QWJzb2x1dGVCQm94KGVsZW1lbnQpO1xuXG4gICAgICBnZnggPSBzdmdDcmVhdGUoJ2cnKTtcblxuICAgICAgdmFyIHRleHRQYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEVYVF9BTk5PVEFUSU9OJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogZWxlbWVudC5oZWlnaHQsXG4gICAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgICAgbXg6IDAuMCxcbiAgICAgICAgICBteTogMC4wXG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICB2YXIgcGF0aCA9IHNlbGYucGF0aCA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuXG4gICAgICBzdmdBdHRyKHBhdGgsIHtcbiAgICAgICAgZDogdGV4dFBhdGhEYXRhLFxuICAgICAgICBzdHJva2VXaWR0aDogMixcbiAgICAgICAgc3Ryb2tlOiBnZXRTdHJva2VDb2xvcihlbGVtZW50KVxuICAgICAgfSk7XG5cbiAgICAgIHN2Z0FwcGVuZChnZngsIHBhdGgpO1xuXG4gICAgICBzdmdBcHBlbmQoZGVmYXVsdExheWVyLCBnZngpO1xuXG4gICAgICB0cmFuc2xhdGUoZ2Z4LCBlbGVtZW50LngsIGVsZW1lbnQueSk7XG4gICAgfVxuXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykgfHxcbiAgICAgICAgZWxlbWVudC5sYWJlbFRhcmdldCkge1xuICAgICAgY2FudmFzLmFkZE1hcmtlcihlbGVtZW50LCBNQVJLRVJfSElEREVOKTtcbiAgICB9IGVsc2UgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRhc2snKSB8fFxuICAgICAgICAgICAgICAgaXMoZWxlbWVudCwgJ2JwbW46Q2FsbEFjdGl2aXR5JykgfHxcbiAgICAgICAgICAgICAgIGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSB8fFxuICAgICAgICAgICAgICAgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuICAgICAgY2FudmFzLmFkZE1hcmtlcihlbGVtZW50LCBNQVJLRVJfTEFCRUxfSElEREVOKTtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdkaXJlY3RFZGl0aW5nLnJlc2l6ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIC8vIHRleHQgYW5ub3RhdGlvblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgICB2YXIgaGVpZ2h0ID0gY29udGV4dC5oZWlnaHQsXG4gICAgICAgICAgZHkgPSBjb250ZXh0LmR5O1xuXG4gICAgICB2YXIgbmV3RWxlbWVudEhlaWdodCA9IE1hdGgubWF4KGVsZW1lbnQuaGVpZ2h0IC8gYWJzb2x1dGVFbGVtZW50QkJveC5oZWlnaHQgKiAoaGVpZ2h0ICsgZHkpLCAwKTtcblxuICAgICAgdmFyIHRleHRQYXRoRGF0YSA9IHBhdGhNYXAuZ2V0U2NhbGVkUGF0aCgnVEVYVF9BTk5PVEFUSU9OJywge1xuICAgICAgICB4U2NhbGVGYWN0b3I6IDEsXG4gICAgICAgIHlTY2FsZUZhY3RvcjogMSxcbiAgICAgICAgY29udGFpbmVyV2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGNvbnRhaW5lckhlaWdodDogbmV3RWxlbWVudEhlaWdodCxcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICBteDogMC4wLFxuICAgICAgICAgIG15OiAwLjBcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIHN2Z0F0dHIoc2VsZi5wYXRoLCB7XG4gICAgICAgIGQ6IHRleHRQYXRoRGF0YVxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdkaXJlY3RFZGl0aW5nLmNvbXBsZXRlJywgJ2RpcmVjdEVkaXRpbmcuY2FuY2VsJyBdLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIGFjdGl2ZVByb3ZpZGVyID0gY29udGV4dC5hY3RpdmU7XG5cbiAgICBpZiAoYWN0aXZlUHJvdmlkZXIpIHtcbiAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoYWN0aXZlUHJvdmlkZXIuZWxlbWVudC5sYWJlbCB8fCBhY3RpdmVQcm92aWRlci5lbGVtZW50LCBNQVJLRVJfSElEREVOKTtcbiAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoZWxlbWVudCwgTUFSS0VSX0xBQkVMX0hJRERFTik7XG4gICAgfVxuXG4gICAgZWxlbWVudCA9IHVuZGVmaW5lZDtcbiAgICBhYnNvbHV0ZUVsZW1lbnRCQm94ID0gdW5kZWZpbmVkO1xuXG4gICAgaWYgKGdmeCkge1xuICAgICAgc3ZnUmVtb3ZlKGdmeCk7XG5cbiAgICAgIGdmeCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH0pO1xufVxuXG5MYWJlbEVkaXRpbmdQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ3BhdGhNYXAnXG5dO1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBnZXRTdHJva2VDb2xvcihlbGVtZW50LCBkZWZhdWx0Q29sb3IpIHtcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XG5cbiAgcmV0dXJuIGJvLmRpLmdldCgnc3Ryb2tlJykgfHwgZGVmYXVsdENvbG9yIHx8ICdibGFjayc7XG59IiwiaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0TGFiZWxcbn0gZnJvbSAnLi9MYWJlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRCdXNpbmVzc09iamVjdCxcbiAgaXNcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVDYXRlZ29yeVZhbHVlXG59IGZyb20gJy4uL21vZGVsaW5nL2JlaGF2aW9yL3V0aWwvQ2F0ZWdvcnlVdGlsJztcblxuaW1wb3J0IHsgaXNBbnkgfSBmcm9tICcuLi9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCc7XG5pbXBvcnQgeyBpc0V4cGFuZGVkIH0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRFeHRlcm5hbExhYmVsTWlkLFxuICBpc0xhYmVsRXh0ZXJuYWwsXG4gIGhhc0V4dGVybmFsTGFiZWwsXG4gIGlzTGFiZWxcbn0gZnJvbSAnLi4vLi4vdXRpbC9MYWJlbFV0aWwnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIExhYmVsRWRpdGluZ1Byb3ZpZGVyKFxuICAgIGV2ZW50QnVzLCBicG1uRmFjdG9yeSwgY2FudmFzLCBkaXJlY3RFZGl0aW5nLFxuICAgIG1vZGVsaW5nLCByZXNpemVIYW5kbGVzLCB0ZXh0UmVuZGVyZXIpIHtcblxuICB0aGlzLl9icG1uRmFjdG9yeSA9IGJwbW5GYWN0b3J5O1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX3RleHRSZW5kZXJlciA9IHRleHRSZW5kZXJlcjtcblxuICBkaXJlY3RFZGl0aW5nLnJlZ2lzdGVyUHJvdmlkZXIodGhpcyk7XG5cbiAgLy8gbGlzdGVuIHRvIGRibGNsaWNrIG9uIG5vbi1yb290IGVsZW1lbnRzXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LmRibGNsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBhY3RpdmF0ZURpcmVjdEVkaXQoZXZlbnQuZWxlbWVudCwgdHJ1ZSk7XG4gIH0pO1xuXG4gIC8vIGNvbXBsZXRlIG9uIGZvbGxvd3VwIGNhbnZhcyBvcGVyYXRpb25cbiAgZXZlbnRCdXMub24oW1xuICAgICdhdXRvUGxhY2Uuc3RhcnQnLFxuICAgICdjYW52YXMudmlld2JveC5jaGFuZ2luZycsXG4gICAgJ2RyYWcuaW5pdCcsXG4gICAgJ2VsZW1lbnQubW91c2Vkb3duJyxcbiAgICAncG9wdXBNZW51Lm9wZW4nXG4gIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICBpZiAoZGlyZWN0RWRpdGluZy5pc0FjdGl2ZSgpKSB7XG4gICAgICBkaXJlY3RFZGl0aW5nLmNvbXBsZXRlKCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBjYW5jZWwgb24gY29tbWFuZCBzdGFjayBjaGFuZ2VzXG4gIGV2ZW50QnVzLm9uKFsgJ2NvbW1hbmRTdGFjay5jaGFuZ2VkJyBdLCBmdW5jdGlvbihlKSB7XG4gICAgaWYgKGRpcmVjdEVkaXRpbmcuaXNBY3RpdmUoKSkge1xuICAgICAgZGlyZWN0RWRpdGluZy5jYW5jZWwoKTtcbiAgICB9XG4gIH0pO1xuXG5cbiAgZXZlbnRCdXMub24oJ2RpcmVjdEVkaXRpbmcuYWN0aXZhdGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHJlc2l6ZUhhbmRsZXMucmVtb3ZlUmVzaXplcnMoKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2NyZWF0ZS5lbmQnLCA1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnQgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBjYW5FeGVjdXRlID0gZXZlbnQuY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBpc1RvdWNoID0gZXZlbnQuaXNUb3VjaDtcblxuICAgIC8vIFRPRE8obmlra3UpOiB3ZSBuZWVkIHRvIGZpbmQgYSB3YXkgdG8gc3VwcG9ydCB0aGVcbiAgICAvLyBkaXJlY3QgZWRpdGluZyBvbiBtb2JpbGUgZGV2aWNlczsgcmlnaHQgbm93IHRoaXMgd2lsbFxuICAgIC8vIGJyZWFrIGZvciBkZXN3b3JrZmxvd2VkaXRpbmcgb24gbW9iaWxlIGRldmljZXNcbiAgICAvLyBhcyBpdCBicmVha3MgdGhlIHVzZXIgaW50ZXJhY3Rpb24gd29ya2Zsb3dcblxuICAgIC8vIFRPRE8obnJlKTogd2Ugc2hvdWxkIHRlbXBvcmFyaWx5IGZvY3VzIHRoZSBlZGl0ZWQgZWxlbWVudFxuICAgIC8vIGhlcmUgYW5kIHJlbGVhc2UgdGhlIGZvY3VzZWQgdmlld3BvcnQgYWZ0ZXIgdGhlIGRpcmVjdCBlZGl0XG4gICAgLy8gb3BlcmF0aW9uIGlzIGZpbmlzaGVkXG4gICAgaWYgKGlzVG91Y2gpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWNhbkV4ZWN1dGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dC5oaW50cyAmJiBjb250ZXh0LmhpbnRzLmNyZWF0ZUVsZW1lbnRzQmVoYXZpb3IgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYWN0aXZhdGVEaXJlY3RFZGl0KGVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignYXV0b1BsYWNlLmVuZCcsIDUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBhY3RpdmF0ZURpcmVjdEVkaXQoZXZlbnQuc2hhcGUpO1xuICB9KTtcblxuXG4gIGZ1bmN0aW9uIGFjdGl2YXRlRGlyZWN0RWRpdChlbGVtZW50LCBmb3JjZSkge1xuICAgIGlmIChmb3JjZSB8fFxuICAgICAgICBpc0FueShlbGVtZW50LCBbICdicG1uOlRhc2snLCAnYnBtbjpUZXh0QW5ub3RhdGlvbicsICdicG1uOkdyb3VwJyBdKSB8fFxuICAgICAgICBpc0NvbGxhcHNlZFN1YlByb2Nlc3MoZWxlbWVudCkpIHtcblxuICAgICAgZGlyZWN0RWRpdGluZy5hY3RpdmF0ZShlbGVtZW50KTtcbiAgICB9XG4gIH1cblxufVxuXG5MYWJlbEVkaXRpbmdQcm92aWRlci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnYnBtbkZhY3RvcnknLFxuICAnY2FudmFzJyxcbiAgJ2RpcmVjdEVkaXRpbmcnLFxuICAnbW9kZWxpbmcnLFxuICAncmVzaXplSGFuZGxlcycsXG4gICd0ZXh0UmVuZGVyZXInXG5dO1xuXG5cbi8qKlxuICogQWN0aXZhdGUgZGlyZWN0IGVkaXRpbmcgZm9yIGFjdGl2aXRpZXMgYW5kIHRleHQgYW5ub3RhdGlvbnMuXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGFuIG9iamVjdCB3aXRoIHByb3BlcnRpZXMgYm91bmRzIChwb3NpdGlvbiBhbmQgc2l6ZSksIHRleHQgYW5kIG9wdGlvbnNcbiAqL1xuTGFiZWxFZGl0aW5nUHJvdmlkZXIucHJvdG90eXBlLmFjdGl2YXRlID0gZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gIC8vIHRleHRcbiAgdmFyIHRleHQgPSBnZXRMYWJlbChlbGVtZW50KTtcblxuICBpZiAodGV4dCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgdGV4dDogdGV4dFxuICB9O1xuXG4gIC8vIGJvdW5kc1xuICB2YXIgYm91bmRzID0gdGhpcy5nZXRFZGl0aW5nQkJveChlbGVtZW50KTtcblxuICBhc3NpZ24oY29udGV4dCwgYm91bmRzKTtcblxuICB2YXIgb3B0aW9ucyA9IHt9O1xuXG4gIC8vIHRhc2tzXG4gIGlmIChcbiAgICBpc0FueShlbGVtZW50LCBbXG4gICAgICAnYnBtbjpUYXNrJyxcbiAgICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAgICdicG1uOkxhbmUnLFxuICAgICAgJ2JwbW46Q2FsbEFjdGl2aXR5J1xuICAgIF0pIHx8XG4gICAgaXNDb2xsYXBzZWRTdWJQcm9jZXNzKGVsZW1lbnQpXG4gICkge1xuICAgIGFzc2lnbihvcHRpb25zLCB7XG4gICAgICBjZW50ZXJWZXJ0aWNhbGx5OiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICAvLyBleHRlcm5hbCBsYWJlbHNcbiAgaWYgKGlzTGFiZWxFeHRlcm5hbChlbGVtZW50KSkge1xuICAgIGFzc2lnbihvcHRpb25zLCB7XG4gICAgICBhdXRvUmVzaXplOiB0cnVlXG4gICAgfSk7XG4gIH1cblxuICAvLyB0ZXh0IGFubm90YXRpb25zXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgYXNzaWduKG9wdGlvbnMsIHtcbiAgICAgIHJlc2l6YWJsZTogdHJ1ZSxcbiAgICAgIGF1dG9SZXNpemU6IHRydWVcbiAgICB9KTtcbiAgfVxuXG4gIGFzc2lnbihjb250ZXh0LCB7XG4gICAgb3B0aW9uczogb3B0aW9uc1xuICB9KTtcblxuICByZXR1cm4gY29udGV4dDtcbn07XG5cblxuLyoqXG4gKiBHZXQgdGhlIGVkaXRpbmcgYm91bmRpbmcgYm94IGJhc2VkIG9uIHRoZSBlbGVtZW50J3Mgc2l6ZSBhbmQgcG9zaXRpb25cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gYW4gb2JqZWN0IGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gYWJvdXQgcG9zaXRpb25cbiAqICAgICAgICAgICAgICAgICAgYW5kIHNpemUgKGZpeGVkIG9yIG1pbmltdW0gYW5kL29yIG1heGltdW0pXG4gKi9cbkxhYmVsRWRpdGluZ1Byb3ZpZGVyLnByb3RvdHlwZS5nZXRFZGl0aW5nQkJveCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgdmFyIGNhbnZhcyA9IHRoaXMuX2NhbnZhcztcblxuICB2YXIgdGFyZ2V0ID0gZWxlbWVudC5sYWJlbCB8fCBlbGVtZW50O1xuXG4gIHZhciBiYm94ID0gY2FudmFzLmdldEFic29sdXRlQkJveCh0YXJnZXQpO1xuXG4gIHZhciBtaWQgPSB7XG4gICAgeDogYmJveC54ICsgYmJveC53aWR0aCAvIDIsXG4gICAgeTogYmJveC55ICsgYmJveC5oZWlnaHQgLyAyXG4gIH07XG5cbiAgLy8gZGVmYXVsdCBwb3NpdGlvblxuICB2YXIgYm91bmRzID0geyB4OiBiYm94LngsIHk6IGJib3gueSB9O1xuXG4gIHZhciB6b29tID0gY2FudmFzLnpvb20oKTtcblxuICB2YXIgZGVmYXVsdFN0eWxlID0gdGhpcy5fdGV4dFJlbmRlcmVyLmdldERlZmF1bHRTdHlsZSgpLFxuICAgICAgZXh0ZXJuYWxTdHlsZSA9IHRoaXMuX3RleHRSZW5kZXJlci5nZXRFeHRlcm5hbFN0eWxlKCk7XG5cbiAgLy8gdGFrZSB6b29tIGludG8gYWNjb3VudFxuICB2YXIgZXh0ZXJuYWxGb250U2l6ZSA9IGV4dGVybmFsU3R5bGUuZm9udFNpemUgKiB6b29tLFxuICAgICAgZXh0ZXJuYWxMaW5lSGVpZ2h0ID0gZXh0ZXJuYWxTdHlsZS5saW5lSGVpZ2h0LFxuICAgICAgZGVmYXVsdEZvbnRTaXplID0gZGVmYXVsdFN0eWxlLmZvbnRTaXplICogem9vbSxcbiAgICAgIGRlZmF1bHRMaW5lSGVpZ2h0ID0gZGVmYXVsdFN0eWxlLmxpbmVIZWlnaHQ7XG5cbiAgdmFyIHN0eWxlID0ge1xuICAgIGZvbnRGYW1pbHk6IHRoaXMuX3RleHRSZW5kZXJlci5nZXREZWZhdWx0U3R5bGUoKS5mb250RmFtaWx5LFxuICAgIGZvbnRXZWlnaHQ6IHRoaXMuX3RleHRSZW5kZXJlci5nZXREZWZhdWx0U3R5bGUoKS5mb250V2VpZ2h0XG4gIH07XG5cbiAgLy8gYWRqdXN0IGZvciBleHBhbmRlZCBwb29scyBBTkQgbGFuZXNcbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkxhbmUnKSB8fCBpc0V4cGFuZGVkUG9vbChlbGVtZW50KSkge1xuXG4gICAgYXNzaWduKGJvdW5kcywge1xuICAgICAgd2lkdGg6IGJib3guaGVpZ2h0LFxuICAgICAgaGVpZ2h0OiAzMCAqIHpvb20sXG4gICAgICB4OiBiYm94LnggLSBiYm94LmhlaWdodCAvIDIgKyAoMTUgKiB6b29tKSxcbiAgICAgIHk6IG1pZC55IC0gKDMwICogem9vbSkgLyAyXG4gICAgfSk7XG5cbiAgICBhc3NpZ24oc3R5bGUsIHtcbiAgICAgIGZvbnRTaXplOiBkZWZhdWx0Rm9udFNpemUgKyAncHgnLFxuICAgICAgbGluZUhlaWdodDogZGVmYXVsdExpbmVIZWlnaHQsXG4gICAgICBwYWRkaW5nVG9wOiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdCb3R0b206ICg3ICogem9vbSkgKyAncHgnLFxuICAgICAgcGFkZGluZ0xlZnQ6ICg1ICogem9vbSkgKyAncHgnLFxuICAgICAgcGFkZGluZ1JpZ2h0OiAoNSAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHRyYW5zZm9ybTogJ3JvdGF0ZSgtOTBkZWcpJ1xuICAgIH0pO1xuICB9XG5cblxuICAvLyBpbnRlcm5hbCBsYWJlbHMgZm9yIHRhc2tzIGFuZCBjb2xsYXBzZWQgY2FsbCBhY3Rpdml0aWVzLFxuICAvLyBzdWIgcHJvY2Vzc2VzIGFuZCBwYXJ0aWNpcGFudHNcbiAgaWYgKGlzQW55KGVsZW1lbnQsIFsgJ2JwbW46VGFzaycsICdicG1uOkNhbGxBY3Rpdml0eSddKSB8fFxuICAgICAgaXNDb2xsYXBzZWRQb29sKGVsZW1lbnQpIHx8XG4gICAgICBpc0NvbGxhcHNlZFN1YlByb2Nlc3MoZWxlbWVudCkpIHtcblxuICAgIGFzc2lnbihib3VuZHMsIHtcbiAgICAgIHdpZHRoOiBiYm94LndpZHRoLFxuICAgICAgaGVpZ2h0OiBiYm94LmhlaWdodFxuICAgIH0pO1xuXG4gICAgYXNzaWduKHN0eWxlLCB7XG4gICAgICBmb250U2l6ZTogZGVmYXVsdEZvbnRTaXplICsgJ3B4JyxcbiAgICAgIGxpbmVIZWlnaHQ6IGRlZmF1bHRMaW5lSGVpZ2h0LFxuICAgICAgcGFkZGluZ1RvcDogKDcgKiB6b29tKSArICdweCcsXG4gICAgICBwYWRkaW5nQm90dG9tOiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdMZWZ0OiAoNSAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdSaWdodDogKDUgKiB6b29tKSArICdweCdcbiAgICB9KTtcbiAgfVxuXG5cbiAgLy8gaW50ZXJuYWwgbGFiZWxzIGZvciBleHBhbmRlZCBzdWIgcHJvY2Vzc2VzXG4gIGlmIChpc0V4cGFuZGVkU3ViUHJvY2VzcyhlbGVtZW50KSkge1xuICAgIGFzc2lnbihib3VuZHMsIHtcbiAgICAgIHdpZHRoOiBiYm94LndpZHRoLFxuICAgICAgeDogYmJveC54XG4gICAgfSk7XG5cbiAgICBhc3NpZ24oc3R5bGUsIHtcbiAgICAgIGZvbnRTaXplOiBkZWZhdWx0Rm9udFNpemUgKyAncHgnLFxuICAgICAgbGluZUhlaWdodDogZGVmYXVsdExpbmVIZWlnaHQsXG4gICAgICBwYWRkaW5nVG9wOiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdCb3R0b206ICg3ICogem9vbSkgKyAncHgnLFxuICAgICAgcGFkZGluZ0xlZnQ6ICg1ICogem9vbSkgKyAncHgnLFxuICAgICAgcGFkZGluZ1JpZ2h0OiAoNSAqIHpvb20pICsgJ3B4J1xuICAgIH0pO1xuICB9XG5cbiAgdmFyIHdpZHRoID0gOTAgKiB6b29tLFxuICAgICAgcGFkZGluZ1RvcCA9IDcgKiB6b29tLFxuICAgICAgcGFkZGluZ0JvdHRvbSA9IDQgKiB6b29tO1xuXG4gIC8vIGV4dGVybmFsIGxhYmVscyBmb3IgZXZlbnRzLCBkYXRhIGVsZW1lbnRzLCBnYXRld2F5cywgZ3JvdXBzIGFuZCBjb25uZWN0aW9uc1xuICBpZiAodGFyZ2V0LmxhYmVsVGFyZ2V0KSB7XG4gICAgYXNzaWduKGJvdW5kcywge1xuICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgaGVpZ2h0OiBiYm94LmhlaWdodCArIHBhZGRpbmdUb3AgKyBwYWRkaW5nQm90dG9tLFxuICAgICAgeDogbWlkLnggLSB3aWR0aCAvIDIsXG4gICAgICB5OiBiYm94LnkgLSBwYWRkaW5nVG9wXG4gICAgfSk7XG5cbiAgICBhc3NpZ24oc3R5bGUsIHtcbiAgICAgIGZvbnRTaXplOiBleHRlcm5hbEZvbnRTaXplICsgJ3B4JyxcbiAgICAgIGxpbmVIZWlnaHQ6IGV4dGVybmFsTGluZUhlaWdodCxcbiAgICAgIHBhZGRpbmdUb3A6IHBhZGRpbmdUb3AgKyAncHgnLFxuICAgICAgcGFkZGluZ0JvdHRvbTogcGFkZGluZ0JvdHRvbSArICdweCdcbiAgICB9KTtcbiAgfVxuXG4gIC8vIGV4dGVybmFsIGxhYmVsIG5vdCB5ZXQgY3JlYXRlZFxuICBpZiAoaXNMYWJlbEV4dGVybmFsKHRhcmdldClcbiAgICAgICYmICFoYXNFeHRlcm5hbExhYmVsKHRhcmdldClcbiAgICAgICYmICFpc0xhYmVsKHRhcmdldCkpIHtcblxuICAgIHZhciBleHRlcm5hbExhYmVsTWlkID0gZ2V0RXh0ZXJuYWxMYWJlbE1pZChlbGVtZW50KTtcblxuICAgIHZhciBhYnNvbHV0ZUJCb3ggPSBjYW52YXMuZ2V0QWJzb2x1dGVCQm94KHtcbiAgICAgIHg6IGV4dGVybmFsTGFiZWxNaWQueCxcbiAgICAgIHk6IGV4dGVybmFsTGFiZWxNaWQueSxcbiAgICAgIHdpZHRoOiAwLFxuICAgICAgaGVpZ2h0OiAwXG4gICAgfSk7XG5cbiAgICB2YXIgaGVpZ2h0ID0gZXh0ZXJuYWxGb250U2l6ZSArIHBhZGRpbmdUb3AgKyBwYWRkaW5nQm90dG9tO1xuXG4gICAgYXNzaWduKGJvdW5kcywge1xuICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgaGVpZ2h0OiBoZWlnaHQsXG4gICAgICB4OiBhYnNvbHV0ZUJCb3gueCAtIHdpZHRoIC8gMixcbiAgICAgIHk6IGFic29sdXRlQkJveC55IC0gaGVpZ2h0IC8gMlxuICAgIH0pO1xuXG4gICAgYXNzaWduKHN0eWxlLCB7XG4gICAgICBmb250U2l6ZTogZXh0ZXJuYWxGb250U2l6ZSArICdweCcsXG4gICAgICBsaW5lSGVpZ2h0OiBleHRlcm5hbExpbmVIZWlnaHQsXG4gICAgICBwYWRkaW5nVG9wOiBwYWRkaW5nVG9wICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdCb3R0b206IHBhZGRpbmdCb3R0b20gKyAncHgnXG4gICAgfSk7XG4gIH1cblxuICAvLyB0ZXh0IGFubm90YXRpb25zXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgYXNzaWduKGJvdW5kcywge1xuICAgICAgd2lkdGg6IGJib3gud2lkdGgsXG4gICAgICBoZWlnaHQ6IGJib3guaGVpZ2h0LFxuICAgICAgbWluV2lkdGg6IDMwICogem9vbSxcbiAgICAgIG1pbkhlaWdodDogMTAgKiB6b29tXG4gICAgfSk7XG5cbiAgICBhc3NpZ24oc3R5bGUsIHtcbiAgICAgIHRleHRBbGlnbjogJ2xlZnQnLFxuICAgICAgcGFkZGluZ1RvcDogKDUgKiB6b29tKSArICdweCcsXG4gICAgICBwYWRkaW5nQm90dG9tOiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdMZWZ0OiAoNyAqIHpvb20pICsgJ3B4JyxcbiAgICAgIHBhZGRpbmdSaWdodDogKDUgKiB6b29tKSArICdweCcsXG4gICAgICBmb250U2l6ZTogZGVmYXVsdEZvbnRTaXplICsgJ3B4JyxcbiAgICAgIGxpbmVIZWlnaHQ6IGRlZmF1bHRMaW5lSGVpZ2h0XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4geyBib3VuZHM6IGJvdW5kcywgc3R5bGU6IHN0eWxlIH07XG59O1xuXG5cbkxhYmVsRWRpdGluZ1Byb3ZpZGVyLnByb3RvdHlwZS51cGRhdGUgPSBmdW5jdGlvbihcbiAgICBlbGVtZW50LCBuZXdMYWJlbCxcbiAgICBhY3RpdmVDb250ZXh0VGV4dCwgYm91bmRzKSB7XG5cbiAgdmFyIG5ld0JvdW5kcyxcbiAgICAgIGJib3g7XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcblxuICAgIGJib3ggPSB0aGlzLl9jYW52YXMuZ2V0QWJzb2x1dGVCQm94KGVsZW1lbnQpO1xuXG4gICAgbmV3Qm91bmRzID0ge1xuICAgICAgeDogZWxlbWVudC54LFxuICAgICAgeTogZWxlbWVudC55LFxuICAgICAgd2lkdGg6IGVsZW1lbnQud2lkdGggLyBiYm94LndpZHRoICogYm91bmRzLndpZHRoLFxuICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodCAvIGJib3guaGVpZ2h0ICogYm91bmRzLmhlaWdodFxuICAgIH07XG4gIH1cblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46R3JvdXAnKSkge1xuXG4gICAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XG5cbiAgICAvLyBpbml0aWFsaXplIGNhdGVnb3J5VmFsdWUgaWYgbm90IGV4aXN0aW5nXG4gICAgaWYgKCFidXNpbmVzc09iamVjdC5jYXRlZ29yeVZhbHVlUmVmKSB7XG5cbiAgICAgIHZhciByb290RWxlbWVudCA9IHRoaXMuX2NhbnZhcy5nZXRSb290RWxlbWVudCgpLFxuICAgICAgICAgIGRlZmluaXRpb25zID0gZ2V0QnVzaW5lc3NPYmplY3Qocm9vdEVsZW1lbnQpLiRwYXJlbnQ7XG5cbiAgICAgIHZhciBjYXRlZ29yeVZhbHVlID0gY3JlYXRlQ2F0ZWdvcnlWYWx1ZShkZWZpbml0aW9ucywgdGhpcy5fYnBtbkZhY3RvcnkpO1xuXG4gICAgICBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5jYXRlZ29yeVZhbHVlUmVmID0gY2F0ZWdvcnlWYWx1ZTtcbiAgICB9XG5cbiAgfVxuXG4gIGlmIChpc0VtcHR5VGV4dChuZXdMYWJlbCkpIHtcbiAgICBuZXdMYWJlbCA9IG51bGw7XG4gIH1cblxuICB0aGlzLl9tb2RlbGluZy51cGRhdGVMYWJlbChlbGVtZW50LCBuZXdMYWJlbCwgbmV3Qm91bmRzKTtcbn07XG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNDb2xsYXBzZWRTdWJQcm9jZXNzKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJiAhaXNFeHBhbmRlZChlbGVtZW50KTtcbn1cblxuZnVuY3Rpb24gaXNFeHBhbmRlZFN1YlByb2Nlc3MoZWxlbWVudCkge1xuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46U3ViUHJvY2VzcycpICYmIGlzRXhwYW5kZWQoZWxlbWVudCk7XG59XG5cbmZ1bmN0aW9uIGlzQ29sbGFwc2VkUG9vbChlbGVtZW50KSB7XG4gIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpICYmICFpc0V4cGFuZGVkKGVsZW1lbnQpO1xufVxuXG5mdW5jdGlvbiBpc0V4cGFuZGVkUG9vbChlbGVtZW50KSB7XG4gIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpICYmIGlzRXhwYW5kZWQoZWxlbWVudCk7XG59XG5cbmZ1bmN0aW9uIGlzRW1wdHlUZXh0KGxhYmVsKSB7XG4gIHJldHVybiAhbGFiZWwgfHwgIWxhYmVsLnRyaW0oKTtcbn0iLCJpbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuZnVuY3Rpb24gZ2V0TGFiZWxBdHRyKHNlbWFudGljKSB7XG4gIGlmIChcbiAgICBpcyhzZW1hbnRpYywgJ2JwbW46Rmxvd0VsZW1lbnQnKSB8fFxuICAgIGlzKHNlbWFudGljLCAnYnBtbjpQYXJ0aWNpcGFudCcpIHx8XG4gICAgaXMoc2VtYW50aWMsICdicG1uOkxhbmUnKSB8fFxuICAgIGlzKHNlbWFudGljLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSB8fFxuICAgIGlzKHNlbWFudGljLCAnYnBtbjpNZXNzYWdlRmxvdycpIHx8XG4gICAgaXMoc2VtYW50aWMsICdicG1uOkRhdGFJbnB1dCcpIHx8XG4gICAgaXMoc2VtYW50aWMsICdicG1uOkRhdGFPdXRwdXQnKVxuICApIHtcbiAgICByZXR1cm4gJ25hbWUnO1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgcmV0dXJuICd0ZXh0JztcbiAgfVxuXG4gIGlmIChpcyhzZW1hbnRpYywgJ2JwbW46R3JvdXAnKSkge1xuICAgIHJldHVybiAnY2F0ZWdvcnlWYWx1ZVJlZic7XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0Q2F0ZWdvcnlWYWx1ZShzZW1hbnRpYykge1xuICB2YXIgY2F0ZWdvcnlWYWx1ZVJlZiA9IHNlbWFudGljWydjYXRlZ29yeVZhbHVlUmVmJ107XG5cbiAgaWYgKCFjYXRlZ29yeVZhbHVlUmVmKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cblxuICByZXR1cm4gY2F0ZWdvcnlWYWx1ZVJlZi52YWx1ZSB8fCAnJztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExhYmVsKGVsZW1lbnQpIHtcbiAgdmFyIHNlbWFudGljID0gZWxlbWVudC5idXNpbmVzc09iamVjdCxcbiAgICAgIGF0dHIgPSBnZXRMYWJlbEF0dHIoc2VtYW50aWMpO1xuXG4gIGlmIChhdHRyKSB7XG5cbiAgICBpZiAoYXR0ciA9PT0gJ2NhdGVnb3J5VmFsdWVSZWYnKSB7XG5cbiAgICAgIHJldHVybiBnZXRDYXRlZ29yeVZhbHVlKHNlbWFudGljKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2VtYW50aWNbYXR0cl0gfHwgJyc7XG4gIH1cbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gc2V0TGFiZWwoZWxlbWVudCwgdGV4dCwgaXNFeHRlcm5hbCkge1xuICB2YXIgc2VtYW50aWMgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LFxuICAgICAgYXR0ciA9IGdldExhYmVsQXR0cihzZW1hbnRpYyk7XG5cbiAgaWYgKGF0dHIpIHtcblxuICAgIGlmIChhdHRyID09PSAnY2F0ZWdvcnlWYWx1ZVJlZicpIHtcbiAgICAgIHNlbWFudGljWydjYXRlZ29yeVZhbHVlUmVmJ10udmFsdWUgPSB0ZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICBzZW1hbnRpY1thdHRyXSA9IHRleHQ7XG4gICAgfVxuXG4gIH1cblxuICByZXR1cm4gZWxlbWVudDtcbn0iLCJpbXBvcnQge1xuICBzZXRMYWJlbCxcbiAgZ2V0TGFiZWxcbn0gZnJvbSAnLi4vTGFiZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0RXh0ZXJuYWxMYWJlbE1pZCxcbiAgaXNMYWJlbEV4dGVybmFsLFxuICBoYXNFeHRlcm5hbExhYmVsLFxuICBpc0xhYmVsXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTGFiZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgaXNcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG52YXIgTlVMTF9ESU1FTlNJT05TID0ge1xuICB3aWR0aDogMCxcbiAgaGVpZ2h0OiAwXG59O1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgdXBkYXRlcyB0aGUgdGV4dCBvZiBhIEJQTU4gZWxlbWVudC5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVXBkYXRlTGFiZWxIYW5kbGVyKG1vZGVsaW5nLCB0ZXh0UmVuZGVyZXIpIHtcblxuICAvKipcbiAgICogU2V0IHRoZSBsYWJlbCBhbmQgcmV0dXJuIHRoZSBjaGFuZ2VkIGVsZW1lbnRzLlxuICAgKlxuICAgKiBFbGVtZW50IHBhcmFtZXRlciBjYW4gYmUgbGFiZWwgaXRzZWxmIG9yIGNvbm5lY3Rpb24gKGkuZS4gc2VxdWVuY2UgZmxvdykuXG4gICAqXG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHRleHRcbiAgICovXG4gIGZ1bmN0aW9uIHNldFRleHQoZWxlbWVudCwgdGV4dCkge1xuXG4gICAgLy8gZXh0ZXJuYWwgbGFiZWwgaWYgcHJlc2VudFxuICAgIHZhciBsYWJlbCA9IGVsZW1lbnQubGFiZWwgfHwgZWxlbWVudDtcblxuICAgIHZhciBsYWJlbFRhcmdldCA9IGVsZW1lbnQubGFiZWxUYXJnZXQgfHwgZWxlbWVudDtcblxuICAgIHNldExhYmVsKGxhYmVsLCB0ZXh0LCBsYWJlbFRhcmdldCAhPT0gbGFiZWwpO1xuXG4gICAgcmV0dXJuIFsgbGFiZWwsIGxhYmVsVGFyZ2V0IF07XG4gIH1cblxuICBmdW5jdGlvbiBwcmVFeGVjdXRlKGN0eCkge1xuICAgIHZhciBlbGVtZW50ID0gY3R4LmVsZW1lbnQsXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0ID0gZWxlbWVudC5idXNpbmVzc09iamVjdCxcbiAgICAgICAgbmV3TGFiZWwgPSBjdHgubmV3TGFiZWw7XG5cbiAgICBpZiAoIWlzTGFiZWwoZWxlbWVudClcbiAgICAgICAgJiYgaXNMYWJlbEV4dGVybmFsKGVsZW1lbnQpXG4gICAgICAgICYmICFoYXNFeHRlcm5hbExhYmVsKGVsZW1lbnQpXG4gICAgICAgICYmICFpc0VtcHR5VGV4dChuZXdMYWJlbCkpIHtcblxuICAgICAgLy8gY3JlYXRlIGxhYmVsXG4gICAgICB2YXIgcGFkZGluZ1RvcCA9IDc7XG5cbiAgICAgIHZhciBsYWJlbENlbnRlciA9IGdldEV4dGVybmFsTGFiZWxNaWQoZWxlbWVudCk7XG5cbiAgICAgIGxhYmVsQ2VudGVyID0ge1xuICAgICAgICB4OiBsYWJlbENlbnRlci54LFxuICAgICAgICB5OiBsYWJlbENlbnRlci55ICsgcGFkZGluZ1RvcFxuICAgICAgfTtcblxuICAgICAgbW9kZWxpbmcuY3JlYXRlTGFiZWwoZWxlbWVudCwgbGFiZWxDZW50ZXIsIHtcbiAgICAgICAgaWQ6IGJ1c2luZXNzT2JqZWN0LmlkICsgJ19sYWJlbCcsXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0OiBidXNpbmVzc09iamVjdFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZXhlY3V0ZShjdHgpIHtcbiAgICBjdHgub2xkTGFiZWwgPSBnZXRMYWJlbChjdHguZWxlbWVudCk7XG4gICAgcmV0dXJuIHNldFRleHQoY3R4LmVsZW1lbnQsIGN0eC5uZXdMYWJlbCk7XG4gIH1cblxuICBmdW5jdGlvbiByZXZlcnQoY3R4KSB7XG4gICAgcmV0dXJuIHNldFRleHQoY3R4LmVsZW1lbnQsIGN0eC5vbGRMYWJlbCk7XG4gIH1cblxuICBmdW5jdGlvbiBwb3N0RXhlY3V0ZShjdHgpIHtcbiAgICB2YXIgZWxlbWVudCA9IGN0eC5lbGVtZW50LFxuICAgICAgICBsYWJlbCA9IGVsZW1lbnQubGFiZWwgfHwgZWxlbWVudCxcbiAgICAgICAgbmV3TGFiZWwgPSBjdHgubmV3TGFiZWwsXG4gICAgICAgIG5ld0JvdW5kcyA9IGN0eC5uZXdCb3VuZHMsXG4gICAgICAgIGhpbnRzID0gY3R4LmhpbnRzIHx8IHt9O1xuXG4gICAgLy8gaWdub3JlIGludGVybmFsIGxhYmVscyBmb3IgZWxlbWVudHMgZXhjZXB0IHRleHQgYW5ub3RhdGlvbnNcbiAgICBpZiAoIWlzTGFiZWwobGFiZWwpICYmICFpcyhsYWJlbCwgJ2JwbW46VGV4dEFubm90YXRpb24nKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpc0xhYmVsKGxhYmVsKSAmJiBpc0VtcHR5VGV4dChuZXdMYWJlbCkpIHtcblxuICAgICAgaWYgKGhpbnRzLnJlbW92ZVNoYXBlICE9PSBmYWxzZSkge1xuICAgICAgICBtb2RlbGluZy5yZW1vdmVTaGFwZShsYWJlbCwgeyB1bnNldExhYmVsOiBmYWxzZSB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciB0ZXh0ID0gZ2V0TGFiZWwobGFiZWwpO1xuXG4gICAgLy8gcmVzaXplIGVsZW1lbnQgYmFzZWQgb24gbGFiZWwgX29yXyBwcmUtZGVmaW5lZCBib3VuZHNcbiAgICBpZiAodHlwZW9mIG5ld0JvdW5kcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG5ld0JvdW5kcyA9IHRleHRSZW5kZXJlci5nZXRFeHRlcm5hbExhYmVsQm91bmRzKGxhYmVsLCB0ZXh0KTtcbiAgICB9XG5cbiAgICAvLyBzZXR0aW5nIG5ld0JvdW5kcyB0byBmYWxzZSBvciBfbnVsbF8gd2lsbFxuICAgIC8vIGRpc2FibGUgdGhlIHBvc3RFeGVjdXRlIHJlc2l6ZSBvcGVyYXRpb25cbiAgICBpZiAobmV3Qm91bmRzKSB7XG4gICAgICBtb2RlbGluZy5yZXNpemVTaGFwZShsYWJlbCwgbmV3Qm91bmRzLCBOVUxMX0RJTUVOU0lPTlMpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFQSVxuXG4gIHRoaXMucHJlRXhlY3V0ZSA9IHByZUV4ZWN1dGU7XG4gIHRoaXMuZXhlY3V0ZSA9IGV4ZWN1dGU7XG4gIHRoaXMucmV2ZXJ0ID0gcmV2ZXJ0O1xuICB0aGlzLnBvc3RFeGVjdXRlID0gcG9zdEV4ZWN1dGU7XG59XG5cblVwZGF0ZUxhYmVsSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnbW9kZWxpbmcnLFxuICAndGV4dFJlbmRlcmVyJ1xuXTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGlzRW1wdHlUZXh0KGxhYmVsKSB7XG4gIHJldHVybiAhbGFiZWwgfHwgIWxhYmVsLnRyaW0oKTtcbn0iLCJpbXBvcnQgQ2hhbmdlU3VwcG9ydE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9jaGFuZ2Utc3VwcG9ydCc7XG5pbXBvcnQgUmVzaXplTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Jlc2l6ZSc7XG5pbXBvcnQgRGlyZWN0RWRpdGluZ01vZHVsZSBmcm9tICdkaWFncmFtLWpzLWRpcmVjdC1lZGl0aW5nJztcblxuaW1wb3J0IExhYmVsRWRpdGluZ1Byb3ZpZGVyIGZyb20gJy4vTGFiZWxFZGl0aW5nUHJvdmlkZXInO1xuaW1wb3J0IExhYmVsRWRpdGluZ1ByZXZpZXcgZnJvbSAnLi9MYWJlbEVkaXRpbmdQcmV2aWV3JztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgQ2hhbmdlU3VwcG9ydE1vZHVsZSxcbiAgICBSZXNpemVNb2R1bGUsXG4gICAgRGlyZWN0RWRpdGluZ01vZHVsZVxuICBdLFxuICBfX2luaXRfXzogW1xuICAgICdsYWJlbEVkaXRpbmdQcm92aWRlcicsXG4gICAgJ2xhYmVsRWRpdGluZ1ByZXZpZXcnXG4gIF0sXG4gIGxhYmVsRWRpdGluZ1Byb3ZpZGVyOiBbICd0eXBlJywgTGFiZWxFZGl0aW5nUHJvdmlkZXIgXSxcbiAgbGFiZWxFZGl0aW5nUHJldmlldzogWyAndHlwZScsIExhYmVsRWRpdGluZ1ByZXZpZXcgXVxufTtcbiIsImltcG9ydCB7XG4gIG1hcCxcbiAgYXNzaWduLFxuICBwaWNrXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgaXNBbnlcbn0gZnJvbSAnLi91dGlsL01vZGVsaW5nVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzXG59IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uRmFjdG9yeShtb2RkbGUpIHtcbiAgdGhpcy5fbW9kZWwgPSBtb2RkbGU7XG59XG5cbkJwbW5GYWN0b3J5LiRpbmplY3QgPSBbICdtb2RkbGUnIF07XG5cblxuQnBtbkZhY3RvcnkucHJvdG90eXBlLl9uZWVkc0lkID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICByZXR1cm4gaXNBbnkoZWxlbWVudCwgW1xuICAgICdicG1uOlJvb3RFbGVtZW50JyxcbiAgICAnYnBtbjpGbG93RWxlbWVudCcsXG4gICAgJ2JwbW46TWVzc2FnZUZsb3cnLFxuICAgICdicG1uOkRhdGFBc3NvY2lhdGlvbicsXG4gICAgJ2JwbW46QXJ0aWZhY3QnLFxuICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAnYnBtbjpMYW5lJyxcbiAgICAnYnBtbjpMYW5lU2V0JyxcbiAgICAnYnBtbjpQcm9jZXNzJyxcbiAgICAnYnBtbjpDb2xsYWJvcmF0aW9uJyxcbiAgICAnYnBtbmRpOkJQTU5TaGFwZScsXG4gICAgJ2JwbW5kaTpCUE1ORWRnZScsXG4gICAgJ2JwbW5kaTpCUE1ORGlhZ3JhbScsXG4gICAgJ2JwbW5kaTpCUE1OUGxhbmUnLFxuICAgICdicG1uOlByb3BlcnR5JyxcbiAgICAnYnBtbjpDYXRlZ29yeVZhbHVlJ1xuICBdKTtcbn07XG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5fZW5zdXJlSWQgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgLy8gZ2VuZXJhdGUgc2VtYW50aWMgaWRzIGZvciBlbGVtZW50c1xuICAvLyBicG1uOlNlcXVlbmNlRmxvdyAtPiBTZXF1ZW5jZUZsb3dfSURcbiAgdmFyIHByZWZpeDtcblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46QWN0aXZpdHknKSkge1xuICAgIHByZWZpeCA9ICdBY3Rpdml0eSc7XG4gIH0gZWxzZSBpZiAoaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSkge1xuICAgIHByZWZpeCA9ICdFdmVudCc7XG4gIH0gZWxzZSBpZiAoaXMoZWxlbWVudCwgJ2JwbW46R2F0ZXdheScpKSB7XG4gICAgcHJlZml4ID0gJ0dhdGV3YXknO1xuICB9IGVsc2UgaWYgKGlzQW55KGVsZW1lbnQsIFsgJ2JwbW46U2VxdWVuY2VGbG93JywgJ2JwbW46TWVzc2FnZUZsb3cnIF0pKSB7XG4gICAgcHJlZml4ID0gJ0Zsb3cnO1xuICB9IGVsc2Uge1xuICAgIHByZWZpeCA9IChlbGVtZW50LiR0eXBlIHx8ICcnKS5yZXBsYWNlKC9eW146XSo6L2csICcnKTtcbiAgfVxuXG4gIHByZWZpeCArPSAnXyc7XG5cbiAgaWYgKCFlbGVtZW50LmlkICYmIHRoaXMuX25lZWRzSWQoZWxlbWVudCkpIHtcbiAgICBlbGVtZW50LmlkID0gdGhpcy5fbW9kZWwuaWRzLm5leHRQcmVmaXhlZChwcmVmaXgsIGVsZW1lbnQpO1xuICB9XG59O1xuXG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbih0eXBlLCBhdHRycykge1xuICB2YXIgZWxlbWVudCA9IHRoaXMuX21vZGVsLmNyZWF0ZSh0eXBlLCBhdHRycyB8fCB7fSk7XG5cbiAgdGhpcy5fZW5zdXJlSWQoZWxlbWVudCk7XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuXG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVEaUxhYmVsID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnYnBtbmRpOkJQTU5MYWJlbCcsIHtcbiAgICBib3VuZHM6IHRoaXMuY3JlYXRlRGlCb3VuZHMoKVxuICB9KTtcbn07XG5cblxuQnBtbkZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZURpU2hhcGUgPSBmdW5jdGlvbihzZW1hbnRpYywgYm91bmRzLCBhdHRycykge1xuXG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnYnBtbmRpOkJQTU5TaGFwZScsIGFzc2lnbih7XG4gICAgYnBtbkVsZW1lbnQ6IHNlbWFudGljLFxuICAgIGJvdW5kczogdGhpcy5jcmVhdGVEaUJvdW5kcyhib3VuZHMpXG4gIH0sIGF0dHJzKSk7XG59O1xuXG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVEaUJvdW5kcyA9IGZ1bmN0aW9uKGJvdW5kcykge1xuICByZXR1cm4gdGhpcy5jcmVhdGUoJ2RjOkJvdW5kcycsIGJvdW5kcyk7XG59O1xuXG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVEaVdheXBvaW50cyA9IGZ1bmN0aW9uKHdheXBvaW50cykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgcmV0dXJuIG1hcCh3YXlwb2ludHMsIGZ1bmN0aW9uKHBvcykge1xuICAgIHJldHVybiBzZWxmLmNyZWF0ZURpV2F5cG9pbnQocG9zKTtcbiAgfSk7XG59O1xuXG5CcG1uRmFjdG9yeS5wcm90b3R5cGUuY3JlYXRlRGlXYXlwb2ludCA9IGZ1bmN0aW9uKHBvaW50KSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnZGM6UG9pbnQnLCBwaWNrKHBvaW50LCBbICd4JywgJ3knIF0pKTtcbn07XG5cblxuQnBtbkZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZURpRWRnZSA9IGZ1bmN0aW9uKHNlbWFudGljLCB3YXlwb2ludHMsIGF0dHJzKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnYnBtbmRpOkJQTU5FZGdlJywgYXNzaWduKHtcbiAgICBicG1uRWxlbWVudDogc2VtYW50aWNcbiAgfSwgYXR0cnMpKTtcbn07XG5cbkJwbW5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVEaVBsYW5lID0gZnVuY3Rpb24oc2VtYW50aWMpIHtcbiAgcmV0dXJuIHRoaXMuY3JlYXRlKCdicG1uZGk6QlBNTlBsYW5lJywge1xuICAgIGJwbW5FbGVtZW50OiBzZW1hbnRpY1xuICB9KTtcbn07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IEJhc2VMYXlvdXRlciBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvQmFzZUxheW91dGVyJztcblxuaW1wb3J0IHtcbiAgcmVwYWlyQ29ubmVjdGlvbixcbiAgd2l0aG91dFJlZHVuZGFudFBvaW50c1xufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTWFuaGF0dGFuTGF5b3V0JztcblxuaW1wb3J0IHtcbiAgZ2V0TWlkLFxuICBnZXRPcmllbnRhdGlvblxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzRXhwYW5kZWRcbn0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxudmFyIEFUVEFDSF9PUklFTlRBVElPTl9QQURESU5HID0gLTEwLFxuICAgIEJPVU5EQVJZX1RPX0hPU1RfVEhSRVNIT0xEID0gNDA7XG5cbnZhciBvcHBvc2l0ZU9yaWVudGF0aW9uTWFwcGluZyA9IHtcbiAgJ3RvcCc6ICdib3R0b20nLFxuICAndG9wLXJpZ2h0JzogJ2JvdHRvbS1sZWZ0JyxcbiAgJ3RvcC1sZWZ0JzogJ2JvdHRvbS1yaWdodCcsXG4gICdyaWdodCc6ICdsZWZ0JyxcbiAgJ2JvdHRvbSc6ICd0b3AnLFxuICAnYm90dG9tLXJpZ2h0JzogJ3RvcC1sZWZ0JyxcbiAgJ2JvdHRvbS1sZWZ0JzogJ3RvcC1yaWdodCcsXG4gICdsZWZ0JzogJ3JpZ2h0J1xufTtcblxudmFyIG9yaWVudGF0aW9uRGlyZWN0aW9uTWFwcGluZyA9IHtcbiAgdG9wOiAndCcsXG4gIHJpZ2h0OiAncicsXG4gIGJvdHRvbTogJ2InLFxuICBsZWZ0OiAnbCdcbn07XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkxheW91dGVyKCkge31cblxuaW5oZXJpdHMoQnBtbkxheW91dGVyLCBCYXNlTGF5b3V0ZXIpO1xuXG5cbkJwbW5MYXlvdXRlci5wcm90b3R5cGUubGF5b3V0Q29ubmVjdGlvbiA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIGhpbnRzKSB7XG4gIGlmICghaGludHMpIHtcbiAgICBoaW50cyA9IHt9O1xuICB9XG5cbiAgdmFyIHNvdXJjZSA9IGhpbnRzLnNvdXJjZSB8fCBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgIHRhcmdldCA9IGhpbnRzLnRhcmdldCB8fCBjb25uZWN0aW9uLnRhcmdldCxcbiAgICAgIHdheXBvaW50cyA9IGhpbnRzLndheXBvaW50cyB8fCBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgIGNvbm5lY3Rpb25TdGFydCA9IGhpbnRzLmNvbm5lY3Rpb25TdGFydCxcbiAgICAgIGNvbm5lY3Rpb25FbmQgPSBoaW50cy5jb25uZWN0aW9uRW5kO1xuXG4gIHZhciBtYW5oYXR0YW5PcHRpb25zLFxuICAgICAgdXBkYXRlZFdheXBvaW50cztcblxuICBpZiAoIWNvbm5lY3Rpb25TdGFydCkge1xuICAgIGNvbm5lY3Rpb25TdGFydCA9IGdldENvbm5lY3Rpb25Eb2NraW5nKHdheXBvaW50cyAmJiB3YXlwb2ludHNbIDAgXSwgc291cmNlKTtcbiAgfVxuXG4gIGlmICghY29ubmVjdGlvbkVuZCkge1xuICAgIGNvbm5lY3Rpb25FbmQgPSBnZXRDb25uZWN0aW9uRG9ja2luZyh3YXlwb2ludHMgJiYgd2F5cG9pbnRzWyB3YXlwb2ludHMubGVuZ3RoIC0gMSBdLCB0YXJnZXQpO1xuICB9XG5cbiAgLy8gVE9ETyhuaWtrdSk6IHN1cHBvcnQgdmVydGljYWwgbW9kZWxpbmdcbiAgLy8gYW5kIGludmVydCBwcmVmZXJyZWRMYXlvdXRzIGFjY29yZGluZ2x5XG5cbiAgaWYgKGlzKGNvbm5lY3Rpb24sICdicG1uOkFzc29jaWF0aW9uJykgfHxcbiAgICAgIGlzKGNvbm5lY3Rpb24sICdicG1uOkRhdGFBc3NvY2lhdGlvbicpKSB7XG5cbiAgICBpZiAod2F5cG9pbnRzICYmICFpc0NvbXBlbnNhdGlvbkFzc29jaWF0aW9uKHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgICAgcmV0dXJuIFtdLmNvbmNhdChbIGNvbm5lY3Rpb25TdGFydCBdLCB3YXlwb2ludHMuc2xpY2UoMSwgLTEpLCBbIGNvbm5lY3Rpb25FbmQgXSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzKGNvbm5lY3Rpb24sICdicG1uOk1lc3NhZ2VGbG93JykpIHtcbiAgICBtYW5oYXR0YW5PcHRpb25zID0gZ2V0TWVzc2FnZUZsb3dNYW5oYXR0YW5PcHRpb25zKHNvdXJjZSwgdGFyZ2V0KTtcbiAgfSBlbHNlIGlmIChpcyhjb25uZWN0aW9uLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSB8fCBpc0NvbXBlbnNhdGlvbkFzc29jaWF0aW9uKHNvdXJjZSwgdGFyZ2V0KSkge1xuXG4gICAgLy8gbGF5b3V0IGFsbCBjb25uZWN0aW9uIGJldHdlZW4gZmxvdyBlbGVtZW50cyBoOmgsIGV4Y2VwdCBmb3JcbiAgICAvLyAoMSkgb3V0Z29pbmcgb2YgYm91bmRhcnkgZXZlbnRzIC0+IGxheW91dCBiYXNlZCBvbiBhdHRhY2ggb3JpZW50YXRpb24gYW5kIHRhcmdldCBvcmllbnRhdGlvblxuICAgIC8vICgyKSBpbmNvbWluZy9vdXRnb2luZyBvZiBnYXRld2F5cyAtPiB2OmggZm9yIG91dGdvaW5nLCBoOnYgZm9yIGluY29taW5nXG4gICAgLy8gKDMpIGxvb3BzXG4gICAgaWYgKHNvdXJjZSA9PT0gdGFyZ2V0KSB7XG4gICAgICBtYW5oYXR0YW5PcHRpb25zID0ge1xuICAgICAgICBwcmVmZXJyZWRMYXlvdXRzOiBnZXRMb29wUHJlZmVycmVkTGF5b3V0KHNvdXJjZSwgY29ubmVjdGlvbilcbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChpcyhzb3VyY2UsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSkge1xuICAgICAgbWFuaGF0dGFuT3B0aW9ucyA9IHtcbiAgICAgICAgcHJlZmVycmVkTGF5b3V0czogZ2V0Qm91bmRhcnlFdmVudFByZWZlcnJlZExheW91dHMoc291cmNlLCB0YXJnZXQsIGNvbm5lY3Rpb25FbmQpXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoaXNFeHBhbmRlZFN1YlByb2Nlc3Moc291cmNlKSB8fCBpc0V4cGFuZGVkU3ViUHJvY2Vzcyh0YXJnZXQpKSB7XG4gICAgICBtYW5oYXR0YW5PcHRpb25zID0gZ2V0U3ViUHJvY2Vzc01hbmhhdHRhbk9wdGlvbnMoc291cmNlKTtcbiAgICB9IGVsc2UgaWYgKGlzKHNvdXJjZSwgJ2JwbW46R2F0ZXdheScpKSB7XG4gICAgICBtYW5oYXR0YW5PcHRpb25zID0ge1xuICAgICAgICBwcmVmZXJyZWRMYXlvdXRzOiBbICd2OmgnIF1cbiAgICAgIH07XG4gICAgfSBlbHNlIGlmIChpcyh0YXJnZXQsICdicG1uOkdhdGV3YXknKSkge1xuICAgICAgbWFuaGF0dGFuT3B0aW9ucyA9IHtcbiAgICAgICAgcHJlZmVycmVkTGF5b3V0czogWyAnaDp2JyBdXG4gICAgICB9O1xuICAgIH0gZWxzZSB7XG4gICAgICBtYW5oYXR0YW5PcHRpb25zID0ge1xuICAgICAgICBwcmVmZXJyZWRMYXlvdXRzOiBbICdoOmgnIF1cbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgaWYgKG1hbmhhdHRhbk9wdGlvbnMpIHtcbiAgICBtYW5oYXR0YW5PcHRpb25zID0gYXNzaWduKG1hbmhhdHRhbk9wdGlvbnMsIGhpbnRzKTtcblxuICAgIHVwZGF0ZWRXYXlwb2ludHMgPSB3aXRob3V0UmVkdW5kYW50UG9pbnRzKHJlcGFpckNvbm5lY3Rpb24oXG4gICAgICBzb3VyY2UsXG4gICAgICB0YXJnZXQsXG4gICAgICBjb25uZWN0aW9uU3RhcnQsXG4gICAgICBjb25uZWN0aW9uRW5kLFxuICAgICAgd2F5cG9pbnRzLFxuICAgICAgbWFuaGF0dGFuT3B0aW9uc1xuICAgICkpO1xuICB9XG5cbiAgcmV0dXJuIHVwZGF0ZWRXYXlwb2ludHMgfHwgWyBjb25uZWN0aW9uU3RhcnQsIGNvbm5lY3Rpb25FbmQgXTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldEF0dGFjaE9yaWVudGF0aW9uKGF0dGFjaGVkRWxlbWVudCkge1xuICB2YXIgaG9zdEVsZW1lbnQgPSBhdHRhY2hlZEVsZW1lbnQuaG9zdDtcblxuICByZXR1cm4gZ2V0T3JpZW50YXRpb24oZ2V0TWlkKGF0dGFjaGVkRWxlbWVudCksIGhvc3RFbGVtZW50LCBBVFRBQ0hfT1JJRU5UQVRJT05fUEFERElORyk7XG59XG5cbmZ1bmN0aW9uIGdldE1lc3NhZ2VGbG93TWFuaGF0dGFuT3B0aW9ucyhzb3VyY2UsIHRhcmdldCkge1xuICByZXR1cm4ge1xuICAgIHByZWZlcnJlZExheW91dHM6IFsgJ3N0cmFpZ2h0JywgJ3Y6dicgXSxcbiAgICBwcmVzZXJ2ZURvY2tpbmc6IGdldE1lc3NhZ2VGbG93UHJlc2VydmVEb2NraW5nKHNvdXJjZSwgdGFyZ2V0KVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRNZXNzYWdlRmxvd1ByZXNlcnZlRG9ja2luZyhzb3VyY2UsIHRhcmdldCkge1xuXG4gIC8vICgxKSBkb2NraW5nIGVsZW1lbnQgY29ubmVjdGVkIHRvIHBhcnRpY2lwYW50IGhhcyBwcmVjZWRlbmNlXG4gIGlmIChpcyh0YXJnZXQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICByZXR1cm4gJ3NvdXJjZSc7XG4gIH1cblxuICBpZiAoaXMoc291cmNlLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgcmV0dXJuICd0YXJnZXQnO1xuICB9XG5cbiAgLy8gKDIpIGRvY2tpbmcgZWxlbWVudCBjb25uZWN0ZWQgdG8gZXhwYW5kZWQgc3ViLXByb2Nlc3MgaGFzIHByZWNlZGVuY2VcbiAgaWYgKGlzRXhwYW5kZWRTdWJQcm9jZXNzKHRhcmdldCkpIHtcbiAgICByZXR1cm4gJ3NvdXJjZSc7XG4gIH1cblxuICBpZiAoaXNFeHBhbmRlZFN1YlByb2Nlc3Moc291cmNlKSkge1xuICAgIHJldHVybiAndGFyZ2V0JztcbiAgfVxuXG4gIC8vICgzKSBkb2NraW5nIGV2ZW50IGhhcyBwcmVjZWRlbmNlXG4gIGlmIChpcyh0YXJnZXQsICdicG1uOkV2ZW50JykpIHtcbiAgICByZXR1cm4gJ3RhcmdldCc7XG4gIH1cblxuICBpZiAoaXMoc291cmNlLCAnYnBtbjpFdmVudCcpKSB7XG4gICAgcmV0dXJuICdzb3VyY2UnO1xuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldFN1YlByb2Nlc3NNYW5oYXR0YW5PcHRpb25zKHNvdXJjZSkge1xuICByZXR1cm4ge1xuICAgIHByZWZlcnJlZExheW91dHM6IFsgJ3N0cmFpZ2h0JywgJ2g6aCcgXSxcbiAgICBwcmVzZXJ2ZURvY2tpbmc6IGdldFN1YlByb2Nlc3NQcmVzZXJ2ZURvY2tpbmcoc291cmNlKVxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRTdWJQcm9jZXNzUHJlc2VydmVEb2NraW5nKHNvdXJjZSkge1xuICByZXR1cm4gaXNFeHBhbmRlZFN1YlByb2Nlc3Moc291cmNlKSA/ICd0YXJnZXQnIDogJ3NvdXJjZSc7XG59XG5cbmZ1bmN0aW9uIGdldENvbm5lY3Rpb25Eb2NraW5nKHBvaW50LCBzaGFwZSkge1xuICByZXR1cm4gcG9pbnQgPyAocG9pbnQub3JpZ2luYWwgfHwgcG9pbnQpIDogZ2V0TWlkKHNoYXBlKTtcbn1cblxuZnVuY3Rpb24gaXNDb21wZW5zYXRpb25Bc3NvY2lhdGlvbihzb3VyY2UsIHRhcmdldCkge1xuICByZXR1cm4gaXModGFyZ2V0LCAnYnBtbjpBY3Rpdml0eScpICYmXG4gICAgaXMoc291cmNlLCAnYnBtbjpCb3VuZGFyeUV2ZW50JykgJiZcbiAgICB0YXJnZXQuYnVzaW5lc3NPYmplY3QuaXNGb3JDb21wZW5zYXRpb247XG59XG5cbmZ1bmN0aW9uIGlzRXhwYW5kZWRTdWJQcm9jZXNzKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJiBpc0V4cGFuZGVkKGVsZW1lbnQpO1xufVxuXG5mdW5jdGlvbiBpc1NhbWUoYSwgYikge1xuICByZXR1cm4gYSA9PT0gYjtcbn1cblxuZnVuY3Rpb24gaXNBbnlPcmllbnRhdGlvbihvcmllbnRhdGlvbiwgb3JpZW50YXRpb25zKSB7XG4gIHJldHVybiBvcmllbnRhdGlvbnMuaW5kZXhPZihvcmllbnRhdGlvbikgIT09IC0xO1xufVxuXG5mdW5jdGlvbiBnZXRIb3Jpem9udGFsT3JpZW50YXRpb24ob3JpZW50YXRpb24pIHtcbiAgdmFyIG1hdGNoZXMgPSAvcmlnaHR8bGVmdC8uZXhlYyhvcmllbnRhdGlvbik7XG5cbiAgcmV0dXJuIG1hdGNoZXMgJiYgbWF0Y2hlc1swXTtcbn1cblxuZnVuY3Rpb24gZ2V0VmVydGljYWxPcmllbnRhdGlvbihvcmllbnRhdGlvbikge1xuICB2YXIgbWF0Y2hlcyA9IC90b3B8Ym90dG9tLy5leGVjKG9yaWVudGF0aW9uKTtcblxuICByZXR1cm4gbWF0Y2hlcyAmJiBtYXRjaGVzWzBdO1xufVxuXG5mdW5jdGlvbiBpc09wcG9zaXRlT3JpZW50YXRpb24oYSwgYikge1xuICByZXR1cm4gb3Bwb3NpdGVPcmllbnRhdGlvbk1hcHBpbmdbYV0gPT09IGI7XG59XG5cbmZ1bmN0aW9uIGlzT3Bwb3NpdGVIb3Jpem9udGFsT3JpZW50YXRpb24oYSwgYikge1xuICB2YXIgaG9yaXpvbnRhbE9yaWVudGF0aW9uID0gZ2V0SG9yaXpvbnRhbE9yaWVudGF0aW9uKGEpO1xuXG4gIHZhciBvcHBvc2l0ZUhvcml6b250YWxPcmllbnRhdGlvbiA9IG9wcG9zaXRlT3JpZW50YXRpb25NYXBwaW5nW2hvcml6b250YWxPcmllbnRhdGlvbl07XG5cbiAgcmV0dXJuIGIuaW5kZXhPZihvcHBvc2l0ZUhvcml6b250YWxPcmllbnRhdGlvbikgIT09IC0xO1xufVxuXG5mdW5jdGlvbiBpc09wcG9zaXRlVmVydGljYWxPcmllbnRhdGlvbihhLCBiKSB7XG4gIHZhciB2ZXJ0aWNhbE9yaWVudGF0aW9uID0gZ2V0VmVydGljYWxPcmllbnRhdGlvbihhKTtcblxuICB2YXIgb3Bwb3NpdGVWZXJ0aWNhbE9yaWVudGF0aW9uID0gb3Bwb3NpdGVPcmllbnRhdGlvbk1hcHBpbmdbdmVydGljYWxPcmllbnRhdGlvbl07XG5cbiAgcmV0dXJuIGIuaW5kZXhPZihvcHBvc2l0ZVZlcnRpY2FsT3JpZW50YXRpb24pICE9PSAtMTtcbn1cblxuZnVuY3Rpb24gaXNIb3Jpem9udGFsT3JpZW50YXRpb24ob3JpZW50YXRpb24pIHtcbiAgcmV0dXJuIG9yaWVudGF0aW9uID09PSAncmlnaHQnIHx8IG9yaWVudGF0aW9uID09PSAnbGVmdCc7XG59XG5cbmZ1bmN0aW9uIGdldExvb3BQcmVmZXJyZWRMYXlvdXQoc291cmNlLCBjb25uZWN0aW9uKSB7XG4gIHZhciB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cztcblxuICB2YXIgb3JpZW50YXRpb24gPSB3YXlwb2ludHMgJiYgd2F5cG9pbnRzLmxlbmd0aCAmJiBnZXRPcmllbnRhdGlvbih3YXlwb2ludHNbMF0sIHNvdXJjZSk7XG5cbiAgaWYgKG9yaWVudGF0aW9uID09PSAndG9wJykge1xuICAgIHJldHVybiBbICd0OnInIF07XG4gIH0gZWxzZSBpZiAob3JpZW50YXRpb24gPT09ICdyaWdodCcpIHtcbiAgICByZXR1cm4gWyAncjpiJyBdO1xuICB9IGVsc2UgaWYgKG9yaWVudGF0aW9uID09PSAnbGVmdCcpIHtcbiAgICByZXR1cm4gWyAnbDp0JyBdO1xuICB9XG5cbiAgcmV0dXJuIFsgJ2I6bCcgXTtcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRhcnlFdmVudFByZWZlcnJlZExheW91dHMoc291cmNlLCB0YXJnZXQsIGVuZCkge1xuICB2YXIgc291cmNlTWlkID0gZ2V0TWlkKHNvdXJjZSksXG4gICAgICB0YXJnZXRNaWQgPSBnZXRNaWQodGFyZ2V0KSxcbiAgICAgIGF0dGFjaE9yaWVudGF0aW9uID0gZ2V0QXR0YWNoT3JpZW50YXRpb24oc291cmNlKSxcbiAgICAgIHNvdXJjZUxheW91dCxcbiAgICAgIHRhcmdldExheW91dDtcblxuICB2YXIgaXNMb29wID0gaXNTYW1lKHNvdXJjZS5ob3N0LCB0YXJnZXQpO1xuXG4gIHZhciBhdHRhY2hlZFRvU2lkZSA9IGlzQW55T3JpZW50YXRpb24oYXR0YWNoT3JpZW50YXRpb24sIFsgJ3RvcCcsICdyaWdodCcsICdib3R0b20nLCAnbGVmdCcgXSk7XG5cbiAgdmFyIHRhcmdldE9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24odGFyZ2V0TWlkLCBzb3VyY2VNaWQsIHtcbiAgICB4OiBzb3VyY2Uud2lkdGggLyAyICsgdGFyZ2V0LndpZHRoIC8gMixcbiAgICB5OiBzb3VyY2UuaGVpZ2h0IC8gMiArIHRhcmdldC5oZWlnaHQgLyAyXG4gIH0pO1xuXG4gIGlmIChpc0xvb3ApIHtcbiAgICByZXR1cm4gZ2V0Qm91bmRhcnlFdmVudExvb3BMYXlvdXQoYXR0YWNoT3JpZW50YXRpb24sIGF0dGFjaGVkVG9TaWRlLCBzb3VyY2UsIHRhcmdldCwgZW5kKTtcbiAgfVxuXG4gIC8vIHNvdXJjZSBsYXlvdXRcbiAgc291cmNlTGF5b3V0ID0gZ2V0Qm91bmRhcnlFdmVudFNvdXJjZUxheW91dChhdHRhY2hPcmllbnRhdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24sIGF0dGFjaGVkVG9TaWRlKTtcblxuICAvLyB0YXJnZXQgbGF5b3V0XG4gIHRhcmdldExheW91dCA9IGdldEJvdW5kYXJ5RXZlbnRUYXJnZXRMYXlvdXQoYXR0YWNoT3JpZW50YXRpb24sIHRhcmdldE9yaWVudGF0aW9uLCBhdHRhY2hlZFRvU2lkZSk7XG5cbiAgcmV0dXJuIFsgc291cmNlTGF5b3V0ICsgJzonICsgdGFyZ2V0TGF5b3V0IF07XG59XG5cbmZ1bmN0aW9uIGdldEJvdW5kYXJ5RXZlbnRMb29wTGF5b3V0KGF0dGFjaE9yaWVudGF0aW9uLCBhdHRhY2hlZFRvU2lkZSwgc291cmNlLCB0YXJnZXQsIGVuZCkge1xuICB2YXIgb3JpZW50YXRpb24gPSBhdHRhY2hlZFRvU2lkZSA/IGF0dGFjaE9yaWVudGF0aW9uIDogZ2V0VmVydGljYWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbiksXG4gICAgICBzb3VyY2VMYXlvdXQgPSBvcmllbnRhdGlvbkRpcmVjdGlvbk1hcHBpbmdbIG9yaWVudGF0aW9uIF0sXG4gICAgICB0YXJnZXRMYXlvdXQ7XG5cbiAgaWYgKGF0dGFjaGVkVG9TaWRlKSB7XG4gICAgaWYgKGlzSG9yaXpvbnRhbE9yaWVudGF0aW9uKGF0dGFjaE9yaWVudGF0aW9uKSkge1xuICAgICAgdGFyZ2V0TGF5b3V0ID0gc2hvdWxkQ29ubmVjdFRvU2FtZVNpZGUoJ3knLCBzb3VyY2UsIHRhcmdldCwgZW5kKSA/ICdoJyA6ICdiJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGFyZ2V0TGF5b3V0ID0gc2hvdWxkQ29ubmVjdFRvU2FtZVNpZGUoJ3gnLCBzb3VyY2UsIHRhcmdldCwgZW5kKSA/ICd2JyA6ICdsJztcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0TGF5b3V0ID0gJ3YnO1xuICB9XG5cbiAgcmV0dXJuIFsgc291cmNlTGF5b3V0ICsgJzonICsgdGFyZ2V0TGF5b3V0IF07XG59XG5cbmZ1bmN0aW9uIHNob3VsZENvbm5lY3RUb1NhbWVTaWRlKGF4aXMsIHNvdXJjZSwgdGFyZ2V0LCBlbmQpIHtcbiAgdmFyIHRocmVzaG9sZCA9IEJPVU5EQVJZX1RPX0hPU1RfVEhSRVNIT0xEO1xuXG4gIHJldHVybiAhKFxuICAgIGFyZUNsb3NlT25BeGlzKGF4aXMsIGVuZCwgdGFyZ2V0LCB0aHJlc2hvbGQpIHx8XG4gICAgYXJlQ2xvc2VPbkF4aXMoYXhpcywgZW5kLCB7XG4gICAgICB4OiB0YXJnZXQueCArIHRhcmdldC53aWR0aCxcbiAgICAgIHk6IHRhcmdldC55ICsgdGFyZ2V0LmhlaWdodFxuICAgIH0sIHRocmVzaG9sZCkgfHxcbiAgICBhcmVDbG9zZU9uQXhpcyhheGlzLCBlbmQsIGdldE1pZChzb3VyY2UpLCB0aHJlc2hvbGQpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGFyZUNsb3NlT25BeGlzKGF4aXMsIGEsIGIsIHRocmVzaG9sZCkge1xuICByZXR1cm4gTWF0aC5hYnMoYVsgYXhpcyBdIC0gYlsgYXhpcyBdKSA8IHRocmVzaG9sZDtcbn1cblxuZnVuY3Rpb24gZ2V0Qm91bmRhcnlFdmVudFNvdXJjZUxheW91dChhdHRhY2hPcmllbnRhdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24sIGF0dGFjaGVkVG9TaWRlKSB7XG5cbiAgLy8gYXR0YWNoZWQgdG8gZWl0aGVyIHRvcCwgcmlnaHQsIGJvdHRvbSBvciBsZWZ0IHNpZGVcbiAgaWYgKGF0dGFjaGVkVG9TaWRlKSB7XG4gICAgcmV0dXJuIG9yaWVudGF0aW9uRGlyZWN0aW9uTWFwcGluZ1sgYXR0YWNoT3JpZW50YXRpb24gXTtcbiAgfVxuXG4gIC8vIGF0dGFjaGVkIHRvIGVpdGhlciB0b3AtcmlnaHQsIHRvcC1sZWZ0LCBib3R0b20tcmlnaHQgb3IgYm90dG9tLWxlZnQgY29ybmVyXG5cbiAgLy8gc2FtZSB2ZXJ0aWNhbCBvciBvcHBvc2l0ZSBob3Jpem9udGFsIG9yaWVudGF0aW9uXG4gIGlmIChpc1NhbWUoXG4gICAgZ2V0VmVydGljYWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbiksIGdldFZlcnRpY2FsT3JpZW50YXRpb24odGFyZ2V0T3JpZW50YXRpb24pXG4gICkgfHwgaXNPcHBvc2l0ZU9yaWVudGF0aW9uKFxuICAgIGdldEhvcml6b250YWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbiksIGdldEhvcml6b250YWxPcmllbnRhdGlvbih0YXJnZXRPcmllbnRhdGlvbilcbiAgKSkge1xuICAgIHJldHVybiBvcmllbnRhdGlvbkRpcmVjdGlvbk1hcHBpbmdbIGdldFZlcnRpY2FsT3JpZW50YXRpb24oYXR0YWNoT3JpZW50YXRpb24pIF07XG4gIH1cblxuICAvLyBmYWxsYmFja1xuICByZXR1cm4gb3JpZW50YXRpb25EaXJlY3Rpb25NYXBwaW5nWyBnZXRIb3Jpem9udGFsT3JpZW50YXRpb24oYXR0YWNoT3JpZW50YXRpb24pIF07XG59XG5cbmZ1bmN0aW9uIGdldEJvdW5kYXJ5RXZlbnRUYXJnZXRMYXlvdXQoYXR0YWNoT3JpZW50YXRpb24sIHRhcmdldE9yaWVudGF0aW9uLCBhdHRhY2hlZFRvU2lkZSkge1xuXG4gIC8vIGF0dGFjaGVkIHRvIGVpdGhlciB0b3AsIHJpZ2h0LCBib3R0b20gb3IgbGVmdCBzaWRlXG4gIGlmIChhdHRhY2hlZFRvU2lkZSkge1xuICAgIGlmIChpc0hvcml6b250YWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbikpIHtcblxuICAgICAgLy8gb3JpZW50YXRpb24gaXMgcmlnaHQgb3IgbGVmdFxuXG4gICAgICAvLyBvcHBvc2l0ZSBob3Jpem9udGFsIG9yaWVudGF0aW9uIG9yIHNhbWUgb3JpZW50YXRpb25cbiAgICAgIGlmIChcbiAgICAgICAgaXNPcHBvc2l0ZUhvcml6b250YWxPcmllbnRhdGlvbihhdHRhY2hPcmllbnRhdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24pIHx8XG4gICAgICAgIGlzU2FtZShhdHRhY2hPcmllbnRhdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24pXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuICdoJztcbiAgICAgIH1cblxuICAgICAgLy8gZmFsbGJhY2tcbiAgICAgIHJldHVybiAndic7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gb3JpZW50YXRpb24gaXMgdG9wIG9yIGJvdHRvbVxuXG4gICAgICAvLyBvcHBvc2l0ZSB2ZXJ0aWNhbCBvcmllbnRhdGlvbiBvciBzYW1lIG9yaWVudGF0aW9uXG4gICAgICBpZiAoXG4gICAgICAgIGlzT3Bwb3NpdGVWZXJ0aWNhbE9yaWVudGF0aW9uKGF0dGFjaE9yaWVudGF0aW9uLCB0YXJnZXRPcmllbnRhdGlvbikgfHxcbiAgICAgICAgaXNTYW1lKGF0dGFjaE9yaWVudGF0aW9uLCB0YXJnZXRPcmllbnRhdGlvbilcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gJ3YnO1xuICAgICAgfVxuXG4gICAgICAvLyBmYWxsYmFja1xuICAgICAgcmV0dXJuICdoJztcbiAgICB9XG4gIH1cblxuICAvLyBhdHRhY2hlZCB0byBlaXRoZXIgdG9wLXJpZ2h0LCB0b3AtbGVmdCwgYm90dG9tLXJpZ2h0IG9yIGJvdHRvbS1sZWZ0IGNvcm5lclxuXG4gIC8vIG9yaWVudGF0aW9uIGlzIHJpZ2h0LCBsZWZ0XG4gIC8vIG9yIHNhbWUgdmVydGljYWwgb3JpZW50YXRpb24gYnV0IGFsc28gcmlnaHQgb3IgbGVmdFxuICBpZiAoaXNIb3Jpem9udGFsT3JpZW50YXRpb24odGFyZ2V0T3JpZW50YXRpb24pIHx8XG4gICAgKGlzU2FtZShnZXRWZXJ0aWNhbE9yaWVudGF0aW9uKGF0dGFjaE9yaWVudGF0aW9uKSwgZ2V0VmVydGljYWxPcmllbnRhdGlvbih0YXJnZXRPcmllbnRhdGlvbikpICYmXG4gICAgICBnZXRIb3Jpem9udGFsT3JpZW50YXRpb24odGFyZ2V0T3JpZW50YXRpb24pKSkge1xuICAgIHJldHVybiAnaCc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuICd2JztcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHtcbiAgcmVtb3ZlIGFzIGNvbGxlY3Rpb25SZW1vdmUsXG4gIGFkZCBhcyBjb2xsZWN0aW9uQWRkXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5pbXBvcnQge1xuICBMYWJlbFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9tb2RlbCc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzQW55XG59IGZyb20gJy4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuLyoqXG4gKiBBIGhhbmRsZXIgcmVzcG9uc2libGUgZm9yIHVwZGF0aW5nIHRoZSB1bmRlcmx5aW5nIEJQTU4gMi4wIFhNTCArIERJXG4gKiBvbmNlIGNoYW5nZXMgb24gdGhlIGRpYWdyYW0gaGFwcGVuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5VcGRhdGVyKFxuICAgIGV2ZW50QnVzLCBicG1uRmFjdG9yeSwgY29ubmVjdGlvbkRvY2tpbmcsXG4gICAgdHJhbnNsYXRlKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuX2JwbW5GYWN0b3J5ID0gYnBtbkZhY3Rvcnk7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cblxuXG4gIC8vIGNvbm5lY3Rpb24gY3JvcHBpbmcgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIC8vIGNyb3AgY29ubmVjdGlvbiBlbmRzIGR1cmluZyBjcmVhdGUvdXBkYXRlXG4gIGZ1bmN0aW9uIGNyb3BDb25uZWN0aW9uKGUpIHtcbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICBjb25uZWN0aW9uO1xuXG4gICAgaWYgKCFjb250ZXh0LmNyb3BwZWQgJiYgaGludHMuY3JlYXRlRWxlbWVudHNCZWhhdmlvciAhPT0gZmFsc2UpIHtcbiAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb247XG4gICAgICBjb25uZWN0aW9uLndheXBvaW50cyA9IGNvbm5lY3Rpb25Eb2NraW5nLmdldENyb3BwZWRXYXlwb2ludHMoY29ubmVjdGlvbik7XG4gICAgICBjb250ZXh0LmNyb3BwZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMuZXhlY3V0ZWQoW1xuICAgICdjb25uZWN0aW9uLmxheW91dCcsXG4gICAgJ2Nvbm5lY3Rpb24uY3JlYXRlJ1xuICBdLCBjcm9wQ29ubmVjdGlvbik7XG5cbiAgdGhpcy5yZXZlcnRlZChbICdjb25uZWN0aW9uLmxheW91dCcgXSwgZnVuY3Rpb24oZSkge1xuICAgIGRlbGV0ZSBlLmNvbnRleHQuY3JvcHBlZDtcbiAgfSk7XG5cblxuXG4gIC8vIEJQTU4gKyBESSB1cGRhdGUgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5cbiAgLy8gdXBkYXRlIHBhcmVudFxuICBmdW5jdGlvbiB1cGRhdGVQYXJlbnQoZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0O1xuXG4gICAgc2VsZi51cGRhdGVQYXJlbnQoY29udGV4dC5zaGFwZSB8fCBjb250ZXh0LmNvbm5lY3Rpb24sIGNvbnRleHQub2xkUGFyZW50KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJldmVyc2VVcGRhdGVQYXJlbnQoZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0O1xuXG4gICAgdmFyIGVsZW1lbnQgPSBjb250ZXh0LnNoYXBlIHx8IGNvbnRleHQuY29ubmVjdGlvbixcblxuICAgICAgICAvLyBvbGRQYXJlbnQgaXMgdGhlIChvbGQpIG5ldyBwYXJlbnQsIGJlY2F1c2Ugd2UgYXJlIHVuZG9pbmdcbiAgICAgICAgb2xkUGFyZW50ID0gY29udGV4dC5wYXJlbnQgfHwgY29udGV4dC5uZXdQYXJlbnQ7XG5cbiAgICBzZWxmLnVwZGF0ZVBhcmVudChlbGVtZW50LCBvbGRQYXJlbnQpO1xuICB9XG5cbiAgdGhpcy5leGVjdXRlZChbXG4gICAgJ3NoYXBlLm1vdmUnLFxuICAgICdzaGFwZS5jcmVhdGUnLFxuICAgICdzaGFwZS5kZWxldGUnLFxuICAgICdjb25uZWN0aW9uLmNyZWF0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubW92ZScsXG4gICAgJ2Nvbm5lY3Rpb24uZGVsZXRlJ1xuICBdLCBpZkJwbW4odXBkYXRlUGFyZW50KSk7XG5cbiAgdGhpcy5yZXZlcnRlZChbXG4gICAgJ3NoYXBlLm1vdmUnLFxuICAgICdzaGFwZS5jcmVhdGUnLFxuICAgICdzaGFwZS5kZWxldGUnLFxuICAgICdjb25uZWN0aW9uLmNyZWF0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubW92ZScsXG4gICAgJ2Nvbm5lY3Rpb24uZGVsZXRlJ1xuICBdLCBpZkJwbW4ocmV2ZXJzZVVwZGF0ZVBhcmVudCkpO1xuXG4gIC8qXG4gICAqICMjIFVwZGF0aW5nIFBhcmVudFxuICAgKlxuICAgKiBXaGVuIG1vcnBoaW5nIGEgUHJvY2VzcyBpbnRvIGEgQ29sbGFib3JhdGlvbiBvciB2aWNlLXZlcnNhLFxuICAgKiBtYWtlIHN1cmUgdGhhdCBib3RoIHRoZSAqc2VtYW50aWMqIGFuZCAqZGkqIHBhcmVudCBvZiBlYWNoIGVsZW1lbnRcbiAgICogaXMgdXBkYXRlZC5cbiAgICpcbiAgICovXG4gIGZ1bmN0aW9uIHVwZGF0ZVJvb3QoZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIG9sZFJvb3QgPSBjb250ZXh0Lm9sZFJvb3QsXG4gICAgICAgIGNoaWxkcmVuID0gb2xkUm9vdC5jaGlsZHJlbjtcblxuICAgIGZvckVhY2goY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICBpZiAoaXMoY2hpbGQsICdicG1uOkJhc2VFbGVtZW50JykpIHtcbiAgICAgICAgc2VsZi51cGRhdGVQYXJlbnQoY2hpbGQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdGhpcy5leGVjdXRlZChbICdjYW52YXMudXBkYXRlUm9vdCcgXSwgdXBkYXRlUm9vdCk7XG4gIHRoaXMucmV2ZXJ0ZWQoWyAnY2FudmFzLnVwZGF0ZVJvb3QnIF0sIHVwZGF0ZVJvb3QpO1xuXG5cbiAgLy8gdXBkYXRlIGJvdW5kc1xuICBmdW5jdGlvbiB1cGRhdGVCb3VuZHMoZSkge1xuICAgIHZhciBzaGFwZSA9IGUuY29udGV4dC5zaGFwZTtcblxuICAgIGlmICghaXMoc2hhcGUsICdicG1uOkJhc2VFbGVtZW50JykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmLnVwZGF0ZUJvdW5kcyhzaGFwZSk7XG4gIH1cblxuICB0aGlzLmV4ZWN1dGVkKFsgJ3NoYXBlLm1vdmUnLCAnc2hhcGUuY3JlYXRlJywgJ3NoYXBlLnJlc2l6ZScgXSwgaWZCcG1uKGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICAvLyBleGNsdWRlIGxhYmVscyBiZWNhdXNlIHRoZXkncmUgaGFuZGxlZCBzZXBhcmF0ZWx5IGR1cmluZyBzaGFwZS5jaGFuZ2VkXG4gICAgaWYgKGV2ZW50LmNvbnRleHQuc2hhcGUudHlwZSA9PT0gJ2xhYmVsJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHVwZGF0ZUJvdW5kcyhldmVudCk7XG4gIH0pKTtcblxuICB0aGlzLnJldmVydGVkKFsgJ3NoYXBlLm1vdmUnLCAnc2hhcGUuY3JlYXRlJywgJ3NoYXBlLnJlc2l6ZScgXSwgaWZCcG1uKGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICAvLyBleGNsdWRlIGxhYmVscyBiZWNhdXNlIHRoZXkncmUgaGFuZGxlZCBzZXBhcmF0ZWx5IGR1cmluZyBzaGFwZS5jaGFuZ2VkXG4gICAgaWYgKGV2ZW50LmNvbnRleHQuc2hhcGUudHlwZSA9PT0gJ2xhYmVsJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHVwZGF0ZUJvdW5kcyhldmVudCk7XG4gIH0pKTtcblxuICAvLyBIYW5kbGUgbGFiZWxzIHNlcGFyYXRlbHkuIFRoaXMgaXMgbmVjZXNzYXJ5LCBiZWNhdXNlIHRoZSBsYWJlbCBib3VuZHMgaGF2ZSB0byBiZSB1cGRhdGVkXG4gIC8vIGV2ZXJ5IHRpbWUgaXRzIHNoYXBlIGNoYW5nZXMsIG5vdCBvbmx5IG9uIG1vdmUsIGNyZWF0ZSBhbmQgcmVzaXplLlxuICBldmVudEJ1cy5vbignc2hhcGUuY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LmVsZW1lbnQudHlwZSA9PT0gJ2xhYmVsJykge1xuICAgICAgdXBkYXRlQm91bmRzKHsgY29udGV4dDogeyBzaGFwZTogZXZlbnQuZWxlbWVudCB9IH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYXR0YWNoIC8gZGV0YWNoIGNvbm5lY3Rpb25cbiAgZnVuY3Rpb24gdXBkYXRlQ29ubmVjdGlvbihlKSB7XG4gICAgc2VsZi51cGRhdGVDb25uZWN0aW9uKGUuY29udGV4dCk7XG4gIH1cblxuICB0aGlzLmV4ZWN1dGVkKFtcbiAgICAnY29ubmVjdGlvbi5jcmVhdGUnLFxuICAgICdjb25uZWN0aW9uLm1vdmUnLFxuICAgICdjb25uZWN0aW9uLmRlbGV0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ucmVjb25uZWN0J1xuICBdLCBpZkJwbW4odXBkYXRlQ29ubmVjdGlvbikpO1xuXG4gIHRoaXMucmV2ZXJ0ZWQoW1xuICAgICdjb25uZWN0aW9uLmNyZWF0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubW92ZScsXG4gICAgJ2Nvbm5lY3Rpb24uZGVsZXRlJyxcbiAgICAnY29ubmVjdGlvbi5yZWNvbm5lY3QnXG4gIF0sIGlmQnBtbih1cGRhdGVDb25uZWN0aW9uKSk7XG5cblxuICAvLyB1cGRhdGUgd2F5cG9pbnRzXG4gIGZ1bmN0aW9uIHVwZGF0ZUNvbm5lY3Rpb25XYXlwb2ludHMoZSkge1xuICAgIHNlbGYudXBkYXRlQ29ubmVjdGlvbldheXBvaW50cyhlLmNvbnRleHQuY29ubmVjdGlvbik7XG4gIH1cblxuICB0aGlzLmV4ZWN1dGVkKFtcbiAgICAnY29ubmVjdGlvbi5sYXlvdXQnLFxuICAgICdjb25uZWN0aW9uLm1vdmUnLFxuICAgICdjb25uZWN0aW9uLnVwZGF0ZVdheXBvaW50cycsXG4gIF0sIGlmQnBtbih1cGRhdGVDb25uZWN0aW9uV2F5cG9pbnRzKSk7XG5cbiAgdGhpcy5yZXZlcnRlZChbXG4gICAgJ2Nvbm5lY3Rpb24ubGF5b3V0JyxcbiAgICAnY29ubmVjdGlvbi5tb3ZlJyxcbiAgICAnY29ubmVjdGlvbi51cGRhdGVXYXlwb2ludHMnLFxuICBdLCBpZkJwbW4odXBkYXRlQ29ubmVjdGlvbldheXBvaW50cykpO1xuXG4gIC8vIHVwZGF0ZSBjb25kaXRpb25hbC9kZWZhdWx0IGZsb3dzXG4gIHRoaXMuZXhlY3V0ZWQoJ2Nvbm5lY3Rpb24ucmVjb25uZWN0JywgaWZCcG1uKGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBvbGRTb3VyY2UgPSBjb250ZXh0Lm9sZFNvdXJjZSxcbiAgICAgICAgbmV3U291cmNlID0gY29udGV4dC5uZXdTb3VyY2UsXG4gICAgICAgIGNvbm5lY3Rpb25CbyA9IGdldEJ1c2luZXNzT2JqZWN0KGNvbm5lY3Rpb24pLFxuICAgICAgICBvbGRTb3VyY2VCbyA9IGdldEJ1c2luZXNzT2JqZWN0KG9sZFNvdXJjZSksXG4gICAgICAgIG5ld1NvdXJjZUJvID0gZ2V0QnVzaW5lc3NPYmplY3QobmV3U291cmNlKTtcblxuICAgIC8vIHJlbW92ZSBjb25kaXRpb24gZnJvbSBjb25uZWN0aW9uIG9uIHJlY29ubmVjdCB0byBuZXcgc291cmNlXG4gICAgLy8gaWYgbmV3IHNvdXJjZSBjYW4gTk9UIGhhdmUgY29uZGlvbmFsIHNlcXVlbmNlIGZsb3dcbiAgICBpZiAoY29ubmVjdGlvbkJvLmNvbmRpdGlvbkV4cHJlc3Npb24gJiYgIWlzQW55KG5ld1NvdXJjZUJvLCBbXG4gICAgICAnYnBtbjpBY3Rpdml0eScsXG4gICAgICAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JyxcbiAgICAgICdicG1uOkluY2x1c2l2ZUdhdGV3YXknXG4gICAgXSkpIHtcbiAgICAgIGNvbnRleHQub2xkQ29uZGl0aW9uRXhwcmVzc2lvbiA9IGNvbm5lY3Rpb25Cby5jb25kaXRpb25FeHByZXNzaW9uO1xuXG4gICAgICBkZWxldGUgY29ubmVjdGlvbkJvLmNvbmRpdGlvbkV4cHJlc3Npb247XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGRlZmF1bHQgZnJvbSBvbGQgc291cmNlIGZsb3cgb24gcmVjb25uZWN0IHRvIG5ldyBzb3VyY2VcbiAgICAvLyBpZiBzb3VyY2UgY2hhbmdlZFxuICAgIGlmIChvbGRTb3VyY2UgIT09IG5ld1NvdXJjZSAmJiBvbGRTb3VyY2VCby5kZWZhdWx0ID09PSBjb25uZWN0aW9uQm8pIHtcbiAgICAgIGNvbnRleHQub2xkRGVmYXVsdCA9IG9sZFNvdXJjZUJvLmRlZmF1bHQ7XG5cbiAgICAgIGRlbGV0ZSBvbGRTb3VyY2VCby5kZWZhdWx0O1xuICAgIH1cbiAgfSkpO1xuXG4gIHRoaXMucmV2ZXJ0ZWQoJ2Nvbm5lY3Rpb24ucmVjb25uZWN0JywgaWZCcG1uKGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBvbGRTb3VyY2UgPSBjb250ZXh0Lm9sZFNvdXJjZSxcbiAgICAgICAgbmV3U291cmNlID0gY29udGV4dC5uZXdTb3VyY2UsXG4gICAgICAgIGNvbm5lY3Rpb25CbyA9IGdldEJ1c2luZXNzT2JqZWN0KGNvbm5lY3Rpb24pLFxuICAgICAgICBvbGRTb3VyY2VCbyA9IGdldEJ1c2luZXNzT2JqZWN0KG9sZFNvdXJjZSksXG4gICAgICAgIG5ld1NvdXJjZUJvID0gZ2V0QnVzaW5lc3NPYmplY3QobmV3U291cmNlKTtcblxuICAgIC8vIGFkZCBjb25kaXRpb24gdG8gY29ubmVjdGlvbiBvbiByZXZlcnQgcmVjb25uZWN0IHRvIG5ldyBzb3VyY2VcbiAgICBpZiAoY29udGV4dC5vbGRDb25kaXRpb25FeHByZXNzaW9uKSB7XG4gICAgICBjb25uZWN0aW9uQm8uY29uZGl0aW9uRXhwcmVzc2lvbiA9IGNvbnRleHQub2xkQ29uZGl0aW9uRXhwcmVzc2lvbjtcbiAgICB9XG5cbiAgICAvLyBhZGQgZGVmYXVsdCB0byBvbGQgc291cmNlIG9uIHJldmVydCByZWNvbm5lY3QgdG8gbmV3IHNvdXJjZVxuICAgIGlmIChjb250ZXh0Lm9sZERlZmF1bHQpIHtcbiAgICAgIG9sZFNvdXJjZUJvLmRlZmF1bHQgPSBjb250ZXh0Lm9sZERlZmF1bHQ7XG5cbiAgICAgIGRlbGV0ZSBuZXdTb3VyY2VCby5kZWZhdWx0O1xuICAgIH1cbiAgfSkpO1xuXG4gIC8vIHVwZGF0ZSBhdHRhY2htZW50c1xuICBmdW5jdGlvbiB1cGRhdGVBdHRhY2htZW50KGUpIHtcbiAgICBzZWxmLnVwZGF0ZUF0dGFjaG1lbnQoZS5jb250ZXh0KTtcbiAgfVxuXG4gIHRoaXMuZXhlY3V0ZWQoWyAnZWxlbWVudC51cGRhdGVBdHRhY2htZW50JyBdLCBpZkJwbW4odXBkYXRlQXR0YWNobWVudCkpO1xuICB0aGlzLnJldmVydGVkKFsgJ2VsZW1lbnQudXBkYXRlQXR0YWNobWVudCcgXSwgaWZCcG1uKHVwZGF0ZUF0dGFjaG1lbnQpKTtcbn1cblxuaW5oZXJpdHMoQnBtblVwZGF0ZXIsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cbkJwbW5VcGRhdGVyLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdicG1uRmFjdG9yeScsXG4gICdjb25uZWN0aW9uRG9ja2luZycsXG4gICd0cmFuc2xhdGUnXG5dO1xuXG5cbi8vIGltcGxlbWVudGF0aW9uIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZUF0dGFjaG1lbnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIGJ1c2luZXNzT2JqZWN0ID0gc2hhcGUuYnVzaW5lc3NPYmplY3QsXG4gICAgICBob3N0ID0gc2hhcGUuaG9zdDtcblxuICBidXNpbmVzc09iamVjdC5hdHRhY2hlZFRvUmVmID0gaG9zdCAmJiBob3N0LmJ1c2luZXNzT2JqZWN0O1xufTtcblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZVBhcmVudCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG9sZFBhcmVudCkge1xuXG4gIC8vIGRvIG5vdCB1cGRhdGUgQlBNTiAyLjAgbGFiZWwgcGFyZW50XG4gIGlmIChlbGVtZW50IGluc3RhbmNlb2YgTGFiZWwpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBkYXRhIHN0b3JlcyBpbiBjb2xsYWJvcmF0aW9ucyBhcmUgaGFuZGxlZCBzZXBhcmF0ZWx5IGJ5IERhdGFTdG9yZUJlaGF2aW9yXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSAmJlxuICAgICAgZWxlbWVudC5wYXJlbnQgJiZcbiAgICAgIGlzKGVsZW1lbnQucGFyZW50LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcGFyZW50U2hhcGUgPSBlbGVtZW50LnBhcmVudDtcblxuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LFxuICAgICAgcGFyZW50QnVzaW5lc3NPYmplY3QgPSBwYXJlbnRTaGFwZSAmJiBwYXJlbnRTaGFwZS5idXNpbmVzc09iamVjdCxcbiAgICAgIHBhcmVudERpID0gcGFyZW50QnVzaW5lc3NPYmplY3QgJiYgcGFyZW50QnVzaW5lc3NPYmplY3QuZGk7XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkZsb3dOb2RlJykpIHtcbiAgICB0aGlzLnVwZGF0ZUZsb3dOb2RlUmVmcyhidXNpbmVzc09iamVjdCwgcGFyZW50QnVzaW5lc3NPYmplY3QsIG9sZFBhcmVudCAmJiBvbGRQYXJlbnQuYnVzaW5lc3NPYmplY3QpO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkRhdGFPdXRwdXRBc3NvY2lhdGlvbicpKSB7XG4gICAgaWYgKGVsZW1lbnQuc291cmNlKSB7XG4gICAgICBwYXJlbnRCdXNpbmVzc09iamVjdCA9IGVsZW1lbnQuc291cmNlLmJ1c2luZXNzT2JqZWN0O1xuICAgIH0gZWxzZSB7XG4gICAgICBwYXJlbnRCdXNpbmVzc09iamVjdCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJykpIHtcbiAgICBpZiAoZWxlbWVudC50YXJnZXQpIHtcbiAgICAgIHBhcmVudEJ1c2luZXNzT2JqZWN0ID0gZWxlbWVudC50YXJnZXQuYnVzaW5lc3NPYmplY3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHBhcmVudEJ1c2luZXNzT2JqZWN0ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICB0aGlzLnVwZGF0ZVNlbWFudGljUGFyZW50KGJ1c2luZXNzT2JqZWN0LCBwYXJlbnRCdXNpbmVzc09iamVjdCk7XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnKSAmJiBidXNpbmVzc09iamVjdC5kYXRhT2JqZWN0UmVmKSB7XG4gICAgdGhpcy51cGRhdGVTZW1hbnRpY1BhcmVudChidXNpbmVzc09iamVjdC5kYXRhT2JqZWN0UmVmLCBwYXJlbnRCdXNpbmVzc09iamVjdCk7XG4gIH1cblxuICB0aGlzLnVwZGF0ZURpUGFyZW50KGJ1c2luZXNzT2JqZWN0LmRpLCBwYXJlbnREaSk7XG59O1xuXG5cbkJwbW5VcGRhdGVyLnByb3RvdHlwZS51cGRhdGVCb3VuZHMgPSBmdW5jdGlvbihzaGFwZSkge1xuXG4gIHZhciBkaSA9IHNoYXBlLmJ1c2luZXNzT2JqZWN0LmRpO1xuXG4gIHZhciB0YXJnZXQgPSAoc2hhcGUgaW5zdGFuY2VvZiBMYWJlbCkgPyB0aGlzLl9nZXRMYWJlbChkaSkgOiBkaTtcblxuICB2YXIgYm91bmRzID0gdGFyZ2V0LmJvdW5kcztcblxuICBpZiAoIWJvdW5kcykge1xuICAgIGJvdW5kcyA9IHRoaXMuX2JwbW5GYWN0b3J5LmNyZWF0ZURpQm91bmRzKCk7XG4gICAgdGFyZ2V0LnNldCgnYm91bmRzJywgYm91bmRzKTtcbiAgfVxuXG4gIGFzc2lnbihib3VuZHMsIHtcbiAgICB4OiBzaGFwZS54LFxuICAgIHk6IHNoYXBlLnksXG4gICAgd2lkdGg6IHNoYXBlLndpZHRoLFxuICAgIGhlaWdodDogc2hhcGUuaGVpZ2h0XG4gIH0pO1xufTtcblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZUZsb3dOb2RlUmVmcyA9IGZ1bmN0aW9uKGJ1c2luZXNzT2JqZWN0LCBuZXdDb250YWlubWVudCwgb2xkQ29udGFpbm1lbnQpIHtcblxuICBpZiAob2xkQ29udGFpbm1lbnQgPT09IG5ld0NvbnRhaW5tZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG9sZFJlZnMsIG5ld1JlZnM7XG5cbiAgaWYgKGlzIChvbGRDb250YWlubWVudCwgJ2JwbW46TGFuZScpKSB7XG4gICAgb2xkUmVmcyA9IG9sZENvbnRhaW5tZW50LmdldCgnZmxvd05vZGVSZWYnKTtcbiAgICBjb2xsZWN0aW9uUmVtb3ZlKG9sZFJlZnMsIGJ1c2luZXNzT2JqZWN0KTtcbiAgfVxuXG4gIGlmIChpcyhuZXdDb250YWlubWVudCwgJ2JwbW46TGFuZScpKSB7XG4gICAgbmV3UmVmcyA9IG5ld0NvbnRhaW5tZW50LmdldCgnZmxvd05vZGVSZWYnKTtcbiAgICBjb2xsZWN0aW9uQWRkKG5ld1JlZnMsIGJ1c2luZXNzT2JqZWN0KTtcbiAgfVxufTtcblxuXG4vLyB1cGRhdGUgZXhpc3Rpbmcgc291cmNlRWxlbWVudCBhbmQgdGFyZ2V0RWxlbWVudCBkaSBpbmZvcm1hdGlvblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZURpQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKGRpLCBuZXdTb3VyY2UsIG5ld1RhcmdldCkge1xuXG4gIGlmIChkaS5zb3VyY2VFbGVtZW50ICYmIGRpLnNvdXJjZUVsZW1lbnQuYnBtbkVsZW1lbnQgIT09IG5ld1NvdXJjZSkge1xuICAgIGRpLnNvdXJjZUVsZW1lbnQgPSBuZXdTb3VyY2UgJiYgbmV3U291cmNlLmRpO1xuICB9XG5cbiAgaWYgKGRpLnRhcmdldEVsZW1lbnQgJiYgZGkudGFyZ2V0RWxlbWVudC5icG1uRWxlbWVudCAhPT0gbmV3VGFyZ2V0KSB7XG4gICAgZGkudGFyZ2V0RWxlbWVudCA9IG5ld1RhcmdldCAmJiBuZXdUYXJnZXQuZGk7XG4gIH1cblxufTtcblxuXG5CcG1uVXBkYXRlci5wcm90b3R5cGUudXBkYXRlRGlQYXJlbnQgPSBmdW5jdGlvbihkaSwgcGFyZW50RGkpIHtcblxuICBpZiAocGFyZW50RGkgJiYgIWlzKHBhcmVudERpLCAnYnBtbmRpOkJQTU5QbGFuZScpKSB7XG4gICAgcGFyZW50RGkgPSBwYXJlbnREaS4kcGFyZW50O1xuICB9XG5cbiAgaWYgKGRpLiRwYXJlbnQgPT09IHBhcmVudERpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHBsYW5lRWxlbWVudHMgPSAocGFyZW50RGkgfHwgZGkuJHBhcmVudCkuZ2V0KCdwbGFuZUVsZW1lbnQnKTtcblxuICBpZiAocGFyZW50RGkpIHtcbiAgICBwbGFuZUVsZW1lbnRzLnB1c2goZGkpO1xuICAgIGRpLiRwYXJlbnQgPSBwYXJlbnREaTtcbiAgfSBlbHNlIHtcbiAgICBjb2xsZWN0aW9uUmVtb3ZlKHBsYW5lRWxlbWVudHMsIGRpKTtcbiAgICBkaS4kcGFyZW50ID0gbnVsbDtcbiAgfVxufTtcblxuZnVuY3Rpb24gZ2V0RGVmaW5pdGlvbnMoZWxlbWVudCkge1xuICB3aGlsZSAoZWxlbWVudCAmJiAhaXMoZWxlbWVudCwgJ2JwbW46RGVmaW5pdGlvbnMnKSkge1xuICAgIGVsZW1lbnQgPSBlbGVtZW50LiRwYXJlbnQ7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudDtcbn1cblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLmdldExhbmVTZXQgPSBmdW5jdGlvbihjb250YWluZXIpIHtcblxuICB2YXIgbGFuZVNldCwgbGFuZVNldHM7XG5cbiAgLy8gYnBtbjpMYW5lXG4gIGlmIChpcyhjb250YWluZXIsICdicG1uOkxhbmUnKSkge1xuICAgIGxhbmVTZXQgPSBjb250YWluZXIuY2hpbGRMYW5lU2V0O1xuXG4gICAgaWYgKCFsYW5lU2V0KSB7XG4gICAgICBsYW5lU2V0ID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkxhbmVTZXQnKTtcbiAgICAgIGNvbnRhaW5lci5jaGlsZExhbmVTZXQgPSBsYW5lU2V0O1xuICAgICAgbGFuZVNldC4kcGFyZW50ID0gY29udGFpbmVyO1xuICAgIH1cblxuICAgIHJldHVybiBsYW5lU2V0O1xuICB9XG5cbiAgLy8gYnBtbjpQYXJ0aWNpcGFudFxuICBpZiAoaXMoY29udGFpbmVyLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgY29udGFpbmVyID0gY29udGFpbmVyLnByb2Nlc3NSZWY7XG4gIH1cblxuICAvLyBicG1uOkZsb3dFbGVtZW50c0NvbnRhaW5lclxuICBsYW5lU2V0cyA9IGNvbnRhaW5lci5nZXQoJ2xhbmVTZXRzJyk7XG4gIGxhbmVTZXQgPSBsYW5lU2V0c1swXTtcblxuICBpZiAoIWxhbmVTZXQpIHtcbiAgICBsYW5lU2V0ID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkxhbmVTZXQnKTtcbiAgICBsYW5lU2V0LiRwYXJlbnQgPSBjb250YWluZXI7XG4gICAgbGFuZVNldHMucHVzaChsYW5lU2V0KTtcbiAgfVxuXG4gIHJldHVybiBsYW5lU2V0O1xufTtcblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZVNlbWFudGljUGFyZW50ID0gZnVuY3Rpb24oYnVzaW5lc3NPYmplY3QsIG5ld1BhcmVudCwgdmlzdWFsUGFyZW50KSB7XG5cbiAgdmFyIGNvbnRhaW5tZW50LFxuICAgICAgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuXG4gIGlmIChidXNpbmVzc09iamVjdC4kcGFyZW50ID09PSBuZXdQYXJlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkRhdGFJbnB1dCcpIHx8IGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpEYXRhT3V0cHV0JykpIHtcblxuICAgIGlmIChpcyhuZXdQYXJlbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgJ3Byb2Nlc3NSZWYnIGluIG5ld1BhcmVudCkge1xuICAgICAgbmV3UGFyZW50ID0gbmV3UGFyZW50LnByb2Nlc3NSZWY7XG4gICAgfVxuXG4gICAgLy8gYWxyZWFkeSBpbiBjb3JyZWN0IGlvU3BlY2lmaWNhdGlvblxuICAgIGlmICgnaW9TcGVjaWZpY2F0aW9uJyBpbiBuZXdQYXJlbnQgJiYgbmV3UGFyZW50LmlvU3BlY2lmaWNhdGlvbiA9PT0gYnVzaW5lc3NPYmplY3QuJHBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46TGFuZScpKSB7XG5cbiAgICBpZiAobmV3UGFyZW50KSB7XG4gICAgICBuZXdQYXJlbnQgPSB0aGlzLmdldExhbmVTZXQobmV3UGFyZW50KTtcbiAgICB9XG5cbiAgICBjb250YWlubWVudCA9ICdsYW5lcyc7XG4gIH0gZWxzZVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46Rmxvd0VsZW1lbnQnKSkge1xuXG4gICAgaWYgKG5ld1BhcmVudCkge1xuXG4gICAgICBpZiAoaXMobmV3UGFyZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgICAgIG5ld1BhcmVudCA9IG5ld1BhcmVudC5wcm9jZXNzUmVmO1xuICAgICAgfSBlbHNlXG5cbiAgICAgIGlmIChpcyhuZXdQYXJlbnQsICdicG1uOkxhbmUnKSkge1xuICAgICAgICBkbyB7XG5cbiAgICAgICAgICAvLyB1bndyYXAgTGFuZSAtPiBMYW5lU2V0IC0+IChMYW5lIHwgRmxvd0VsZW1lbnRzQ29udGFpbmVyKVxuICAgICAgICAgIG5ld1BhcmVudCA9IG5ld1BhcmVudC4kcGFyZW50LiRwYXJlbnQ7XG4gICAgICAgIH0gd2hpbGUgKGlzKG5ld1BhcmVudCwgJ2JwbW46TGFuZScpKTtcblxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnRhaW5tZW50ID0gJ2Zsb3dFbGVtZW50cyc7XG5cbiAgfSBlbHNlXG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpBcnRpZmFjdCcpKSB7XG5cbiAgICB3aGlsZSAobmV3UGFyZW50ICYmXG4gICAgICAgICAgICFpcyhuZXdQYXJlbnQsICdicG1uOlByb2Nlc3MnKSAmJlxuICAgICAgICAgICAhaXMobmV3UGFyZW50LCAnYnBtbjpTdWJQcm9jZXNzJykgJiZcbiAgICAgICAgICAgIWlzKG5ld1BhcmVudCwgJ2JwbW46Q29sbGFib3JhdGlvbicpKSB7XG5cbiAgICAgIGlmIChpcyhuZXdQYXJlbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICAgICAgbmV3UGFyZW50ID0gbmV3UGFyZW50LnByb2Nlc3NSZWY7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3UGFyZW50ID0gbmV3UGFyZW50LiRwYXJlbnQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29udGFpbm1lbnQgPSAnYXJ0aWZhY3RzJztcbiAgfSBlbHNlXG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpNZXNzYWdlRmxvdycpKSB7XG4gICAgY29udGFpbm1lbnQgPSAnbWVzc2FnZUZsb3dzJztcblxuICB9IGVsc2VcblxuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICBjb250YWlubWVudCA9ICdwYXJ0aWNpcGFudHMnO1xuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBwYXJ0aWNpcGFudHMgcHJvY2VzcyBpcyBwcm9wZXJseSBhdHRhY2hlZCAvIGRldGFjaGVkXG4gICAgLy8gZnJvbSB0aGUgWE1MIGRvY3VtZW50XG5cbiAgICB2YXIgcHJvY2VzcyA9IGJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWYsXG4gICAgICAgIGRlZmluaXRpb25zO1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcbiAgICAgIGRlZmluaXRpb25zID0gZ2V0RGVmaW5pdGlvbnMoYnVzaW5lc3NPYmplY3QuJHBhcmVudCB8fCBuZXdQYXJlbnQpO1xuXG4gICAgICBpZiAoYnVzaW5lc3NPYmplY3QuJHBhcmVudCkge1xuICAgICAgICBjb2xsZWN0aW9uUmVtb3ZlKGRlZmluaXRpb25zLmdldCgncm9vdEVsZW1lbnRzJyksIHByb2Nlc3MpO1xuICAgICAgICBwcm9jZXNzLiRwYXJlbnQgPSBudWxsO1xuICAgICAgfVxuXG4gICAgICBpZiAobmV3UGFyZW50KSB7XG4gICAgICAgIGNvbGxlY3Rpb25BZGQoZGVmaW5pdGlvbnMuZ2V0KCdyb290RWxlbWVudHMnKSwgcHJvY2Vzcyk7XG4gICAgICAgIHByb2Nlc3MuJHBhcmVudCA9IGRlZmluaXRpb25zO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlXG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpEYXRhT3V0cHV0QXNzb2NpYXRpb24nKSkge1xuICAgIGNvbnRhaW5tZW50ID0gJ2RhdGFPdXRwdXRBc3NvY2lhdGlvbnMnO1xuICB9IGVsc2VcblxuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJykpIHtcbiAgICBjb250YWlubWVudCA9ICdkYXRhSW5wdXRBc3NvY2lhdGlvbnMnO1xuICB9XG5cbiAgaWYgKCFjb250YWlubWVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcih0cmFuc2xhdGUoXG4gICAgICAnbm8gcGFyZW50IGZvciB7ZWxlbWVudH0gaW4ge3BhcmVudH0nLFxuICAgICAge1xuICAgICAgICBlbGVtZW50OiBidXNpbmVzc09iamVjdC5pZCxcbiAgICAgICAgcGFyZW50OiBuZXdQYXJlbnQuaWRcbiAgICAgIH1cbiAgICApKTtcbiAgfVxuXG4gIHZhciBjaGlsZHJlbjtcblxuICBpZiAoYnVzaW5lc3NPYmplY3QuJHBhcmVudCkge1xuXG4gICAgLy8gcmVtb3ZlIGZyb20gb2xkIHBhcmVudFxuICAgIGNoaWxkcmVuID0gYnVzaW5lc3NPYmplY3QuJHBhcmVudC5nZXQoY29udGFpbm1lbnQpO1xuICAgIGNvbGxlY3Rpb25SZW1vdmUoY2hpbGRyZW4sIGJ1c2luZXNzT2JqZWN0KTtcbiAgfVxuXG4gIGlmICghbmV3UGFyZW50KSB7XG4gICAgYnVzaW5lc3NPYmplY3QuJHBhcmVudCA9IG51bGw7XG4gIH0gZWxzZSB7XG5cbiAgICAvLyBhZGQgdG8gbmV3IHBhcmVudFxuICAgIGNoaWxkcmVuID0gbmV3UGFyZW50LmdldChjb250YWlubWVudCk7XG4gICAgY2hpbGRyZW4ucHVzaChidXNpbmVzc09iamVjdCk7XG4gICAgYnVzaW5lc3NPYmplY3QuJHBhcmVudCA9IG5ld1BhcmVudDtcbiAgfVxuXG4gIGlmICh2aXN1YWxQYXJlbnQpIHtcbiAgICB2YXIgZGlDaGlsZHJlbiA9IHZpc3VhbFBhcmVudC5nZXQoY29udGFpbm1lbnQpO1xuXG4gICAgY29sbGVjdGlvblJlbW92ZShjaGlsZHJlbiwgYnVzaW5lc3NPYmplY3QpO1xuXG4gICAgaWYgKG5ld1BhcmVudCkge1xuXG4gICAgICBpZiAoIWRpQ2hpbGRyZW4pIHtcbiAgICAgICAgZGlDaGlsZHJlbiA9IFtdO1xuICAgICAgICBuZXdQYXJlbnQuc2V0KGNvbnRhaW5tZW50LCBkaUNoaWxkcmVuKTtcbiAgICAgIH1cblxuICAgICAgZGlDaGlsZHJlbi5wdXNoKGJ1c2luZXNzT2JqZWN0KTtcbiAgICB9XG4gIH1cbn07XG5cblxuQnBtblVwZGF0ZXIucHJvdG90eXBlLnVwZGF0ZUNvbm5lY3Rpb25XYXlwb2ludHMgPSBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gIGNvbm5lY3Rpb24uYnVzaW5lc3NPYmplY3QuZGkuc2V0KCd3YXlwb2ludCcsIHRoaXMuX2JwbW5GYWN0b3J5LmNyZWF0ZURpV2F5cG9pbnRzKGNvbm5lY3Rpb24ud2F5cG9pbnRzKSk7XG59O1xuXG5cbkJwbW5VcGRhdGVyLnByb3RvdHlwZS51cGRhdGVDb25uZWN0aW9uID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChjb25uZWN0aW9uKSxcbiAgICAgIG5ld1NvdXJjZSA9IGdldEJ1c2luZXNzT2JqZWN0KGNvbm5lY3Rpb24uc291cmNlKSxcbiAgICAgIG5ld1RhcmdldCA9IGdldEJ1c2luZXNzT2JqZWN0KGNvbm5lY3Rpb24udGFyZ2V0KSxcbiAgICAgIHZpc3VhbFBhcmVudDtcblxuICBpZiAoIWlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpEYXRhQXNzb2NpYXRpb24nKSkge1xuXG4gICAgdmFyIGludmVyc2VTZXQgPSBpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46U2VxdWVuY2VGbG93Jyk7XG5cbiAgICBpZiAoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmICE9PSBuZXdTb3VyY2UpIHtcbiAgICAgIGlmIChpbnZlcnNlU2V0KSB7XG4gICAgICAgIGNvbGxlY3Rpb25SZW1vdmUoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmICYmIGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZi5nZXQoJ291dGdvaW5nJyksIGJ1c2luZXNzT2JqZWN0KTtcblxuICAgICAgICBpZiAobmV3U291cmNlICYmIG5ld1NvdXJjZS5nZXQoJ291dGdvaW5nJykpIHtcbiAgICAgICAgICBuZXdTb3VyY2UuZ2V0KCdvdXRnb2luZycpLnB1c2goYnVzaW5lc3NPYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiA9IG5ld1NvdXJjZTtcbiAgICB9XG5cbiAgICBpZiAoYnVzaW5lc3NPYmplY3QudGFyZ2V0UmVmICE9PSBuZXdUYXJnZXQpIHtcbiAgICAgIGlmIChpbnZlcnNlU2V0KSB7XG4gICAgICAgIGNvbGxlY3Rpb25SZW1vdmUoYnVzaW5lc3NPYmplY3QudGFyZ2V0UmVmICYmIGJ1c2luZXNzT2JqZWN0LnRhcmdldFJlZi5nZXQoJ2luY29taW5nJyksIGJ1c2luZXNzT2JqZWN0KTtcblxuICAgICAgICBpZiAobmV3VGFyZ2V0ICYmIG5ld1RhcmdldC5nZXQoJ2luY29taW5nJykpIHtcbiAgICAgICAgICBuZXdUYXJnZXQuZ2V0KCdpbmNvbWluZycpLnB1c2goYnVzaW5lc3NPYmplY3QpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGJ1c2luZXNzT2JqZWN0LnRhcmdldFJlZiA9IG5ld1RhcmdldDtcbiAgICB9XG4gIH0gZWxzZVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46RGF0YUlucHV0QXNzb2NpYXRpb24nKSkge1xuXG4gICAgLy8gaGFuZGxlIG9ibm94aW91cyBpc01zb21lIHNvdXJjZVJlZlxuICAgIGJ1c2luZXNzT2JqZWN0LmdldCgnc291cmNlUmVmJylbMF0gPSBuZXdTb3VyY2U7XG5cbiAgICB2aXN1YWxQYXJlbnQgPSBjb250ZXh0LnBhcmVudCB8fCBjb250ZXh0Lm5ld1BhcmVudCB8fCBuZXdUYXJnZXQ7XG5cbiAgICB0aGlzLnVwZGF0ZVNlbWFudGljUGFyZW50KGJ1c2luZXNzT2JqZWN0LCBuZXdUYXJnZXQsIHZpc3VhbFBhcmVudCk7XG4gIH0gZWxzZVxuXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46RGF0YU91dHB1dEFzc29jaWF0aW9uJykpIHtcbiAgICB2aXN1YWxQYXJlbnQgPSBjb250ZXh0LnBhcmVudCB8fCBjb250ZXh0Lm5ld1BhcmVudCB8fCBuZXdTb3VyY2U7XG5cbiAgICB0aGlzLnVwZGF0ZVNlbWFudGljUGFyZW50KGJ1c2luZXNzT2JqZWN0LCBuZXdTb3VyY2UsIHZpc3VhbFBhcmVudCk7XG5cbiAgICAvLyB0YXJnZXRSZWYgPSBuZXcgdGFyZ2V0XG4gICAgYnVzaW5lc3NPYmplY3QudGFyZ2V0UmVmID0gbmV3VGFyZ2V0O1xuICB9XG5cbiAgdGhpcy51cGRhdGVDb25uZWN0aW9uV2F5cG9pbnRzKGNvbm5lY3Rpb24pO1xuXG4gIHRoaXMudXBkYXRlRGlDb25uZWN0aW9uKGJ1c2luZXNzT2JqZWN0LmRpLCBuZXdTb3VyY2UsIG5ld1RhcmdldCk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5CcG1uVXBkYXRlci5wcm90b3R5cGUuX2dldExhYmVsID0gZnVuY3Rpb24oZGkpIHtcbiAgaWYgKCFkaS5sYWJlbCkge1xuICAgIGRpLmxhYmVsID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlRGlMYWJlbCgpO1xuICB9XG5cbiAgcmV0dXJuIGRpLmxhYmVsO1xufTtcblxuXG4vKipcbiAqIE1ha2Ugc3VyZSB0aGUgZXZlbnQgbGlzdGVuZXIgaXMgb25seSBjYWxsZWRcbiAqIGlmIHRoZSB0b3VjaGVkIGVsZW1lbnQgaXMgYSBCUE1OIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gZ3VhcmRlZCBmdW5jdGlvblxuICovXG5mdW5jdGlvbiBpZkJwbW4oZm4pIHtcblxuICByZXR1cm4gZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuc2hhcGUgfHwgY29udGV4dC5jb25uZWN0aW9uO1xuXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkJhc2VFbGVtZW50JykpIHtcbiAgICAgIGZuKGV2ZW50KTtcbiAgICB9XG4gIH07XG59XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIGlzT2JqZWN0XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzRXhwYW5kZWRcbn0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQgQmFzZUVsZW1lbnRGYWN0b3J5IGZyb20gJ2RpYWdyYW0tanMvbGliL2NvcmUvRWxlbWVudEZhY3RvcnknO1xuXG5pbXBvcnQge1xuICBERUZBVUxUX0xBQkVMX1NJWkVcbn0gZnJvbSAnLi4vLi4vdXRpbC9MYWJlbFV0aWwnO1xuXG5cbi8qKlxuICogQSBicG1uLWF3YXJlIGZhY3RvcnkgZm9yIGRpYWdyYW0tanMgc2hhcGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEVsZW1lbnRGYWN0b3J5KGJwbW5GYWN0b3J5LCBtb2RkbGUsIHRyYW5zbGF0ZSkge1xuICBCYXNlRWxlbWVudEZhY3RvcnkuY2FsbCh0aGlzKTtcblxuICB0aGlzLl9icG1uRmFjdG9yeSA9IGJwbW5GYWN0b3J5O1xuICB0aGlzLl9tb2RkbGUgPSBtb2RkbGU7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcbn1cblxuaW5oZXJpdHMoRWxlbWVudEZhY3RvcnksIEJhc2VFbGVtZW50RmFjdG9yeSk7XG5cbkVsZW1lbnRGYWN0b3J5LiRpbmplY3QgPSBbXG4gICdicG1uRmFjdG9yeScsXG4gICdtb2RkbGUnLFxuICAndHJhbnNsYXRlJ1xuXTtcblxuRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmJhc2VDcmVhdGUgPSBCYXNlRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZTtcblxuRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uKGVsZW1lbnRUeXBlLCBhdHRycykge1xuXG4gIC8vIG5vIHNwZWNpYWwgbWFnaWMgZm9yIGxhYmVscyxcbiAgLy8gd2UgYXNzdW1lIHRoZWlyIGJ1c2luZXNzT2JqZWN0cyBoYXZlIGFscmVhZHkgYmVlbiBjcmVhdGVkXG4gIC8vIGFuZCB3aXJlZCB2aWEgYXR0cnNcbiAgaWYgKGVsZW1lbnRUeXBlID09PSAnbGFiZWwnKSB7XG4gICAgcmV0dXJuIHRoaXMuYmFzZUNyZWF0ZShlbGVtZW50VHlwZSwgYXNzaWduKHsgdHlwZTogJ2xhYmVsJyB9LCBERUZBVUxUX0xBQkVMX1NJWkUsIGF0dHJzKSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5jcmVhdGVCcG1uRWxlbWVudChlbGVtZW50VHlwZSwgYXR0cnMpO1xufTtcblxuRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZUJwbW5FbGVtZW50ID0gZnVuY3Rpb24oZWxlbWVudFR5cGUsIGF0dHJzKSB7XG4gIHZhciBzaXplLFxuICAgICAgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuXG4gIGF0dHJzID0gYXR0cnMgfHwge307XG5cbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gYXR0cnMuYnVzaW5lc3NPYmplY3Q7XG5cbiAgaWYgKCFidXNpbmVzc09iamVjdCkge1xuICAgIGlmICghYXR0cnMudHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnbm8gc2hhcGUgdHlwZSBzcGVjaWZpZWQnKSk7XG4gICAgfVxuXG4gICAgYnVzaW5lc3NPYmplY3QgPSB0aGlzLl9icG1uRmFjdG9yeS5jcmVhdGUoYXR0cnMudHlwZSk7XG4gIH1cblxuICBpZiAoIWJ1c2luZXNzT2JqZWN0LmRpKSB7XG4gICAgaWYgKGVsZW1lbnRUeXBlID09PSAncm9vdCcpIHtcbiAgICAgIGJ1c2luZXNzT2JqZWN0LmRpID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlRGlQbGFuZShidXNpbmVzc09iamVjdCwgW10sIHtcbiAgICAgICAgaWQ6IGJ1c2luZXNzT2JqZWN0LmlkICsgJ19kaSdcbiAgICAgIH0pO1xuICAgIH0gZWxzZVxuICAgIGlmIChlbGVtZW50VHlwZSA9PT0gJ2Nvbm5lY3Rpb24nKSB7XG4gICAgICBidXNpbmVzc09iamVjdC5kaSA9IHRoaXMuX2JwbW5GYWN0b3J5LmNyZWF0ZURpRWRnZShidXNpbmVzc09iamVjdCwgW10sIHtcbiAgICAgICAgaWQ6IGJ1c2luZXNzT2JqZWN0LmlkICsgJ19kaSdcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBidXNpbmVzc09iamVjdC5kaSA9IHRoaXMuX2JwbW5GYWN0b3J5LmNyZWF0ZURpU2hhcGUoYnVzaW5lc3NPYmplY3QsIHt9LCB7XG4gICAgICAgIGlkOiBidXNpbmVzc09iamVjdC5pZCArICdfZGknXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkdyb3VwJykpIHtcbiAgICBhdHRycyA9IGFzc2lnbih7XG4gICAgICBpc0ZyYW1lOiB0cnVlXG4gICAgfSwgYXR0cnMpO1xuICB9XG5cbiAgaWYgKGF0dHJzLmRpKSB7XG4gICAgYXNzaWduKGJ1c2luZXNzT2JqZWN0LmRpLCBhdHRycy5kaSk7XG5cbiAgICBkZWxldGUgYXR0cnMuZGk7XG4gIH1cblxuICBhcHBseUF0dHJpYnV0ZXMoYnVzaW5lc3NPYmplY3QsIGF0dHJzLCBbXG4gICAgJ3Byb2Nlc3NSZWYnLFxuICAgICdpc0ludGVycnVwdGluZycsXG4gICAgJ2Fzc29jaWF0aW9uRGlyZWN0aW9uJyxcbiAgICAnaXNGb3JDb21wZW5zYXRpb24nXG4gIF0pO1xuXG4gIGlmIChhdHRycy5pc0V4cGFuZGVkKSB7XG4gICAgYXBwbHlBdHRyaWJ1dGUoYnVzaW5lc3NPYmplY3QuZGksIGF0dHJzLCAnaXNFeHBhbmRlZCcpO1xuICB9XG5cbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JykpIHtcbiAgICBidXNpbmVzc09iamVjdC5kaS5pc01hcmtlclZpc2libGUgPSB0cnVlO1xuICB9XG5cbiAgdmFyIGV2ZW50RGVmaW5pdGlvbnMsXG4gICAgICBuZXdFdmVudERlZmluaXRpb247XG5cbiAgaWYgKGF0dHJzLmV2ZW50RGVmaW5pdGlvblR5cGUpIHtcbiAgICBldmVudERlZmluaXRpb25zID0gYnVzaW5lc3NPYmplY3QuZ2V0KCdldmVudERlZmluaXRpb25zJykgfHwgW107XG4gICAgbmV3RXZlbnREZWZpbml0aW9uID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlKGF0dHJzLmV2ZW50RGVmaW5pdGlvblR5cGUsIGF0dHJzLmV2ZW50RGVmaW5pdGlvbkF0dHJzKTtcblxuICAgIGlmIChhdHRycy5ldmVudERlZmluaXRpb25UeXBlID09PSAnYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbicpIHtcbiAgICAgIG5ld0V2ZW50RGVmaW5pdGlvbi5jb25kaXRpb24gPSB0aGlzLl9icG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46Rm9ybWFsRXhwcmVzc2lvbicpO1xuICAgIH1cblxuICAgIGV2ZW50RGVmaW5pdGlvbnMucHVzaChuZXdFdmVudERlZmluaXRpb24pO1xuXG4gICAgbmV3RXZlbnREZWZpbml0aW9uLiRwYXJlbnQgPSBidXNpbmVzc09iamVjdDtcbiAgICBidXNpbmVzc09iamVjdC5ldmVudERlZmluaXRpb25zID0gZXZlbnREZWZpbml0aW9ucztcblxuICAgIGRlbGV0ZSBhdHRycy5ldmVudERlZmluaXRpb25UeXBlO1xuICB9XG5cbiAgc2l6ZSA9IHRoaXMuX2dldERlZmF1bHRTaXplKGJ1c2luZXNzT2JqZWN0KTtcblxuICBhdHRycyA9IGFzc2lnbih7XG4gICAgYnVzaW5lc3NPYmplY3Q6IGJ1c2luZXNzT2JqZWN0LFxuICAgIGlkOiBidXNpbmVzc09iamVjdC5pZFxuICB9LCBzaXplLCBhdHRycyk7XG5cbiAgcmV0dXJuIHRoaXMuYmFzZUNyZWF0ZShlbGVtZW50VHlwZSwgYXR0cnMpO1xufTtcblxuXG5FbGVtZW50RmFjdG9yeS5wcm90b3R5cGUuX2dldERlZmF1bHRTaXplID0gZnVuY3Rpb24oc2VtYW50aWMpIHtcblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuXG4gICAgaWYgKGlzRXhwYW5kZWQoc2VtYW50aWMpKSB7XG4gICAgICByZXR1cm4geyB3aWR0aDogMzUwLCBoZWlnaHQ6IDIwMCB9O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4geyB3aWR0aDogMTAwLCBoZWlnaHQ6IDgwIH07XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpUYXNrJykpIHtcbiAgICByZXR1cm4geyB3aWR0aDogMTAwLCBoZWlnaHQ6IDgwIH07XG4gIH1cblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkdhdGV3YXknKSkge1xuICAgIHJldHVybiB7IHdpZHRoOiA1MCwgaGVpZ2h0OiA1MCB9O1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpFdmVudCcpKSB7XG4gICAgcmV0dXJuIHsgd2lkdGg6IDM2LCBoZWlnaHQ6IDM2IH07XG4gIH1cblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICBpZiAoaXNFeHBhbmRlZChzZW1hbnRpYykpIHtcbiAgICAgIHJldHVybiB7IHdpZHRoOiA2MDAsIGhlaWdodDogMjUwIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB7IHdpZHRoOiA0MDAsIGhlaWdodDogNjAgfTtcbiAgICB9XG4gIH1cblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkxhbmUnKSkge1xuICAgIHJldHVybiB7IHdpZHRoOiA0MDAsIGhlaWdodDogMTAwIH07XG4gIH1cblxuICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnKSkge1xuICAgIHJldHVybiB7IHdpZHRoOiAzNiwgaGVpZ2h0OiA1MCB9O1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSkge1xuICAgIHJldHVybiB7IHdpZHRoOiA1MCwgaGVpZ2h0OiA1MCB9O1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XG4gICAgcmV0dXJuIHsgd2lkdGg6IDEwMCwgaGVpZ2h0OiAzMCB9O1xuICB9XG5cbiAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpHcm91cCcpKSB7XG4gICAgcmV0dXJuIHsgd2lkdGg6IDMwMCwgaGVpZ2h0OiAzMDAgfTtcbiAgfVxuXG4gIHJldHVybiB7IHdpZHRoOiAxMDAsIGhlaWdodDogODAgfTtcbn07XG5cblxuLyoqXG4gKiBDcmVhdGUgcGFydGljaXBhbnQuXG4gKlxuICogQHBhcmFtIHtib29sZWFufE9iamVjdH0gW2F0dHJzXSBhdHRyc1xuICpcbiAqIEByZXR1cm5zIHtkanMubW9kZWwuU2hhcGV9XG4gKi9cbkVsZW1lbnRGYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVQYXJ0aWNpcGFudFNoYXBlID0gZnVuY3Rpb24oYXR0cnMpIHtcblxuICBpZiAoIWlzT2JqZWN0KGF0dHJzKSkge1xuICAgIGF0dHJzID0geyBpc0V4cGFuZGVkOiBhdHRycyB9O1xuICB9XG5cbiAgYXR0cnMgPSBhc3NpZ24oeyB0eXBlOiAnYnBtbjpQYXJ0aWNpcGFudCcgfSwgYXR0cnMgfHwge30pO1xuXG4gIC8vIHBhcnRpY2lwYW50cyBhcmUgZXhwYW5kZWQgYnkgZGVmYXVsdFxuICBpZiAoYXR0cnMuaXNFeHBhbmRlZCAhPT0gZmFsc2UpIHtcbiAgICBhdHRycy5wcm9jZXNzUmVmID0gdGhpcy5fYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOlByb2Nlc3MnKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmNyZWF0ZVNoYXBlKGF0dHJzKTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQXBwbHkgYXR0cmlidXRlcyBmcm9tIGEgbWFwIHRvIHRoZSBnaXZlbiBlbGVtZW50LFxuICogcmVtb3ZlIGF0dHJpYnV0ZSBmcm9tIHRoZSBtYXAgb24gYXBwbGljYXRpb24uXG4gKlxuICogQHBhcmFtIHtCYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gYXR0cnMgKGluL291dCBtYXAgb2YgYXR0cmlidXRlcylcbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gYXR0cmlidXRlTmFtZXMgbmFtZSBvZiBhdHRyaWJ1dGVzIHRvIGFwcGx5XG4gKi9cbmZ1bmN0aW9uIGFwcGx5QXR0cmlidXRlcyhlbGVtZW50LCBhdHRycywgYXR0cmlidXRlTmFtZXMpIHtcblxuICBmb3JFYWNoKGF0dHJpYnV0ZU5hbWVzLCBmdW5jdGlvbihwcm9wZXJ0eSkge1xuICAgIGlmIChhdHRyc1twcm9wZXJ0eV0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXBwbHlBdHRyaWJ1dGUoZWxlbWVudCwgYXR0cnMsIHByb3BlcnR5KTtcbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIEFwcGx5IG5hbWVkIHByb3BlcnR5IHRvIGVsZW1lbnQgYW5kIGRyYWluIGl0IGZyb20gdGhlIGF0dHJzXG4gKiBjb2xsZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7QmFzZX0gZWxlbWVudFxuICogQHBhcmFtIHtPYmplY3R9IGF0dHJzIChpbi9vdXQgbWFwIG9mIGF0dHJpYnV0ZXMpXG4gKiBAcGFyYW0ge3N0cmluZ30gYXR0cmlidXRlTmFtZSB0byBhcHBseVxuICovXG5mdW5jdGlvbiBhcHBseUF0dHJpYnV0ZShlbGVtZW50LCBhdHRycywgYXR0cmlidXRlTmFtZSkge1xuICBlbGVtZW50W2F0dHJpYnV0ZU5hbWVdID0gYXR0cnNbYXR0cmlidXRlTmFtZV07XG5cbiAgZGVsZXRlIGF0dHJzW2F0dHJpYnV0ZU5hbWVdO1xufSIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBCYXNlTW9kZWxpbmcgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW9kZWxpbmcvTW9kZWxpbmcnO1xuXG5pbXBvcnQgVXBkYXRlUHJvcGVydGllc0hhbmRsZXIgZnJvbSAnLi9jbWQvVXBkYXRlUHJvcGVydGllc0hhbmRsZXInO1xuaW1wb3J0IFVwZGF0ZUNhbnZhc1Jvb3RIYW5kbGVyIGZyb20gJy4vY21kL1VwZGF0ZUNhbnZhc1Jvb3RIYW5kbGVyJztcbmltcG9ydCBBZGRMYW5lSGFuZGxlciBmcm9tICcuL2NtZC9BZGRMYW5lSGFuZGxlcic7XG5pbXBvcnQgU3BsaXRMYW5lSGFuZGxlciBmcm9tICcuL2NtZC9TcGxpdExhbmVIYW5kbGVyJztcbmltcG9ydCBSZXNpemVMYW5lSGFuZGxlciBmcm9tICcuL2NtZC9SZXNpemVMYW5lSGFuZGxlcic7XG5pbXBvcnQgVXBkYXRlRmxvd05vZGVSZWZzSGFuZGxlciBmcm9tICcuL2NtZC9VcGRhdGVGbG93Tm9kZVJlZnNIYW5kbGVyJztcbmltcG9ydCBJZENsYWltSGFuZGxlciBmcm9tICcuL2NtZC9JZENsYWltSGFuZGxlcic7XG5pbXBvcnQgU2V0Q29sb3JIYW5kbGVyIGZyb20gJy4vY21kL1NldENvbG9ySGFuZGxlcic7XG5cbmltcG9ydCBVcGRhdGVMYWJlbEhhbmRsZXIgZnJvbSAnLi4vbGFiZWwtZWRpdGluZy9jbWQvVXBkYXRlTGFiZWxIYW5kbGVyJztcblxuXG4vKipcbiAqIEJQTU4gMi4wIG1vZGVsaW5nIGZlYXR1cmVzIGFjdGl2YXRvclxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0VsZW1lbnRGYWN0b3J5fSBlbGVtZW50RmFjdG9yeVxuICogQHBhcmFtIHtDb21tYW5kU3RhY2t9IGNvbW1hbmRTdGFja1xuICogQHBhcmFtIHtCcG1uUnVsZXN9IGJwbW5SdWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb2RlbGluZyhcbiAgICBldmVudEJ1cywgZWxlbWVudEZhY3RvcnksIGNvbW1hbmRTdGFjayxcbiAgICBicG1uUnVsZXMpIHtcblxuICBCYXNlTW9kZWxpbmcuY2FsbCh0aGlzLCBldmVudEJ1cywgZWxlbWVudEZhY3RvcnksIGNvbW1hbmRTdGFjayk7XG5cbiAgdGhpcy5fYnBtblJ1bGVzID0gYnBtblJ1bGVzO1xufVxuXG5pbmhlcml0cyhNb2RlbGluZywgQmFzZU1vZGVsaW5nKTtcblxuTW9kZWxpbmcuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcbiAgJ2NvbW1hbmRTdGFjaycsXG4gICdicG1uUnVsZXMnXG5dO1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5nZXRIYW5kbGVycyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgaGFuZGxlcnMgPSBCYXNlTW9kZWxpbmcucHJvdG90eXBlLmdldEhhbmRsZXJzLmNhbGwodGhpcyk7XG5cbiAgaGFuZGxlcnNbJ2VsZW1lbnQudXBkYXRlUHJvcGVydGllcyddID0gVXBkYXRlUHJvcGVydGllc0hhbmRsZXI7XG4gIGhhbmRsZXJzWydjYW52YXMudXBkYXRlUm9vdCddID0gVXBkYXRlQ2FudmFzUm9vdEhhbmRsZXI7XG4gIGhhbmRsZXJzWydsYW5lLmFkZCddID0gQWRkTGFuZUhhbmRsZXI7XG4gIGhhbmRsZXJzWydsYW5lLnJlc2l6ZSddID0gUmVzaXplTGFuZUhhbmRsZXI7XG4gIGhhbmRsZXJzWydsYW5lLnNwbGl0J10gPSBTcGxpdExhbmVIYW5kbGVyO1xuICBoYW5kbGVyc1snbGFuZS51cGRhdGVSZWZzJ10gPSBVcGRhdGVGbG93Tm9kZVJlZnNIYW5kbGVyO1xuICBoYW5kbGVyc1snaWQudXBkYXRlQ2xhaW0nXSA9IElkQ2xhaW1IYW5kbGVyO1xuICBoYW5kbGVyc1snZWxlbWVudC5zZXRDb2xvciddID0gU2V0Q29sb3JIYW5kbGVyO1xuICBoYW5kbGVyc1snZWxlbWVudC51cGRhdGVMYWJlbCddID0gVXBkYXRlTGFiZWxIYW5kbGVyO1xuXG4gIHJldHVybiBoYW5kbGVycztcbn07XG5cblxuTW9kZWxpbmcucHJvdG90eXBlLnVwZGF0ZUxhYmVsID0gZnVuY3Rpb24oZWxlbWVudCwgbmV3TGFiZWwsIG5ld0JvdW5kcywgaGludHMpIHtcbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnQudXBkYXRlTGFiZWwnLCB7XG4gICAgZWxlbWVudDogZWxlbWVudCxcbiAgICBuZXdMYWJlbDogbmV3TGFiZWwsXG4gICAgbmV3Qm91bmRzOiBuZXdCb3VuZHMsXG4gICAgaGludHM6IGhpbnRzIHx8IHt9XG4gIH0pO1xufTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBhdHRycywgaGludHMpIHtcblxuICB2YXIgYnBtblJ1bGVzID0gdGhpcy5fYnBtblJ1bGVzO1xuXG4gIGlmICghYXR0cnMpIHtcbiAgICBhdHRycyA9IGJwbW5SdWxlcy5jYW5Db25uZWN0KHNvdXJjZSwgdGFyZ2V0KTtcbiAgfVxuXG4gIGlmICghYXR0cnMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICByZXR1cm4gdGhpcy5jcmVhdGVDb25uZWN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBhdHRycywgc291cmNlLnBhcmVudCwgaGludHMpO1xufTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUudXBkYXRlUHJvcGVydGllcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHByb3BlcnRpZXMpIHtcbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnQudXBkYXRlUHJvcGVydGllcycsIHtcbiAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgIHByb3BlcnRpZXM6IHByb3BlcnRpZXNcbiAgfSk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUucmVzaXplTGFuZSA9IGZ1bmN0aW9uKGxhbmVTaGFwZSwgbmV3Qm91bmRzLCBiYWxhbmNlZCkge1xuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnbGFuZS5yZXNpemUnLCB7XG4gICAgc2hhcGU6IGxhbmVTaGFwZSxcbiAgICBuZXdCb3VuZHM6IG5ld0JvdW5kcyxcbiAgICBiYWxhbmNlZDogYmFsYW5jZWRcbiAgfSk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUuYWRkTGFuZSA9IGZ1bmN0aW9uKHRhcmdldExhbmVTaGFwZSwgbG9jYXRpb24pIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgc2hhcGU6IHRhcmdldExhbmVTaGFwZSxcbiAgICBsb2NhdGlvbjogbG9jYXRpb25cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnbGFuZS5hZGQnLCBjb250ZXh0KTtcblxuICByZXR1cm4gY29udGV4dC5uZXdMYW5lO1xufTtcblxuTW9kZWxpbmcucHJvdG90eXBlLnNwbGl0TGFuZSA9IGZ1bmN0aW9uKHRhcmdldExhbmUsIGNvdW50KSB7XG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdsYW5lLnNwbGl0Jywge1xuICAgIHNoYXBlOiB0YXJnZXRMYW5lLFxuICAgIGNvdW50OiBjb3VudFxuICB9KTtcbn07XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBjdXJyZW50IGRpYWdyYW0gaW50byBhIGNvbGxhYm9yYXRpb24uXG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGVsLlJvb3R9IHRoZSBuZXcgcm9vdCBlbGVtZW50XG4gKi9cbk1vZGVsaW5nLnByb3RvdHlwZS5tYWtlQ29sbGFib3JhdGlvbiA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBjb2xsYWJvcmF0aW9uRWxlbWVudCA9IHRoaXMuX2NyZWF0ZSgncm9vdCcsIHtcbiAgICB0eXBlOiAnYnBtbjpDb2xsYWJvcmF0aW9uJ1xuICB9KTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBuZXdSb290OiBjb2xsYWJvcmF0aW9uRWxlbWVudFxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdjYW52YXMudXBkYXRlUm9vdCcsIGNvbnRleHQpO1xuXG4gIHJldHVybiBjb2xsYWJvcmF0aW9uRWxlbWVudDtcbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS51cGRhdGVMYW5lUmVmcyA9IGZ1bmN0aW9uKGZsb3dOb2RlU2hhcGVzLCBsYW5lU2hhcGVzKSB7XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2xhbmUudXBkYXRlUmVmcycsIHtcbiAgICBmbG93Tm9kZVNoYXBlczogZmxvd05vZGVTaGFwZXMsXG4gICAgbGFuZVNoYXBlczogbGFuZVNoYXBlc1xuICB9KTtcbn07XG5cbi8qKlxuICogVHJhbnNmb3JtIHRoZSBjdXJyZW50IGRpYWdyYW0gaW50byBhIHByb2Nlc3MuXG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGVsLlJvb3R9IHRoZSBuZXcgcm9vdCBlbGVtZW50XG4gKi9cbk1vZGVsaW5nLnByb3RvdHlwZS5tYWtlUHJvY2VzcyA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBwcm9jZXNzRWxlbWVudCA9IHRoaXMuX2NyZWF0ZSgncm9vdCcsIHtcbiAgICB0eXBlOiAnYnBtbjpQcm9jZXNzJ1xuICB9KTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBuZXdSb290OiBwcm9jZXNzRWxlbWVudFxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdjYW52YXMudXBkYXRlUm9vdCcsIGNvbnRleHQpO1xufTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUuY2xhaW1JZCA9IGZ1bmN0aW9uKGlkLCBtb2RkbGVFbGVtZW50KSB7XG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdpZC51cGRhdGVDbGFpbScsIHtcbiAgICBpZDogaWQsXG4gICAgZWxlbWVudDogbW9kZGxlRWxlbWVudCxcbiAgICBjbGFpbWluZzogdHJ1ZVxuICB9KTtcbn07XG5cblxuTW9kZWxpbmcucHJvdG90eXBlLnVuY2xhaW1JZCA9IGZ1bmN0aW9uKGlkLCBtb2RkbGVFbGVtZW50KSB7XG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdpZC51cGRhdGVDbGFpbScsIHtcbiAgICBpZDogaWQsXG4gICAgZWxlbWVudDogbW9kZGxlRWxlbWVudFxuICB9KTtcbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS5zZXRDb2xvciA9IGZ1bmN0aW9uKGVsZW1lbnRzLCBjb2xvcnMpIHtcbiAgaWYgKCFlbGVtZW50cy5sZW5ndGgpIHtcbiAgICBlbGVtZW50cyA9IFsgZWxlbWVudHMgXTtcbiAgfVxuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdlbGVtZW50LnNldENvbG9yJywge1xuICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICBjb2xvcnM6IGNvbG9yc1xuICB9KTtcbn07XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQge1xuICBnZXRPcmllbnRhdGlvbixcbiAgZ2V0TWlkLFxuICBhc1RSQkxcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBzdWJzdHJhY3Rcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9NYXRoJztcblxuaW1wb3J0IHtcbiAgaGFzRXh0ZXJuYWxMYWJlbFxufSBmcm9tICcuLi8uLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG52YXIgQUxJR05NRU5UUyA9IFtcbiAgJ3RvcCcsXG4gICdib3R0b20nLFxuICAnbGVmdCcsXG4gICdyaWdodCdcbl07XG5cbnZhciBFTEVNRU5UX0xBQkVMX0RJU1RBTkNFID0gMTA7XG5cbi8qKlxuICogQSBjb21wb25lbnQgdGhhdCBtYWtlcyBzdXJlIHRoYXQgZXh0ZXJuYWwgbGFiZWxzIGFyZSBhZGRlZFxuICogdG9nZXRoZXIgd2l0aCByZXNwZWN0aXZlIGVsZW1lbnRzIGFuZCBwcm9wZXJseSB1cGRhdGVkIChESSB3aXNlKVxuICogZHVyaW5nIG1vdmUuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFkYXB0aXZlTGFiZWxQb3NpdGlvbmluZ0JlaGF2aW9yKGV2ZW50QnVzLCBtb2RlbGluZykge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuICB0aGlzLnBvc3RFeGVjdXRlZChbXG4gICAgJ2Nvbm5lY3Rpb24uY3JlYXRlJyxcbiAgICAnY29ubmVjdGlvbi5sYXlvdXQnLFxuICAgICdjb25uZWN0aW9uLnVwZGF0ZVdheXBvaW50cydcbiAgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHNvdXJjZSA9IGNvbm5lY3Rpb24uc291cmNlLFxuICAgICAgICB0YXJnZXQgPSBjb25uZWN0aW9uLnRhcmdldCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gICAgaWYgKGhpbnRzLmNyZWF0ZUVsZW1lbnRzQmVoYXZpb3IgIT09IGZhbHNlKSB7XG4gICAgICBjaGVja0xhYmVsQWRqdXN0bWVudChzb3VyY2UpO1xuICAgICAgY2hlY2tMYWJlbEFkanVzdG1lbnQodGFyZ2V0KTtcbiAgICB9XG4gIH0pO1xuXG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoW1xuICAgICdsYWJlbC5jcmVhdGUnXG4gIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fTtcblxuICAgIGlmIChoaW50cy5jcmVhdGVFbGVtZW50c0JlaGF2aW9yICE9PSBmYWxzZSkge1xuICAgICAgY2hlY2tMYWJlbEFkanVzdG1lbnQoc2hhcGUubGFiZWxUYXJnZXQpO1xuICAgIH1cbiAgfSk7XG5cblxuICB0aGlzLnBvc3RFeGVjdXRlZChbXG4gICAgJ2VsZW1lbnRzLmNyZWF0ZSdcbiAgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnRzID0gY29udGV4dC5lbGVtZW50cyxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gICAgaWYgKGhpbnRzLmNyZWF0ZUVsZW1lbnRzQmVoYXZpb3IgIT09IGZhbHNlKSB7XG4gICAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgY2hlY2tMYWJlbEFkanVzdG1lbnQoZWxlbWVudCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIGZ1bmN0aW9uIGNoZWNrTGFiZWxBZGp1c3RtZW50KGVsZW1lbnQpIHtcblxuICAgIC8vIHNraXAgbm9uLWV4aXN0aW5nIGxhYmVsc1xuICAgIGlmICghaGFzRXh0ZXJuYWxMYWJlbChlbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBvcHRpbWFsUG9zaXRpb24gPSBnZXRPcHRpbWFsUG9zaXRpb24oZWxlbWVudCk7XG5cbiAgICAvLyBubyBvcHRpbWFsIHBvc2l0aW9uIGZvdW5kXG4gICAgaWYgKCFvcHRpbWFsUG9zaXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhZGp1c3RMYWJlbFBvc2l0aW9uKGVsZW1lbnQsIG9wdGltYWxQb3NpdGlvbik7XG4gIH1cblxuICBmdW5jdGlvbiBhZGp1c3RMYWJlbFBvc2l0aW9uKGVsZW1lbnQsIG9yaWVudGF0aW9uKSB7XG5cbiAgICB2YXIgZWxlbWVudE1pZCA9IGdldE1pZChlbGVtZW50KSxcbiAgICAgICAgbGFiZWwgPSBlbGVtZW50LmxhYmVsLFxuICAgICAgICBsYWJlbE1pZCA9IGdldE1pZChsYWJlbCk7XG5cbiAgICAvLyBpZ25vcmUgbGFiZWxzIHRoYXQgYXJlIGJlaW5nIGNyZWF0ZWRcbiAgICBpZiAoIWxhYmVsLnBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBlbGVtZW50VHJibCA9IGFzVFJCTChlbGVtZW50KTtcblxuICAgIHZhciBuZXdMYWJlbE1pZDtcblxuICAgIHN3aXRjaCAob3JpZW50YXRpb24pIHtcbiAgICBjYXNlICd0b3AnOlxuICAgICAgbmV3TGFiZWxNaWQgPSB7XG4gICAgICAgIHg6IGVsZW1lbnRNaWQueCxcbiAgICAgICAgeTogZWxlbWVudFRyYmwudG9wIC0gRUxFTUVOVF9MQUJFTF9ESVNUQU5DRSAtIGxhYmVsLmhlaWdodCAvIDJcbiAgICAgIH07XG5cbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnbGVmdCc6XG5cbiAgICAgIG5ld0xhYmVsTWlkID0ge1xuICAgICAgICB4OiBlbGVtZW50VHJibC5sZWZ0IC0gRUxFTUVOVF9MQUJFTF9ESVNUQU5DRSAtIGxhYmVsLndpZHRoIC8gMixcbiAgICAgICAgeTogZWxlbWVudE1pZC55XG4gICAgICB9O1xuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ2JvdHRvbSc6XG5cbiAgICAgIG5ld0xhYmVsTWlkID0ge1xuICAgICAgICB4OiBlbGVtZW50TWlkLngsXG4gICAgICAgIHk6IGVsZW1lbnRUcmJsLmJvdHRvbSArIEVMRU1FTlRfTEFCRUxfRElTVEFOQ0UgKyBsYWJlbC5oZWlnaHQgLyAyXG4gICAgICB9O1xuXG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3JpZ2h0JzpcblxuICAgICAgbmV3TGFiZWxNaWQgPSB7XG4gICAgICAgIHg6IGVsZW1lbnRUcmJsLnJpZ2h0ICsgRUxFTUVOVF9MQUJFTF9ESVNUQU5DRSArIGxhYmVsLndpZHRoIC8gMixcbiAgICAgICAgeTogZWxlbWVudE1pZC55XG4gICAgICB9O1xuXG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICB2YXIgZGVsdGEgPSBzdWJzdHJhY3QobmV3TGFiZWxNaWQsIGxhYmVsTWlkKTtcblxuICAgIG1vZGVsaW5nLm1vdmVTaGFwZShsYWJlbCwgZGVsdGEpO1xuICB9XG5cbn1cblxuaW5oZXJpdHMoQWRhcHRpdmVMYWJlbFBvc2l0aW9uaW5nQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cbkFkYXB0aXZlTGFiZWxQb3NpdGlvbmluZ0JlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogUmV0dXJuIGFsaWdubWVudHMgd2hpY2ggYXJlIHRha2VuIGJ5IGEgYm91bmRhcnkncyBob3N0IGVsZW1lbnRcbiAqXG4gKiBAcGFyYW0ge1NoYXBlfSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7QXJyYXk8c3RyaW5nPn1cbiAqL1xuZnVuY3Rpb24gZ2V0VGFrZW5Ib3N0QWxpZ25tZW50cyhlbGVtZW50KSB7XG5cbiAgdmFyIGhvc3RFbGVtZW50ID0gZWxlbWVudC5ob3N0LFxuICAgICAgZWxlbWVudE1pZCA9IGdldE1pZChlbGVtZW50KSxcbiAgICAgIGhvc3RPcmllbnRhdGlvbiA9IGdldE9yaWVudGF0aW9uKGVsZW1lbnRNaWQsIGhvc3RFbGVtZW50KTtcblxuICB2YXIgZnJlZUFsaWdubWVudHM7XG5cbiAgLy8gY2hlY2sgd2hldGhlciB0aGVyZSBpcyBhIG11bHRpLW9yaWVudGF0aW9uLCBlLmcuICd0b3AtbGVmdCdcbiAgaWYgKGhvc3RPcmllbnRhdGlvbi5pbmRleE9mKCctJykgPj0gMCkge1xuICAgIGZyZWVBbGlnbm1lbnRzID0gaG9zdE9yaWVudGF0aW9uLnNwbGl0KCctJyk7XG4gIH0gZWxzZSB7XG4gICAgZnJlZUFsaWdubWVudHMgPSBbIGhvc3RPcmllbnRhdGlvbiBdO1xuICB9XG5cbiAgdmFyIHRha2VuQWxpZ25tZW50cyA9IEFMSUdOTUVOVFMuZmlsdGVyKGZ1bmN0aW9uKGFsaWdubWVudCkge1xuXG4gICAgcmV0dXJuIGZyZWVBbGlnbm1lbnRzLmluZGV4T2YoYWxpZ25tZW50KSA9PT0gLTE7XG4gIH0pO1xuXG4gIHJldHVybiB0YWtlbkFsaWdubWVudHM7XG5cbn1cblxuLyoqXG4gKiBSZXR1cm4gYWxpZ25tZW50cyB3aGljaCBhcmUgdGFrZW4gYnkgcmVsYXRlZCBjb25uZWN0aW9uc1xuICpcbiAqIEBwYXJhbSB7U2hhcGV9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxzdHJpbmc+fVxuICovXG5mdW5jdGlvbiBnZXRUYWtlbkNvbm5lY3Rpb25BbGlnbm1lbnRzKGVsZW1lbnQpIHtcblxuICB2YXIgZWxlbWVudE1pZCA9IGdldE1pZChlbGVtZW50KTtcblxuICB2YXIgdGFrZW5BbGlnbm1lbnRzID0gW10uY29uY2F0KFxuICAgIGVsZW1lbnQuaW5jb21pbmcubWFwKGZ1bmN0aW9uKGMpIHtcbiAgICAgIHJldHVybiBjLndheXBvaW50c1tjLndheXBvaW50cy5sZW5ndGggLSAyIF07XG4gICAgfSksXG4gICAgZWxlbWVudC5vdXRnb2luZy5tYXAoZnVuY3Rpb24oYykge1xuICAgICAgcmV0dXJuIGMud2F5cG9pbnRzWzFdO1xuICAgIH0pXG4gICkubWFwKGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgcmV0dXJuIGdldEFwcHJveGltYXRlT3JpZW50YXRpb24oZWxlbWVudE1pZCwgcG9pbnQpO1xuICB9KTtcblxuICByZXR1cm4gdGFrZW5BbGlnbm1lbnRzO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgb3B0aW1hbCBsYWJlbCBwb3NpdGlvbiBhcm91bmQgYW4gZWxlbWVudFxuICogb3IgX3VuZGVmaW5lZF8sIGlmIG5vbmUgd2FzIGZvdW5kLlxuICpcbiAqIEBwYXJhbSAge1NoYXBlfSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7c3RyaW5nfSBwb3NpdGlvbmluZyBpZGVudGlmaWVyXG4gKi9cbmZ1bmN0aW9uIGdldE9wdGltYWxQb3NpdGlvbihlbGVtZW50KSB7XG5cbiAgdmFyIGxhYmVsTWlkID0gZ2V0TWlkKGVsZW1lbnQubGFiZWwpO1xuXG4gIHZhciBlbGVtZW50TWlkID0gZ2V0TWlkKGVsZW1lbnQpO1xuXG4gIHZhciBsYWJlbE9yaWVudGF0aW9uID0gZ2V0QXBwcm94aW1hdGVPcmllbnRhdGlvbihlbGVtZW50TWlkLCBsYWJlbE1pZCk7XG5cbiAgaWYgKCFpc0FsaWduZWQobGFiZWxPcmllbnRhdGlvbikpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgdGFrZW5BbGlnbm1lbnRzID0gZ2V0VGFrZW5Db25uZWN0aW9uQWxpZ25tZW50cyhlbGVtZW50KTtcblxuICBpZiAoZWxlbWVudC5ob3N0KSB7XG4gICAgdmFyIHRha2VuSG9zdEFsaWdubWVudHMgPSBnZXRUYWtlbkhvc3RBbGlnbm1lbnRzKGVsZW1lbnQpO1xuXG4gICAgdGFrZW5BbGlnbm1lbnRzID0gdGFrZW5BbGlnbm1lbnRzLmNvbmNhdCh0YWtlbkhvc3RBbGlnbm1lbnRzKTtcbiAgfVxuXG4gIHZhciBmcmVlQWxpZ25tZW50cyA9IEFMSUdOTUVOVFMuZmlsdGVyKGZ1bmN0aW9uKGFsaWdubWVudCkge1xuXG4gICAgcmV0dXJuIHRha2VuQWxpZ25tZW50cy5pbmRleE9mKGFsaWdubWVudCkgPT09IC0xO1xuICB9KTtcblxuICAvLyBOT1RISU5HIFRPIERPOyBsYWJlbCBhbHJlYWR5IGFsaWduZWQgYS5PLksuXG4gIGlmIChmcmVlQWxpZ25tZW50cy5pbmRleE9mKGxhYmVsT3JpZW50YXRpb24pICE9PSAtMSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiBmcmVlQWxpZ25tZW50c1swXTtcbn1cblxuZnVuY3Rpb24gZ2V0QXBwcm94aW1hdGVPcmllbnRhdGlvbihwMCwgcDEpIHtcbiAgcmV0dXJuIGdldE9yaWVudGF0aW9uKHAxLCBwMCwgNSk7XG59XG5cbmZ1bmN0aW9uIGlzQWxpZ25lZChvcmllbnRhdGlvbikge1xuICByZXR1cm4gQUxJR05NRU5UUy5pbmRleE9mKG9yaWVudGF0aW9uKSAhPT0gLTE7XG59XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwZW5kQmVoYXZpb3IoZXZlbnRCdXMsIGVsZW1lbnRGYWN0b3J5LCBicG1uUnVsZXMpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgLy8gYXNzaWduIGNvcnJlY3Qgc2hhcGUgcG9zaXRpb24gdW5sZXNzIGFscmVhZHkgc2V0XG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5hcHBlbmQnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZTtcblxuICAgIGlmICghY29udGV4dC5wb3NpdGlvbikge1xuXG4gICAgICBpZiAoaXMoc2hhcGUsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcbiAgICAgICAgY29udGV4dC5wb3NpdGlvbiA9IHtcbiAgICAgICAgICB4OiBzb3VyY2UueCArIHNvdXJjZS53aWR0aCAvIDIgKyA3NSxcbiAgICAgICAgICB5OiBzb3VyY2UueSAtICg1MCkgLSBzaGFwZS5oZWlnaHQgLyAyXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZXh0LnBvc2l0aW9uID0ge1xuICAgICAgICAgIHg6IHNvdXJjZS54ICsgc291cmNlLndpZHRoICsgODAgKyBzaGFwZS53aWR0aCAvIDIsXG4gICAgICAgICAgeTogc291cmNlLnkgKyBzb3VyY2UuaGVpZ2h0IC8gMlxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfSwgdHJ1ZSk7XG59XG5cbmluaGVyaXRzKEFwcGVuZEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5BcHBlbmRCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnYnBtblJ1bGVzJ1xuXTsiLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xyXG5cclxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XHJcblxyXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcclxuXHJcbmltcG9ydCB7XHJcbiAgZmlsdGVyLFxyXG4gIGZvckVhY2hcclxufSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXNzb2NpYXRpb25CZWhhdmlvcihpbmplY3RvciwgbW9kZWxpbmcpIHtcclxuICBpbmplY3Rvci5pbnZva2UoQ29tbWFuZEludGVyY2VwdG9yLCB0aGlzKTtcclxuXHJcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUubW92ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIHZhciBuZXdQYXJlbnQgPSBjb250ZXh0Lm5ld1BhcmVudCxcclxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XHJcblxyXG4gICAgdmFyIGFzc29jaWF0aW9ucyA9IGZpbHRlcihzaGFwZS5pbmNvbWluZy5jb25jYXQoc2hhcGUub3V0Z29pbmcpLCBmdW5jdGlvbihjb25uZWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiBpcyhjb25uZWN0aW9uLCAnYnBtbjpBc3NvY2lhdGlvbicpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgZm9yRWFjaChhc3NvY2lhdGlvbnMsIGZ1bmN0aW9uKGFzc29jaWF0aW9uKSB7XHJcbiAgICAgIG1vZGVsaW5nLm1vdmVDb25uZWN0aW9uKGFzc29jaWF0aW9uLCB7IHg6IDAsIHk6IDAgfSwgbmV3UGFyZW50KTtcclxuICAgIH0pO1xyXG4gIH0sIHRydWUpO1xyXG59XHJcblxyXG5pbmhlcml0cyhBc3NvY2lhdGlvbkJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xyXG5cclxuQXNzb2NpYXRpb25CZWhhdmlvci4kaW5qZWN0ID0gW1xyXG4gICdpbmplY3RvcicsXHJcbiAgJ21vZGVsaW5nJ1xyXG5dOyIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5pbXBvcnQgeyBnZXRCdXNpbmVzc09iamVjdCB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHsgaXNBbnkgfSBmcm9tICcuLi91dGlsL01vZGVsaW5nVXRpbCc7XG5cbmltcG9ydCB7IGlzTGFiZWwgfSBmcm9tICcuLi8uLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cblxuLyoqXG4gKiBSZXBsYWNlIGludGVybWVkaWF0ZSBldmVudCB3aXRoIGJvdW5kYXJ5IGV2ZW50IHdoZW4gY3JlYXRpbmcgb3IgbW92aW5nIHJlc3VsdHMgaW4gYXR0YWNoZWQgZXZlbnQuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEF0dGFjaEV2ZW50QmVoYXZpb3IoYnBtblJlcGxhY2UsIGluamVjdG9yKSB7XG4gIGluamVjdG9yLmludm9rZShDb21tYW5kSW50ZXJjZXB0b3IsIHRoaXMpO1xuXG4gIHRoaXMuX2JwbW5SZXBsYWNlID0gYnBtblJlcGxhY2U7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdlbGVtZW50cy5jcmVhdGUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzO1xuXG4gICAgZWxlbWVudHMgPSBlbGVtZW50cy5maWx0ZXIoZnVuY3Rpb24oc2hhcGUpIHtcbiAgICAgIHZhciBob3N0ID0gc2hhcGUuaG9zdDtcblxuICAgICAgcmV0dXJuIHNob3VsZFJlcGxhY2Uoc2hhcGUsIGhvc3QpO1xuICAgIH0pO1xuXG4gICAgaWYgKGVsZW1lbnRzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGVsZW1lbnRzLm1hcChmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KTtcbiAgICB9KS5mb3JFYWNoKGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICB2YXIgaG9zdCA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXG4gICAgICBjb250ZXh0LmVsZW1lbnRzWyBpbmRleCBdID0gc2VsZi5yZXBsYWNlU2hhcGUoZWxlbWVudHNbIGluZGV4IF0sIGhvc3QpO1xuICAgIH0pO1xuICB9LCB0cnVlKTtcblxuXG4gIHRoaXMucHJlRXhlY3V0ZSgnZWxlbWVudHMubW92ZScsIExPV19QUklPUklUWSwgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgaG9zdCA9IGNvbnRleHQubmV3SG9zdDtcblxuICAgIGlmIChzaGFwZXMubGVuZ3RoICE9PSAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNoYXBlID0gc2hhcGVzWzBdO1xuXG4gICAgaWYgKHNob3VsZFJlcGxhY2Uoc2hhcGUsIGhvc3QpKSB7XG4gICAgICBjb250ZXh0LnNoYXBlcyA9IFsgc2VsZi5yZXBsYWNlU2hhcGUoc2hhcGUsIGhvc3QpIF07XG4gICAgfVxuICB9LCB0cnVlKTtcbn1cblxuQXR0YWNoRXZlbnRCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnYnBtblJlcGxhY2UnLFxuICAnaW5qZWN0b3InXG5dO1xuXG5pbmhlcml0cyhBdHRhY2hFdmVudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5BdHRhY2hFdmVudEJlaGF2aW9yLnByb3RvdHlwZS5yZXBsYWNlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgaG9zdCkge1xuICB2YXIgZXZlbnREZWZpbml0aW9uID0gZ2V0RXZlbnREZWZpbml0aW9uKHNoYXBlKTtcblxuICB2YXIgYm91bmRhcnlFdmVudCA9IHtcbiAgICB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcbiAgICBob3N0OiBob3N0XG4gIH07XG5cbiAgaWYgKGV2ZW50RGVmaW5pdGlvbikge1xuICAgIGJvdW5kYXJ5RXZlbnQuZXZlbnREZWZpbml0aW9uVHlwZSA9IGV2ZW50RGVmaW5pdGlvbi4kdHlwZTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9icG1uUmVwbGFjZS5yZXBsYWNlRWxlbWVudChzaGFwZSwgYm91bmRhcnlFdmVudCwgeyBsYXlvdXRDb25uZWN0aW9uOiBmYWxzZSB9KTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50KSB7XG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxuICAgICAgZXZlbnREZWZpbml0aW9ucyA9IGJ1c2luZXNzT2JqZWN0LmV2ZW50RGVmaW5pdGlvbnM7XG5cbiAgcmV0dXJuIGV2ZW50RGVmaW5pdGlvbnMgJiYgZXZlbnREZWZpbml0aW9uc1swXTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkUmVwbGFjZShzaGFwZSwgaG9zdCkge1xuICByZXR1cm4gIWlzTGFiZWwoc2hhcGUpICYmXG4gICAgaXNBbnkoc2hhcGUsIFsgJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcsICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnIF0pICYmICEhaG9zdDtcbn1cbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgZmlsdGVyLFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEJQTU4gc3BlY2lmaWMgYm91bmRhcnkgZXZlbnQgYmVoYXZpb3JcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQm91bmRhcnlFdmVudEJlaGF2aW9yKGV2ZW50QnVzLCBtb2RlbGluZykge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuICBmdW5jdGlvbiBnZXRCb3VuZGFyeUV2ZW50cyhlbGVtZW50KSB7XG4gICAgcmV0dXJuIGZpbHRlcihlbGVtZW50LmF0dGFjaGVycywgZnVuY3Rpb24oYXR0YWNoZXIpIHtcbiAgICAgIHJldHVybiBpcyhhdHRhY2hlciwgJ2JwbW46Qm91bmRhcnlFdmVudCcpO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gcmVtb3ZlIGFmdGVyIGNvbm5lY3RpbmcgdG8gZXZlbnQtYmFzZWQgZ2F0ZXdheVxuICB0aGlzLnBvc3RFeGVjdXRlKCdjb25uZWN0aW9uLmNyZWF0ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIHNvdXJjZSA9IGV2ZW50LmNvbnRleHQuc291cmNlLFxuICAgICAgICB0YXJnZXQgPSBldmVudC5jb250ZXh0LnRhcmdldCxcbiAgICAgICAgYm91bmRhcnlFdmVudHMgPSBnZXRCb3VuZGFyeUV2ZW50cyh0YXJnZXQpO1xuXG4gICAgaWYgKFxuICAgICAgaXMoc291cmNlLCAnYnBtbjpFdmVudEJhc2VkR2F0ZXdheScpICYmXG4gICAgICBpcyh0YXJnZXQsICdicG1uOlJlY2VpdmVUYXNrJykgJiZcbiAgICAgIGJvdW5kYXJ5RXZlbnRzLmxlbmd0aCA+IDBcbiAgICApIHtcbiAgICAgIG1vZGVsaW5nLnJlbW92ZUVsZW1lbnRzKGJvdW5kYXJ5RXZlbnRzKTtcbiAgICB9XG5cbiAgfSk7XG5cbiAgLy8gcmVtb3ZlIGFmdGVyIHJlcGxhY2luZyBjb25uZWN0ZWQgZ2F0ZXdheSB3aXRoIGV2ZW50LWJhc2VkIGdhdGV3YXlcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBvbGRTb3VyY2UgPSBldmVudC5jb250ZXh0Lm9sZFNvdXJjZSxcbiAgICAgICAgbmV3U291cmNlID0gZXZlbnQuY29udGV4dC5uZXdTb3VyY2U7XG5cbiAgICBpZiAoaXMob2xkU291cmNlLCAnYnBtbjpHYXRld2F5JykgJiZcbiAgICAgICAgaXMobmV3U291cmNlLCAnYnBtbjpFdmVudEJhc2VkR2F0ZXdheScpKSB7XG4gICAgICBmb3JFYWNoKG5ld1NvdXJjZS5vdXRnb2luZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgICB2YXIgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgICAgICBhdHRhY2hlZGJvdW5kYXJ5RXZlbnRzID0gZ2V0Qm91bmRhcnlFdmVudHModGFyZ2V0KTtcblxuICAgICAgICBpZiAoaXModGFyZ2V0LCAnYnBtbjpSZWNlaXZlVGFzaycpICYmXG4gICAgICAgICAgICBhdHRhY2hlZGJvdW5kYXJ5RXZlbnRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBtb2RlbGluZy5yZW1vdmVFbGVtZW50cyhhdHRhY2hlZGJvdW5kYXJ5RXZlbnRzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbn1cblxuQm91bmRhcnlFdmVudEJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cbmluaGVyaXRzKEJvdW5kYXJ5RXZlbnRCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTtcbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgZ2V0UGFyZW50IH0gZnJvbSAnLi4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENyZWF0ZUJlaGF2aW9yKGluamVjdG9yKSB7XG4gIGluamVjdG9yLmludm9rZShDb21tYW5kSW50ZXJjZXB0b3IsIHRoaXMpO1xuXG4gIHRoaXMucHJlRXhlY3V0ZSgnc2hhcGUuY3JlYXRlJywgMTUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMocGFyZW50LCAnYnBtbjpMYW5lJykgJiYgIWlzKHNoYXBlLCAnYnBtbjpMYW5lJykpIHtcbiAgICAgIGNvbnRleHQucGFyZW50ID0gZ2V0UGFyZW50KHBhcmVudCwgJ2JwbW46UGFydGljaXBhbnQnKTtcbiAgICB9XG4gIH0pO1xuXG59XG5cblxuQ3JlYXRlQmVoYXZpb3IuJGluamVjdCA9IFsgJ2luamVjdG9yJyBdO1xuXG5pbmhlcml0cyhDcmVhdGVCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTsiLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cblxuLyoqXG4gKiBCUE1OIHNwZWNpZmljIGNyZWF0ZSBkYXRhIG9iamVjdCBiZWhhdmlvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3IoZXZlbnRCdXMsIGJwbW5GYWN0b3J5LCBtb2RkbGUpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnKSAmJiBzaGFwZS50eXBlICE9PSAnbGFiZWwnKSB7XG5cbiAgICAgIC8vIGNyZWF0ZSBhIERhdGFPYmplY3QgZXZlcnkgdGltZSBhIERhdGFPYmplY3RSZWZlcmVuY2UgaXMgY3JlYXRlZFxuICAgICAgdmFyIGRhdGFPYmplY3QgPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46RGF0YU9iamVjdCcpO1xuXG4gICAgICAvLyBzZXQgdGhlIHJlZmVyZW5jZSB0byB0aGUgRGF0YU9iamVjdFxuICAgICAgc2hhcGUuYnVzaW5lc3NPYmplY3QuZGF0YU9iamVjdFJlZiA9IGRhdGFPYmplY3Q7XG4gICAgfVxuICB9KTtcblxufVxuXG5DcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2JwbW5GYWN0b3J5JyxcbiAgJ21vZGRsZSdcbl07XG5cbmluaGVyaXRzKENyZWF0ZURhdGFPYmplY3RCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTsiLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7IGlzTGFiZWwgfSBmcm9tICcuLi8uLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbmltcG9ydCB7IGdldEJCb3ggfSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaW5kXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgYXNUUkJMIH0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG52YXIgSE9SSVpPTlRBTF9QQVJUSUNJUEFOVF9QQURESU5HID0gMjAsXG4gICAgVkVSVElDQUxfUEFSVElDSVBBTlRfUEFERElORyA9IDIwO1xuXG5leHBvcnQgdmFyIFBBUlRJQ0lQQU5UX0JPUkRFUl9XSURUSCA9IDMwO1xuXG52YXIgSElHSF9QUklPUklUWSA9IDIwMDA7XG5cblxuLyoqXG4gKiBCUE1OLXNwZWNpZmljIGJlaGF2aW9yIGZvciBjcmVhdGluZyBwYXJ0aWNpcGFudHMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IoY2FudmFzLCBldmVudEJ1cywgbW9kZWxpbmcpIHtcbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8vIGZpdCBwYXJ0aWNpcGFudFxuICBldmVudEJ1cy5vbihbXG4gICAgJ2NyZWF0ZS5zdGFydCcsXG4gICAgJ3NoYXBlLm1vdmUuc3RhcnQnXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIHJvb3RFbGVtZW50ID0gY2FudmFzLmdldFJvb3RFbGVtZW50KCk7XG5cbiAgICBpZiAoIWlzKHNoYXBlLCAnYnBtbjpQYXJ0aWNpcGFudCcpIHx8XG4gICAgICAhaXMocm9vdEVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSB8fFxuICAgICAgIXJvb3RFbGVtZW50LmNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGlnbm9yZSBjb25uZWN0aW9ucywgZ3JvdXBzIGFuZCBsYWJlbHNcbiAgICB2YXIgY2hpbGRyZW4gPSByb290RWxlbWVudC5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuICFpcyhlbGVtZW50LCAnYnBtbjpHcm91cCcpICYmXG4gICAgICAgICFpc0xhYmVsKGVsZW1lbnQpICYmXG4gICAgICAgICFpc0Nvbm5lY3Rpb24oZWxlbWVudCk7XG4gICAgfSk7XG5cbiAgICAvLyBlbnN1cmUgZm9yIGF2YWlsYWJsZSBjaGlsZHJlbiB0byBjYWxjdWxhdGUgYm91bmRzXG4gICAgaWYgKCFjaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY2hpbGRyZW5CQm94ID0gZ2V0QkJveChjaGlsZHJlbik7XG5cbiAgICB2YXIgcGFydGljaXBhbnRCb3VuZHMgPSBnZXRQYXJ0aWNpcGFudEJvdW5kcyhzaGFwZSwgY2hpbGRyZW5CQm94KTtcblxuICAgIC8vIGFzc2lnbiB3aWR0aCBhbmQgaGVpZ2h0XG4gICAgYXNzaWduKHNoYXBlLCBwYXJ0aWNpcGFudEJvdW5kcyk7XG5cbiAgICAvLyBhc3NpZ24gY3JlYXRlIGNvbnN0cmFpbnRzXG4gICAgY29udGV4dC5jcmVhdGVDb25zdHJhaW50cyA9IGdldFBhcnRpY2lwYW50Q3JlYXRlQ29uc3RyYWludHMoc2hhcGUsIGNoaWxkcmVuQkJveCk7XG4gIH0pO1xuXG4gIC8vIGZvcmNlIGhvdmVyaW5nIHByb2Nlc3Mgd2hlbiBjcmVhdGluZyBmaXJzdCBwYXJ0aWNpcGFudFxuICBldmVudEJ1cy5vbignY3JlYXRlLnN0YXJ0JywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgICAgcm9vdEVsZW1lbnRHZnggPSBjYW52YXMuZ2V0R3JhcGhpY3Mocm9vdEVsZW1lbnQpO1xuXG4gICAgZnVuY3Rpb24gZW5zdXJlSG92ZXJpbmdQcm9jZXNzKGV2ZW50KSB7XG4gICAgICBldmVudC5lbGVtZW50ID0gcm9vdEVsZW1lbnQ7XG4gICAgICBldmVudC5nZnggPSByb290RWxlbWVudEdmeDtcbiAgICB9XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykgJiYgaXMocm9vdEVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSkge1xuICAgICAgZXZlbnRCdXMub24oJ2VsZW1lbnQuaG92ZXInLCBISUdIX1BSSU9SSVRZLCBlbnN1cmVIb3ZlcmluZ1Byb2Nlc3MpO1xuXG4gICAgICBldmVudEJ1cy5vbmNlKCdjcmVhdGUuY2xlYW51cCcsIGZ1bmN0aW9uKCkge1xuICAgICAgICBldmVudEJ1cy5vZmYoJ2VsZW1lbnQuaG92ZXInLCBlbnN1cmVIb3ZlcmluZ1Byb2Nlc3MpO1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICBmdW5jdGlvbiBlbnN1cmVDb2xsYWJvcmF0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICAgIGNvbGxhYm9yYXRpb247XG5cbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKTtcblxuICAgIGlmIChpcyhyb290RWxlbWVudCwgJ2JwbW46Q29sbGFib3JhdGlvbicpKSB7XG4gICAgICBjb2xsYWJvcmF0aW9uID0gcm9vdEVsZW1lbnQ7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gdXBkYXRlIHJvb3QgZWxlbWVudCBieSBtYWtpbmcgY29sbGFib3JhdGlvblxuICAgICAgY29sbGFib3JhdGlvbiA9IG1vZGVsaW5nLm1ha2VDb2xsYWJvcmF0aW9uKCk7XG5cbiAgICAgIC8vIHJlLXVzZSBwcm9jZXNzIHdoZW4gY3JlYXRpbmcgZmlyc3QgcGFydGljaXBhbnRcbiAgICAgIGNvbnRleHQucHJvY2VzcyA9IHBhcmVudDtcbiAgICB9XG5cbiAgICBjb250ZXh0LnBhcmVudCA9IGNvbGxhYm9yYXRpb247XG4gIH1cblxuICAvLyB0dXJuIHByb2Nlc3MgaW50byBjb2xsYWJvcmF0aW9uIGJlZm9yZSBhZGRpbmcgcGFydGljaXBhbnRcbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykgJiYgaXMocGFyZW50LCAnYnBtbjpQcm9jZXNzJykpIHtcbiAgICAgIGVuc3VyZUNvbGxhYm9yYXRpb24oY29udGV4dCk7XG4gICAgfVxuICB9LCB0cnVlKTtcblxuICB0aGlzLmV4ZWN1dGUoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcHJvY2VzcyA9IGNvbnRleHQucHJvY2VzcyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcbiAgICAgIGNvbnRleHQub2xkUHJvY2Vzc1JlZiA9IHNoYXBlLmJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWY7XG5cbiAgICAgIC8vIHJlLXVzZSBwcm9jZXNzIHdoZW4gY3JlYXRpbmcgZmlyc3QgcGFydGljaXBhbnRcbiAgICAgIHNoYXBlLmJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWYgPSBwcm9jZXNzLmJ1c2luZXNzT2JqZWN0O1xuICAgIH1cbiAgfSwgdHJ1ZSk7XG5cbiAgdGhpcy5yZXZlcnQoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcHJvY2VzcyA9IGNvbnRleHQucHJvY2VzcyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcblxuICAgICAgLy8gcmUtdXNlIHByb2Nlc3Mgd2hlbiBjcmVhdGluZyBmaXJzdCBwYXJ0aWNpcGFudFxuICAgICAgc2hhcGUuYnVzaW5lc3NPYmplY3QucHJvY2Vzc1JlZiA9IGNvbnRleHQub2xkUHJvY2Vzc1JlZjtcbiAgICB9XG4gIH0sIHRydWUpO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgcHJvY2VzcyA9IGNvbnRleHQucHJvY2VzcyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcblxuICAgICAgLy8gbW92ZSBjaGlsZHJlbiBmcm9tIHByb2Nlc3MgdG8gcGFydGljaXBhbnRcbiAgICAgIHZhciBwcm9jZXNzQ2hpbGRyZW4gPSBwcm9jZXNzLmNoaWxkcmVuLnNsaWNlKCk7XG5cbiAgICAgIG1vZGVsaW5nLm1vdmVFbGVtZW50cyhwcm9jZXNzQ2hpbGRyZW4sIHsgeDogMCwgeTogMCB9LCBzaGFwZSk7XG4gICAgfVxuXG4gIH0sIHRydWUpO1xuXG4gIC8vIHR1cm4gcHJvY2VzcyBpbnRvIGNvbGxhYm9yYXRpb24gd2hlbiBjcmVhdGluZyBwYXJ0aWNpcGFudHNcbiAgdGhpcy5wcmVFeGVjdXRlKCdlbGVtZW50cy5jcmVhdGUnLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIGVsZW1lbnRzID0gY29udGV4dC5lbGVtZW50cyxcbiAgICAgICAgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICAgIHBhcnRpY2lwYW50O1xuXG4gICAgdmFyIGhhc1BhcnRpY2lwYW50cyA9IGZpbmRQYXJ0aWNpcGFudChlbGVtZW50cyk7XG5cbiAgICBpZiAoaGFzUGFydGljaXBhbnRzICYmIGlzKHBhcmVudCwgJ2JwbW46UHJvY2VzcycpKSB7XG4gICAgICBlbnN1cmVDb2xsYWJvcmF0aW9uKGNvbnRleHQpO1xuXG4gICAgICBwYXJ0aWNpcGFudCA9IGZpbmRQYXJ0aWNpcGFudChlbGVtZW50cyk7XG5cbiAgICAgIGNvbnRleHQub2xkUHJvY2Vzc1JlZiA9IHBhcnRpY2lwYW50LmJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWY7XG5cbiAgICAgIC8vIHJlLXVzZSBwcm9jZXNzIHdoZW4gY3JlYXRpbmcgZmlyc3QgcGFydGljaXBhbnRcbiAgICAgIHBhcnRpY2lwYW50LmJ1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWYgPSBwYXJlbnQuYnVzaW5lc3NPYmplY3Q7XG4gICAgfVxuICB9LCB0cnVlKTtcblxuICB0aGlzLnJldmVydCgnZWxlbWVudHMuY3JlYXRlJywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXG4gICAgICAgIHByb2Nlc3MgPSBjb250ZXh0LnByb2Nlc3MsXG4gICAgICAgIHBhcnRpY2lwYW50O1xuXG4gICAgaWYgKHByb2Nlc3MpIHtcbiAgICAgIHBhcnRpY2lwYW50ID0gZmluZFBhcnRpY2lwYW50KGVsZW1lbnRzKTtcblxuICAgICAgLy8gcmUtdXNlIHByb2Nlc3Mgd2hlbiBjcmVhdGluZyBmaXJzdCBwYXJ0aWNpcGFudFxuICAgICAgcGFydGljaXBhbnQuYnVzaW5lc3NPYmplY3QucHJvY2Vzc1JlZiA9IGNvbnRleHQub2xkUHJvY2Vzc1JlZjtcbiAgICB9XG4gIH0sIHRydWUpO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ2VsZW1lbnRzLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzLFxuICAgICAgICBwcm9jZXNzID0gY29udGV4dC5wcm9jZXNzLFxuICAgICAgICBwYXJ0aWNpcGFudDtcblxuICAgIGlmIChwcm9jZXNzKSB7XG4gICAgICBwYXJ0aWNpcGFudCA9IGZpbmRQYXJ0aWNpcGFudChlbGVtZW50cyk7XG5cbiAgICAgIC8vIG1vdmUgY2hpbGRyZW4gZnJvbSBwcm9jZXNzIHRvIGZpcnN0IHBhcnRpY2lwYW50XG4gICAgICB2YXIgcHJvY2Vzc0NoaWxkcmVuID0gcHJvY2Vzcy5jaGlsZHJlbi5zbGljZSgpO1xuXG4gICAgICBtb2RlbGluZy5tb3ZlRWxlbWVudHMocHJvY2Vzc0NoaWxkcmVuLCB7IHg6IDAsIHk6IDAgfSwgcGFydGljaXBhbnQpO1xuICAgIH1cblxuICB9LCB0cnVlKTtcblxufVxuXG5DcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdjYW52YXMnLFxuICAnZXZlbnRCdXMnLFxuICAnbW9kZWxpbmcnXG5dO1xuXG5pbmhlcml0cyhDcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZ2V0UGFydGljaXBhbnRCb3VuZHMoc2hhcGUsIGNoaWxkcmVuQkJveCkge1xuICBjaGlsZHJlbkJCb3ggPSB7XG4gICAgd2lkdGg6IGNoaWxkcmVuQkJveC53aWR0aCArIEhPUklaT05UQUxfUEFSVElDSVBBTlRfUEFERElORyAqIDIgKyBQQVJUSUNJUEFOVF9CT1JERVJfV0lEVEgsXG4gICAgaGVpZ2h0OiBjaGlsZHJlbkJCb3guaGVpZ2h0ICsgVkVSVElDQUxfUEFSVElDSVBBTlRfUEFERElORyAqIDJcbiAgfTtcblxuICB2YXIgd2lkdGggPSBNYXRoLm1heChzaGFwZS53aWR0aCwgY2hpbGRyZW5CQm94LndpZHRoKSxcbiAgICAgIGhlaWdodCA9IE1hdGgubWF4KHNoYXBlLmhlaWdodCwgY2hpbGRyZW5CQm94LmhlaWdodCk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiAtd2lkdGggLyAyLFxuICAgIHk6IC1oZWlnaHQgLyAyLFxuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRQYXJ0aWNpcGFudENyZWF0ZUNvbnN0cmFpbnRzKHNoYXBlLCBjaGlsZHJlbkJCb3gpIHtcbiAgY2hpbGRyZW5CQm94ID0gYXNUUkJMKGNoaWxkcmVuQkJveCk7XG5cbiAgcmV0dXJuIHtcbiAgICBib3R0b206IGNoaWxkcmVuQkJveC50b3AgKyBzaGFwZS5oZWlnaHQgLyAyIC0gVkVSVElDQUxfUEFSVElDSVBBTlRfUEFERElORyxcbiAgICBsZWZ0OiBjaGlsZHJlbkJCb3gucmlnaHQgLSBzaGFwZS53aWR0aCAvIDIgKyBIT1JJWk9OVEFMX1BBUlRJQ0lQQU5UX1BBRERJTkcsXG4gICAgdG9wOiBjaGlsZHJlbkJCb3guYm90dG9tIC0gc2hhcGUuaGVpZ2h0IC8gMiArIFZFUlRJQ0FMX1BBUlRJQ0lQQU5UX1BBRERJTkcsXG4gICAgcmlnaHQ6IGNoaWxkcmVuQkJveC5sZWZ0ICsgc2hhcGUud2lkdGggLyAyIC0gSE9SSVpPTlRBTF9QQVJUSUNJUEFOVF9QQURESU5HIC0gUEFSVElDSVBBTlRfQk9SREVSX1dJRFRIXG4gIH07XG59XG5cbmZ1bmN0aW9uIGlzQ29ubmVjdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiAhIWVsZW1lbnQud2F5cG9pbnRzO1xufVxuXG5mdW5jdGlvbiBmaW5kUGFydGljaXBhbnQoZWxlbWVudHMpIHtcbiAgcmV0dXJuIGZpbmQoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKTtcbiAgfSk7XG59IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGFkZCBhcyBjb2xsZWN0aW9uQWRkLFxuICByZW1vdmUgYXMgY29sbGVjdGlvblJlbW92ZVxufSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zJztcblxuaW1wb3J0IHtcbiAgZmluZFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGlzXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxudmFyIFRBUkdFVF9SRUZfUExBQ0VIT0xERVJfTkFNRSA9ICdfX3RhcmdldFJlZl9wbGFjZWhvbGRlcic7XG5cblxuLyoqXG4gKiBUaGlzIGJlaGF2aW9yIG1ha2VzIHN1cmUgd2UgYWx3YXlzIHNldCBhIGZha2VcbiAqIERhdGFJbnB1dEFzc29jaWF0aW9uI3RhcmdldFJlZiBhcyBkZW1hbmRlZCBieSB0aGUgQlBNTiAyLjBcbiAqIFhTRCBzY2hlbWEuXG4gKlxuICogVGhlIHJlZmVyZW5jZSBpcyBzZXQgdG8gYSBicG1uOlByb3BlcnR5eyBuYW1lOiAnX190YXJnZXRSZWZfcGxhY2Vob2xkZXInIH1cbiAqIHdoaWNoIGlzIGNyZWF0ZWQgb24gdGhlIGZseSBhbmQgY2xlYW5lZCB1cCBhZnRlcndhcmRzIGlmIG5vdCBuZWVkZWRcbiAqIGFueW1vcmUuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERhdGFJbnB1dEFzc29jaWF0aW9uQmVoYXZpb3IoZXZlbnRCdXMsIGJwbW5GYWN0b3J5KSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG5cbiAgdGhpcy5leGVjdXRlZChbXG4gICAgJ2Nvbm5lY3Rpb24uY3JlYXRlJyxcbiAgICAnY29ubmVjdGlvbi5kZWxldGUnLFxuICAgICdjb25uZWN0aW9uLm1vdmUnLFxuICAgICdjb25uZWN0aW9uLnJlY29ubmVjdCdcbiAgXSwgaWZEYXRhSW5wdXRBc3NvY2lhdGlvbihmaXhUYXJnZXRSZWYpKTtcblxuICB0aGlzLnJldmVydGVkKFtcbiAgICAnY29ubmVjdGlvbi5jcmVhdGUnLFxuICAgICdjb25uZWN0aW9uLmRlbGV0ZScsXG4gICAgJ2Nvbm5lY3Rpb24ubW92ZScsXG4gICAgJ2Nvbm5lY3Rpb24ucmVjb25uZWN0J1xuICBdLCBpZkRhdGFJbnB1dEFzc29jaWF0aW9uKGZpeFRhcmdldFJlZikpO1xuXG5cbiAgZnVuY3Rpb24gdXNlc1RhcmdldFJlZihlbGVtZW50LCB0YXJnZXRSZWYsIHJlbW92ZWRDb25uZWN0aW9uKSB7XG5cbiAgICB2YXIgaW5wdXRBc3NvY2lhdGlvbnMgPSBlbGVtZW50LmdldCgnZGF0YUlucHV0QXNzb2NpYXRpb25zJyk7XG5cbiAgICByZXR1cm4gZmluZChpbnB1dEFzc29jaWF0aW9ucywgZnVuY3Rpb24oYXNzb2NpYXRpb24pIHtcbiAgICAgIHJldHVybiBhc3NvY2lhdGlvbiAhPT0gcmVtb3ZlZENvbm5lY3Rpb24gJiZcbiAgICAgICAgICAgICBhc3NvY2lhdGlvbi50YXJnZXRSZWYgPT09IHRhcmdldFJlZjtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldFRhcmdldFJlZihlbGVtZW50LCBjcmVhdGUpIHtcblxuICAgIHZhciBwcm9wZXJ0aWVzID0gZWxlbWVudC5nZXQoJ3Byb3BlcnRpZXMnKTtcblxuICAgIHZhciB0YXJnZXRSZWZQcm9wID0gZmluZChwcm9wZXJ0aWVzLCBmdW5jdGlvbihwKSB7XG4gICAgICByZXR1cm4gcC5uYW1lID09PSBUQVJHRVRfUkVGX1BMQUNFSE9MREVSX05BTUU7XG4gICAgfSk7XG5cbiAgICBpZiAoIXRhcmdldFJlZlByb3AgJiYgY3JlYXRlKSB7XG4gICAgICB0YXJnZXRSZWZQcm9wID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOlByb3BlcnR5Jywge1xuICAgICAgICBuYW1lOiBUQVJHRVRfUkVGX1BMQUNFSE9MREVSX05BTUVcbiAgICAgIH0pO1xuXG4gICAgICBjb2xsZWN0aW9uQWRkKHByb3BlcnRpZXMsIHRhcmdldFJlZlByb3ApO1xuICAgIH1cblxuICAgIHJldHVybiB0YXJnZXRSZWZQcm9wO1xuICB9XG5cbiAgZnVuY3Rpb24gY2xlYW51cFRhcmdldFJlZihlbGVtZW50LCBjb25uZWN0aW9uKSB7XG5cbiAgICB2YXIgdGFyZ2V0UmVmUHJvcCA9IGdldFRhcmdldFJlZihlbGVtZW50KTtcblxuICAgIGlmICghdGFyZ2V0UmVmUHJvcCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdXNlc1RhcmdldFJlZihlbGVtZW50LCB0YXJnZXRSZWZQcm9wLCBjb25uZWN0aW9uKSkge1xuICAgICAgY29sbGVjdGlvblJlbW92ZShlbGVtZW50LmdldCgncHJvcGVydGllcycpLCB0YXJnZXRSZWZQcm9wKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWFrZSBzdXJlIHRhcmdldFJlZiBpcyBzZXQgdG8gYSB2YWxpZCBwcm9wZXJ0eSBvclxuICAgKiBgbnVsbGAgaWYgdGhlIGNvbm5lY3Rpb24gaXMgZGV0YWNoZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50XG4gICAqL1xuICBmdW5jdGlvbiBmaXhUYXJnZXRSZWYoZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgY29ubmVjdGlvbkJvID0gY29ubmVjdGlvbi5idXNpbmVzc09iamVjdCxcbiAgICAgICAgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIHRhcmdldEJvID0gdGFyZ2V0ICYmIHRhcmdldC5idXNpbmVzc09iamVjdCxcbiAgICAgICAgbmV3VGFyZ2V0ID0gY29udGV4dC5uZXdUYXJnZXQsXG4gICAgICAgIG5ld1RhcmdldEJvID0gbmV3VGFyZ2V0ICYmIG5ld1RhcmdldC5idXNpbmVzc09iamVjdCxcbiAgICAgICAgb2xkVGFyZ2V0ID0gY29udGV4dC5vbGRUYXJnZXQgfHwgY29udGV4dC50YXJnZXQsXG4gICAgICAgIG9sZFRhcmdldEJvID0gb2xkVGFyZ2V0ICYmIG9sZFRhcmdldC5idXNpbmVzc09iamVjdDtcblxuICAgIHZhciBkYXRhQXNzb2NpYXRpb24gPSBjb25uZWN0aW9uLmJ1c2luZXNzT2JqZWN0LFxuICAgICAgICB0YXJnZXRSZWZQcm9wO1xuXG4gICAgaWYgKG9sZFRhcmdldEJvICYmIG9sZFRhcmdldEJvICE9PSB0YXJnZXRCbykge1xuICAgICAgY2xlYW51cFRhcmdldFJlZihvbGRUYXJnZXRCbywgY29ubmVjdGlvbkJvKTtcbiAgICB9XG5cbiAgICBpZiAobmV3VGFyZ2V0Qm8gJiYgbmV3VGFyZ2V0Qm8gIT09IHRhcmdldEJvKSB7XG4gICAgICBjbGVhbnVwVGFyZ2V0UmVmKG5ld1RhcmdldEJvLCBjb25uZWN0aW9uQm8pO1xuICAgIH1cblxuICAgIGlmICh0YXJnZXRCbykge1xuICAgICAgdGFyZ2V0UmVmUHJvcCA9IGdldFRhcmdldFJlZih0YXJnZXRCbywgdHJ1ZSk7XG4gICAgICBkYXRhQXNzb2NpYXRpb24udGFyZ2V0UmVmID0gdGFyZ2V0UmVmUHJvcDtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YUFzc29jaWF0aW9uLnRhcmdldFJlZiA9IG51bGw7XG4gICAgfVxuICB9XG59XG5cbkRhdGFJbnB1dEFzc29jaWF0aW9uQmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2JwbW5GYWN0b3J5J1xuXTtcblxuaW5oZXJpdHMoRGF0YUlucHV0QXNzb2NpYXRpb25CZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuXG4vKipcbiAqIE9ubHkgY2FsbCB0aGUgZ2l2ZW4gZnVuY3Rpb24gd2hlbiB0aGUgZXZlbnRcbiAqIHRvdWNoZXMgYSBicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uLlxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xuZnVuY3Rpb24gaWZEYXRhSW5wdXRBc3NvY2lhdGlvbihmbikge1xuXG4gIHJldHVybiBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbjtcblxuICAgIGlmIChpcyhjb25uZWN0aW9uLCAnYnBtbjpEYXRhSW5wdXRBc3NvY2lhdGlvbicpKSB7XG4gICAgICByZXR1cm4gZm4oZXZlbnQpO1xuICAgIH1cbiAgfTtcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xyXG5cclxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XHJcblxyXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcclxuXHJcbmltcG9ydCB7IGlzQW55IH0gZnJvbSAnLi4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xyXG5cclxuaW1wb3J0IFVwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlciBmcm9tICcuLi9jbWQvVXBkYXRlU2VtYW50aWNQYXJlbnRIYW5kbGVyJztcclxuXHJcblxyXG4vKipcclxuICogQlBNTiBzcGVjaWZpYyBkYXRhIHN0b3JlIGJlaGF2aW9yXHJcbiAqL1xyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEYXRhU3RvcmVCZWhhdmlvcihcclxuICAgIGNhbnZhcywgY29tbWFuZFN0YWNrLCBlbGVtZW50UmVnaXN0cnksXHJcbiAgICBldmVudEJ1cykge1xyXG5cclxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XHJcblxyXG4gIGNvbW1hbmRTdGFjay5yZWdpc3RlckhhbmRsZXIoJ2RhdGFTdG9yZS51cGRhdGVDb250YWlubWVudCcsIFVwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlcik7XHJcblxyXG4gIGZ1bmN0aW9uIGdldEZpcnN0UGFydGljaXBhbnQoKSB7XHJcbiAgICByZXR1cm4gZWxlbWVudFJlZ2lzdHJ5LmZpbHRlcihmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpO1xyXG4gICAgfSlbMF07XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBnZXREYXRhU3RvcmVzKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBlbGVtZW50LmNoaWxkcmVuLmZpbHRlcihmdW5jdGlvbihjaGlsZCkge1xyXG4gICAgICByZXR1cm4gaXMoY2hpbGQsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpICYmICFjaGlsZC5sYWJlbFRhcmdldDtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlRGF0YVN0b3JlUGFyZW50KGRhdGFTdG9yZSwgbmV3RGF0YVN0b3JlUGFyZW50KSB7XHJcbiAgICB2YXIgZGF0YVN0b3JlQm8gPSBkYXRhU3RvcmUuYnVzaW5lc3NPYmplY3QgfHwgZGF0YVN0b3JlO1xyXG5cclxuICAgIG5ld0RhdGFTdG9yZVBhcmVudCA9IG5ld0RhdGFTdG9yZVBhcmVudCB8fCBnZXRGaXJzdFBhcnRpY2lwYW50KCk7XHJcblxyXG4gICAgaWYgKG5ld0RhdGFTdG9yZVBhcmVudCkge1xyXG4gICAgICB2YXIgbmV3RGF0YVN0b3JlUGFyZW50Qm8gPSBuZXdEYXRhU3RvcmVQYXJlbnQuYnVzaW5lc3NPYmplY3QgfHwgbmV3RGF0YVN0b3JlUGFyZW50O1xyXG5cclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2RhdGFTdG9yZS51cGRhdGVDb250YWlubWVudCcsIHtcclxuICAgICAgICBkYXRhU3RvcmVCbzogZGF0YVN0b3JlQm8sXHJcbiAgICAgICAgbmV3U2VtYW50aWNQYXJlbnQ6IG5ld0RhdGFTdG9yZVBhcmVudEJvLnByb2Nlc3NSZWYgfHwgbmV3RGF0YVN0b3JlUGFyZW50Qm8sXHJcbiAgICAgICAgbmV3RGlQYXJlbnQ6IG5ld0RhdGFTdG9yZVBhcmVudEJvLmRpXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcblxyXG4gIC8vIGRpc2FibGUgYXV0by1yZXNpemUgZm9yIGRhdGEgc3RvcmVzXHJcbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xyXG5cclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XHJcblxyXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSAmJlxyXG4gICAgICAgIHNoYXBlLnR5cGUgIT09ICdsYWJlbCcpIHtcclxuXHJcbiAgICAgIGlmICghY29udGV4dC5oaW50cykge1xyXG4gICAgICAgIGNvbnRleHQuaGludHMgPSB7fTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gcHJldmVudCBhdXRvIHJlc2l6aW5nXHJcbiAgICAgIGNvbnRleHQuaGludHMuYXV0b1Jlc2l6ZSA9IGZhbHNlO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgLy8gZGlzYWJsZSBhdXRvLXJlc2l6ZSBmb3IgZGF0YSBzdG9yZXNcclxuICB0aGlzLnByZUV4ZWN1dGUoJ2VsZW1lbnRzLm1vdmUnLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzO1xyXG5cclxuICAgIHZhciBkYXRhU3RvcmVSZWZlcmVuY2VzID0gc2hhcGVzLmZpbHRlcihmdW5jdGlvbihzaGFwZSkge1xyXG4gICAgICByZXR1cm4gaXMoc2hhcGUsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKGRhdGFTdG9yZVJlZmVyZW5jZXMubGVuZ3RoKSB7XHJcbiAgICAgIGlmICghY29udGV4dC5oaW50cykge1xyXG4gICAgICAgIGNvbnRleHQuaGludHMgPSB7fTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gcHJldmVudCBhdXRvIHJlc2l6aW5nIGZvciBkYXRhIHN0b3JlIHJlZmVyZW5jZXNcclxuICAgICAgY29udGV4dC5oaW50cy5hdXRvUmVzaXplID0gc2hhcGVzLmZpbHRlcihmdW5jdGlvbihzaGFwZSkge1xyXG4gICAgICAgIHJldHVybiAhaXMoc2hhcGUsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9KTtcclxuXHJcblxyXG4gIC8vIHVwZGF0ZSBwYXJlbnQgb24gZGF0YSBzdG9yZSBjcmVhdGVkXHJcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUuY3JlYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXHJcbiAgICAgICAgcGFyZW50ID0gc2hhcGUucGFyZW50O1xyXG5cclxuXHJcbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpICYmXHJcbiAgICAgICAgc2hhcGUudHlwZSAhPT0gJ2xhYmVsJyAmJlxyXG4gICAgICAgIGlzKHBhcmVudCwgJ2JwbW46Q29sbGFib3JhdGlvbicpKSB7XHJcblxyXG4gICAgICB1cGRhdGVEYXRhU3RvcmVQYXJlbnQoc2hhcGUpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgLy8gdXBkYXRlIHBhcmVudCBvbiBkYXRhIHN0b3JlIG1vdmVkXHJcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxyXG4gICAgICAgIG9sZFBhcmVudCA9IGNvbnRleHQub2xkUGFyZW50LFxyXG4gICAgICAgIHBhcmVudCA9IHNoYXBlLnBhcmVudDtcclxuXHJcbiAgICBpZiAoaXMob2xkUGFyZW50LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykpIHtcclxuXHJcbiAgICAgIC8vIGRvIG5vdGhpbmcgaWYgbm90IG5lY2Vzc2FyeVxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSAmJlxyXG4gICAgICAgIHNoYXBlLnR5cGUgIT09ICdsYWJlbCcgJiZcclxuICAgICAgICBpcyhwYXJlbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKSkge1xyXG5cclxuICAgICAgdmFyIHBhcnRpY2lwYW50ID0gaXMob2xkUGFyZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpID9cclxuICAgICAgICBvbGRQYXJlbnQgOlxyXG4gICAgICAgIGdldEFuY2VzdG9yKG9sZFBhcmVudCwgJ2JwbW46UGFydGljaXBhbnQnKTtcclxuXHJcbiAgICAgIHVwZGF0ZURhdGFTdG9yZVBhcmVudChzaGFwZSwgcGFydGljaXBhbnQpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgLy8gdXBkYXRlIGRhdGEgc3RvcmUgcGFyZW50cyBvbiBwYXJ0aWNpcGFudCBvciBzdWJwcm9jZXNzIGRlbGV0ZWRcclxuICB0aGlzLnBvc3RFeGVjdXRlKCdzaGFwZS5kZWxldGUnLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcclxuICAgICAgICByb290RWxlbWVudCA9IGNhbnZhcy5nZXRSb290RWxlbWVudCgpO1xyXG5cclxuICAgIGlmIChpc0FueShzaGFwZSwgWyAnYnBtbjpQYXJ0aWNpcGFudCcsICdicG1uOlN1YlByb2Nlc3MnIF0pXHJcbiAgICAgICAgJiYgaXMocm9vdEVsZW1lbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKSkge1xyXG4gICAgICBnZXREYXRhU3RvcmVzKHJvb3RFbGVtZW50KVxyXG4gICAgICAgIC5maWx0ZXIoZnVuY3Rpb24oZGF0YVN0b3JlKSB7XHJcbiAgICAgICAgICByZXR1cm4gaXNEZXNjZW5kYW50KGRhdGFTdG9yZSwgc2hhcGUpO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmZvckVhY2goZnVuY3Rpb24oZGF0YVN0b3JlKSB7XHJcbiAgICAgICAgICB1cGRhdGVEYXRhU3RvcmVQYXJlbnQoZGF0YVN0b3JlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gdXBkYXRlIGRhdGEgc3RvcmUgcGFyZW50cyBvbiBjb2xsYWJvcmF0aW9uIC0+IHByb2Nlc3NcclxuICB0aGlzLnBvc3RFeGVjdXRlKCdjYW52YXMudXBkYXRlUm9vdCcsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgb2xkUm9vdCA9IGNvbnRleHQub2xkUm9vdCxcclxuICAgICAgICBuZXdSb290ID0gY29udGV4dC5uZXdSb290O1xyXG5cclxuICAgIHZhciBkYXRhU3RvcmVzID0gZ2V0RGF0YVN0b3JlcyhvbGRSb290KTtcclxuXHJcbiAgICBkYXRhU3RvcmVzLmZvckVhY2goZnVuY3Rpb24oZGF0YVN0b3JlKSB7XHJcblxyXG4gICAgICBpZiAoaXMobmV3Um9vdCwgJ2JwbW46UHJvY2VzcycpKSB7XHJcbiAgICAgICAgdXBkYXRlRGF0YVN0b3JlUGFyZW50KGRhdGFTdG9yZSwgbmV3Um9vdCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICB9KTtcclxuICB9KTtcclxufVxyXG5cclxuRGF0YVN0b3JlQmVoYXZpb3IuJGluamVjdCA9IFtcclxuICAnY2FudmFzJyxcclxuICAnY29tbWFuZFN0YWNrJyxcclxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcclxuICAnZXZlbnRCdXMnLFxyXG5dO1xyXG5cclxuaW5oZXJpdHMoRGF0YVN0b3JlQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XHJcblxyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBpc0Rlc2NlbmRhbnQoZGVzY2VuZGFudCwgYW5jZXN0b3IpIHtcclxuICB2YXIgZGVzY2VuZGFudEJvID0gZGVzY2VuZGFudC5idXNpbmVzc09iamVjdCB8fCBkZXNjZW5kYW50LFxyXG4gICAgICBhbmNlc3RvckJvID0gYW5jZXN0b3IuYnVzaW5lc3NPYmplY3QgfHwgYW5jZXN0b3I7XHJcblxyXG4gIHdoaWxlIChkZXNjZW5kYW50Qm8uJHBhcmVudCkge1xyXG4gICAgaWYgKGRlc2NlbmRhbnRCby4kcGFyZW50ID09PSBhbmNlc3RvckJvLnByb2Nlc3NSZWYgfHwgYW5jZXN0b3JCbykge1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBkZXNjZW5kYW50Qm8gPSBkZXNjZW5kYW50Qm8uJHBhcmVudDtcclxuICB9XHJcblxyXG4gIHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0QW5jZXN0b3IoZWxlbWVudCwgdHlwZSkge1xyXG5cclxuICB3aGlsZSAoZWxlbWVudC5wYXJlbnQpIHtcclxuICAgIGlmIChpcyhlbGVtZW50LnBhcmVudCwgdHlwZSkpIHtcclxuICAgICAgcmV0dXJuIGVsZW1lbnQucGFyZW50O1xyXG4gICAgfVxyXG5cclxuICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudDtcclxuICB9XHJcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldENoaWxkTGFuZXNcbn0gZnJvbSAnLi4vdXRpbC9MYW5lVXRpbCc7XG5cbmltcG9ydCB7XG4gIGVhY2hFbGVtZW50XG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvRWxlbWVudHMnO1xuXG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cblxuLyoqXG4gKiBCUE1OIHNwZWNpZmljIGRlbGV0ZSBsYW5lIGJlaGF2aW9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERlbGV0ZUxhbmVCZWhhdmlvcihldmVudEJ1cywgbW9kZWxpbmcsIHNwYWNlVG9vbCkge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuXG4gIGZ1bmN0aW9uIGNvbXBlbnNhdGVMYW5lRGVsZXRlKHNoYXBlLCBvbGRQYXJlbnQpIHtcblxuICAgIHZhciBzaWJsaW5ncyA9IGdldENoaWxkTGFuZXMob2xkUGFyZW50KTtcblxuICAgIHZhciB0b3BBZmZlY3RlZCA9IFtdO1xuICAgIHZhciBib3R0b21BZmZlY3RlZCA9IFtdO1xuXG4gICAgZWFjaEVsZW1lbnQoc2libGluZ3MsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICAgICAgaWYgKGVsZW1lbnQueSA+IHNoYXBlLnkpIHtcbiAgICAgICAgYm90dG9tQWZmZWN0ZWQucHVzaChlbGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRvcEFmZmVjdGVkLnB1c2goZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlbGVtZW50LmNoaWxkcmVuO1xuICAgIH0pO1xuXG4gICAgaWYgKCFzaWJsaW5ncy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgb2Zmc2V0O1xuXG4gICAgaWYgKGJvdHRvbUFmZmVjdGVkLmxlbmd0aCAmJiB0b3BBZmZlY3RlZC5sZW5ndGgpIHtcbiAgICAgIG9mZnNldCA9IHNoYXBlLmhlaWdodCAvIDI7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9mZnNldCA9IHNoYXBlLmhlaWdodDtcbiAgICB9XG5cbiAgICB2YXIgdG9wQWRqdXN0bWVudHMsXG4gICAgICAgIGJvdHRvbUFkanVzdG1lbnRzO1xuXG4gICAgaWYgKHRvcEFmZmVjdGVkLmxlbmd0aCkge1xuICAgICAgdG9wQWRqdXN0bWVudHMgPSBzcGFjZVRvb2wuY2FsY3VsYXRlQWRqdXN0bWVudHMoXG4gICAgICAgIHRvcEFmZmVjdGVkLCAneScsIG9mZnNldCwgc2hhcGUueSAtIDEwKTtcblxuICAgICAgc3BhY2VUb29sLm1ha2VTcGFjZShcbiAgICAgICAgdG9wQWRqdXN0bWVudHMubW92aW5nU2hhcGVzLFxuICAgICAgICB0b3BBZGp1c3RtZW50cy5yZXNpemluZ1NoYXBlcyxcbiAgICAgICAgeyB4OiAwLCB5OiBvZmZzZXQgfSwgJ3MnKTtcbiAgICB9XG5cbiAgICBpZiAoYm90dG9tQWZmZWN0ZWQubGVuZ3RoKSB7XG4gICAgICBib3R0b21BZGp1c3RtZW50cyA9IHNwYWNlVG9vbC5jYWxjdWxhdGVBZGp1c3RtZW50cyhcbiAgICAgICAgYm90dG9tQWZmZWN0ZWQsICd5JywgLW9mZnNldCwgc2hhcGUueSArIHNoYXBlLmhlaWdodCArIDEwKTtcblxuICAgICAgc3BhY2VUb29sLm1ha2VTcGFjZShcbiAgICAgICAgYm90dG9tQWRqdXN0bWVudHMubW92aW5nU2hhcGVzLFxuICAgICAgICBib3R0b21BZGp1c3RtZW50cy5yZXNpemluZ1NoYXBlcyxcbiAgICAgICAgeyB4OiAwLCB5OiAtb2Zmc2V0IH0sICduJyk7XG4gICAgfVxuICB9XG5cblxuICAvKipcbiAgICogQWRqdXN0IHNpemVzIG9mIG90aGVyIGxhbmVzIGFmdGVyIGxhbmUgZGVsZXRpb25cbiAgICovXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdzaGFwZS5kZWxldGUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBvbGRQYXJlbnQgPSBjb250ZXh0Lm9sZFBhcmVudDtcblxuICAgIC8vIG9ubHkgY29tcGVuc2F0ZSBsYW5lIGRlbGV0ZXNcbiAgICBpZiAoIWlzKHNoYXBlLCAnYnBtbjpMYW5lJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBjb21wZW5zYXRlIHJvb3QgZGVsZXRlcyBvbmx5XG4gICAgaWYgKGhpbnRzICYmIGhpbnRzLm5lc3RlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbXBlbnNhdGVMYW5lRGVsZXRlKHNoYXBlLCBvbGRQYXJlbnQpO1xuICB9KTtcbn1cblxuRGVsZXRlTGFuZUJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZycsXG4gICdzcGFjZVRvb2wnXG5dO1xuXG5pbmhlcml0cyhEZWxldGVMYW5lQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7IGlzTGFiZWwgfSBmcm9tICcuLi8uLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cblxuLyoqXG4gKiBSZXBsYWNlIGJvdW5kYXJ5IGV2ZW50IHdpdGggaW50ZXJtZWRpYXRlIGV2ZW50IHdoZW4gY3JlYXRpbmcgb3IgbW92aW5nIHJlc3VsdHMgaW4gZGV0YWNoZWQgZXZlbnQuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERldGFjaEV2ZW50QmVoYXZpb3IoYnBtblJlcGxhY2UsIGluamVjdG9yKSB7XG4gIGluamVjdG9yLmludm9rZShDb21tYW5kSW50ZXJjZXB0b3IsIHRoaXMpO1xuXG4gIHRoaXMuX2JwbW5SZXBsYWNlID0gYnBtblJlcGxhY2U7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdlbGVtZW50cy5jcmVhdGUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzO1xuXG4gICAgZWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICB2YXIgaG9zdCA9IHNoYXBlLmhvc3Q7XG5cbiAgICAgIHJldHVybiBzaG91bGRSZXBsYWNlKHNoYXBlLCBob3N0KTtcbiAgICB9KS5tYXAoZnVuY3Rpb24oc2hhcGUpIHtcbiAgICAgIHJldHVybiBlbGVtZW50cy5pbmRleE9mKHNoYXBlKTtcbiAgICB9KS5mb3JFYWNoKGZ1bmN0aW9uKGluZGV4KSB7XG4gICAgICBjb250ZXh0LmVsZW1lbnRzWyBpbmRleCBdID0gc2VsZi5yZXBsYWNlU2hhcGUoZWxlbWVudHNbIGluZGV4IF0pO1xuICAgIH0pO1xuICB9LCB0cnVlKTtcblxuICB0aGlzLnByZUV4ZWN1dGUoJ2VsZW1lbnRzLm1vdmUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgc2hhcGVzID0gY29udGV4dC5zaGFwZXMsXG4gICAgICAgIG5ld0hvc3QgPSBjb250ZXh0Lm5ld0hvc3Q7XG5cbiAgICBzaGFwZXMuZm9yRWFjaChmdW5jdGlvbihzaGFwZSwgaW5kZXgpIHtcbiAgICAgIHZhciBob3N0ID0gc2hhcGUuaG9zdDtcblxuICAgICAgaWYgKHNob3VsZFJlcGxhY2Uoc2hhcGUsIGluY2x1ZGVzKHNoYXBlcywgaG9zdCkgPyBob3N0IDogbmV3SG9zdCkpIHtcbiAgICAgICAgc2hhcGVzWyBpbmRleCBdID0gc2VsZi5yZXBsYWNlU2hhcGUoc2hhcGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9LCB0cnVlKTtcbn1cblxuRGV0YWNoRXZlbnRCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnYnBtblJlcGxhY2UnLFxuICAnaW5qZWN0b3InXG5dO1xuXG5pbmhlcml0cyhEZXRhY2hFdmVudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5EZXRhY2hFdmVudEJlaGF2aW9yLnByb3RvdHlwZS5yZXBsYWNlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSkge1xuICB2YXIgZXZlbnREZWZpbml0aW9uID0gZ2V0RXZlbnREZWZpbml0aW9uKHNoYXBlKSxcbiAgICAgIGludGVybWVkaWF0ZUV2ZW50O1xuXG4gIGlmIChldmVudERlZmluaXRpb24pIHtcbiAgICBpbnRlcm1lZGlhdGVFdmVudCA9IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogZXZlbnREZWZpbml0aW9uLiR0eXBlXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICBpbnRlcm1lZGlhdGVFdmVudCA9IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLl9icG1uUmVwbGFjZS5yZXBsYWNlRWxlbWVudChzaGFwZSwgaW50ZXJtZWRpYXRlRXZlbnQsIHsgbGF5b3V0Q29ubmVjdGlvbjogZmFsc2UgfSk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBnZXRFdmVudERlZmluaXRpb24oZWxlbWVudCkge1xuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcbiAgICAgIGV2ZW50RGVmaW5pdGlvbnMgPSBidXNpbmVzc09iamVjdC5ldmVudERlZmluaXRpb25zO1xuXG4gIHJldHVybiBldmVudERlZmluaXRpb25zICYmIGV2ZW50RGVmaW5pdGlvbnNbMF07XG59XG5cbmZ1bmN0aW9uIHNob3VsZFJlcGxhY2Uoc2hhcGUsIGhvc3QpIHtcbiAgcmV0dXJuICFpc0xhYmVsKHNoYXBlKSAmJiBpcyhzaGFwZSwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmICFob3N0O1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlcyhhcnJheSwgaXRlbSkge1xuICByZXR1cm4gYXJyYXkuaW5kZXhPZihpdGVtKSAhPT0gLTE7XG59IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaWx0ZXIsXG4gIGZpbmQsXG4gIGlzTnVtYmVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgZ2V0TWlkIH0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHtcbiAgZ2V0QXBwcm94SW50ZXJzZWN0aW9uXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvTGluZUludGVyc2VjdGlvbic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRHJvcE9uRmxvd0JlaGF2aW9yKGV2ZW50QnVzLCBicG1uUnVsZXMsIG1vZGVsaW5nKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8qKlxuICAgKiBSZWNvbm5lY3Qgc3RhcnQgLyBlbmQgb2YgYSBjb25uZWN0aW9uIGFmdGVyXG4gICAqIGRyb3BwaW5nIGFuIGVsZW1lbnQgb24gYSBmbG93LlxuICAgKi9cblxuICBmdW5jdGlvbiBpbnNlcnRTaGFwZShzaGFwZSwgdGFyZ2V0RmxvdywgcG9zaXRpb25PckJvdW5kcykge1xuICAgIHZhciB3YXlwb2ludHMgPSB0YXJnZXRGbG93LndheXBvaW50cyxcbiAgICAgICAgd2F5cG9pbnRzQmVmb3JlLFxuICAgICAgICB3YXlwb2ludHNBZnRlcixcbiAgICAgICAgZG9ja2luZ1BvaW50LFxuICAgICAgICBzb3VyY2UsXG4gICAgICAgIHRhcmdldCxcbiAgICAgICAgaW5jb21pbmdDb25uZWN0aW9uLFxuICAgICAgICBvdXRnb2luZ0Nvbm5lY3Rpb24sXG4gICAgICAgIG9sZE91dGdvaW5nID0gc2hhcGUub3V0Z29pbmcuc2xpY2UoKSxcbiAgICAgICAgb2xkSW5jb21pbmcgPSBzaGFwZS5pbmNvbWluZy5zbGljZSgpO1xuXG4gICAgdmFyIG1pZDtcblxuICAgIGlmIChpc051bWJlcihwb3NpdGlvbk9yQm91bmRzLndpZHRoKSkge1xuICAgICAgbWlkID0gZ2V0TWlkKHBvc2l0aW9uT3JCb3VuZHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBtaWQgPSBwb3NpdGlvbk9yQm91bmRzO1xuICAgIH1cblxuICAgIHZhciBpbnRlcnNlY3Rpb24gPSBnZXRBcHByb3hJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCBtaWQpO1xuXG4gICAgaWYgKGludGVyc2VjdGlvbikge1xuICAgICAgd2F5cG9pbnRzQmVmb3JlID0gd2F5cG9pbnRzLnNsaWNlKDAsIGludGVyc2VjdGlvbi5pbmRleCk7XG4gICAgICB3YXlwb2ludHNBZnRlciA9IHdheXBvaW50cy5zbGljZShpbnRlcnNlY3Rpb24uaW5kZXggKyAoaW50ZXJzZWN0aW9uLmJlbmRwb2ludCA/IDEgOiAwKSk7XG5cbiAgICAgIC8vIGR1ZSB0byBpbmFjY3VyYWN5IGludGVyc2VjdGlvbiBtaWdodCBoYXZlIGJlZW4gZm91bmRcbiAgICAgIGlmICghd2F5cG9pbnRzQmVmb3JlLmxlbmd0aCB8fCAhd2F5cG9pbnRzQWZ0ZXIubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgZG9ja2luZ1BvaW50ID0gaW50ZXJzZWN0aW9uLmJlbmRwb2ludCA/IHdheXBvaW50c1tpbnRlcnNlY3Rpb24uaW5kZXhdIDogbWlkO1xuXG4gICAgICAvLyBpZiBsYXN0IHdheXBvaW50QmVmb3JlIGlzIGluc2lkZSBzaGFwZSdzIGJvdW5kcywgaWdub3JlIGRvY2tpbmcgcG9pbnRcbiAgICAgIGlmICghaXNQb2ludEluc2lkZUJCb3goc2hhcGUsIHdheXBvaW50c0JlZm9yZVt3YXlwb2ludHNCZWZvcmUubGVuZ3RoLTFdKSkge1xuICAgICAgICB3YXlwb2ludHNCZWZvcmUucHVzaChjb3B5KGRvY2tpbmdQb2ludCkpO1xuICAgICAgfVxuXG4gICAgICAvLyBpZiBmaXJzdCB3YXlwb2ludEFmdGVyIGlzIGluc2lkZSBzaGFwZSdzIGJvdW5kcywgaWdub3JlIGRvY2tpbmcgcG9pbnRcbiAgICAgIGlmICghaXNQb2ludEluc2lkZUJCb3goc2hhcGUsIHdheXBvaW50c0FmdGVyWzBdKSkge1xuICAgICAgICB3YXlwb2ludHNBZnRlci51bnNoaWZ0KGNvcHkoZG9ja2luZ1BvaW50KSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc291cmNlID0gdGFyZ2V0Rmxvdy5zb3VyY2U7XG4gICAgdGFyZ2V0ID0gdGFyZ2V0Rmxvdy50YXJnZXQ7XG5cbiAgICBpZiAoYnBtblJ1bGVzLmNhbkNvbm5lY3Qoc291cmNlLCBzaGFwZSwgdGFyZ2V0RmxvdykpIHtcblxuICAgICAgLy8gcmVjb25uZWN0IHNvdXJjZSAtPiBpbnNlcnRlZCBzaGFwZVxuICAgICAgbW9kZWxpbmcucmVjb25uZWN0RW5kKHRhcmdldEZsb3csIHNoYXBlLCB3YXlwb2ludHNCZWZvcmUgfHwgbWlkKTtcblxuICAgICAgaW5jb21pbmdDb25uZWN0aW9uID0gdGFyZ2V0RmxvdztcbiAgICB9XG5cbiAgICBpZiAoYnBtblJ1bGVzLmNhbkNvbm5lY3Qoc2hhcGUsIHRhcmdldCwgdGFyZ2V0RmxvdykpIHtcblxuICAgICAgaWYgKCFpbmNvbWluZ0Nvbm5lY3Rpb24pIHtcblxuICAgICAgICAvLyByZWNvbm5lY3QgaW5zZXJ0ZWQgc2hhcGUgLT4gZW5kXG4gICAgICAgIG1vZGVsaW5nLnJlY29ubmVjdFN0YXJ0KHRhcmdldEZsb3csIHNoYXBlLCB3YXlwb2ludHNBZnRlciB8fCBtaWQpO1xuXG4gICAgICAgIG91dGdvaW5nQ29ubmVjdGlvbiA9IHRhcmdldEZsb3c7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBvdXRnb2luZ0Nvbm5lY3Rpb24gPSBtb2RlbGluZy5jb25uZWN0KFxuICAgICAgICAgIHNoYXBlLCB0YXJnZXQsIHsgdHlwZTogdGFyZ2V0Rmxvdy50eXBlLCB3YXlwb2ludHM6IHdheXBvaW50c0FmdGVyIH1cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgZHVwbGljYXRlQ29ubmVjdGlvbnMgPSBbXS5jb25jYXQoXG5cbiAgICAgIGluY29taW5nQ29ubmVjdGlvbiAmJiBmaWx0ZXIob2xkSW5jb21pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb24uc291cmNlID09PSBpbmNvbWluZ0Nvbm5lY3Rpb24uc291cmNlO1xuICAgICAgfSkgfHwgW10sXG5cbiAgICAgIG91dGdvaW5nQ29ubmVjdGlvbiAmJiBmaWx0ZXIob2xkT3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgcmV0dXJuIGNvbm5lY3Rpb24udGFyZ2V0ID09PSBvdXRnb2luZ0Nvbm5lY3Rpb24udGFyZ2V0O1xuICAgICAgfSkgfHwgW11cbiAgICApO1xuXG4gICAgaWYgKGR1cGxpY2F0ZUNvbm5lY3Rpb25zLmxlbmd0aCkge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlRWxlbWVudHMoZHVwbGljYXRlQ29ubmVjdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMucHJlRXhlY3V0ZSgnZWxlbWVudHMubW92ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBuZXdQYXJlbnQgPSBjb250ZXh0Lm5ld1BhcmVudCxcbiAgICAgICAgc2hhcGVzID0gY29udGV4dC5zaGFwZXMsXG4gICAgICAgIGRlbHRhID0gY29udGV4dC5kZWx0YSxcbiAgICAgICAgc2hhcGUgPSBzaGFwZXNbMF07XG5cbiAgICBpZiAoIXNoYXBlIHx8ICFuZXdQYXJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBpZiB0aGUgbmV3IHBhcmVudCBpcyBhIGNvbm5lY3Rpb24sXG4gICAgLy8gY2hhbmdlIGl0IHRvIHRoZSBuZXcgcGFyZW50J3MgcGFyZW50XG4gICAgaWYgKG5ld1BhcmVudCAmJiBuZXdQYXJlbnQud2F5cG9pbnRzKSB7XG4gICAgICBjb250ZXh0Lm5ld1BhcmVudCA9IG5ld1BhcmVudCA9IG5ld1BhcmVudC5wYXJlbnQ7XG4gICAgfVxuXG4gICAgdmFyIHNoYXBlTWlkID0gZ2V0TWlkKHNoYXBlKTtcbiAgICB2YXIgbmV3U2hhcGVNaWQgPSB7XG4gICAgICB4OiBzaGFwZU1pZC54ICsgZGVsdGEueCxcbiAgICAgIHk6IHNoYXBlTWlkLnkgKyBkZWx0YS55XG4gICAgfTtcblxuICAgIC8vIGZpbmQgYSBjb25uZWN0aW9uIHdoaWNoIGludGVyc2VjdHMgd2l0aCB0aGVcbiAgICAvLyBlbGVtZW50J3MgbWlkIHBvaW50XG4gICAgdmFyIGNvbm5lY3Rpb24gPSBmaW5kKG5ld1BhcmVudC5jaGlsZHJlbiwgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgdmFyIGNhbkluc2VydCA9IGJwbW5SdWxlcy5jYW5JbnNlcnQoc2hhcGVzLCBlbGVtZW50KTtcblxuICAgICAgcmV0dXJuIGNhbkluc2VydCAmJiBnZXRBcHByb3hJbnRlcnNlY3Rpb24oZWxlbWVudC53YXlwb2ludHMsIG5ld1NoYXBlTWlkKTtcbiAgICB9KTtcblxuICAgIGlmIChjb25uZWN0aW9uKSB7XG4gICAgICBjb250ZXh0LnRhcmdldEZsb3cgPSBjb25uZWN0aW9uO1xuICAgICAgY29udGV4dC5wb3NpdGlvbiA9IG5ld1NoYXBlTWlkO1xuICAgIH1cblxuICB9LCB0cnVlKTtcblxuICB0aGlzLnBvc3RFeGVjdXRlZCgnZWxlbWVudHMubW92ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgdGFyZ2V0RmxvdyA9IGNvbnRleHQudGFyZ2V0RmxvdyxcbiAgICAgICAgcG9zaXRpb24gPSBjb250ZXh0LnBvc2l0aW9uO1xuXG4gICAgaWYgKHRhcmdldEZsb3cpIHtcbiAgICAgIGluc2VydFNoYXBlKHNoYXBlc1swXSwgdGFyZ2V0RmxvdywgcG9zaXRpb24pO1xuICAgIH1cblxuICB9LCB0cnVlKTtcblxuICB0aGlzLnByZUV4ZWN1dGUoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBwYXJlbnQgPSBjb250ZXh0LnBhcmVudCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKGJwbW5SdWxlcy5jYW5JbnNlcnQoc2hhcGUsIHBhcmVudCkpIHtcbiAgICAgIGNvbnRleHQudGFyZ2V0RmxvdyA9IHBhcmVudDtcbiAgICAgIGNvbnRleHQucGFyZW50ID0gcGFyZW50LnBhcmVudDtcbiAgICB9XG4gIH0sIHRydWUpO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICB0YXJnZXRGbG93ID0gY29udGV4dC50YXJnZXRGbG93LFxuICAgICAgICBwb3NpdGlvbk9yQm91bmRzID0gY29udGV4dC5wb3NpdGlvbjtcblxuICAgIGlmICh0YXJnZXRGbG93KSB7XG4gICAgICBpbnNlcnRTaGFwZShzaGFwZSwgdGFyZ2V0RmxvdywgcG9zaXRpb25PckJvdW5kcyk7XG4gICAgfVxuICB9LCB0cnVlKTtcbn1cblxuaW5oZXJpdHMoRHJvcE9uRmxvd0JlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5Ecm9wT25GbG93QmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2JwbW5SdWxlcycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNQb2ludEluc2lkZUJCb3goYmJveCwgcG9pbnQpIHtcbiAgdmFyIHggPSBwb2ludC54LFxuICAgICAgeSA9IHBvaW50Lnk7XG5cbiAgcmV0dXJuIHggPj0gYmJveC54ICYmXG4gICAgeCA8PSBiYm94LnggKyBiYm94LndpZHRoICYmXG4gICAgeSA+PSBiYm94LnkgJiZcbiAgICB5IDw9IGJib3gueSArIGJib3guaGVpZ2h0O1xufVxuXG5mdW5jdGlvbiBjb3B5KG9iaikge1xuICByZXR1cm4gYXNzaWduKHt9LCBvYmopO1xufVxuXG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEV2ZW50QmFzZWRHYXRld2F5QmVoYXZpb3IoZXZlbnRCdXMsIG1vZGVsaW5nKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8qKlxuICAgKiBSZW1vdmUgZXhpc3Rpbmcgc2VxdWVuY2UgZmxvd3Mgb2YgZXZlbnQtYmFzZWQgdGFyZ2V0IGJlZm9yZSBjb25uZWN0aW5nXG4gICAqIGZyb20gZXZlbnQtYmFzZWQgZ2F0ZXdheS5cbiAgICovXG4gIHRoaXMucHJlRXhlY3V0ZWQoJ2Nvbm5lY3Rpb24uY3JlYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICBleGlzdGluZ0luY29taW5nQ29ubmVjdGlvbnMgPSB0YXJnZXQuaW5jb21pbmcuc2xpY2UoKTtcblxuICAgIGlmIChjb250ZXh0LmhpbnRzICYmIGNvbnRleHQuaGludHMuY3JlYXRlRWxlbWVudHNCZWhhdmlvciA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoXG4gICAgICBpcyhzb3VyY2UsICdicG1uOkV2ZW50QmFzZWRHYXRld2F5JykgJiZcbiAgICAgIHRhcmdldC5pbmNvbWluZy5sZW5ndGhcbiAgICApIHtcblxuICAgICAgZXhpc3RpbmdJbmNvbWluZ0Nvbm5lY3Rpb25zLmZpbHRlcihpc1NlcXVlbmNlRmxvdylcbiAgICAgICAgLmZvckVhY2goZnVuY3Rpb24oc2VxdWVuY2VGbG93KSB7XG4gICAgICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihzZXF1ZW5jZUZsb3cpO1xuICAgICAgICB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiAgQWZ0ZXIgcmVwbGFjaW5nIHNoYXBlIHdpdGggZXZlbnQtYmFzZWQgZ2F0ZXdheSwgcmVtb3ZlIGluY29taW5nIHNlcXVlbmNlXG4gICAqICBmbG93cyBvZiBldmVudC1iYXNlZCB0YXJnZXRzIHdoaWNoIGRvIG5vdCBiZWxvbmcgdG8gZXZlbnQtYmFzZWQgZ2F0ZXdheVxuICAgKiAgc291cmNlLlxuICAgKi9cbiAgdGhpcy5wcmVFeGVjdXRlZCgnc2hhcGUucmVwbGFjZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgbmV3U2hhcGUgPSBldmVudC5jb250ZXh0Lm5ld1NoYXBlLFxuICAgICAgICBuZXdTaGFwZVRhcmdldHMsXG4gICAgICAgIG5ld1NoYXBlVGFyZ2V0c0luY29taW5nU2VxdWVuY2VGbG93cztcblxuICAgIGlmICghaXMobmV3U2hhcGUsICdicG1uOkV2ZW50QmFzZWRHYXRld2F5JykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXdTaGFwZVRhcmdldHMgPSBuZXdTaGFwZS5vdXRnb2luZy5maWx0ZXIoaXNTZXF1ZW5jZUZsb3cpXG4gICAgICAubWFwKGZ1bmN0aW9uKHNlcXVlbmNlRmxvdykge1xuICAgICAgICByZXR1cm4gc2VxdWVuY2VGbG93LnRhcmdldDtcbiAgICAgIH0pO1xuXG4gICAgbmV3U2hhcGVUYXJnZXRzSW5jb21pbmdTZXF1ZW5jZUZsb3dzID0gbmV3U2hhcGVUYXJnZXRzLnJlZHVjZShmdW5jdGlvbihzZXF1ZW5jZUZsb3dzLCB0YXJnZXQpIHtcbiAgICAgIHZhciBpbmNvbWluZ1NlcXVlbmNlRmxvd3MgPSB0YXJnZXQuaW5jb21pbmcuZmlsdGVyKGlzU2VxdWVuY2VGbG93KTtcblxuICAgICAgcmV0dXJuIHNlcXVlbmNlRmxvd3MuY29uY2F0KGluY29taW5nU2VxdWVuY2VGbG93cyk7XG4gICAgfSwgW10pO1xuXG4gICAgbmV3U2hhcGVUYXJnZXRzSW5jb21pbmdTZXF1ZW5jZUZsb3dzLmZvckVhY2goZnVuY3Rpb24oc2VxdWVuY2VGbG93KSB7XG4gICAgICBpZiAoc2VxdWVuY2VGbG93LnNvdXJjZSAhPT0gbmV3U2hhcGUpIHtcbiAgICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihzZXF1ZW5jZUZsb3cpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuRXZlbnRCYXNlZEdhdGV3YXlCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnbW9kZWxpbmcnXG5dO1xuXG5pbmhlcml0cyhFdmVudEJhc2VkR2F0ZXdheUJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGlzU2VxdWVuY2VGbG93KGNvbm5lY3Rpb24pIHtcbiAgcmV0dXJuIGlzKGNvbm5lY3Rpb24sICdicG1uOlNlcXVlbmNlRmxvdycpO1xufVxuIiwiaW1wb3J0IHsgZ2V0TGFuZXNSb290IH0gZnJvbSAnLi4vdXRpbC9MYW5lVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcclxuXHJcbmltcG9ydCB7IGlzQW55IH0gZnJvbSAnLi4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xyXG5cclxudmFyIEhJR0hfUFJJT1JJVFkgPSAxNTAwO1xyXG52YXIgSElHSEVTVF9QUklPUklUWSA9IDIwMDA7XHJcblxyXG5cclxuLyoqXHJcbiAqIENvcnJlY3QgaG92ZXIgdGFyZ2V0cyBpbiBjZXJ0YWluIHNpdHVhdGlvbnMgdG8gaW1wcm92ZSBkaWFncmFtIGludGVyYWN0aW9uLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XHJcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXHJcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEZpeEhvdmVyQmVoYXZpb3IoZWxlbWVudFJlZ2lzdHJ5LCBldmVudEJ1cywgY2FudmFzKSB7XHJcblxyXG4gIGV2ZW50QnVzLm9uKFtcclxuICAgICdjcmVhdGUuaG92ZXInLFxyXG4gICAgJ2NyZWF0ZS5tb3ZlJyxcclxuICAgICdjcmVhdGUuZW5kJyxcclxuICAgICdzaGFwZS5tb3ZlLmhvdmVyJyxcclxuICAgICdzaGFwZS5tb3ZlLm1vdmUnLFxyXG4gICAgJ3NoYXBlLm1vdmUuZW5kJ1xyXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlIHx8IGV2ZW50LnNoYXBlLFxyXG4gICAgICAgIGhvdmVyID0gZXZlbnQuaG92ZXI7XHJcblxyXG4gICAgLy8gZW5zdXJlIGVsZW1lbnRzIGFyZSBub3QgZHJvcHBlZCBvbnRvIGEgYnBtbjpMYW5lIGJ1dCBvbnRvXHJcbiAgICAvLyB0aGUgdW5kZXJseWluZyBicG1uOlBhcnRpY2lwYW50XHJcbiAgICBpZiAoaXMoaG92ZXIsICdicG1uOkxhbmUnKSAmJiAhaXNBbnkoc2hhcGUsIFsgJ2JwbW46TGFuZScsICdicG1uOlBhcnRpY2lwYW50JyBdKSkge1xyXG4gICAgICBldmVudC5ob3ZlciA9IGdldExhbmVzUm9vdChob3Zlcik7XHJcbiAgICAgIGV2ZW50LmhvdmVyR2Z4ID0gZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGV2ZW50LmhvdmVyKTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKTtcclxuXHJcbiAgICAvLyBlbnN1cmUgYnBtbjpHcm91cCBhbmQgbGFiZWwgZWxlbWVudHMgYXJlIGRyb3BwZWRcclxuICAgIC8vIGFsd2F5cyBvbnRvIHRoZSByb290XHJcbiAgICBpZiAoaG92ZXIgIT09IHJvb3RFbGVtZW50ICYmIChzaGFwZS5sYWJlbFRhcmdldCB8fCBpcyhzaGFwZSwgJ2JwbW46R3JvdXAnKSkpIHtcclxuICAgICAgZXZlbnQuaG92ZXIgPSByb290RWxlbWVudDtcclxuICAgICAgZXZlbnQuaG92ZXJHZnggPSBlbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZXZlbnQuaG92ZXIpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2Nvbm5lY3QuaG92ZXInLFxyXG4gICAgJ2Nvbm5lY3Qub3V0JyxcclxuICAgICdjb25uZWN0LmVuZCcsXHJcbiAgICAnY29ubmVjdC5jbGVhbnVwJyxcclxuICAgICdnbG9iYWwtY29ubmVjdC5ob3ZlcicsXHJcbiAgICAnZ2xvYmFsLWNvbm5lY3Qub3V0JyxcclxuICAgICdnbG9iYWwtY29ubmVjdC5lbmQnLFxyXG4gICAgJ2dsb2JhbC1jb25uZWN0LmNsZWFudXAnXHJcbiAgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBob3ZlciA9IGV2ZW50LmhvdmVyO1xyXG5cclxuICAgIC8vIGVuc3VyZSBjb25uZWN0aW9ucyBzdGFydC9lbmQgb24gYnBtbjpQYXJ0aWNpcGFudCxcclxuICAgIC8vIG5vdCB0aGUgdW5kZXJseWluZyBicG1uOkxhbmVcclxuICAgIGlmIChpcyhob3ZlciwgJ2JwbW46TGFuZScpKSB7XHJcbiAgICAgIGV2ZW50LmhvdmVyID0gZ2V0TGFuZXNSb290KGhvdmVyKSB8fCBob3ZlcjtcclxuICAgICAgZXZlbnQuaG92ZXJHZnggPSBlbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZXZlbnQuaG92ZXIpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2JlbmRwb2ludC5tb3ZlLmhvdmVyJ1xyXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgaG92ZXIgPSBldmVudC5ob3ZlcixcclxuICAgICAgICB0eXBlID0gY29udGV4dC50eXBlO1xyXG5cclxuICAgIC8vIGVuc3VyZSByZWNvbm5lY3Qgc3RhcnQvZW5kIG9uIGJwbW46UGFydGljaXBhbnQsXHJcbiAgICAvLyBub3QgdGhlIHVuZGVybHlpbmcgYnBtbjpMYW5lXHJcbiAgICBpZiAoaXMoaG92ZXIsICdicG1uOkxhbmUnKSAmJiAvcmVjb25uZWN0Ly50ZXN0KHR5cGUpKSB7XHJcbiAgICAgIGV2ZW50LmhvdmVyID0gZ2V0TGFuZXNSb290KGhvdmVyKSB8fCBob3ZlcjtcclxuICAgICAgZXZlbnQuaG92ZXJHZnggPSBlbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZXZlbnQuaG92ZXIpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2Nvbm5lY3Quc3RhcnQnXHJcbiAgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBzdGFydCA9IGNvbnRleHQuc3RhcnQ7XHJcblxyXG4gICAgLy8gZW5zdXJlIGNvbm5lY3Qgc3RhcnQgb24gYnBtbjpQYXJ0aWNpcGFudCxcclxuICAgIC8vIG5vdCB0aGUgdW5kZXJseWluZyBicG1uOkxhbmVcclxuICAgIGlmIChpcyhzdGFydCwgJ2JwbW46TGFuZScpKSB7XHJcbiAgICAgIGNvbnRleHQuc3RhcnQgPSBnZXRMYW5lc1Jvb3Qoc3RhcnQpIHx8IHN0YXJ0O1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgLy8gYWxsb3cgbW92ZW1lbnQgb2YgcGFydGljaXBhbnRzIGZyb20gbGFuZXNcclxuICBldmVudEJ1cy5vbignc2hhcGUubW92ZS5zdGFydCcsIEhJR0hFU1RfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgc2hhcGUgPSBldmVudC5zaGFwZTtcclxuXHJcbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkxhbmUnKSkge1xyXG4gICAgICBldmVudC5zaGFwZSA9IGdldExhbmVzUm9vdChzaGFwZSkgfHwgc2hhcGU7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG59XHJcblxyXG5GaXhIb3ZlckJlaGF2aW9yLiRpbmplY3QgPSBbXHJcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXHJcbiAgJ2V2ZW50QnVzJyxcclxuICAnY2FudmFzJ1xyXG5dOyIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5pbXBvcnQge1xuICBhZGQgYXMgY29sbGVjdGlvbkFkZCxcbiAgcmVtb3ZlIGFzIGNvbGxlY3Rpb25SZW1vdmVcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9Db2xsZWN0aW9ucyc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGNyZWF0ZUNhdGVnb3J5VmFsdWVcbn0gZnJvbSAnLi91dGlsL0NhdGVnb3J5VXRpbCc7XG5cbnZhciBISUdIX1BSSU9SSVRZID0gMjAwMDtcblxuXG4vKipcbiAqIEJQTU4gc3BlY2lmaWMgR3JvdXAgYmVoYXZpb3JcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gR3JvdXBCZWhhdmlvcihcbiAgICBicG1uRmFjdG9yeSxcbiAgICBjYW52YXMsXG4gICAgZWxlbWVudFJlZ2lzdHJ5LFxuICAgIGV2ZW50QnVzLFxuICAgIGluamVjdG9yLFxuICAgIG1vZGRsZUNvcHlcbikge1xuICBpbmplY3Rvci5pbnZva2UoQ29tbWFuZEludGVyY2VwdG9yLCB0aGlzKTtcblxuICAvKipcbiAgICogR2V0cyBwcm9jZXNzIGRlZmluaXRpb25zXG4gICAqXG4gICAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9IGRlZmluaXRpb25zXG4gICAqL1xuICBmdW5jdGlvbiBnZXREZWZpbml0aW9ucygpIHtcbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgICAgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChyb290RWxlbWVudCk7XG5cbiAgICByZXR1cm4gYnVzaW5lc3NPYmplY3QuJHBhcmVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgcmVmZXJlbmNlZCBjYXRlZ29yeSB2YWx1ZSBmb3IgYSBnaXZlbiBncm91cCBzaGFwZVxuICAgKlxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAgICovXG4gIGZ1bmN0aW9uIHJlbW92ZVJlZmVyZW5jZWRDYXRlZ29yeVZhbHVlKHNoYXBlKSB7XG5cbiAgICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChzaGFwZSksXG4gICAgICAgIGNhdGVnb3J5VmFsdWUgPSBidXNpbmVzc09iamVjdC5jYXRlZ29yeVZhbHVlUmVmO1xuXG4gICAgaWYgKCFjYXRlZ29yeVZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGNhdGVnb3J5ID0gY2F0ZWdvcnlWYWx1ZS4kcGFyZW50O1xuXG4gICAgaWYgKCFjYXRlZ29yeVZhbHVlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29sbGVjdGlvblJlbW92ZShjYXRlZ29yeS5jYXRlZ29yeVZhbHVlLCBjYXRlZ29yeVZhbHVlKTtcblxuICAgIC8vIGNsZWFudXAgY2F0ZWdvcnkgaWYgaXQgaXMgZW1wdHlcbiAgICBpZiAoY2F0ZWdvcnkgJiYgIWNhdGVnb3J5LmNhdGVnb3J5VmFsdWUubGVuZ3RoKSB7XG4gICAgICByZW1vdmVDYXRlZ29yeShjYXRlZ29yeSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgYSBnaXZlbiBjYXRlZ29yeSBmcm9tIHRoZSBkZWZpbml0aW9uc1xuICAgKlxuICAgKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGNhdGVnb3J5XG4gICAqL1xuICBmdW5jdGlvbiByZW1vdmVDYXRlZ29yeShjYXRlZ29yeSkge1xuXG4gICAgdmFyIGRlZmluaXRpb25zID0gZ2V0RGVmaW5pdGlvbnMoKTtcblxuICAgIGNvbGxlY3Rpb25SZW1vdmUoZGVmaW5pdGlvbnMuZ2V0KCdyb290RWxlbWVudHMnKSwgY2F0ZWdvcnkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYWxsIGdyb3VwIGVsZW1lbnQgaW4gdGhlIGN1cnJlbnQgcmVnaXN0cnlcbiAgICpcbiAgICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLnNoYXBlPn0gYSBsaXN0IG9mIGdyb3VwIHNoYXBlc1xuICAgKi9cbiAgZnVuY3Rpb24gZ2V0R3JvdXBFbGVtZW50cygpIHtcbiAgICByZXR1cm4gZWxlbWVudFJlZ2lzdHJ5LmZpbHRlcihmdW5jdGlvbihlKSB7XG4gICAgICByZXR1cm4gaXMoZSwgJ2JwbW46R3JvdXAnKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgaWYgZ2l2ZW4gY2F0ZWdvcnlWYWx1ZSBpcyByZWZlcmVuY2VkIGluIG9uZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudHNcbiAgICpcbiAgICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuc2hhcGU+fSBlbGVtZW50c1xuICAgKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGNhdGVnb3J5VmFsdWVcbiAgICogQHJldHVybiB7Ym9vbGVhbn1cbiAgICovXG4gIGZ1bmN0aW9uIGlzUmVmZXJlbmNlZChlbGVtZW50cywgY2F0ZWdvcnlWYWx1ZSkge1xuICAgIHJldHVybiBlbGVtZW50cy5zb21lKGZ1bmN0aW9uKGUpIHtcblxuICAgICAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZSk7XG5cbiAgICAgIHJldHVybiBidXNpbmVzc09iamVjdC5jYXRlZ29yeVZhbHVlUmVmXG4gICAgICAgICYmIGJ1c2luZXNzT2JqZWN0LmNhdGVnb3J5VmFsdWVSZWYgPT09IGNhdGVnb3J5VmFsdWU7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogcmVtb3ZlIHJlZmVyZW5jZWQgY2F0ZWdvcnkgKyB2YWx1ZSB3aGVuIGdyb3VwIHdhcyBkZWxldGVkXG4gICAqL1xuICB0aGlzLmV4ZWN1dGVkKCdzaGFwZS5kZWxldGUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkdyb3VwJykpIHtcblxuICAgICAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3Qoc2hhcGUpLFxuICAgICAgICAgIGNhdGVnb3J5VmFsdWVSZWYgPSBidXNpbmVzc09iamVjdC5jYXRlZ29yeVZhbHVlUmVmLFxuICAgICAgICAgIGdyb3VwRWxlbWVudHMgPSBnZXRHcm91cEVsZW1lbnRzKCk7XG5cbiAgICAgIGlmICghaXNSZWZlcmVuY2VkKGdyb3VwRWxlbWVudHMsIGNhdGVnb3J5VmFsdWVSZWYpKSB7XG4gICAgICAgIHJlbW92ZVJlZmVyZW5jZWRDYXRlZ29yeVZhbHVlKHNoYXBlKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiByZS1hdHRhY2ggcmVtb3ZlZCBjYXRlZ29yeVxuICAgKi9cbiAgdGhpcy5yZXZlcnRlZCgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpHcm91cCcpKSB7XG5cbiAgICAgIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KHNoYXBlKSxcbiAgICAgICAgICBjYXRlZ29yeVZhbHVlUmVmID0gYnVzaW5lc3NPYmplY3QuY2F0ZWdvcnlWYWx1ZVJlZixcbiAgICAgICAgICBkZWZpbml0aW9ucyA9IGdldERlZmluaXRpb25zKCksXG4gICAgICAgICAgY2F0ZWdvcnkgPSBjYXRlZ29yeVZhbHVlUmVmID8gY2F0ZWdvcnlWYWx1ZVJlZi4kcGFyZW50IDogbnVsbDtcblxuICAgICAgY29sbGVjdGlvbkFkZChjYXRlZ29yeS5nZXQoJ2NhdGVnb3J5VmFsdWUnKSwgY2F0ZWdvcnlWYWx1ZVJlZik7XG4gICAgICBjb2xsZWN0aW9uQWRkKGRlZmluaXRpb25zLmdldCgncm9vdEVsZW1lbnRzJyksIGNhdGVnb3J5KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBjcmVhdGUgbmV3IGNhdGVnb3J5ICsgdmFsdWUgd2hlbiBncm91cCB3YXMgY3JlYXRlZFxuICAgKi9cbiAgdGhpcy5leGVjdXRlKCdzaGFwZS5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KHNoYXBlKTtcblxuICAgIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46R3JvdXAnKSAmJiAhYnVzaW5lc3NPYmplY3QuY2F0ZWdvcnlWYWx1ZVJlZikge1xuXG4gICAgICB2YXIgZGVmaW5pdGlvbnMgPSBnZXREZWZpbml0aW9ucygpLFxuICAgICAgICAgIGNhdGVnb3J5VmFsdWUgPSBjcmVhdGVDYXRlZ29yeVZhbHVlKGRlZmluaXRpb25zLCBicG1uRmFjdG9yeSk7XG5cbiAgICAgIC8vIGxpbmsgdGhlIHJlZmVyZW5jZSB0byB0aGUgR3JvdXBcbiAgICAgIGJ1c2luZXNzT2JqZWN0LmNhdGVnb3J5VmFsdWVSZWYgPSBjYXRlZ29yeVZhbHVlO1xuICAgIH1cbiAgfSk7XG5cblxuICB0aGlzLnJldmVydCgnc2hhcGUuY3JlYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpHcm91cCcpKSB7XG4gICAgICByZW1vdmVSZWZlcmVuY2VkQ2F0ZWdvcnlWYWx1ZShzaGFwZSk7XG5cbiAgICAgIGRlbGV0ZSBnZXRCdXNpbmVzc09iamVjdChzaGFwZSkuY2F0ZWdvcnlWYWx1ZVJlZjtcblxuICAgIH1cbiAgfSk7XG5cbiAgLy8gY29weSBicG1uOkNhdGVnb3J5VmFsdWUgd2hlbiBjb3B5aW5nIGVsZW1lbnRcbiAgZXZlbnRCdXMub24oJ21vZGRsZUNvcHkuY2FuQ29weVByb3BlcnR5JywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBwcm9wZXJ0eSA9IGNvbnRleHQucHJvcGVydHksXG4gICAgICAgIGNhdGVnb3J5VmFsdWU7XG5cbiAgICBpZiAoaXMocHJvcGVydHksICdicG1uOkNhdGVnb3J5VmFsdWUnKSkge1xuICAgICAgY2F0ZWdvcnlWYWx1ZSA9IGNyZWF0ZUNhdGVnb3J5VmFsdWUoZ2V0RGVmaW5pdGlvbnMoKSwgYnBtbkZhY3RvcnkpO1xuXG4gICAgICAvLyByZXR1cm4gY29weSBvZiBjYXRlZ29yeVxuICAgICAgcmV0dXJuIG1vZGRsZUNvcHkuY29weUVsZW1lbnQocHJvcGVydHksIGNhdGVnb3J5VmFsdWUpO1xuICAgIH1cbiAgfSk7XG5cbn1cblxuR3JvdXBCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnYnBtbkZhY3RvcnknLFxuICAnY2FudmFzJyxcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXG4gICdldmVudEJ1cycsXG4gICdpbmplY3RvcicsXG4gICdtb2RkbGVDb3B5J1xuXTtcblxuaW5oZXJpdHMoR3JvdXBCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTsiLCJpbXBvcnQge1xuICBnZXRNaWRcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQgbGluZUludGVyc2VjdCBmcm9tICcuL3V0aWwvTGluZUludGVyc2VjdCc7XG5cblxuLyoqXG4gKiBGaXggYnJva2VuIGRvY2tpbmdzIGFmdGVyIERJIGltcG9ydHMuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gSW1wb3J0RG9ja2luZ0ZpeChldmVudEJ1cykge1xuXG4gIGZ1bmN0aW9uIGFkanVzdERvY2tpbmcoc3RhcnRQb2ludCwgbmV4dFBvaW50LCBlbGVtZW50TWlkKSB7XG5cbiAgICB2YXIgZWxlbWVudFRvcCA9IHtcbiAgICAgIHg6IGVsZW1lbnRNaWQueCxcbiAgICAgIHk6IGVsZW1lbnRNaWQueSAtIDUwXG4gICAgfTtcblxuICAgIHZhciBlbGVtZW50TGVmdCA9IHtcbiAgICAgIHg6IGVsZW1lbnRNaWQueCAtIDUwLFxuICAgICAgeTogZWxlbWVudE1pZC55XG4gICAgfTtcblxuICAgIHZhciB2ZXJ0aWNhbEludGVyc2VjdCA9IGxpbmVJbnRlcnNlY3Qoc3RhcnRQb2ludCwgbmV4dFBvaW50LCBlbGVtZW50TWlkLCBlbGVtZW50VG9wKSxcbiAgICAgICAgaG9yaXpvbnRhbEludGVyc2VjdCA9IGxpbmVJbnRlcnNlY3Qoc3RhcnRQb2ludCwgbmV4dFBvaW50LCBlbGVtZW50TWlkLCBlbGVtZW50TGVmdCk7XG5cbiAgICAvLyBvcmlnaW5hbCBpcyBob3Jpem9udGFsIG9yIHZlcnRpY2FsIGNlbnRlciBjcm9zcyBpbnRlcnNlY3Rpb25cbiAgICB2YXIgY2VudGVySW50ZXJzZWN0O1xuXG4gICAgaWYgKHZlcnRpY2FsSW50ZXJzZWN0ICYmIGhvcml6b250YWxJbnRlcnNlY3QpIHtcbiAgICAgIGlmIChnZXREaXN0YW5jZSh2ZXJ0aWNhbEludGVyc2VjdCwgZWxlbWVudE1pZCkgPiBnZXREaXN0YW5jZShob3Jpem9udGFsSW50ZXJzZWN0LCBlbGVtZW50TWlkKSkge1xuICAgICAgICBjZW50ZXJJbnRlcnNlY3QgPSBob3Jpem9udGFsSW50ZXJzZWN0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2VudGVySW50ZXJzZWN0ID0gdmVydGljYWxJbnRlcnNlY3Q7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNlbnRlckludGVyc2VjdCA9IHZlcnRpY2FsSW50ZXJzZWN0IHx8IGhvcml6b250YWxJbnRlcnNlY3Q7XG4gICAgfVxuXG4gICAgc3RhcnRQb2ludC5vcmlnaW5hbCA9IGNlbnRlckludGVyc2VjdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpeERvY2tpbmdzKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG5cbiAgICBhZGp1c3REb2NraW5nKFxuICAgICAgd2F5cG9pbnRzWzBdLFxuICAgICAgd2F5cG9pbnRzWzFdLFxuICAgICAgZ2V0TWlkKGNvbm5lY3Rpb24uc291cmNlKVxuICAgICk7XG5cbiAgICBhZGp1c3REb2NraW5nKFxuICAgICAgd2F5cG9pbnRzW3dheXBvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgIHdheXBvaW50c1t3YXlwb2ludHMubGVuZ3RoIC0gMl0sXG4gICAgICBnZXRNaWQoY29ubmVjdGlvbi50YXJnZXQpXG4gICAgKTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdicG1uRWxlbWVudC5hZGRlZCcsIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBlbGVtZW50ID0gZS5lbGVtZW50O1xuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICBmaXhEb2NraW5ncyhlbGVtZW50KTtcbiAgICB9XG4gIH0pO1xufVxuXG5JbXBvcnREb2NraW5nRml4LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldERpc3RhbmNlKHAxLCBwMikge1xuICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHAxLnggLSBwMi54LCAyKSArIE1hdGgucG93KHAxLnkgLSBwMi55LCAyKSk7XG59IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0XG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgaXNBbnlcbn0gZnJvbSAnLi4vdXRpbC9Nb2RlbGluZ1V0aWwnO1xuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgbWFrZXMgc3VyZSB0aGF0IGVhY2ggY3JlYXRlZCBvciB1cGRhdGVkXG4gKiBQb29sIGFuZCBMYW5lIGlzIGFzc2lnbmVkIGFuIGlzSG9yaXpvbnRhbCBwcm9wZXJ0eSBzZXQgdG8gdHJ1ZS5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBJc0hvcml6b250YWxGaXgoZXZlbnRCdXMpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdmFyIGVsZW1lbnRUeXBlc1RvVXBkYXRlID0gW1xuICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAnYnBtbjpMYW5lJ1xuICBdO1xuXG4gIHRoaXMuZXhlY3V0ZWQoWyAnc2hhcGUubW92ZScsICdzaGFwZS5jcmVhdGUnLCAnc2hhcGUucmVzaXplJyBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGV2ZW50LmNvbnRleHQuc2hhcGUpO1xuXG4gICAgaWYgKGlzQW55KGJvLCBlbGVtZW50VHlwZXNUb1VwZGF0ZSkgJiYgIWJvLmRpLmdldCgnaXNIb3Jpem9udGFsJykpIHtcblxuICAgICAgLy8gc2V0IGF0dHJpYnV0ZSBkaXJlY3RseSB0byBhdm9pZCBtb2RlbGluZyN1cGRhdGVQcm9wZXJ0eSBzaWRlIGVmZmVjdHNcbiAgICAgIGJvLmRpLnNldCgnaXNIb3Jpem9udGFsJywgdHJ1ZSk7XG4gICAgfVxuICB9KTtcblxufVxuXG5Jc0hvcml6b250YWxGaXguJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdO1xuXG5pbmhlcml0cyhJc0hvcml6b250YWxGaXgsIENvbW1hbmRJbnRlcmNlcHRvcik7XG4iLCJpbXBvcnQge1xuICBhc3NpZ25cbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQge1xuICBpcyxcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0xhYmVsRXh0ZXJuYWwsXG4gIGdldEV4dGVybmFsTGFiZWxNaWQsXG4gIGhhc0V4dGVybmFsTGFiZWwsXG4gIGlzTGFiZWxcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9MYWJlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRMYWJlbFxufSBmcm9tICcuLi8uLi9sYWJlbC1lZGl0aW5nL0xhYmVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldExhYmVsQWRqdXN0bWVudFxufSBmcm9tICcuL3V0aWwvTGFiZWxMYXlvdXRVdGlsJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldE5ld0F0dGFjaFBvaW50XG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvQXR0YWNoVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldE1pZCxcbiAgcm91bmRQb2ludFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7XG4gIGRlbHRhXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvUG9zaXRpb25VdGlsJztcblxuaW1wb3J0IHtcbiAgc29ydEJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0RGlzdGFuY2VQb2ludExpbmUsXG4gIHBlcnBlbmRpY3VsYXJGb290XG59IGZyb20gJy4vdXRpbC9HZW9tZXRyaWNVdGlsJztcblxudmFyIERFRkFVTFRfTEFCRUxfRElNRU5TSU9OUyA9IHtcbiAgd2lkdGg6IDkwLFxuICBoZWlnaHQ6IDIwXG59O1xuXG52YXIgTkFNRV9QUk9QRVJUWSA9ICduYW1lJztcbnZhciBURVhUX1BST1BFUlRZID0gJ3RleHQnO1xuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgbWFrZXMgc3VyZSB0aGF0IGV4dGVybmFsIGxhYmVscyBhcmUgYWRkZWRcbiAqIHRvZ2V0aGVyIHdpdGggcmVzcGVjdGl2ZSBlbGVtZW50cyBhbmQgcHJvcGVybHkgdXBkYXRlZCAoREkgd2lzZSlcbiAqIGR1cmluZyBtb3ZlLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcbiAqIEBwYXJhbSB7VGV4dFJlbmRlcmVyfSB0ZXh0UmVuZGVyZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGFiZWxCZWhhdmlvcihcbiAgICBldmVudEJ1cywgbW9kZWxpbmcsIGJwbW5GYWN0b3J5LFxuICAgIHRleHRSZW5kZXJlcikge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuICAvLyB1cGRhdGUgbGFiZWwgaWYgbmFtZSBwcm9wZXJ0eSB3YXMgdXBkYXRlZFxuICB0aGlzLnBvc3RFeGVjdXRlKCdlbGVtZW50LnVwZGF0ZVByb3BlcnRpZXMnLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnQgPSBjb250ZXh0LmVsZW1lbnQsXG4gICAgICAgIHByb3BlcnRpZXMgPSBjb250ZXh0LnByb3BlcnRpZXM7XG5cbiAgICBpZiAoTkFNRV9QUk9QRVJUWSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICBtb2RlbGluZy51cGRhdGVMYWJlbChlbGVtZW50LCBwcm9wZXJ0aWVzW05BTUVfUFJPUEVSVFldKTtcbiAgICB9XG5cbiAgICBpZiAoVEVYVF9QUk9QRVJUWSBpbiBwcm9wZXJ0aWVzXG4gICAgICAgICYmIGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcblxuICAgICAgdmFyIG5ld0JvdW5kcyA9IHRleHRSZW5kZXJlci5nZXRUZXh0QW5ub3RhdGlvbkJvdW5kcyhcbiAgICAgICAge1xuICAgICAgICAgIHg6IGVsZW1lbnQueCxcbiAgICAgICAgICB5OiBlbGVtZW50LnksXG4gICAgICAgICAgd2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICAgICAgICB9LFxuICAgICAgICBwcm9wZXJ0aWVzW1RFWFRfUFJPUEVSVFldIHx8ICcnXG4gICAgICApO1xuXG4gICAgICBtb2RlbGluZy51cGRhdGVMYWJlbChlbGVtZW50LCBwcm9wZXJ0aWVzLnRleHQsIG5ld0JvdW5kcyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBjcmVhdGUgbGFiZWwgc2hhcGUgYWZ0ZXIgc2hhcGUvY29ubmVjdGlvbiB3YXMgY3JlYXRlZFxuICB0aGlzLnBvc3RFeGVjdXRlKFsgJ3NoYXBlLmNyZWF0ZScsICdjb25uZWN0aW9uLmNyZWF0ZScgXSwgZnVuY3Rpb24oZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgICBpZiAoaGludHMuY3JlYXRlRWxlbWVudHNCZWhhdmlvciA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgZWxlbWVudCA9IGNvbnRleHQuc2hhcGUgfHwgY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBidXNpbmVzc09iamVjdCA9IGVsZW1lbnQuYnVzaW5lc3NPYmplY3Q7XG5cbiAgICBpZiAoaXNMYWJlbChlbGVtZW50KSB8fCAhaXNMYWJlbEV4dGVybmFsKGVsZW1lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gb25seSBjcmVhdGUgbGFiZWwgaWYgYXR0cmlidXRlIGF2YWlsYWJsZVxuICAgIGlmICghZ2V0TGFiZWwoZWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbGFiZWxDZW50ZXIgPSBnZXRFeHRlcm5hbExhYmVsTWlkKGVsZW1lbnQpO1xuXG4gICAgLy8gd2UgZG9uJ3QgY2FyZSBhYm91dCB4IGFuZCB5XG4gICAgdmFyIGxhYmVsRGltZW5zaW9ucyA9IHRleHRSZW5kZXJlci5nZXRFeHRlcm5hbExhYmVsQm91bmRzKFxuICAgICAgREVGQVVMVF9MQUJFTF9ESU1FTlNJT05TLFxuICAgICAgZ2V0TGFiZWwoZWxlbWVudClcbiAgICApO1xuXG4gICAgbW9kZWxpbmcuY3JlYXRlTGFiZWwoZWxlbWVudCwgbGFiZWxDZW50ZXIsIHtcbiAgICAgIGlkOiBidXNpbmVzc09iamVjdC5pZCArICdfbGFiZWwnLFxuICAgICAgYnVzaW5lc3NPYmplY3Q6IGJ1c2luZXNzT2JqZWN0LFxuICAgICAgd2lkdGg6IGxhYmVsRGltZW5zaW9ucy53aWR0aCxcbiAgICAgIGhlaWdodDogbGFiZWxEaW1lbnNpb25zLmhlaWdodFxuICAgIH0pO1xuICB9KTtcblxuICAvLyB1cGRhdGUgbGFiZWwgYWZ0ZXIgbGFiZWwgc2hhcGUgd2FzIGRlbGV0ZWRcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGxhYmVsVGFyZ2V0ID0gY29udGV4dC5sYWJlbFRhcmdldCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gICAgLy8gY2hlY2sgaWYgbGFiZWxcbiAgICBpZiAobGFiZWxUYXJnZXQgJiYgaGludHMudW5zZXRMYWJlbCAhPT0gZmFsc2UpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZUxhYmVsKGxhYmVsVGFyZ2V0LCBudWxsLCBudWxsLCB7IHJlbW92ZVNoYXBlOiBmYWxzZSB9KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHVwZGF0ZSBkaSBpbmZvcm1hdGlvbiBvbiBsYWJlbCBjcmVhdGlvblxuICB0aGlzLnBvc3RFeGVjdXRlKFsgJ2xhYmVsLmNyZWF0ZScgXSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0LFxuICAgICAgICBkaTtcblxuICAgIC8vIHdlIHdhbnQgdG8gdHJpZ2dlciBvbiByZWFsIGxhYmVscyBvbmx5XG4gICAgaWYgKCFlbGVtZW50LmxhYmVsVGFyZ2V0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gd2Ugd2FudCB0byB0cmlnZ2VyIG9uIEJQTU4gZWxlbWVudHMgb25seVxuICAgIGlmICghaXMoZWxlbWVudC5sYWJlbFRhcmdldCB8fCBlbGVtZW50LCAnYnBtbjpCYXNlRWxlbWVudCcpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgYnVzaW5lc3NPYmplY3QgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LFxuICAgIGRpID0gYnVzaW5lc3NPYmplY3QuZGk7XG5cblxuICAgIGlmICghZGkubGFiZWwpIHtcbiAgICAgIGRpLmxhYmVsID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uZGk6QlBNTkxhYmVsJywge1xuICAgICAgICBib3VuZHM6IGJwbW5GYWN0b3J5LmNyZWF0ZSgnZGM6Qm91bmRzJylcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzc2lnbihkaS5sYWJlbC5ib3VuZHMsIHtcbiAgICAgIHg6IGVsZW1lbnQueCxcbiAgICAgIHk6IGVsZW1lbnQueSxcbiAgICAgIHdpZHRoOiBlbGVtZW50LndpZHRoLFxuICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICAgIH0pO1xuICB9KTtcblxuICBmdW5jdGlvbiBnZXRWaXNpYmxlTGFiZWxBZGp1c3RtZW50KGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIGxhYmVsID0gY29ubmVjdGlvbi5sYWJlbCxcbiAgICAgICAgaGludHMgPSBhc3NpZ24oe30sIGNvbnRleHQuaGludHMpLFxuICAgICAgICBuZXdXYXlwb2ludHMgPSBjb250ZXh0Lm5ld1dheXBvaW50cyB8fCBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgICAgb2xkV2F5cG9pbnRzID0gY29udGV4dC5vbGRXYXlwb2ludHM7XG5cblxuICAgIGlmICh0eXBlb2YgaGludHMuc3RhcnRDaGFuZ2VkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgaGludHMuc3RhcnRDaGFuZ2VkID0gISFoaW50cy5jb25uZWN0aW9uU3RhcnQ7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBoaW50cy5lbmRDaGFuZ2VkID09PSAndW5kZWZpbmVkJykge1xuICAgICAgaGludHMuZW5kQ2hhbmdlZCA9ICEhaGludHMuY29ubmVjdGlvbkVuZDtcbiAgICB9XG5cbiAgICByZXR1cm4gZ2V0TGFiZWxBZGp1c3RtZW50KGxhYmVsLCBuZXdXYXlwb2ludHMsIG9sZFdheXBvaW50cywgaGludHMpO1xuICB9XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZShbXG4gICAgJ2Nvbm5lY3Rpb24ubGF5b3V0JyxcbiAgICAnY29ubmVjdGlvbi51cGRhdGVXYXlwb2ludHMnXG4gIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgICBpZiAoaGludHMubGFiZWxCZWhhdmlvciA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgbGFiZWwgPSBjb25uZWN0aW9uLmxhYmVsLFxuICAgICAgICBsYWJlbEFkanVzdG1lbnQ7XG5cbiAgICAvLyBoYW5kbGUgbWlzc2luZyBsYWJlbCBhcyB3ZWxsIGFzIHRoZSBjYXNlXG4gICAgLy8gdGhhdCB0aGUgbGFiZWwgcGFyZW50IGRvZXMgbm90IGV4aXN0ICh5ZXQpLFxuICAgIC8vIGJlY2F1c2UgaXQgaXMgYmVpbmcgcGFzdGVkIC8gY3JlYXRlZCB2aWEgbXVsdGkgZWxlbWVudCBjcmVhdGVcbiAgICAvL1xuICAgIC8vIENmLiBodHRwczovL2dpdGh1Yi5jb20vYnBtbi1pby9icG1uLWpzL3B1bGwvMTIyN1xuICAgIGlmICghbGFiZWwgfHwgIWxhYmVsLnBhcmVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxhYmVsQWRqdXN0bWVudCA9IGdldFZpc2libGVMYWJlbEFkanVzdG1lbnQoZXZlbnQpO1xuXG4gICAgbW9kZWxpbmcubW92ZVNoYXBlKGxhYmVsLCBsYWJlbEFkanVzdG1lbnQpO1xuICB9KTtcblxuXG4gIC8vIGtlZXAgbGFiZWwgcG9zaXRpb24gb24gc2hhcGUgcmVwbGFjZVxuICB0aGlzLnBvc3RFeGVjdXRlKFsgJ3NoYXBlLnJlcGxhY2UnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBuZXdTaGFwZSA9IGNvbnRleHQubmV3U2hhcGUsXG4gICAgICAgIG9sZFNoYXBlID0gY29udGV4dC5vbGRTaGFwZTtcblxuICAgIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KG5ld1NoYXBlKTtcblxuICAgIGlmIChidXNpbmVzc09iamVjdFxuICAgICAgJiYgaXNMYWJlbEV4dGVybmFsKGJ1c2luZXNzT2JqZWN0KVxuICAgICAgJiYgb2xkU2hhcGUubGFiZWxcbiAgICAgICYmIG5ld1NoYXBlLmxhYmVsKSB7XG4gICAgICBuZXdTaGFwZS5sYWJlbC54ID0gb2xkU2hhcGUubGFiZWwueDtcbiAgICAgIG5ld1NoYXBlLmxhYmVsLnkgPSBvbGRTaGFwZS5sYWJlbC55O1xuICAgIH1cbiAgfSk7XG5cblxuICAvLyBtb3ZlIGV4dGVybmFsIGxhYmVsIGFmdGVyIHJlc2l6aW5nXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ3NoYXBlLnJlc2l6ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgbmV3Qm91bmRzID0gY29udGV4dC5uZXdCb3VuZHMsXG4gICAgICAgIG9sZEJvdW5kcyA9IGNvbnRleHQub2xkQm91bmRzO1xuXG4gICAgaWYgKGhhc0V4dGVybmFsTGFiZWwoc2hhcGUpKSB7XG5cbiAgICAgIHZhciBsYWJlbCA9IHNoYXBlLmxhYmVsLFxuICAgICAgICAgIGxhYmVsTWlkID0gZ2V0TWlkKGxhYmVsKSxcbiAgICAgICAgICBlZGdlcyA9IGFzRWRnZXMob2xkQm91bmRzKTtcblxuICAgICAgLy8gZ2V0IG5lYXJlc3QgYm9yZGVyIHBvaW50IHRvIGxhYmVsIGFzIHJlZmVyZW5jZSBwb2ludFxuICAgICAgdmFyIHJlZmVyZW5jZVBvaW50ID0gZ2V0UmVmZXJlbmNlUG9pbnQobGFiZWxNaWQsIGVkZ2VzKTtcblxuICAgICAgdmFyIGRlbHRhID0gZ2V0UmVmZXJlbmNlUG9pbnREZWx0YShyZWZlcmVuY2VQb2ludCwgb2xkQm91bmRzLCBuZXdCb3VuZHMpO1xuXG4gICAgICBtb2RlbGluZy5tb3ZlU2hhcGUobGFiZWwsIGRlbHRhKTtcblxuICAgIH1cblxuICB9KTtcblxufVxuXG5pbmhlcml0cyhMYWJlbEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5MYWJlbEJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZycsXG4gICdicG1uRmFjdG9yeScsXG4gICd0ZXh0UmVuZGVyZXInXG5dO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBDYWxjdWxhdGVzIGEgcmVmZXJlbmNlIHBvaW50IGRlbHRhIHJlbGF0aXZlIHRvIGEgbmV3IHBvc2l0aW9uXG4gKiBvZiBhIGNlcnRhaW4gZWxlbWVudCdzIGJvdW5kc1xuICpcbiAqIEBwYXJhbSB7UG9pbnR9IHBvaW50XG4gKiBAcGFyYW0ge0JvdW5kc30gb2xkQm91bmRzXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXG4gKlxuICogQHJldHVybiB7RGVsdGF9IGRlbHRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRSZWZlcmVuY2VQb2ludERlbHRhKHJlZmVyZW5jZVBvaW50LCBvbGRCb3VuZHMsIG5ld0JvdW5kcykge1xuXG4gIHZhciBuZXdSZWZlcmVuY2VQb2ludCA9IGdldE5ld0F0dGFjaFBvaW50KHJlZmVyZW5jZVBvaW50LCBvbGRCb3VuZHMsIG5ld0JvdW5kcyk7XG5cbiAgcmV0dXJuIHJvdW5kUG9pbnQoZGVsdGEobmV3UmVmZXJlbmNlUG9pbnQsIHJlZmVyZW5jZVBvaW50KSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSBuZWFyZXN0IHBvaW50IChyZWZlcmVuY2UgcG9pbnQpIGZvciBhIGdpdmVuIHBvaW50XG4gKiBvbnRvIGdpdmVuIHNldCBvZiBsaW5lc1xuICpcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQsIFBvaW50Pn0gbGluZXNcbiAqIEBwYXJhbSB7UG9pbnR9IHBvaW50XG4gKlxuICogQHBhcmFtIHtQb2ludH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlZmVyZW5jZVBvaW50KHBvaW50LCBsaW5lcykge1xuXG4gIGlmICghbGluZXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG5lYXJlc3RMaW5lID0gZ2V0TmVhcmVzdExpbmUocG9pbnQsIGxpbmVzKTtcblxuICByZXR1cm4gcGVycGVuZGljdWxhckZvb3QocG9pbnQsIG5lYXJlc3RMaW5lKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IHRoZSBnaXZlbiBib3VuZHMgdG8gYSBsaW5lcyBhcnJheSBjb250YWluaW5nIGFsbCBlZGdlc1xuICpcbiAqIEBwYXJhbSB7Qm91bmRzfFBvaW50fSBib3VuZHNcbiAqXG4gKiBAcmV0dXJuIEFycmF5PFBvaW50PlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNFZGdlcyhib3VuZHMpIHtcbiAgcmV0dXJuIFtcbiAgICBbIC8vIHRvcFxuICAgICAge1xuICAgICAgICB4OiBib3VuZHMueCxcbiAgICAgICAgeTogYm91bmRzLnlcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHg6IGJvdW5kcy54ICsgKGJvdW5kcy53aWR0aCB8fCAwKSxcbiAgICAgICAgeTogYm91bmRzLnlcbiAgICAgIH1cbiAgICBdLFxuICAgIFsgLy8gcmlnaHRcbiAgICAgIHtcbiAgICAgICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIHx8IDApLFxuICAgICAgICB5OiBib3VuZHMueVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIHx8IDApLFxuICAgICAgICB5OiBib3VuZHMueSArIChib3VuZHMuaGVpZ2h0IHx8IDApXG4gICAgICB9XG4gICAgXSxcbiAgICBbIC8vIGJvdHRvbVxuICAgICAge1xuICAgICAgICB4OiBib3VuZHMueCxcbiAgICAgICAgeTogYm91bmRzLnkgKyAoYm91bmRzLmhlaWdodCB8fCAwKVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIHx8IDApLFxuICAgICAgICB5OiBib3VuZHMueSArIChib3VuZHMuaGVpZ2h0IHx8IDApXG4gICAgICB9XG4gICAgXSxcbiAgICBbIC8vIGxlZnRcbiAgICAgIHtcbiAgICAgICAgeDogYm91bmRzLngsXG4gICAgICAgIHk6IGJvdW5kcy55XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB4OiBib3VuZHMueCxcbiAgICAgICAgeTogYm91bmRzLnkgKyAoYm91bmRzLmhlaWdodCB8fCAwKVxuICAgICAgfVxuICAgIF1cbiAgXTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBuZWFyZXN0IGxpbmUgZm9yIGEgZ2l2ZW4gcG9pbnQgYnkgZGlzdGFuY2VcbiAqIEBwYXJhbSB7UG9pbnR9IHBvaW50XG4gKiBAcGFyYW0gQXJyYXk8UG9pbnQ+IGxpbmVzXG4gKlxuICogQHJldHVybiBBcnJheTxQb2ludD5cbiAqL1xuZnVuY3Rpb24gZ2V0TmVhcmVzdExpbmUocG9pbnQsIGxpbmVzKSB7XG5cbiAgdmFyIGRpc3RhbmNlcyA9IGxpbmVzLm1hcChmdW5jdGlvbihsKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGxpbmU6IGwsXG4gICAgICBkaXN0YW5jZTogZ2V0RGlzdGFuY2VQb2ludExpbmUocG9pbnQsIGwpXG4gICAgfTtcbiAgfSk7XG5cbiAgdmFyIHNvcnRlZCA9IHNvcnRCeShkaXN0YW5jZXMsICdkaXN0YW5jZScpO1xuXG4gIHJldHVybiBzb3J0ZWRbMF0ubGluZTtcbn1cbiIsImltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG52YXIgQ09MTEFCX0VSUl9NU0cgPSAnZmxvdyBlbGVtZW50cyBtdXN0IGJlIGNoaWxkcmVuIG9mIHBvb2xzL3BhcnRpY2lwYW50cycsXG4gICAgUFJPQ0VTU19FUlJfTVNHID0gJ3BhcnRpY2lwYW50cyBjYW5ub3QgYmUgcGFzdGVkIG9udG8gYSBub24tZW1wdHkgcHJvY2VzcyBkaWFncmFtJztcblxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb2RlbGluZ0ZlZWRiYWNrKGV2ZW50QnVzLCB0b29sdGlwcywgdHJhbnNsYXRlKSB7XG5cbiAgZnVuY3Rpb24gc2hvd0Vycm9yKHBvc2l0aW9uLCBtZXNzYWdlLCB0aW1lb3V0KSB7XG4gICAgdG9vbHRpcHMuYWRkKHtcbiAgICAgIHBvc2l0aW9uOiB7XG4gICAgICAgIHg6IHBvc2l0aW9uLnggKyA1LFxuICAgICAgICB5OiBwb3NpdGlvbi55ICsgNVxuICAgICAgfSxcbiAgICAgIHR5cGU6ICdlcnJvcicsXG4gICAgICB0aW1lb3V0OiB0aW1lb3V0IHx8IDIwMDAsXG4gICAgICBodG1sOiAnPGRpdj4nICsgbWVzc2FnZSArICc8L2Rpdj4nXG4gICAgfSk7XG4gIH1cblxuICBldmVudEJ1cy5vbihbICdzaGFwZS5tb3ZlLnJlamVjdGVkJywgJ2NyZWF0ZS5yZWplY3RlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgdGFyZ2V0ID0gY29udGV4dC50YXJnZXQ7XG5cbiAgICBpZiAoaXModGFyZ2V0LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykgJiYgaXMoc2hhcGUsICdicG1uOkZsb3dOb2RlJykpIHtcbiAgICAgIHNob3dFcnJvcihldmVudCwgdHJhbnNsYXRlKENPTExBQl9FUlJfTVNHKSk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdlbGVtZW50cy5wYXN0ZS5yZWplY3RlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHBvc2l0aW9uID0gY29udGV4dC5wb3NpdGlvbixcbiAgICAgICAgdGFyZ2V0ID0gY29udGV4dC50YXJnZXQ7XG5cbiAgICBpZiAoaXModGFyZ2V0LCAnYnBtbjpDb2xsYWJvcmF0aW9uJykpIHtcbiAgICAgIHNob3dFcnJvcihwb3NpdGlvbiwgdHJhbnNsYXRlKENPTExBQl9FUlJfTVNHKSk7XG4gICAgfVxuXG4gICAgaWYgKGlzKHRhcmdldCwgJ2JwbW46UHJvY2VzcycpKSB7XG4gICAgICBzaG93RXJyb3IocG9zaXRpb24sIHRyYW5zbGF0ZShQUk9DRVNTX0VSUl9NU0cpLCAzMDAwKTtcbiAgICB9XG4gIH0pO1xufVxuXG5Nb2RlbGluZ0ZlZWRiYWNrLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICd0b29sdGlwcycsXG4gICd0cmFuc2xhdGUnXG5dO1xuIiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnZGlhZ3JhbS1qcy9saWIvY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5pbXBvcnQgbGluZUludGVyc2VjdCBmcm9tICcuL3V0aWwvTGluZUludGVyc2VjdCc7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVtb3ZlRWxlbWVudEJlaGF2aW9yKGV2ZW50QnVzLCBicG1uUnVsZXMsIG1vZGVsaW5nKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8qKlxuICAgKiBDb21iaW5lIHNlcXVlbmNlIGZsb3dzIHdoZW4gZGVsZXRpbmcgYW4gZWxlbWVudFxuICAgKiBpZiB0aGVyZSBpcyBvbmUgaW5jb21pbmcgYW5kIG9uZSBvdXRnb2luZ1xuICAgKiBzZXF1ZW5jZSBmbG93XG4gICAqL1xuICB0aGlzLnByZUV4ZWN1dGUoJ3NoYXBlLmRlbGV0ZScsIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBzaGFwZSA9IGUuY29udGV4dC5zaGFwZTtcblxuICAgIC8vIG9ubHkgaGFuZGxlIFthXSAtPiBbc2hhcGVdIC0+IFtiXSBwYXR0ZXJuc1xuICAgIGlmIChzaGFwZS5pbmNvbWluZy5sZW5ndGggIT09IDEgfHwgc2hhcGUub3V0Z29pbmcubGVuZ3RoICE9PSAxKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGluQ29ubmVjdGlvbiA9IHNoYXBlLmluY29taW5nWzBdLFxuICAgICAgICBvdXRDb25uZWN0aW9uID0gc2hhcGUub3V0Z29pbmdbMF07XG5cbiAgICAvLyBvbmx5IGhhbmRsZSBzZXF1ZW5jZSBmbG93c1xuICAgIGlmICghaXMoaW5Db25uZWN0aW9uLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSB8fCAhaXMob3V0Q29ubmVjdGlvbiwgJ2JwbW46U2VxdWVuY2VGbG93JykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoYnBtblJ1bGVzLmNhbkNvbm5lY3QoaW5Db25uZWN0aW9uLnNvdXJjZSwgb3V0Q29ubmVjdGlvbi50YXJnZXQsIGluQ29ubmVjdGlvbikpIHtcblxuICAgICAgLy8gY29tcHV0ZSBuZXcsIGNvbWJpbmVkIHdheXBvaW50c1xuICAgICAgdmFyIG5ld1dheXBvaW50cyA9IGdldE5ld1dheXBvaW50cyhpbkNvbm5lY3Rpb24ud2F5cG9pbnRzLCBvdXRDb25uZWN0aW9uLndheXBvaW50cyk7XG5cbiAgICAgIG1vZGVsaW5nLnJlY29ubmVjdEVuZChpbkNvbm5lY3Rpb24sIG91dENvbm5lY3Rpb24udGFyZ2V0LCBuZXdXYXlwb2ludHMpO1xuICAgIH1cbiAgfSk7XG5cbn1cblxuaW5oZXJpdHMoUmVtb3ZlRWxlbWVudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5SZW1vdmVFbGVtZW50QmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2JwbW5SdWxlcycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldERvY2tpbmcocG9pbnQpIHtcbiAgcmV0dXJuIHBvaW50Lm9yaWdpbmFsIHx8IHBvaW50O1xufVxuXG5cbmZ1bmN0aW9uIGdldE5ld1dheXBvaW50cyhpbldheXBvaW50cywgb3V0V2F5cG9pbnRzKSB7XG5cbiAgdmFyIGludGVyc2VjdGlvbiA9IGxpbmVJbnRlcnNlY3QoXG4gICAgZ2V0RG9ja2luZyhpbldheXBvaW50c1tpbldheXBvaW50cy5sZW5ndGggLSAyXSksXG4gICAgZ2V0RG9ja2luZyhpbldheXBvaW50c1tpbldheXBvaW50cy5sZW5ndGggLSAxXSksXG4gICAgZ2V0RG9ja2luZyhvdXRXYXlwb2ludHNbMV0pLFxuICAgIGdldERvY2tpbmcob3V0V2F5cG9pbnRzWzBdKSk7XG5cbiAgaWYgKGludGVyc2VjdGlvbikge1xuICAgIHJldHVybiBbXS5jb25jYXQoXG4gICAgICBpbldheXBvaW50cy5zbGljZSgwLCBpbldheXBvaW50cy5sZW5ndGggLSAxKSxcbiAgICAgIFsgaW50ZXJzZWN0aW9uIF0sXG4gICAgICBvdXRXYXlwb2ludHMuc2xpY2UoMSkpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBbXG4gICAgICBnZXREb2NraW5nKGluV2F5cG9pbnRzWzBdKSxcbiAgICAgIGdldERvY2tpbmcob3V0V2F5cG9pbnRzW291dFdheXBvaW50cy5sZW5ndGggLSAxXSlcbiAgICBdO1xuICB9XG59IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5cbi8qKlxuICogQlBNTiBzcGVjaWZpYyByZW1vdmUgYmVoYXZpb3JcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVtb3ZlUGFydGljaXBhbnRCZWhhdmlvcihldmVudEJ1cywgbW9kZWxpbmcpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cblxuICAvKipcbiAgICogbW9ycGggY29sbGFib3JhdGlvbiBkaWFncmFtIGludG8gcHJvY2VzcyBkaWFncmFtXG4gICAqIGFmdGVyIHRoZSBsYXN0IHBhcnRpY2lwYW50IGhhcyBiZWVuIHJlbW92ZWRcbiAgICovXG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5kZWxldGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBwYXJlbnQgPSBzaGFwZS5wYXJlbnQ7XG5cbiAgICAvLyBhY3RpdmF0ZSB0aGUgYmVoYXZpb3IgaWYgdGhlIHNoYXBlIHRvIGJlIHJlbW92ZWRcbiAgICAvLyBpcyBhIHBhcnRpY2lwYW50XG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgICBjb250ZXh0LmNvbGxhYm9yYXRpb25Sb290ID0gcGFyZW50O1xuICAgIH1cbiAgfSwgdHJ1ZSk7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGNvbGxhYm9yYXRpb25Sb290ID0gY29udGV4dC5jb2xsYWJvcmF0aW9uUm9vdDtcblxuICAgIGlmIChjb2xsYWJvcmF0aW9uUm9vdCAmJiAhY29sbGFib3JhdGlvblJvb3QuYnVzaW5lc3NPYmplY3QucGFydGljaXBhbnRzLmxlbmd0aCkge1xuXG4gICAgICAvLyByZXBsYWNlIGVtcHR5IGNvbGxhYm9yYXRpb24gd2l0aCBwcm9jZXNzIGRpYWdyYW1cbiAgICAgIG1vZGVsaW5nLm1ha2VQcm9jZXNzKCk7XG4gICAgfVxuICB9LCB0cnVlKTtcblxufVxuXG5SZW1vdmVQYXJ0aWNpcGFudEJlaGF2aW9yLiRpbmplY3QgPSBbICdldmVudEJ1cycsICdtb2RlbGluZycgXTtcblxuaW5oZXJpdHMoUmVtb3ZlUGFydGljaXBhbnRCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTsiLCJpbXBvcnQge1xuICBmb3JFYWNoLFxuICBmaW5kLFxuICBtYXRjaFBhdHRlcm5cbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVwbGFjZUNvbm5lY3Rpb25CZWhhdmlvcihldmVudEJ1cywgbW9kZWxpbmcsIGJwbW5SdWxlcywgaW5qZWN0b3IpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdmFyIGRyYWdnaW5nID0gaW5qZWN0b3IuZ2V0KCdkcmFnZ2luZycsIGZhbHNlKTtcblxuICBmdW5jdGlvbiBmaXhDb25uZWN0aW9uKGNvbm5lY3Rpb24pIHtcblxuICAgIHZhciBzb3VyY2UgPSBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIHBhcmVudCA9IGNvbm5lY3Rpb24ucGFyZW50O1xuXG4gICAgLy8gZG8gbm90IGRvIGFueXRoaW5nIGlmIGNvbm5lY3Rpb25cbiAgICAvLyBpcyBhbHJlYWR5IGRlbGV0ZWQgKG1heSBoYXBwZW4gZHVlIHRvIG90aGVyXG4gICAgLy8gYmVoYXZpb3JzIHBsdWdnZWQtaW4gYmVmb3JlKVxuICAgIGlmICghcGFyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHJlcGxhY2VtZW50VHlwZSxcbiAgICAgICAgcmVtb3ZlO1xuXG4gICAgLyoqXG4gICAgICogQ2hlY2sgaWYgaW5jb21pbmcgb3Igb3V0Z29pbmcgY29ubmVjdGlvbnNcbiAgICAgKiBjYW4gc3RheSBvciBjb3VsZCBiZSBzdWJzdGl0dXRlZCB3aXRoIGFuXG4gICAgICogYXBwcm9wcmlhdGUgcmVwbGFjZW1lbnQuXG4gICAgICpcbiAgICAgKiBUaGlzIGhvbGRzIHRydWUgZm9yIFNlcXVlbmNlRmxvdyA8PiBNZXNzYWdlRmxvdy5cbiAgICAgKi9cblxuICAgIGlmIChpcyhjb25uZWN0aW9uLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgICAgaWYgKCFicG1uUnVsZXMuY2FuQ29ubmVjdFNlcXVlbmNlRmxvdyhzb3VyY2UsIHRhcmdldCkpIHtcbiAgICAgICAgcmVtb3ZlID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgaWYgKGJwbW5SdWxlcy5jYW5Db25uZWN0TWVzc2FnZUZsb3coc291cmNlLCB0YXJnZXQpKSB7XG4gICAgICAgIHJlcGxhY2VtZW50VHlwZSA9ICdicG1uOk1lc3NhZ2VGbG93JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB0cmFuc2Zvcm0gbWVzc2FnZSBmbG93cyBpbnRvIHNlcXVlbmNlIGZsb3dzLCBpZiBwb3NzaWJsZVxuXG4gICAgaWYgKGlzKGNvbm5lY3Rpb24sICdicG1uOk1lc3NhZ2VGbG93JykpIHtcblxuICAgICAgaWYgKCFicG1uUnVsZXMuY2FuQ29ubmVjdE1lc3NhZ2VGbG93KHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgICAgICByZW1vdmUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoYnBtblJ1bGVzLmNhbkNvbm5lY3RTZXF1ZW5jZUZsb3coc291cmNlLCB0YXJnZXQpKSB7XG4gICAgICAgIHJlcGxhY2VtZW50VHlwZSA9ICdicG1uOlNlcXVlbmNlRmxvdyc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzKGNvbm5lY3Rpb24sICdicG1uOkFzc29jaWF0aW9uJykgJiYgIWJwbW5SdWxlcy5jYW5Db25uZWN0QXNzb2NpYXRpb24oc291cmNlLCB0YXJnZXQpKSB7XG4gICAgICByZW1vdmUgPSB0cnVlO1xuICAgIH1cblxuXG4gICAgLy8gcmVtb3ZlIGludmFsaWQgY29ubmVjdGlvbixcbiAgICAvLyB1bmxlc3MgaXQgaGFzIGJlZW4gcmVtb3ZlZCBhbHJlYWR5XG4gICAgaWYgKHJlbW92ZSkge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihjb25uZWN0aW9uKTtcbiAgICB9XG5cbiAgICAvLyByZXBsYWNlIFNlcXVlbmNlRmxvdyA8PiBNZXNzYWdlRmxvd1xuXG4gICAgaWYgKHJlcGxhY2VtZW50VHlwZSkge1xuICAgICAgbW9kZWxpbmcuY29ubmVjdChzb3VyY2UsIHRhcmdldCwge1xuICAgICAgICB0eXBlOiByZXBsYWNlbWVudFR5cGUsXG4gICAgICAgIHdheXBvaW50czogY29ubmVjdGlvbi53YXlwb2ludHMuc2xpY2UoKVxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmVwbGFjZVJlY29ubmVjdGVkQ29ubmVjdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBzb3VyY2UgPSBjb250ZXh0Lm5ld1NvdXJjZSB8fCBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgdGFyZ2V0ID0gY29udGV4dC5uZXdUYXJnZXQgfHwgY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIGFsbG93ZWQsXG4gICAgICAgIHJlcGxhY2VtZW50O1xuXG4gICAgYWxsb3dlZCA9IGJwbW5SdWxlcy5jYW5Db25uZWN0KHNvdXJjZSwgdGFyZ2V0KTtcblxuICAgIGlmICghYWxsb3dlZCB8fCBhbGxvd2VkLnR5cGUgPT09IGNvbm5lY3Rpb24udHlwZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHJlcGxhY2VtZW50ID0gbW9kZWxpbmcuY29ubmVjdChzb3VyY2UsIHRhcmdldCwge1xuICAgICAgdHlwZTogYWxsb3dlZC50eXBlLFxuICAgICAgd2F5cG9pbnRzOiBjb25uZWN0aW9uLndheXBvaW50cy5zbGljZSgpXG4gICAgfSk7XG5cbiAgICAvLyByZW1vdmUgb2xkIGNvbm5lY3Rpb25cbiAgICBtb2RlbGluZy5yZW1vdmVDb25uZWN0aW9uKGNvbm5lY3Rpb24pO1xuXG4gICAgLy8gcmVwbGFjZSBjb25uZWN0aW9uIGluIGNvbnRleHQgdG8gcmVjb25uZWN0IGVuZC9zdGFydFxuICAgIGNvbnRleHQuY29ubmVjdGlvbiA9IHJlcGxhY2VtZW50O1xuXG4gICAgaWYgKGRyYWdnaW5nKSB7XG4gICAgICBjbGVhbkRyYWdnaW5nU2VsZWN0aW9uKGNvbm5lY3Rpb24sIHJlcGxhY2VtZW50KTtcbiAgICB9XG4gIH1cblxuICAvLyBtb25rZXktcGF0Y2ggc2VsZWN0aW9uIHNhdmVkIGluIGRyYWdnaW5nIGluIG9yZGVyIHRvIHJlLXNlbGVjdCBpdCB3aGVuIG9wZXJhdGlvbiBpcyBmaW5pc2hlZFxuICBmdW5jdGlvbiBjbGVhbkRyYWdnaW5nU2VsZWN0aW9uKG9sZENvbm5lY3Rpb24sIG5ld0Nvbm5lY3Rpb24pIHtcbiAgICB2YXIgY29udGV4dCA9IGRyYWdnaW5nLmNvbnRleHQoKSxcbiAgICAgICAgcHJldmlvdXNTZWxlY3Rpb24gPSBjb250ZXh0ICYmIGNvbnRleHQucGF5bG9hZC5wcmV2aW91c1NlbGVjdGlvbixcbiAgICAgICAgaW5kZXg7XG5cbiAgICAvLyBkbyBub3RoaW5nIGlmIG5vdCBkcmFnZ2luZyBvciBubyBzZWxlY3Rpb24gd2FzIHByZXNlbnRcbiAgICBpZiAoIXByZXZpb3VzU2VsZWN0aW9uIHx8ICFwcmV2aW91c1NlbGVjdGlvbi5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpbmRleCA9IHByZXZpb3VzU2VsZWN0aW9uLmluZGV4T2Yob2xkQ29ubmVjdGlvbik7XG5cbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcHJldmlvdXNTZWxlY3Rpb24uc3BsaWNlKGluZGV4LCAxLCBuZXdDb25uZWN0aW9uKTtcbiAgfVxuXG4gIC8vIGxpZmVjeWNsZSBob29rc1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKCdlbGVtZW50cy5tb3ZlJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGNsb3N1cmUgPSBjb250ZXh0LmNsb3N1cmUsXG4gICAgICAgIGFsbENvbm5lY3Rpb25zID0gY2xvc3VyZS5hbGxDb25uZWN0aW9ucztcblxuICAgIGZvckVhY2goYWxsQ29ubmVjdGlvbnMsIGZpeENvbm5lY3Rpb24pO1xuICB9LCB0cnVlKTtcblxuICB0aGlzLnByZUV4ZWN1dGUoJ2Nvbm5lY3Rpb24ucmVjb25uZWN0JywgcmVwbGFjZVJlY29ubmVjdGVkQ29ubmVjdGlvbik7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoJ2VsZW1lbnQudXBkYXRlUHJvcGVydGllcycsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBwcm9wZXJ0aWVzID0gY29udGV4dC5wcm9wZXJ0aWVzLFxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBidXNpbmVzc09iamVjdCA9IGVsZW1lbnQuYnVzaW5lc3NPYmplY3QsXG4gICAgICAgIGNvbm5lY3Rpb247XG5cbiAgICAvLyByZW1vdmUgY29uZGl0aW9uIG9uIGNoYW5nZSB0byBkZWZhdWx0XG4gICAgaWYgKHByb3BlcnRpZXMuZGVmYXVsdCkge1xuICAgICAgY29ubmVjdGlvbiA9IGZpbmQoXG4gICAgICAgIGVsZW1lbnQub3V0Z29pbmcsXG4gICAgICAgIG1hdGNoUGF0dGVybih7IGlkOiBlbGVtZW50LmJ1c2luZXNzT2JqZWN0LmRlZmF1bHQuaWQgfSlcbiAgICAgICk7XG5cbiAgICAgIGlmIChjb25uZWN0aW9uKSB7XG4gICAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoY29ubmVjdGlvbiwgeyBjb25kaXRpb25FeHByZXNzaW9uOiB1bmRlZmluZWQgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGRlZmF1bHQgZnJvbSBzb3VyY2Ugb24gY2hhbmdlIHRvIGNvbmRpdGlvbmFsXG4gICAgaWYgKHByb3BlcnRpZXMuY29uZGl0aW9uRXhwcmVzc2lvbiAmJiBidXNpbmVzc09iamVjdC5zb3VyY2VSZWYuZGVmYXVsdCA9PT0gYnVzaW5lc3NPYmplY3QpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudC5zb3VyY2UsIHsgZGVmYXVsdDogdW5kZWZpbmVkIH0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmluaGVyaXRzKFJlcGxhY2VDb25uZWN0aW9uQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cblJlcGxhY2VDb25uZWN0aW9uQmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGVsaW5nJyxcbiAgJ2JwbW5SdWxlcycsXG4gICdpbmplY3Rvcidcbl07XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXNFdmVudFN1YlByb2Nlc3MgfSBmcm9tICcuLi8uLi8uLi91dGlsL0RpVXRpbCc7XG5cblxuLyoqXG4gKiBCUE1OLXNwZWNpZmljIHJlcGxhY2UgYmVoYXZpb3IuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlcGxhY2VFbGVtZW50QmVoYXZpb3VyKFxuICAgIGJwbW5SZXBsYWNlLFxuICAgIGJwbW5SdWxlcyxcbiAgICBlbGVtZW50UmVnaXN0cnksXG4gICAgaW5qZWN0b3IsXG4gICAgbW9kZWxpbmcsXG4gICAgc2VsZWN0aW9uXG4pIHtcbiAgaW5qZWN0b3IuaW52b2tlKENvbW1hbmRJbnRlcmNlcHRvciwgdGhpcyk7XG5cbiAgdGhpcy5fYnBtblJlcGxhY2UgPSBicG1uUmVwbGFjZTtcbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9zZWxlY3Rpb24gPSBzZWxlY3Rpb247XG5cbiAgLy8gcmVwbGFjZSBlbGVtZW50cyBvbiBtb3ZlXG4gIHRoaXMucG9zdEV4ZWN1dGVkKFsgJ2VsZW1lbnRzLm1vdmUnIF0sIDUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQubmV3UGFyZW50LFxuICAgICAgICBuZXdIb3N0ID0gY29udGV4dC5uZXdIb3N0LFxuICAgICAgICBlbGVtZW50cyA9IFtdO1xuXG4gICAgZm9yRWFjaChjb250ZXh0LmNsb3N1cmUudG9wTGV2ZWwsIGZ1bmN0aW9uKHRvcExldmVsRWxlbWVudHMpIHtcbiAgICAgIGlmIChpc0V2ZW50U3ViUHJvY2Vzcyh0b3BMZXZlbEVsZW1lbnRzKSkge1xuICAgICAgICBlbGVtZW50cyA9IGVsZW1lbnRzLmNvbmNhdCh0b3BMZXZlbEVsZW1lbnRzLmNoaWxkcmVuKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsZW1lbnRzID0gZWxlbWVudHMuY29uY2F0KHRvcExldmVsRWxlbWVudHMpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gc2V0IHRhcmdldCB0byBob3N0IGlmIGF0dGFjaGluZ1xuICAgIGlmIChlbGVtZW50cy5sZW5ndGggPT09IDEgJiYgbmV3SG9zdCkge1xuICAgICAgdGFyZ2V0ID0gbmV3SG9zdDtcbiAgICB9XG5cbiAgICB2YXIgY2FuUmVwbGFjZSA9IGJwbW5SdWxlcy5jYW5SZXBsYWNlKGVsZW1lbnRzLCB0YXJnZXQpO1xuXG4gICAgaWYgKGNhblJlcGxhY2UpIHtcbiAgICAgIHRoaXMucmVwbGFjZUVsZW1lbnRzKGVsZW1lbnRzLCBjYW5SZXBsYWNlLnJlcGxhY2VtZW50cywgbmV3SG9zdCk7XG4gICAgfVxuICB9LCB0aGlzKTtcblxuICAvLyB1cGRhdGUgYXR0YWNobWVudHMgb24gaG9zdCByZXBsYWNlXG4gIHRoaXMucG9zdEV4ZWN1dGUoWyAnc2hhcGUucmVwbGFjZScgXSwgMTUwMCwgZnVuY3Rpb24oZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBvbGRTaGFwZSA9IGNvbnRleHQub2xkU2hhcGUsXG4gICAgICAgIG5ld1NoYXBlID0gY29udGV4dC5uZXdTaGFwZSxcbiAgICAgICAgYXR0YWNoZXJzID0gb2xkU2hhcGUuYXR0YWNoZXJzLFxuICAgICAgICBjYW5SZXBsYWNlO1xuXG4gICAgaWYgKGF0dGFjaGVycyAmJiBhdHRhY2hlcnMubGVuZ3RoKSB7XG4gICAgICBjYW5SZXBsYWNlID0gYnBtblJ1bGVzLmNhblJlcGxhY2UoYXR0YWNoZXJzLCBuZXdTaGFwZSk7XG5cbiAgICAgIHRoaXMucmVwbGFjZUVsZW1lbnRzKGF0dGFjaGVycywgY2FuUmVwbGFjZS5yZXBsYWNlbWVudHMpO1xuICAgIH1cblxuICB9LCB0aGlzKTtcblxuICAvLyBrZWVwIElEIG9uIHNoYXBlIHJlcGxhY2VcbiAgdGhpcy5wb3N0RXhlY3V0ZWQoWyAnc2hhcGUucmVwbGFjZScgXSwgMTUwMCwgZnVuY3Rpb24oZSkge1xuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBvbGRTaGFwZSA9IGNvbnRleHQub2xkU2hhcGUsXG4gICAgICAgIG5ld1NoYXBlID0gY29udGV4dC5uZXdTaGFwZTtcblxuICAgIG1vZGVsaW5nLnVuY2xhaW1JZChvbGRTaGFwZS5idXNpbmVzc09iamVjdC5pZCwgb2xkU2hhcGUuYnVzaW5lc3NPYmplY3QpO1xuICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMobmV3U2hhcGUsIHsgaWQ6IG9sZFNoYXBlLmlkIH0pO1xuICB9KTtcbn1cblxuaW5oZXJpdHMoUmVwbGFjZUVsZW1lbnRCZWhhdmlvdXIsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cblJlcGxhY2VFbGVtZW50QmVoYXZpb3VyLnByb3RvdHlwZS5yZXBsYWNlRWxlbWVudHMgPSBmdW5jdGlvbihlbGVtZW50cywgbmV3RWxlbWVudHMpIHtcbiAgdmFyIGVsZW1lbnRSZWdpc3RyeSA9IHRoaXMuX2VsZW1lbnRSZWdpc3RyeSxcbiAgICAgIGJwbW5SZXBsYWNlID0gdGhpcy5fYnBtblJlcGxhY2UsXG4gICAgICBzZWxlY3Rpb24gPSB0aGlzLl9zZWxlY3Rpb247XG5cbiAgZm9yRWFjaChuZXdFbGVtZW50cywgZnVuY3Rpb24ocmVwbGFjZW1lbnQpIHtcbiAgICB2YXIgbmV3RWxlbWVudCA9IHtcbiAgICAgIHR5cGU6IHJlcGxhY2VtZW50Lm5ld0VsZW1lbnRUeXBlXG4gICAgfTtcblxuICAgIHZhciBvbGRFbGVtZW50ID0gZWxlbWVudFJlZ2lzdHJ5LmdldChyZXBsYWNlbWVudC5vbGRFbGVtZW50SWQpO1xuXG4gICAgdmFyIGlkeCA9IGVsZW1lbnRzLmluZGV4T2Yob2xkRWxlbWVudCk7XG5cbiAgICBlbGVtZW50c1tpZHhdID0gYnBtblJlcGxhY2UucmVwbGFjZUVsZW1lbnQob2xkRWxlbWVudCwgbmV3RWxlbWVudCwgeyBzZWxlY3Q6IGZhbHNlIH0pO1xuICB9KTtcblxuICBpZiAobmV3RWxlbWVudHMpIHtcbiAgICBzZWxlY3Rpb24uc2VsZWN0KGVsZW1lbnRzKTtcbiAgfVxufTtcblxuUmVwbGFjZUVsZW1lbnRCZWhhdmlvdXIuJGluamVjdCA9IFtcbiAgJ2JwbW5SZXBsYWNlJyxcbiAgJ2JwbW5SdWxlcycsXG4gICdlbGVtZW50UmVnaXN0cnknLFxuICAnaW5qZWN0b3InLFxuICAnbW9kZWxpbmcnLFxuICAnc2VsZWN0aW9uJ1xuXTtcbiIsImltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xyXG5cclxuaW1wb3J0IHsgaXNFeHBhbmRlZCB9IGZyb20gJy4uLy4uLy4uL3V0aWwvRGlVdGlsJztcclxuXHJcbmltcG9ydCB7IGdldFBhcnRpY2lwYW50UmVzaXplQ29uc3RyYWludHMgfSBmcm9tICcuL3V0aWwvUmVzaXplVXRpbCc7XHJcblxyXG52YXIgSElHSF9QUklPUklUWSA9IDE1MDA7XHJcblxyXG5leHBvcnQgdmFyIExBTkVfTUlOX0RJTUVOU0lPTlMgPSB7IHdpZHRoOiAzMDAsIGhlaWdodDogNjAgfTtcclxuXHJcbmV4cG9ydCB2YXIgUEFSVElDSVBBTlRfTUlOX0RJTUVOU0lPTlMgPSB7IHdpZHRoOiAzMDAsIGhlaWdodDogMTUwIH07XHJcblxyXG5leHBvcnQgdmFyIFNVQl9QUk9DRVNTX01JTl9ESU1FTlNJT05TID0geyB3aWR0aDogMTQwLCBoZWlnaHQ6IDEyMCB9O1xyXG5cclxuZXhwb3J0IHZhciBURVhUX0FOTk9UQVRJT05fTUlOX0RJTUVOU0lPTlMgPSB7IHdpZHRoOiA1MCwgaGVpZ2h0OiAzMCB9O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBTZXQgbWluaW11bSBib3VuZHMvcmVzaXplIGNvbnN0cmFpbnRzIG9uIHJlc2l6ZS5cclxuICpcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlc2l6ZUJlaGF2aW9yKGV2ZW50QnVzKSB7XHJcbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5zdGFydCcsIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxyXG4gICAgICAgIGRpcmVjdGlvbiA9IGNvbnRleHQuZGlyZWN0aW9uLFxyXG4gICAgICAgIGJhbGFuY2VkID0gY29udGV4dC5iYWxhbmNlZDtcclxuXHJcbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkxhbmUnKSB8fCBpcyhzaGFwZSwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICBjb250ZXh0LnJlc2l6ZUNvbnN0cmFpbnRzID0gZ2V0UGFydGljaXBhbnRSZXNpemVDb25zdHJhaW50cyhzaGFwZSwgZGlyZWN0aW9uLCBiYWxhbmNlZCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICAgIGNvbnRleHQubWluRGltZW5zaW9ucyA9IFBBUlRJQ0lQQU5UX01JTl9ESU1FTlNJT05TO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpcyhzaGFwZSwgJ2JwbW46U3ViUHJvY2VzcycpICYmIGlzRXhwYW5kZWQoc2hhcGUpKSB7XHJcbiAgICAgIGNvbnRleHQubWluRGltZW5zaW9ucyA9IFNVQl9QUk9DRVNTX01JTl9ESU1FTlNJT05TO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpcyhzaGFwZSwgJ2JwbW46VGV4dEFubm90YXRpb24nKSkge1xyXG4gICAgICBjb250ZXh0Lm1pbkRpbWVuc2lvbnMgPSBURVhUX0FOTk9UQVRJT05fTUlOX0RJTUVOU0lPTlM7XHJcbiAgICB9XHJcbiAgfSk7XHJcbn1cclxuXHJcblJlc2l6ZUJlaGF2aW9yLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTsiLCJpbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgcm91bmRCb3VuZHNcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBoYXNQcmltYXJ5TW9kaWZpZXJcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9Nb3VzZSc7XG5cbnZhciBTTElHSFRMWV9ISUdIRVJfUFJJT1JJVFkgPSAxMDAxO1xuXG5cbi8qKlxuICogSW52b2tlIHtAbGluayBNb2RlbGluZyNyZXNpemVMYW5lfSBpbnN0ZWFkIG9mXG4gKiB7QGxpbmsgTW9kZWxpbmcjcmVzaXplU2hhcGV9IHdoZW4gcmVzaXppbmcgYSBMYW5lXG4gKiBvciBQYXJ0aWNpcGFudCBzaGFwZS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVzaXplTGFuZUJlaGF2aW9yKGV2ZW50QnVzLCBtb2RlbGluZykge1xuXG4gIGV2ZW50QnVzLm9uKCdyZXNpemUuc3RhcnQnLCBTTElHSFRMWV9ISUdIRVJfUFJJT1JJVFkgKyA1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaXMoc2hhcGUsICdicG1uOkxhbmUnKSB8fCBpcyhzaGFwZSwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuXG4gICAgICAvLyBzaG91bGQgd2UgcmVzaXplIHRoZSBvcHBvc2l0ZSBsYW5lKHMpIGluXG4gICAgICAvLyBvcmRlciB0byBjb21wZW5zYXRlIGZvciB0aGUgcmVzaXplIG9wZXJhdGlvbj9cbiAgICAgIGNvbnRleHQuYmFsYW5jZWQgPSAhaGFzUHJpbWFyeU1vZGlmaWVyKGV2ZW50KTtcbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBJbnRlcmNlcHQgcmVzaXplIGVuZCBhbmQgY2FsbCByZXNpemUgbGFuZSBmdW5jdGlvbiBpbnN0ZWFkLlxuICAgKi9cbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5lbmQnLCBTTElHSFRMWV9ISUdIRVJfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIGNhbkV4ZWN1dGUgPSBjb250ZXh0LmNhbkV4ZWN1dGUsXG4gICAgICAgIG5ld0JvdW5kcyA9IGNvbnRleHQubmV3Qm91bmRzO1xuXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpMYW5lJykgfHwgaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykpIHtcblxuICAgICAgaWYgKGNhbkV4ZWN1dGUpIHtcblxuICAgICAgICAvLyBlbnN1cmUgd2UgaGF2ZSBhY3R1YWwgcGl4ZWwgdmFsdWVzIGZvciBuZXcgYm91bmRzXG4gICAgICAgIC8vIChpbXBvcnRhbnQgd2hlbiB6b29tIGxldmVsIHdhcyA+IDEgZHVyaW5nIG1vdmUpXG4gICAgICAgIG5ld0JvdW5kcyA9IHJvdW5kQm91bmRzKG5ld0JvdW5kcyk7XG5cbiAgICAgICAgLy8gcGVyZm9ybSB0aGUgYWN0dWFsIHJlc2l6ZVxuICAgICAgICBtb2RlbGluZy5yZXNpemVMYW5lKHNoYXBlLCBuZXdCb3VuZHMsIGNvbnRleHQuYmFsYW5jZWQpO1xuICAgICAgfVxuXG4gICAgICAvLyBzdG9wIHByb3BhZ2F0aW9uXG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcbn1cblxuUmVzaXplTGFuZUJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xyXG5cclxuaW1wb3J0IHtcclxuICBmaW5kLFxyXG4gIGlzQXJyYXksXHJcbiAgbWF0Y2hQYXR0ZXJuLFxyXG4gIHNvbWVcclxufSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcclxuXHJcbmltcG9ydCB7XHJcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXHJcbiAgcmVtb3ZlIGFzIGNvbGxlY3Rpb25SZW1vdmVcclxufSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zJztcclxuXHJcbmltcG9ydCB7XHJcbiAgZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgaXNcclxufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0FueSB9IGZyb20gJy4uL3V0aWwvTW9kZWxpbmdVdGlsJztcclxuXHJcbmltcG9ydCB7IGhhc0V2ZW50RGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uL3V0aWwvRGlVdGlsJztcclxuXHJcbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XHJcblxyXG5cclxuLyoqXHJcbiAqIEFkZCByZWZlcmVuY2VkIHJvb3QgZWxlbWVudHMgKGVycm9yLCBlc2NhbGF0aW9uLCBtZXNzYWdlLCBzaWduYWwpIGlmIHRoZXkgZG9uJ3QgZXhpc3QuXHJcbiAqIENvcHkgcmVmZXJlbmNlZCByb290IGVsZW1lbnRzIG9uIGNvcHkgJiBwYXN0ZS5cclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3IoXHJcbiAgICBicG1uanMsIGV2ZW50QnVzLCBpbmplY3RvciwgbW9kZGxlQ29weSwgYnBtbkZhY3RvcnlcclxuKSB7XHJcbiAgaW5qZWN0b3IuaW52b2tlKENvbW1hbmRJbnRlcmNlcHRvciwgdGhpcyk7XHJcblxyXG4gIGZ1bmN0aW9uIGNhbkhhdmVSb290RWxlbWVudFJlZmVyZW5jZShlbGVtZW50KSB7XHJcbiAgICByZXR1cm4gaXNBbnkoZWxlbWVudCwgWyAnYnBtbjpSZWNlaXZlVGFzaycsICdicG1uOlNlbmRUYXNrJyBdKSB8fFxyXG4gICAgICBoYXNBbnlFdmVudERlZmluaXRpb24oZWxlbWVudCwgW1xyXG4gICAgICAgICdicG1uOkVycm9yRXZlbnREZWZpbml0aW9uJyxcclxuICAgICAgICAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJyxcclxuICAgICAgICAnYnBtbjpNZXNzYWdlRXZlbnREZWZpbml0aW9uJyxcclxuICAgICAgICAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nXHJcbiAgICAgIF0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gaGFzUm9vdEVsZW1lbnQocm9vdEVsZW1lbnQpIHtcclxuICAgIHZhciBkZWZpbml0aW9ucyA9IGJwbW5qcy5nZXREZWZpbml0aW9ucygpLFxyXG4gICAgICAgIHJvb3RFbGVtZW50cyA9IGRlZmluaXRpb25zLmdldCgncm9vdEVsZW1lbnRzJyk7XHJcblxyXG4gICAgcmV0dXJuICEhZmluZChyb290RWxlbWVudHMsIG1hdGNoUGF0dGVybih7IGlkOiByb290RWxlbWVudC5pZCB9KSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBnZXRSb290RWxlbWVudFJlZmVyZW5jZVByb3BlcnR5TmFtZShldmVudERlZmluaXRpb24pIHtcclxuICAgIGlmIChpcyhldmVudERlZmluaXRpb24sICdicG1uOkVycm9yRXZlbnREZWZpbml0aW9uJykpIHtcclxuICAgICAgcmV0dXJuICdlcnJvclJlZic7XHJcbiAgICB9IGVsc2UgaWYgKGlzKGV2ZW50RGVmaW5pdGlvbiwgJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicpKSB7XHJcbiAgICAgIHJldHVybiAnZXNjYWxhdGlvblJlZic7XHJcbiAgICB9IGVsc2UgaWYgKGlzKGV2ZW50RGVmaW5pdGlvbiwgJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbicpKSB7XHJcbiAgICAgIHJldHVybiAnbWVzc2FnZVJlZic7XHJcbiAgICB9IGVsc2UgaWYgKGlzKGV2ZW50RGVmaW5pdGlvbiwgJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJykpIHtcclxuICAgICAgcmV0dXJuICdzaWduYWxSZWYnO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0Um9vdEVsZW1lbnQoYnVzaW5lc3NPYmplY3QpIHtcclxuICAgIGlmIChpc0FueShidXNpbmVzc09iamVjdCwgWyAnYnBtbjpSZWNlaXZlVGFzaycsICdicG1uOlNlbmRUYXNrJyBdKSkge1xyXG4gICAgICByZXR1cm4gYnVzaW5lc3NPYmplY3QuZ2V0KCdtZXNzYWdlUmVmJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGV2ZW50RGVmaW5pdGlvbnMgPSBidXNpbmVzc09iamVjdC5nZXQoJ2V2ZW50RGVmaW5pdGlvbnMnKSxcclxuICAgICAgICBldmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25zWyAwIF07XHJcblxyXG4gICAgcmV0dXJuIGV2ZW50RGVmaW5pdGlvbi5nZXQoZ2V0Um9vdEVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eU5hbWUoZXZlbnREZWZpbml0aW9uKSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBzZXRSb290RWxlbWVudChidXNpbmVzc09iamVjdCwgcm9vdEVsZW1lbnQpIHtcclxuICAgIGlmIChpc0FueShidXNpbmVzc09iamVjdCwgWyAnYnBtbjpSZWNlaXZlVGFzaycsICdicG1uOlNlbmRUYXNrJyBdKSkge1xyXG4gICAgICByZXR1cm4gYnVzaW5lc3NPYmplY3Quc2V0KCdtZXNzYWdlUmVmJywgcm9vdEVsZW1lbnQpO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBldmVudERlZmluaXRpb25zID0gYnVzaW5lc3NPYmplY3QuZ2V0KCdldmVudERlZmluaXRpb25zJyksXHJcbiAgICAgICAgZXZlbnREZWZpbml0aW9uID0gZXZlbnREZWZpbml0aW9uc1sgMCBdO1xyXG5cclxuICAgIHJldHVybiBldmVudERlZmluaXRpb24uc2V0KGdldFJvb3RFbGVtZW50UmVmZXJlbmNlUHJvcGVydHlOYW1lKGV2ZW50RGVmaW5pdGlvbiksIHJvb3RFbGVtZW50KTtcclxuICB9XHJcblxyXG4gIC8vIGNyZWF0ZSBzaGFwZVxyXG4gIHRoaXMuZXhlY3V0ZWQoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XHJcblxyXG4gICAgaWYgKCFjYW5IYXZlUm9vdEVsZW1lbnRSZWZlcmVuY2Uoc2hhcGUpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChzaGFwZSksXHJcbiAgICAgICAgcm9vdEVsZW1lbnQgPSBnZXRSb290RWxlbWVudChidXNpbmVzc09iamVjdCksXHJcbiAgICAgICAgcm9vdEVsZW1lbnRzO1xyXG5cclxuICAgIGlmIChyb290RWxlbWVudCAmJiAhaGFzUm9vdEVsZW1lbnQocm9vdEVsZW1lbnQpKSB7XHJcbiAgICAgIHJvb3RFbGVtZW50cyA9IGJwbW5qcy5nZXREZWZpbml0aW9ucygpLmdldCgncm9vdEVsZW1lbnRzJyk7XHJcblxyXG4gICAgICAvLyBhZGQgcm9vdCBlbGVtZW50XHJcbiAgICAgIGNvbGxlY3Rpb25BZGQocm9vdEVsZW1lbnRzLCByb290RWxlbWVudCk7XHJcblxyXG4gICAgICBjb250ZXh0LmFkZGVkUm9vdEVsZW1lbnQgPSByb290RWxlbWVudDtcclxuICAgIH1cclxuICB9LCB0cnVlKTtcclxuXHJcbiAgdGhpcy5yZXZlcnRlZCgnc2hhcGUuY3JlYXRlJywgZnVuY3Rpb24oY29udGV4dCkge1xyXG4gICAgdmFyIGFkZGVkUm9vdEVsZW1lbnQgPSBjb250ZXh0LmFkZGVkUm9vdEVsZW1lbnQ7XHJcblxyXG4gICAgaWYgKCFhZGRlZFJvb3RFbGVtZW50KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgcm9vdEVsZW1lbnRzID0gYnBtbmpzLmdldERlZmluaXRpb25zKCkuZ2V0KCdyb290RWxlbWVudHMnKTtcclxuXHJcbiAgICAvLyByZW1vdmUgcm9vdCBlbGVtZW50XHJcbiAgICBjb2xsZWN0aW9uUmVtb3ZlKHJvb3RFbGVtZW50cywgYWRkZWRSb290RWxlbWVudCk7XHJcbiAgfSwgdHJ1ZSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdjb3B5UGFzdGUuY29weUVsZW1lbnQnLCBmdW5jdGlvbihjb250ZXh0KSB7XHJcbiAgICB2YXIgZGVzY3JpcHRvciA9IGNvbnRleHQuZGVzY3JpcHRvcixcclxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50O1xyXG5cclxuICAgIGlmICghY2FuSGF2ZVJvb3RFbGVtZW50UmVmZXJlbmNlKGVsZW1lbnQpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICByb290RWxlbWVudCA9IGdldFJvb3RFbGVtZW50KGJ1c2luZXNzT2JqZWN0KTtcclxuXHJcbiAgICBpZiAocm9vdEVsZW1lbnQpIHtcclxuICAgICAgZGVzY3JpcHRvci5yZWZlcmVuY2VkUm9vdEVsZW1lbnQgPSByb290RWxlbWVudDtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgZXZlbnRCdXMub24oJ2NvcHlQYXN0ZS5wYXN0ZUVsZW1lbnQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIHZhciBkZXNjcmlwdG9yID0gY29udGV4dC5kZXNjcmlwdG9yLFxyXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0ID0gZGVzY3JpcHRvci5idXNpbmVzc09iamVjdDtcclxuXHJcbiAgICBpZiAoIWNhbkhhdmVSb290RWxlbWVudFJlZmVyZW5jZShidXNpbmVzc09iamVjdCkpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciByZWZlcmVuY2VkUm9vdEVsZW1lbnQgPSBkZXNjcmlwdG9yLnJlZmVyZW5jZWRSb290RWxlbWVudDtcclxuXHJcbiAgICBpZiAoIXJlZmVyZW5jZWRSb290RWxlbWVudCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFoYXNSb290RWxlbWVudChyZWZlcmVuY2VkUm9vdEVsZW1lbnQpKSB7XHJcbiAgICAgIHJlZmVyZW5jZWRSb290RWxlbWVudCA9IG1vZGRsZUNvcHkuY29weUVsZW1lbnQoXHJcbiAgICAgICAgcmVmZXJlbmNlZFJvb3RFbGVtZW50LFxyXG4gICAgICAgIGJwbW5GYWN0b3J5LmNyZWF0ZShyZWZlcmVuY2VkUm9vdEVsZW1lbnQuJHR5cGUpXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0Um9vdEVsZW1lbnQoYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRSb290RWxlbWVudCk7XHJcbiAgfSk7XHJcbn1cclxuXHJcblJvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3IuJGluamVjdCA9IFtcclxuICAnYnBtbmpzJyxcclxuICAnZXZlbnRCdXMnLFxyXG4gICdpbmplY3RvcicsXHJcbiAgJ21vZGRsZUNvcHknLFxyXG4gICdicG1uRmFjdG9yeSdcclxuXTtcclxuXHJcbmluaGVyaXRzKFJvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIGhhc0FueUV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCB0eXBlcykge1xyXG4gIGlmICghaXNBcnJheSh0eXBlcykpIHtcclxuICAgIHR5cGVzID0gWyB0eXBlcyBdO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHNvbWUodHlwZXMsIGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgdHlwZSk7XHJcbiAgfSk7XHJcbn0iLCJpbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0V4cGFuZGVkIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9EaVV0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBMQU5FX01JTl9ESU1FTlNJT05TLFxyXG4gIFBBUlRJQ0lQQU5UX01JTl9ESU1FTlNJT05TLFxyXG4gIFNVQl9QUk9DRVNTX01JTl9ESU1FTlNJT05TLFxyXG4gIFRFWFRfQU5OT1RBVElPTl9NSU5fRElNRU5TSU9OU1xyXG59IGZyb20gJy4vUmVzaXplQmVoYXZpb3InO1xyXG5cclxuaW1wb3J0IHsgZ2V0Q2hpbGRMYW5lcyB9IGZyb20gJy4uL3V0aWwvTGFuZVV0aWwnO1xyXG5cclxudmFyIG1heCA9IE1hdGgubWF4O1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNwYWNlVG9vbEJlaGF2aW9yKGV2ZW50QnVzKSB7XHJcbiAgZXZlbnRCdXMub24oJ3NwYWNlVG9vbC5nZXRNaW5EaW1lbnNpb25zJywgZnVuY3Rpb24oY29udGV4dCkge1xyXG4gICAgdmFyIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzLFxyXG4gICAgICAgIGF4aXMgPSBjb250ZXh0LmF4aXMsXHJcbiAgICAgICAgc3RhcnQgPSBjb250ZXh0LnN0YXJ0LFxyXG4gICAgICAgIG1pbkRpbWVuc2lvbnMgPSB7fTtcclxuXHJcbiAgICBmb3JFYWNoKHNoYXBlcywgZnVuY3Rpb24oc2hhcGUpIHtcclxuICAgICAgdmFyIGlkID0gc2hhcGUuaWQ7XHJcblxyXG4gICAgICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuXHJcbiAgICAgICAgaWYgKGlzSG9yaXpvbnRhbChheGlzKSkge1xyXG4gICAgICAgICAgbWluRGltZW5zaW9uc1sgaWQgXSA9IFBBUlRJQ0lQQU5UX01JTl9ESU1FTlNJT05TO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBtaW5EaW1lbnNpb25zWyBpZCBdID0ge1xyXG4gICAgICAgICAgICB3aWR0aDogUEFSVElDSVBBTlRfTUlOX0RJTUVOU0lPTlMud2lkdGgsXHJcbiAgICAgICAgICAgIGhlaWdodDogZ2V0UGFydGljaXBhbnRNaW5IZWlnaHQoc2hhcGUsIHN0YXJ0KVxyXG4gICAgICAgICAgfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXMoc2hhcGUsICdicG1uOlN1YlByb2Nlc3MnKSAmJiBpc0V4cGFuZGVkKHNoYXBlKSkge1xyXG4gICAgICAgIG1pbkRpbWVuc2lvbnNbIGlkIF0gPSBTVUJfUFJPQ0VTU19NSU5fRElNRU5TSU9OUztcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpUZXh0QW5ub3RhdGlvbicpKSB7XHJcbiAgICAgICAgbWluRGltZW5zaW9uc1sgaWQgXSA9IFRFWFRfQU5OT1RBVElPTl9NSU5fRElNRU5TSU9OUztcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIG1pbkRpbWVuc2lvbnM7XHJcbiAgfSk7XHJcbn1cclxuXHJcblNwYWNlVG9vbEJlaGF2aW9yLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTtcclxuXHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuZnVuY3Rpb24gaXNIb3Jpem9udGFsKGF4aXMpIHtcclxuICByZXR1cm4gYXhpcyA9PT0gJ3gnO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IG1pbmltdW0gaGVpZ2h0IGZvciBwYXJ0aWNpcGFudCB0YWtpbmcgbGFuZXMgaW50byBhY2NvdW50LlxyXG4gKlxyXG4gKiBAcGFyYW0gezxkanMubW9kZWwuU2hhcGU+fSBwYXJ0aWNpcGFudFxyXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnRcclxuICpcclxuICogQHJldHVybnMge09iamVjdH1cclxuICovXHJcbmZ1bmN0aW9uIGdldFBhcnRpY2lwYW50TWluSGVpZ2h0KHBhcnRpY2lwYW50LCBzdGFydCkge1xyXG4gIHZhciBsYW5lc01pbkhlaWdodDtcclxuXHJcbiAgaWYgKCFoYXNDaGlsZExhbmVzKHBhcnRpY2lwYW50KSkge1xyXG4gICAgcmV0dXJuIFBBUlRJQ0lQQU5UX01JTl9ESU1FTlNJT05TLmhlaWdodDtcclxuICB9XHJcblxyXG4gIGxhbmVzTWluSGVpZ2h0ID0gZ2V0TGFuZXNNaW5IZWlnaHQocGFydGljaXBhbnQsIHN0YXJ0KTtcclxuXHJcbiAgcmV0dXJuIG1heChQQVJUSUNJUEFOVF9NSU5fRElNRU5TSU9OUy5oZWlnaHQsIGxhbmVzTWluSGVpZ2h0KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaGFzQ2hpbGRMYW5lcyhlbGVtZW50KSB7XHJcbiAgcmV0dXJuICEhZ2V0Q2hpbGRMYW5lcyhlbGVtZW50KS5sZW5ndGg7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldExhbmVzTWluSGVpZ2h0KHBhcnRpY2lwYW50LCByZXNpemVTdGFydCkge1xyXG4gIHZhciBsYW5lcyA9IGdldENoaWxkTGFuZXMocGFydGljaXBhbnQpLFxyXG4gICAgICByZXNpemVkTGFuZTtcclxuXHJcbiAgLy8gZmluZCB0aGUgbmVzdGVkIGxhbmUgd2hpY2ggaXMgY3VycmVudGx5IHJlc2l6ZWRcclxuICByZXNpemVkTGFuZSA9IGZpbmRSZXNpemVkTGFuZShsYW5lcywgcmVzaXplU3RhcnQpO1xyXG5cclxuICAvLyByZXNpemVkIGxhbmUgY2Fubm90IHNocmluayBiZWxvdyB0aGUgbWluaW11bSBoZWlnaHRcclxuICAvLyBidXQgcmVtYWluaW5nIGxhbmVzJyBkaW1lbnNpb25zIGFyZSBrZXB0IGludGFjdFxyXG4gIHJldHVybiBwYXJ0aWNpcGFudC5oZWlnaHQgLSByZXNpemVkTGFuZS5oZWlnaHQgKyBMQU5FX01JTl9ESU1FTlNJT05TLmhlaWdodDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbmQgbmVzdGVkIGxhbmUgd2hpY2ggaXMgY3VycmVudGx5IHJlc2l6ZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLlNoYXBlPn0gbGFuZXNcclxuICogQHBhcmFtIHtudW1iZXJ9IHJlc2l6ZVN0YXJ0XHJcbiAqL1xyXG5mdW5jdGlvbiBmaW5kUmVzaXplZExhbmUobGFuZXMsIHJlc2l6ZVN0YXJ0KSB7XHJcbiAgdmFyIGksIGxhbmUsIGNoaWxkTGFuZXM7XHJcblxyXG4gIGZvciAoaSA9IDA7IGkgPCBsYW5lcy5sZW5ndGg7IGkrKykge1xyXG4gICAgbGFuZSA9IGxhbmVzW2ldO1xyXG5cclxuICAgIC8vIHJlc2l6aW5nIGN1cnJlbnQgbGFuZSBvciBhIGxhbmUgbmVzdGVkXHJcbiAgICBpZiAocmVzaXplU3RhcnQgPj0gbGFuZS55ICYmIHJlc2l6ZVN0YXJ0IDw9IGxhbmUueSArIGxhbmUuaGVpZ2h0KSB7XHJcbiAgICAgIGNoaWxkTGFuZXMgPSBnZXRDaGlsZExhbmVzKGxhbmUpO1xyXG5cclxuICAgICAgLy8gYSBuZXN0ZWQgbGFuZSBpcyByZXNpemVkXHJcbiAgICAgIGlmIChjaGlsZExhbmVzLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBmaW5kUmVzaXplZExhbmUoY2hpbGRMYW5lcywgcmVzaXplU3RhcnQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBjdXJyZW50IGxhbmUgaXMgdGhlIHJlc2l6ZWQgb25lXHJcbiAgICAgIHJldHVybiBsYW5lO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5pbXBvcnQgeyBpc0V4cGFuZGVkIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9EaVV0aWwuanMnO1xuXG4vKipcbiAqIEFkZCBzdGFydCBldmVudCByZXBsYWNpbmcgZWxlbWVudCB3aXRoIGV4cGFuZGVkIHN1YiBwcm9jZXNzLlxuICpcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBTdWJQcm9jZXNzU3RhcnRFdmVudEJlaGF2aW9yKGluamVjdG9yLCBtb2RlbGluZykge1xuICBpbmplY3Rvci5pbnZva2UoQ29tbWFuZEludGVyY2VwdG9yLCB0aGlzKTtcblxuICB0aGlzLnBvc3RFeGVjdXRlZCgnc2hhcGUucmVwbGFjZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIG9sZFNoYXBlID0gZXZlbnQuY29udGV4dC5vbGRTaGFwZSxcbiAgICAgICAgbmV3U2hhcGUgPSBldmVudC5jb250ZXh0Lm5ld1NoYXBlO1xuXG4gICAgaWYgKFxuICAgICAgIWlzKG5ld1NoYXBlLCAnYnBtbjpTdWJQcm9jZXNzJykgfHxcbiAgICAgICFpcyhvbGRTaGFwZSwgJ2JwbW46VGFzaycpIHx8XG4gICAgICAhaXNFeHBhbmRlZChuZXdTaGFwZSlcbiAgICApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcG9zaXRpb24gPSBnZXRTdGFydEV2ZW50UG9zaXRpb24obmV3U2hhcGUpO1xuXG4gICAgbW9kZWxpbmcuY3JlYXRlU2hhcGUoeyB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyB9LCBwb3NpdGlvbiwgbmV3U2hhcGUpO1xuICB9KTtcbn1cblxuU3ViUHJvY2Vzc1N0YXJ0RXZlbnRCZWhhdmlvci4kaW5qZWN0ID0gW1xuICAnaW5qZWN0b3InLFxuICAnbW9kZWxpbmcnXG5dO1xuXG5pbmhlcml0cyhTdWJQcm9jZXNzU3RhcnRFdmVudEJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZ2V0U3RhcnRFdmVudFBvc2l0aW9uKHNoYXBlKSB7XG4gIHJldHVybiB7XG4gICAgeDogc2hhcGUueCArIHNoYXBlLndpZHRoIC8gNixcbiAgICB5OiBzaGFwZS55ICsgc2hhcGUuaGVpZ2h0IC8gMlxuICB9O1xufVxuIiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGNvbXB1dGVDaGlsZHJlbkJCb3hcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcmVzaXplL1Jlc2l6ZVV0aWwnO1xuXG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVG9nZ2xlRWxlbWVudENvbGxhcHNlQmVoYXZpb3VyKFxuICAgIGV2ZW50QnVzLCBlbGVtZW50RmFjdG9yeSwgbW9kZWxpbmcsXG4gICAgcmVzaXplKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG5cbiAgZnVuY3Rpb24gaGlkZUVtcHR5TGFiZWxzKGNoaWxkcmVuKSB7XG4gICAgaWYgKGNoaWxkcmVuLmxlbmd0aCkge1xuICAgICAgY2hpbGRyZW4uZm9yRWFjaChmdW5jdGlvbihjaGlsZCkge1xuICAgICAgICBpZiAoY2hpbGQudHlwZSA9PT0gJ2xhYmVsJyAmJiAhY2hpbGQuYnVzaW5lc3NPYmplY3QubmFtZSkge1xuICAgICAgICAgIGNoaWxkLmhpZGRlbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGV4cGFuZGVkQm91bmRzKHNoYXBlLCBkZWZhdWx0U2l6ZSkge1xuICAgIHZhciBjaGlsZHJlbiA9IHNoYXBlLmNoaWxkcmVuLFxuICAgICAgICBuZXdCb3VuZHMgPSBkZWZhdWx0U2l6ZSxcbiAgICAgICAgdmlzaWJsZUVsZW1lbnRzLFxuICAgICAgICB2aXNpYmxlQkJveDtcblxuICAgIHZpc2libGVFbGVtZW50cyA9IGZpbHRlclZpc2libGUoY2hpbGRyZW4pLmNvbmNhdChbIHNoYXBlIF0pO1xuXG4gICAgdmlzaWJsZUJCb3ggPSBjb21wdXRlQ2hpbGRyZW5CQm94KHZpc2libGVFbGVtZW50cyk7XG5cbiAgICBpZiAodmlzaWJsZUJCb3gpIHtcblxuICAgICAgLy8gY2VudGVyIHRvIHZpc2libGVCQm94IHdpdGggbWF4KGRlZmF1bHRTaXplLCBjaGlsZHJlbkJvdW5kcylcbiAgICAgIG5ld0JvdW5kcy53aWR0aCA9IE1hdGgubWF4KHZpc2libGVCQm94LndpZHRoLCBuZXdCb3VuZHMud2lkdGgpO1xuICAgICAgbmV3Qm91bmRzLmhlaWdodCA9IE1hdGgubWF4KHZpc2libGVCQm94LmhlaWdodCwgbmV3Qm91bmRzLmhlaWdodCk7XG5cbiAgICAgIG5ld0JvdW5kcy54ID0gdmlzaWJsZUJCb3gueCArICh2aXNpYmxlQkJveC53aWR0aCAtIG5ld0JvdW5kcy53aWR0aCkgLyAyO1xuICAgICAgbmV3Qm91bmRzLnkgPSB2aXNpYmxlQkJveC55ICsgKHZpc2libGVCQm94LmhlaWdodCAtIG5ld0JvdW5kcy5oZWlnaHQpIC8gMjtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBjZW50ZXIgdG8gY29sbGFwc2VkIHNoYXBlIHdpdGggZGVmYXVsdFNpemVcbiAgICAgIG5ld0JvdW5kcy54ID0gc2hhcGUueCArIChzaGFwZS53aWR0aCAtIG5ld0JvdW5kcy53aWR0aCkgLyAyO1xuICAgICAgbmV3Qm91bmRzLnkgPSBzaGFwZS55ICsgKHNoYXBlLmhlaWdodCAtIG5ld0JvdW5kcy5oZWlnaHQpIC8gMjtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3Qm91bmRzO1xuICB9XG5cbiAgZnVuY3Rpb24gY29sbGFwc2VkQm91bmRzKHNoYXBlLCBkZWZhdWx0U2l6ZSkge1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHNoYXBlLnggKyAoc2hhcGUud2lkdGggLSBkZWZhdWx0U2l6ZS53aWR0aCkgLyAyLFxuICAgICAgeTogc2hhcGUueSArIChzaGFwZS5oZWlnaHQgLSBkZWZhdWx0U2l6ZS5oZWlnaHQpIC8gMixcbiAgICAgIHdpZHRoOiBkZWZhdWx0U2l6ZS53aWR0aCxcbiAgICAgIGhlaWdodDogZGVmYXVsdFNpemUuaGVpZ2h0XG4gICAgfTtcbiAgfVxuXG4gIHRoaXMuZXhlY3V0ZWQoWyAnc2hhcGUudG9nZ2xlQ29sbGFwc2UnIF0sIExPV19QUklPUklUWSwgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZTtcblxuICAgIGlmICghaXMoc2hhcGUsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghc2hhcGUuY29sbGFwc2VkKSB7XG5cbiAgICAgIC8vIGFsbCBjaGlsZHJlbiBnb3QgbWFkZSB2aXNpYmxlIHRocm91Z2ggZGpzLCBoaWRlIGVtcHR5IGxhYmVsc1xuICAgICAgaGlkZUVtcHR5TGFiZWxzKHNoYXBlLmNoaWxkcmVuKTtcblxuICAgICAgLy8gcmVtb3ZlIGNvbGxhcHNlZCBtYXJrZXJcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0KHNoYXBlKS5kaS5pc0V4cGFuZGVkID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBwbGFjZSBjb2xsYXBzZWQgbWFya2VyXG4gICAgICBnZXRCdXNpbmVzc09iamVjdChzaGFwZSkuZGkuaXNFeHBhbmRlZCA9IGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5yZXZlcnRlZChbICdzaGFwZS50b2dnbGVDb2xsYXBzZScgXSwgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dDtcbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG5cbiAgICAvLyByZXZlcnQgcmVtb3ZpbmcvcGxhY2luZyBjb2xsYXBzZWQgbWFya2VyXG4gICAgaWYgKCFzaGFwZS5jb2xsYXBzZWQpIHtcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0KHNoYXBlKS5kaS5pc0V4cGFuZGVkID0gdHJ1ZTtcblxuICAgIH0gZWxzZSB7XG4gICAgICBnZXRCdXNpbmVzc09iamVjdChzaGFwZSkuZGkuaXNFeHBhbmRlZCA9IGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoWyAnc2hhcGUudG9nZ2xlQ29sbGFwc2UnIF0sIExPV19QUklPUklUWSwgZnVuY3Rpb24oZSkge1xuICAgIHZhciBzaGFwZSA9IGUuY29udGV4dC5zaGFwZSxcbiAgICAgICAgZGVmYXVsdFNpemUgPSBlbGVtZW50RmFjdG9yeS5fZ2V0RGVmYXVsdFNpemUoc2hhcGUpLFxuICAgICAgICBuZXdCb3VuZHM7XG5cbiAgICBpZiAoc2hhcGUuY29sbGFwc2VkKSB7XG5cbiAgICAgIC8vIHJlc2l6ZSB0byBkZWZhdWx0IHNpemUgb2YgY29sbGFwc2VkIHNoYXBlc1xuICAgICAgbmV3Qm91bmRzID0gY29sbGFwc2VkQm91bmRzKHNoYXBlLCBkZWZhdWx0U2l6ZSk7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gcmVzaXplIHRvIGJvdW5kcyBvZiBtYXgodmlzaWJsZSBjaGlsZHJlbiwgZGVmYXVsdFNpemUpXG4gICAgICBuZXdCb3VuZHMgPSBleHBhbmRlZEJvdW5kcyhzaGFwZSwgZGVmYXVsdFNpemUpO1xuICAgIH1cblxuICAgIG1vZGVsaW5nLnJlc2l6ZVNoYXBlKHNoYXBlLCBuZXdCb3VuZHMsIG51bGwsIHtcbiAgICAgIGF1dG9SZXNpemU6IHNoYXBlLmNvbGxhcHNlZCA/IGZhbHNlIDogJ253c2UnXG4gICAgfSk7XG4gIH0pO1xuXG59XG5cblxuaW5oZXJpdHMoVG9nZ2xlRWxlbWVudENvbGxhcHNlQmVoYXZpb3VyLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuXG5Ub2dnbGVFbGVtZW50Q29sbGFwc2VCZWhhdmlvdXIuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZmlsdGVyVmlzaWJsZShlbGVtZW50cykge1xuICByZXR1cm4gZWxlbWVudHMuZmlsdGVyKGZ1bmN0aW9uKGUpIHtcbiAgICByZXR1cm4gIWUuaGlkZGVuO1xuICB9KTtcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5pbXBvcnQgeyBpc0V4cGFuZGVkIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9EaVV0aWwnO1xuaW1wb3J0IHsgaXNMYWJlbCB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTGFiZWxVdGlsJztcblxuXG4vKipcbiAqIFVuY2xhaW1zIG1vZGVsIElEcyBvbiBlbGVtZW50IGRlbGV0aW9uLlxuICpcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKiBAcGFyYW0ge01vZGRsZX0gbW9kZGxlXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBVbmNsYWltSWRCZWhhdmlvcihjYW52YXMsIGluamVjdG9yLCBtb2RkbGUsIG1vZGVsaW5nKSB7XG4gIGluamVjdG9yLmludm9rZShDb21tYW5kSW50ZXJjZXB0b3IsIHRoaXMpO1xuXG4gIHRoaXMucHJlRXhlY3V0ZSgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgc2hhcGVCbyA9IHNoYXBlLmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgaWYgKGlzTGFiZWwoc2hhcGUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGlzKHNoYXBlLCAnYnBtbjpQYXJ0aWNpcGFudCcpICYmIGlzRXhwYW5kZWQoc2hhcGUpKSB7XG4gICAgICBtb2RkbGUuaWRzLnVuY2xhaW0oc2hhcGVCby5wcm9jZXNzUmVmLmlkKTtcbiAgICB9XG5cbiAgICBtb2RlbGluZy51bmNsYWltSWQoc2hhcGVCby5pZCwgc2hhcGVCbyk7XG4gIH0pO1xuXG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdjb25uZWN0aW9uLmRlbGV0ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBjb25uZWN0aW9uQm8gPSBjb25uZWN0aW9uLmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgbW9kZWxpbmcudW5jbGFpbUlkKGNvbm5lY3Rpb25Cby5pZCwgY29ubmVjdGlvbkJvKTtcbiAgfSk7XG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdjYW52YXMudXBkYXRlUm9vdCcsIGZ1bmN0aW9uKCkge1xuICAgIHZhciByb290RWxlbWVudCA9IGNhbnZhcy5nZXRSb290RWxlbWVudCgpLFxuICAgICAgICByb290RWxlbWVudEJvID0gcm9vdEVsZW1lbnQuYnVzaW5lc3NPYmplY3Q7XG5cbiAgICBtb2RkbGUuaWRzLnVuY2xhaW0ocm9vdEVsZW1lbnRCby5pZCk7XG4gIH0pO1xufVxuXG5pbmhlcml0cyhVbmNsYWltSWRCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuVW5jbGFpbUlkQmVoYXZpb3IuJGluamVjdCA9IFsgJ2NhbnZhcycsICdpbmplY3RvcicsICdtb2RkbGUnLCAnbW9kZWxpbmcnIF07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0LFxuICBpc1xufSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cblxuLyoqXG4gKiBBIGJlaGF2aW9yIHRoYXQgdW5zZXRzIHRoZSBEZWZhdWx0IHByb3BlcnR5IG9mXG4gKiBzZXF1ZW5jZSBmbG93IHNvdXJjZSBvbiBlbGVtZW50IGRlbGV0ZSwgaWYgdGhlXG4gKiByZW1vdmVkIGVsZW1lbnQgaXMgdGhlIEdhdGV3YXkgb3IgVGFzaydzIGRlZmF1bHQgZmxvdy5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRGVsZXRlU2VxdWVuY2VGbG93QmVoYXZpb3IoZXZlbnRCdXMsIG1vZGVsaW5nKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG5cbiAgdGhpcy5wcmVFeGVjdXRlKCdjb25uZWN0aW9uLmRlbGV0ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBzb3VyY2UgPSBjb25uZWN0aW9uLnNvdXJjZTtcblxuICAgIGlmIChpc0RlZmF1bHRGbG93KGNvbm5lY3Rpb24sIHNvdXJjZSkpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoc291cmNlLCB7XG4gICAgICAgICdkZWZhdWx0JzogbnVsbFxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbn1cblxuaW5oZXJpdHMoRGVsZXRlU2VxdWVuY2VGbG93QmVoYXZpb3IsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cbkRlbGV0ZVNlcXVlbmNlRmxvd0JlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGlzRGVmYXVsdEZsb3coY29ubmVjdGlvbiwgc291cmNlKSB7XG5cbiAgaWYgKCFpcyhjb25uZWN0aW9uLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBzb3VyY2VCbyA9IGdldEJ1c2luZXNzT2JqZWN0KHNvdXJjZSksXG4gICAgICBzZXF1ZW5jZUZsb3cgPSBnZXRCdXNpbmVzc09iamVjdChjb25uZWN0aW9uKTtcblxuICByZXR1cm4gc291cmNlQm8uZ2V0KCdkZWZhdWx0JykgPT09IHNlcXVlbmNlRmxvdztcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuaW1wb3J0IHtcbiAgaXNcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gNTAwLFxuICAgIEhJR0hfUFJJT1JJVFkgPSA1MDAwO1xuXG5cbi8qKlxuICogQlBNTiBzcGVjaWZpYyBkZWxldGUgbGFuZSBiZWhhdmlvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBVcGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvcihldmVudEJ1cywgbW9kZWxpbmcsIHRyYW5zbGF0ZSkge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuICAvKipcbiAgICogT2ssIHRoaXMgaXMgaXQ6XG4gICAqXG4gICAqIFdlIGhhdmUgdG8gdXBkYXRlIHRoZSBMYW5lI2Zsb3dOb2RlUmVmcyBfYW5kX1xuICAgKiBGbG93Tm9kZSNsYW5lcyB3aXRoIGV2ZXJ5IEZsb3dOb2RlIG1vdmUvcmVzaXplIGFuZFxuICAgKiBMYW5lIG1vdmUvcmVzaXplLlxuICAgKlxuICAgKiBXZSB3YW50IHRvIGdyb3VwIHRoYXQgc3R1ZmYgdG8gcmVjb21wdXRlIGNvbnRhaW5tZW50c1xuICAgKiBhcyBlZmZpY2llbnQgYXMgcG9zc2libGUuXG4gICAqXG4gICAqIFllYSFcbiAgICovXG5cbiAgLy8gdGhlIHVwZGF0ZSBjb250ZXh0XG4gIHZhciBjb250ZXh0O1xuXG5cbiAgZnVuY3Rpb24gaW5pdENvbnRleHQoKSB7XG4gICAgY29udGV4dCA9IGNvbnRleHQgfHwgbmV3IFVwZGF0ZUNvbnRleHQoKTtcbiAgICBjb250ZXh0LmVudGVyKCk7XG5cbiAgICByZXR1cm4gY29udGV4dDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldENvbnRleHQoKSB7XG4gICAgaWYgKCFjb250ZXh0KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IodHJhbnNsYXRlKCdvdXQgb2YgYm91bmRzIHJlbGVhc2UnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnRleHQ7XG4gIH1cblxuICBmdW5jdGlvbiByZWxlYXNlQ29udGV4dCgpIHtcblxuICAgIGlmICghY29udGV4dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnb3V0IG9mIGJvdW5kcyByZWxlYXNlJykpO1xuICAgIH1cblxuICAgIHZhciB0cmlnZ2VyVXBkYXRlID0gY29udGV4dC5sZWF2ZSgpO1xuXG4gICAgaWYgKHRyaWdnZXJVcGRhdGUpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZUxhbmVSZWZzKGNvbnRleHQuZmxvd05vZGVzLCBjb250ZXh0LmxhbmVzKTtcblxuICAgICAgY29udGV4dCA9IG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRyaWdnZXJVcGRhdGU7XG4gIH1cblxuXG4gIHZhciBsYW5lUmVmVXBkYXRlRXZlbnRzID0gW1xuICAgICdzcGFjZVRvb2wnLFxuICAgICdsYW5lLmFkZCcsXG4gICAgJ2xhbmUucmVzaXplJyxcbiAgICAnbGFuZS5zcGxpdCcsXG4gICAgJ2VsZW1lbnRzLmNyZWF0ZScsXG4gICAgJ2VsZW1lbnRzLmRlbGV0ZScsXG4gICAgJ2VsZW1lbnRzLm1vdmUnLFxuICAgICdzaGFwZS5jcmVhdGUnLFxuICAgICdzaGFwZS5kZWxldGUnLFxuICAgICdzaGFwZS5tb3ZlJyxcbiAgICAnc2hhcGUucmVzaXplJ1xuICBdO1xuXG5cbiAgLy8gbGlzdGVuIHRvIGEgbG90IG9mIHN0dWZmIHRvIGdyb3VwIGxhbmUgdXBkYXRlc1xuXG4gIHRoaXMucHJlRXhlY3V0ZShsYW5lUmVmVXBkYXRlRXZlbnRzLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIGluaXRDb250ZXh0KCk7XG4gIH0pO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKGxhbmVSZWZVcGRhdGVFdmVudHMsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICByZWxlYXNlQ29udGV4dCgpO1xuICB9KTtcblxuXG4gIC8vIE1hcmsgZmxvdyBub2RlcyArIGxhbmVzIHRoYXQgbmVlZCBhbiB1cGRhdGVcblxuICB0aGlzLnByZUV4ZWN1dGUoW1xuICAgICdzaGFwZS5jcmVhdGUnLFxuICAgICdzaGFwZS5tb3ZlJyxcbiAgICAnc2hhcGUuZGVsZXRlJyxcbiAgICAnc2hhcGUucmVzaXplJ1xuICBdLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICB2YXIgdXBkYXRlQ29udGV4dCA9IGdldENvbnRleHQoKTtcblxuICAgIC8vIG5vIG5lZWQgdG8gdXBkYXRlIGxhYmVsc1xuICAgIGlmIChzaGFwZS5sYWJlbFRhcmdldCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChpcyhzaGFwZSwgJ2JwbW46TGFuZScpKSB7XG4gICAgICB1cGRhdGVDb250ZXh0LmFkZExhbmUoc2hhcGUpO1xuICAgIH1cblxuICAgIGlmIChpcyhzaGFwZSwgJ2JwbW46Rmxvd05vZGUnKSkge1xuICAgICAgdXBkYXRlQ29udGV4dC5hZGRGbG93Tm9kZShzaGFwZSk7XG4gICAgfVxuICB9KTtcbn1cblxuVXBkYXRlRmxvd05vZGVSZWZzQmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGVsaW5nJyAsXG4gICd0cmFuc2xhdGUnXG5dO1xuXG5pbmhlcml0cyhVcGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvciwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuXG5mdW5jdGlvbiBVcGRhdGVDb250ZXh0KCkge1xuXG4gIHRoaXMuZmxvd05vZGVzID0gW107XG4gIHRoaXMubGFuZXMgPSBbXTtcblxuICB0aGlzLmNvdW50ZXIgPSAwO1xuXG4gIHRoaXMuYWRkTGFuZSA9IGZ1bmN0aW9uKGxhbmUpIHtcbiAgICB0aGlzLmxhbmVzLnB1c2gobGFuZSk7XG4gIH07XG5cbiAgdGhpcy5hZGRGbG93Tm9kZSA9IGZ1bmN0aW9uKGZsb3dOb2RlKSB7XG4gICAgdGhpcy5mbG93Tm9kZXMucHVzaChmbG93Tm9kZSk7XG4gIH07XG5cbiAgdGhpcy5lbnRlciA9IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuY291bnRlcisrO1xuICB9O1xuXG4gIHRoaXMubGVhdmUgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLmNvdW50ZXItLTtcblxuICAgIHJldHVybiAhdGhpcy5jb3VudGVyO1xuICB9O1xufSIsImltcG9ydCBBZGFwdGl2ZUxhYmVsUG9zaXRpb25pbmdCZWhhdmlvciBmcm9tICcuL0FkYXB0aXZlTGFiZWxQb3NpdGlvbmluZ0JlaGF2aW9yJztcbmltcG9ydCBBcHBlbmRCZWhhdmlvciBmcm9tICcuL0FwcGVuZEJlaGF2aW9yJztcbmltcG9ydCBBc3NvY2lhdGlvbkJlaGF2aW9yIGZyb20gJy4vQXNzb2NpYXRpb25CZWhhdmlvcic7XG5pbXBvcnQgQXR0YWNoRXZlbnRCZWhhdmlvciBmcm9tICcuL0F0dGFjaEV2ZW50QmVoYXZpb3InO1xuaW1wb3J0IEJvdW5kYXJ5RXZlbnRCZWhhdmlvciBmcm9tICcuL0JvdW5kYXJ5RXZlbnRCZWhhdmlvcic7XG5pbXBvcnQgUm9vdEVsZW1lbnRSZWZlcmVuY2VCZWhhdmlvciBmcm9tICcuL1Jvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3InO1xuaW1wb3J0IENyZWF0ZUJlaGF2aW9yIGZyb20gJy4vQ3JlYXRlQmVoYXZpb3InO1xuaW1wb3J0IEZpeEhvdmVyQmVoYXZpb3IgZnJvbSAnLi9GaXhIb3ZlckJlaGF2aW9yJztcbmltcG9ydCBDcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3IgZnJvbSAnLi9DcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3InO1xuaW1wb3J0IENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IgZnJvbSAnLi9DcmVhdGVQYXJ0aWNpcGFudEJlaGF2aW9yJztcbmltcG9ydCBEYXRhSW5wdXRBc3NvY2lhdGlvbkJlaGF2aW9yIGZyb20gJy4vRGF0YUlucHV0QXNzb2NpYXRpb25CZWhhdmlvcic7XG5pbXBvcnQgRGF0YVN0b3JlQmVoYXZpb3IgZnJvbSAnLi9EYXRhU3RvcmVCZWhhdmlvcic7XG5pbXBvcnQgRGVsZXRlTGFuZUJlaGF2aW9yIGZyb20gJy4vRGVsZXRlTGFuZUJlaGF2aW9yJztcbmltcG9ydCBEZXRhY2hFdmVudEJlaGF2aW9yIGZyb20gJy4vRGV0YWNoRXZlbnRCZWhhdmlvcic7XG5pbXBvcnQgRHJvcE9uRmxvd0JlaGF2aW9yIGZyb20gJy4vRHJvcE9uRmxvd0JlaGF2aW9yJztcbmltcG9ydCBFdmVudEJhc2VkR2F0ZXdheUJlaGF2aW9yIGZyb20gJy4vRXZlbnRCYXNlZEdhdGV3YXlCZWhhdmlvcic7XG5pbXBvcnQgR3JvdXBCZWhhdmlvciBmcm9tICcuL0dyb3VwQmVoYXZpb3InO1xuaW1wb3J0IEltcG9ydERvY2tpbmdGaXggZnJvbSAnLi9JbXBvcnREb2NraW5nRml4JztcbmltcG9ydCBJc0hvcml6b250YWxGaXggZnJvbSAnLi9Jc0hvcml6b250YWxGaXgnO1xuaW1wb3J0IExhYmVsQmVoYXZpb3IgZnJvbSAnLi9MYWJlbEJlaGF2aW9yJztcbmltcG9ydCBNb2RlbGluZ0ZlZWRiYWNrIGZyb20gJy4vTW9kZWxpbmdGZWVkYmFjayc7XG5pbXBvcnQgUmVwbGFjZUNvbm5lY3Rpb25CZWhhdmlvciBmcm9tICcuL1JlcGxhY2VDb25uZWN0aW9uQmVoYXZpb3InO1xuaW1wb3J0IFJlbW92ZVBhcnRpY2lwYW50QmVoYXZpb3IgZnJvbSAnLi9SZW1vdmVQYXJ0aWNpcGFudEJlaGF2aW9yJztcbmltcG9ydCBSZXBsYWNlRWxlbWVudEJlaGF2aW91ciBmcm9tICcuL1JlcGxhY2VFbGVtZW50QmVoYXZpb3VyJztcbmltcG9ydCBSZXNpemVCZWhhdmlvciBmcm9tICcuL1Jlc2l6ZUJlaGF2aW9yJztcbmltcG9ydCBSZXNpemVMYW5lQmVoYXZpb3IgZnJvbSAnLi9SZXNpemVMYW5lQmVoYXZpb3InO1xuaW1wb3J0IFJlbW92ZUVsZW1lbnRCZWhhdmlvciBmcm9tICcuL1JlbW92ZUVsZW1lbnRCZWhhdmlvcic7XG5pbXBvcnQgU3BhY2VUb29sQmVoYXZpb3IgZnJvbSAnLi9TcGFjZVRvb2xCZWhhdmlvcic7XG5pbXBvcnQgU3ViUHJvY2Vzc1N0YXJ0RXZlbnRCZWhhdmlvciBmcm9tICcuL1N1YlByb2Nlc3NTdGFydEV2ZW50QmVoYXZpb3InO1xuaW1wb3J0IFRvZ2dsZUVsZW1lbnRDb2xsYXBzZUJlaGF2aW91ciBmcm9tICcuL1RvZ2dsZUVsZW1lbnRDb2xsYXBzZUJlaGF2aW91cic7XG5pbXBvcnQgVW5jbGFpbUlkQmVoYXZpb3IgZnJvbSAnLi9VbmNsYWltSWRCZWhhdmlvcic7XG5pbXBvcnQgVXBkYXRlRmxvd05vZGVSZWZzQmVoYXZpb3IgZnJvbSAnLi9VcGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvcic7XG5pbXBvcnQgVW5zZXREZWZhdWx0Rmxvd0JlaGF2aW9yIGZyb20gJy4vVW5zZXREZWZhdWx0Rmxvd0JlaGF2aW9yJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogW1xuICAgICdhZGFwdGl2ZUxhYmVsUG9zaXRpb25pbmdCZWhhdmlvcicsXG4gICAgJ2FwcGVuZEJlaGF2aW9yJyxcbiAgICAnYXNzb2NpYXRpb25CZWhhdmlvcicsXG4gICAgJ2F0dGFjaEV2ZW50QmVoYXZpb3InLFxuICAgICdib3VuZGFyeUV2ZW50QmVoYXZpb3InLFxuICAgICdyb290RWxlbWVudFJlZmVyZW5jZUJlaGF2aW9yJyxcbiAgICAnY3JlYXRlQmVoYXZpb3InLFxuICAgICdmaXhIb3ZlckJlaGF2aW9yJyxcbiAgICAnY3JlYXRlRGF0YU9iamVjdEJlaGF2aW9yJyxcbiAgICAnY3JlYXRlUGFydGljaXBhbnRCZWhhdmlvcicsXG4gICAgJ2RhdGFTdG9yZUJlaGF2aW9yJyxcbiAgICAnZGF0YUlucHV0QXNzb2NpYXRpb25CZWhhdmlvcicsXG4gICAgJ2RlbGV0ZUxhbmVCZWhhdmlvcicsXG4gICAgJ2RldGFjaEV2ZW50QmVoYXZpb3InLFxuICAgICdkcm9wT25GbG93QmVoYXZpb3InLFxuICAgICdldmVudEJhc2VkR2F0ZXdheUJlaGF2aW9yJyxcbiAgICAnZ3JvdXBCZWhhdmlvcicsXG4gICAgJ2ltcG9ydERvY2tpbmdGaXgnLFxuICAgICdpc0hvcml6b250YWxGaXgnLFxuICAgICdsYWJlbEJlaGF2aW9yJyxcbiAgICAnbW9kZWxpbmdGZWVkYmFjaycsXG4gICAgJ3JlbW92ZUVsZW1lbnRCZWhhdmlvcicsXG4gICAgJ3JlbW92ZVBhcnRpY2lwYW50QmVoYXZpb3InLFxuICAgICdyZXBsYWNlQ29ubmVjdGlvbkJlaGF2aW9yJyxcbiAgICAncmVwbGFjZUVsZW1lbnRCZWhhdmlvdXInLFxuICAgICdyZXNpemVCZWhhdmlvcicsXG4gICAgJ3Jlc2l6ZUxhbmVCZWhhdmlvcicsXG4gICAgJ3RvZ2dsZUVsZW1lbnRDb2xsYXBzZUJlaGF2aW91cicsXG4gICAgJ3NwYWNlVG9vbEJlaGF2aW9yJyxcbiAgICAnc3ViUHJvY2Vzc1N0YXJ0RXZlbnRCZWhhdmlvcicsXG4gICAgJ3VuY2xhaW1JZEJlaGF2aW9yJyxcbiAgICAndW5zZXREZWZhdWx0Rmxvd0JlaGF2aW9yJyxcbiAgICAndXBkYXRlRmxvd05vZGVSZWZzQmVoYXZpb3InXG4gIF0sXG4gIGFkYXB0aXZlTGFiZWxQb3NpdGlvbmluZ0JlaGF2aW9yOiBbICd0eXBlJywgQWRhcHRpdmVMYWJlbFBvc2l0aW9uaW5nQmVoYXZpb3IgXSxcbiAgYXBwZW5kQmVoYXZpb3I6IFsgJ3R5cGUnLCBBcHBlbmRCZWhhdmlvciBdLFxuICBhc3NvY2lhdGlvbkJlaGF2aW9yOiBbICd0eXBlJywgQXNzb2NpYXRpb25CZWhhdmlvciBdLFxuICBhdHRhY2hFdmVudEJlaGF2aW9yOiBbICd0eXBlJywgQXR0YWNoRXZlbnRCZWhhdmlvciBdLFxuICBib3VuZGFyeUV2ZW50QmVoYXZpb3I6IFsgJ3R5cGUnLCBCb3VuZGFyeUV2ZW50QmVoYXZpb3IgXSxcbiAgcm9vdEVsZW1lbnRSZWZlcmVuY2VCZWhhdmlvcjogWyAndHlwZScsIFJvb3RFbGVtZW50UmVmZXJlbmNlQmVoYXZpb3IgXSxcbiAgY3JlYXRlQmVoYXZpb3I6IFsgJ3R5cGUnLCBDcmVhdGVCZWhhdmlvciBdLFxuICBmaXhIb3ZlckJlaGF2aW9yOiBbICd0eXBlJywgRml4SG92ZXJCZWhhdmlvciBdLFxuICBjcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3I6IFsgJ3R5cGUnLCBDcmVhdGVEYXRhT2JqZWN0QmVoYXZpb3IgXSxcbiAgY3JlYXRlUGFydGljaXBhbnRCZWhhdmlvcjogWyAndHlwZScsIENyZWF0ZVBhcnRpY2lwYW50QmVoYXZpb3IgXSxcbiAgZGF0YUlucHV0QXNzb2NpYXRpb25CZWhhdmlvcjogWyAndHlwZScsIERhdGFJbnB1dEFzc29jaWF0aW9uQmVoYXZpb3IgXSxcbiAgZGF0YVN0b3JlQmVoYXZpb3I6IFsgJ3R5cGUnLCBEYXRhU3RvcmVCZWhhdmlvciBdLFxuICBkZWxldGVMYW5lQmVoYXZpb3I6IFsgJ3R5cGUnLCBEZWxldGVMYW5lQmVoYXZpb3IgXSxcbiAgZGV0YWNoRXZlbnRCZWhhdmlvcjogWyAndHlwZScsIERldGFjaEV2ZW50QmVoYXZpb3IgXSxcbiAgZHJvcE9uRmxvd0JlaGF2aW9yOiBbICd0eXBlJywgRHJvcE9uRmxvd0JlaGF2aW9yIF0sXG4gIGV2ZW50QmFzZWRHYXRld2F5QmVoYXZpb3I6IFsgJ3R5cGUnLCBFdmVudEJhc2VkR2F0ZXdheUJlaGF2aW9yIF0sXG4gIGdyb3VwQmVoYXZpb3I6IFsgJ3R5cGUnLCBHcm91cEJlaGF2aW9yIF0sXG4gIGltcG9ydERvY2tpbmdGaXg6IFsgJ3R5cGUnLCBJbXBvcnREb2NraW5nRml4IF0sXG4gIGlzSG9yaXpvbnRhbEZpeDogWyAndHlwZScsIElzSG9yaXpvbnRhbEZpeCBdLFxuICBsYWJlbEJlaGF2aW9yOiBbICd0eXBlJywgTGFiZWxCZWhhdmlvciBdLFxuICBtb2RlbGluZ0ZlZWRiYWNrOiBbICd0eXBlJywgTW9kZWxpbmdGZWVkYmFjayBdLFxuICByZXBsYWNlQ29ubmVjdGlvbkJlaGF2aW9yOiBbICd0eXBlJywgUmVwbGFjZUNvbm5lY3Rpb25CZWhhdmlvciBdLFxuICByZW1vdmVQYXJ0aWNpcGFudEJlaGF2aW9yOiBbICd0eXBlJywgUmVtb3ZlUGFydGljaXBhbnRCZWhhdmlvciBdLFxuICByZXBsYWNlRWxlbWVudEJlaGF2aW91cjogWyAndHlwZScsIFJlcGxhY2VFbGVtZW50QmVoYXZpb3VyIF0sXG4gIHJlc2l6ZUJlaGF2aW9yOiBbICd0eXBlJywgUmVzaXplQmVoYXZpb3IgXSxcbiAgcmVzaXplTGFuZUJlaGF2aW9yOiBbICd0eXBlJywgUmVzaXplTGFuZUJlaGF2aW9yIF0sXG4gIHJlbW92ZUVsZW1lbnRCZWhhdmlvcjogWyAndHlwZScsIFJlbW92ZUVsZW1lbnRCZWhhdmlvciBdLFxuICB0b2dnbGVFbGVtZW50Q29sbGFwc2VCZWhhdmlvdXIgOiBbICd0eXBlJywgVG9nZ2xlRWxlbWVudENvbGxhcHNlQmVoYXZpb3VyIF0sXG4gIHNwYWNlVG9vbEJlaGF2aW9yOiBbICd0eXBlJywgU3BhY2VUb29sQmVoYXZpb3IgXSxcbiAgc3ViUHJvY2Vzc1N0YXJ0RXZlbnRCZWhhdmlvcjogWyAndHlwZScsIFN1YlByb2Nlc3NTdGFydEV2ZW50QmVoYXZpb3IgXSxcbiAgdW5jbGFpbUlkQmVoYXZpb3I6IFsgJ3R5cGUnLCBVbmNsYWltSWRCZWhhdmlvciBdLFxuICB1cGRhdGVGbG93Tm9kZVJlZnNCZWhhdmlvcjogWyAndHlwZScsIFVwZGF0ZUZsb3dOb2RlUmVmc0JlaGF2aW9yIF0sXG4gIHVuc2V0RGVmYXVsdEZsb3dCZWhhdmlvcjogWyAndHlwZScsIFVuc2V0RGVmYXVsdEZsb3dCZWhhdmlvciBdXG59O1xuIiwiaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGRcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9Db2xsZWN0aW9ucyc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0XG59IGZyb20gJy4uLy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGJwbW46Q2F0ZWdvcnlWYWx1ZSBpbnNpZGUgYSBuZXcgYnBtbjpDYXRlZ29yeVxuICpcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gZGVmaW5pdGlvbnNcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XG4gKlxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gY2F0ZWdvcnlWYWx1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUNhdGVnb3J5VmFsdWUoZGVmaW5pdGlvbnMsIGJwbW5GYWN0b3J5KSB7XG4gIHZhciBjYXRlZ29yeVZhbHVlID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkNhdGVnb3J5VmFsdWUnKSxcbiAgICAgIGNhdGVnb3J5ID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkNhdGVnb3J5Jywge1xuICAgICAgICBjYXRlZ29yeVZhbHVlOiBbIGNhdGVnb3J5VmFsdWUgXVxuICAgICAgfSk7XG5cbiAgLy8gYWRkIHRvIGNvcnJlY3QgcGxhY2VcbiAgY29sbGVjdGlvbkFkZChkZWZpbml0aW9ucy5nZXQoJ3Jvb3RFbGVtZW50cycpLCBjYXRlZ29yeSk7XG4gIGdldEJ1c2luZXNzT2JqZWN0KGNhdGVnb3J5KS4kcGFyZW50ID0gZGVmaW5pdGlvbnM7XG4gIGdldEJ1c2luZXNzT2JqZWN0KGNhdGVnb3J5VmFsdWUpLiRwYXJlbnQgPSBjYXRlZ29yeTtcblxuICByZXR1cm4gY2F0ZWdvcnlWYWx1ZTtcblxufSIsIi8qKlxuICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIGEgdmVjdG9yXG4gKlxuICogQHBhcmFtIHtWZWN0b3J9XG4gKiBAcmV0dXJuIHtGbG9hdH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlY3Rvckxlbmd0aCh2KSB7XG4gIHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3codi54LCAyKSArIE1hdGgucG93KHYueSwgMikpO1xufVxuXG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgYW5nbGUgYmV0d2VlbiBhIGxpbmUgYSB0aGUgeUF4aXNcbiAqXG4gKiBAcGFyYW0ge0FycmF5fVxuICogQHJldHVybiB7RmxvYXR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBbmdsZShsaW5lKSB7XG5cbiAgLy8gcmV0dXJuIHZhbHVlIGlzIGJldHdlZW4gMCwgMTgwIGFuZCAtMTgwLCAtMFxuICAvLyBAamFuc3R1ZW1tZWw6IG1heWJlIHJlcGxhY2UgcmV0dXJuIGEvYiB3aXRoIGIvYVxuICByZXR1cm4gTWF0aC5hdGFuKChsaW5lWzFdLnkgLSBsaW5lWzBdLnkpIC8gKGxpbmVbMV0ueCAtIGxpbmVbMF0ueCkpO1xufVxuXG5cbi8qKlxuICogUm90YXRlcyBhIHZlY3RvciBieSBhIGdpdmVuIGFuZ2xlXG4gKlxuICogQHBhcmFtIHtWZWN0b3J9XG4gKiBAcGFyYW0ge0Zsb2F0fSBBbmdsZSBpbiByYWRpYW5zXG4gKiBAcmV0dXJuIHtWZWN0b3J9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByb3RhdGVWZWN0b3IodmVjdG9yLCBhbmdsZSkge1xuICByZXR1cm4gKCFhbmdsZSkgPyB2ZWN0b3IgOiB7XG4gICAgeDogTWF0aC5jb3MoYW5nbGUpICogdmVjdG9yLnggLSBNYXRoLnNpbihhbmdsZSkgKiB2ZWN0b3IueSxcbiAgICB5OiBNYXRoLnNpbihhbmdsZSkgKiB2ZWN0b3IueCArIE1hdGguY29zKGFuZ2xlKSAqIHZlY3Rvci55XG4gIH07XG59XG5cblxuLyoqXG4gKiBTb2x2ZXMgYSAyRCBlcXVhdGlvbiBzeXN0ZW1cbiAqIGEgKyByKmIgPSBjLCB3aGVyZSBhLGIsYyBhcmUgMkQgdmVjdG9yc1xuICpcbiAqIEBwYXJhbSB7VmVjdG9yfVxuICogQHBhcmFtIHtWZWN0b3J9XG4gKiBAcGFyYW0ge1ZlY3Rvcn1cbiAqIEByZXR1cm4ge0Zsb2F0fVxuICovXG5mdW5jdGlvbiBzb2x2ZUxhbWJhU3lzdGVtKGEsIGIsIGMpIHtcblxuICAvLyB0aGUgMmQgc3lzdGVtXG4gIHZhciBzeXN0ZW0gPSBbXG4gICAgeyBuOiBhWzBdIC0gY1swXSwgbGFtYmRhOiBiWzBdIH0sXG4gICAgeyBuOiBhWzFdIC0gY1sxXSwgbGFtYmRhOiBiWzFdIH1cbiAgXTtcblxuICAvLyBzb2x2ZVxuICB2YXIgbiA9IHN5c3RlbVswXS5uICogYlswXSArIHN5c3RlbVsxXS5uICogYlsxXSxcbiAgICAgIGwgPSBzeXN0ZW1bMF0ubGFtYmRhICogYlswXSArIHN5c3RlbVsxXS5sYW1iZGEgKiBiWzFdO1xuXG4gIHJldHVybiAtbi9sO1xufVxuXG5cbi8qKlxuICogUG9zaXRpb24gb2YgcGVycGVuZGljdWxhciBmb290XG4gKlxuICogQHBhcmFtIHtQb2ludH1cbiAqIEBwYXJhbSBbIHtQb2ludH0sIHtQb2ludH0gXSBsaW5lIGRlZmluZWQgdGhyb3VnaCB0d28gcG9pbnRzXG4gKiBAcmV0dXJuIHtQb2ludH0gdGhlIHBlcnBlbmRpY3VsYXIgZm9vdCBwb3NpdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gcGVycGVuZGljdWxhckZvb3QocG9pbnQsIGxpbmUpIHtcblxuICB2YXIgYSA9IGxpbmVbMF0sIGIgPSBsaW5lWzFdO1xuXG4gIC8vIHJlbGF0aXZlIHBvc2l0aW9uIG9mIGIgZnJvbSBhXG4gIHZhciBiZCA9IHsgeDogYi54IC0gYS54LCB5OiBiLnkgLSBhLnkgfTtcblxuICAvLyBzb2x2ZSBlcXVhdGlvbiBzeXN0ZW0gdG8gdGhlIHBhcmFtZXRyaXplZCB2ZWN0b3JzIHBhcmFtIHJlYWwgdmFsdWVcbiAgdmFyIHIgPSBzb2x2ZUxhbWJhU3lzdGVtKFsgYS54LCBhLnkgXSwgWyBiZC54LCBiZC55IF0sIFsgcG9pbnQueCwgcG9pbnQueSBdKTtcblxuICByZXR1cm4geyB4OiBhLnggKyByKmJkLngsIHk6IGEueSArIHIqYmQueSB9O1xufVxuXG5cbi8qKlxuICogQ2FsY3VsYXRlcyB0aGUgZGlzdGFuY2UgYmV0d2VlbiBhIHBvaW50IGFuZCBhIGxpbmVcbiAqXG4gKiBAcGFyYW0ge1BvaW50fVxuICogQHBhcmFtIFsge1BvaW50fSwge1BvaW50fSBdIGxpbmUgZGVmaW5lZCB0aHJvdWdoIHR3byBwb2ludHNcbiAqIEByZXR1cm4ge0Zsb2F0fSBkaXN0YW5jZVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGlzdGFuY2VQb2ludExpbmUocG9pbnQsIGxpbmUpIHtcblxuICB2YXIgcGZQb2ludCA9IHBlcnBlbmRpY3VsYXJGb290KHBvaW50LCBsaW5lKTtcblxuICAvLyBkaXN0YW5jZSB2ZWN0b3JcbiAgdmFyIGNvbm5lY3Rpb25WZWN0b3IgPSB7XG4gICAgeDogcGZQb2ludC54IC0gcG9pbnQueCxcbiAgICB5OiBwZlBvaW50LnkgLSBwb2ludC55XG4gIH07XG5cbiAgcmV0dXJuIHZlY3Rvckxlbmd0aChjb25uZWN0aW9uVmVjdG9yKTtcbn1cblxuXG4vKipcbiAqIENhbGN1bGF0ZXMgdGhlIGRpc3RhbmNlIGJldHdlZW4gdHdvIHBvaW50c1xuICpcbiAqIEBwYXJhbSB7UG9pbnR9XG4gKiBAcGFyYW0ge1BvaW50fVxuICogQHJldHVybiB7RmxvYXR9IGRpc3RhbmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREaXN0YW5jZVBvaW50UG9pbnQocG9pbnQxLCBwb2ludDIpIHtcblxuICByZXR1cm4gdmVjdG9yTGVuZ3RoKHtcbiAgICB4OiBwb2ludDEueCAtIHBvaW50Mi54LFxuICAgIHk6IHBvaW50MS55IC0gcG9pbnQyLnlcbiAgfSk7XG59IiwiaW1wb3J0IHtcbiAgZ2V0RGlzdGFuY2VQb2ludFBvaW50LFxuICByb3RhdGVWZWN0b3IsXG4gIGdldEFuZ2xlXG59IGZyb20gJy4vR2VvbWV0cmljVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldEF0dGFjaG1lbnRcbn0gZnJvbSAnLi9MaW5lQXR0YWNobWVudFV0aWwnO1xuXG5pbXBvcnQge1xuICByb3VuZFBvaW50XG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2xheW91dC9MYXlvdXRVdGlsJztcblxuXG5leHBvcnQgZnVuY3Rpb24gZmluZE5ld0xhYmVsTGluZVN0YXJ0SW5kZXgob2xkV2F5cG9pbnRzLCBuZXdXYXlwb2ludHMsIGF0dGFjaG1lbnQsIGhpbnRzKSB7XG5cbiAgdmFyIGluZGV4ID0gYXR0YWNobWVudC5zZWdtZW50SW5kZXg7XG5cbiAgdmFyIG9mZnNldCA9IG5ld1dheXBvaW50cy5sZW5ndGggLSBvbGRXYXlwb2ludHMubGVuZ3RoO1xuXG4gIC8vIHNlZ21lbnRNb3ZlIGhhcHBlbmVkXG4gIGlmIChoaW50cy5zZWdtZW50TW92ZSkge1xuXG4gICAgdmFyIG9sZFNlZ21lbnRTdGFydEluZGV4ID0gaGludHMuc2VnbWVudE1vdmUuc2VnbWVudFN0YXJ0SW5kZXgsXG4gICAgICAgIG5ld1NlZ21lbnRTdGFydEluZGV4ID0gaGludHMuc2VnbWVudE1vdmUubmV3U2VnbWVudFN0YXJ0SW5kZXg7XG5cbiAgICAvLyBpZiBsYWJlbCB3YXMgb24gbW92ZWQgc2VnbWVudCByZXR1cm4gbmV3IHNlZ21lbnQgaW5kZXhcbiAgICBpZiAoaW5kZXggPT09IG9sZFNlZ21lbnRTdGFydEluZGV4KSB7XG4gICAgICByZXR1cm4gbmV3U2VnbWVudFN0YXJ0SW5kZXg7XG4gICAgfVxuXG4gICAgLy8gbGFiZWwgaXMgYWZ0ZXIgbmV3IHNlZ21lbnQgaW5kZXhcbiAgICBpZiAoaW5kZXggPj0gbmV3U2VnbWVudFN0YXJ0SW5kZXgpIHtcbiAgICAgIHJldHVybiAoaW5kZXgrb2Zmc2V0IDwgbmV3U2VnbWVudFN0YXJ0SW5kZXgpID8gbmV3U2VnbWVudFN0YXJ0SW5kZXggOiBpbmRleCtvZmZzZXQ7XG4gICAgfVxuXG4gICAgLy8gaWYgbGFiZWwgaXMgYmVmb3JlIG5ldyBzZWdtZW50IGluZGV4XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgLy8gYmVuZHBvaW50TW92ZSBoYXBwZW5lZFxuICBpZiAoaGludHMuYmVuZHBvaW50TW92ZSkge1xuXG4gICAgdmFyIGluc2VydCA9IGhpbnRzLmJlbmRwb2ludE1vdmUuaW5zZXJ0LFxuICAgICAgICBiZW5kcG9pbnRJbmRleCA9IGhpbnRzLmJlbmRwb2ludE1vdmUuYmVuZHBvaW50SW5kZXgsXG4gICAgICAgIG5ld0luZGV4O1xuXG4gICAgLy8gd2F5cG9pbnRzIGxlbmd0aCBkaWRudCBjaGFuZ2VcbiAgICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuXG4gICAgLy8gbGFiZWwgYmVoaW5kIG5ldy9yZW1vdmVkIGJlbmRwb2ludFxuICAgIGlmIChpbmRleCA+PSBiZW5kcG9pbnRJbmRleCkge1xuICAgICAgbmV3SW5kZXggPSBpbnNlcnQgPyBpbmRleCArIDEgOiBpbmRleCAtIDE7XG4gICAgfVxuXG4gICAgLy8gbGFiZWwgYmVmb3JlIG5ldy9yZW1vdmVkIGJlbmRwb2ludFxuICAgIGlmIChpbmRleCA8IGJlbmRwb2ludEluZGV4KSB7XG5cbiAgICAgIG5ld0luZGV4ID0gaW5kZXg7XG5cbiAgICAgIC8vIGRlY2lkZSBsYWJlbCBzaG91bGQgdGFrZSByaWdodCBvciBsZWZ0IHNlZ21lbnRcbiAgICAgIGlmIChpbnNlcnQgJiYgYXR0YWNobWVudC50eXBlICE9PSAnYmVuZHBvaW50JyAmJiBiZW5kcG9pbnRJbmRleC0xID09PSBpbmRleCkge1xuXG4gICAgICAgIHZhciByZWwgPSByZWxhdGl2ZVBvc2l0aW9uTWlkV2F5cG9pbnQobmV3V2F5cG9pbnRzLCBiZW5kcG9pbnRJbmRleCk7XG5cbiAgICAgICAgaWYgKHJlbCA8IGF0dGFjaG1lbnQucmVsYXRpdmVMb2NhdGlvbikge1xuICAgICAgICAgIG5ld0luZGV4Kys7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbmV3SW5kZXg7XG4gIH1cblxuICAvLyBzdGFydC9lbmQgY2hhbmdlZFxuICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG5cbiAgaWYgKGhpbnRzLmNvbm5lY3Rpb25TdGFydCkge1xuICAgIHJldHVybiAoaW5kZXggPT09IDApID8gMCA6IG51bGw7XG4gIH1cblxuICBpZiAoaGludHMuY29ubmVjdGlvbkVuZCkge1xuICAgIHJldHVybiAoaW5kZXggPT09IG9sZFdheXBvaW50cy5sZW5ndGggLSAyKSA/IG5ld1dheXBvaW50cy5sZW5ndGggLSAyIDogbnVsbDtcbiAgfVxuXG4gIC8vIGlmIG5vdGhpbmcgZml0cywgcmV0dXJuIG51bGxcbiAgcmV0dXJuIG51bGw7XG59XG5cblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHJlcXVpcmVkIGFkanVzdG1lbnQgKG1vdmUgZGVsdGEpIGZvciB0aGUgZ2l2ZW4gbGFiZWxcbiAqIGFmdGVyIHRoZSBjb25uZWN0aW9uIHdheXBvaW50cyBnb3QgdXBkYXRlZC5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5MYWJlbH0gbGFiZWxcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSBuZXdXYXlwb2ludHNcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSBvbGRXYXlwb2ludHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBoaW50c1xuICpcbiAqIEByZXR1cm4ge1BvaW50fSBkZWx0YVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TGFiZWxBZGp1c3RtZW50KGxhYmVsLCBuZXdXYXlwb2ludHMsIG9sZFdheXBvaW50cywgaGludHMpIHtcblxuICB2YXIgeCA9IDAsXG4gICAgICB5ID0gMDtcblxuICB2YXIgbGFiZWxQb3NpdGlvbiA9IGdldExhYmVsTWlkKGxhYmVsKTtcblxuICAvLyBnZXQgY2xvc2VzdCBhdHRhY2htZW50XG4gIHZhciBhdHRhY2htZW50ID0gZ2V0QXR0YWNobWVudChsYWJlbFBvc2l0aW9uLCBvbGRXYXlwb2ludHMpLFxuICAgICAgb2xkTGFiZWxMaW5lSW5kZXggPSBhdHRhY2htZW50LnNlZ21lbnRJbmRleCxcbiAgICAgIG5ld0xhYmVsTGluZUluZGV4ID0gZmluZE5ld0xhYmVsTGluZVN0YXJ0SW5kZXgob2xkV2F5cG9pbnRzLCBuZXdXYXlwb2ludHMsIGF0dGFjaG1lbnQsIGhpbnRzKTtcblxuICBpZiAobmV3TGFiZWxMaW5lSW5kZXggPT09IG51bGwpIHtcbiAgICByZXR1cm4geyB4OiB4LCB5OiB5IH07XG4gIH1cblxuICAvLyBzaG91bGQgbmV2ZXIgaGFwcGVuXG4gIC8vIFRPRE8oQGphbnN0dWVtbWVsKTogdGhyb3cgYW4gZXJyb3IgaGVyZSB3aGVuIGNvbm5lY3Rpb25TZWdtZW50TW92ZSBpcyByZWZhY3RvcmVkXG4gIGlmIChuZXdMYWJlbExpbmVJbmRleCA8IDAgfHxcbiAgICAgIG5ld0xhYmVsTGluZUluZGV4ID4gbmV3V2F5cG9pbnRzLmxlbmd0aCAtIDIpIHtcbiAgICByZXR1cm4geyB4OiB4LCB5OiB5IH07XG4gIH1cblxuICB2YXIgb2xkTGFiZWxMaW5lID0gZ2V0TGluZShvbGRXYXlwb2ludHMsIG9sZExhYmVsTGluZUluZGV4KSxcbiAgICAgIG5ld0xhYmVsTGluZSA9IGdldExpbmUobmV3V2F5cG9pbnRzLCBuZXdMYWJlbExpbmVJbmRleCksXG4gICAgICBvbGRGb290ID0gYXR0YWNobWVudC5wb3NpdGlvbjtcblxuICB2YXIgcmVsYXRpdmVGb290UG9zaXRpb24gPSBnZXRSZWxhdGl2ZUZvb3RQb3NpdGlvbihvbGRMYWJlbExpbmUsIG9sZEZvb3QpLFxuICAgICAgYW5nbGVEZWx0YSA9IGdldEFuZ2xlRGVsdGEob2xkTGFiZWxMaW5lLCBuZXdMYWJlbExpbmUpO1xuXG4gIC8vIHNwZWNpYWwgcnVsZSBpZiBsYWJlbCBvbiBiZW5kcG9pbnRcbiAgaWYgKGF0dGFjaG1lbnQudHlwZSA9PT0gJ2JlbmRwb2ludCcpIHtcblxuICAgIHZhciBvZmZzZXQgPSBuZXdXYXlwb2ludHMubGVuZ3RoIC0gb2xkV2F5cG9pbnRzLmxlbmd0aCxcbiAgICAgICAgb2xkQmVuZHBvaW50SW5kZXggPSBhdHRhY2htZW50LmJlbmRwb2ludEluZGV4LFxuICAgICAgICBvbGRCZW5kcG9pbnQgPSBvbGRXYXlwb2ludHNbb2xkQmVuZHBvaW50SW5kZXhdO1xuXG4gICAgLy8gYmVuZHBvaW50IHBvc2l0aW9uIGhhc24ndCBjaGFuZ2VkLCByZXR1cm4gc2FtZSBwb3NpdGlvblxuICAgIGlmIChuZXdXYXlwb2ludHMuaW5kZXhPZihvbGRCZW5kcG9pbnQpICE9PSAtMSkge1xuICAgICAgcmV0dXJuIHsgeDogeCwgeTogeSB9O1xuICAgIH1cblxuICAgIC8vIG5ldyBiZW5kcG9pbnQgYW5kIG9sZCBiZW5kcG9pbnQgaGF2ZSBzYW1lIGluZGV4LCB0aGVuIGp1c3QgcmV0dXJuIHRoZSBvZmZzZXRcbiAgICBpZiAob2Zmc2V0ID09PSAwKSB7XG4gICAgICB2YXIgbmV3QmVuZHBvaW50ID0gbmV3V2F5cG9pbnRzW29sZEJlbmRwb2ludEluZGV4XTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgeDogbmV3QmVuZHBvaW50LnggLSBhdHRhY2htZW50LnBvc2l0aW9uLngsXG4gICAgICAgIHk6IG5ld0JlbmRwb2ludC55IC0gYXR0YWNobWVudC5wb3NpdGlvbi55XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIGlmIGJlbmRwb2ludHMgZ2V0IHJlbW92ZWRcbiAgICBpZiAob2Zmc2V0IDwgMCAmJiBvbGRCZW5kcG9pbnRJbmRleCAhPT0gMCAmJiBvbGRCZW5kcG9pbnRJbmRleCA8IG9sZFdheXBvaW50cy5sZW5ndGggLSAxKSB7XG4gICAgICByZWxhdGl2ZUZvb3RQb3NpdGlvbiA9IHJlbGF0aXZlUG9zaXRpb25NaWRXYXlwb2ludChvbGRXYXlwb2ludHMsIG9sZEJlbmRwb2ludEluZGV4KTtcbiAgICB9XG4gIH1cblxuICB2YXIgbmV3Rm9vdCA9IHtcbiAgICB4OiAobmV3TGFiZWxMaW5lWzFdLnggLSBuZXdMYWJlbExpbmVbMF0ueCkgKiByZWxhdGl2ZUZvb3RQb3NpdGlvbiArIG5ld0xhYmVsTGluZVswXS54LFxuICAgIHk6IChuZXdMYWJlbExpbmVbMV0ueSAtIG5ld0xhYmVsTGluZVswXS55KSAqIHJlbGF0aXZlRm9vdFBvc2l0aW9uICsgbmV3TGFiZWxMaW5lWzBdLnlcbiAgfTtcblxuICAvLyB0aGUgcm90YXRlZCB2ZWN0b3IgdG8gbGFiZWxcbiAgdmFyIG5ld0xhYmVsVmVjdG9yID0gcm90YXRlVmVjdG9yKHtcbiAgICB4OiBsYWJlbFBvc2l0aW9uLnggLSBvbGRGb290LngsXG4gICAgeTogbGFiZWxQb3NpdGlvbi55IC0gb2xkRm9vdC55XG4gIH0sIGFuZ2xlRGVsdGEpO1xuXG4gIC8vIHRoZSBuZXcgcmVsYXRpdmUgcG9zaXRpb25cbiAgeCA9IG5ld0Zvb3QueCArIG5ld0xhYmVsVmVjdG9yLnggLSBsYWJlbFBvc2l0aW9uLng7XG4gIHkgPSBuZXdGb290LnkgKyBuZXdMYWJlbFZlY3Rvci55IC0gbGFiZWxQb3NpdGlvbi55O1xuXG4gIHJldHVybiByb3VuZFBvaW50KHtcbiAgICB4OiB4LFxuICAgIHk6IHlcbiAgfSk7XG59XG5cblxuLy8gSEVMUEVSUyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIHJlbGF0aXZlUG9zaXRpb25NaWRXYXlwb2ludCh3YXlwb2ludHMsIGlkeCkge1xuXG4gIHZhciBkaXN0YW5jZVNlZ21lbnQxID0gZ2V0RGlzdGFuY2VQb2ludFBvaW50KHdheXBvaW50c1tpZHgtMV0sIHdheXBvaW50c1tpZHhdKSxcbiAgICAgIGRpc3RhbmNlU2VnbWVudDIgPSBnZXREaXN0YW5jZVBvaW50UG9pbnQod2F5cG9pbnRzW2lkeF0sIHdheXBvaW50c1tpZHgrMV0pO1xuXG4gIHZhciByZWxhdGl2ZVBvc2l0aW9uID0gZGlzdGFuY2VTZWdtZW50MSAvIChkaXN0YW5jZVNlZ21lbnQxICsgZGlzdGFuY2VTZWdtZW50Mik7XG5cbiAgcmV0dXJuIHJlbGF0aXZlUG9zaXRpb247XG59XG5cbmZ1bmN0aW9uIGdldExhYmVsTWlkKGxhYmVsKSB7XG4gIHJldHVybiB7XG4gICAgeDogbGFiZWwueCArIGxhYmVsLndpZHRoIC8gMixcbiAgICB5OiBsYWJlbC55ICsgbGFiZWwuaGVpZ2h0IC8gMlxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRBbmdsZURlbHRhKGwxLCBsMikge1xuICB2YXIgYTEgPSBnZXRBbmdsZShsMSksXG4gICAgICBhMiA9IGdldEFuZ2xlKGwyKTtcbiAgcmV0dXJuIGEyIC0gYTE7XG59XG5cbmZ1bmN0aW9uIGdldExpbmUod2F5cG9pbnRzLCBpZHgpIHtcbiAgcmV0dXJuIFsgd2F5cG9pbnRzW2lkeF0sIHdheXBvaW50c1tpZHgrMV0gXTtcbn1cblxuZnVuY3Rpb24gZ2V0UmVsYXRpdmVGb290UG9zaXRpb24obGluZSwgZm9vdCkge1xuXG4gIHZhciBsZW5ndGggPSBnZXREaXN0YW5jZVBvaW50UG9pbnQobGluZVswXSwgbGluZVsxXSksXG4gICAgICBsZW5ndGhUb0Zvb3QgPSBnZXREaXN0YW5jZVBvaW50UG9pbnQobGluZVswXSwgZm9vdCk7XG5cbiAgcmV0dXJuIGxlbmd0aCA9PT0gMCA/IDAgOiBsZW5ndGhUb0Zvb3QgLyBsZW5ndGg7XG59XG4iLCJ2YXIgc3FydCA9IE1hdGguc3FydCxcbiAgICBtaW4gPSBNYXRoLm1pbixcbiAgICBtYXggPSBNYXRoLm1heCxcbiAgICBhYnMgPSBNYXRoLmFicztcblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHNxdWFyZSAocG93ZXIgdG8gdHdvKSBvZiBhIG51bWJlci5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gblxuICpcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZnVuY3Rpb24gc3Eobikge1xuICByZXR1cm4gTWF0aC5wb3cobiwgMik7XG59XG5cbi8qKlxuICogR2V0IGRpc3RhbmNlIGJldHdlZW4gdHdvIHBvaW50cy5cbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBwMVxuICogQHBhcmFtIHtQb2ludH0gcDJcbiAqXG4gKiBAcmV0dXJuIHtudW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIGdldERpc3RhbmNlKHAxLCBwMikge1xuICByZXR1cm4gc3FydChzcShwMS54IC0gcDIueCkgKyBzcShwMS55IC0gcDIueSkpO1xufVxuXG4vKipcbiAqIFJldHVybiB0aGUgYXR0YWNobWVudCBvZiB0aGUgZ2l2ZW4gcG9pbnQgb24gdGhlIHNwZWNpZmllZCBsaW5lLlxuICpcbiAqIFRoZSBhdHRhY2htZW50IGlzIGVpdGhlciBhIGJlbmRwb2ludCAoYXR0YWNoZWQgdG8gdGhlIGdpdmVuIHBvaW50KVxuICogb3Igc2VnbWVudCAoYXR0YWNoZWQgdG8gYSBsb2NhdGlvbiBvbiBhIGxpbmUgc2VnbWVudCkgYXR0YWNobWVudDpcbiAqXG4gKiBgYGBqYXZhc2NyaXB0XG4gKiB2YXIgcG9pbnRBdHRhY2htZW50ID0ge1xuICogICB0eXBlOiAnYmVuZHBvaW50JyxcbiAqICAgYmVuZHBvaW50SW5kZXg6IDMsXG4gKiAgIHBvc2l0aW9uOiB7IHg6IDEwLCB5OiAxMCB9IC8vIHRoZSBhdHRhY2ggcG9pbnQgb24gdGhlIGxpbmVcbiAqIH07XG4gKlxuICogdmFyIHNlZ21lbnRBdHRhY2htZW50ID0ge1xuICogICB0eXBlOiAnc2VnbWVudCcsXG4gKiAgIHNlZ21lbnRJbmRleDogMixcbiAqICAgcmVsYXRpdmVMb2NhdGlvbjogMC4zMSwgLy8gYXR0YWNoIHBvaW50IGxvY2F0aW9uIGJldHdlZW4gMCAoYXQgc3RhcnQpIGFuZCAxIChhdCBlbmQpXG4gKiAgIHBvc2l0aW9uOiB7IHg6IDEwLCB5OiAxMCB9IC8vIHRoZSBhdHRhY2ggcG9pbnQgb24gdGhlIGxpbmVcbiAqIH07XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBwb2ludFxuICogQHBhcmFtIHtBcnJheTxQb2ludD59IGxpbmVcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGF0dGFjaG1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEF0dGFjaG1lbnQocG9pbnQsIGxpbmUpIHtcblxuICB2YXIgaWR4ID0gMCxcbiAgICAgIHNlZ21lbnRTdGFydCxcbiAgICAgIHNlZ21lbnRFbmQsXG4gICAgICBzZWdtZW50U3RhcnREaXN0YW5jZSxcbiAgICAgIHNlZ21lbnRFbmREaXN0YW5jZSxcbiAgICAgIGF0dGFjaG1lbnRQb3NpdGlvbixcbiAgICAgIG1pbkRpc3RhbmNlLFxuICAgICAgaW50ZXJzZWN0aW9ucyxcbiAgICAgIGF0dGFjaG1lbnQsXG4gICAgICBhdHRhY2htZW50RGlzdGFuY2UsXG4gICAgICBjbG9zZXN0QXR0YWNobWVudERpc3RhbmNlLFxuICAgICAgY2xvc2VzdEF0dGFjaG1lbnQ7XG5cbiAgZm9yIChpZHggPSAwOyBpZHggPCBsaW5lLmxlbmd0aCAtIDE7IGlkeCsrKSB7XG5cbiAgICBzZWdtZW50U3RhcnQgPSBsaW5lW2lkeF07XG4gICAgc2VnbWVudEVuZCA9IGxpbmVbaWR4ICsgMV07XG5cbiAgICBpZiAocG9pbnRzRXF1YWwoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKSkge1xuICAgICAgaW50ZXJzZWN0aW9ucyA9IFsgc2VnbWVudFN0YXJ0IF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlZ21lbnRTdGFydERpc3RhbmNlID0gZ2V0RGlzdGFuY2UocG9pbnQsIHNlZ21lbnRTdGFydCk7XG4gICAgICBzZWdtZW50RW5kRGlzdGFuY2UgPSBnZXREaXN0YW5jZShwb2ludCwgc2VnbWVudEVuZCk7XG5cbiAgICAgIG1pbkRpc3RhbmNlID0gbWluKHNlZ21lbnRTdGFydERpc3RhbmNlLCBzZWdtZW50RW5kRGlzdGFuY2UpO1xuXG4gICAgICBpbnRlcnNlY3Rpb25zID0gZ2V0Q2lyY2xlU2VnbWVudEludGVyc2VjdGlvbnMoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kLCBwb2ludCwgbWluRGlzdGFuY2UpO1xuICAgIH1cblxuICAgIGlmIChpbnRlcnNlY3Rpb25zLmxlbmd0aCA8IDEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXhwZWN0ZWQgYmV0d2VlbiBbMSwgMl0gY2lyY2xlIC0+IGxpbmUgaW50ZXJzZWN0aW9ucycpO1xuICAgIH1cblxuICAgIC8vIG9uZSBpbnRlcnNlY3Rpb24gLT4gYmVuZHBvaW50IGF0dGFjaG1lbnRcbiAgICBpZiAoaW50ZXJzZWN0aW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICAgIGF0dGFjaG1lbnQgPSB7XG4gICAgICAgIHR5cGU6ICdiZW5kcG9pbnQnLFxuICAgICAgICBwb3NpdGlvbjogaW50ZXJzZWN0aW9uc1swXSxcbiAgICAgICAgc2VnbWVudEluZGV4OiBpZHgsXG4gICAgICAgIGJlbmRwb2ludEluZGV4OiBwb2ludHNFcXVhbChzZWdtZW50U3RhcnQsIGludGVyc2VjdGlvbnNbMF0pID8gaWR4IDogaWR4ICsgMVxuICAgICAgfTtcbiAgICB9XG5cbiAgICAvLyB0d28gaW50ZXJzZWN0aW9ucyAtPiBzZWdtZW50IGF0dGFjaG1lbnRcbiAgICBpZiAoaW50ZXJzZWN0aW9ucy5sZW5ndGggPT09IDIpIHtcblxuICAgICAgYXR0YWNobWVudFBvc2l0aW9uID0gbWlkKGludGVyc2VjdGlvbnNbMF0sIGludGVyc2VjdGlvbnNbMV0pO1xuXG4gICAgICBhdHRhY2htZW50ID0ge1xuICAgICAgICB0eXBlOiAnc2VnbWVudCcsXG4gICAgICAgIHBvc2l0aW9uOiBhdHRhY2htZW50UG9zaXRpb24sXG4gICAgICAgIHNlZ21lbnRJbmRleDogaWR4LFxuICAgICAgICByZWxhdGl2ZUxvY2F0aW9uOiBnZXREaXN0YW5jZShzZWdtZW50U3RhcnQsIGF0dGFjaG1lbnRQb3NpdGlvbikgLyBnZXREaXN0YW5jZShzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQpXG4gICAgICB9O1xuICAgIH1cblxuICAgIGF0dGFjaG1lbnREaXN0YW5jZSA9IGdldERpc3RhbmNlKGF0dGFjaG1lbnQucG9zaXRpb24sIHBvaW50KTtcblxuICAgIGlmICghY2xvc2VzdEF0dGFjaG1lbnQgfHwgY2xvc2VzdEF0dGFjaG1lbnREaXN0YW5jZSA+IGF0dGFjaG1lbnREaXN0YW5jZSkge1xuICAgICAgY2xvc2VzdEF0dGFjaG1lbnQgPSBhdHRhY2htZW50O1xuICAgICAgY2xvc2VzdEF0dGFjaG1lbnREaXN0YW5jZSA9IGF0dGFjaG1lbnREaXN0YW5jZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY2xvc2VzdEF0dGFjaG1lbnQ7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgaW50ZXJzZWN0aW9uIGJldHdlZW4gYSBjaXJjbGUgYW5kIGEgbGluZSBzZWdtZW50LlxuICpcbiAqIEBwYXJhbSB7UG9pbnR9IHMxIHNlZ21lbnQgc3RhcnRcbiAqIEBwYXJhbSB7UG9pbnR9IHMyIHNlZ21lbnQgZW5kXG4gKiBAcGFyYW0ge1BvaW50fSBjYyBjaXJjbGUgY2VudGVyXG4gKiBAcGFyYW0ge251bWJlcn0gY3IgY2lyY2xlIHJhZGl1c1xuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gaW50ZXJzZWN0aW9uc1xuICovXG5mdW5jdGlvbiBnZXRDaXJjbGVTZWdtZW50SW50ZXJzZWN0aW9ucyhzMSwgczIsIGNjLCBjcikge1xuXG4gIHZhciBiYVggPSBzMi54IC0gczEueDtcbiAgdmFyIGJhWSA9IHMyLnkgLSBzMS55O1xuICB2YXIgY2FYID0gY2MueCAtIHMxLng7XG4gIHZhciBjYVkgPSBjYy55IC0gczEueTtcblxuICB2YXIgYSA9IGJhWCAqIGJhWCArIGJhWSAqIGJhWTtcbiAgdmFyIGJCeTIgPSBiYVggKiBjYVggKyBiYVkgKiBjYVk7XG4gIHZhciBjID0gY2FYICogY2FYICsgY2FZICogY2FZIC0gY3IgKiBjcjtcblxuICB2YXIgcEJ5MiA9IGJCeTIgLyBhO1xuICB2YXIgcSA9IGMgLyBhO1xuXG4gIHZhciBkaXNjID0gcEJ5MiAqIHBCeTIgLSBxO1xuXG4gIC8vIGNoZWNrIGFnYWluc3QgbmVnYXRpdmUgdmFsdWUgdG8gd29yayBhcm91bmRcbiAgLy8gbmVnYXRpdmUsIHZlcnkgY2xvc2UgdG8gemVybyByZXN1bHRzICgtNGUtMTUpXG4gIC8vIGJlaW5nIHByb2R1Y2VkIGluIHNvbWUgZW52aXJvbm1lbnRzXG4gIGlmIChkaXNjIDwgMCAmJiBkaXNjID4gLTAuMDAwMDAxKSB7XG4gICAgZGlzYyA9IDA7XG4gIH1cblxuICBpZiAoZGlzYyA8IDApIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICAvLyBpZiBkaXNjID09IDAgLi4uIGRlYWx0IHdpdGggbGF0ZXJcbiAgdmFyIHRtcFNxcnQgPSBzcXJ0KGRpc2MpO1xuICB2YXIgYWJTY2FsaW5nRmFjdG9yMSA9IC1wQnkyICsgdG1wU3FydDtcbiAgdmFyIGFiU2NhbGluZ0ZhY3RvcjIgPSAtcEJ5MiAtIHRtcFNxcnQ7XG5cbiAgdmFyIGkxID0ge1xuICAgIHg6IHMxLnggLSBiYVggKiBhYlNjYWxpbmdGYWN0b3IxLFxuICAgIHk6IHMxLnkgLSBiYVkgKiBhYlNjYWxpbmdGYWN0b3IxXG4gIH07XG5cbiAgaWYgKGRpc2MgPT09IDApIHsgLy8gYWJTY2FsaW5nRmFjdG9yMSA9PSBhYlNjYWxpbmdGYWN0b3IyXG4gICAgcmV0dXJuIFsgaTEgXTtcbiAgfVxuXG4gIHZhciBpMiA9IHtcbiAgICB4OiBzMS54IC0gYmFYICogYWJTY2FsaW5nRmFjdG9yMixcbiAgICB5OiBzMS55IC0gYmFZICogYWJTY2FsaW5nRmFjdG9yMlxuICB9O1xuXG4gIC8vIHJldHVybiBvbmx5IHBvaW50cyBvbiBsaW5lIHNlZ21lbnRcbiAgcmV0dXJuIFsgaTEsIGkyIF0uZmlsdGVyKGZ1bmN0aW9uKHApIHtcbiAgICByZXR1cm4gaXNQb2ludEluU2VnbWVudChwLCBzMSwgczIpO1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBpc1BvaW50SW5TZWdtZW50KHAsIHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCkge1xuICByZXR1cm4gKFxuICAgIGZlbmNlZChwLngsIHNlZ21lbnRTdGFydC54LCBzZWdtZW50RW5kLngpICYmXG4gICAgZmVuY2VkKHAueSwgc2VnbWVudFN0YXJ0LnksIHNlZ21lbnRFbmQueSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gZmVuY2VkKG4sIHJhbmdlU3RhcnQsIHJhbmdlRW5kKSB7XG5cbiAgLy8gdXNlIG1hdGNoaW5nIHRocmVzaG9sZCB0byB3b3JrIGFyb3VuZFxuICAvLyBwcmVjaXNpb24gZXJyb3JzIGluIGludGVyc2VjdGlvbiBjb21wdXRhdGlvblxuXG4gIHJldHVybiAoXG4gICAgbiA+PSBtaW4ocmFuZ2VTdGFydCwgcmFuZ2VFbmQpIC0gRVFVQUxfVEhSRVNIT0xEICYmXG4gICAgbiA8PSBtYXgocmFuZ2VTdGFydCwgcmFuZ2VFbmQpICsgRVFVQUxfVEhSRVNIT0xEXG4gICk7XG59XG5cbi8qKlxuICogQ2FsY3VsYXRlIG1pZCBvZiB0d28gcG9pbnRzLlxuICpcbiAqIEBwYXJhbSB7UG9pbnR9IHAxXG4gKiBAcGFyYW0ge1BvaW50fSBwMlxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5mdW5jdGlvbiBtaWQocDEsIHAyKSB7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiAocDEueCArIHAyLngpIC8gMixcbiAgICB5OiAocDEueSArIHAyLnkpIC8gMlxuICB9O1xufVxuXG52YXIgRVFVQUxfVEhSRVNIT0xEID0gMC4xO1xuXG5mdW5jdGlvbiBwb2ludHNFcXVhbChwMSwgcDIpIHtcblxuICByZXR1cm4gKFxuICAgIGFicyhwMS54IC0gcDIueCkgPD0gRVFVQUxfVEhSRVNIT0xEICYmXG4gICAgYWJzKHAxLnkgLSBwMi55KSA8PSBFUVVBTF9USFJFU0hPTERcbiAgKTtcbn1cbiIsIi8qKlxuICogUmV0dXJucyB0aGUgaW50ZXJzZWN0aW9uIGJldHdlZW4gdHdvIGxpbmUgc2VnbWVudHMgYSBhbmQgYi5cbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBsMXNcbiAqIEBwYXJhbSB7UG9pbnR9IGwxZVxuICogQHBhcmFtIHtQb2ludH0gbDJzXG4gKiBAcGFyYW0ge1BvaW50fSBsMmVcbiAqXG4gKiBAcmV0dXJuIHtQb2ludH1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gbGluZUludGVyc2VjdChsMXMsIGwxZSwgbDJzLCBsMmUpIHtcblxuICAvLyBpZiB0aGUgbGluZXMgaW50ZXJzZWN0LCB0aGUgcmVzdWx0IGNvbnRhaW5zIHRoZSB4IGFuZCB5IG9mIHRoZVxuICAvLyBpbnRlcnNlY3Rpb24gKHRyZWF0aW5nIHRoZSBsaW5lcyBhcyBpbmZpbml0ZSkgYW5kIGJvb2xlYW5zIGZvclxuICAvLyB3aGV0aGVyIGxpbmUgc2VnbWVudCAxIG9yIGxpbmUgc2VnbWVudCAyIGNvbnRhaW4gdGhlIHBvaW50XG4gIHZhciBkZW5vbWluYXRvciwgYSwgYiwgYywgbnVtZXJhdG9yO1xuXG4gIGRlbm9taW5hdG9yID0gKChsMmUueSAtIGwycy55KSAqIChsMWUueCAtIGwxcy54KSkgLSAoKGwyZS54IC0gbDJzLngpICogKGwxZS55IC0gbDFzLnkpKTtcblxuICBpZiAoZGVub21pbmF0b3IgPT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgYSA9IGwxcy55IC0gbDJzLnk7XG4gIGIgPSBsMXMueCAtIGwycy54O1xuICBudW1lcmF0b3IgPSAoKGwyZS54IC0gbDJzLngpICogYSkgLSAoKGwyZS55IC0gbDJzLnkpICogYik7XG5cbiAgYyA9IG51bWVyYXRvciAvIGRlbm9taW5hdG9yO1xuXG4gIC8vIGlmIHdlIGNhc3QgdGhlc2UgbGluZXMgaW5maW5pdGVseSBpblxuICAvLyBib3RoIGRpcmVjdGlvbnMsIHRoZXkgaW50ZXJzZWN0IGhlcmVcbiAgcmV0dXJuIHtcbiAgICB4OiBNYXRoLnJvdW5kKGwxcy54ICsgKGMgKiAobDFlLnggLSBsMXMueCkpKSxcbiAgICB5OiBNYXRoLnJvdW5kKGwxcy55ICsgKGMgKiAobDFlLnkgLSBsMXMueSkpKVxuICB9O1xufSIsImltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBhc1RSQkxcclxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIGNvbGxlY3RMYW5lcyxcclxuICBnZXRMYW5lc1Jvb3RcclxufSBmcm9tICcuLi8uLi8uLi9tb2RlbGluZy91dGlsL0xhbmVVdGlsJztcclxuXHJcbmltcG9ydCB7IExBTkVfTUlOX0RJTUVOU0lPTlMgfSBmcm9tICcuLi9SZXNpemVCZWhhdmlvcic7XHJcblxyXG52YXIgYWJzID0gTWF0aC5hYnMsXHJcbiAgICBtaW4gPSBNYXRoLm1pbixcclxuICAgIG1heCA9IE1hdGgubWF4O1xyXG5cclxuXHJcbmZ1bmN0aW9uIGFkZFRvVHJibCh0cmJsLCBhdHRyLCB2YWx1ZSwgY2hvaWNlKSB7XHJcbiAgdmFyIGN1cnJlbnQgPSB0cmJsW2F0dHJdO1xyXG5cclxuICAvLyBtYWtlIHN1cmUgdG8gc2V0IHRoZSB2YWx1ZSBpZiBpdCBkb2VzIG5vdCBleGlzdFxyXG4gIC8vIG9yIGFwcGx5IHRoZSBjb3JyZWN0IHZhbHVlIGJ5IGNvbXBhcmluZyBhZ2FpbnN0XHJcbiAgLy8gY2hvaWNlKHZhbHVlLCBjdXJyZW50VmFsdWUpXHJcbiAgdHJibFthdHRyXSA9IGN1cnJlbnQgPT09IHVuZGVmaW5lZCA/IHZhbHVlIDogY2hvaWNlKHZhbHVlLCBjdXJyZW50KTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkTWluKHRyYmwsIGF0dHIsIHZhbHVlKSB7XHJcbiAgcmV0dXJuIGFkZFRvVHJibCh0cmJsLCBhdHRyLCB2YWx1ZSwgbWluKTtcclxufVxyXG5cclxuZnVuY3Rpb24gYWRkTWF4KHRyYmwsIGF0dHIsIHZhbHVlKSB7XHJcbiAgcmV0dXJuIGFkZFRvVHJibCh0cmJsLCBhdHRyLCB2YWx1ZSwgbWF4KTtcclxufVxyXG5cclxudmFyIExBTkVfUklHSFRfUEFERElORyA9IDIwLFxyXG4gICAgTEFORV9MRUZUX1BBRERJTkcgPSA1MCxcclxuICAgIExBTkVfVE9QX1BBRERJTkcgPSAyMCxcclxuICAgIExBTkVfQk9UVE9NX1BBRERJTkcgPSAyMDtcclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFydGljaXBhbnRSZXNpemVDb25zdHJhaW50cyhsYW5lU2hhcGUsIHJlc2l6ZURpcmVjdGlvbiwgYmFsYW5jZWQpIHtcclxuICB2YXIgbGFuZXNSb290ID0gZ2V0TGFuZXNSb290KGxhbmVTaGFwZSk7XHJcblxyXG4gIHZhciBpc0ZpcnN0ID0gdHJ1ZSxcclxuICAgICAgaXNMYXN0ID0gdHJ1ZTtcclxuXHJcbiAgLy8gbWF4IHRvcC9ib3R0b20gc2l6ZSBmb3IgbGFuZXNcclxuICB2YXIgYWxsTGFuZXMgPSBjb2xsZWN0TGFuZXMobGFuZXNSb290LCBbIGxhbmVzUm9vdCBdKTtcclxuXHJcbiAgdmFyIGxhbmVUcmJsID0gYXNUUkJMKGxhbmVTaGFwZSk7XHJcblxyXG4gIHZhciBtYXhUcmJsID0ge30sXHJcbiAgICAgIG1pblRyYmwgPSB7fTtcclxuXHJcbiAgaWYgKC9lLy50ZXN0KHJlc2l6ZURpcmVjdGlvbikpIHtcclxuICAgIG1pblRyYmwucmlnaHQgPSBsYW5lVHJibC5sZWZ0ICsgTEFORV9NSU5fRElNRU5TSU9OUy53aWR0aDtcclxuICB9IGVsc2VcclxuICBpZiAoL3cvLnRlc3QocmVzaXplRGlyZWN0aW9uKSkge1xyXG4gICAgbWluVHJibC5sZWZ0ID0gbGFuZVRyYmwucmlnaHQgLSBMQU5FX01JTl9ESU1FTlNJT05TLndpZHRoO1xyXG4gIH1cclxuXHJcbiAgYWxsTGFuZXMuZm9yRWFjaChmdW5jdGlvbihvdGhlcikge1xyXG5cclxuICAgIHZhciBvdGhlclRyYmwgPSBhc1RSQkwob3RoZXIpO1xyXG5cclxuICAgIGlmICgvbi8udGVzdChyZXNpemVEaXJlY3Rpb24pKSB7XHJcblxyXG4gICAgICBpZiAob3RoZXJUcmJsLnRvcCA8IChsYW5lVHJibC50b3AgLSAxMCkpIHtcclxuICAgICAgICBpc0ZpcnN0ID0gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIG1heCB0b3Agc2l6ZSAoYmFzZWQgb24gbmV4dCBlbGVtZW50KVxyXG4gICAgICBpZiAoYmFsYW5jZWQgJiYgYWJzKGxhbmVUcmJsLnRvcCAtIG90aGVyVHJibC5ib3R0b20pIDwgMTApIHtcclxuICAgICAgICBhZGRNYXgobWF4VHJibCwgJ3RvcCcsIG90aGVyVHJibC50b3AgKyBMQU5FX01JTl9ESU1FTlNJT05TLmhlaWdodCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIG1pbiB0b3Agc2l6ZSAoYmFzZWQgb24gc2VsZiBvciBuZXN0ZWQgZWxlbWVudClcclxuICAgICAgaWYgKGFicyhsYW5lVHJibC50b3AgLSBvdGhlclRyYmwudG9wKSA8IDUpIHtcclxuICAgICAgICBhZGRNaW4obWluVHJibCwgJ3RvcCcsIG90aGVyVHJibC5ib3R0b20gLSBMQU5FX01JTl9ESU1FTlNJT05TLmhlaWdodCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoL3MvLnRlc3QocmVzaXplRGlyZWN0aW9uKSkge1xyXG5cclxuICAgICAgaWYgKG90aGVyVHJibC5ib3R0b20gPiAobGFuZVRyYmwuYm90dG9tICsgMTApKSB7XHJcbiAgICAgICAgaXNMYXN0ID0gZmFsc2U7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIG1heCBib3R0b20gc2l6ZSAoYmFzZWQgb24gcHJldmlvdXMgZWxlbWVudClcclxuICAgICAgaWYgKGJhbGFuY2VkICYmIGFicyhsYW5lVHJibC5ib3R0b20gLSBvdGhlclRyYmwudG9wKSA8IDEwKSB7XHJcbiAgICAgICAgYWRkTWluKG1heFRyYmwsICdib3R0b20nLCBvdGhlclRyYmwuYm90dG9tIC0gTEFORV9NSU5fRElNRU5TSU9OUy5oZWlnaHQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBtaW4gYm90dG9tIHNpemUgKGJhc2VkIG9uIHNlbGYgb3IgbmVzdGVkIGVsZW1lbnQpXHJcbiAgICAgIGlmIChhYnMobGFuZVRyYmwuYm90dG9tIC0gb3RoZXJUcmJsLmJvdHRvbSkgPCA1KSB7XHJcbiAgICAgICAgYWRkTWF4KG1pblRyYmwsICdib3R0b20nLCBvdGhlclRyYmwudG9wICsgTEFORV9NSU5fRElNRU5TSU9OUy5oZWlnaHQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIC8vIG1heCB0b3AvYm90dG9tL2xlZnQvcmlnaHQgc2l6ZSBiYXNlZCBvbiBmbG93IG5vZGVzXHJcbiAgdmFyIGZsb3dFbGVtZW50cyA9IGxhbmVzUm9vdC5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24ocykge1xyXG4gICAgcmV0dXJuICFzLmhpZGRlbiAmJiAhcy53YXlwb2ludHMgJiYgKGlzKHMsICdicG1uOkZsb3dFbGVtZW50JykgfHwgaXMocywgJ2JwbW46QXJ0aWZhY3QnKSk7XHJcbiAgfSk7XHJcblxyXG4gIGZsb3dFbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dFbGVtZW50KSB7XHJcblxyXG4gICAgdmFyIGZsb3dFbGVtZW50VHJibCA9IGFzVFJCTChmbG93RWxlbWVudCk7XHJcblxyXG4gICAgaWYgKGlzRmlyc3QgJiYgL24vLnRlc3QocmVzaXplRGlyZWN0aW9uKSkge1xyXG4gICAgICBhZGRNaW4obWluVHJibCwgJ3RvcCcsIGZsb3dFbGVtZW50VHJibC50b3AgLSBMQU5FX1RPUF9QQURESU5HKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoL2UvLnRlc3QocmVzaXplRGlyZWN0aW9uKSkge1xyXG4gICAgICBhZGRNYXgobWluVHJibCwgJ3JpZ2h0JywgZmxvd0VsZW1lbnRUcmJsLnJpZ2h0ICsgTEFORV9SSUdIVF9QQURESU5HKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaXNMYXN0ICYmIC9zLy50ZXN0KHJlc2l6ZURpcmVjdGlvbikpIHtcclxuICAgICAgYWRkTWF4KG1pblRyYmwsICdib3R0b20nLCBmbG93RWxlbWVudFRyYmwuYm90dG9tICsgTEFORV9CT1RUT01fUEFERElORyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKC93Ly50ZXN0KHJlc2l6ZURpcmVjdGlvbikpIHtcclxuICAgICAgYWRkTWluKG1pblRyYmwsICdsZWZ0JywgZmxvd0VsZW1lbnRUcmJsLmxlZnQgLSBMQU5FX0xFRlRfUEFERElORyk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBtaW46IG1pblRyYmwsXHJcbiAgICBtYXg6IG1heFRyYmxcclxuICB9O1xyXG59IiwiaW1wb3J0IHtcbiAgZmlsdGVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZWFjaEVsZW1lbnRcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvdXRpbC9FbGVtZW50cyc7XG5cbmltcG9ydCB7XG4gIGdldExhbmVzUm9vdCxcbiAgZ2V0Q2hpbGRMYW5lcyxcbiAgTEFORV9JTkRFTlRBVElPTlxufSBmcm9tICcuLi91dGlsL0xhbmVVdGlsJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGFsbG93cyB1cyB0byBhZGQgYSBuZXcgbGFuZVxuICogYWJvdmUgb3IgYmVsb3cgYW4gZXhpc3Rpbmcgb25lLlxuICpcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKiBAcGFyYW0ge1NwYWNlVG9vbH0gc3BhY2VUb29sXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFkZExhbmVIYW5kbGVyKG1vZGVsaW5nLCBzcGFjZVRvb2wpIHtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fc3BhY2VUb29sID0gc3BhY2VUb29sO1xufVxuXG5BZGRMYW5lSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnbW9kZWxpbmcnLFxuICAnc3BhY2VUb29sJ1xuXTtcblxuXG5BZGRMYW5lSGFuZGxlci5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgc3BhY2VUb29sID0gdGhpcy5fc3BhY2VUb29sLFxuICAgICAgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgbG9jYXRpb24gPSBjb250ZXh0LmxvY2F0aW9uO1xuXG4gIHZhciBsYW5lc1Jvb3QgPSBnZXRMYW5lc1Jvb3Qoc2hhcGUpO1xuXG4gIHZhciBpc1Jvb3QgPSBsYW5lc1Jvb3QgPT09IHNoYXBlLFxuICAgICAgbGFuZVBhcmVudCA9IGlzUm9vdCA/IHNoYXBlIDogc2hhcGUucGFyZW50O1xuXG4gIHZhciBleGlzdGluZ0NoaWxkTGFuZXMgPSBnZXRDaGlsZExhbmVzKGxhbmVQYXJlbnQpO1xuXG4gIC8vICgwKSBhZGQgYSBsYW5lIGlmIHdlIGN1cnJlbnRseSBnb3Qgbm9uZSBhbmQgYXJlIGFkZGluZyB0byByb290XG4gIGlmICghZXhpc3RpbmdDaGlsZExhbmVzLmxlbmd0aCkge1xuICAgIG1vZGVsaW5nLmNyZWF0ZVNoYXBlKHsgdHlwZTogJ2JwbW46TGFuZScgfSwge1xuICAgICAgeDogc2hhcGUueCArIExBTkVfSU5ERU5UQVRJT04sXG4gICAgICB5OiBzaGFwZS55LFxuICAgICAgd2lkdGg6IHNoYXBlLndpZHRoIC0gTEFORV9JTkRFTlRBVElPTixcbiAgICAgIGhlaWdodDogc2hhcGUuaGVpZ2h0XG4gICAgfSwgbGFuZVBhcmVudCk7XG4gIH1cblxuICAvLyAoMSkgY29sbGVjdCBhZmZlY3RlZCBlbGVtZW50cyB0byBjcmVhdGUgbmVjZXNzYXJ5IHNwYWNlXG4gIHZhciBhbGxBZmZlY3RlZCA9IFtdO1xuXG4gIGVhY2hFbGVtZW50KGxhbmVzUm9vdCwgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGFsbEFmZmVjdGVkLnB1c2goZWxlbWVudCk7XG5cbiAgICAvLyBoYW5kbGUgZWxlbWVudCBsYWJlbHMgaW4gdGhlIGRpYWdyYW0gcm9vdFxuICAgIGlmIChlbGVtZW50LmxhYmVsKSB7XG4gICAgICBhbGxBZmZlY3RlZC5wdXNoKGVsZW1lbnQubGFiZWwpO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50ID09PSBzaGFwZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiBmaWx0ZXIoZWxlbWVudC5jaGlsZHJlbiwgZnVuY3Rpb24oYykge1xuICAgICAgcmV0dXJuIGMgIT09IHNoYXBlO1xuICAgIH0pO1xuICB9KTtcblxuICB2YXIgb2Zmc2V0ID0gbG9jYXRpb24gPT09ICd0b3AnID8gLTEyMCA6IDEyMCxcbiAgICAgIGxhbmVQb3NpdGlvbiA9IGxvY2F0aW9uID09PSAndG9wJyA/IHNoYXBlLnkgOiBzaGFwZS55ICsgc2hhcGUuaGVpZ2h0LFxuICAgICAgc3BhY2VQb3MgPSBsYW5lUG9zaXRpb24gKyAobG9jYXRpb24gPT09ICd0b3AnID8gMTAgOiAtMTApLFxuICAgICAgZGlyZWN0aW9uID0gbG9jYXRpb24gPT09ICd0b3AnID8gJ24nIDogJ3MnO1xuXG4gIHZhciBhZGp1c3RtZW50cyA9IHNwYWNlVG9vbC5jYWxjdWxhdGVBZGp1c3RtZW50cyhhbGxBZmZlY3RlZCwgJ3knLCBvZmZzZXQsIHNwYWNlUG9zKTtcblxuICBzcGFjZVRvb2wubWFrZVNwYWNlKFxuICAgIGFkanVzdG1lbnRzLm1vdmluZ1NoYXBlcyxcbiAgICBhZGp1c3RtZW50cy5yZXNpemluZ1NoYXBlcyxcbiAgICB7IHg6IDAsIHk6IG9mZnNldCB9LFxuICAgIGRpcmVjdGlvbixcbiAgICBzcGFjZVBvc1xuICApO1xuXG4gIC8vICgyKSBjcmVhdGUgbmV3IGxhbmUgYXQgb3BlbiBzcGFjZVxuICBjb250ZXh0Lm5ld0xhbmUgPSBtb2RlbGluZy5jcmVhdGVTaGFwZSh7IHR5cGU6ICdicG1uOkxhbmUnIH0sIHtcbiAgICB4OiBzaGFwZS54ICsgKGlzUm9vdCA/IExBTkVfSU5ERU5UQVRJT04gOiAwKSxcbiAgICB5OiBsYW5lUG9zaXRpb24gLSAobG9jYXRpb24gPT09ICd0b3AnID8gMTIwIDogMCksXG4gICAgd2lkdGg6IHNoYXBlLndpZHRoIC0gKGlzUm9vdCA/IExBTkVfSU5ERU5UQVRJT04gOiAwKSxcbiAgICBoZWlnaHQ6IDEyMFxuICB9LCBsYW5lUGFyZW50KTtcbn07XG4iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBJZENsYWltSGFuZGxlcihtb2RkbGUpIHtcbiAgdGhpcy5fbW9kZGxlID0gbW9kZGxlO1xufVxuXG5JZENsYWltSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZGxlJyBdO1xuXG5cbklkQ2xhaW1IYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgaWRzID0gdGhpcy5fbW9kZGxlLmlkcyxcbiAgICAgIGlkID0gY29udGV4dC5pZCxcbiAgICAgIGVsZW1lbnQgPSBjb250ZXh0LmVsZW1lbnQsXG4gICAgICBjbGFpbWluZyA9IGNvbnRleHQuY2xhaW1pbmc7XG5cbiAgaWYgKGNsYWltaW5nKSB7XG4gICAgaWRzLmNsYWltKGlkLCBlbGVtZW50KTtcbiAgfSBlbHNlIHtcbiAgICBpZHMudW5jbGFpbShpZCk7XG4gIH1cbn07XG5cbi8qKlxuICogQ29tbWFuZCByZXZlcnQgaW1wbGVtZW50YXRpb24uXG4gKi9cbklkQ2xhaW1IYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBpZHMgPSB0aGlzLl9tb2RkbGUuaWRzLFxuICAgICAgaWQgPSBjb250ZXh0LmlkLFxuICAgICAgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcbiAgICAgIGNsYWltaW5nID0gY29udGV4dC5jbGFpbWluZztcblxuICBpZiAoY2xhaW1pbmcpIHtcbiAgICBpZHMudW5jbGFpbShpZCk7XG4gIH0gZWxzZSB7XG4gICAgaWRzLmNsYWltKGlkLCBlbGVtZW50KTtcbiAgfVxufTtcblxuIiwiaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi8uLi91dGlsL01vZGVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldExhbmVzUm9vdCxcbiAgY29tcHV0ZUxhbmVzUmVzaXplXG59IGZyb20gJy4uL3V0aWwvTGFuZVV0aWwnO1xuXG5pbXBvcnQge1xuICBlYWNoRWxlbWVudFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IHtcbiAgYXNUUkJMXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgc3Vic3RyYWN0VFJCTFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9yZXNpemUvUmVzaXplVXRpbCc7XG5cblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCByZXNpemVzIGEgbGFuZS5cbiAqXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSZXNpemVMYW5lSGFuZGxlcihtb2RlbGluZywgc3BhY2VUb29sKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX3NwYWNlVG9vbCA9IHNwYWNlVG9vbDtcbn1cblxuUmVzaXplTGFuZUhhbmRsZXIuJGluamVjdCA9IFtcbiAgJ21vZGVsaW5nJyxcbiAgJ3NwYWNlVG9vbCdcbl07XG5cblxuUmVzaXplTGFuZUhhbmRsZXIucHJvdG90eXBlLnByZUV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG5ld0JvdW5kcyA9IGNvbnRleHQubmV3Qm91bmRzLFxuICAgICAgYmFsYW5jZWQgPSBjb250ZXh0LmJhbGFuY2VkO1xuXG4gIGlmIChiYWxhbmNlZCAhPT0gZmFsc2UpIHtcbiAgICB0aGlzLnJlc2l6ZUJhbGFuY2VkKHNoYXBlLCBuZXdCb3VuZHMpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucmVzaXplU3BhY2Uoc2hhcGUsIG5ld0JvdW5kcyk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBSZXNpemUgYmFsYW5jZWQsIGFkanVzdGluZyBuZXh0IC8gcHJldmlvdXMgbGFuZSBzaXplcy5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAqIEBwYXJhbSB7Qm91bmRzfSBuZXdCb3VuZHNcbiAqL1xuUmVzaXplTGFuZUhhbmRsZXIucHJvdG90eXBlLnJlc2l6ZUJhbGFuY2VkID0gZnVuY3Rpb24oc2hhcGUsIG5ld0JvdW5kcykge1xuXG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nO1xuXG4gIHZhciByZXNpemVOZWVkZWQgPSBjb21wdXRlTGFuZXNSZXNpemUoc2hhcGUsIG5ld0JvdW5kcyk7XG5cbiAgLy8gcmVzaXplIHRoZSBsYW5lXG4gIG1vZGVsaW5nLnJlc2l6ZVNoYXBlKHNoYXBlLCBuZXdCb3VuZHMpO1xuXG4gIC8vIHJlc2l6ZSBvdGhlciBsYW5lcyBhcyBuZWVkZWRcbiAgcmVzaXplTmVlZGVkLmZvckVhY2goZnVuY3Rpb24ocikge1xuICAgIG1vZGVsaW5nLnJlc2l6ZVNoYXBlKHIuc2hhcGUsIHIubmV3Qm91bmRzKTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmVzaXplLCBtYWtpbmcgYWN0dWFsIHNwYWNlIGFuZCBtb3ZpbmcgYmVsb3cgLyBhYm92ZSBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAqIEBwYXJhbSB7Qm91bmRzfSBuZXdCb3VuZHNcbiAqL1xuUmVzaXplTGFuZUhhbmRsZXIucHJvdG90eXBlLnJlc2l6ZVNwYWNlID0gZnVuY3Rpb24oc2hhcGUsIG5ld0JvdW5kcykge1xuICB2YXIgc3BhY2VUb29sID0gdGhpcy5fc3BhY2VUb29sO1xuXG4gIHZhciBzaGFwZVRyYmwgPSBhc1RSQkwoc2hhcGUpLFxuICAgICAgbmV3VHJibCA9IGFzVFJCTChuZXdCb3VuZHMpO1xuXG4gIHZhciB0cmJsRGlmZiA9IHN1YnN0cmFjdFRSQkwobmV3VHJibCwgc2hhcGVUcmJsKTtcblxuICB2YXIgbGFuZXNSb290ID0gZ2V0TGFuZXNSb290KHNoYXBlKTtcblxuICB2YXIgYWxsQWZmZWN0ZWQgPSBbXSxcbiAgICAgIGFsbExhbmVzID0gW107XG5cbiAgZWFjaEVsZW1lbnQobGFuZXNSb290LCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgYWxsQWZmZWN0ZWQucHVzaChlbGVtZW50KTtcblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpMYW5lJykgfHwgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuICAgICAgYWxsTGFuZXMucHVzaChlbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxlbWVudC5jaGlsZHJlbjtcbiAgfSk7XG5cbiAgdmFyIGNoYW5nZSxcbiAgICAgIHNwYWNlUG9zLFxuICAgICAgZGlyZWN0aW9uLFxuICAgICAgb2Zmc2V0LFxuICAgICAgYWRqdXN0bWVudHM7XG5cbiAgaWYgKHRyYmxEaWZmLmJvdHRvbSB8fCB0cmJsRGlmZi50b3ApIHtcblxuICAgIGNoYW5nZSA9IHRyYmxEaWZmLmJvdHRvbSB8fCB0cmJsRGlmZi50b3A7XG4gICAgc3BhY2VQb3MgPSBzaGFwZS55ICsgKHRyYmxEaWZmLmJvdHRvbSA/IHNoYXBlLmhlaWdodCA6IDApICsgKHRyYmxEaWZmLmJvdHRvbSA/IC0xMCA6IDEwKTtcbiAgICBkaXJlY3Rpb24gPSB0cmJsRGlmZi5ib3R0b20gPyAncycgOiAnbic7XG5cbiAgICBvZmZzZXQgPSB0cmJsRGlmZi50b3AgPiAwIHx8IHRyYmxEaWZmLmJvdHRvbSA8IDAgPyAtY2hhbmdlIDogY2hhbmdlO1xuXG4gICAgYWRqdXN0bWVudHMgPSBzcGFjZVRvb2wuY2FsY3VsYXRlQWRqdXN0bWVudHMoYWxsQWZmZWN0ZWQsICd5Jywgb2Zmc2V0LCBzcGFjZVBvcyk7XG5cbiAgICBzcGFjZVRvb2wubWFrZVNwYWNlKGFkanVzdG1lbnRzLm1vdmluZ1NoYXBlcywgYWRqdXN0bWVudHMucmVzaXppbmdTaGFwZXMsIHsgeDogMCwgeTogY2hhbmdlIH0sIGRpcmVjdGlvbik7XG4gIH1cblxuXG4gIGlmICh0cmJsRGlmZi5sZWZ0IHx8IHRyYmxEaWZmLnJpZ2h0KSB7XG5cbiAgICBjaGFuZ2UgPSB0cmJsRGlmZi5yaWdodCB8fCB0cmJsRGlmZi5sZWZ0O1xuICAgIHNwYWNlUG9zID0gc2hhcGUueCArICh0cmJsRGlmZi5yaWdodCA/IHNoYXBlLndpZHRoIDogMCkgKyAodHJibERpZmYucmlnaHQgPyAtMTAgOiAxMDApO1xuICAgIGRpcmVjdGlvbiA9IHRyYmxEaWZmLnJpZ2h0ID8gJ2UnIDogJ3cnO1xuXG4gICAgb2Zmc2V0ID0gdHJibERpZmYubGVmdCA+IDAgfHwgdHJibERpZmYucmlnaHQgPCAwID8gLWNoYW5nZSA6IGNoYW5nZTtcblxuICAgIGFkanVzdG1lbnRzID0gc3BhY2VUb29sLmNhbGN1bGF0ZUFkanVzdG1lbnRzKGFsbExhbmVzLCAneCcsIG9mZnNldCwgc3BhY2VQb3MpO1xuXG4gICAgc3BhY2VUb29sLm1ha2VTcGFjZShhZGp1c3RtZW50cy5tb3ZpbmdTaGFwZXMsIGFkanVzdG1lbnRzLnJlc2l6aW5nU2hhcGVzLCB7IHg6IGNoYW5nZSwgeTogMCB9LCBkaXJlY3Rpb24pO1xuICB9XG59OyIsImltcG9ydCB7XHJcbiAgYXNzaWduLFxyXG4gIGZvckVhY2hcclxufSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG5cclxudmFyIERFRkFVTFRfQ09MT1JTID0ge1xyXG4gIGZpbGw6IHVuZGVmaW5lZCxcclxuICBzdHJva2U6IHVuZGVmaW5lZFxyXG59O1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNldENvbG9ySGFuZGxlcihjb21tYW5kU3RhY2spIHtcclxuICB0aGlzLl9jb21tYW5kU3RhY2sgPSBjb21tYW5kU3RhY2s7XHJcbn1cclxuXHJcblNldENvbG9ySGFuZGxlci4kaW5qZWN0ID0gW1xyXG4gICdjb21tYW5kU3RhY2snXHJcbl07XHJcblxyXG5cclxuU2V0Q29sb3JIYW5kbGVyLnByb3RvdHlwZS5wb3N0RXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzLFxyXG4gICAgICBjb2xvcnMgPSBjb250ZXh0LmNvbG9ycyB8fCBERUZBVUxUX0NPTE9SUztcclxuXHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICB2YXIgZGkgPSB7fTtcclxuXHJcbiAgaWYgKCdmaWxsJyBpbiBjb2xvcnMpIHtcclxuICAgIGFzc2lnbihkaSwgeyBmaWxsOiBjb2xvcnMuZmlsbCB9KTtcclxuICB9XHJcblxyXG4gIGlmICgnc3Ryb2tlJyBpbiBjb2xvcnMpIHtcclxuICAgIGFzc2lnbihkaSwgeyBzdHJva2U6IGNvbG9ycy5zdHJva2UgfSk7XHJcbiAgfVxyXG5cclxuICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XHJcblxyXG4gICAgc2VsZi5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnQudXBkYXRlUHJvcGVydGllcycsIHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgcHJvcGVydGllczoge1xyXG4gICAgICAgIGRpOiBkaVxyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9KTtcclxuXHJcbn07IiwiaW1wb3J0IHtcbiAgZ2V0Q2hpbGRMYW5lcyxcbiAgTEFORV9JTkRFTlRBVElPTlxufSBmcm9tICcuLi91dGlsL0xhbmVVdGlsJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IHNwbGl0cyBhIGxhbmUgaW50byBhIG51bWJlciBvZiBzdWItbGFuZXMsXG4gKiBjcmVhdGluZyBuZXcgc3ViIGxhbmVzLCBpZiBuZWNlc3NhcnkuXG4gKlxuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gU3BsaXRMYW5lSGFuZGxlcihtb2RlbGluZywgdHJhbnNsYXRlKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcbn1cblxuU3BsaXRMYW5lSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnbW9kZWxpbmcnLFxuICAndHJhbnNsYXRlJ1xuXTtcblxuXG5TcGxpdExhbmVIYW5kbGVyLnByb3RvdHlwZS5wcmVFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nLFxuICAgICAgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuXG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBuZXdMYW5lc0NvdW50ID0gY29udGV4dC5jb3VudDtcblxuICB2YXIgY2hpbGRMYW5lcyA9IGdldENoaWxkTGFuZXMoc2hhcGUpLFxuICAgICAgZXhpc3RpbmdMYW5lc0NvdW50ID0gY2hpbGRMYW5lcy5sZW5ndGg7XG5cbiAgaWYgKGV4aXN0aW5nTGFuZXNDb3VudCA+IG5ld0xhbmVzQ291bnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodHJhbnNsYXRlKCdtb3JlIHRoYW4ge2NvdW50fSBjaGlsZCBsYW5lcycsIHsgY291bnQ6IG5ld0xhbmVzQ291bnQgfSkpO1xuICB9XG5cbiAgdmFyIG5ld0xhbmVzSGVpZ2h0ID0gTWF0aC5yb3VuZChzaGFwZS5oZWlnaHQgLyBuZXdMYW5lc0NvdW50KTtcblxuICAvLyBJdGVyYXRlIGZyb20gdG9wIHRvIGJvdHRvbSBpbiBjaGlsZCBsYW5lIG9yZGVyLFxuICAvLyByZXNpemluZyBleGlzdGluZyBsYW5lcyBhbmQgY3JlYXRpbmcgbmV3IG9uZXNcbiAgLy8gc28gdGhhdCB0aGV5IHNwbGl0IHRoZSBwYXJlbnQgcHJvcG9ydGlvbmFsbHkuXG4gIC8vXG4gIC8vIER1ZSB0byByb3VuZGluZyByZWxhdGVkIGVycm9ycywgdGhlIGJvdHRvbSBsYW5lXG4gIC8vIG5lZWRzIHRvIHRha2UgdXAgYWxsIHRoZSByZW1haW5pbmcgc3BhY2UuXG4gIHZhciBsYW5lWSxcbiAgICAgIGxhbmVIZWlnaHQsXG4gICAgICBsYW5lQm91bmRzLFxuICAgICAgbmV3TGFuZUF0dHJzLFxuICAgICAgaWR4O1xuXG4gIGZvciAoaWR4ID0gMDsgaWR4IDwgbmV3TGFuZXNDb3VudDsgaWR4KyspIHtcblxuICAgIGxhbmVZID0gc2hhcGUueSArIGlkeCAqIG5ld0xhbmVzSGVpZ2h0O1xuXG4gICAgLy8gaWYgYm90dG9tIGxhbmVcbiAgICBpZiAoaWR4ID09PSBuZXdMYW5lc0NvdW50IC0gMSkge1xuICAgICAgbGFuZUhlaWdodCA9IHNoYXBlLmhlaWdodCAtIChuZXdMYW5lc0hlaWdodCAqIGlkeCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxhbmVIZWlnaHQgPSBuZXdMYW5lc0hlaWdodDtcbiAgICB9XG5cbiAgICBsYW5lQm91bmRzID0ge1xuICAgICAgeDogc2hhcGUueCArIExBTkVfSU5ERU5UQVRJT04sXG4gICAgICB5OiBsYW5lWSxcbiAgICAgIHdpZHRoOiBzaGFwZS53aWR0aCAtIExBTkVfSU5ERU5UQVRJT04sXG4gICAgICBoZWlnaHQ6IGxhbmVIZWlnaHRcbiAgICB9O1xuXG4gICAgaWYgKGlkeCA8IGV4aXN0aW5nTGFuZXNDb3VudCkge1xuXG4gICAgICAvLyByZXNpemUgZXhpc3RpbmcgbGFuZVxuICAgICAgbW9kZWxpbmcucmVzaXplU2hhcGUoY2hpbGRMYW5lc1tpZHhdLCBsYW5lQm91bmRzKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBjcmVhdGUgYSBuZXcgbGFuZSBhdCBwb3NpdGlvblxuICAgICAgbmV3TGFuZUF0dHJzID0ge1xuICAgICAgICB0eXBlOiAnYnBtbjpMYW5lJ1xuICAgICAgfTtcblxuICAgICAgbW9kZWxpbmcuY3JlYXRlU2hhcGUobmV3TGFuZUF0dHJzLCBsYW5lQm91bmRzLCBzaGFwZSk7XG4gICAgfVxuICB9XG59O1xuIiwiaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIHJlbW92ZSBhcyBjb2xsZWN0aW9uUmVtb3ZlXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFVwZGF0ZUNhbnZhc1Jvb3RIYW5kbGVyKGNhbnZhcywgbW9kZWxpbmcpIHtcbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xufVxuXG5VcGRhdGVDYW52YXNSb290SGFuZGxlci4kaW5qZWN0ID0gW1xuICAnY2FudmFzJyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuXG5VcGRhdGVDYW52YXNSb290SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY2FudmFzID0gdGhpcy5fY2FudmFzO1xuXG4gIHZhciBuZXdSb290ID0gY29udGV4dC5uZXdSb290LFxuICAgICAgbmV3Um9vdEJ1c2luZXNzT2JqZWN0ID0gbmV3Um9vdC5idXNpbmVzc09iamVjdCxcbiAgICAgIG9sZFJvb3QgPSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgIG9sZFJvb3RCdXNpbmVzc09iamVjdCA9IG9sZFJvb3QuYnVzaW5lc3NPYmplY3QsXG4gICAgICBicG1uRGVmaW5pdGlvbnMgPSBvbGRSb290QnVzaW5lc3NPYmplY3QuJHBhcmVudCxcbiAgICAgIGRpUGxhbmUgPSBvbGRSb290QnVzaW5lc3NPYmplY3QuZGk7XG5cbiAgLy8gKDEpIHJlcGxhY2UgcHJvY2VzcyBvbGQgPD4gbmV3IHJvb3RcbiAgY2FudmFzLnNldFJvb3RFbGVtZW50KG5ld1Jvb3QsIHRydWUpO1xuXG4gIC8vICgyKSB1cGRhdGUgcm9vdCBlbGVtZW50c1xuICBjb2xsZWN0aW9uQWRkKGJwbW5EZWZpbml0aW9ucy5yb290RWxlbWVudHMsIG5ld1Jvb3RCdXNpbmVzc09iamVjdCk7XG4gIG5ld1Jvb3RCdXNpbmVzc09iamVjdC4kcGFyZW50ID0gYnBtbkRlZmluaXRpb25zO1xuXG4gIGNvbGxlY3Rpb25SZW1vdmUoYnBtbkRlZmluaXRpb25zLnJvb3RFbGVtZW50cywgb2xkUm9vdEJ1c2luZXNzT2JqZWN0KTtcbiAgb2xkUm9vdEJ1c2luZXNzT2JqZWN0LiRwYXJlbnQgPSBudWxsO1xuXG4gIC8vICgzKSB3aXJlIGRpXG4gIG9sZFJvb3RCdXNpbmVzc09iamVjdC5kaSA9IG51bGw7XG5cbiAgZGlQbGFuZS5icG1uRWxlbWVudCA9IG5ld1Jvb3RCdXNpbmVzc09iamVjdDtcbiAgbmV3Um9vdEJ1c2luZXNzT2JqZWN0LmRpID0gZGlQbGFuZTtcblxuICBjb250ZXh0Lm9sZFJvb3QgPSBvbGRSb290O1xuXG4gIC8vIFRPRE8obmlra3UpOiByZXR1cm4gY2hhbmdlZCBlbGVtZW50cz9cbiAgLy8gcmV0dXJuIFsgbmV3Um9vdCwgb2xkUm9vdCBdO1xufTtcblxuXG5VcGRhdGVDYW52YXNSb290SGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjYW52YXMgPSB0aGlzLl9jYW52YXM7XG5cbiAgdmFyIG5ld1Jvb3QgPSBjb250ZXh0Lm5ld1Jvb3QsXG4gICAgICBuZXdSb290QnVzaW5lc3NPYmplY3QgPSBuZXdSb290LmJ1c2luZXNzT2JqZWN0LFxuICAgICAgb2xkUm9vdCA9IGNvbnRleHQub2xkUm9vdCxcbiAgICAgIG9sZFJvb3RCdXNpbmVzc09iamVjdCA9IG9sZFJvb3QuYnVzaW5lc3NPYmplY3QsXG4gICAgICBicG1uRGVmaW5pdGlvbnMgPSBuZXdSb290QnVzaW5lc3NPYmplY3QuJHBhcmVudCxcbiAgICAgIGRpUGxhbmUgPSBuZXdSb290QnVzaW5lc3NPYmplY3QuZGk7XG5cbiAgLy8gKDEpIHJlcGxhY2UgcHJvY2VzcyBvbGQgPD4gbmV3IHJvb3RcbiAgY2FudmFzLnNldFJvb3RFbGVtZW50KG9sZFJvb3QsIHRydWUpO1xuXG4gIC8vICgyKSB1cGRhdGUgcm9vdCBlbGVtZW50c1xuICBjb2xsZWN0aW9uUmVtb3ZlKGJwbW5EZWZpbml0aW9ucy5yb290RWxlbWVudHMsIG5ld1Jvb3RCdXNpbmVzc09iamVjdCk7XG4gIG5ld1Jvb3RCdXNpbmVzc09iamVjdC4kcGFyZW50ID0gbnVsbDtcblxuICBjb2xsZWN0aW9uQWRkKGJwbW5EZWZpbml0aW9ucy5yb290RWxlbWVudHMsIG9sZFJvb3RCdXNpbmVzc09iamVjdCk7XG4gIG9sZFJvb3RCdXNpbmVzc09iamVjdC4kcGFyZW50ID0gYnBtbkRlZmluaXRpb25zO1xuXG4gIC8vICgzKSB3aXJlIGRpXG4gIG5ld1Jvb3RCdXNpbmVzc09iamVjdC5kaSA9IG51bGw7XG5cbiAgZGlQbGFuZS5icG1uRWxlbWVudCA9IG9sZFJvb3RCdXNpbmVzc09iamVjdDtcbiAgb2xkUm9vdEJ1c2luZXNzT2JqZWN0LmRpID0gZGlQbGFuZTtcblxuICAvLyBUT0RPKG5pa2t1KTogcmV0dXJuIGNoYW5nZWQgZWxlbWVudHM/XG4gIC8vIHJldHVybiBbIG5ld1Jvb3QsIG9sZFJvb3QgXTtcbn07IiwiaW1wb3J0IHtcbiAgY29sbGVjdExhbmVzLFxuICBnZXRMYW5lc1Jvb3Rcbn0gZnJvbSAnLi4vdXRpbC9MYW5lVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIHJlbW92ZSBhcyBjb2xsZWN0aW9uUmVtb3ZlXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5pbXBvcnQge1xuICBhc1RSQkxcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG52YXIgRkxPV19OT0RFX1JFRlNfQVRUUiA9ICdmbG93Tm9kZVJlZicsXG4gICAgTEFORVNfQVRUUiA9ICdsYW5lcyc7XG5cblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCB1cGRhdGVzIGxhbmUgcmVmcyBvbiBjaGFuZ2VkIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFVwZGF0ZUZsb3dOb2RlUmVmc0hhbmRsZXIoZWxlbWVudFJlZ2lzdHJ5KSB7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbn1cblxuVXBkYXRlRmxvd05vZGVSZWZzSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnZWxlbWVudFJlZ2lzdHJ5J1xuXTtcblxuXG5VcGRhdGVGbG93Tm9kZVJlZnNIYW5kbGVyLnByb3RvdHlwZS5jb21wdXRlVXBkYXRlcyA9IGZ1bmN0aW9uKGZsb3dOb2RlU2hhcGVzLCBsYW5lU2hhcGVzKSB7XG5cbiAgdmFyIGhhbmRsZWROb2RlcyA9IFtdO1xuXG4gIHZhciB1cGRhdGVzID0gW107XG5cbiAgdmFyIHBhcnRpY2lwYW50Q2FjaGUgPSB7fTtcblxuICB2YXIgYWxsRmxvd05vZGVTaGFwZXMgPSBbXTtcblxuICBmdW5jdGlvbiBpc0luTGFuZVNoYXBlKGVsZW1lbnQsIGxhbmVTaGFwZSkge1xuXG4gICAgdmFyIGxhbmVUcmJsID0gYXNUUkJMKGxhbmVTaGFwZSk7XG5cbiAgICB2YXIgZWxlbWVudE1pZCA9IHtcbiAgICAgIHg6IGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGggLyAyLFxuICAgICAgeTogZWxlbWVudC55ICsgZWxlbWVudC5oZWlnaHQgLyAyXG4gICAgfTtcblxuICAgIHJldHVybiBlbGVtZW50TWlkLnggPiBsYW5lVHJibC5sZWZ0ICYmXG4gICAgICAgICAgIGVsZW1lbnRNaWQueCA8IGxhbmVUcmJsLnJpZ2h0ICYmXG4gICAgICAgICAgIGVsZW1lbnRNaWQueSA+IGxhbmVUcmJsLnRvcCAmJlxuICAgICAgICAgICBlbGVtZW50TWlkLnkgPCBsYW5lVHJibC5ib3R0b207XG4gIH1cblxuICBmdW5jdGlvbiBhZGRGbG93Tm9kZVNoYXBlKGZsb3dOb2RlU2hhcGUpIHtcbiAgICBpZiAoaGFuZGxlZE5vZGVzLmluZGV4T2YoZmxvd05vZGVTaGFwZSkgPT09IC0xKSB7XG4gICAgICBhbGxGbG93Tm9kZVNoYXBlcy5wdXNoKGZsb3dOb2RlU2hhcGUpO1xuICAgICAgaGFuZGxlZE5vZGVzLnB1c2goZmxvd05vZGVTaGFwZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZ2V0QWxsTGFuZVNoYXBlcyhmbG93Tm9kZVNoYXBlKSB7XG5cbiAgICB2YXIgcm9vdCA9IGdldExhbmVzUm9vdChmbG93Tm9kZVNoYXBlKTtcblxuICAgIGlmICghcGFydGljaXBhbnRDYWNoZVtyb290LmlkXSkge1xuICAgICAgcGFydGljaXBhbnRDYWNoZVtyb290LmlkXSA9IGNvbGxlY3RMYW5lcyhyb290KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFydGljaXBhbnRDYWNoZVtyb290LmlkXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldE5ld0xhbmVzKGZsb3dOb2RlU2hhcGUpIHtcbiAgICBpZiAoIWZsb3dOb2RlU2hhcGUucGFyZW50KSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgdmFyIGFsbExhbmVTaGFwZXMgPSBnZXRBbGxMYW5lU2hhcGVzKGZsb3dOb2RlU2hhcGUpO1xuXG4gICAgcmV0dXJuIGFsbExhbmVTaGFwZXMuZmlsdGVyKGZ1bmN0aW9uKGwpIHtcbiAgICAgIHJldHVybiBpc0luTGFuZVNoYXBlKGZsb3dOb2RlU2hhcGUsIGwpO1xuICAgIH0pLm1hcChmdW5jdGlvbihzaGFwZSkge1xuICAgICAgcmV0dXJuIHNoYXBlLmJ1c2luZXNzT2JqZWN0O1xuICAgIH0pO1xuICB9XG5cbiAgbGFuZVNoYXBlcy5mb3JFYWNoKGZ1bmN0aW9uKGxhbmVTaGFwZSkge1xuICAgIHZhciByb290ID0gZ2V0TGFuZXNSb290KGxhbmVTaGFwZSk7XG5cbiAgICBpZiAoIXJvb3QgfHwgaGFuZGxlZE5vZGVzLmluZGV4T2Yocm9vdCkgIT09IC0xKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGNoaWxkcmVuID0gcm9vdC5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24oYykge1xuICAgICAgcmV0dXJuIGlzKGMsICdicG1uOkZsb3dOb2RlJyk7XG4gICAgfSk7XG5cbiAgICBjaGlsZHJlbi5mb3JFYWNoKGFkZEZsb3dOb2RlU2hhcGUpO1xuXG4gICAgaGFuZGxlZE5vZGVzLnB1c2gocm9vdCk7XG4gIH0pO1xuXG4gIGZsb3dOb2RlU2hhcGVzLmZvckVhY2goYWRkRmxvd05vZGVTaGFwZSk7XG5cblxuICBhbGxGbG93Tm9kZVNoYXBlcy5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dOb2RlU2hhcGUpIHtcblxuICAgIHZhciBmbG93Tm9kZSA9IGZsb3dOb2RlU2hhcGUuYnVzaW5lc3NPYmplY3Q7XG5cbiAgICB2YXIgbGFuZXMgPSBmbG93Tm9kZS5nZXQoTEFORVNfQVRUUiksXG4gICAgICAgIHJlbW92ZSA9IGxhbmVzLnNsaWNlKCksXG4gICAgICAgIGFkZCA9IGdldE5ld0xhbmVzKGZsb3dOb2RlU2hhcGUpO1xuXG4gICAgdXBkYXRlcy5wdXNoKHsgZmxvd05vZGU6IGZsb3dOb2RlLCByZW1vdmU6IHJlbW92ZSwgYWRkOiBhZGQgfSk7XG4gIH0pO1xuXG4gIGxhbmVTaGFwZXMuZm9yRWFjaChmdW5jdGlvbihsYW5lU2hhcGUpIHtcblxuICAgIHZhciBsYW5lID0gbGFuZVNoYXBlLmJ1c2luZXNzT2JqZWN0O1xuXG4gICAgLy8gbGFuZSBnb3QgcmVtb3ZlZCBYWC0pXG4gICAgaWYgKCFsYW5lU2hhcGUucGFyZW50KSB7XG4gICAgICBsYW5lLmdldChGTE9XX05PREVfUkVGU19BVFRSKS5mb3JFYWNoKGZ1bmN0aW9uKGZsb3dOb2RlKSB7XG4gICAgICAgIHVwZGF0ZXMucHVzaCh7IGZsb3dOb2RlOiBmbG93Tm9kZSwgcmVtb3ZlOiBbIGxhbmUgXSwgYWRkOiBbXSB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHVwZGF0ZXM7XG59O1xuXG5VcGRhdGVGbG93Tm9kZVJlZnNIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciB1cGRhdGVzID0gY29udGV4dC51cGRhdGVzO1xuXG4gIGlmICghdXBkYXRlcykge1xuICAgIHVwZGF0ZXMgPSBjb250ZXh0LnVwZGF0ZXMgPSB0aGlzLmNvbXB1dGVVcGRhdGVzKGNvbnRleHQuZmxvd05vZGVTaGFwZXMsIGNvbnRleHQubGFuZVNoYXBlcyk7XG4gIH1cblxuXG4gIHVwZGF0ZXMuZm9yRWFjaChmdW5jdGlvbih1cGRhdGUpIHtcblxuICAgIHZhciBmbG93Tm9kZSA9IHVwZGF0ZS5mbG93Tm9kZSxcbiAgICAgICAgbGFuZXMgPSBmbG93Tm9kZS5nZXQoTEFORVNfQVRUUik7XG5cbiAgICAvLyB1bndpcmUgb2xkXG4gICAgdXBkYXRlLnJlbW92ZS5mb3JFYWNoKGZ1bmN0aW9uKG9sZExhbmUpIHtcbiAgICAgIGNvbGxlY3Rpb25SZW1vdmUobGFuZXMsIG9sZExhbmUpO1xuICAgICAgY29sbGVjdGlvblJlbW92ZShvbGRMYW5lLmdldChGTE9XX05PREVfUkVGU19BVFRSKSwgZmxvd05vZGUpO1xuICAgIH0pO1xuXG4gICAgLy8gd2lyZSBuZXdcbiAgICB1cGRhdGUuYWRkLmZvckVhY2goZnVuY3Rpb24obmV3TGFuZSkge1xuICAgICAgY29sbGVjdGlvbkFkZChsYW5lcywgbmV3TGFuZSk7XG4gICAgICBjb2xsZWN0aW9uQWRkKG5ld0xhbmUuZ2V0KEZMT1dfTk9ERV9SRUZTX0FUVFIpLCBmbG93Tm9kZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIFRPRE8obmlra3UpOiByZXR1cm4gY2hhbmdlZCBlbGVtZW50c1xuICAvLyByZXR1cm4gWyAuLi4gXTtcbn07XG5cblxuVXBkYXRlRmxvd05vZGVSZWZzSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciB1cGRhdGVzID0gY29udGV4dC51cGRhdGVzO1xuXG4gIHVwZGF0ZXMuZm9yRWFjaChmdW5jdGlvbih1cGRhdGUpIHtcblxuICAgIHZhciBmbG93Tm9kZSA9IHVwZGF0ZS5mbG93Tm9kZSxcbiAgICAgICAgbGFuZXMgPSBmbG93Tm9kZS5nZXQoTEFORVNfQVRUUik7XG5cbiAgICAvLyB1bndpcmUgbmV3XG4gICAgdXBkYXRlLmFkZC5mb3JFYWNoKGZ1bmN0aW9uKG5ld0xhbmUpIHtcbiAgICAgIGNvbGxlY3Rpb25SZW1vdmUobGFuZXMsIG5ld0xhbmUpO1xuICAgICAgY29sbGVjdGlvblJlbW92ZShuZXdMYW5lLmdldChGTE9XX05PREVfUkVGU19BVFRSKSwgZmxvd05vZGUpO1xuICAgIH0pO1xuXG4gICAgLy8gd2lyZSBvbGRcbiAgICB1cGRhdGUucmVtb3ZlLmZvckVhY2goZnVuY3Rpb24ob2xkTGFuZSkge1xuICAgICAgY29sbGVjdGlvbkFkZChsYW5lcywgb2xkTGFuZSk7XG4gICAgICBjb2xsZWN0aW9uQWRkKG9sZExhbmUuZ2V0KEZMT1dfTk9ERV9SRUZTX0FUVFIpLCBmbG93Tm9kZSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIFRPRE8obmlra3UpOiByZXR1cm4gY2hhbmdlZCBlbGVtZW50c1xuICAvLyByZXR1cm4gWyAuLi4gXTtcbn07XG4iLCJpbXBvcnQge1xuICByZWR1Y2UsXG4gIGtleXMsXG4gIGZvckVhY2gsXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGdldEJ1c2luZXNzT2JqZWN0XG59IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxudmFyIERFRkFVTFRfRkxPVyA9ICdkZWZhdWx0JyxcbiAgICBJRCA9ICdpZCcsXG4gICAgREkgPSAnZGknO1xuXG52YXIgTlVMTF9ESU1FTlNJT05TID0ge1xuICB3aWR0aDogMCxcbiAgaGVpZ2h0OiAwXG59O1xuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgYSBCUE1OIDIuMCBwcm9wZXJ0eSB1cGRhdGUuXG4gKlxuICogVGhpcyBzaG91bGQgYmUgdXNlZCB0byBzZXQgc2ltcGxlIHByb3BlcnRpZXMgb24gZWxlbWVudHMgd2l0aFxuICogYW4gdW5kZXJseWluZyBCUE1OIGJ1c2luZXNzIG9iamVjdC5cbiAqXG4gKiBVc2UgcmVzcGVjdGl2ZSBkaWFncmFtLWpzIHByb3ZpZGVkIGhhbmRsZXJzIGlmIHlvdSB3b3VsZFxuICogbGlrZSB0byBwZXJmb3JtIGF1dG9tYXRlZCBtb2RlbGluZy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVXBkYXRlUHJvcGVydGllc0hhbmRsZXIoXG4gICAgZWxlbWVudFJlZ2lzdHJ5LCBtb2RkbGUsIHRyYW5zbGF0ZSxcbiAgICBtb2RlbGluZywgdGV4dFJlbmRlcmVyKSB7XG5cbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9tb2RkbGUgPSBtb2RkbGU7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fdGV4dFJlbmRlcmVyID0gdGV4dFJlbmRlcmVyO1xufVxuXG5VcGRhdGVQcm9wZXJ0aWVzSGFuZGxlci4kaW5qZWN0ID0gW1xuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ21vZGRsZScsXG4gICd0cmFuc2xhdGUnLFxuICAnbW9kZWxpbmcnLFxuICAndGV4dFJlbmRlcmVyJ1xuXTtcblxuXG4vLyBhcGkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vKipcbiAqIFVwZGF0ZXMgYSBCUE1OIGVsZW1lbnQgd2l0aCBhIGxpc3Qgb2YgbmV3IHByb3BlcnRpZXNcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gY29udGV4dC5lbGVtZW50IHRoZSBlbGVtZW50IHRvIHVwZGF0ZVxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQucHJvcGVydGllcyBhIGxpc3Qgb2YgcHJvcGVydGllcyB0byBzZXQgb24gdGhlIGVsZW1lbnQnc1xuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidXNpbmVzc09iamVjdCAodGhlIEJQTU4gbW9kZWwgZWxlbWVudClcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuQmFzZT59IHRoZSB1cGRhdGVkIGVsZW1lbnRcbiAqL1xuVXBkYXRlUHJvcGVydGllc0hhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGVsZW1lbnQgPSBjb250ZXh0LmVsZW1lbnQsXG4gICAgICBjaGFuZ2VkID0gWyBlbGVtZW50IF0sXG4gICAgICB0cmFuc2xhdGUgPSB0aGlzLl90cmFuc2xhdGU7XG5cbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnZWxlbWVudCByZXF1aXJlZCcpKTtcbiAgfVxuXG4gIHZhciBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnksXG4gICAgICBpZHMgPSB0aGlzLl9tb2RkbGUuaWRzO1xuXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGVsZW1lbnQuYnVzaW5lc3NPYmplY3QsXG4gICAgICBwcm9wZXJ0aWVzID0gdW53cmFwQnVzaW5lc3NPYmplY3RzKGNvbnRleHQucHJvcGVydGllcyksXG4gICAgICBvbGRQcm9wZXJ0aWVzID0gY29udGV4dC5vbGRQcm9wZXJ0aWVzIHx8IGdldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIHByb3BlcnRpZXMpO1xuXG4gIGlmIChpc0lkQ2hhbmdlKHByb3BlcnRpZXMsIGJ1c2luZXNzT2JqZWN0KSkge1xuICAgIGlkcy51bmNsYWltKGJ1c2luZXNzT2JqZWN0W0lEXSk7XG5cbiAgICBlbGVtZW50UmVnaXN0cnkudXBkYXRlSWQoZWxlbWVudCwgcHJvcGVydGllc1tJRF0pO1xuXG4gICAgaWRzLmNsYWltKHByb3BlcnRpZXNbSURdLCBidXNpbmVzc09iamVjdCk7XG4gIH1cblxuICAvLyBjb3JyZWN0bHkgaW5kaWNhdGUgdmlzdWFsIGNoYW5nZXMgb24gZGVmYXVsdCBmbG93IHVwZGF0ZXNcbiAgaWYgKERFRkFVTFRfRkxPVyBpbiBwcm9wZXJ0aWVzKSB7XG5cbiAgICBpZiAocHJvcGVydGllc1tERUZBVUxUX0ZMT1ddKSB7XG4gICAgICBjaGFuZ2VkLnB1c2goZWxlbWVudFJlZ2lzdHJ5LmdldChwcm9wZXJ0aWVzW0RFRkFVTFRfRkxPV10uaWQpKTtcbiAgICB9XG5cbiAgICBpZiAoYnVzaW5lc3NPYmplY3RbREVGQVVMVF9GTE9XXSkge1xuICAgICAgY2hhbmdlZC5wdXNoKGVsZW1lbnRSZWdpc3RyeS5nZXQoYnVzaW5lc3NPYmplY3RbREVGQVVMVF9GTE9XXS5pZCkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHVwZGF0ZSBwcm9wZXJ0aWVzXG4gIHNldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIHByb3BlcnRpZXMpO1xuXG4gIC8vIHN0b3JlIG9sZCB2YWx1ZXNcbiAgY29udGV4dC5vbGRQcm9wZXJ0aWVzID0gb2xkUHJvcGVydGllcztcbiAgY29udGV4dC5jaGFuZ2VkID0gY2hhbmdlZDtcblxuICAvLyBpbmRpY2F0ZSBjaGFuZ2VkIG9uIG9iamVjdHMgYWZmZWN0ZWQgYnkgdGhlIHVwZGF0ZVxuICByZXR1cm4gY2hhbmdlZDtcbn07XG5cblxuVXBkYXRlUHJvcGVydGllc0hhbmRsZXIucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcbiAgICAgIGxhYmVsID0gZWxlbWVudC5sYWJlbDtcblxuICB2YXIgdGV4dCA9IGxhYmVsICYmIGdldEJ1c2luZXNzT2JqZWN0KGxhYmVsKS5uYW1lO1xuXG4gIGlmICghdGV4dCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGdldCBsYXlvdXRlZCB0ZXh0IGJvdW5kcyBhbmQgcmVzaXplIGV4dGVybmFsXG4gIC8vIGV4dGVybmFsIGxhYmVsIGFjY29yZGluZ2x5XG4gIHZhciBuZXdMYWJlbEJvdW5kcyA9IHRoaXMuX3RleHRSZW5kZXJlci5nZXRFeHRlcm5hbExhYmVsQm91bmRzKGxhYmVsLCB0ZXh0KTtcblxuICB0aGlzLl9tb2RlbGluZy5yZXNpemVTaGFwZShsYWJlbCwgbmV3TGFiZWxCb3VuZHMsIE5VTExfRElNRU5TSU9OUyk7XG59O1xuXG4vKipcbiAqIFJldmVydHMgdGhlIHVwZGF0ZSBvbiBhIEJQTU4gZWxlbWVudHMgcHJvcGVydGllcy5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGNvbnRleHRcbiAqXG4gKiBAcmV0dXJuIHtkanMubW9kZWwuQmFzZX0gdGhlIHVwZGF0ZWQgZWxlbWVudFxuICovXG5VcGRhdGVQcm9wZXJ0aWVzSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgcHJvcGVydGllcyA9IGNvbnRleHQucHJvcGVydGllcyxcbiAgICAgIG9sZFByb3BlcnRpZXMgPSBjb250ZXh0Lm9sZFByb3BlcnRpZXMsXG4gICAgICBidXNpbmVzc09iamVjdCA9IGVsZW1lbnQuYnVzaW5lc3NPYmplY3QsXG4gICAgICBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnksXG4gICAgICBpZHMgPSB0aGlzLl9tb2RkbGUuaWRzO1xuXG4gIC8vIHVwZGF0ZSBwcm9wZXJ0aWVzXG4gIHNldFByb3BlcnRpZXMoYnVzaW5lc3NPYmplY3QsIG9sZFByb3BlcnRpZXMpO1xuXG4gIGlmIChpc0lkQ2hhbmdlKHByb3BlcnRpZXMsIGJ1c2luZXNzT2JqZWN0KSkge1xuICAgIGlkcy51bmNsYWltKHByb3BlcnRpZXNbSURdKTtcblxuICAgIGVsZW1lbnRSZWdpc3RyeS51cGRhdGVJZChlbGVtZW50LCBvbGRQcm9wZXJ0aWVzW0lEXSk7XG5cbiAgICBpZHMuY2xhaW0ob2xkUHJvcGVydGllc1tJRF0sIGJ1c2luZXNzT2JqZWN0KTtcbiAgfVxuXG4gIHJldHVybiBjb250ZXh0LmNoYW5nZWQ7XG59O1xuXG5cbmZ1bmN0aW9uIGlzSWRDaGFuZ2UocHJvcGVydGllcywgYnVzaW5lc3NPYmplY3QpIHtcbiAgcmV0dXJuIElEIGluIHByb3BlcnRpZXMgJiYgcHJvcGVydGllc1tJRF0gIT09IGJ1c2luZXNzT2JqZWN0W0lEXTtcbn1cblxuXG5mdW5jdGlvbiBnZXRQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBwcm9wZXJ0aWVzKSB7XG4gIHZhciBwcm9wZXJ0eU5hbWVzID0ga2V5cyhwcm9wZXJ0aWVzKTtcblxuICByZXR1cm4gcmVkdWNlKHByb3BlcnR5TmFtZXMsIGZ1bmN0aW9uKHJlc3VsdCwga2V5KSB7XG5cbiAgICAvLyBoYW5kbGUgREkgc2VwYXJhdGVseVxuICAgIGlmIChrZXkgIT09IERJKSB7XG4gICAgICByZXN1bHRba2V5XSA9IGJ1c2luZXNzT2JqZWN0LmdldChrZXkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHRba2V5XSA9IGdldERpUHJvcGVydGllcyhidXNpbmVzc09iamVjdC5kaSwga2V5cyhwcm9wZXJ0aWVzLmRpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSwge30pO1xufVxuXG5cbmZ1bmN0aW9uIGdldERpUHJvcGVydGllcyhkaSwgcHJvcGVydHlOYW1lcykge1xuICByZXR1cm4gcmVkdWNlKHByb3BlcnR5TmFtZXMsIGZ1bmN0aW9uKHJlc3VsdCwga2V5KSB7XG4gICAgcmVzdWx0W2tleV0gPSBkaS5nZXQoa2V5KTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH0sIHt9KTtcbn1cblxuXG5mdW5jdGlvbiBzZXRQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LCBwcm9wZXJ0aWVzKSB7XG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24odmFsdWUsIGtleSkge1xuXG4gICAgaWYgKGtleSAhPT0gREkpIHtcbiAgICAgIGJ1c2luZXNzT2JqZWN0LnNldChrZXksIHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBvbmx5IHVwZGF0ZSwgaWYgYnVzaW5lc3NPYmplY3QuZGkgZXhpc3RzXG4gICAgICBpZiAoYnVzaW5lc3NPYmplY3QuZGkpIHtcbiAgICAgICAgc2V0RGlQcm9wZXJ0aWVzKGJ1c2luZXNzT2JqZWN0LmRpLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBzZXREaVByb3BlcnRpZXMoZGksIHByb3BlcnRpZXMpIHtcbiAgZm9yRWFjaChwcm9wZXJ0aWVzLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gICAgZGkuc2V0KGtleSwgdmFsdWUpO1xuICB9KTtcbn1cblxuXG52YXIgcmVmZXJlbmNlUHJvcGVydHlOYW1lcyA9IFsgJ2RlZmF1bHQnIF07XG5cbi8qKlxuICogTWFrZSBzdXJlIHdlIHVud3JhcCB0aGUgYWN0dWFsIGJ1c2luZXNzIG9iamVjdFxuICogYmVoaW5kIGRpYWdyYW0gZWxlbWVudCB0aGF0IG1heSBoYXZlIGJlZW5cbiAqIHBhc3NlZCBhcyBhcmd1bWVudHMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBwcm9wZXJ0aWVzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB1bndyYXBwZWRQcm9wc1xuICovXG5mdW5jdGlvbiB1bndyYXBCdXNpbmVzc09iamVjdHMocHJvcGVydGllcykge1xuXG4gIHZhciB1bndyYXBwZWRQcm9wcyA9IGFzc2lnbih7fSwgcHJvcGVydGllcyk7XG5cbiAgcmVmZXJlbmNlUHJvcGVydHlOYW1lcy5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICBpZiAobmFtZSBpbiBwcm9wZXJ0aWVzKSB7XG4gICAgICB1bndyYXBwZWRQcm9wc1tuYW1lXSA9IGdldEJ1c2luZXNzT2JqZWN0KHVud3JhcHBlZFByb3BzW25hbWVdKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB1bndyYXBwZWRQcm9wcztcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBVcGRhdGVTZW1hbnRpY1BhcmVudEhhbmRsZXIoYnBtblVwZGF0ZXIpIHtcclxuICB0aGlzLl9icG1uVXBkYXRlciA9IGJwbW5VcGRhdGVyO1xyXG59XHJcblxyXG5VcGRhdGVTZW1hbnRpY1BhcmVudEhhbmRsZXIuJGluamVjdCA9IFsgJ2JwbW5VcGRhdGVyJyBdO1xyXG5cclxuXHJcblVwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICB2YXIgZGF0YVN0b3JlQm8gPSBjb250ZXh0LmRhdGFTdG9yZUJvLFxyXG4gICAgICBuZXdTZW1hbnRpY1BhcmVudCA9IGNvbnRleHQubmV3U2VtYW50aWNQYXJlbnQsXHJcbiAgICAgIG5ld0RpUGFyZW50ID0gY29udGV4dC5uZXdEaVBhcmVudDtcclxuXHJcbiAgY29udGV4dC5vbGRTZW1hbnRpY1BhcmVudCA9IGRhdGFTdG9yZUJvLiRwYXJlbnQ7XHJcbiAgY29udGV4dC5vbGREaVBhcmVudCA9IGRhdGFTdG9yZUJvLmRpLiRwYXJlbnQ7XHJcblxyXG4gIC8vIHVwZGF0ZSBzZW1hbnRpYyBwYXJlbnRcclxuICB0aGlzLl9icG1uVXBkYXRlci51cGRhdGVTZW1hbnRpY1BhcmVudChkYXRhU3RvcmVCbywgbmV3U2VtYW50aWNQYXJlbnQpO1xyXG5cclxuICAvLyB1cGRhdGUgREkgcGFyZW50XHJcbiAgdGhpcy5fYnBtblVwZGF0ZXIudXBkYXRlRGlQYXJlbnQoZGF0YVN0b3JlQm8uZGksIG5ld0RpUGFyZW50KTtcclxufTtcclxuXHJcblVwZGF0ZVNlbWFudGljUGFyZW50SGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xyXG4gIHZhciBkYXRhU3RvcmVCbyA9IGNvbnRleHQuZGF0YVN0b3JlQm8sXHJcbiAgICAgIG9sZFNlbWFudGljUGFyZW50ID0gY29udGV4dC5vbGRTZW1hbnRpY1BhcmVudCxcclxuICAgICAgb2xkRGlQYXJlbnQgPSBjb250ZXh0Lm9sZERpUGFyZW50O1xyXG5cclxuICAvLyB1cGRhdGUgc2VtYW50aWMgcGFyZW50XHJcbiAgdGhpcy5fYnBtblVwZGF0ZXIudXBkYXRlU2VtYW50aWNQYXJlbnQoZGF0YVN0b3JlQm8sIG9sZFNlbWFudGljUGFyZW50KTtcclxuXHJcbiAgLy8gdXBkYXRlIERJIHBhcmVudFxyXG4gIHRoaXMuX2JwbW5VcGRhdGVyLnVwZGF0ZURpUGFyZW50KGRhdGFTdG9yZUJvLmRpLCBvbGREaVBhcmVudCk7XHJcbn07XHJcblxyXG4iLCJpbXBvcnQgQmVoYXZpb3JNb2R1bGUgZnJvbSAnLi9iZWhhdmlvcic7XG5pbXBvcnQgUnVsZXNNb2R1bGUgZnJvbSAnLi4vcnVsZXMnO1xuaW1wb3J0IERpT3JkZXJpbmdNb2R1bGUgZnJvbSAnLi4vZGktb3JkZXJpbmcnO1xuaW1wb3J0IE9yZGVyaW5nTW9kdWxlIGZyb20gJy4uL29yZGVyaW5nJztcbmltcG9ydCBSZXBsYWNlTW9kdWxlIGZyb20gJy4uL3JlcGxhY2UnO1xuXG5pbXBvcnQgQ29tbWFuZE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kJztcbmltcG9ydCBUb29sdGlwc01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy90b29sdGlwcyc7XG5pbXBvcnQgTGFiZWxTdXBwb3J0TW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2xhYmVsLXN1cHBvcnQnO1xuaW1wb3J0IEF0dGFjaFN1cHBvcnRNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvYXR0YWNoLXN1cHBvcnQnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zZWxlY3Rpb24nO1xuaW1wb3J0IENoYW5nZVN1cHBvcnRNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY2hhbmdlLXN1cHBvcnQnO1xuaW1wb3J0IFNwYWNlVG9vbE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zcGFjZS10b29sJztcblxuaW1wb3J0IEJwbW5GYWN0b3J5IGZyb20gJy4vQnBtbkZhY3RvcnknO1xuaW1wb3J0IEJwbW5VcGRhdGVyIGZyb20gJy4vQnBtblVwZGF0ZXInO1xuaW1wb3J0IEVsZW1lbnRGYWN0b3J5IGZyb20gJy4vRWxlbWVudEZhY3RvcnknO1xuaW1wb3J0IE1vZGVsaW5nIGZyb20gJy4vTW9kZWxpbmcnO1xuaW1wb3J0IEJwbW5MYXlvdXRlciBmcm9tICcuL0JwbW5MYXlvdXRlcic7XG5pbXBvcnQgQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZyBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZyc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogW1xuICAgICdtb2RlbGluZycsXG4gICAgJ2JwbW5VcGRhdGVyJ1xuICBdLFxuICBfX2RlcGVuZHNfXzogW1xuICAgIEJlaGF2aW9yTW9kdWxlLFxuICAgIFJ1bGVzTW9kdWxlLFxuICAgIERpT3JkZXJpbmdNb2R1bGUsXG4gICAgT3JkZXJpbmdNb2R1bGUsXG4gICAgUmVwbGFjZU1vZHVsZSxcbiAgICBDb21tYW5kTW9kdWxlLFxuICAgIFRvb2x0aXBzTW9kdWxlLFxuICAgIExhYmVsU3VwcG9ydE1vZHVsZSxcbiAgICBBdHRhY2hTdXBwb3J0TW9kdWxlLFxuICAgIFNlbGVjdGlvbk1vZHVsZSxcbiAgICBDaGFuZ2VTdXBwb3J0TW9kdWxlLFxuICAgIFNwYWNlVG9vbE1vZHVsZVxuICBdLFxuICBicG1uRmFjdG9yeTogWyAndHlwZScsIEJwbW5GYWN0b3J5IF0sXG4gIGJwbW5VcGRhdGVyOiBbICd0eXBlJywgQnBtblVwZGF0ZXIgXSxcbiAgZWxlbWVudEZhY3Rvcnk6IFsgJ3R5cGUnLCBFbGVtZW50RmFjdG9yeSBdLFxuICBtb2RlbGluZzogWyAndHlwZScsIE1vZGVsaW5nIF0sXG4gIGxheW91dGVyOiBbICd0eXBlJywgQnBtbkxheW91dGVyIF0sXG4gIGNvbm5lY3Rpb25Eb2NraW5nOiBbICd0eXBlJywgQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZyBdXG59OyIsImltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRQYXJlbnRcbn0gZnJvbSAnLi9Nb2RlbGluZ1V0aWwnO1xuXG5pbXBvcnQge1xuICBhc1RSQkxcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBzdWJzdHJhY3RUUkJMLFxuICByZXNpemVUUkJMXG59IGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3Jlc2l6ZS9SZXNpemVVdGlsJztcblxudmFyIGFicyA9IE1hdGguYWJzO1xuXG5cbmZ1bmN0aW9uIGdldFRSQkxSZXNpemUob2xkQm91bmRzLCBuZXdCb3VuZHMpIHtcbiAgcmV0dXJuIHN1YnN0cmFjdFRSQkwoYXNUUkJMKG5ld0JvdW5kcyksIGFzVFJCTChvbGRCb3VuZHMpKTtcbn1cblxuXG52YXIgTEFORV9QQVJFTlRTID0gW1xuICAnYnBtbjpQYXJ0aWNpcGFudCcsXG4gICdicG1uOlByb2Nlc3MnLFxuICAnYnBtbjpTdWJQcm9jZXNzJ1xuXTtcblxuZXhwb3J0IHZhciBMQU5FX0lOREVOVEFUSU9OID0gMzA7XG5cblxuLyoqXG4gKiBDb2xsZWN0IGFsbCBsYW5lIHNoYXBlcyBpbiB0aGUgZ2l2ZW4gcGFyZW5cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuU2hhcGV9IHNoYXBlXG4gKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuQmFzZT59IFtjb2xsZWN0ZWRTaGFwZXNdXG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29sbGVjdExhbmVzKHNoYXBlLCBjb2xsZWN0ZWRTaGFwZXMpIHtcblxuICBjb2xsZWN0ZWRTaGFwZXMgPSBjb2xsZWN0ZWRTaGFwZXMgfHwgW107XG5cbiAgc2hhcGUuY2hpbGRyZW4uZmlsdGVyKGZ1bmN0aW9uKHMpIHtcbiAgICBpZiAoaXMocywgJ2JwbW46TGFuZScpKSB7XG4gICAgICBjb2xsZWN0TGFuZXMocywgY29sbGVjdGVkU2hhcGVzKTtcblxuICAgICAgY29sbGVjdGVkU2hhcGVzLnB1c2gocyk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gY29sbGVjdGVkU2hhcGVzO1xufVxuXG5cbi8qKlxuICogUmV0dXJuIHRoZSBsYW5lIGNoaWxkcmVuIG9mIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICpcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGlsZExhbmVzKHNoYXBlKSB7XG4gIHJldHVybiBzaGFwZS5jaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24oYykge1xuICAgIHJldHVybiBpcyhjLCAnYnBtbjpMYW5lJyk7XG4gIH0pO1xufVxuXG5cbi8qKlxuICogUmV0dXJuIHRoZSByb290IGVsZW1lbnQgY29udGFpbmluZyB0aGUgZ2l2ZW4gbGFuZSBzaGFwZVxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5TaGFwZX1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExhbmVzUm9vdChzaGFwZSkge1xuICByZXR1cm4gZ2V0UGFyZW50KHNoYXBlLCBMQU5FX1BBUkVOVFMpIHx8IHNoYXBlO1xufVxuXG5cbi8qKlxuICogQ29tcHV0ZSB0aGUgcmVxdWlyZWQgcmVzaXplIG9wZXJhdGlvbnMgZm9yIGxhbmVzXG4gKiBhZGphY2VudCB0byB0aGUgZ2l2ZW4gc2hhcGUsIGFzc3VtaW5nIGl0IHdpbGwgYmVcbiAqIHJlc2l6ZWQgdG8gdGhlIGdpdmVuIG5ldyBib3VuZHMuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHNoYXBlXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXG4gKlxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVMYW5lc1Jlc2l6ZShzaGFwZSwgbmV3Qm91bmRzKSB7XG5cbiAgdmFyIHJvb3RFbGVtZW50ID0gZ2V0TGFuZXNSb290KHNoYXBlKTtcblxuICB2YXIgaW5pdGlhbFNoYXBlcyA9IGlzKHJvb3RFbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgPyBbXSA6IFsgcm9vdEVsZW1lbnQgXTtcblxuICB2YXIgYWxsTGFuZXMgPSBjb2xsZWN0TGFuZXMocm9vdEVsZW1lbnQsIGluaXRpYWxTaGFwZXMpLFxuICAgICAgc2hhcGVUcmJsID0gYXNUUkJMKHNoYXBlKSxcbiAgICAgIHNoYXBlTmV3VHJibCA9IGFzVFJCTChuZXdCb3VuZHMpLFxuICAgICAgdHJibFJlc2l6ZSA9IGdldFRSQkxSZXNpemUoc2hhcGUsIG5ld0JvdW5kcyksXG4gICAgICByZXNpemVOZWVkZWQgPSBbXTtcblxuICBhbGxMYW5lcy5mb3JFYWNoKGZ1bmN0aW9uKG90aGVyKSB7XG5cbiAgICBpZiAob3RoZXIgPT09IHNoYXBlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRvcFJlc2l6ZSA9IDAsXG4gICAgICAgIHJpZ2h0UmVzaXplID0gdHJibFJlc2l6ZS5yaWdodCxcbiAgICAgICAgYm90dG9tUmVzaXplID0gMCxcbiAgICAgICAgbGVmdFJlc2l6ZSA9IHRyYmxSZXNpemUubGVmdDtcblxuICAgIHZhciBvdGhlclRyYmwgPSBhc1RSQkwob3RoZXIpO1xuXG4gICAgaWYgKHRyYmxSZXNpemUudG9wKSB7XG4gICAgICBpZiAoYWJzKG90aGVyVHJibC5ib3R0b20gLSBzaGFwZVRyYmwudG9wKSA8IDEwKSB7XG4gICAgICAgIGJvdHRvbVJlc2l6ZSA9IHNoYXBlTmV3VHJibC50b3AgLSBvdGhlclRyYmwuYm90dG9tO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWJzKG90aGVyVHJibC50b3AgLSBzaGFwZVRyYmwudG9wKSA8IDUpIHtcbiAgICAgICAgdG9wUmVzaXplID0gc2hhcGVOZXdUcmJsLnRvcCAtIG90aGVyVHJibC50b3A7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRyYmxSZXNpemUuYm90dG9tKSB7XG4gICAgICBpZiAoYWJzKG90aGVyVHJibC50b3AgLSBzaGFwZVRyYmwuYm90dG9tKSA8IDEwKSB7XG4gICAgICAgIHRvcFJlc2l6ZSA9IHNoYXBlTmV3VHJibC5ib3R0b20gLSBvdGhlclRyYmwudG9wO1xuICAgICAgfVxuXG4gICAgICBpZiAoYWJzKG90aGVyVHJibC5ib3R0b20gLSBzaGFwZVRyYmwuYm90dG9tKSA8IDUpIHtcbiAgICAgICAgYm90dG9tUmVzaXplID0gc2hhcGVOZXdUcmJsLmJvdHRvbSAtIG90aGVyVHJibC5ib3R0b207XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRvcFJlc2l6ZSB8fCByaWdodFJlc2l6ZSB8fCBib3R0b21SZXNpemUgfHwgbGVmdFJlc2l6ZSkge1xuXG4gICAgICByZXNpemVOZWVkZWQucHVzaCh7XG4gICAgICAgIHNoYXBlOiBvdGhlcixcbiAgICAgICAgbmV3Qm91bmRzOiByZXNpemVUUkJMKG90aGVyLCB7XG4gICAgICAgICAgdG9wOiB0b3BSZXNpemUsXG4gICAgICAgICAgcmlnaHQ6IHJpZ2h0UmVzaXplLFxuICAgICAgICAgIGJvdHRvbTogYm90dG9tUmVzaXplLFxuICAgICAgICAgIGxlZnQ6IGxlZnRSZXNpemVcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgIH1cblxuICB9KTtcblxuICByZXR1cm4gcmVzaXplTmVlZGVkO1xufSIsImltcG9ydCB7XG4gIHNvbWVcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgeyBpcyB9IGZyb20gJy4uLy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuXG4vKipcbiAqIFJldHVybiB0cnVlIGlmIGVsZW1lbnQgaGFzIGFueSBvZiB0aGUgZ2l2ZW4gdHlwZXMuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSB0eXBlc1xuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0FueShlbGVtZW50LCB0eXBlcykge1xuICByZXR1cm4gc29tZSh0eXBlcywgZnVuY3Rpb24odCkge1xuICAgIHJldHVybiBpcyhlbGVtZW50LCB0KTtcbiAgfSk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm4gdGhlIHBhcmVudCBvZiB0aGUgZWxlbWVudCB3aXRoIGFueSBvZiB0aGUgZ2l2ZW4gdHlwZXMuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gYW55VHlwZVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5CYXNlfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFyZW50KGVsZW1lbnQsIGFueVR5cGUpIHtcblxuICBpZiAodHlwZW9mIGFueVR5cGUgPT09ICdzdHJpbmcnKSB7XG4gICAgYW55VHlwZSA9IFsgYW55VHlwZSBdO1xuICB9XG5cbiAgd2hpbGUgKChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnQpKSB7XG4gICAgaWYgKGlzQW55KGVsZW1lbnQsIGFueVR5cGUpKSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgT3JkZXJpbmdQcm92aWRlciBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9vcmRlcmluZy9PcmRlcmluZ1Byb3ZpZGVyJztcblxuaW1wb3J0IHtcbiAgaXNBbnlcbn0gZnJvbSAnLi4vbW9kZWxpbmcvdXRpbC9Nb2RlbGluZ1V0aWwnO1xuXG5pbXBvcnQge1xuICBmaW5kSW5kZXgsXG4gIGZpbmRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5cbi8qKlxuICogYSBzaW1wbGUgb3JkZXJpbmcgcHJvdmlkZXIgdGhhdCBtYWtlcyBzdXJlOlxuICpcbiAqICgwKSBsYWJlbHMgYW5kIGdyb3VwcyBhcmUgcmVuZGVyZWQgYWx3YXlzIG9uIHRvcFxuICogKDEpIGVsZW1lbnRzIGFyZSBvcmRlcmVkIGJ5IGEge2xldmVsfSBwcm9wZXJ0eVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uT3JkZXJpbmdQcm92aWRlcihldmVudEJ1cywgY2FudmFzLCB0cmFuc2xhdGUpIHtcblxuICBPcmRlcmluZ1Byb3ZpZGVyLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHZhciBvcmRlcnMgPSBbXG4gICAgeyB0eXBlOiAnYnBtbjpTdWJQcm9jZXNzJywgb3JkZXI6IHsgbGV2ZWw6IDYgfSB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdicG1uOlNlcXVlbmNlRmxvdycsXG4gICAgICBvcmRlcjoge1xuICAgICAgICBsZXZlbDogMyxcbiAgICAgICAgY29udGFpbmVyczogW1xuICAgICAgICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAgICAgICAnYnBtbjpGbG93RWxlbWVudHNDb250YWluZXInXG4gICAgICAgIF1cbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLy8gaGFuZGxlIERhdGFBc3NvY2lhdGlvbihzKSBsaWtlIG1lc3NhZ2UgZmxvd3MgYW5kIHJlbmRlciB0aGVtIGFsd2F5cyBvbiB0b3BcbiAgICB7XG4gICAgICB0eXBlOiAnYnBtbjpEYXRhQXNzb2NpYXRpb24nLFxuICAgICAgb3JkZXI6IHtcbiAgICAgICAgbGV2ZWw6IDksXG4gICAgICAgIGNvbnRhaW5lcnM6IFtcbiAgICAgICAgICAnYnBtbjpDb2xsYWJvcmF0aW9uJyxcbiAgICAgICAgICAnYnBtbjpQcm9jZXNzJ1xuICAgICAgICBdXG4gICAgICB9XG4gICAgfSxcbiAgICB7XG4gICAgICB0eXBlOiAnYnBtbjpNZXNzYWdlRmxvdycsIG9yZGVyOiB7XG4gICAgICAgIGxldmVsOiA5LFxuICAgICAgICBjb250YWluZXJzOiBbICdicG1uOkNvbGxhYm9yYXRpb24nIF1cbiAgICAgIH1cbiAgICB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdicG1uOkFzc29jaWF0aW9uJyxcbiAgICAgIG9yZGVyOiB7XG4gICAgICAgIGxldmVsOiA2LFxuICAgICAgICBjb250YWluZXJzOiBbXG4gICAgICAgICAgJ2JwbW46UGFydGljaXBhbnQnLFxuICAgICAgICAgICdicG1uOkZsb3dFbGVtZW50c0NvbnRhaW5lcicsXG4gICAgICAgICAgJ2JwbW46Q29sbGFib3JhdGlvbidcbiAgICAgICAgXVxuICAgICAgfVxuICAgIH0sXG4gICAgeyB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50Jywgb3JkZXI6IHsgbGV2ZWw6IDggfSB9LFxuICAgIHtcbiAgICAgIHR5cGU6ICdicG1uOkdyb3VwJyxcbiAgICAgIG9yZGVyOiB7XG4gICAgICAgIGxldmVsOiAxMCxcbiAgICAgICAgY29udGFpbmVyczogW1xuICAgICAgICAgICdicG1uOkNvbGxhYm9yYXRpb24nLFxuICAgICAgICAgICdicG1uOlByb2Nlc3MnXG4gICAgICAgIF1cbiAgICAgIH1cbiAgICB9LFxuICAgIHsgdHlwZTogJ2JwbW46Rmxvd0VsZW1lbnQnLCBvcmRlcjogeyBsZXZlbDogNSB9IH0sXG4gICAgeyB0eXBlOiAnYnBtbjpQYXJ0aWNpcGFudCcsIG9yZGVyOiB7IGxldmVsOiAtMiB9IH0sXG4gICAgeyB0eXBlOiAnYnBtbjpMYW5lJywgb3JkZXI6IHsgbGV2ZWw6IC0xIH0gfVxuICBdO1xuXG4gIGZ1bmN0aW9uIGNvbXB1dGVPcmRlcihlbGVtZW50KSB7XG4gICAgaWYgKGVsZW1lbnQubGFiZWxUYXJnZXQpIHtcbiAgICAgIHJldHVybiB7IGxldmVsOiAxMCB9O1xuICAgIH1cblxuICAgIHZhciBlbnRyeSA9IGZpbmQob3JkZXJzLCBmdW5jdGlvbihvKSB7XG4gICAgICByZXR1cm4gaXNBbnkoZWxlbWVudCwgWyBvLnR5cGUgXSk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZW50cnkgJiYgZW50cnkub3JkZXIgfHwgeyBsZXZlbDogMSB9O1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0T3JkZXIoZWxlbWVudCkge1xuXG4gICAgdmFyIG9yZGVyID0gZWxlbWVudC5vcmRlcjtcblxuICAgIGlmICghb3JkZXIpIHtcbiAgICAgIGVsZW1lbnQub3JkZXIgPSBvcmRlciA9IGNvbXB1dGVPcmRlcihlbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3JkZXI7XG4gIH1cblxuICBmdW5jdGlvbiBmaW5kQWN0dWFsUGFyZW50KGVsZW1lbnQsIG5ld1BhcmVudCwgY29udGFpbmVycykge1xuXG4gICAgdmFyIGFjdHVhbFBhcmVudCA9IG5ld1BhcmVudDtcblxuICAgIHdoaWxlIChhY3R1YWxQYXJlbnQpIHtcblxuICAgICAgaWYgKGlzQW55KGFjdHVhbFBhcmVudCwgY29udGFpbmVycykpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGFjdHVhbFBhcmVudCA9IGFjdHVhbFBhcmVudC5wYXJlbnQ7XG4gICAgfVxuXG4gICAgaWYgKCFhY3R1YWxQYXJlbnQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0cmFuc2xhdGUoJ25vIHBhcmVudCBmb3Ige2VsZW1lbnR9IGluIHtwYXJlbnR9Jywge1xuICAgICAgICBlbGVtZW50OiBlbGVtZW50LmlkLFxuICAgICAgICBwYXJlbnQ6IG5ld1BhcmVudC5pZFxuICAgICAgfSkpO1xuICAgIH1cblxuICAgIHJldHVybiBhY3R1YWxQYXJlbnQ7XG4gIH1cblxuICB0aGlzLmdldE9yZGVyaW5nID0gZnVuY3Rpb24oZWxlbWVudCwgbmV3UGFyZW50KSB7XG5cbiAgICAvLyByZW5kZXIgbGFiZWxzIGFsd2F5cyBvbiB0b3BcbiAgICBpZiAoZWxlbWVudC5sYWJlbFRhcmdldCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGFyZW50OiBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSxcbiAgICAgICAgaW5kZXg6IC0xXG4gICAgICB9O1xuICAgIH1cblxuICAgIHZhciBlbGVtZW50T3JkZXIgPSBnZXRPcmRlcihlbGVtZW50KTtcblxuXG4gICAgaWYgKGVsZW1lbnRPcmRlci5jb250YWluZXJzKSB7XG4gICAgICBuZXdQYXJlbnQgPSBmaW5kQWN0dWFsUGFyZW50KGVsZW1lbnQsIG5ld1BhcmVudCwgZWxlbWVudE9yZGVyLmNvbnRhaW5lcnMpO1xuICAgIH1cblxuXG4gICAgdmFyIGN1cnJlbnRJbmRleCA9IG5ld1BhcmVudC5jaGlsZHJlbi5pbmRleE9mKGVsZW1lbnQpO1xuXG4gICAgdmFyIGluc2VydEluZGV4ID0gZmluZEluZGV4KG5ld1BhcmVudC5jaGlsZHJlbiwgZnVuY3Rpb24oY2hpbGQpIHtcblxuICAgICAgLy8gZG8gbm90IGNvbXBhcmUgd2l0aCBsYWJlbHMsIHRoZXkgYXJlIGNyZWF0ZWRcbiAgICAgIC8vIGluIHRoZSB3cm9uZyBvcmRlciAocmlnaHQgYWZ0ZXIgZWxlbWVudHMpIGR1cmluZyBpbXBvcnQgYW5kXG4gICAgICAvLyBtZXNzIHVwIHRoZSBwb3NpdGlvbmluZy5cbiAgICAgIGlmICghZWxlbWVudC5sYWJlbFRhcmdldCAmJiBjaGlsZC5sYWJlbFRhcmdldCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlbGVtZW50T3JkZXIubGV2ZWwgPCBnZXRPcmRlcihjaGlsZCkubGV2ZWw7XG4gICAgfSk7XG5cblxuICAgIC8vIGlmIHRoZSBlbGVtZW50IGlzIGFscmVhZHkgaW4gdGhlIGNoaWxkIGxpc3QgYXRcbiAgICAvLyBhIHNtYWxsZXIgaW5kZXgsIHdlIG5lZWQgdG8gYWRqdXN0IHRoZSBpbnNlcnQgaW5kZXguXG4gICAgLy8gdGhpcyB0YWtlcyBpbnRvIGFjY291bnQgdGhhdCB0aGUgZWxlbWVudCBpcyBiZWluZyByZW1vdmVkXG4gICAgLy8gYmVmb3JlIGJlaW5nIHJlLWluc2VydGVkXG4gICAgaWYgKGluc2VydEluZGV4ICE9PSAtMSkge1xuICAgICAgaWYgKGN1cnJlbnRJbmRleCAhPT0gLTEgJiYgY3VycmVudEluZGV4IDwgaW5zZXJ0SW5kZXgpIHtcbiAgICAgICAgaW5zZXJ0SW5kZXggLT0gMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW5kZXg6IGluc2VydEluZGV4LFxuICAgICAgcGFyZW50OiBuZXdQYXJlbnRcbiAgICB9O1xuICB9O1xufVxuXG5CcG1uT3JkZXJpbmdQcm92aWRlci4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnLCAnY2FudmFzJywgJ3RyYW5zbGF0ZScgXTtcblxuaW5oZXJpdHMoQnBtbk9yZGVyaW5nUHJvdmlkZXIsIE9yZGVyaW5nUHJvdmlkZXIpOyIsImltcG9ydCB0cmFuc2xhdGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnO1xuXG5pbXBvcnQgQnBtbk9yZGVyaW5nUHJvdmlkZXIgZnJvbSAnLi9CcG1uT3JkZXJpbmdQcm92aWRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICB0cmFuc2xhdGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2JwbW5PcmRlcmluZ1Byb3ZpZGVyJyBdLFxuICBicG1uT3JkZXJpbmdQcm92aWRlcjogWyAndHlwZScsIEJwbW5PcmRlcmluZ1Byb3ZpZGVyIF1cbn07IiwiaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEEgcGFsZXR0ZSBwcm92aWRlciBmb3IgQlBNTiAyLjAgZWxlbWVudHMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFBhbGV0dGVQcm92aWRlcihcbiAgICBwYWxldHRlLCBjcmVhdGUsIGVsZW1lbnRGYWN0b3J5LFxuICAgIHNwYWNlVG9vbCwgbGFzc29Ub29sLCBoYW5kVG9vbCxcbiAgICBnbG9iYWxDb25uZWN0LCB0cmFuc2xhdGUpIHtcblxuICB0aGlzLl9wYWxldHRlID0gcGFsZXR0ZTtcbiAgdGhpcy5fY3JlYXRlID0gY3JlYXRlO1xuICB0aGlzLl9lbGVtZW50RmFjdG9yeSA9IGVsZW1lbnRGYWN0b3J5O1xuICB0aGlzLl9zcGFjZVRvb2wgPSBzcGFjZVRvb2w7XG4gIHRoaXMuX2xhc3NvVG9vbCA9IGxhc3NvVG9vbDtcbiAgdGhpcy5faGFuZFRvb2wgPSBoYW5kVG9vbDtcbiAgdGhpcy5fZ2xvYmFsQ29ubmVjdCA9IGdsb2JhbENvbm5lY3Q7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcblxuICBwYWxldHRlLnJlZ2lzdGVyUHJvdmlkZXIodGhpcyk7XG59XG5cblBhbGV0dGVQcm92aWRlci4kaW5qZWN0ID0gW1xuICAncGFsZXR0ZScsXG4gICdjcmVhdGUnLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnc3BhY2VUb29sJyxcbiAgJ2xhc3NvVG9vbCcsXG4gICdoYW5kVG9vbCcsXG4gICdnbG9iYWxDb25uZWN0JyxcbiAgJ3RyYW5zbGF0ZSdcbl07XG5cblxuUGFsZXR0ZVByb3ZpZGVyLnByb3RvdHlwZS5nZXRQYWxldHRlRW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICB2YXIgYWN0aW9ucyA9IHt9LFxuICAgICAgY3JlYXRlID0gdGhpcy5fY3JlYXRlLFxuICAgICAgZWxlbWVudEZhY3RvcnkgPSB0aGlzLl9lbGVtZW50RmFjdG9yeSxcbiAgICAgIHNwYWNlVG9vbCA9IHRoaXMuX3NwYWNlVG9vbCxcbiAgICAgIGxhc3NvVG9vbCA9IHRoaXMuX2xhc3NvVG9vbCxcbiAgICAgIGhhbmRUb29sID0gdGhpcy5faGFuZFRvb2wsXG4gICAgICBnbG9iYWxDb25uZWN0ID0gdGhpcy5fZ2xvYmFsQ29ubmVjdCxcbiAgICAgIHRyYW5zbGF0ZSA9IHRoaXMuX3RyYW5zbGF0ZTtcblxuICBmdW5jdGlvbiBjcmVhdGVBY3Rpb24odHlwZSwgZ3JvdXAsIGNsYXNzTmFtZSwgdGl0bGUsIG9wdGlvbnMpIHtcblxuICAgIGZ1bmN0aW9uIGNyZWF0ZUxpc3RlbmVyKGV2ZW50KSB7XG4gICAgICB2YXIgc2hhcGUgPSBlbGVtZW50RmFjdG9yeS5jcmVhdGVTaGFwZShhc3NpZ24oeyB0eXBlOiB0eXBlIH0sIG9wdGlvbnMpKTtcblxuICAgICAgaWYgKG9wdGlvbnMpIHtcbiAgICAgICAgc2hhcGUuYnVzaW5lc3NPYmplY3QuZGkuaXNFeHBhbmRlZCA9IG9wdGlvbnMuaXNFeHBhbmRlZDtcbiAgICAgIH1cblxuICAgICAgY3JlYXRlLnN0YXJ0KGV2ZW50LCBzaGFwZSk7XG4gICAgfVxuXG4gICAgdmFyIHNob3J0VHlwZSA9IHR5cGUucmVwbGFjZSgvXmJwbW46LywgJycpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGdyb3VwOiBncm91cCxcbiAgICAgIGNsYXNzTmFtZTogY2xhc3NOYW1lLFxuICAgICAgdGl0bGU6IHRpdGxlIHx8IHRyYW5zbGF0ZSgnQ3JlYXRlIHt0eXBlfScsIHsgdHlwZTogc2hvcnRUeXBlIH0pLFxuICAgICAgYWN0aW9uOiB7XG4gICAgICAgIGRyYWdzdGFydDogY3JlYXRlTGlzdGVuZXIsXG4gICAgICAgIGNsaWNrOiBjcmVhdGVMaXN0ZW5lclxuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVTdWJwcm9jZXNzKGV2ZW50KSB7XG4gICAgdmFyIHN1YlByb2Nlc3MgPSBlbGVtZW50RmFjdG9yeS5jcmVhdGVTaGFwZSh7XG4gICAgICB0eXBlOiAnYnBtbjpTdWJQcm9jZXNzJyxcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwLFxuICAgICAgaXNFeHBhbmRlZDogdHJ1ZVxuICAgIH0pO1xuXG4gICAgdmFyIHN0YXJ0RXZlbnQgPSBlbGVtZW50RmFjdG9yeS5jcmVhdGVTaGFwZSh7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIHg6IDQwLFxuICAgICAgeTogODIsXG4gICAgICBwYXJlbnQ6IHN1YlByb2Nlc3NcbiAgICB9KTtcblxuICAgIGNyZWF0ZS5zdGFydChldmVudCwgWyBzdWJQcm9jZXNzLCBzdGFydEV2ZW50IF0sIHtcbiAgICAgIGhpbnRzOiB7XG4gICAgICAgIGF1dG9TZWxlY3Q6IFsgc3RhcnRFdmVudCBdXG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVQYXJ0aWNpcGFudChldmVudCkge1xuICAgIGNyZWF0ZS5zdGFydChldmVudCwgZWxlbWVudEZhY3RvcnkuY3JlYXRlUGFydGljaXBhbnRTaGFwZSgpKTtcbiAgfVxuXG4gIGFzc2lnbihhY3Rpb25zLCB7XG4gICAgJ2hhbmQtdG9vbCc6IHtcbiAgICAgIGdyb3VwOiAndG9vbHMnLFxuICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWhhbmQtdG9vbCcsXG4gICAgICB0aXRsZTogdHJhbnNsYXRlKCdBY3RpdmF0ZSB0aGUgaGFuZCB0b29sJyksXG4gICAgICBhY3Rpb246IHtcbiAgICAgICAgY2xpY2s6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgaGFuZFRvb2wuYWN0aXZhdGVIYW5kKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgJ2xhc3NvLXRvb2wnOiB7XG4gICAgICBncm91cDogJ3Rvb2xzJyxcbiAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sYXNzby10b29sJyxcbiAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FjdGl2YXRlIHRoZSBsYXNzbyB0b29sJyksXG4gICAgICBhY3Rpb246IHtcbiAgICAgICAgY2xpY2s6IGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgICAgbGFzc29Ub29sLmFjdGl2YXRlU2VsZWN0aW9uKGV2ZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gICAgJ3NwYWNlLXRvb2wnOiB7XG4gICAgICBncm91cDogJ3Rvb2xzJyxcbiAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zcGFjZS10b29sJyxcbiAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FjdGl2YXRlIHRoZSBjcmVhdGUvcmVtb3ZlIHNwYWNlIHRvb2wnKSxcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICBjbGljazogZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICBzcGFjZVRvb2wuYWN0aXZhdGVTZWxlY3Rpb24oZXZlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgICAnZ2xvYmFsLWNvbm5lY3QtdG9vbCc6IHtcbiAgICAgIGdyb3VwOiAndG9vbHMnLFxuICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWNvbm5lY3Rpb24tbXVsdGknLFxuICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQWN0aXZhdGUgdGhlIGdsb2JhbCBjb25uZWN0IHRvb2wnKSxcbiAgICAgIGFjdGlvbjoge1xuICAgICAgICBjbGljazogZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICBnbG9iYWxDb25uZWN0LnRvZ2dsZShldmVudCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9LFxuICAgICd0b29sLXNlcGFyYXRvcic6IHtcbiAgICAgIGdyb3VwOiAndG9vbHMnLFxuICAgICAgc2VwYXJhdG9yOiB0cnVlXG4gICAgfSxcbiAgICAnY3JlYXRlLnN0YXJ0LWV2ZW50JzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46U3RhcnRFdmVudCcsICdldmVudCcsICdicG1uLWljb24tc3RhcnQtZXZlbnQtbm9uZScsXG4gICAgICB0cmFuc2xhdGUoJ0NyZWF0ZSBTdGFydEV2ZW50JylcbiAgICApLFxuICAgICdjcmVhdGUuaW50ZXJtZWRpYXRlLWV2ZW50JzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcsICdldmVudCcsICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LW5vbmUnLFxuICAgICAgdHJhbnNsYXRlKCdDcmVhdGUgSW50ZXJtZWRpYXRlL0JvdW5kYXJ5IEV2ZW50JylcbiAgICApLFxuICAgICdjcmVhdGUuZW5kLWV2ZW50JzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46RW5kRXZlbnQnLCAnZXZlbnQnLCAnYnBtbi1pY29uLWVuZC1ldmVudC1ub25lJyxcbiAgICAgIHRyYW5zbGF0ZSgnQ3JlYXRlIEVuZEV2ZW50JylcbiAgICApLFxuICAgICdjcmVhdGUuZXhjbHVzaXZlLWdhdGV3YXknOiBjcmVhdGVBY3Rpb24oXG4gICAgICAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JywgJ2dhdGV3YXknLCAnYnBtbi1pY29uLWdhdGV3YXktbm9uZScsXG4gICAgICB0cmFuc2xhdGUoJ0NyZWF0ZSBHYXRld2F5JylcbiAgICApLFxuICAgICdjcmVhdGUudGFzayc6IGNyZWF0ZUFjdGlvbihcbiAgICAgICdicG1uOlRhc2snLCAnYWN0aXZpdHknLCAnYnBtbi1pY29uLXRhc2snLFxuICAgICAgdHJhbnNsYXRlKCdDcmVhdGUgVGFzaycpXG4gICAgKSxcbiAgICAnY3JlYXRlLmRhdGEtb2JqZWN0JzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46RGF0YU9iamVjdFJlZmVyZW5jZScsICdkYXRhLW9iamVjdCcsICdicG1uLWljb24tZGF0YS1vYmplY3QnLFxuICAgICAgdHJhbnNsYXRlKCdDcmVhdGUgRGF0YU9iamVjdFJlZmVyZW5jZScpXG4gICAgKSxcbiAgICAnY3JlYXRlLmRhdGEtc3RvcmUnOiBjcmVhdGVBY3Rpb24oXG4gICAgICAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnLCAnZGF0YS1zdG9yZScsICdicG1uLWljb24tZGF0YS1zdG9yZScsXG4gICAgICB0cmFuc2xhdGUoJ0NyZWF0ZSBEYXRhU3RvcmVSZWZlcmVuY2UnKVxuICAgICksXG4gICAgJ2NyZWF0ZS5zdWJwcm9jZXNzLWV4cGFuZGVkJzoge1xuICAgICAgZ3JvdXA6ICdhY3Rpdml0eScsXG4gICAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3VicHJvY2Vzcy1leHBhbmRlZCcsXG4gICAgICB0aXRsZTogdHJhbnNsYXRlKCdDcmVhdGUgZXhwYW5kZWQgU3ViUHJvY2VzcycpLFxuICAgICAgYWN0aW9uOiB7XG4gICAgICAgIGRyYWdzdGFydDogY3JlYXRlU3VicHJvY2VzcyxcbiAgICAgICAgY2xpY2s6IGNyZWF0ZVN1YnByb2Nlc3NcbiAgICAgIH1cbiAgICB9LFxuICAgICdjcmVhdGUucGFydGljaXBhbnQtZXhwYW5kZWQnOiB7XG4gICAgICBncm91cDogJ2NvbGxhYm9yYXRpb24nLFxuICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXBhcnRpY2lwYW50JyxcbiAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0NyZWF0ZSBQb29sL1BhcnRpY2lwYW50JyksXG4gICAgICBhY3Rpb246IHtcbiAgICAgICAgZHJhZ3N0YXJ0OiBjcmVhdGVQYXJ0aWNpcGFudCxcbiAgICAgICAgY2xpY2s6IGNyZWF0ZVBhcnRpY2lwYW50XG4gICAgICB9XG4gICAgfSxcbiAgICAnY3JlYXRlLmdyb3VwJzogY3JlYXRlQWN0aW9uKFxuICAgICAgJ2JwbW46R3JvdXAnLCAnYXJ0aWZhY3QnLCAnYnBtbi1pY29uLWdyb3VwJyxcbiAgICAgIHRyYW5zbGF0ZSgnQ3JlYXRlIEdyb3VwJylcbiAgICApLFxuICB9KTtcblxuICByZXR1cm4gYWN0aW9ucztcbn07XG4iLCJpbXBvcnQgUGFsZXR0ZU1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wYWxldHRlJztcbmltcG9ydCBDcmVhdGVNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvY3JlYXRlJztcbmltcG9ydCBTcGFjZVRvb2xNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc3BhY2UtdG9vbCc7XG5pbXBvcnQgTGFzc29Ub29sTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2xhc3NvLXRvb2wnO1xuaW1wb3J0IEhhbmRUb29sTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2hhbmQtdG9vbCc7XG5pbXBvcnQgR2xvYmFsQ29ubmVjdE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9nbG9iYWwtY29ubmVjdCc7XG5pbXBvcnQgdHJhbnNsYXRlIGZyb20gJ2RpYWdyYW0tanMvbGliL2kxOG4vdHJhbnNsYXRlJztcblxuaW1wb3J0IFBhbGV0dGVQcm92aWRlciBmcm9tICcuL1BhbGV0dGVQcm92aWRlcic7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBQYWxldHRlTW9kdWxlLFxuICAgIENyZWF0ZU1vZHVsZSxcbiAgICBTcGFjZVRvb2xNb2R1bGUsXG4gICAgTGFzc29Ub29sTW9kdWxlLFxuICAgIEhhbmRUb29sTW9kdWxlLFxuICAgIEdsb2JhbENvbm5lY3RNb2R1bGUsXG4gICAgdHJhbnNsYXRlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdwYWxldHRlUHJvdmlkZXInIF0sXG4gIHBhbGV0dGVQcm92aWRlcjogWyAndHlwZScsIFBhbGV0dGVQcm92aWRlciBdXG59O1xuIiwiaW1wb3J0IHtcbiAgZ2V0QnVzaW5lc3NPYmplY3QsXG4gIGlzXG59IGZyb20gJy4uLy4uL3V0aWwvTW9kZWxVdGlsJztcblxuaW1wb3J0IHtcbiAgaXNFdmVudFN1YlByb2Nlc3MsXG4gIGlzRXhwYW5kZWRcbn0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0RpZmZlcmVudFR5cGVcbn0gZnJvbSAnLi91dGlsL1R5cGVVdGlsJztcblxuaW1wb3J0IHtcbiAgZm9yRWFjaCxcbiAgZmlsdGVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0ICogYXMgcmVwbGFjZU9wdGlvbnMgZnJvbSAnLi4vcmVwbGFjZS9SZXBsYWNlT3B0aW9ucyc7XG5cblxuLyoqXG4gKiBUaGlzIG1vZHVsZSBpcyBhbiBlbGVtZW50IGFnbm9zdGljIHJlcGxhY2UgbWVudSBwcm92aWRlciBmb3IgdGhlIHBvcHVwIG1lbnUuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlcGxhY2VNZW51UHJvdmlkZXIoXG4gICAgcG9wdXBNZW51LCBtb2RlbGluZywgbW9kZGxlLFxuICAgIGJwbW5SZXBsYWNlLCBydWxlcywgdHJhbnNsYXRlKSB7XG5cbiAgdGhpcy5fcG9wdXBNZW51ID0gcG9wdXBNZW51O1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xuICB0aGlzLl9tb2RkbGUgPSBtb2RkbGU7XG4gIHRoaXMuX2JwbW5SZXBsYWNlID0gYnBtblJlcGxhY2U7XG4gIHRoaXMuX3J1bGVzID0gcnVsZXM7XG4gIHRoaXMuX3RyYW5zbGF0ZSA9IHRyYW5zbGF0ZTtcblxuICB0aGlzLnJlZ2lzdGVyKCk7XG59XG5cblJlcGxhY2VNZW51UHJvdmlkZXIuJGluamVjdCA9IFtcbiAgJ3BvcHVwTWVudScsXG4gICdtb2RlbGluZycsXG4gICdtb2RkbGUnLFxuICAnYnBtblJlcGxhY2UnLFxuICAncnVsZXMnLFxuICAndHJhbnNsYXRlJ1xuXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVyIHJlcGxhY2UgbWVudSBwcm92aWRlciBpbiB0aGUgcG9wdXAgbWVudVxuICovXG5SZXBsYWNlTWVudVByb3ZpZGVyLnByb3RvdHlwZS5yZWdpc3RlciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9wb3B1cE1lbnUucmVnaXN0ZXJQcm92aWRlcignYnBtbi1yZXBsYWNlJywgdGhpcyk7XG59O1xuXG5cbi8qKlxuICogR2V0IGFsbCBlbnRyaWVzIGZyb20gcmVwbGFjZU9wdGlvbnMgZm9yIHRoZSBnaXZlbiBlbGVtZW50IGFuZCBhcHBseSBmaWx0ZXJzXG4gKiBvbiB0aGVtLiBHZXQgZm9yIGV4YW1wbGUgb25seSBlbGVtZW50cywgd2hpY2ggYXJlIGRpZmZlcmVudCBmcm9tIHRoZSBjdXJyZW50IG9uZS5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn0gYSBsaXN0IG9mIG1lbnUgZW50cnkgaXRlbXNcbiAqL1xuUmVwbGFjZU1lbnVQcm92aWRlci5wcm90b3R5cGUuZ2V0RW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0O1xuXG4gIHZhciBydWxlcyA9IHRoaXMuX3J1bGVzO1xuXG4gIHZhciBlbnRyaWVzO1xuXG4gIGlmICghcnVsZXMuYWxsb3dlZCgnc2hhcGUucmVwbGFjZScsIHsgZWxlbWVudDogZWxlbWVudCB9KSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHZhciBkaWZmZXJlbnRUeXBlID0gaXNEaWZmZXJlbnRUeXBlKGVsZW1lbnQpO1xuXG4gIC8vIHN0YXJ0IGV2ZW50cyBvdXRzaWRlIHN1YiBwcm9jZXNzZXNcbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpTdGFydEV2ZW50JykgJiYgIWlzKGJ1c2luZXNzT2JqZWN0LiRwYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5TVEFSVF9FVkVOVCwgZGlmZmVyZW50VHlwZSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIGV4cGFuZGVkL2NvbGxhcHNlZCBwb29sc1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOlBhcnRpY2lwYW50JykpIHtcblxuICAgIGVudHJpZXMgPSBmaWx0ZXIocmVwbGFjZU9wdGlvbnMuUEFSVElDSVBBTlQsIGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgICByZXR1cm4gaXNFeHBhbmRlZChidXNpbmVzc09iamVjdCkgIT09IGVudHJ5LnRhcmdldC5pc0V4cGFuZGVkO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVudHJpZXMoZWxlbWVudCwgZW50cmllcyk7XG4gIH1cblxuICAvLyBzdGFydCBldmVudHMgaW5zaWRlIGV2ZW50IHN1YiBwcm9jZXNzZXNcbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpTdGFydEV2ZW50JykgJiYgaXNFdmVudFN1YlByb2Nlc3MoYnVzaW5lc3NPYmplY3QuJHBhcmVudCkpIHtcbiAgICBlbnRyaWVzID0gZmlsdGVyKHJlcGxhY2VPcHRpb25zLkVWRU5UX1NVQl9QUk9DRVNTX1NUQVJUX0VWRU5ULCBmdW5jdGlvbihlbnRyeSkge1xuXG4gICAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgICB2YXIgaXNJbnRlcnJ1cHRpbmcgPSB0YXJnZXQuaXNJbnRlcnJ1cHRpbmcgIT09IGZhbHNlO1xuXG4gICAgICB2YXIgaXNJbnRlcnJ1cHRpbmdFcXVhbCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLmlzSW50ZXJydXB0aW5nID09PSBpc0ludGVycnVwdGluZztcblxuICAgICAgLy8gZmlsdGVycyBlbGVtZW50cyB3aGljaCB0eXBlcyBhbmQgZXZlbnQgZGVmaW5pdGlvbiBhcmUgZXF1YWwgYnV0IGhhdmUgaGF2ZSBkaWZmZXJlbnQgaW50ZXJydXB0aW5nIHR5cGVzXG4gICAgICByZXR1cm4gZGlmZmVyZW50VHlwZShlbnRyeSkgfHwgIWRpZmZlcmVudFR5cGUoZW50cnkpICYmICFpc0ludGVycnVwdGluZ0VxdWFsO1xuXG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIHN0YXJ0IGV2ZW50cyBpbnNpZGUgc3ViIHByb2Nlc3Nlc1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOlN0YXJ0RXZlbnQnKSAmJiAhaXNFdmVudFN1YlByb2Nlc3MoYnVzaW5lc3NPYmplY3QuJHBhcmVudClcbiAgICAgICYmIGlzKGJ1c2luZXNzT2JqZWN0LiRwYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuICAgIGVudHJpZXMgPSBmaWx0ZXIocmVwbGFjZU9wdGlvbnMuU1RBUlRfRVZFTlRfU1VCX1BST0NFU1MsIGRpZmZlcmVudFR5cGUpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVudHJpZXMoZWxlbWVudCwgZW50cmllcyk7XG4gIH1cblxuICAvLyBlbmQgZXZlbnRzXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46RW5kRXZlbnQnKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5FTkRfRVZFTlQsIGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgICAvLyBoaWRlIGNhbmNlbCBlbmQgZXZlbnRzIG91dHNpZGUgdHJhbnNhY3Rpb25zXG4gICAgICBpZiAodGFyZ2V0LmV2ZW50RGVmaW5pdGlvblR5cGUgPT0gJ2JwbW46Q2FuY2VsRXZlbnREZWZpbml0aW9uJyAmJiAhaXMoYnVzaW5lc3NPYmplY3QuJHBhcmVudCwgJ2JwbW46VHJhbnNhY3Rpb24nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBkaWZmZXJlbnRUeXBlKGVudHJ5KTtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbnRyaWVzKGVsZW1lbnQsIGVudHJpZXMpO1xuICB9XG5cbiAgLy8gYm91bmRhcnkgZXZlbnRzXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpKSB7XG5cbiAgICBlbnRyaWVzID0gZmlsdGVyKHJlcGxhY2VPcHRpb25zLkJPVU5EQVJZX0VWRU5ULCBmdW5jdGlvbihlbnRyeSkge1xuXG4gICAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgICBpZiAodGFyZ2V0LmV2ZW50RGVmaW5pdGlvbiA9PSAnYnBtbjpDYW5jZWxFdmVudERlZmluaXRpb24nICYmXG4gICAgICAgICAhaXMoYnVzaW5lc3NPYmplY3QuYXR0YWNoZWRUb1JlZiwgJ2JwbW46VHJhbnNhY3Rpb24nKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICB2YXIgY2FuY2VsQWN0aXZpdHkgPSB0YXJnZXQuY2FuY2VsQWN0aXZpdHkgIT09IGZhbHNlO1xuXG4gICAgICB2YXIgaXNDYW5jZWxBY3Rpdml0eUVxdWFsID0gYnVzaW5lc3NPYmplY3QuY2FuY2VsQWN0aXZpdHkgPT0gY2FuY2VsQWN0aXZpdHk7XG5cbiAgICAgIHJldHVybiBkaWZmZXJlbnRUeXBlKGVudHJ5KSB8fCAhZGlmZmVyZW50VHlwZShlbnRyeSkgJiYgIWlzQ2FuY2VsQWN0aXZpdHlFcXVhbDtcbiAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbnRyaWVzKGVsZW1lbnQsIGVudHJpZXMpO1xuICB9XG5cbiAgLy8gaW50ZXJtZWRpYXRlIGV2ZW50c1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnKSB8fFxuICAgICAgaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5JTlRFUk1FRElBVEVfRVZFTlQsIGRpZmZlcmVudFR5cGUpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVudHJpZXMoZWxlbWVudCwgZW50cmllcyk7XG4gIH1cblxuICAvLyBnYXRld2F5c1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkdhdGV3YXknKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5HQVRFV0FZLCBkaWZmZXJlbnRUeXBlKTtcblxuICAgIHJldHVybiB0aGlzLl9jcmVhdGVFbnRyaWVzKGVsZW1lbnQsIGVudHJpZXMpO1xuICB9XG5cbiAgLy8gdHJhbnNhY3Rpb25zXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46VHJhbnNhY3Rpb24nKSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5UUkFOU0FDVElPTiwgZGlmZmVyZW50VHlwZSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIGV4cGFuZGVkIGV2ZW50IHN1YiBwcm9jZXNzZXNcbiAgaWYgKGlzRXZlbnRTdWJQcm9jZXNzKGJ1c2luZXNzT2JqZWN0KSAmJiBpc0V4cGFuZGVkKGJ1c2luZXNzT2JqZWN0KSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5FVkVOVF9TVUJfUFJPQ0VTUywgZGlmZmVyZW50VHlwZSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIGV4cGFuZGVkIHN1YiBwcm9jZXNzZXNcbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpTdWJQcm9jZXNzJykgJiYgaXNFeHBhbmRlZChidXNpbmVzc09iamVjdCkpIHtcblxuICAgIGVudHJpZXMgPSBmaWx0ZXIocmVwbGFjZU9wdGlvbnMuU1VCUFJPQ0VTU19FWFBBTkRFRCwgZGlmZmVyZW50VHlwZSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIGNvbGxhcHNlZCBhZCBob2Mgc3ViIHByb2Nlc3Nlc1xuICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOkFkSG9jU3ViUHJvY2VzcycpICYmICFpc0V4cGFuZGVkKGJ1c2luZXNzT2JqZWN0KSkge1xuXG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5UQVNLLCBmdW5jdGlvbihlbnRyeSkge1xuXG4gICAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgICB2YXIgaXNUYXJnZXRTdWJQcm9jZXNzID0gdGFyZ2V0LnR5cGUgPT09ICdicG1uOlN1YlByb2Nlc3MnO1xuXG4gICAgICB2YXIgaXNUYXJnZXRFeHBhbmRlZCA9IHRhcmdldC5pc0V4cGFuZGVkID09PSB0cnVlO1xuXG4gICAgICByZXR1cm4gaXNEaWZmZXJlbnRUeXBlKGVsZW1lbnQsIHRhcmdldCkgJiYgKCFpc1RhcmdldFN1YlByb2Nlc3MgfHwgaXNUYXJnZXRFeHBhbmRlZCk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlRW50cmllcyhlbGVtZW50LCBlbnRyaWVzKTtcbiAgfVxuXG4gIC8vIHNlcXVlbmNlIGZsb3dzXG4gIGlmIChpcyhidXNpbmVzc09iamVjdCwgJ2JwbW46U2VxdWVuY2VGbG93JykpIHtcbiAgICByZXR1cm4gdGhpcy5fY3JlYXRlU2VxdWVuY2VGbG93RW50cmllcyhlbGVtZW50LCByZXBsYWNlT3B0aW9ucy5TRVFVRU5DRV9GTE9XKTtcbiAgfVxuXG4gIC8vIGZsb3cgbm9kZXNcbiAgaWYgKGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpGbG93Tm9kZScpKSB7XG4gICAgZW50cmllcyA9IGZpbHRlcihyZXBsYWNlT3B0aW9ucy5UQVNLLCBkaWZmZXJlbnRUeXBlKTtcblxuICAgIC8vIGNvbGxhcHNlZCBTdWJQcm9jZXNzIGNhbiBub3QgYmUgcmVwbGFjZWQgd2l0aCBpdHNlbGZcbiAgICBpZiAoaXMoYnVzaW5lc3NPYmplY3QsICdicG1uOlN1YlByb2Nlc3MnKSAmJiAhaXNFeHBhbmRlZChidXNpbmVzc09iamVjdCkpIHtcbiAgICAgIGVudHJpZXMgPSBmaWx0ZXIoZW50cmllcywgZnVuY3Rpb24oZW50cnkpIHtcbiAgICAgICAgcmV0dXJuIGVudHJ5LmxhYmVsICE9PSAnU3ViIFByb2Nlc3MgKGNvbGxhcHNlZCknO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2NyZWF0ZUVudHJpZXMoZWxlbWVudCwgZW50cmllcyk7XG4gIH1cblxuICByZXR1cm4gW107XG59O1xuXG5cbi8qKlxuICogR2V0IGEgbGlzdCBvZiBoZWFkZXIgaXRlbXMgZm9yIHRoZSBnaXZlbiBlbGVtZW50LiBUaGlzIGluY2x1ZGVzIGJ1dHRvbnNcbiAqIGZvciBtdWx0aSBpbnN0YW5jZSBtYXJrZXJzIGFuZCBmb3IgdGhlIGFkIGhvYyBtYXJrZXIuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge0FycmF5PE9iamVjdD59IGEgbGlzdCBvZiBtZW51IGVudHJ5IGl0ZW1zXG4gKi9cblJlcGxhY2VNZW51UHJvdmlkZXIucHJvdG90eXBlLmdldEhlYWRlckVudHJpZXMgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgdmFyIGhlYWRlckVudHJpZXMgPSBbXTtcblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46QWN0aXZpdHknKSAmJiAhaXNFdmVudFN1YlByb2Nlc3MoZWxlbWVudCkpIHtcbiAgICBoZWFkZXJFbnRyaWVzID0gaGVhZGVyRW50cmllcy5jb25jYXQodGhpcy5fZ2V0TG9vcEVudHJpZXMoZWxlbWVudCkpO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJlxuICAgICAgIWlzKGVsZW1lbnQsICdicG1uOlRyYW5zYWN0aW9uJykgJiZcbiAgICAgICFpc0V2ZW50U3ViUHJvY2VzcyhlbGVtZW50KSkge1xuICAgIGhlYWRlckVudHJpZXMucHVzaCh0aGlzLl9nZXRBZEhvY0VudHJ5KGVsZW1lbnQpKTtcbiAgfVxuXG4gIHJldHVybiBoZWFkZXJFbnRyaWVzO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgbWVudSBlbnRyeSBvYmplY3RzIGZvciBhIGdpdmVuIGVsZW1lbnQgYW5kIGZpbHRlcnMgdGhlIHJlcGxhY2VPcHRpb25zXG4gKiBhY2NvcmRpbmcgdG8gYSBmaWx0ZXIgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSAge09iamVjdH0gcmVwbGFjZU9wdGlvbnNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxPYmplY3Q+fSBhIGxpc3Qgb2YgbWVudSBpdGVtc1xuICovXG5SZXBsYWNlTWVudVByb3ZpZGVyLnByb3RvdHlwZS5fY3JlYXRlRW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHJlcGxhY2VPcHRpb25zKSB7XG4gIHZhciBtZW51RW50cmllcyA9IFtdO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmb3JFYWNoKHJlcGxhY2VPcHRpb25zLCBmdW5jdGlvbihkZWZpbml0aW9uKSB7XG4gICAgdmFyIGVudHJ5ID0gc2VsZi5fY3JlYXRlTWVudUVudHJ5KGRlZmluaXRpb24sIGVsZW1lbnQpO1xuXG4gICAgbWVudUVudHJpZXMucHVzaChlbnRyeSk7XG4gIH0pO1xuXG4gIHJldHVybiBtZW51RW50cmllcztcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiBtZW51IGVudHJ5IG9iamVjdHMgZm9yIGEgZ2l2ZW4gc2VxdWVuY2UgZmxvdy5cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtICB7T2JqZWN0fSByZXBsYWNlT3B0aW9uc1xuXG4gKiBAcmV0dXJuIHtBcnJheTxPYmplY3Q+fSBhIGxpc3Qgb2YgbWVudSBpdGVtc1xuICovXG5SZXBsYWNlTWVudVByb3ZpZGVyLnByb3RvdHlwZS5fY3JlYXRlU2VxdWVuY2VGbG93RW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHJlcGxhY2VPcHRpb25zKSB7XG5cbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XG5cbiAgdmFyIG1lbnVFbnRyaWVzID0gW107XG5cbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmcsXG4gICAgICBtb2RkbGUgPSB0aGlzLl9tb2RkbGU7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGZvckVhY2gocmVwbGFjZU9wdGlvbnMsIGZ1bmN0aW9uKGVudHJ5KSB7XG5cbiAgICBzd2l0Y2ggKGVudHJ5LmFjdGlvbk5hbWUpIHtcbiAgICBjYXNlICdyZXBsYWNlLXdpdGgtZGVmYXVsdC1mbG93JzpcbiAgICAgIGlmIChidXNpbmVzc09iamVjdC5zb3VyY2VSZWYuZGVmYXVsdCAhPT0gYnVzaW5lc3NPYmplY3QgJiZcbiAgICAgICAgICAgIChpcyhidXNpbmVzc09iamVjdC5zb3VyY2VSZWYsICdicG1uOkV4Y2x1c2l2ZUdhdGV3YXknKSB8fFxuICAgICAgICAgICAgIGlzKGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiwgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheScpIHx8XG4gICAgICAgICAgICAgaXMoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmLCAnYnBtbjpDb21wbGV4R2F0ZXdheScpIHx8XG4gICAgICAgICAgICAgaXMoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmLCAnYnBtbjpBY3Rpdml0eScpKSkge1xuXG4gICAgICAgIG1lbnVFbnRyaWVzLnB1c2goc2VsZi5fY3JlYXRlTWVudUVudHJ5KGVudHJ5LCBlbGVtZW50LCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBtb2RlbGluZy51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQuc291cmNlLCB7IGRlZmF1bHQ6IGJ1c2luZXNzT2JqZWN0IH0pO1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdyZXBsYWNlLXdpdGgtY29uZGl0aW9uYWwtZmxvdyc6XG4gICAgICBpZiAoIWJ1c2luZXNzT2JqZWN0LmNvbmRpdGlvbkV4cHJlc3Npb24gJiYgaXMoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmLCAnYnBtbjpBY3Rpdml0eScpKSB7XG5cbiAgICAgICAgbWVudUVudHJpZXMucHVzaChzZWxmLl9jcmVhdGVNZW51RW50cnkoZW50cnksIGVsZW1lbnQsIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHZhciBjb25kaXRpb25FeHByZXNzaW9uID0gbW9kZGxlLmNyZWF0ZSgnYnBtbjpGb3JtYWxFeHByZXNzaW9uJywgeyBib2R5OiAnJyB9KTtcblxuICAgICAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgeyBjb25kaXRpb25FeHByZXNzaW9uOiBjb25kaXRpb25FeHByZXNzaW9uIH0pO1xuICAgICAgICB9KSk7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuXG4gICAgICAvLyBkZWZhdWx0IGZsb3dzXG4gICAgICBpZiAoaXMoYnVzaW5lc3NPYmplY3Quc291cmNlUmVmLCAnYnBtbjpBY3Rpdml0eScpICYmIGJ1c2luZXNzT2JqZWN0LmNvbmRpdGlvbkV4cHJlc3Npb24pIHtcbiAgICAgICAgcmV0dXJuIG1lbnVFbnRyaWVzLnB1c2goc2VsZi5fY3JlYXRlTWVudUVudHJ5KGVudHJ5LCBlbGVtZW50LCBmdW5jdGlvbigpIHtcbiAgICAgICAgICBtb2RlbGluZy51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHsgY29uZGl0aW9uRXhwcmVzc2lvbjogdW5kZWZpbmVkIH0pO1xuICAgICAgICB9KSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGNvbmRpdGlvbmFsIGZsb3dzXG4gICAgICBpZiAoKGlzKGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiwgJ2JwbW46RXhjbHVzaXZlR2F0ZXdheScpIHx8XG4gICAgICAgICAgIGlzKGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiwgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheScpIHx8XG4gICAgICAgICAgIGlzKGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZiwgJ2JwbW46Q29tcGxleEdhdGV3YXknKSB8fFxuICAgICAgICAgICBpcyhidXNpbmVzc09iamVjdC5zb3VyY2VSZWYsICdicG1uOkFjdGl2aXR5JykpICYmXG4gICAgICAgICAgIGJ1c2luZXNzT2JqZWN0LnNvdXJjZVJlZi5kZWZhdWx0ID09PSBidXNpbmVzc09iamVjdCkge1xuXG4gICAgICAgIHJldHVybiBtZW51RW50cmllcy5wdXNoKHNlbGYuX2NyZWF0ZU1lbnVFbnRyeShlbnRyeSwgZWxlbWVudCwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgbW9kZWxpbmcudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LnNvdXJjZSwgeyBkZWZhdWx0OiB1bmRlZmluZWQgfSk7XG4gICAgICAgIH0pKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBtZW51RW50cmllcztcbn07XG5cblxuLyoqXG4gKiBDcmVhdGVzIGFuZCByZXR1cm5zIGEgc2luZ2xlIG1lbnUgZW50cnkgaXRlbS5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGRlZmluaXRpb24gYSBzaW5nbGUgcmVwbGFjZSBvcHRpb25zIGRlZmluaXRpb24gb2JqZWN0XG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtICB7RnVuY3Rpb259IFthY3Rpb25dIGFuIGFjdGlvbiBjYWxsYmFjayBmdW5jdGlvbiB3aGljaCBnZXRzIGNhbGxlZCB3aGVuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG1lbnUgZW50cnkgaXMgYmVpbmcgdHJpZ2dlcmVkLlxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gbWVudSBlbnRyeSBpdGVtXG4gKi9cblJlcGxhY2VNZW51UHJvdmlkZXIucHJvdG90eXBlLl9jcmVhdGVNZW51RW50cnkgPSBmdW5jdGlvbihkZWZpbml0aW9uLCBlbGVtZW50LCBhY3Rpb24pIHtcbiAgdmFyIHRyYW5zbGF0ZSA9IHRoaXMuX3RyYW5zbGF0ZTtcbiAgdmFyIHJlcGxhY2VFbGVtZW50ID0gdGhpcy5fYnBtblJlcGxhY2UucmVwbGFjZUVsZW1lbnQ7XG5cbiAgdmFyIHJlcGxhY2VBY3Rpb24gPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gcmVwbGFjZUVsZW1lbnQoZWxlbWVudCwgZGVmaW5pdGlvbi50YXJnZXQpO1xuICB9O1xuXG4gIGFjdGlvbiA9IGFjdGlvbiB8fCByZXBsYWNlQWN0aW9uO1xuXG4gIHZhciBtZW51RW50cnkgPSB7XG4gICAgbGFiZWw6IHRyYW5zbGF0ZShkZWZpbml0aW9uLmxhYmVsKSxcbiAgICBjbGFzc05hbWU6IGRlZmluaXRpb24uY2xhc3NOYW1lLFxuICAgIGlkOiBkZWZpbml0aW9uLmFjdGlvbk5hbWUsXG4gICAgYWN0aW9uOiBhY3Rpb25cbiAgfTtcblxuICByZXR1cm4gbWVudUVudHJ5O1xufTtcblxuLyoqXG4gKiBHZXQgYSBsaXN0IG9mIG1lbnUgaXRlbXMgY29udGFpbmluZyBidXR0b25zIGZvciBtdWx0aSBpbnN0YW5jZSBtYXJrZXJzXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxPYmplY3Q+fSBhIGxpc3Qgb2YgbWVudSBpdGVtc1xuICovXG5SZXBsYWNlTWVudVByb3ZpZGVyLnByb3RvdHlwZS5fZ2V0TG9vcEVudHJpZXMgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB2YXIgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuXG4gIGZ1bmN0aW9uIHRvZ2dsZUxvb3BFbnRyeShldmVudCwgZW50cnkpIHtcbiAgICB2YXIgbG9vcENoYXJhY3RlcmlzdGljcztcblxuICAgIGlmIChlbnRyeS5hY3RpdmUpIHtcbiAgICAgIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSB1bmRlZmluZWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSBzZWxmLl9tb2RkbGUuY3JlYXRlKGVudHJ5Lm9wdGlvbnMubG9vcENoYXJhY3RlcmlzdGljcyk7XG5cbiAgICAgIGlmIChlbnRyeS5vcHRpb25zLmlzU2VxdWVudGlhbCkge1xuICAgICAgICBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbCA9IGVudHJ5Lm9wdGlvbnMuaXNTZXF1ZW50aWFsO1xuICAgICAgfVxuICAgIH1cbiAgICBzZWxmLl9tb2RlbGluZy51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHsgbG9vcENoYXJhY3RlcmlzdGljczogbG9vcENoYXJhY3RlcmlzdGljcyB9KTtcbiAgfVxuXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxuICAgICAgbG9vcENoYXJhY3RlcmlzdGljcyA9IGJ1c2luZXNzT2JqZWN0Lmxvb3BDaGFyYWN0ZXJpc3RpY3M7XG5cbiAgdmFyIGlzU2VxdWVudGlhbCxcbiAgICAgIGlzTG9vcCxcbiAgICAgIGlzUGFyYWxsZWw7XG5cbiAgaWYgKGxvb3BDaGFyYWN0ZXJpc3RpY3MpIHtcbiAgICBpc1NlcXVlbnRpYWwgPSBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbDtcbiAgICBpc0xvb3AgPSBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbCA9PT0gdW5kZWZpbmVkO1xuICAgIGlzUGFyYWxsZWwgPSBsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbCAhPT0gdW5kZWZpbmVkICYmICFsb29wQ2hhcmFjdGVyaXN0aWNzLmlzU2VxdWVudGlhbDtcbiAgfVxuXG5cbiAgdmFyIGxvb3BFbnRyaWVzID0gW1xuICAgIHtcbiAgICAgIGlkOiAndG9nZ2xlLXBhcmFsbGVsLW1pJyxcbiAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1wYXJhbGxlbC1taS1tYXJrZXInLFxuICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnUGFyYWxsZWwgTXVsdGkgSW5zdGFuY2UnKSxcbiAgICAgIGFjdGl2ZTogaXNQYXJhbGxlbCxcbiAgICAgIGFjdGlvbjogdG9nZ2xlTG9vcEVudHJ5LFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICBsb29wQ2hhcmFjdGVyaXN0aWNzOiAnYnBtbjpNdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljcycsXG4gICAgICAgIGlzU2VxdWVudGlhbDogZmFsc2VcbiAgICAgIH1cbiAgICB9LFxuICAgIHtcbiAgICAgIGlkOiAndG9nZ2xlLXNlcXVlbnRpYWwtbWknLFxuICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXNlcXVlbnRpYWwtbWktbWFya2VyJyxcbiAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ1NlcXVlbnRpYWwgTXVsdGkgSW5zdGFuY2UnKSxcbiAgICAgIGFjdGl2ZTogaXNTZXF1ZW50aWFsLFxuICAgICAgYWN0aW9uOiB0b2dnbGVMb29wRW50cnksXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIGxvb3BDaGFyYWN0ZXJpc3RpY3M6ICdicG1uOk11bHRpSW5zdGFuY2VMb29wQ2hhcmFjdGVyaXN0aWNzJyxcbiAgICAgICAgaXNTZXF1ZW50aWFsOiB0cnVlXG4gICAgICB9XG4gICAgfSxcbiAgICB7XG4gICAgICBpZDogJ3RvZ2dsZS1sb29wJyxcbiAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sb29wLW1hcmtlcicsXG4gICAgICB0aXRsZTogdHJhbnNsYXRlKCdMb29wJyksXG4gICAgICBhY3RpdmU6IGlzTG9vcCxcbiAgICAgIGFjdGlvbjogdG9nZ2xlTG9vcEVudHJ5LFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICBsb29wQ2hhcmFjdGVyaXN0aWNzOiAnYnBtbjpTdGFuZGFyZExvb3BDaGFyYWN0ZXJpc3RpY3MnXG4gICAgICB9XG4gICAgfVxuICBdO1xuICByZXR1cm4gbG9vcEVudHJpZXM7XG59O1xuXG5cbi8qKlxuICogR2V0IHRoZSBtZW51IGl0ZW1zIGNvbnRhaW5pbmcgYSBidXR0b24gZm9yIHRoZSBhZCBob2MgbWFya2VyXG4gKlxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGEgbWVudSBpdGVtXG4gKi9cblJlcGxhY2VNZW51UHJvdmlkZXIucHJvdG90eXBlLl9nZXRBZEhvY0VudHJ5ID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICB2YXIgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlO1xuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcblxuICB2YXIgaXNBZEhvYyA9IGlzKGJ1c2luZXNzT2JqZWN0LCAnYnBtbjpBZEhvY1N1YlByb2Nlc3MnKTtcblxuICB2YXIgcmVwbGFjZUVsZW1lbnQgPSB0aGlzLl9icG1uUmVwbGFjZS5yZXBsYWNlRWxlbWVudDtcblxuICB2YXIgYWRIb2NFbnRyeSA9IHtcbiAgICBpZDogJ3RvZ2dsZS1hZGhvYycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWFkLWhvYy1tYXJrZXInLFxuICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FkLWhvYycpLFxuICAgIGFjdGl2ZTogaXNBZEhvYyxcbiAgICBhY3Rpb246IGZ1bmN0aW9uKGV2ZW50LCBlbnRyeSkge1xuICAgICAgaWYgKGlzQWRIb2MpIHtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VFbGVtZW50KGVsZW1lbnQsIHsgdHlwZTogJ2JwbW46U3ViUHJvY2VzcycgfSwge1xuICAgICAgICAgIGF1dG9SZXNpemU6IGZhbHNlLFxuICAgICAgICAgIGxheW91dENvbm5lY3Rpb246IGZhbHNlXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHJlcGxhY2VFbGVtZW50KGVsZW1lbnQsIHsgdHlwZTogJ2JwbW46QWRIb2NTdWJQcm9jZXNzJyB9LCB7XG4gICAgICAgICAgYXV0b1Jlc2l6ZTogZmFsc2UsXG4gICAgICAgICAgbGF5b3V0Q29ubmVjdGlvbjogZmFsc2VcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBhZEhvY0VudHJ5O1xufTtcbiIsImltcG9ydCBQb3B1cE1lbnVNb2R1bGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvcG9wdXAtbWVudSc7XG5pbXBvcnQgUmVwbGFjZU1vZHVsZSBmcm9tICcuLi9yZXBsYWNlJztcblxuaW1wb3J0IFJlcGxhY2VNZW51UHJvdmlkZXIgZnJvbSAnLi9SZXBsYWNlTWVudVByb3ZpZGVyJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgUG9wdXBNZW51TW9kdWxlLFxuICAgIFJlcGxhY2VNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ3JlcGxhY2VNZW51UHJvdmlkZXInIF0sXG4gIHJlcGxhY2VNZW51UHJvdmlkZXI6IFsgJ3R5cGUnLCBSZXBsYWNlTWVudVByb3ZpZGVyIF1cbn07IiwiaW1wb3J0IHtcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0V4cGFuZGVkXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvRGlVdGlsJztcblxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSwgaWYgYW4gZWxlbWVudCBpcyBmcm9tIGEgZGlmZmVyZW50IHR5cGVcbiAqIHRoYW4gYSB0YXJnZXQgZGVmaW5pdGlvbi4gVGFrZXMgaW50byBhY2NvdW50IHRoZSB0eXBlLFxuICogZXZlbnQgZGVmaW5pdGlvbiB0eXBlIGFuZCB0cmlnZ2VyZWRCeUV2ZW50IHByb3BlcnR5LlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEaWZmZXJlbnRUeXBlKGVsZW1lbnQpIHtcblxuICByZXR1cm4gZnVuY3Rpb24oZW50cnkpIHtcbiAgICB2YXIgdGFyZ2V0ID0gZW50cnkudGFyZ2V0O1xuXG4gICAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksXG4gICAgICAgIGV2ZW50RGVmaW5pdGlvbiA9IGJ1c2luZXNzT2JqZWN0LmV2ZW50RGVmaW5pdGlvbnMgJiYgYnVzaW5lc3NPYmplY3QuZXZlbnREZWZpbml0aW9uc1swXTtcblxuICAgIHZhciBpc1R5cGVFcXVhbCA9IGJ1c2luZXNzT2JqZWN0LiR0eXBlID09PSB0YXJnZXQudHlwZTtcblxuICAgIHZhciBpc0V2ZW50RGVmaW5pdGlvbkVxdWFsID0gKFxuICAgICAgKGV2ZW50RGVmaW5pdGlvbiAmJiBldmVudERlZmluaXRpb24uJHR5cGUpID09PSB0YXJnZXQuZXZlbnREZWZpbml0aW9uVHlwZVxuICAgICk7XG5cbiAgICB2YXIgaXNUcmlnZ2VyZWRCeUV2ZW50RXF1YWwgPSAoXG4gICAgICBidXNpbmVzc09iamVjdC50cmlnZ2VyZWRCeUV2ZW50ID09PSB0YXJnZXQudHJpZ2dlcmVkQnlFdmVudFxuICAgICk7XG5cbiAgICB2YXIgaXNFeHBhbmRlZEVxdWFsID0gKFxuICAgICAgdGFyZ2V0LmlzRXhwYW5kZWQgPT09IHVuZGVmaW5lZCB8fFxuICAgICAgdGFyZ2V0LmlzRXhwYW5kZWQgPT09IGlzRXhwYW5kZWQoYnVzaW5lc3NPYmplY3QpXG4gICAgKTtcblxuICAgIHJldHVybiAhaXNUeXBlRXF1YWwgfHwgIWlzRXZlbnREZWZpbml0aW9uRXF1YWwgfHwgIWlzVHJpZ2dlcmVkQnlFdmVudEVxdWFsIHx8ICFpc0V4cGFuZGVkRXF1YWw7XG4gIH07XG59IiwiaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICdkaWFncmFtLWpzL2xpYi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cbmltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBjc3NFc2NhcGUgZnJvbSAnY3NzLmVzY2FwZSc7XG5cbmltcG9ydCB7XG4gIGFzc2lnbixcbiAgZm9yRWFjaFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIHF1ZXJ5IGFzIGRvbVF1ZXJ5XG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICBhdHRyIGFzIHN2Z0F0dHJcbn0gZnJvbSAndGlueS1zdmcnO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gMjUwO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5SZXBsYWNlUHJldmlldyhcbiAgICBldmVudEJ1cywgZWxlbWVudFJlZ2lzdHJ5LCBlbGVtZW50RmFjdG9yeSxcbiAgICBjYW52YXMsIHByZXZpZXdTdXBwb3J0KSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIC8qKlxuICAgKiBSZXBsYWNlIHRoZSB2aXN1YWxzIG9mIGFsbCBlbGVtZW50cyBpbiB0aGUgY29udGV4dCB3aGljaCBjYW4gYmUgcmVwbGFjZWRcbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBjb250ZXh0XG4gICAqL1xuICBmdW5jdGlvbiByZXBsYWNlVmlzdWFsKGNvbnRleHQpIHtcblxuICAgIHZhciByZXBsYWNlbWVudHMgPSBjb250ZXh0LmNhbkV4ZWN1dGUucmVwbGFjZW1lbnRzO1xuXG4gICAgZm9yRWFjaChyZXBsYWNlbWVudHMsIGZ1bmN0aW9uKHJlcGxhY2VtZW50KSB7XG5cbiAgICAgIHZhciBpZCA9IHJlcGxhY2VtZW50Lm9sZEVsZW1lbnRJZDtcblxuICAgICAgdmFyIG5ld0VsZW1lbnQgPSB7XG4gICAgICAgIHR5cGU6IHJlcGxhY2VtZW50Lm5ld0VsZW1lbnRUeXBlXG4gICAgICB9O1xuXG4gICAgICAvLyBpZiB0aGUgdmlzdWFsIG9mIHRoZSBlbGVtZW50IGlzIGFscmVhZHkgcmVwbGFjZWRcbiAgICAgIGlmIChjb250ZXh0LnZpc3VhbFJlcGxhY2VtZW50c1tpZF0pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB2YXIgZWxlbWVudCA9IGVsZW1lbnRSZWdpc3RyeS5nZXQoaWQpO1xuXG4gICAgICBhc3NpZ24obmV3RWxlbWVudCwgeyB4OiBlbGVtZW50LngsIHk6IGVsZW1lbnQueSB9KTtcblxuICAgICAgLy8gY3JlYXRlIGEgdGVtcG9yYXJ5IHNoYXBlXG4gICAgICB2YXIgdGVtcFNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUobmV3RWxlbWVudCk7XG5cbiAgICAgIGNhbnZhcy5hZGRTaGFwZSh0ZW1wU2hhcGUsIGVsZW1lbnQucGFyZW50KTtcblxuICAgICAgLy8gc2VsZWN0IHRoZSBvcmlnaW5hbCBTVkcgZWxlbWVudCByZWxhdGVkIHRvIHRoZSBlbGVtZW50IGFuZCBoaWRlIGl0XG4gICAgICB2YXIgZ2Z4ID0gZG9tUXVlcnkoJ1tkYXRhLWVsZW1lbnQtaWQ9XCInICsgY3NzRXNjYXBlKGVsZW1lbnQuaWQpICsgJ1wiXScsIGNvbnRleHQuZHJhZ0dyb3VwKTtcblxuICAgICAgaWYgKGdmeCkge1xuICAgICAgICBzdmdBdHRyKGdmeCwgeyBkaXNwbGF5OiAnbm9uZScgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGNsb25lIHRoZSBnZnggb2YgdGhlIHRlbXBvcmFyeSBzaGFwZSBhbmQgYWRkIGl0IHRvIHRoZSBkcmFnIGdyb3VwXG4gICAgICB2YXIgZHJhZ2dlciA9IHByZXZpZXdTdXBwb3J0LmFkZERyYWdnZXIodGVtcFNoYXBlLCBjb250ZXh0LmRyYWdHcm91cCk7XG5cbiAgICAgIGNvbnRleHQudmlzdWFsUmVwbGFjZW1lbnRzW2lkXSA9IGRyYWdnZXI7XG5cbiAgICAgIGNhbnZhcy5yZW1vdmVTaGFwZSh0ZW1wU2hhcGUpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHZpc3VhbHMgb2YgdGhlIHByZXZpb3VzbHkgcmVwbGFjZWQgZWxlbWVudHNcbiAgICpcbiAgICogQHBhcmFtICB7T2JqZWN0fSBjb250ZXh0XG4gICAqL1xuICBmdW5jdGlvbiByZXN0b3JlVmlzdWFsKGNvbnRleHQpIHtcblxuICAgIHZhciB2aXN1YWxSZXBsYWNlbWVudHMgPSBjb250ZXh0LnZpc3VhbFJlcGxhY2VtZW50cztcblxuICAgIGZvckVhY2godmlzdWFsUmVwbGFjZW1lbnRzLCBmdW5jdGlvbihkcmFnZ2VyLCBpZCkge1xuXG4gICAgICB2YXIgb3JpZ2luYWxHZnggPSBkb21RdWVyeSgnW2RhdGEtZWxlbWVudC1pZD1cIicgKyBjc3NFc2NhcGUoaWQpICsgJ1wiXScsIGNvbnRleHQuZHJhZ0dyb3VwKTtcblxuICAgICAgaWYgKG9yaWdpbmFsR2Z4KSB7XG4gICAgICAgIHN2Z0F0dHIob3JpZ2luYWxHZngsIHsgZGlzcGxheTogJ2lubGluZScgfSk7XG4gICAgICB9XG5cbiAgICAgIGRyYWdnZXIucmVtb3ZlKCk7XG5cbiAgICAgIGlmICh2aXN1YWxSZXBsYWNlbWVudHNbaWRdKSB7XG4gICAgICAgIGRlbGV0ZSB2aXN1YWxSZXBsYWNlbWVudHNbaWRdO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUubW92ZScsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZTtcblxuICAgIGlmICghY29udGV4dC52aXN1YWxSZXBsYWNlbWVudHMpIHtcbiAgICAgIGNvbnRleHQudmlzdWFsUmVwbGFjZW1lbnRzID0ge307XG4gICAgfVxuXG4gICAgaWYgKGNhbkV4ZWN1dGUgJiYgY2FuRXhlY3V0ZS5yZXBsYWNlbWVudHMpIHtcbiAgICAgIHJlcGxhY2VWaXN1YWwoY29udGV4dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3RvcmVWaXN1YWwoY29udGV4dCk7XG4gICAgfVxuICB9KTtcbn1cblxuQnBtblJlcGxhY2VQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdlbGVtZW50UmVnaXN0cnknLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnY2FudmFzJyxcbiAgJ3ByZXZpZXdTdXBwb3J0J1xuXTtcblxuaW5oZXJpdHMoQnBtblJlcGxhY2VQcmV2aWV3LCBDb21tYW5kSW50ZXJjZXB0b3IpOyIsImltcG9ydCBQcmV2aWV3U3VwcG9ydE1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9wcmV2aWV3LXN1cHBvcnQnO1xuXG5pbXBvcnQgQnBtblJlcGxhY2VQcmV2aWV3IGZyb20gJy4vQnBtblJlcGxhY2VQcmV2aWV3JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIFByZXZpZXdTdXBwb3J0TW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdicG1uUmVwbGFjZVByZXZpZXcnIF0sXG4gIGJwbW5SZXBsYWNlUHJldmlldzogWyAndHlwZScsIEJwbW5SZXBsYWNlUHJldmlldyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgcGljayxcbiAgYXNzaWduLFxuICBmaWx0ZXIsXG4gIGZvckVhY2gsXG4gIGlzQXJyYXksXG4gIGlzVW5kZWZpbmVkLFxuICBoYXNcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBpcyxcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0FueVxufSBmcm9tICcuLi9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzRXhwYW5kZWQsXG4gIGlzRXZlbnRTdWJQcm9jZXNzXG59IGZyb20gJy4uLy4uL3V0aWwvRGlVdGlsJztcblxuaW1wb3J0IHsgZ2V0UHJvcGVydHlOYW1lcyB9IGZyb20gJy4uL2NvcHktcGFzdGUvTW9kZGxlQ29weSc7XG5cbmZ1bmN0aW9uIGNvcHlQcm9wZXJ0aWVzKHNvdXJjZSwgdGFyZ2V0LCBwcm9wZXJ0aWVzKSB7XG4gIGlmICghaXNBcnJheShwcm9wZXJ0aWVzKSkge1xuICAgIHByb3BlcnRpZXMgPSBbIHByb3BlcnRpZXMgXTtcbiAgfVxuXG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24ocHJvcGVydHkpIHtcbiAgICBpZiAoIWlzVW5kZWZpbmVkKHNvdXJjZVtwcm9wZXJ0eV0pKSB7XG4gICAgICB0YXJnZXRbcHJvcGVydHldID0gc291cmNlW3Byb3BlcnR5XTtcbiAgICB9XG4gIH0pO1xufVxuXG52YXIgQ1VTVE9NX1BST1BFUlRJRVMgPSBbXG4gICdjYW5jZWxBY3Rpdml0eScsXG4gICdpbnN0YW50aWF0ZScsXG4gICdldmVudEdhdGV3YXlUeXBlJyxcbiAgJ3RyaWdnZXJlZEJ5RXZlbnQnLFxuICAnaXNJbnRlcnJ1cHRpbmcnXG5dO1xuXG5cbmZ1bmN0aW9uIHRvZ2dlbGluZyhlbGVtZW50LCB0YXJnZXQpIHtcblxuICB2YXIgb2xkQ29sbGFwc2VkID0gKFxuICAgIGVsZW1lbnQgJiYgaGFzKGVsZW1lbnQsICdjb2xsYXBzZWQnKSA/IGVsZW1lbnQuY29sbGFwc2VkIDogIWlzRXhwYW5kZWQoZWxlbWVudClcbiAgKTtcblxuICB2YXIgdGFyZ2V0Q29sbGFwc2VkO1xuXG4gIGlmICh0YXJnZXQgJiYgKGhhcyh0YXJnZXQsICdjb2xsYXBzZWQnKSB8fCBoYXModGFyZ2V0LCAnaXNFeHBhbmRlZCcpKSkge1xuXG4gICAgLy8gcHJvcGVydHkgaXMgZXhwbGljaXRseSBzZXQgc28gdXNlIGl0XG4gICAgdGFyZ2V0Q29sbGFwc2VkID0gKFxuICAgICAgaGFzKHRhcmdldCwgJ2NvbGxhcHNlZCcpID8gdGFyZ2V0LmNvbGxhcHNlZCA6ICF0YXJnZXQuaXNFeHBhbmRlZFxuICAgICk7XG4gIH0gZWxzZSB7XG5cbiAgICAvLyBrZWVwIG9sZCBzdGF0ZVxuICAgIHRhcmdldENvbGxhcHNlZCA9IG9sZENvbGxhcHNlZDtcbiAgfVxuXG4gIGlmIChvbGRDb2xsYXBzZWQgIT09IHRhcmdldENvbGxhcHNlZCkge1xuICAgIGVsZW1lbnQuY29sbGFwc2VkID0gb2xkQ29sbGFwc2VkO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5cblxuLyoqXG4gKiBUaGlzIG1vZHVsZSB0YWtlcyBjYXJlIG9mIHJlcGxhY2luZyBCUE1OIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5SZXBsYWNlKFxuICAgIGJwbW5GYWN0b3J5LFxuICAgIGVsZW1lbnRGYWN0b3J5LFxuICAgIG1vZGRsZUNvcHksXG4gICAgbW9kZWxpbmcsXG4gICAgcmVwbGFjZSxcbiAgICBzZWxlY3Rpb25cbikge1xuXG4gIC8qKlxuICAgKiBQcmVwYXJlcyBhIG5ldyBidXNpbmVzcyBvYmplY3QgZm9yIHRoZSByZXBsYWNlbWVudCBlbGVtZW50XG4gICAqIGFuZCB0cmlnZ2VycyB0aGUgcmVwbGFjZSBvcGVyYXRpb24uXG4gICAqXG4gICAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gICAqIEBwYXJhbSAge09iamVjdH0gdGFyZ2V0XG4gICAqIEBwYXJhbSAge09iamVjdH0gW2hpbnRzXVxuICAgKlxuICAgKiBAcmV0dXJuIHtkanMubW9kZWwuQmFzZX0gdGhlIG5ld2x5IGNyZWF0ZWQgZWxlbWVudFxuICAgKi9cbiAgZnVuY3Rpb24gcmVwbGFjZUVsZW1lbnQoZWxlbWVudCwgdGFyZ2V0LCBoaW50cykge1xuXG4gICAgaGludHMgPSBoaW50cyB8fCB7fTtcblxuICAgIHZhciB0eXBlID0gdGFyZ2V0LnR5cGUsXG4gICAgICAgIG9sZEJ1c2luZXNzT2JqZWN0ID0gZWxlbWVudC5idXNpbmVzc09iamVjdDtcblxuICAgIGlmIChpc1N1YlByb2Nlc3Mob2xkQnVzaW5lc3NPYmplY3QpKSB7XG4gICAgICBpZiAodHlwZSA9PT0gJ2JwbW46U3ViUHJvY2VzcycpIHtcbiAgICAgICAgaWYgKHRvZ2dlbGluZyhlbGVtZW50LCB0YXJnZXQpKSB7XG5cbiAgICAgICAgICAvLyBleHBhbmRpbmcgb3IgY29sbGFwc2luZyBwcm9jZXNzXG4gICAgICAgICAgbW9kZWxpbmcudG9nZ2xlQ29sbGFwc2UoZWxlbWVudCk7XG5cbiAgICAgICAgICByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBuZXdCdXNpbmVzc09iamVjdCA9IGJwbW5GYWN0b3J5LmNyZWF0ZSh0eXBlKTtcblxuICAgIHZhciBuZXdFbGVtZW50ID0ge1xuICAgICAgdHlwZTogdHlwZSxcbiAgICAgIGJ1c2luZXNzT2JqZWN0OiBuZXdCdXNpbmVzc09iamVjdFxuICAgIH07XG5cbiAgICB2YXIgZWxlbWVudFByb3BzID0gZ2V0UHJvcGVydHlOYW1lcyhvbGRCdXNpbmVzc09iamVjdC4kZGVzY3JpcHRvciksXG4gICAgICAgIG5ld0VsZW1lbnRQcm9wcyA9IGdldFByb3BlcnR5TmFtZXMobmV3QnVzaW5lc3NPYmplY3QuJGRlc2NyaXB0b3IsIHRydWUpLFxuICAgICAgICBjb3B5UHJvcHMgPSBpbnRlcnNlY3Rpb24oZWxlbWVudFByb3BzLCBuZXdFbGVtZW50UHJvcHMpO1xuXG4gICAgLy8gaW5pdGlhbGl6ZSBzcGVjaWFsIHByb3BlcnRpZXMgZGVmaW5lZCBpbiB0YXJnZXQgZGVmaW5pdGlvblxuICAgIGFzc2lnbihuZXdCdXNpbmVzc09iamVjdCwgcGljayh0YXJnZXQsIENVU1RPTV9QUk9QRVJUSUVTKSk7XG5cbiAgICB2YXIgcHJvcGVydGllcyA9IGZpbHRlcihjb3B5UHJvcHMsIGZ1bmN0aW9uKHByb3BlcnR5TmFtZSkge1xuXG4gICAgICAvLyBjb3B5aW5nIGV2ZW50IGRlZmluaXRpb25zLCB1bmxlc3Mgd2UgcmVwbGFjZVxuICAgICAgaWYgKHByb3BlcnR5TmFtZSA9PT0gJ2V2ZW50RGVmaW5pdGlvbnMnKSB7XG4gICAgICAgIHJldHVybiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgdGFyZ2V0LmV2ZW50RGVmaW5pdGlvblR5cGUpO1xuICAgICAgfVxuXG4gICAgICAvLyByZXRhaW4gbG9vcCBjaGFyYWN0ZXJpc3RpY3MgaWYgdGhlIHRhcmdldCBlbGVtZW50XG4gICAgICAvLyBpcyBub3QgYW4gZXZlbnQgc3ViIHByb2Nlc3NcbiAgICAgIGlmIChwcm9wZXJ0eU5hbWUgPT09ICdsb29wQ2hhcmFjdGVyaXN0aWNzJykge1xuICAgICAgICByZXR1cm4gIWlzRXZlbnRTdWJQcm9jZXNzKG5ld0J1c2luZXNzT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgLy8gc28gdGhlIGFwcGxpZWQgcHJvcGVydGllcyBmcm9tICd0YXJnZXQnIGRvbid0IGdldCBsb3N0XG4gICAgICBpZiAobmV3QnVzaW5lc3NPYmplY3QuaGFzT3duUHJvcGVydHkocHJvcGVydHlOYW1lKSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wZXJ0eU5hbWUgPT09ICdwcm9jZXNzUmVmJyAmJiB0YXJnZXQuaXNFeHBhbmRlZCA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAocHJvcGVydHlOYW1lID09PSAndHJpZ2dlcmVkQnlFdmVudCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcblxuICAgIG5ld0J1c2luZXNzT2JqZWN0ID0gbW9kZGxlQ29weS5jb3B5RWxlbWVudChcbiAgICAgIG9sZEJ1c2luZXNzT2JqZWN0LFxuICAgICAgbmV3QnVzaW5lc3NPYmplY3QsXG4gICAgICBwcm9wZXJ0aWVzXG4gICAgKTtcblxuICAgIC8vIGluaXRpYWxpemUgY3VzdG9tIEJQTU4gZXh0ZW5zaW9uc1xuICAgIGlmICh0YXJnZXQuZXZlbnREZWZpbml0aW9uVHlwZSkge1xuXG4gICAgICAvLyBvbmx5IGluaXRpYWxpemUgd2l0aCBuZXcgZXZlbnREZWZpbml0aW9uXG4gICAgICAvLyBpZiB3ZSBkaWQgbm90IHNldCBhbiBldmVudCBkZWZpbml0aW9uIHlldCxcbiAgICAgIC8vIGkuZS4gYmVjYXVzZSB3ZSBjb3BpZWQgaXRcbiAgICAgIGlmICghaGFzRXZlbnREZWZpbml0aW9uKG5ld0J1c2luZXNzT2JqZWN0LCB0YXJnZXQuZXZlbnREZWZpbml0aW9uVHlwZSkpIHtcbiAgICAgICAgbmV3RWxlbWVudC5ldmVudERlZmluaXRpb25UeXBlID0gdGFyZ2V0LmV2ZW50RGVmaW5pdGlvblR5cGU7XG4gICAgICAgIG5ld0VsZW1lbnQuZXZlbnREZWZpbml0aW9uQXR0cnMgPSB0YXJnZXQuZXZlbnREZWZpbml0aW9uQXR0cnM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGlzKG9sZEJ1c2luZXNzT2JqZWN0LCAnYnBtbjpBY3Rpdml0eScpKSB7XG5cbiAgICAgIGlmIChpc1N1YlByb2Nlc3Mob2xkQnVzaW5lc3NPYmplY3QpKSB7XG5cbiAgICAgICAgLy8gbm8gdG9nZ2VsaW5nLCBzbyBrZWVwIG9sZCBzdGF0ZVxuICAgICAgICBuZXdFbGVtZW50LmlzRXhwYW5kZWQgPSBpc0V4cGFuZGVkKG9sZEJ1c2luZXNzT2JqZWN0KTtcbiAgICAgIH1cblxuICAgICAgLy8gZWxzZSBpZiBwcm9wZXJ0eSBpcyBleHBsaWNpdGx5IHNldCwgdXNlIGl0XG4gICAgICBlbHNlIGlmICh0YXJnZXQgJiYgaGFzKHRhcmdldCwgJ2lzRXhwYW5kZWQnKSkge1xuICAgICAgICBuZXdFbGVtZW50LmlzRXhwYW5kZWQgPSB0YXJnZXQuaXNFeHBhbmRlZDtcbiAgICAgIH1cblxuICAgICAgLy8gVE9ETzogbmVlZCBhbHNvIHRvIHJlc3BlY3QgbWluL21heCBTaXplXG4gICAgICAvLyBjb3B5IHNpemUsIGZyb20gYW4gZXhwYW5kZWQgc3VicHJvY2VzcyB0byBhbiBleHBhbmRlZCBhbHRlcm5hdGl2ZSBzdWJwcm9jZXNzXG4gICAgICAvLyBleGNlcHQgYnBtbjpUYXNrLCBiZWNhdXNlIFRhc2sgaXMgYWx3YXlzIGV4cGFuZGVkXG4gICAgICBpZiAoKGlzRXhwYW5kZWQob2xkQnVzaW5lc3NPYmplY3QpICYmICFpcyhvbGRCdXNpbmVzc09iamVjdCwgJ2JwbW46VGFzaycpKSAmJiBuZXdFbGVtZW50LmlzRXhwYW5kZWQpIHtcbiAgICAgICAgbmV3RWxlbWVudC53aWR0aCA9IGVsZW1lbnQud2lkdGg7XG4gICAgICAgIG5ld0VsZW1lbnQuaGVpZ2h0ID0gZWxlbWVudC5oZWlnaHQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gcmVtb3ZlIGNoaWxkcmVuIGlmIG5vdCBleHBhbmRpbmcgc3ViIHByb2Nlc3NcbiAgICBpZiAoaXNTdWJQcm9jZXNzKG9sZEJ1c2luZXNzT2JqZWN0KSAmJiAhaXNTdWJQcm9jZXNzKG5ld0J1c2luZXNzT2JqZWN0KSkge1xuICAgICAgaGludHMubW92ZUNoaWxkcmVuID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gdHJhbnNmb3JtIGNvbGxhcHNlZC9leHBhbmRlZCBwb29sc1xuICAgIGlmIChpcyhvbGRCdXNpbmVzc09iamVjdCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuXG4gICAgICAvLyBjcmVhdGUgZXhwYW5kZWQgcG9vbFxuICAgICAgaWYgKHRhcmdldC5pc0V4cGFuZGVkID09PSB0cnVlKSB7XG4gICAgICAgIG5ld0J1c2luZXNzT2JqZWN0LnByb2Nlc3NSZWYgPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46UHJvY2VzcycpO1xuICAgICAgfSBlbHNlIHtcblxuICAgICAgICAvLyByZW1vdmUgY2hpbGRyZW4gd2hlbiB0cmFuc2Zvcm1pbmcgdG8gY29sbGFwc2VkIHBvb2xcbiAgICAgICAgaGludHMubW92ZUNoaWxkcmVuID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIC8vIGFwcGx5IHNhbWUgd2lkdGggYW5kIGRlZmF1bHQgaGVpZ2h0XG4gICAgICBuZXdFbGVtZW50LndpZHRoID0gZWxlbWVudC53aWR0aDtcbiAgICAgIG5ld0VsZW1lbnQuaGVpZ2h0ID0gZWxlbWVudEZhY3RvcnkuX2dldERlZmF1bHRTaXplKG5ld0J1c2luZXNzT2JqZWN0KS5oZWlnaHQ7XG4gICAgfVxuXG4gICAgbmV3QnVzaW5lc3NPYmplY3QubmFtZSA9IG9sZEJ1c2luZXNzT2JqZWN0Lm5hbWU7XG5cbiAgICAvLyByZXRhaW4gZGVmYXVsdCBmbG93J3MgcmVmZXJlbmNlIGJldHdlZW4gaW5jbHVzaXZlIDwtPiBleGNsdXNpdmUgZ2F0ZXdheXMgYW5kIGFjdGl2aXRpZXNcbiAgICBpZiAoXG4gICAgICBpc0FueShvbGRCdXNpbmVzc09iamVjdCwgW1xuICAgICAgICAnYnBtbjpFeGNsdXNpdmVHYXRld2F5JyxcbiAgICAgICAgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheScsXG4gICAgICAgICdicG1uOkFjdGl2aXR5J1xuICAgICAgXSkgJiZcbiAgICAgIGlzQW55KG5ld0J1c2luZXNzT2JqZWN0LCBbXG4gICAgICAgICdicG1uOkV4Y2x1c2l2ZUdhdGV3YXknLFxuICAgICAgICAnYnBtbjpJbmNsdXNpdmVHYXRld2F5JyxcbiAgICAgICAgJ2JwbW46QWN0aXZpdHknXG4gICAgICBdKVxuICAgICkge1xuICAgICAgbmV3QnVzaW5lc3NPYmplY3QuZGVmYXVsdCA9IG9sZEJ1c2luZXNzT2JqZWN0LmRlZmF1bHQ7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGFyZ2V0Lmhvc3QgJiZcbiAgICAgICFpcyhvbGRCdXNpbmVzc09iamVjdCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmXG4gICAgICBpcyhuZXdCdXNpbmVzc09iamVjdCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpXG4gICAgKSB7XG4gICAgICBuZXdFbGVtZW50Lmhvc3QgPSB0YXJnZXQuaG9zdDtcbiAgICB9XG5cbiAgICBuZXdFbGVtZW50LmRpID0ge307XG5cbiAgICAvLyBmaWxsIGFuZCBzdHJva2Ugd2lsbCBiZSBzZXQgdG8gRElcbiAgICBjb3B5UHJvcGVydGllcyhvbGRCdXNpbmVzc09iamVjdC5kaSwgbmV3RWxlbWVudC5kaSwgW1xuICAgICAgJ2ZpbGwnLFxuICAgICAgJ3N0cm9rZSdcbiAgICBdKTtcblxuICAgIG5ld0VsZW1lbnQgPSByZXBsYWNlLnJlcGxhY2VFbGVtZW50KGVsZW1lbnQsIG5ld0VsZW1lbnQsIGhpbnRzKTtcblxuICAgIGlmIChoaW50cy5zZWxlY3QgIT09IGZhbHNlKSB7XG4gICAgICBzZWxlY3Rpb24uc2VsZWN0KG5ld0VsZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBuZXdFbGVtZW50O1xuICB9XG5cbiAgdGhpcy5yZXBsYWNlRWxlbWVudCA9IHJlcGxhY2VFbGVtZW50O1xufVxuXG5CcG1uUmVwbGFjZS4kaW5qZWN0ID0gW1xuICAnYnBtbkZhY3RvcnknLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnbW9kZGxlQ29weScsXG4gICdtb2RlbGluZycsXG4gICdyZXBsYWNlJyxcbiAgJ3NlbGVjdGlvbidcbl07XG5cblxuZnVuY3Rpb24gaXNTdWJQcm9jZXNzKGJvKSB7XG4gIHJldHVybiBpcyhibywgJ2JwbW46U3ViUHJvY2VzcycpO1xufVxuXG5mdW5jdGlvbiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgdHlwZSkge1xuXG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xuXG4gIHJldHVybiB0eXBlICYmIGJvLmdldCgnZXZlbnREZWZpbml0aW9ucycpLnNvbWUoZnVuY3Rpb24oZGVmaW5pdGlvbikge1xuICAgIHJldHVybiBpcyhkZWZpbml0aW9uLCB0eXBlKTtcbiAgfSk7XG59XG5cbi8qKlxuICogQ29tcHV0ZSBpbnRlcnNlY3Rpb24gYmV0d2VlbiB0d28gYXJyYXlzLlxuICovXG5mdW5jdGlvbiBpbnRlcnNlY3Rpb24oYTEsIGEyKSB7XG4gIHJldHVybiBhMS5maWx0ZXIoZnVuY3Rpb24oZWwpIHtcbiAgICByZXR1cm4gYTIuaW5kZXhPZihlbCkgIT09IC0xO1xuICB9KTtcbn1cbiIsImV4cG9ydCB2YXIgU1RBUlRfRVZFTlQgPSBbXG4gIHtcbiAgICBsYWJlbDogJ1N0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbmUtc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1ub25lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdJbnRlcm1lZGlhdGUgVGhyb3cgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uZS1pbnRlcm1lZGlhdGUtdGhyb3dpbmcnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtbm9uZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnRW5kIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbmUtZW5kJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZW5kLWV2ZW50LW5vbmUnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46RW5kRXZlbnQnXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdNZXNzYWdlIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW1lc3NhZ2Utc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1tZXNzYWdlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1RpbWVyIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXRpbWVyLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtdGltZXInLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpUaW1lckV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0NvbmRpdGlvbmFsIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbmRpdGlvbmFsLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtY29uZGl0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTaWduYWwgU3RhcnQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtc2lnbmFsLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtc2lnbmFsJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfVxuXTtcblxuZXhwb3J0IHZhciBTVEFSVF9FVkVOVF9TVUJfUFJPQ0VTUyA9IFtcbiAge1xuICAgIGxhYmVsOiAnU3RhcnQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uZS1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LW5vbmUnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0ludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLWludGVybWVkaWF0ZS10aHJvd2luZycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1ub25lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFbmQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uZS1lbmQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1lbmQtZXZlbnQtbm9uZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCdcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgSU5URVJNRURJQVRFX0VWRU5UID0gW1xuICB7XG4gICAgbGFiZWw6ICdTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtbm9uZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbmUtaW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LW5vbmUnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0VuZCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLWVuZCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWVuZC1ldmVudC1ub25lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkVuZEV2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnTWVzc2FnZSBJbnRlcm1lZGlhdGUgQ2F0Y2ggRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbWVzc2FnZS1pbnRlcm1lZGlhdGUtY2F0Y2gnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbWVzc2FnZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdNZXNzYWdlIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1tZXNzYWdlLWludGVybWVkaWF0ZS10aHJvdycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC10aHJvdy1tZXNzYWdlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1RpbWVyIEludGVybWVkaWF0ZSBDYXRjaCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC10aW1lci1pbnRlcm1lZGlhdGUtY2F0Y2gnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtdGltZXInLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpUaW1lckV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0VzY2FsYXRpb24gSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVzY2FsYXRpb24taW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LWVzY2FsYXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29uZGl0aW9uYWwgSW50ZXJtZWRpYXRlIENhdGNoIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbmRpdGlvbmFsLWludGVybWVkaWF0ZS1jYXRjaCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb25kaXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0xpbmsgSW50ZXJtZWRpYXRlIENhdGNoIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWxpbmstaW50ZXJtZWRpYXRlLWNhdGNoJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWxpbmsnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpMaW5rRXZlbnREZWZpbml0aW9uJyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvbkF0dHJzOiB7XG4gICAgICAgIG5hbWU6ICcnXG4gICAgICB9XG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdMaW5rIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1saW5rLWludGVybWVkaWF0ZS10aHJvdycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC10aHJvdy1saW5rJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicsXG4gICAgICBldmVudERlZmluaXRpb25BdHRyczoge1xuICAgICAgICBuYW1lOiAnJ1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29tcGVuc2F0aW9uIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb21wZW5zYXRpb24taW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LWNvbXBlbnNhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTaWduYWwgSW50ZXJtZWRpYXRlIENhdGNoIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNpZ25hbC1pbnRlcm1lZGlhdGUtY2F0Y2gnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtc2lnbmFsJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU2lnbmFsIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1zaWduYWwtaW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LXRocm93LXNpZ25hbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgRU5EX0VWRU5UID0gW1xuICB7XG4gICAgbGFiZWw6ICdTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtbm9uZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbmUtaW50ZXJtZWRpYXRlLXRocm93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LW5vbmUnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0VuZCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub25lLWVuZCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWVuZC1ldmVudC1ub25lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkVuZEV2ZW50J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnTWVzc2FnZSBFbmQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbWVzc2FnZS1lbmQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1lbmQtZXZlbnQtbWVzc2FnZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpNZXNzYWdlRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnRXNjYWxhdGlvbiBFbmQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZXNjYWxhdGlvbi1lbmQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1lbmQtZXZlbnQtZXNjYWxhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnRXJyb3IgRW5kIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVycm9yLWVuZCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWVuZC1ldmVudC1lcnJvcicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFcnJvckV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0NhbmNlbCBFbmQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtY2FuY2VsLWVuZCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWVuZC1ldmVudC1jYW5jZWwnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46RW5kRXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46Q2FuY2VsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29tcGVuc2F0aW9uIEVuZCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb21wZW5zYXRpb24tZW5kJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZW5kLWV2ZW50LWNvbXBlbnNhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU2lnbmFsIEVuZCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1zaWduYWwtZW5kJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZW5kLWV2ZW50LXNpZ25hbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdUZXJtaW5hdGUgRW5kIEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXRlcm1pbmF0ZS1lbmQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1lbmQtZXZlbnQtdGVybWluYXRlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkVuZEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlRlcm1pbmF0ZUV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgR0FURVdBWSA9IFtcbiAge1xuICAgIGxhYmVsOiAnRXhjbHVzaXZlIEdhdGV3YXknLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZXhjbHVzaXZlLWdhdGV3YXknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1nYXRld2F5LXhvcicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpFeGNsdXNpdmVHYXRld2F5J1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnUGFyYWxsZWwgR2F0ZXdheScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1wYXJhbGxlbC1nYXRld2F5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZ2F0ZXdheS1wYXJhbGxlbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpQYXJhbGxlbEdhdGV3YXknXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdJbmNsdXNpdmUgR2F0ZXdheScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1pbmNsdXNpdmUtZ2F0ZXdheScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWdhdGV3YXktb3InLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46SW5jbHVzaXZlR2F0ZXdheSdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0NvbXBsZXggR2F0ZXdheScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb21wbGV4LWdhdGV3YXknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1nYXRld2F5LWNvbXBsZXgnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46Q29tcGxleEdhdGV3YXknXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFdmVudCBiYXNlZCBHYXRld2F5JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWV2ZW50LWJhc2VkLWdhdGV3YXknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1nYXRld2F5LWV2ZW50YmFzZWQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46RXZlbnRCYXNlZEdhdGV3YXknLFxuICAgICAgaW5zdGFudGlhdGU6IGZhbHNlLFxuICAgICAgZXZlbnRHYXRld2F5VHlwZTogJ0V4Y2x1c2l2ZSdcbiAgICB9XG4gIH1cblxuICAvLyBHYXRld2F5cyBkZWFjdGl2YXRlZCB1bnRpbCBodHRwczovL2dpdGh1Yi5jb20vYnBtbi1pby9icG1uLWpzL2lzc3Vlcy8xOTRcbiAgLy8ge1xuICAvLyAgIGxhYmVsOiAnRXZlbnQgYmFzZWQgaW5zdGFudGlhdGluZyBHYXRld2F5JyxcbiAgLy8gICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWV4Y2x1c2l2ZS1ldmVudC1iYXNlZC1nYXRld2F5JyxcbiAgLy8gICBjbGFzc05hbWU6ICdicG1uLWljb24tZXhjbHVzaXZlLWV2ZW50LWJhc2VkJyxcbiAgLy8gICB0YXJnZXQ6IHtcbiAgLy8gICAgIHR5cGU6ICdicG1uOkV2ZW50QmFzZWRHYXRld2F5J1xuICAvLyAgIH0sXG4gIC8vICAgb3B0aW9uczoge1xuICAvLyAgICAgYnVzaW5lc3NPYmplY3Q6IHsgaW5zdGFudGlhdGU6IHRydWUsIGV2ZW50R2F0ZXdheVR5cGU6ICdFeGNsdXNpdmUnIH1cbiAgLy8gICB9XG4gIC8vIH0sXG4gIC8vIHtcbiAgLy8gICBsYWJlbDogJ1BhcmFsbGVsIEV2ZW50IGJhc2VkIGluc3RhbnRpYXRpbmcgR2F0ZXdheScsXG4gIC8vICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1wYXJhbGxlbC1ldmVudC1iYXNlZC1pbnN0YW50aWF0ZS1nYXRld2F5JyxcbiAgLy8gICBjbGFzc05hbWU6ICdicG1uLWljb24tcGFyYWxsZWwtZXZlbnQtYmFzZWQtaW5zdGFudGlhdGUtZ2F0ZXdheScsXG4gIC8vICAgdGFyZ2V0OiB7XG4gIC8vICAgICB0eXBlOiAnYnBtbjpFdmVudEJhc2VkR2F0ZXdheSdcbiAgLy8gICB9LFxuICAvLyAgIG9wdGlvbnM6IHtcbiAgLy8gICAgIGJ1c2luZXNzT2JqZWN0OiB7IGluc3RhbnRpYXRlOiB0cnVlLCBldmVudEdhdGV3YXlUeXBlOiAnUGFyYWxsZWwnIH1cbiAgLy8gICB9XG4gIC8vIH1cbl07XG5cbmV4cG9ydCB2YXIgU1VCUFJPQ0VTU19FWFBBTkRFRCA9IFtcbiAge1xuICAgIGxhYmVsOiAnVHJhbnNhY3Rpb24nLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtdHJhbnNhY3Rpb24nLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi10cmFuc2FjdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpUcmFuc2FjdGlvbicsXG4gICAgICBpc0V4cGFuZGVkOiB0cnVlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFdmVudCBTdWIgUHJvY2VzcycsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ldmVudC1zdWJwcm9jZXNzJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZXZlbnQtc3VicHJvY2Vzcy1leHBhbmRlZCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdWJQcm9jZXNzJyxcbiAgICAgIHRyaWdnZXJlZEJ5RXZlbnQ6IHRydWUsXG4gICAgICBpc0V4cGFuZGVkOiB0cnVlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTdWIgUHJvY2VzcyAoY29sbGFwc2VkKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb2xsYXBzZWQtc3VicHJvY2VzcycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN1YnByb2Nlc3MtY29sbGFwc2VkJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN1YlByb2Nlc3MnLFxuICAgICAgaXNFeHBhbmRlZDogZmFsc2VcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgVFJBTlNBQ1RJT04gPSBbXG4gIHtcbiAgICBsYWJlbDogJ1N1YiBQcm9jZXNzJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXN1YnByb2Nlc3MnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdWJwcm9jZXNzLWV4cGFuZGVkJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN1YlByb2Nlc3MnLFxuICAgICAgaXNFeHBhbmRlZDogdHJ1ZVxuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnRXZlbnQgU3ViIFByb2Nlc3MnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZXZlbnQtc3VicHJvY2VzcycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWV2ZW50LXN1YnByb2Nlc3MtZXhwYW5kZWQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3ViUHJvY2VzcycsXG4gICAgICB0cmlnZ2VyZWRCeUV2ZW50OiB0cnVlLFxuICAgICAgaXNFeHBhbmRlZDogdHJ1ZVxuICAgIH1cbiAgfVxuXTtcblxuZXhwb3J0IHZhciBFVkVOVF9TVUJfUFJPQ0VTUyA9IFtcbiAge1xuICAgIGxhYmVsOiAnU3ViIFByb2Nlc3MnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtc3VicHJvY2VzcycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN1YnByb2Nlc3MtZXhwYW5kZWQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3ViUHJvY2VzcycsXG4gICAgICBpc0V4cGFuZGVkOiB0cnVlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdUcmFuc2FjdGlvbicsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC10cmFuc2FjdGlvbicsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXRyYW5zYWN0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlRyYW5zYWN0aW9uJyxcbiAgICAgIGlzRXhwYW5kZWQ6IHRydWVcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgVEFTSyA9IFtcbiAge1xuICAgIGxhYmVsOiAnVGFzaycsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC10YXNrJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tdGFzaycsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpUYXNrJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU2VuZCBUYXNrJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNlbmQtdGFzaycsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXNlbmQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U2VuZFRhc2snXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdSZWNlaXZlIFRhc2snLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtcmVjZWl2ZS10YXNrJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tcmVjZWl2ZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpSZWNlaXZlVGFzaydcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1VzZXIgVGFzaycsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC11c2VyLXRhc2snLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi11c2VyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlVzZXJUYXNrJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnTWFudWFsIFRhc2snLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbWFudWFsLXRhc2snLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1tYW51YWwnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46TWFudWFsVGFzaydcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0J1c2luZXNzIFJ1bGUgVGFzaycsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ydWxlLXRhc2snLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1idXNpbmVzcy1ydWxlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJ1c2luZXNzUnVsZVRhc2snXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTZXJ2aWNlIFRhc2snLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtc2VydmljZS10YXNrJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc2VydmljZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTZXJ2aWNlVGFzaydcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1NjcmlwdCBUYXNrJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNjcmlwdC10YXNrJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc2NyaXB0JyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlNjcmlwdFRhc2snXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDYWxsIEFjdGl2aXR5JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNhbGwtYWN0aXZpdHknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jYWxsLWFjdGl2aXR5JyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkNhbGxBY3Rpdml0eSdcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1N1YiBQcm9jZXNzIChjb2xsYXBzZWQpJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbGxhcHNlZC1zdWJwcm9jZXNzJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3VicHJvY2Vzcy1jb2xsYXBzZWQnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3ViUHJvY2VzcycsXG4gICAgICBpc0V4cGFuZGVkOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU3ViIFByb2Nlc3MgKGV4cGFuZGVkKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1leHBhbmRlZC1zdWJwcm9jZXNzJyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3VicHJvY2Vzcy1leHBhbmRlZCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdWJQcm9jZXNzJyxcbiAgICAgIGlzRXhwYW5kZWQ6IHRydWVcbiAgICB9XG4gIH1cbl07XG5cbmV4cG9ydCB2YXIgQk9VTkRBUllfRVZFTlQgPSBbXG4gIHtcbiAgICBsYWJlbDogJ01lc3NhZ2UgQm91bmRhcnkgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbWVzc2FnZS1ib3VuZGFyeScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1tZXNzYWdlJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1RpbWVyIEJvdW5kYXJ5IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXRpbWVyLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLXRpbWVyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFc2NhbGF0aW9uIEJvdW5kYXJ5IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVzY2FsYXRpb24tYm91bmRhcnknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtZXNjYWxhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkVzY2FsYXRpb25FdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb25kaXRpb25hbCBCb3VuZGFyeSBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb25kaXRpb25hbC1ib3VuZGFyeScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb25kaXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46Qm91bmRhcnlFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0Vycm9yIEJvdW5kYXJ5IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVycm9yLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWVycm9yJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46RXJyb3JFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDYW5jZWwgQm91bmRhcnkgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtY2FuY2VsLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLWNhbmNlbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNhbmNlbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ1NpZ25hbCBCb3VuZGFyeSBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1zaWduYWwtYm91bmRhcnknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtc2lnbmFsJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29tcGVuc2F0aW9uIEJvdW5kYXJ5IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbXBlbnNhdGlvbi1ib3VuZGFyeScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1jb21wZW5zYXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46Qm91bmRhcnlFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnTWVzc2FnZSBCb3VuZGFyeSBFdmVudCAobm9uLWludGVycnVwdGluZyknLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uLWludGVycnVwdGluZy1tZXNzYWdlLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW5vbi1pbnRlcnJ1cHRpbmctbWVzc2FnZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nLFxuICAgICAgY2FuY2VsQWN0aXZpdHk6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdUaW1lciBCb3VuZGFyeSBFdmVudCAobm9uLWludGVycnVwdGluZyknLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uLWludGVycnVwdGluZy10aW1lci1ib3VuZGFyeScsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWludGVybWVkaWF0ZS1ldmVudC1jYXRjaC1ub24taW50ZXJydXB0aW5nLXRpbWVyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nLFxuICAgICAgY2FuY2VsQWN0aXZpdHk6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFc2NhbGF0aW9uIEJvdW5kYXJ5IEV2ZW50IChub24taW50ZXJydXB0aW5nKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub24taW50ZXJydXB0aW5nLWVzY2FsYXRpb24tYm91bmRhcnknLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1pbnRlcm1lZGlhdGUtZXZlbnQtY2F0Y2gtbm9uLWludGVycnVwdGluZy1lc2NhbGF0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46RXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicsXG4gICAgICBjYW5jZWxBY3Rpdml0eTogZmFsc2VcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0NvbmRpdGlvbmFsIEJvdW5kYXJ5IEV2ZW50IChub24taW50ZXJydXB0aW5nKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub24taW50ZXJydXB0aW5nLWNvbmRpdGlvbmFsLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW5vbi1pbnRlcnJ1cHRpbmctY29uZGl0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nLFxuICAgICAgY2FuY2VsQWN0aXZpdHk6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTaWduYWwgQm91bmRhcnkgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbi1pbnRlcnJ1cHRpbmctc2lnbmFsLWJvdW5kYXJ5JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24taW50ZXJtZWRpYXRlLWV2ZW50LWNhdGNoLW5vbi1pbnRlcnJ1cHRpbmctc2lnbmFsJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJyxcbiAgICAgIGNhbmNlbEFjdGl2aXR5OiBmYWxzZVxuICAgIH1cbiAgfVxuXTtcblxuZXhwb3J0IHZhciBFVkVOVF9TVUJfUFJPQ0VTU19TVEFSVF9FVkVOVCA9IFtcbiAge1xuICAgIGxhYmVsOiAnTWVzc2FnZSBTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1tZXNzYWdlLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtbWVzc2FnZScsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdUaW1lciBTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC10aW1lci1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LXRpbWVyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb25kaXRpb25hbCBTdGFydCBFdmVudCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb25kaXRpb25hbC1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LWNvbmRpdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnU2lnbmFsIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNpZ25hbC1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LXNpZ25hbCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0Vycm9yIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWVycm9yLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtZXJyb3InLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFcnJvckV2ZW50RGVmaW5pdGlvbidcbiAgICB9XG4gIH0sXG4gIHtcbiAgICBsYWJlbDogJ0VzY2FsYXRpb24gU3RhcnQgRXZlbnQnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZXNjYWxhdGlvbi1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LWVzY2FsYXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJ1xuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnQ29tcGVuc2F0aW9uIFN0YXJ0IEV2ZW50JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbXBlbnNhdGlvbi1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LWNvbXBlbnNhdGlvbicsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpTdGFydEV2ZW50JyxcbiAgICAgIGV2ZW50RGVmaW5pdGlvblR5cGU6ICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdNZXNzYWdlIFN0YXJ0IEV2ZW50IChub24taW50ZXJydXB0aW5nKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub24taW50ZXJydXB0aW5nLW1lc3NhZ2Utc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1ub24taW50ZXJydXB0aW5nLW1lc3NhZ2UnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpNZXNzYWdlRXZlbnREZWZpbml0aW9uJyxcbiAgICAgIGlzSW50ZXJydXB0aW5nOiBmYWxzZVxuICAgIH1cbiAgfSxcbiAge1xuICAgIGxhYmVsOiAnVGltZXIgU3RhcnQgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbi1pbnRlcnJ1cHRpbmctdGltZXItc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1ub24taW50ZXJydXB0aW5nLXRpbWVyJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nLFxuICAgICAgaXNJbnRlcnJ1cHRpbmc6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb25kaXRpb25hbCBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtbm9uLWludGVycnVwdGluZy1jb25kaXRpb25hbC1zdGFydCcsXG4gICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXN0YXJ0LWV2ZW50LW5vbi1pbnRlcnJ1cHRpbmctY29uZGl0aW9uJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnLFxuICAgICAgZXZlbnREZWZpbml0aW9uVHlwZTogJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nLFxuICAgICAgaXNJbnRlcnJ1cHRpbmc6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdTaWduYWwgU3RhcnQgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLW5vbi1pbnRlcnJ1cHRpbmctc2lnbmFsLXN0YXJ0JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tc3RhcnQtZXZlbnQtbm9uLWludGVycnVwdGluZy1zaWduYWwnLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nLFxuICAgICAgaXNJbnRlcnJ1cHRpbmc6IGZhbHNlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdFc2NhbGF0aW9uIFN0YXJ0IEV2ZW50IChub24taW50ZXJydXB0aW5nKScsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1ub24taW50ZXJydXB0aW5nLWVzY2FsYXRpb24tc3RhcnQnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1zdGFydC1ldmVudC1ub24taW50ZXJydXB0aW5nLWVzY2FsYXRpb24nLFxuICAgIHRhcmdldDoge1xuICAgICAgdHlwZTogJ2JwbW46U3RhcnRFdmVudCcsXG4gICAgICBldmVudERlZmluaXRpb25UeXBlOiAnYnBtbjpFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uJyxcbiAgICAgIGlzSW50ZXJydXB0aW5nOiBmYWxzZVxuICAgIH1cbiAgfVxuXTtcblxuZXhwb3J0IHZhciBTRVFVRU5DRV9GTE9XID0gW1xuICB7XG4gICAgbGFiZWw6ICdTZXF1ZW5jZSBGbG93JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLXNlcXVlbmNlLWZsb3cnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jb25uZWN0aW9uJ1xuICB9LFxuICB7XG4gICAgbGFiZWw6ICdEZWZhdWx0IEZsb3cnLFxuICAgIGFjdGlvbk5hbWU6ICdyZXBsYWNlLXdpdGgtZGVmYXVsdC1mbG93JyxcbiAgICBjbGFzc05hbWU6ICdicG1uLWljb24tZGVmYXVsdC1mbG93J1xuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb25kaXRpb25hbCBGbG93JyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWNvbmRpdGlvbmFsLWZsb3cnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jb25kaXRpb25hbC1mbG93J1xuICB9XG5dO1xuXG5leHBvcnQgdmFyIFBBUlRJQ0lQQU5UID0gW1xuICB7XG4gICAgbGFiZWw6ICdFeHBhbmRlZCBQb29sJyxcbiAgICBhY3Rpb25OYW1lOiAncmVwbGFjZS13aXRoLWV4cGFuZGVkLXBvb2wnLFxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1wYXJ0aWNpcGFudCcsXG4gICAgdGFyZ2V0OiB7XG4gICAgICB0eXBlOiAnYnBtbjpQYXJ0aWNpcGFudCcsXG4gICAgICBpc0V4cGFuZGVkOiB0cnVlXG4gICAgfVxuICB9LFxuICB7XG4gICAgbGFiZWw6ICdDb2xsYXBzZWQgUG9vbCcsXG4gICAgYWN0aW9uTmFtZTogJ3JlcGxhY2Utd2l0aC1jb2xsYXBzZWQtcG9vbCcsXG5cbiAgICAvLyBUT0RPKEBqYW5zdHVlbW1lbCk6IG1heWJlIGRlc2lnbiBuZXcgaWNvblxuICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1sYW5lJyxcbiAgICB0YXJnZXQ6IHtcbiAgICAgIHR5cGU6ICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAgIGlzRXhwYW5kZWQ6IGZhbHNlXG4gICAgfVxuICB9XG5dO1xuIiwiaW1wb3J0IENvcHlQYXN0ZU1vZHVsZSBmcm9tICcuLi9jb3B5LXBhc3RlJztcbmltcG9ydCBSZXBsYWNlTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3JlcGxhY2UnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zZWxlY3Rpb24nO1xuXG5pbXBvcnQgQnBtblJlcGxhY2UgZnJvbSAnLi9CcG1uUmVwbGFjZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBDb3B5UGFzdGVNb2R1bGUsXG4gICAgUmVwbGFjZU1vZHVsZSxcbiAgICBTZWxlY3Rpb25Nb2R1bGVcbiAgXSxcbiAgYnBtblJlcGxhY2U6IFsgJ3R5cGUnLCBCcG1uUmVwbGFjZSBdXG59O1xuIiwiaW1wb3J0IHtcbiAgZXZlcnksXG4gIGZpbmQsXG4gIGZvckVhY2gsXG4gIHNvbWVcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQge1xuICBpcyxcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRQYXJlbnQsXG4gIGlzQW55XG59IGZyb20gJy4uL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJztcblxuaW1wb3J0IHtcbiAgaXNMYWJlbFxufSBmcm9tICcuLi8uLi91dGlsL0xhYmVsVXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzRXhwYW5kZWQsXG4gIGlzRXZlbnRTdWJQcm9jZXNzLFxuICBpc0ludGVycnVwdGluZyxcbiAgaGFzRXJyb3JFdmVudERlZmluaXRpb24sXG4gIGhhc0VzY2FsYXRpb25FdmVudERlZmluaXRpb24sXG4gIGhhc0NvbXBlbnNhdGVFdmVudERlZmluaXRpb25cbn0gZnJvbSAnLi4vLi4vdXRpbC9EaVV0aWwnO1xuXG5pbXBvcnQgUnVsZVByb3ZpZGVyIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3J1bGVzL1J1bGVQcm92aWRlcic7XG5cbmltcG9ydCB7XG4gIGdldEJvdW5kYXJ5QXR0YWNobWVudCBhcyBpc0JvdW5kYXJ5QXR0YWNobWVudFxufSBmcm9tICcuLi9zbmFwcGluZy9CcG1uU25hcHBpbmdVdGlsJztcblxuXG4vKipcbiAqIEJQTU4gc3BlY2lmaWMgbW9kZWxpbmcgcnVsZVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBCcG1uUnVsZXMoZXZlbnRCdXMpIHtcbiAgUnVsZVByb3ZpZGVyLmNhbGwodGhpcywgZXZlbnRCdXMpO1xufVxuXG5pbmhlcml0cyhCcG1uUnVsZXMsIFJ1bGVQcm92aWRlcik7XG5cbkJwbW5SdWxlcy4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge1xuXG4gIHRoaXMuYWRkUnVsZSgnY29ubmVjdGlvbi5zdGFydCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgc291cmNlID0gY29udGV4dC5zb3VyY2U7XG5cbiAgICByZXR1cm4gY2FuU3RhcnRDb25uZWN0aW9uKHNvdXJjZSk7XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnY29ubmVjdGlvbi5jcmVhdGUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICB0YXJnZXRQYXJlbnQgPSBoaW50cy50YXJnZXRQYXJlbnQsXG4gICAgICAgIHRhcmdldEF0dGFjaCA9IGhpbnRzLnRhcmdldEF0dGFjaDtcblxuICAgIC8vIGRvbid0IGFsbG93IGluY29taW5nIGNvbm5lY3Rpb25zIG9uXG4gICAgLy8gbmV3bHkgY3JlYXRlZCBib3VuZGFyeSBldmVudHNcbiAgICAvLyB0byBib3VuZGFyeSBldmVudHNcbiAgICBpZiAodGFyZ2V0QXR0YWNoKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gdGVtcG9yYXJpbHkgc2V0IHRhcmdldCBwYXJlbnQgZm9yIHNjb3BpbmdcbiAgICAvLyBjaGVja3MgdG8gd29ya1xuICAgIGlmICh0YXJnZXRQYXJlbnQpIHtcbiAgICAgIHRhcmdldC5wYXJlbnQgPSB0YXJnZXRQYXJlbnQ7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBjYW5Db25uZWN0KHNvdXJjZSwgdGFyZ2V0KTtcbiAgICB9IGZpbmFsbHkge1xuXG4gICAgICAvLyB1bnNldCB0ZW1wb3JhcnkgdGFyZ2V0IHBhcmVudFxuICAgICAgaWYgKHRhcmdldFBhcmVudCkge1xuICAgICAgICB0YXJnZXQucGFyZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0O1xuXG4gICAgcmV0dXJuIGNhbkNvbm5lY3Qoc291cmNlLCB0YXJnZXQsIGNvbm5lY3Rpb24pO1xuICB9KTtcblxuICB0aGlzLmFkZFJ1bGUoJ2Nvbm5lY3Rpb24udXBkYXRlV2F5cG9pbnRzJywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBjb250ZXh0LmNvbm5lY3Rpb24udHlwZVxuICAgIH07XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnc2hhcGUucmVzaXplJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgbmV3Qm91bmRzID0gY29udGV4dC5uZXdCb3VuZHM7XG5cbiAgICByZXR1cm4gY2FuUmVzaXplKHNoYXBlLCBuZXdCb3VuZHMpO1xuICB9KTtcblxuICB0aGlzLmFkZFJ1bGUoJ2VsZW1lbnRzLmNyZWF0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgZWxlbWVudHMgPSBjb250ZXh0LmVsZW1lbnRzLFxuICAgICAgICBwb3NpdGlvbiA9IGNvbnRleHQucG9zaXRpb24sXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0O1xuXG4gICAgcmV0dXJuIGV2ZXJ5KGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICBpZiAoaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICAgIHJldHVybiBjYW5Db25uZWN0KGVsZW1lbnQuc291cmNlLCBlbGVtZW50LnRhcmdldCwgZWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbGVtZW50Lmhvc3QpIHtcbiAgICAgICAgcmV0dXJuIGNhbkF0dGFjaChlbGVtZW50LCBlbGVtZW50Lmhvc3QsIG51bGwsIHBvc2l0aW9uKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNhbkNyZWF0ZShlbGVtZW50LCB0YXJnZXQsIG51bGwsIHBvc2l0aW9uKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgdGhpcy5hZGRSdWxlKCdlbGVtZW50cy5tb3ZlJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgcG9zaXRpb24gPSBjb250ZXh0LnBvc2l0aW9uO1xuXG4gICAgcmV0dXJuIGNhbkF0dGFjaChzaGFwZXMsIHRhcmdldCwgbnVsbCwgcG9zaXRpb24pIHx8XG4gICAgICAgICAgIGNhblJlcGxhY2Uoc2hhcGVzLCB0YXJnZXQsIHBvc2l0aW9uKSB8fFxuICAgICAgICAgICBjYW5Nb3ZlKHNoYXBlcywgdGFyZ2V0LCBwb3NpdGlvbikgfHxcbiAgICAgICAgICAgY2FuSW5zZXJ0KHNoYXBlcywgdGFyZ2V0LCBwb3NpdGlvbik7XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnc2hhcGUuY3JlYXRlJywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHJldHVybiBjYW5DcmVhdGUoXG4gICAgICBjb250ZXh0LnNoYXBlLFxuICAgICAgY29udGV4dC50YXJnZXQsXG4gICAgICBjb250ZXh0LnNvdXJjZSxcbiAgICAgIGNvbnRleHQucG9zaXRpb25cbiAgICApO1xuICB9KTtcblxuICB0aGlzLmFkZFJ1bGUoJ3NoYXBlLmF0dGFjaCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHJldHVybiBjYW5BdHRhY2goXG4gICAgICBjb250ZXh0LnNoYXBlLFxuICAgICAgY29udGV4dC50YXJnZXQsXG4gICAgICBudWxsLFxuICAgICAgY29udGV4dC5wb3NpdGlvblxuICAgICk7XG4gIH0pO1xuXG4gIHRoaXMuYWRkUnVsZSgnZWxlbWVudC5jb3B5JywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHM7XG5cbiAgICByZXR1cm4gY2FuQ29weShlbGVtZW50cywgZWxlbWVudCk7XG4gIH0pO1xufTtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5Db25uZWN0TWVzc2FnZUZsb3cgPSBjYW5Db25uZWN0TWVzc2FnZUZsb3c7XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuY2FuQ29ubmVjdFNlcXVlbmNlRmxvdyA9IGNhbkNvbm5lY3RTZXF1ZW5jZUZsb3c7XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuY2FuQ29ubmVjdERhdGFBc3NvY2lhdGlvbiA9IGNhbkNvbm5lY3REYXRhQXNzb2NpYXRpb247XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuY2FuQ29ubmVjdEFzc29jaWF0aW9uID0gY2FuQ29ubmVjdEFzc29jaWF0aW9uO1xuXG5CcG1uUnVsZXMucHJvdG90eXBlLmNhbk1vdmUgPSBjYW5Nb3ZlO1xuXG5CcG1uUnVsZXMucHJvdG90eXBlLmNhbkF0dGFjaCA9IGNhbkF0dGFjaDtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5SZXBsYWNlID0gY2FuUmVwbGFjZTtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5Ecm9wID0gY2FuRHJvcDtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5JbnNlcnQgPSBjYW5JbnNlcnQ7XG5cbkJwbW5SdWxlcy5wcm90b3R5cGUuY2FuQ3JlYXRlID0gY2FuQ3JlYXRlO1xuXG5CcG1uUnVsZXMucHJvdG90eXBlLmNhbkNvbm5lY3QgPSBjYW5Db25uZWN0O1xuXG5CcG1uUnVsZXMucHJvdG90eXBlLmNhblJlc2l6ZSA9IGNhblJlc2l6ZTtcblxuQnBtblJ1bGVzLnByb3RvdHlwZS5jYW5Db3B5ID0gY2FuQ29weTtcblxuLyoqXG4gKiBVdGlsaXR5IGZ1bmN0aW9ucyBmb3IgcnVsZSBjaGVja2luZ1xuICovXG5cbi8qKlxuICogQ2hlY2tzIGlmIGdpdmVuIGVsZW1lbnQgY2FuIGJlIHVzZWQgZm9yIHN0YXJ0aW5nIGNvbm5lY3Rpb24uXG4gKlxuICogQHBhcmFtICB7RWxlbWVudH0gc291cmNlXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5mdW5jdGlvbiBjYW5TdGFydENvbm5lY3Rpb24oZWxlbWVudCkge1xuICBpZiAobm9uRXhpc3RpbmdPckxhYmVsKGVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gaXNBbnkoZWxlbWVudCwgW1xuICAgICdicG1uOkZsb3dOb2RlJyxcbiAgICAnYnBtbjpJbnRlcmFjdGlvbk5vZGUnLFxuICAgICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnLFxuICAgICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScsXG4gICAgJ2JwbW46R3JvdXAnXG4gIF0pO1xufVxuXG5mdW5jdGlvbiBub25FeGlzdGluZ09yTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gIWVsZW1lbnQgfHwgaXNMYWJlbChlbGVtZW50KTtcbn1cblxuZnVuY3Rpb24gaXNTYW1lKGEsIGIpIHtcbiAgcmV0dXJuIGEgPT09IGI7XG59XG5cbmZ1bmN0aW9uIGdldE9yZ2FuaXphdGlvbmFsUGFyZW50KGVsZW1lbnQpIHtcblxuICBkbyB7XG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSkge1xuICAgICAgcmV0dXJuIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgICByZXR1cm4gKFxuICAgICAgICBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5wcm9jZXNzUmVmIHx8XG4gICAgICAgIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpXG4gICAgICApO1xuICAgIH1cbiAgfSB3aGlsZSAoKGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudCkpO1xuXG59XG5cbmZ1bmN0aW9uIGlzVGV4dEFubm90YXRpb24oZWxlbWVudCkge1xuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46VGV4dEFubm90YXRpb24nKTtcbn1cblxuZnVuY3Rpb24gaXNHcm91cChlbGVtZW50KSB7XG4gIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpHcm91cCcpICYmICFlbGVtZW50LmxhYmVsVGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBpc0NvbXBlbnNhdGlvbkJvdW5kYXJ5KGVsZW1lbnQpIHtcbiAgcmV0dXJuIGlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJlxuICAgICAgICAgaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nKTtcbn1cblxuZnVuY3Rpb24gaXNGb3JDb21wZW5zYXRpb24oZSkge1xuICByZXR1cm4gZ2V0QnVzaW5lc3NPYmplY3QoZSkuaXNGb3JDb21wZW5zYXRpb247XG59XG5cbmZ1bmN0aW9uIGlzU2FtZU9yZ2FuaXphdGlvbihhLCBiKSB7XG4gIHZhciBwYXJlbnRBID0gZ2V0T3JnYW5pemF0aW9uYWxQYXJlbnQoYSksXG4gICAgICBwYXJlbnRCID0gZ2V0T3JnYW5pemF0aW9uYWxQYXJlbnQoYik7XG5cbiAgcmV0dXJuIHBhcmVudEEgPT09IHBhcmVudEI7XG59XG5cbmZ1bmN0aW9uIGlzTWVzc2FnZUZsb3dTb3VyY2UoZWxlbWVudCkge1xuICByZXR1cm4gKFxuICAgIGlzKGVsZW1lbnQsICdicG1uOkludGVyYWN0aW9uTm9kZScpICYmXG4gICAgIWlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJiAoXG4gICAgICAhaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSB8fCAoXG4gICAgICAgIGlzKGVsZW1lbnQsICdicG1uOlRocm93RXZlbnQnKSAmJlxuICAgICAgICBoYXNFdmVudERlZmluaXRpb25Pck5vbmUoZWxlbWVudCwgJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbicpXG4gICAgICApXG4gICAgKVxuICApO1xufVxuXG5mdW5jdGlvbiBpc01lc3NhZ2VGbG93VGFyZ2V0KGVsZW1lbnQpIHtcbiAgcmV0dXJuIChcbiAgICBpcyhlbGVtZW50LCAnYnBtbjpJbnRlcmFjdGlvbk5vZGUnKSAmJlxuICAgICFpc0ZvckNvbXBlbnNhdGlvbihlbGVtZW50KSAmJiAoXG4gICAgICAhaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSB8fCAoXG4gICAgICAgIGlzKGVsZW1lbnQsICdicG1uOkNhdGNoRXZlbnQnKSAmJlxuICAgICAgICBoYXNFdmVudERlZmluaXRpb25Pck5vbmUoZWxlbWVudCwgJ2JwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvbicpXG4gICAgICApXG4gICAgKSAmJiAhKFxuICAgICAgaXMoZWxlbWVudCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmXG4gICAgICAhaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKVxuICAgIClcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2NvcGVQYXJlbnQoZWxlbWVudCkge1xuXG4gIHZhciBwYXJlbnQgPSBlbGVtZW50O1xuXG4gIHdoaWxlICgocGFyZW50ID0gcGFyZW50LnBhcmVudCkpIHtcblxuICAgIGlmIChpcyhwYXJlbnQsICdicG1uOkZsb3dFbGVtZW50c0NvbnRhaW5lcicpKSB7XG4gICAgICByZXR1cm4gZ2V0QnVzaW5lc3NPYmplY3QocGFyZW50KTtcbiAgICB9XG5cbiAgICBpZiAoaXMocGFyZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XG4gICAgICByZXR1cm4gZ2V0QnVzaW5lc3NPYmplY3QocGFyZW50KS5wcm9jZXNzUmVmO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBpc1NhbWVTY29wZShhLCBiKSB7XG4gIHZhciBzY29wZVBhcmVudEEgPSBnZXRTY29wZVBhcmVudChhKSxcbiAgICAgIHNjb3BlUGFyZW50QiA9IGdldFNjb3BlUGFyZW50KGIpO1xuXG4gIHJldHVybiBzY29wZVBhcmVudEEgPT09IHNjb3BlUGFyZW50Qjtcbn1cblxuZnVuY3Rpb24gaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsIGV2ZW50RGVmaW5pdGlvbikge1xuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcblxuICByZXR1cm4gISFmaW5kKGJvLmV2ZW50RGVmaW5pdGlvbnMgfHwgW10sIGZ1bmN0aW9uKGRlZmluaXRpb24pIHtcbiAgICByZXR1cm4gaXMoZGVmaW5pdGlvbiwgZXZlbnREZWZpbml0aW9uKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGhhc0V2ZW50RGVmaW5pdGlvbk9yTm9uZShlbGVtZW50LCBldmVudERlZmluaXRpb24pIHtcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XG5cbiAgcmV0dXJuIChiby5ldmVudERlZmluaXRpb25zIHx8IFtdKS5ldmVyeShmdW5jdGlvbihkZWZpbml0aW9uKSB7XG4gICAgcmV0dXJuIGlzKGRlZmluaXRpb24sIGV2ZW50RGVmaW5pdGlvbik7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBpc1NlcXVlbmNlRmxvd1NvdXJjZShlbGVtZW50KSB7XG4gIHJldHVybiAoXG4gICAgaXMoZWxlbWVudCwgJ2JwbW46Rmxvd05vZGUnKSAmJlxuICAgICFpcyhlbGVtZW50LCAnYnBtbjpFbmRFdmVudCcpICYmXG4gICAgIWlzRXZlbnRTdWJQcm9jZXNzKGVsZW1lbnQpICYmXG4gICAgIShpcyhlbGVtZW50LCAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JykgJiZcbiAgICAgIGhhc0V2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpMaW5rRXZlbnREZWZpbml0aW9uJylcbiAgICApICYmXG4gICAgIWlzQ29tcGVuc2F0aW9uQm91bmRhcnkoZWxlbWVudCkgJiZcbiAgICAhaXNGb3JDb21wZW5zYXRpb24oZWxlbWVudClcbiAgKTtcbn1cblxuZnVuY3Rpb24gaXNTZXF1ZW5jZUZsb3dUYXJnZXQoZWxlbWVudCkge1xuICByZXR1cm4gKFxuICAgIGlzKGVsZW1lbnQsICdicG1uOkZsb3dOb2RlJykgJiZcbiAgICAhaXMoZWxlbWVudCwgJ2JwbW46U3RhcnRFdmVudCcpICYmXG4gICAgIWlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJlxuICAgICFpc0V2ZW50U3ViUHJvY2VzcyhlbGVtZW50KSAmJlxuICAgICEoaXMoZWxlbWVudCwgJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcpICYmXG4gICAgICBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpXG4gICAgKSAmJlxuICAgICFpc0ZvckNvbXBlbnNhdGlvbihlbGVtZW50KVxuICApO1xufVxuXG5mdW5jdGlvbiBpc0V2ZW50QmFzZWRUYXJnZXQoZWxlbWVudCkge1xuICByZXR1cm4gKFxuICAgIGlzKGVsZW1lbnQsICdicG1uOlJlY2VpdmVUYXNrJykgfHwgKFxuICAgICAgaXMoZWxlbWVudCwgJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCcpICYmIChcbiAgICAgICAgaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKSB8fFxuICAgICAgICBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nKSB8fFxuICAgICAgICBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nKSB8fFxuICAgICAgICBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJylcbiAgICAgIClcbiAgICApXG4gICk7XG59XG5cbmZ1bmN0aW9uIGlzQ29ubmVjdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiBlbGVtZW50LndheXBvaW50cztcbn1cblxuZnVuY3Rpb24gZ2V0UGFyZW50cyhlbGVtZW50KSB7XG5cbiAgdmFyIHBhcmVudHMgPSBbXTtcblxuICB3aGlsZSAoZWxlbWVudCkge1xuICAgIGVsZW1lbnQgPSBlbGVtZW50LnBhcmVudDtcblxuICAgIGlmIChlbGVtZW50KSB7XG4gICAgICBwYXJlbnRzLnB1c2goZWxlbWVudCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHBhcmVudHM7XG59XG5cbmZ1bmN0aW9uIGlzUGFyZW50KHBvc3NpYmxlUGFyZW50LCBlbGVtZW50KSB7XG4gIHZhciBhbGxQYXJlbnRzID0gZ2V0UGFyZW50cyhlbGVtZW50KTtcbiAgcmV0dXJuIGFsbFBhcmVudHMuaW5kZXhPZihwb3NzaWJsZVBhcmVudCkgIT09IC0xO1xufVxuXG5mdW5jdGlvbiBjYW5Db25uZWN0KHNvdXJjZSwgdGFyZ2V0LCBjb25uZWN0aW9uKSB7XG5cbiAgaWYgKG5vbkV4aXN0aW5nT3JMYWJlbChzb3VyY2UpIHx8IG5vbkV4aXN0aW5nT3JMYWJlbCh0YXJnZXQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoIWlzKGNvbm5lY3Rpb24sICdicG1uOkRhdGFBc3NvY2lhdGlvbicpKSB7XG5cbiAgICBpZiAoY2FuQ29ubmVjdE1lc3NhZ2VGbG93KHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgICAgcmV0dXJuIHsgdHlwZTogJ2JwbW46TWVzc2FnZUZsb3cnIH07XG4gICAgfVxuXG4gICAgaWYgKGNhbkNvbm5lY3RTZXF1ZW5jZUZsb3coc291cmNlLCB0YXJnZXQpKSB7XG4gICAgICByZXR1cm4geyB0eXBlOiAnYnBtbjpTZXF1ZW5jZUZsb3cnIH07XG4gICAgfVxuICB9XG5cbiAgdmFyIGNvbm5lY3REYXRhQXNzb2NpYXRpb24gPSBjYW5Db25uZWN0RGF0YUFzc29jaWF0aW9uKHNvdXJjZSwgdGFyZ2V0KTtcblxuICBpZiAoY29ubmVjdERhdGFBc3NvY2lhdGlvbikge1xuICAgIHJldHVybiBjb25uZWN0RGF0YUFzc29jaWF0aW9uO1xuICB9XG5cbiAgaWYgKGlzQ29tcGVuc2F0aW9uQm91bmRhcnkoc291cmNlKSAmJiBpc0ZvckNvbXBlbnNhdGlvbih0YXJnZXQpKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdicG1uOkFzc29jaWF0aW9uJyxcbiAgICAgIGFzc29jaWF0aW9uRGlyZWN0aW9uOiAnT25lJ1xuICAgIH07XG4gIH1cblxuICBpZiAoY2FuQ29ubmVjdEFzc29jaWF0aW9uKHNvdXJjZSwgdGFyZ2V0KSkge1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6ICdicG1uOkFzc29jaWF0aW9uJ1xuICAgIH07XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2FuIGFuIGVsZW1lbnQgYmUgZHJvcHBlZCBpbnRvIHRoZSB0YXJnZXQgZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGNhbkRyb3AoZWxlbWVudCwgdGFyZ2V0LCBwb3NpdGlvbikge1xuXG4gIC8vIGNhbiBtb3ZlIGxhYmVscyBhbmQgZ3JvdXBzIGV2ZXJ5d2hlcmVcbiAgaWYgKGlzTGFiZWwoZWxlbWVudCkgfHwgaXNHcm91cChlbGVtZW50KSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cblxuICAvLyBkaXNhbGxvdyB0byBjcmVhdGUgZWxlbWVudHMgb24gY29sbGFwc2VkIHBvb2xzXG4gIGlmIChpcyh0YXJnZXQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgIWlzRXhwYW5kZWQodGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGFsbG93IHRvIGNyZWF0ZSBuZXcgcGFydGljaXBhbnRzIG9uXG4gIC8vIGV4aXN0aW5nIGNvbGxhYm9yYXRpb24gYW5kIHByb2Nlc3MgZGlhZ3JhbXNcbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICByZXR1cm4gaXModGFyZ2V0LCAnYnBtbjpQcm9jZXNzJykgfHwgaXModGFyZ2V0LCAnYnBtbjpDb2xsYWJvcmF0aW9uJyk7XG4gIH1cblxuICAvLyBhbGxvdyBtb3ZpbmcgRGF0YUlucHV0IC8gRGF0YU91dHB1dCB3aXRoaW4gaXRzIG9yaWdpbmFsIGNvbnRhaW5lciBvbmx5XG4gIGlmIChpc0FueShlbGVtZW50LCBbICdicG1uOkRhdGFJbnB1dCcsICdicG1uOkRhdGFPdXRwdXQnIF0pKSB7XG5cbiAgICBpZiAoZWxlbWVudC5wYXJlbnQpIHtcbiAgICAgIHJldHVybiB0YXJnZXQgPT09IGVsZW1lbnQucGFyZW50O1xuICAgIH1cbiAgfVxuXG4gIC8vIGFsbG93IGNyZWF0aW5nIGxhbmVzIG9uIHBhcnRpY2lwYW50cyBhbmQgb3RoZXIgbGFuZXMgb25seVxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46TGFuZScpKSB7XG4gICAgcmV0dXJuIGlzKHRhcmdldCwgJ2JwbW46UGFydGljaXBhbnQnKSB8fCBpcyh0YXJnZXQsICdicG1uOkxhbmUnKTtcbiAgfVxuXG4gIC8vIGRpc2FsbG93IGRyb3BwaW5nIGJvdW5kYXJ5IGV2ZW50cyB3aGljaCBjYW5ub3QgcmVwbGFjZSB3aXRoIGludGVybWVkaWF0ZSBldmVudFxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmICFpc0Ryb3BwYWJsZUJvdW5kYXJ5RXZlbnQoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBkcm9wIGZsb3cgZWxlbWVudHMgb250byBmbG93IGVsZW1lbnQgY29udGFpbmVyc1xuICAvLyBhbmQgcGFydGljaXBhbnRzXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpGbG93RWxlbWVudCcpICYmICFpcyhlbGVtZW50LCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnKSkge1xuICAgIGlmIChpcyh0YXJnZXQsICdicG1uOkZsb3dFbGVtZW50c0NvbnRhaW5lcicpKSB7XG4gICAgICByZXR1cm4gaXNFeHBhbmRlZCh0YXJnZXQpO1xuICAgIH1cblxuICAgIHJldHVybiBpc0FueSh0YXJnZXQsIFsgJ2JwbW46UGFydGljaXBhbnQnLCAnYnBtbjpMYW5lJyBdKTtcbiAgfVxuXG4gIC8vIGFjY291bnQgZm9yIHRoZSBmYWN0IHRoYXQgZGF0YSBhc3NvY2lhdGlvbnMgYXJlIGFsd2F5c1xuICAvLyByZW5kZXJlZCBhbmQgbW92ZWQgdG8gdG9wIChQcm9jZXNzIG9yIENvbGxhYm9yYXRpb24gbGV2ZWwpXG4gIC8vXG4gIC8vIGFydGlmYWN0cyBtYXkgYmUgcGxhY2VkIHdoZXJldmVyLCB0b29cbiAgaWYgKGlzQW55KGVsZW1lbnQsIFsgJ2JwbW46QXJ0aWZhY3QnLCAnYnBtbjpEYXRhQXNzb2NpYXRpb24nLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnIF0pKSB7XG4gICAgcmV0dXJuIGlzQW55KHRhcmdldCwgW1xuICAgICAgJ2JwbW46Q29sbGFib3JhdGlvbicsXG4gICAgICAnYnBtbjpMYW5lJyxcbiAgICAgICdicG1uOlBhcnRpY2lwYW50JyxcbiAgICAgICdicG1uOlByb2Nlc3MnLFxuICAgICAgJ2JwbW46U3ViUHJvY2VzcycgXSk7XG4gIH1cblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46TWVzc2FnZUZsb3cnKSkge1xuICAgIHJldHVybiBpcyh0YXJnZXQsICdicG1uOkNvbGxhYm9yYXRpb24nKVxuICAgICAgfHwgZWxlbWVudC5zb3VyY2UucGFyZW50ID09IHRhcmdldFxuICAgICAgfHwgZWxlbWVudC50YXJnZXQucGFyZW50ID09IHRhcmdldDtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gaXNEcm9wcGFibGVCb3VuZGFyeUV2ZW50KGV2ZW50KSB7XG4gIHJldHVybiBnZXRCdXNpbmVzc09iamVjdChldmVudCkuY2FuY2VsQWN0aXZpdHkgJiYgKFxuICAgIGhhc05vRXZlbnREZWZpbml0aW9uKGV2ZW50KSB8fCBoYXNDb21tb25Cb3VuZGFyeUludGVybWVkaWF0ZUV2ZW50RGVmaW5pdGlvbihldmVudClcbiAgKTtcbn1cblxuZnVuY3Rpb24gaXNCb3VuZGFyeUV2ZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuICFpc0xhYmVsKGVsZW1lbnQpICYmIGlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKTtcbn1cblxuZnVuY3Rpb24gaXNMYW5lKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGlzKGVsZW1lbnQsICdicG1uOkxhbmUnKTtcbn1cblxuLyoqXG4gKiBXZSB0cmVhdCBJbnRlcm1lZGlhdGVUaHJvd0V2ZW50cyBhcyBib3VuZGFyeSBldmVudHMgZHVyaW5nIGNyZWF0ZSxcbiAqIHRoaXMgbXVzdCBiZSByZWZsZWN0ZWQgaW4gdGhlIHJ1bGVzLlxuICovXG5mdW5jdGlvbiBpc0JvdW5kYXJ5Q2FuZGlkYXRlKGVsZW1lbnQpIHtcbiAgaWYgKGlzQm91bmRhcnlFdmVudChlbGVtZW50KSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnKSAmJiBoYXNOb0V2ZW50RGVmaW5pdGlvbihlbGVtZW50KSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIChcbiAgICBpcyhlbGVtZW50LCAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JykgJiZcbiAgICBoYXNDb21tb25Cb3VuZGFyeUludGVybWVkaWF0ZUV2ZW50RGVmaW5pdGlvbihlbGVtZW50KVxuICApO1xufVxuXG5mdW5jdGlvbiBoYXNOb0V2ZW50RGVmaW5pdGlvbihlbGVtZW50KSB7XG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xuXG4gIHJldHVybiBibyAmJiAhKGJvLmV2ZW50RGVmaW5pdGlvbnMgJiYgYm8uZXZlbnREZWZpbml0aW9ucy5sZW5ndGgpO1xufVxuXG5mdW5jdGlvbiBoYXNDb21tb25Cb3VuZGFyeUludGVybWVkaWF0ZUV2ZW50RGVmaW5pdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiBoYXNPbmVPZkV2ZW50RGVmaW5pdGlvbnMoZWxlbWVudCwgW1xuICAgICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nLFxuICAgICdicG1uOlRpbWVyRXZlbnREZWZpbml0aW9uJyxcbiAgICAnYnBtbjpTaWduYWxFdmVudERlZmluaXRpb24nLFxuICAgICdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJ1xuICBdKTtcbn1cblxuZnVuY3Rpb24gaGFzT25lT2ZFdmVudERlZmluaXRpb25zKGVsZW1lbnQsIGV2ZW50RGVmaW5pdGlvbnMpIHtcbiAgcmV0dXJuIGV2ZW50RGVmaW5pdGlvbnMuc29tZShmdW5jdGlvbihkZWZpbml0aW9uKSB7XG4gICAgcmV0dXJuIGhhc0V2ZW50RGVmaW5pdGlvbihlbGVtZW50LCBkZWZpbml0aW9uKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzUmVjZWl2ZVRhc2tBZnRlckV2ZW50QmFzZWRHYXRld2F5KGVsZW1lbnQpIHtcbiAgcmV0dXJuIChcbiAgICBpcyhlbGVtZW50LCAnYnBtbjpSZWNlaXZlVGFzaycpICYmXG4gICAgZmluZChlbGVtZW50LmluY29taW5nLCBmdW5jdGlvbihpbmNvbWluZykge1xuICAgICAgcmV0dXJuIGlzKGluY29taW5nLnNvdXJjZSwgJ2JwbW46RXZlbnRCYXNlZEdhdGV3YXknKTtcbiAgICB9KVxuICApO1xufVxuXG5cbmZ1bmN0aW9uIGNhbkF0dGFjaChlbGVtZW50cywgdGFyZ2V0LCBzb3VyY2UsIHBvc2l0aW9uKSB7XG5cbiAgaWYgKCFBcnJheS5pc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gWyBlbGVtZW50cyBdO1xuICB9XG5cbiAgLy8gb25seSAocmUtKWF0dGFjaCBvbmUgZWxlbWVudCBhdCBhIHRpbWVcbiAgaWYgKGVsZW1lbnRzLmxlbmd0aCAhPT0gMSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHZhciBlbGVtZW50ID0gZWxlbWVudHNbMF07XG5cbiAgLy8gZG8gbm90IGF0dGFjaCBsYWJlbHNcbiAgaWYgKGlzTGFiZWwoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBvbmx5IGhhbmRsZSBib3VuZGFyeSBldmVudHNcbiAgaWYgKCFpc0JvdW5kYXJ5Q2FuZGlkYXRlKGVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gZGlzYWxsb3cgZHJvcCBvbiBldmVudCBzdWIgcHJvY2Vzc2VzXG4gIGlmIChpc0V2ZW50U3ViUHJvY2Vzcyh0YXJnZXQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gb25seSBhbGxvdyBkcm9wIG9uIG5vbiBjb21wZW5zYXRpb24gYWN0aXZpdGllc1xuICBpZiAoIWlzKHRhcmdldCwgJ2JwbW46QWN0aXZpdHknKSB8fCBpc0ZvckNvbXBlbnNhdGlvbih0YXJnZXQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gb25seSBhdHRhY2ggdG8gc3VicHJvY2VzcyBib3JkZXJcbiAgaWYgKHBvc2l0aW9uICYmICFpc0JvdW5kYXJ5QXR0YWNobWVudChwb3NpdGlvbiwgdGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGRvIG5vdCBhdHRhY2ggb24gcmVjZWl2ZSB0YXNrcyBhZnRlciBldmVudCBiYXNlZCBnYXRld2F5c1xuICBpZiAoaXNSZWNlaXZlVGFza0FmdGVyRXZlbnRCYXNlZEdhdGV3YXkodGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiAnYXR0YWNoJztcbn1cblxuXG4vKipcbiAqIERlZmluZXMgaG93IHRvIHJlcGxhY2UgZWxlbWVudHMgZm9yIGEgZ2l2ZW4gdGFyZ2V0LlxuICpcbiAqIFJldHVybnMgYW4gYXJyYXkgY29udGFpbmluZyBhbGwgZWxlbWVudHMgd2hpY2ggd2lsbCBiZSByZXBsYWNlZC5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqICBbeyBpZDogJ0ludGVybWVkaWF0ZUV2ZW50XzInLFxuICogICAgIHR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnXG4gKiAgIH0sXG4gKiAgIHsgaWQ6ICdJbnRlcm1lZGlhdGVFdmVudF81JyxcbiAqICAgICB0eXBlOiAnYnBtbjpFbmRFdmVudCdcbiAqICAgfV1cbiAqXG4gKiBAcGFyYW0gIHtBcnJheX0gZWxlbWVudHNcbiAqIEBwYXJhbSAge09iamVjdH0gdGFyZ2V0XG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBhbiBvYmplY3QgY29udGFpbmluZyBhbGwgZWxlbWVudHMgd2hpY2ggaGF2ZSB0byBiZSByZXBsYWNlZFxuICovXG5mdW5jdGlvbiBjYW5SZXBsYWNlKGVsZW1lbnRzLCB0YXJnZXQsIHBvc2l0aW9uKSB7XG5cbiAgaWYgKCF0YXJnZXQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB2YXIgY2FuRXhlY3V0ZSA9IHtcbiAgICByZXBsYWNlbWVudHM6IFtdXG4gIH07XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgaWYgKCFpc0V2ZW50U3ViUHJvY2Vzcyh0YXJnZXQpKSB7XG5cbiAgICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpTdGFydEV2ZW50JykgJiZcbiAgICAgICAgICBlbGVtZW50LnR5cGUgIT09ICdsYWJlbCcgJiZcbiAgICAgICAgICBjYW5Ecm9wKGVsZW1lbnQsIHRhcmdldCkpIHtcblxuICAgICAgICAvLyByZXBsYWNlIGEgbm9uLWludGVycnVwdGluZyBzdGFydCBldmVudCBieSBhIGJsYW5rIGludGVycnVwdGluZyBzdGFydCBldmVudFxuICAgICAgICAvLyB3aGVuIHRoZSB0YXJnZXQgaXMgbm90IGFuIGV2ZW50IHN1YiBwcm9jZXNzXG4gICAgICAgIGlmICghaXNJbnRlcnJ1cHRpbmcoZWxlbWVudCkpIHtcbiAgICAgICAgICBjYW5FeGVjdXRlLnJlcGxhY2VtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIG9sZEVsZW1lbnRJZDogZWxlbWVudC5pZCxcbiAgICAgICAgICAgIG5ld0VsZW1lbnRUeXBlOiAnYnBtbjpTdGFydEV2ZW50J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVwbGFjZSBhbiBlcnJvci9lc2NhbGF0aW9uL2NvbXBlbnNhdGUgc3RhcnQgZXZlbnQgYnkgYSBibGFuayBpbnRlcnJ1cHRpbmcgc3RhcnQgZXZlbnRcbiAgICAgICAgLy8gd2hlbiB0aGUgdGFyZ2V0IGlzIG5vdCBhbiBldmVudCBzdWIgcHJvY2Vzc1xuICAgICAgICBpZiAoaGFzRXJyb3JFdmVudERlZmluaXRpb24oZWxlbWVudCkgfHxcbiAgICAgICAgICAgIGhhc0VzY2FsYXRpb25FdmVudERlZmluaXRpb24oZWxlbWVudCkgfHxcbiAgICAgICAgICAgIGhhc0NvbXBlbnNhdGVFdmVudERlZmluaXRpb24oZWxlbWVudCkpIHtcbiAgICAgICAgICBjYW5FeGVjdXRlLnJlcGxhY2VtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIG9sZEVsZW1lbnRJZDogZWxlbWVudC5pZCxcbiAgICAgICAgICAgIG5ld0VsZW1lbnRUeXBlOiAnYnBtbjpTdGFydEV2ZW50J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVwbGFjZSBhIHR5cGVkIHN0YXJ0IGV2ZW50IGJ5IGEgYmxhbmsgaW50ZXJydXB0aW5nIHN0YXJ0IGV2ZW50XG4gICAgICAgIC8vIHdoZW4gdGhlIHRhcmdldCBpcyBhIHN1YiBwcm9jZXNzIGJ1dCBub3QgYW4gZXZlbnQgc3ViIHByb2Nlc3NcbiAgICAgICAgaWYgKGhhc09uZU9mRXZlbnREZWZpbml0aW9ucyhlbGVtZW50LFxuICAgICAgICAgIFtcbiAgICAgICAgICAgICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nLFxuICAgICAgICAgICAgJ2JwbW46VGltZXJFdmVudERlZmluaXRpb24nLFxuICAgICAgICAgICAgJ2JwbW46U2lnbmFsRXZlbnREZWZpbml0aW9uJyxcbiAgICAgICAgICAgICdicG1uOkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uJ1xuICAgICAgICAgIF0pICYmXG4gICAgICAgICAgICBpcyh0YXJnZXQsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuICAgICAgICAgIGNhbkV4ZWN1dGUucmVwbGFjZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgb2xkRWxlbWVudElkOiBlbGVtZW50LmlkLFxuICAgICAgICAgICAgbmV3RWxlbWVudFR5cGU6ICdicG1uOlN0YXJ0RXZlbnQnXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIWlzKHRhcmdldCwgJ2JwbW46VHJhbnNhY3Rpb24nKSkge1xuICAgICAgaWYgKGhhc0V2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpDYW5jZWxFdmVudERlZmluaXRpb24nKSAmJlxuICAgICAgICAgIGVsZW1lbnQudHlwZSAhPT0gJ2xhYmVsJykge1xuXG4gICAgICAgIGlmIChpcyhlbGVtZW50LCAnYnBtbjpFbmRFdmVudCcpICYmIGNhbkRyb3AoZWxlbWVudCwgdGFyZ2V0KSkge1xuICAgICAgICAgIGNhbkV4ZWN1dGUucmVwbGFjZW1lbnRzLnB1c2goe1xuICAgICAgICAgICAgb2xkRWxlbWVudElkOiBlbGVtZW50LmlkLFxuICAgICAgICAgICAgbmV3RWxlbWVudFR5cGU6ICdicG1uOkVuZEV2ZW50J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJiBjYW5BdHRhY2goZWxlbWVudCwgdGFyZ2V0LCBudWxsLCBwb3NpdGlvbikpIHtcbiAgICAgICAgICBjYW5FeGVjdXRlLnJlcGxhY2VtZW50cy5wdXNoKHtcbiAgICAgICAgICAgIG9sZEVsZW1lbnRJZDogZWxlbWVudC5pZCxcbiAgICAgICAgICAgIG5ld0VsZW1lbnRUeXBlOiAnYnBtbjpCb3VuZGFyeUV2ZW50J1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gY2FuRXhlY3V0ZS5yZXBsYWNlbWVudHMubGVuZ3RoID8gY2FuRXhlY3V0ZSA6IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjYW5Nb3ZlKGVsZW1lbnRzLCB0YXJnZXQpIHtcblxuICAvLyBkbyBub3QgbW92ZSBzZWxlY3Rpb24gY29udGFpbmluZyBsYW5lc1xuICBpZiAoc29tZShlbGVtZW50cywgaXNMYW5lKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGFsbG93IGRlZmF1bHQgbW92ZSBjaGVjayB0byBzdGFydCBtb3ZlIG9wZXJhdGlvblxuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnRzLmV2ZXJ5KGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gY2FuRHJvcChlbGVtZW50LCB0YXJnZXQpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY2FuQ3JlYXRlKHNoYXBlLCB0YXJnZXQsIHNvdXJjZSwgcG9zaXRpb24pIHtcblxuICBpZiAoIXRhcmdldCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChpc0xhYmVsKHNoYXBlKSB8fCBpc0dyb3VwKHNoYXBlKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGlzU2FtZShzb3VyY2UsIHRhcmdldCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyBlbnN1cmUgd2UgZG8gbm90IGRyb3AgdGhlIGVsZW1lbnRcbiAgLy8gaW50byBzb3VyY2VcbiAgaWYgKHNvdXJjZSAmJiBpc1BhcmVudChzb3VyY2UsIHRhcmdldCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gY2FuRHJvcChzaGFwZSwgdGFyZ2V0LCBwb3NpdGlvbikgfHwgY2FuSW5zZXJ0KHNoYXBlLCB0YXJnZXQsIHBvc2l0aW9uKTtcbn1cblxuZnVuY3Rpb24gY2FuUmVzaXplKHNoYXBlLCBuZXdCb3VuZHMpIHtcbiAgaWYgKGlzKHNoYXBlLCAnYnBtbjpTdWJQcm9jZXNzJykpIHtcbiAgICByZXR1cm4gKFxuICAgICAgaXNFeHBhbmRlZChzaGFwZSkgJiYgKFxuICAgICAgICAhbmV3Qm91bmRzIHx8IChuZXdCb3VuZHMud2lkdGggPj0gMTAwICYmIG5ld0JvdW5kcy5oZWlnaHQgPj0gODApXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIGlmIChpcyhzaGFwZSwgJ2JwbW46TGFuZScpKSB7XG4gICAgcmV0dXJuICFuZXdCb3VuZHMgfHwgKG5ld0JvdW5kcy53aWR0aCA+PSAxMzAgJiYgbmV3Qm91bmRzLmhlaWdodCA+PSA2MCk7XG4gIH1cblxuICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykpIHtcbiAgICByZXR1cm4gIW5ld0JvdW5kcyB8fCAobmV3Qm91bmRzLndpZHRoID49IDI1MCAmJiBuZXdCb3VuZHMuaGVpZ2h0ID49IDUwKTtcbiAgfVxuXG4gIGlmIChpc1RleHRBbm5vdGF0aW9uKHNoYXBlKSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGlzR3JvdXAoc2hhcGUpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2hlY2ssIHdoZXRoZXIgb25lIHNpZGUgb2YgdGhlIHJlbGF0aW9uc2hpcFxuICogaXMgYSB0ZXh0IGFubm90YXRpb24uXG4gKi9cbmZ1bmN0aW9uIGlzT25lVGV4dEFubm90YXRpb24oc291cmNlLCB0YXJnZXQpIHtcblxuICB2YXIgc291cmNlVGV4dEFubm90YXRpb24gPSBpc1RleHRBbm5vdGF0aW9uKHNvdXJjZSksXG4gICAgICB0YXJnZXRUZXh0QW5ub3RhdGlvbiA9IGlzVGV4dEFubm90YXRpb24odGFyZ2V0KTtcblxuICByZXR1cm4gKFxuICAgIChzb3VyY2VUZXh0QW5ub3RhdGlvbiB8fCB0YXJnZXRUZXh0QW5ub3RhdGlvbikgJiZcbiAgICAoc291cmNlVGV4dEFubm90YXRpb24gIT09IHRhcmdldFRleHRBbm5vdGF0aW9uKVxuICApO1xufVxuXG5cbmZ1bmN0aW9uIGNhbkNvbm5lY3RBc3NvY2lhdGlvbihzb3VyY2UsIHRhcmdldCkge1xuXG4gIC8vIGRvIG5vdCBjb25uZWN0IGNvbm5lY3Rpb25zXG4gIGlmIChpc0Nvbm5lY3Rpb24oc291cmNlKSB8fCBpc0Nvbm5lY3Rpb24odGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGNvbXBlbnNhdGlvbiBib3VuZGFyeSBldmVudHMgYXJlIGV4Y2VwdGlvblxuICBpZiAoaXNDb21wZW5zYXRpb25Cb3VuZGFyeShzb3VyY2UpICYmIGlzRm9yQ29tcGVuc2F0aW9uKHRhcmdldCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIGRvbid0IGNvbm5lY3QgcGFyZW50IDwtPiBjaGlsZFxuICBpZiAoaXNQYXJlbnQodGFyZ2V0LCBzb3VyY2UpIHx8IGlzUGFyZW50KHNvdXJjZSwgdGFyZ2V0KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGFsbG93IGNvbm5lY3Rpb24gb2YgYXNzb2NpYXRpb25zIGJldHdlZW4gPCFUZXh0QW5ub3RhdGlvbj4gYW5kIDxUZXh0QW5ub3RhdGlvbj5cbiAgaWYgKGlzT25lVGV4dEFubm90YXRpb24oc291cmNlLCB0YXJnZXQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBjYW4gY29ubmVjdCBhc3NvY2lhdGlvbnMgd2hlcmUgd2UgY2FuIGNvbm5lY3RcbiAgLy8gZGF0YSBhc3NvY2lhdGlvbnMsIHRvbyAoISlcbiAgcmV0dXJuICEhY2FuQ29ubmVjdERhdGFBc3NvY2lhdGlvbihzb3VyY2UsIHRhcmdldCk7XG59XG5cbmZ1bmN0aW9uIGNhbkNvbm5lY3RNZXNzYWdlRmxvdyhzb3VyY2UsIHRhcmdldCkge1xuXG4gIC8vIGR1cmluZyBjb25uZWN0IHVzZXIgbWlnaHQgbW92ZSBtb3VzZSBvdXQgb2YgY2FudmFzXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9icG1uLWlvL2JwbW4tanMvaXNzdWVzLzEwMzNcbiAgaWYgKGdldFJvb3RFbGVtZW50KHNvdXJjZSkgJiYgIWdldFJvb3RFbGVtZW50KHRhcmdldCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gKFxuICAgIGlzTWVzc2FnZUZsb3dTb3VyY2Uoc291cmNlKSAmJlxuICAgIGlzTWVzc2FnZUZsb3dUYXJnZXQodGFyZ2V0KSAmJlxuICAgICFpc1NhbWVPcmdhbml6YXRpb24oc291cmNlLCB0YXJnZXQpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNhbkNvbm5lY3RTZXF1ZW5jZUZsb3coc291cmNlLCB0YXJnZXQpIHtcblxuICBpZiAoXG4gICAgaXNFdmVudEJhc2VkVGFyZ2V0KHRhcmdldCkgJiZcbiAgICB0YXJnZXQuaW5jb21pbmcubGVuZ3RoID4gMCAmJlxuICAgIGFyZU91dGdvaW5nRXZlbnRCYXNlZEdhdGV3YXlDb25uZWN0aW9ucyh0YXJnZXQuaW5jb21pbmcpICYmXG4gICAgIWlzKHNvdXJjZSwgJ2JwbW46RXZlbnRCYXNlZEdhdGV3YXknKVxuICApIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gaXNTZXF1ZW5jZUZsb3dTb3VyY2Uoc291cmNlKSAmJlxuICAgICAgICAgaXNTZXF1ZW5jZUZsb3dUYXJnZXQodGFyZ2V0KSAmJlxuICAgICAgICAgaXNTYW1lU2NvcGUoc291cmNlLCB0YXJnZXQpICYmXG4gICAgICAgICAhKGlzKHNvdXJjZSwgJ2JwbW46RXZlbnRCYXNlZEdhdGV3YXknKSAmJiAhaXNFdmVudEJhc2VkVGFyZ2V0KHRhcmdldCkpO1xufVxuXG5cbmZ1bmN0aW9uIGNhbkNvbm5lY3REYXRhQXNzb2NpYXRpb24oc291cmNlLCB0YXJnZXQpIHtcblxuICBpZiAoaXNBbnkoc291cmNlLCBbICdicG1uOkRhdGFPYmplY3RSZWZlcmVuY2UnLCAnYnBtbjpEYXRhU3RvcmVSZWZlcmVuY2UnIF0pICYmXG4gICAgICBpc0FueSh0YXJnZXQsIFsgJ2JwbW46QWN0aXZpdHknLCAnYnBtbjpUaHJvd0V2ZW50JyBdKSkge1xuICAgIHJldHVybiB7IHR5cGU6ICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJyB9O1xuICB9XG5cbiAgaWYgKGlzQW55KHRhcmdldCwgWyAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJywgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJyBdKSAmJlxuICAgICAgaXNBbnkoc291cmNlLCBbICdicG1uOkFjdGl2aXR5JywgJ2JwbW46Q2F0Y2hFdmVudCcgXSkpIHtcbiAgICByZXR1cm4geyB0eXBlOiAnYnBtbjpEYXRhT3V0cHV0QXNzb2NpYXRpb24nIH07XG4gIH1cblxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGNhbkluc2VydChzaGFwZSwgZmxvdywgcG9zaXRpb24pIHtcblxuICBpZiAoIWZsb3cpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAoQXJyYXkuaXNBcnJheShzaGFwZSkpIHtcbiAgICBpZiAoc2hhcGUubGVuZ3RoICE9PSAxKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgc2hhcGUgPSBzaGFwZVswXTtcbiAgfVxuXG4gIGlmIChmbG93LnNvdXJjZSA9PT0gc2hhcGUgfHxcbiAgICAgIGZsb3cudGFyZ2V0ID09PSBzaGFwZSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIHJldHVybiB0cnVlIGlmIHdlIGNhbiBkcm9wIG9uIHRoZVxuICAvLyB1bmRlcmx5aW5nIGZsb3cgcGFyZW50XG4gIC8vXG4gIC8vIGF0IHRoaXMgcG9pbnQgd2UgYXJlIG5vdCByZWFsbHkgYWJsZSB0byB0YWxrXG4gIC8vIGFib3V0IGNvbm5lY3Rpb24gcnVsZXMgKHlldClcblxuICByZXR1cm4gKFxuICAgIGlzQW55KGZsb3csIFsgJ2JwbW46U2VxdWVuY2VGbG93JywgJ2JwbW46TWVzc2FnZUZsb3cnIF0pICYmXG4gICAgIWlzTGFiZWwoZmxvdykgJiZcbiAgICBpcyhzaGFwZSwgJ2JwbW46Rmxvd05vZGUnKSAmJlxuICAgICFpcyhzaGFwZSwgJ2JwbW46Qm91bmRhcnlFdmVudCcpICYmXG4gICAgY2FuRHJvcChzaGFwZSwgZmxvdy5wYXJlbnQsIHBvc2l0aW9uKSk7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVzKGVsZW1lbnRzLCBlbGVtZW50KSB7XG4gIHJldHVybiAoZWxlbWVudHMgJiYgZWxlbWVudCkgJiYgZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGNhbkNvcHkoZWxlbWVudHMsIGVsZW1lbnQpIHtcbiAgaWYgKGlzTGFiZWwoZWxlbWVudCkpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpMYW5lJykgJiYgIWluY2x1ZGVzKGVsZW1lbnRzLCBlbGVtZW50LnBhcmVudCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gaXNPdXRnb2luZ0V2ZW50QmFzZWRHYXRld2F5Q29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG5cbiAgaWYgKGNvbm5lY3Rpb24gJiYgY29ubmVjdGlvbi5zb3VyY2UpIHtcbiAgICByZXR1cm4gaXMoY29ubmVjdGlvbi5zb3VyY2UsICdicG1uOkV2ZW50QmFzZWRHYXRld2F5Jyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYXJlT3V0Z29pbmdFdmVudEJhc2VkR2F0ZXdheUNvbm5lY3Rpb25zKGNvbm5lY3Rpb25zKSB7XG4gIGNvbm5lY3Rpb25zID0gY29ubmVjdGlvbnMgfHwgW107XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb25zLnNvbWUoaXNPdXRnb2luZ0V2ZW50QmFzZWRHYXRld2F5Q29ubmVjdGlvbik7XG59XG5cbmZ1bmN0aW9uIGdldFJvb3RFbGVtZW50KGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFBhcmVudChlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgZ2V0UGFyZW50KGVsZW1lbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKTtcbn1cbiIsImltcG9ydCBSdWxlc01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9ydWxlcyc7XG5cbmltcG9ydCBCcG1uUnVsZXMgZnJvbSAnLi9CcG1uUnVsZXMnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgUnVsZXNNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2JwbW5SdWxlcycgXSxcbiAgYnBtblJ1bGVzOiBbICd0eXBlJywgQnBtblJ1bGVzIF1cbn07XG4iLCJpbXBvcnQge1xuICBtYXAsXG4gIGZpbHRlcixcbiAgc29ydEJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0TGFiZWxcbn0gZnJvbSAnLi4vbGFiZWwtZWRpdGluZy9MYWJlbFV0aWwnO1xuXG5cbi8qKlxuICogUHJvdmlkZXMgYWJpbGl0eSB0byBzZWFyY2ggdGhyb3VnaCBCUE1OIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5TZWFyY2hQcm92aWRlcihlbGVtZW50UmVnaXN0cnksIHNlYXJjaFBhZCwgY2FudmFzKSB7XG5cbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG5cbiAgc2VhcmNoUGFkLnJlZ2lzdGVyUHJvdmlkZXIodGhpcyk7XG59XG5cbkJwbW5TZWFyY2hQcm92aWRlci4kaW5qZWN0ID0gW1xuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ3NlYXJjaFBhZCcsXG4gICdjYW52YXMnXG5dO1xuXG5cbi8qKlxuICogRmluZHMgYWxsIGVsZW1lbnRzIHRoYXQgbWF0Y2ggZ2l2ZW4gcGF0dGVyblxuICpcbiAqIDxSZXN1bHQ+IDpcbiAqICB7XG4gKiAgICBwcmltYXJ5VG9rZW5zOiA8QXJyYXk8VG9rZW4+PixcbiAqICAgIHNlY29uZGFyeVRva2VuczogPEFycmF5PFRva2VuPj4sXG4gKiAgICBlbGVtZW50OiA8RWxlbWVudD5cbiAqICB9XG4gKlxuICogPFRva2VuPiA6XG4gKiAge1xuICogICAgbm9ybWFsfG1hdGNoZWQ6IDxzdHJpbmc+XG4gKiAgfVxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gcGF0dGVyblxuICogQHJldHVybiB7QXJyYXk8UmVzdWx0Pn1cbiAqL1xuQnBtblNlYXJjaFByb3ZpZGVyLnByb3RvdHlwZS5maW5kID0gZnVuY3Rpb24ocGF0dGVybikge1xuICB2YXIgcm9vdEVsZW1lbnQgPSB0aGlzLl9jYW52YXMuZ2V0Um9vdEVsZW1lbnQoKTtcblxuICB2YXIgZWxlbWVudHMgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZmlsdGVyKGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBpZiAoZWxlbWVudC5sYWJlbFRhcmdldCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSk7XG5cbiAgLy8gZG8gbm90IGluY2x1ZGUgcm9vdCBlbGVtZW50XG4gIGVsZW1lbnRzID0gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQgIT09IHJvb3RFbGVtZW50O1xuICB9KTtcblxuICBlbGVtZW50cyA9IG1hcChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHJldHVybiB7XG4gICAgICBwcmltYXJ5VG9rZW5zOiBtYXRjaEFuZFNwbGl0KGdldExhYmVsKGVsZW1lbnQpLCBwYXR0ZXJuKSxcbiAgICAgIHNlY29uZGFyeVRva2VuczogbWF0Y2hBbmRTcGxpdChlbGVtZW50LmlkLCBwYXR0ZXJuKSxcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnRcbiAgICB9O1xuICB9KTtcblxuICAvLyBleGNsdWRlIG5vbi1tYXRjaGVkIGVsZW1lbnRzXG4gIGVsZW1lbnRzID0gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGhhc01hdGNoZWQoZWxlbWVudC5wcmltYXJ5VG9rZW5zKSB8fCBoYXNNYXRjaGVkKGVsZW1lbnQuc2Vjb25kYXJ5VG9rZW5zKTtcbiAgfSk7XG5cbiAgZWxlbWVudHMgPSBzb3J0QnkoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gZ2V0TGFiZWwoZWxlbWVudC5lbGVtZW50KSArIGVsZW1lbnQuZWxlbWVudC5pZDtcbiAgfSk7XG5cbiAgcmV0dXJuIGVsZW1lbnRzO1xufTtcblxuXG5mdW5jdGlvbiBoYXNNYXRjaGVkKHRva2Vucykge1xuICB2YXIgbWF0Y2hlZCA9IGZpbHRlcih0b2tlbnMsIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gISF0Lm1hdGNoZWQ7XG4gIH0pO1xuXG4gIHJldHVybiBtYXRjaGVkLmxlbmd0aCA+IDA7XG59XG5cblxuZnVuY3Rpb24gbWF0Y2hBbmRTcGxpdCh0ZXh0LCBwYXR0ZXJuKSB7XG4gIHZhciB0b2tlbnMgPSBbXSxcbiAgICAgIG9yaWdpbmFsVGV4dCA9IHRleHQ7XG5cbiAgaWYgKCF0ZXh0KSB7XG4gICAgcmV0dXJuIHRva2VucztcbiAgfVxuXG4gIHRleHQgPSB0ZXh0LnRvTG93ZXJDYXNlKCk7XG4gIHBhdHRlcm4gPSBwYXR0ZXJuLnRvTG93ZXJDYXNlKCk7XG5cbiAgdmFyIGkgPSB0ZXh0LmluZGV4T2YocGF0dGVybik7XG5cbiAgaWYgKGkgPiAtMSkge1xuICAgIGlmIChpICE9PSAwKSB7XG4gICAgICB0b2tlbnMucHVzaCh7XG4gICAgICAgIG5vcm1hbDogb3JpZ2luYWxUZXh0LnN1YnN0cigwLCBpKVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgdG9rZW5zLnB1c2goe1xuICAgICAgbWF0Y2hlZDogb3JpZ2luYWxUZXh0LnN1YnN0cihpLCBwYXR0ZXJuLmxlbmd0aClcbiAgICB9KTtcblxuICAgIGlmIChwYXR0ZXJuLmxlbmd0aCArIGkgPCB0ZXh0Lmxlbmd0aCkge1xuICAgICAgdG9rZW5zLnB1c2goe1xuICAgICAgICBub3JtYWw6IG9yaWdpbmFsVGV4dC5zdWJzdHIocGF0dGVybi5sZW5ndGggKyBpLCB0ZXh0Lmxlbmd0aClcbiAgICAgIH0pO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICB0b2tlbnMucHVzaCh7XG4gICAgICBub3JtYWw6IG9yaWdpbmFsVGV4dFxuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHRva2Vucztcbn0iLCJpbXBvcnQgU2VhcmNoUGFkTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NlYXJjaC1wYWQnO1xuXG5pbXBvcnQgQnBtblNlYXJjaFByb3ZpZGVyIGZyb20gJy4vQnBtblNlYXJjaFByb3ZpZGVyJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgU2VhcmNoUGFkTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdicG1uU2VhcmNoJ10sXG4gIGJwbW5TZWFyY2g6IFsgJ3R5cGUnLCBCcG1uU2VhcmNoUHJvdmlkZXIgXVxufTtcbiIsImltcG9ydCB7XHJcbiAgbWlkLFxyXG4gIHNldFNuYXBwZWRcclxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0NtZCB9IGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2tleWJvYXJkL0tleWJvYXJkVXRpbCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIGdldE9yaWVudGF0aW9uXHJcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xyXG5cclxuaW1wb3J0IHsgaXMgfSBmcm9tICcuLi8uLi91dGlsL01vZGVsVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0FueSB9IGZyb20gJy4uL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJztcclxuXHJcbmltcG9ydCB7IHNvbWUgfSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG52YXIgSElHSEVSX1BSSU9SSVRZID0gMTI1MDtcclxuXHJcbnZhciBCT1VOREFSWV9UT19IT1NUX1RIUkVTSE9MRCA9IDQwO1xyXG5cclxudmFyIFRBUkdFVF9CT1VORFNfUEFERElORyA9IDIwLFxyXG4gICAgVEFTS19CT1VORFNfUEFERElORyA9IDEwO1xyXG5cclxudmFyIFRBUkdFVF9DRU5URVJfUEFERElORyA9IDIwO1xyXG5cclxudmFyIEFYRVMgPSBbICd4JywgJ3knIF07XHJcblxyXG52YXIgYWJzID0gTWF0aC5hYnM7XHJcblxyXG4vKipcclxuICogU25hcCBkdXJpbmcgY29ubmVjdC5cclxuICpcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJwbW5Db25uZWN0U25hcHBpbmcoZXZlbnRCdXMpIHtcclxuICBldmVudEJ1cy5vbihbXHJcbiAgICAnY29ubmVjdC5ob3ZlcicsXHJcbiAgICAnY29ubmVjdC5tb3ZlJyxcclxuICAgICdjb25uZWN0LmVuZCcsXHJcbiAgXSwgSElHSEVSX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIGNhbkV4ZWN1dGUgPSBjb250ZXh0LmNhbkV4ZWN1dGUsXHJcbiAgICAgICAgc3RhcnQgPSBjb250ZXh0LnN0YXJ0LFxyXG4gICAgICAgIGhvdmVyID0gY29udGV4dC5ob3ZlcixcclxuICAgICAgICBzb3VyY2UgPSBjb250ZXh0LnNvdXJjZSxcclxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcclxuXHJcbiAgICAvLyBkbyBOT1Qgc25hcCBvbiBDTURcclxuICAgIGlmIChldmVudC5vcmlnaW5hbEV2ZW50ICYmIGlzQ21kKGV2ZW50Lm9yaWdpbmFsRXZlbnQpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWNvbnRleHQuaW5pdGlhbENvbm5lY3Rpb25TdGFydCkge1xyXG4gICAgICBjb250ZXh0LmluaXRpYWxDb25uZWN0aW9uU3RhcnQgPSBjb250ZXh0LmNvbm5lY3Rpb25TdGFydDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBzbmFwIGhvdmVyXHJcbiAgICBpZiAoY2FuRXhlY3V0ZSAmJiBob3Zlcikge1xyXG4gICAgICBzbmFwVG9TaGFwZShldmVudCwgaG92ZXIsIGdldFRhcmdldEJvdW5kc1BhZGRpbmcoaG92ZXIpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaG92ZXIgJiYgaXNBbnlUeXBlKGNhbkV4ZWN1dGUsIFtcclxuICAgICAgJ2JwbW46QXNzb2NpYXRpb24nLFxyXG4gICAgICAnYnBtbjpEYXRhSW5wdXRBc3NvY2lhdGlvbicsXHJcbiAgICAgICdicG1uOkRhdGFPdXRwdXRBc3NvY2lhdGlvbicsXHJcbiAgICAgICdicG1uOlNlcXVlbmNlRmxvdydcclxuICAgIF0pKSB7XHJcbiAgICAgIGNvbnRleHQuY29ubmVjdGlvblN0YXJ0ID0gbWlkKHN0YXJ0KTtcclxuXHJcbiAgICAgIC8vIHNuYXAgaG92ZXJcclxuICAgICAgaWYgKGlzQW55KGhvdmVyLCBbICdicG1uOkV2ZW50JywgJ2JwbW46R2F0ZXdheScgXSkpIHtcclxuICAgICAgICBzbmFwVG9Qb3NpdGlvbihldmVudCwgbWlkKGhvdmVyKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHNuYXAgaG92ZXJcclxuICAgICAgaWYgKGlzQW55KGhvdmVyLCBbICdicG1uOlRhc2snLCAnYnBtbjpTdWJQcm9jZXNzJyBdKSkge1xyXG4gICAgICAgIHNuYXBUb1RhcmdldE1pZChldmVudCwgaG92ZXIpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBzbmFwIHNvdXJjZSBhbmQgdGFyZ2V0XHJcbiAgICAgIGlmIChpcyhzb3VyY2UsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSAmJiB0YXJnZXQgPT09IHNvdXJjZS5ob3N0KSB7XHJcbiAgICAgICAgc25hcEJvdW5kYXJ5RXZlbnRMb29wKGV2ZW50KTtcclxuICAgICAgfVxyXG5cclxuICAgIH0gZWxzZSBpZiAoaXNUeXBlKGNhbkV4ZWN1dGUsICdicG1uOk1lc3NhZ2VGbG93JykpIHtcclxuXHJcbiAgICAgIGlmIChpcyhzdGFydCwgJ2JwbW46RXZlbnQnKSkge1xyXG5cclxuICAgICAgICAvLyBzbmFwIHN0YXJ0XHJcbiAgICAgICAgY29udGV4dC5jb25uZWN0aW9uU3RhcnQgPSBtaWQoc3RhcnQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXMoaG92ZXIsICdicG1uOkV2ZW50JykpIHtcclxuXHJcbiAgICAgICAgLy8gc25hcCBob3ZlclxyXG4gICAgICAgIHNuYXBUb1Bvc2l0aW9uKGV2ZW50LCBtaWQoaG92ZXIpKTtcclxuICAgICAgfVxyXG5cclxuICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAvLyB1bi1zbmFwIHNvdXJjZVxyXG4gICAgICBjb250ZXh0LmNvbm5lY3Rpb25TdGFydCA9IGNvbnRleHQuaW5pdGlhbENvbm5lY3Rpb25TdGFydDtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuQnBtbkNvbm5lY3RTbmFwcGluZy4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07XHJcblxyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG4vLyBzbmFwIHRvIHRhcmdldCBpZiBldmVudCBpbiB0YXJnZXRcclxuZnVuY3Rpb24gc25hcFRvU2hhcGUoZXZlbnQsIHRhcmdldCwgcGFkZGluZykge1xyXG4gIEFYRVMuZm9yRWFjaChmdW5jdGlvbihheGlzKSB7XHJcbiAgICB2YXIgZGltZW5zaW9uRm9yQXhpcyA9IGdldERpbWVuc2lvbkZvckF4aXMoYXhpcywgdGFyZ2V0KTtcclxuXHJcbiAgICBpZiAoZXZlbnRbIGF4aXMgXSA8IHRhcmdldFsgYXhpcyBdICsgcGFkZGluZykge1xyXG4gICAgICBzZXRTbmFwcGVkKGV2ZW50LCBheGlzLCB0YXJnZXRbIGF4aXMgXSArIHBhZGRpbmcpO1xyXG4gICAgfSBlbHNlIGlmIChldmVudFsgYXhpcyBdID4gdGFyZ2V0WyBheGlzIF0gKyBkaW1lbnNpb25Gb3JBeGlzIC0gcGFkZGluZykge1xyXG4gICAgICBzZXRTbmFwcGVkKGV2ZW50LCBheGlzLCB0YXJnZXRbIGF4aXMgXSArIGRpbWVuc2lvbkZvckF4aXMgLSBwYWRkaW5nKTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuLy8gc25hcCB0byB0YXJnZXQgbWlkIGlmIGV2ZW50IGluIHRhcmdldCBtaWRcclxuZnVuY3Rpb24gc25hcFRvVGFyZ2V0TWlkKGV2ZW50LCB0YXJnZXQpIHtcclxuICB2YXIgdGFyZ2V0TWlkID0gbWlkKHRhcmdldCk7XHJcblxyXG4gIEFYRVMuZm9yRWFjaChmdW5jdGlvbihheGlzKSB7XHJcbiAgICBpZiAoaXNNaWQoZXZlbnQsIHRhcmdldCwgYXhpcykpIHtcclxuICAgICAgc2V0U25hcHBlZChldmVudCwgYXhpcywgdGFyZ2V0TWlkWyBheGlzIF0pO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG4vLyBzbmFwIHRvIHByZXZlbnQgbG9vcCBvdmVybGFwcGluZyBib3VuZGFyeSBldmVudFxyXG5mdW5jdGlvbiBzbmFwQm91bmRhcnlFdmVudExvb3AoZXZlbnQpIHtcclxuICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxyXG4gICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcclxuXHJcbiAgaWYgKGlzUmV2ZXJzZShjb250ZXh0KSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIHNvdXJjZU1pZCA9IG1pZChzb3VyY2UpLFxyXG4gICAgICBvcmllbnRhdGlvbiA9IGdldE9yaWVudGF0aW9uKHNvdXJjZU1pZCwgdGFyZ2V0LCAtMTApLFxyXG4gICAgICBheGVzID0gW107XHJcblxyXG4gIGlmICgvdG9wfGJvdHRvbS8udGVzdChvcmllbnRhdGlvbikpIHtcclxuICAgIGF4ZXMucHVzaCgneCcpO1xyXG4gIH1cclxuXHJcbiAgaWYgKC9sZWZ0fHJpZ2h0Ly50ZXN0KG9yaWVudGF0aW9uKSkge1xyXG4gICAgYXhlcy5wdXNoKCd5Jyk7XHJcbiAgfVxyXG5cclxuICBheGVzLmZvckVhY2goZnVuY3Rpb24oYXhpcykge1xyXG4gICAgdmFyIGNvb3JkaW5hdGUgPSBldmVudFsgYXhpcyBdLCBuZXdDb29yZGluYXRlO1xyXG5cclxuICAgIGlmIChhYnMoY29vcmRpbmF0ZSAtIHNvdXJjZU1pZFsgYXhpcyBdKSA8IEJPVU5EQVJZX1RPX0hPU1RfVEhSRVNIT0xEKSB7XHJcbiAgICAgIGlmIChjb29yZGluYXRlID4gc291cmNlTWlkWyBheGlzIF0pIHtcclxuICAgICAgICBuZXdDb29yZGluYXRlID0gc291cmNlTWlkWyBheGlzIF0gKyBCT1VOREFSWV9UT19IT1NUX1RIUkVTSE9MRDtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICBuZXdDb29yZGluYXRlID0gc291cmNlTWlkWyBheGlzIF0gLSBCT1VOREFSWV9UT19IT1NUX1RIUkVTSE9MRDtcclxuICAgICAgfVxyXG5cclxuICAgICAgc2V0U25hcHBlZChldmVudCwgYXhpcywgbmV3Q29vcmRpbmF0ZSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHNuYXBUb1Bvc2l0aW9uKGV2ZW50LCBwb3NpdGlvbikge1xyXG4gIHNldFNuYXBwZWQoZXZlbnQsICd4JywgcG9zaXRpb24ueCk7XHJcbiAgc2V0U25hcHBlZChldmVudCwgJ3knLCBwb3NpdGlvbi55KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNUeXBlKGF0dHJzLCB0eXBlKSB7XHJcbiAgcmV0dXJuIGF0dHJzICYmIGF0dHJzLnR5cGUgPT09IHR5cGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzQW55VHlwZShhdHRycywgdHlwZXMpIHtcclxuICByZXR1cm4gc29tZSh0eXBlcywgZnVuY3Rpb24odHlwZSkge1xyXG4gICAgcmV0dXJuIGlzVHlwZShhdHRycywgdHlwZSk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldERpbWVuc2lvbkZvckF4aXMoYXhpcywgZWxlbWVudCkge1xyXG4gIHJldHVybiBheGlzID09PSAneCcgPyBlbGVtZW50LndpZHRoIDogZWxlbWVudC5oZWlnaHQ7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldFRhcmdldEJvdW5kc1BhZGRpbmcodGFyZ2V0KSB7XHJcbiAgaWYgKGlzKHRhcmdldCwgJ2JwbW46VGFzaycpKSB7XHJcbiAgICByZXR1cm4gVEFTS19CT1VORFNfUEFERElORztcclxuICB9IGVsc2Uge1xyXG4gICAgcmV0dXJuIFRBUkdFVF9CT1VORFNfUEFERElORztcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTWlkKGV2ZW50LCB0YXJnZXQsIGF4aXMpIHtcclxuICByZXR1cm4gZXZlbnRbIGF4aXMgXSA+IHRhcmdldFsgYXhpcyBdICsgVEFSR0VUX0NFTlRFUl9QQURESU5HXHJcbiAgICAmJiBldmVudFsgYXhpcyBdIDwgdGFyZ2V0WyBheGlzIF0gKyBnZXREaW1lbnNpb25Gb3JBeGlzKGF4aXMsIHRhcmdldCkgLSBUQVJHRVRfQ0VOVEVSX1BBRERJTkc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzUmV2ZXJzZShjb250ZXh0KSB7XHJcbiAgdmFyIGhvdmVyID0gY29udGV4dC5ob3ZlcixcclxuICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2U7XHJcblxyXG4gIHJldHVybiBob3ZlciAmJiBzb3VyY2UgJiYgaG92ZXIgPT09IHNvdXJjZTtcclxufSIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDcmVhdGVNb3ZlU25hcHBpbmcgZnJvbSAnZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvc25hcHBpbmcvQ3JlYXRlTW92ZVNuYXBwaW5nJztcblxuaW1wb3J0IHtcbiAgaXNTbmFwcGVkLFxuICBzZXRTbmFwcGVkLFxuICB0b3BMZWZ0LFxuICBib3R0b21SaWdodFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9zbmFwcGluZy9TbmFwVXRpbCc7XG5cbmltcG9ydCB7IGlzRXhwYW5kZWQgfSBmcm9tICcuLi8uLi91dGlsL0RpVXRpbCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBhc1RSQkwsXG4gIGdldE1pZFxufSBmcm9tICdkaWFncmFtLWpzL2xpYi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7IGdldEJvdW5kYXJ5QXR0YWNobWVudCB9IGZyb20gJy4vQnBtblNuYXBwaW5nVXRpbCc7XG5cbmltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cbnZhciBISUdIX1BSSU9SSVRZID0gMTUwMDtcblxuXG4vKipcbiAqIFNuYXAgZHVyaW5nIGNyZWF0ZSBhbmQgbW92ZS5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtJbmplY3Rvcn0gaW5qZWN0b3JcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkNyZWF0ZU1vdmVTbmFwcGluZyhldmVudEJ1cywgaW5qZWN0b3IpIHtcbiAgaW5qZWN0b3IuaW52b2tlKENyZWF0ZU1vdmVTbmFwcGluZywgdGhpcyk7XG5cbiAgLy8gY3JlYXRpbmcgZmlyc3QgcGFydGljaXBhbnRcbiAgZXZlbnRCdXMub24oWyAnY3JlYXRlLm1vdmUnLCAnY3JlYXRlLmVuZCcgXSwgSElHSF9QUklPUklUWSwgc2V0U25hcHBlZElmQ29uc3RyYWluZWQpO1xuXG4gIC8vIHNuYXAgYm91bmRhcnkgZXZlbnRzXG4gIGV2ZW50QnVzLm9uKFtcbiAgICAnY3JlYXRlLm1vdmUnLFxuICAgICdjcmVhdGUuZW5kJyxcbiAgICAnc2hhcGUubW92ZS5tb3ZlJyxcbiAgICAnc2hhcGUubW92ZS5lbmQnXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIHZhciBjYW5BdHRhY2ggPSBjYW5FeGVjdXRlICYmIChjYW5FeGVjdXRlID09PSAnYXR0YWNoJyB8fCBjYW5FeGVjdXRlLmF0dGFjaCk7XG5cbiAgICBpZiAoY2FuQXR0YWNoICYmICFpc1NuYXBwZWQoZXZlbnQpKSB7XG4gICAgICBzbmFwQm91bmRhcnlFdmVudChldmVudCwgdGFyZ2V0KTtcbiAgICB9XG4gIH0pO1xufVxuXG5pbmhlcml0cyhCcG1uQ3JlYXRlTW92ZVNuYXBwaW5nLCBDcmVhdGVNb3ZlU25hcHBpbmcpO1xuXG5CcG1uQ3JlYXRlTW92ZVNuYXBwaW5nLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdpbmplY3Rvcidcbl07XG5cbkJwbW5DcmVhdGVNb3ZlU25hcHBpbmcucHJvdG90eXBlLmluaXRTbmFwID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdmFyIHNuYXBDb250ZXh0ID0gQ3JlYXRlTW92ZVNuYXBwaW5nLnByb3RvdHlwZS5pbml0U25hcC5jYWxsKHRoaXMsIGV2ZW50KTtcblxuICB2YXIgc2hhcGUgPSBldmVudC5zaGFwZTtcblxuICB2YXIgaXNNb3ZlID0gISF0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0KHNoYXBlLmlkKTtcblxuICAvLyBzbmFwIHRvIGRvY2tpbmcgcG9pbnRzXG4gIGZvckVhY2goc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgZG9ja2luZyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzWzBdO1xuXG4gICAgZG9ja2luZyA9IGRvY2tpbmcub3JpZ2luYWwgfHwgZG9ja2luZztcblxuICAgIHNuYXBDb250ZXh0LnNldFNuYXBPcmlnaW4oY29ubmVjdGlvbi5pZCArICctZG9ja2luZycsIGdldERvY2tpbmdTbmFwT3JpZ2luKGRvY2tpbmcsIGlzTW92ZSwgZXZlbnQpKTtcbiAgfSk7XG5cbiAgZm9yRWFjaChzaGFwZS5pbmNvbWluZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgIHZhciBkb2NraW5nID0gY29ubmVjdGlvbi53YXlwb2ludHNbY29ubmVjdGlvbi53YXlwb2ludHMubGVuZ3RoIC0gMV07XG5cbiAgICBkb2NraW5nID0gZG9ja2luZy5vcmlnaW5hbCB8fCBkb2NraW5nO1xuXG4gICAgc25hcENvbnRleHQuc2V0U25hcE9yaWdpbihjb25uZWN0aW9uLmlkICsgJy1kb2NraW5nJywgZ2V0RG9ja2luZ1NuYXBPcmlnaW4oZG9ja2luZywgaXNNb3ZlLCBldmVudCkpO1xuICB9KTtcblxuICBpZiAoaXMoc2hhcGUsICdicG1uOlBhcnRpY2lwYW50JykpIHtcblxuICAgIC8vIHNuYXAgdG8gYm9yZGVycyB3aXRoIGhpZ2hlciBwcmlvcml0eVxuICAgIHNuYXBDb250ZXh0LnNldFNuYXBMb2NhdGlvbnMoWyAndG9wLWxlZnQnLCAnYm90dG9tLXJpZ2h0JywgJ21pZCcgXSk7XG4gIH1cblxuICByZXR1cm4gc25hcENvbnRleHQ7XG59O1xuXG5CcG1uQ3JlYXRlTW92ZVNuYXBwaW5nLnByb3RvdHlwZS5hZGRTbmFwVGFyZ2V0UG9pbnRzID0gZnVuY3Rpb24oc25hcFBvaW50cywgc2hhcGUsIHRhcmdldCkge1xuICBDcmVhdGVNb3ZlU25hcHBpbmcucHJvdG90eXBlLmFkZFNuYXBUYXJnZXRQb2ludHMuY2FsbCh0aGlzLCBzbmFwUG9pbnRzLCBzaGFwZSwgdGFyZ2V0KTtcblxuICB2YXIgc25hcFRhcmdldHMgPSB0aGlzLmdldFNuYXBUYXJnZXRzKHNoYXBlLCB0YXJnZXQpO1xuXG4gIGZvckVhY2goc25hcFRhcmdldHMsIGZ1bmN0aW9uKHNuYXBUYXJnZXQpIHtcblxuICAgIC8vIGhhbmRsZSBUUkJMIGFsaWdubWVudFxuICAgIC8vXG4gICAgLy8gKiB3aXRoIGNvbnRhaW5lciBlbGVtZW50c1xuICAgIC8vICogd2l0aCB0ZXh0IGFubm90YXRpb25zXG4gICAgaWYgKGlzQ29udGFpbmVyKHNuYXBUYXJnZXQpIHx8IGFyZUFsbChbIHNoYXBlLCBzbmFwVGFyZ2V0IF0sICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcbiAgICAgIHNuYXBQb2ludHMuYWRkKCd0b3AtbGVmdCcsIHRvcExlZnQoc25hcFRhcmdldCkpO1xuICAgICAgc25hcFBvaW50cy5hZGQoJ2JvdHRvbS1yaWdodCcsIGJvdHRvbVJpZ2h0KHNuYXBUYXJnZXQpKTtcbiAgICB9XG4gIH0pO1xuXG4gIHZhciBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnk7XG5cbiAgLy8gc25hcCB0byBkb2NraW5nIHBvaW50cyBpZiBub3QgY3JlYXRlIG1vZGVcbiAgZm9yRWFjaChzaGFwZS5pbmNvbWluZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgIGlmIChlbGVtZW50UmVnaXN0cnkuZ2V0KHNoYXBlLmlkKSkge1xuXG4gICAgICBpZiAoIWluY2x1ZGVzKHNuYXBUYXJnZXRzLCBjb25uZWN0aW9uLnNvdXJjZSkpIHtcbiAgICAgICAgc25hcFBvaW50cy5hZGQoJ21pZCcsIGdldE1pZChjb25uZWN0aW9uLnNvdXJjZSkpO1xuICAgICAgfVxuXG4gICAgICB2YXIgZG9ja2luZyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzWzBdO1xuICAgICAgc25hcFBvaW50cy5hZGQoY29ubmVjdGlvbi5pZCArICctZG9ja2luZycsIGRvY2tpbmcub3JpZ2luYWwgfHwgZG9ja2luZyk7XG4gICAgfVxuICB9KTtcblxuICBmb3JFYWNoKHNoYXBlLm91dGdvaW5nLCBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gICAgaWYgKGVsZW1lbnRSZWdpc3RyeS5nZXQoc2hhcGUuaWQpKSB7XG5cbiAgICAgIGlmICghaW5jbHVkZXMoc25hcFRhcmdldHMsIGNvbm5lY3Rpb24udGFyZ2V0KSkge1xuICAgICAgICBzbmFwUG9pbnRzLmFkZCgnbWlkJywgZ2V0TWlkKGNvbm5lY3Rpb24udGFyZ2V0KSk7XG4gICAgICB9XG5cbiAgICAgIHZhciBkb2NraW5nID0gY29ubmVjdGlvbi53YXlwb2ludHNbIGNvbm5lY3Rpb24ud2F5cG9pbnRzLmxlbmd0aCAtIDEgXTtcblxuICAgICAgc25hcFBvaW50cy5hZGQoY29ubmVjdGlvbi5pZCArICctZG9ja2luZycsIGRvY2tpbmcub3JpZ2luYWwgfHwgZG9ja2luZyk7XG4gICAgfVxuICB9KTtcblxuICAvLyBhZGQgc2VxdWVuY2UgZmxvdyBwYXJlbnRzIGFzIHNuYXAgdGFyZ2V0c1xuICBpZiAoaXModGFyZ2V0LCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgIHNuYXBQb2ludHMgPSB0aGlzLmFkZFNuYXBUYXJnZXRQb2ludHMoc25hcFBvaW50cywgc2hhcGUsIHRhcmdldC5wYXJlbnQpO1xuICB9XG5cbiAgcmV0dXJuIHNuYXBQb2ludHM7XG59O1xuXG5CcG1uQ3JlYXRlTW92ZVNuYXBwaW5nLnByb3RvdHlwZS5nZXRTbmFwVGFyZ2V0cyA9IGZ1bmN0aW9uKHNoYXBlLCB0YXJnZXQpIHtcbiAgcmV0dXJuIENyZWF0ZU1vdmVTbmFwcGluZy5wcm90b3R5cGUuZ2V0U25hcFRhcmdldHMuY2FsbCh0aGlzLCBzaGFwZSwgdGFyZ2V0KVxuICAgIC5maWx0ZXIoZnVuY3Rpb24oc25hcFRhcmdldCkge1xuXG4gICAgICAvLyBkbyBub3Qgc25hcCB0byBsYW5lc1xuICAgICAgcmV0dXJuICFpcyhzbmFwVGFyZ2V0LCAnYnBtbjpMYW5lJyk7XG4gICAgfSk7XG59O1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gc25hcEJvdW5kYXJ5RXZlbnQoZXZlbnQsIHRhcmdldCkge1xuICB2YXIgdGFyZ2V0VFJCTCA9IGFzVFJCTCh0YXJnZXQpO1xuXG4gIHZhciBkaXJlY3Rpb24gPSBnZXRCb3VuZGFyeUF0dGFjaG1lbnQoZXZlbnQsIHRhcmdldCk7XG5cbiAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlO1xuXG4gIHZhciBvZmZzZXQ7XG5cbiAgaWYgKHNoYXBlLnBhcmVudCkge1xuICAgIG9mZnNldCA9IHsgeDogMCwgeTogMCB9O1xuICB9IGVsc2Uge1xuICAgIG9mZnNldCA9IGdldE1pZChzaGFwZSk7XG4gIH1cblxuICBpZiAoL3RvcC8udGVzdChkaXJlY3Rpb24pKSB7XG4gICAgc2V0U25hcHBlZChldmVudCwgJ3knLCB0YXJnZXRUUkJMLnRvcCAtIG9mZnNldC55KTtcbiAgfSBlbHNlIGlmICgvYm90dG9tLy50ZXN0KGRpcmVjdGlvbikpIHtcbiAgICBzZXRTbmFwcGVkKGV2ZW50LCAneScsIHRhcmdldFRSQkwuYm90dG9tIC0gb2Zmc2V0LnkpO1xuICB9XG5cbiAgaWYgKC9sZWZ0Ly50ZXN0KGRpcmVjdGlvbikpIHtcbiAgICBzZXRTbmFwcGVkKGV2ZW50LCAneCcsIHRhcmdldFRSQkwubGVmdCAtIG9mZnNldC54KTtcbiAgfSBlbHNlIGlmICgvcmlnaHQvLnRlc3QoZGlyZWN0aW9uKSkge1xuICAgIHNldFNuYXBwZWQoZXZlbnQsICd4JywgdGFyZ2V0VFJCTC5yaWdodCAtIG9mZnNldC54KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhcmVBbGwoZWxlbWVudHMsIHR5cGUpIHtcbiAgcmV0dXJuIGVsZW1lbnRzLmV2ZXJ5KGZ1bmN0aW9uKGVsKSB7XG4gICAgcmV0dXJuIGlzKGVsLCB0eXBlKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGlzQ29udGFpbmVyKGVsZW1lbnQpIHtcbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJiBpc0V4cGFuZGVkKGVsZW1lbnQpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKTtcbn1cblxuXG5mdW5jdGlvbiBzZXRTbmFwcGVkSWZDb25zdHJhaW5lZChldmVudCkge1xuICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICBjcmVhdGVDb25zdHJhaW50cyA9IGNvbnRleHQuY3JlYXRlQ29uc3RyYWludHM7XG5cbiAgaWYgKCFjcmVhdGVDb25zdHJhaW50cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciB0b3AgPSBjcmVhdGVDb25zdHJhaW50cy50b3AsXG4gICAgICByaWdodCA9IGNyZWF0ZUNvbnN0cmFpbnRzLnJpZ2h0LFxuICAgICAgYm90dG9tID0gY3JlYXRlQ29uc3RyYWludHMuYm90dG9tLFxuICAgICAgbGVmdCA9IGNyZWF0ZUNvbnN0cmFpbnRzLmxlZnQ7XG5cbiAgaWYgKChsZWZ0ICYmIGxlZnQgPj0gZXZlbnQueCkgfHwgKHJpZ2h0ICYmIHJpZ2h0IDw9IGV2ZW50LngpKSB7XG4gICAgc2V0U25hcHBlZChldmVudCwgJ3gnLCBldmVudC54KTtcbiAgfVxuXG4gIGlmICgodG9wICYmIHRvcCA+PSBldmVudC55KSB8fCAoYm90dG9tICYmIGJvdHRvbSA8PSBldmVudC55KSkge1xuICAgIHNldFNuYXBwZWQoZXZlbnQsICd5JywgZXZlbnQueSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5jbHVkZXMoYXJyYXksIHZhbHVlKSB7XG4gIHJldHVybiBhcnJheS5pbmRleE9mKHZhbHVlKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGdldERvY2tpbmdTbmFwT3JpZ2luKGRvY2tpbmcsIGlzTW92ZSwgZXZlbnQpIHtcbiAgcmV0dXJuIGlzTW92ZSA/IChcbiAgICB7XG4gICAgICB4OiBkb2NraW5nLnggLSBldmVudC54LFxuICAgICAgeTogZG9ja2luZy55IC0gZXZlbnQueVxuICAgIH1cbiAgKSA6IHtcbiAgICB4OiBkb2NraW5nLngsXG4gICAgeTogZG9ja2luZy55XG4gIH07XG59XG4iLCJpbXBvcnQgeyBnZXRPcmllbnRhdGlvbiB9IGZyb20gJ2RpYWdyYW0tanMvbGliL2xheW91dC9MYXlvdXRVdGlsJztcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRCb3VuZGFyeUF0dGFjaG1lbnQocG9zaXRpb24sIHRhcmdldEJvdW5kcykge1xyXG5cclxuICB2YXIgb3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihwb3NpdGlvbiwgdGFyZ2V0Qm91bmRzLCAtMTUpO1xyXG5cclxuICBpZiAob3JpZW50YXRpb24gIT09ICdpbnRlcnNlY3QnKSB7XHJcbiAgICByZXR1cm4gb3JpZW50YXRpb247XHJcbiAgfSBlbHNlIHtcclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxufSIsImltcG9ydCBCcG1uQ29ubmVjdFNuYXBwaW5nIGZyb20gJy4vQnBtbkNvbm5lY3RTbmFwcGluZyc7XG5pbXBvcnQgQnBtbkNyZWF0ZU1vdmVTbmFwcGluZyBmcm9tICcuL0JwbW5DcmVhdGVNb3ZlU25hcHBpbmcnO1xuaW1wb3J0IFNuYXBwaW5nTW9kdWxlIGZyb20gJ2RpYWdyYW0tanMvbGliL2ZlYXR1cmVzL3NuYXBwaW5nJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogWyBTbmFwcGluZ01vZHVsZSBdLFxuICBfX2luaXRfXzogW1xuICAgICdjb25uZWN0U25hcHBpbmcnLFxuICAgICdjcmVhdGVNb3ZlU25hcHBpbmcnXG4gIF0sXG4gIGNvbm5lY3RTbmFwcGluZzogWyAndHlwZScsIEJwbW5Db25uZWN0U25hcHBpbmcgXSxcbiAgY3JlYXRlTW92ZVNuYXBwaW5nOiBbICd0eXBlJywgQnBtbkNyZWF0ZU1vdmVTbmFwcGluZyBdXG59OyIsImltcG9ydCB7XG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi4vdXRpbC9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0xhYmVsRXh0ZXJuYWwsXG4gIGdldEV4dGVybmFsTGFiZWxCb3VuZHNcbn0gZnJvbSAnLi4vdXRpbC9MYWJlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRNaWRcbn0gZnJvbSAnZGlhZ3JhbS1qcy9saWIvbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBpc0V4cGFuZGVkXG59IGZyb20gJy4uL3V0aWwvRGlVdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0TGFiZWxcbn0gZnJvbSAnLi4vZmVhdHVyZXMvbGFiZWwtZWRpdGluZy9MYWJlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBlbGVtZW50VG9TdHJpbmdcbn0gZnJvbSAnLi9VdGlsJztcblxuXG5mdW5jdGlvbiBlbGVtZW50RGF0YShzZW1hbnRpYywgYXR0cnMpIHtcbiAgcmV0dXJuIGFzc2lnbih7XG4gICAgaWQ6IHNlbWFudGljLmlkLFxuICAgIHR5cGU6IHNlbWFudGljLiR0eXBlLFxuICAgIGJ1c2luZXNzT2JqZWN0OiBzZW1hbnRpY1xuICB9LCBhdHRycyk7XG59XG5cbmZ1bmN0aW9uIGdldFdheXBvaW50cyhibywgc291cmNlLCB0YXJnZXQpIHtcblxuICB2YXIgd2F5cG9pbnRzID0gYm8uZGkud2F5cG9pbnQ7XG5cbiAgaWYgKCF3YXlwb2ludHMgfHwgd2F5cG9pbnRzLmxlbmd0aCA8IDIpIHtcbiAgICByZXR1cm4gWyBnZXRNaWQoc291cmNlKSwgZ2V0TWlkKHRhcmdldCkgXTtcbiAgfVxuXG4gIHJldHVybiB3YXlwb2ludHMubWFwKGZ1bmN0aW9uKHApIHtcbiAgICByZXR1cm4geyB4OiBwLngsIHk6IHAueSB9O1xuICB9KTtcbn1cblxuZnVuY3Rpb24gbm90WWV0RHJhd24odHJhbnNsYXRlLCBzZW1hbnRpYywgcmVmU2VtYW50aWMsIHByb3BlcnR5KSB7XG4gIHJldHVybiBuZXcgRXJyb3IodHJhbnNsYXRlKCdlbGVtZW50IHtlbGVtZW50fSByZWZlcmVuY2VkIGJ5IHtyZWZlcmVuY2VkfSN7cHJvcGVydHl9IG5vdCB5ZXQgZHJhd24nLCB7XG4gICAgZWxlbWVudDogZWxlbWVudFRvU3RyaW5nKHJlZlNlbWFudGljKSxcbiAgICByZWZlcmVuY2VkOiBlbGVtZW50VG9TdHJpbmcoc2VtYW50aWMpLFxuICAgIHByb3BlcnR5OiBwcm9wZXJ0eVxuICB9KSk7XG59XG5cblxuLyoqXG4gKiBBbiBpbXBvcnRlciB0aGF0IGFkZHMgYnBtbiBlbGVtZW50cyB0byB0aGUgY2FudmFzXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7RWxlbWVudEZhY3Rvcnl9IGVsZW1lbnRGYWN0b3J5XG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2xhdGVcbiAqIEBwYXJhbSB7VGV4dFJlbmRlcmVyfSB0ZXh0UmVuZGVyZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtbkltcG9ydGVyKFxuICAgIGV2ZW50QnVzLCBjYW52YXMsIGVsZW1lbnRGYWN0b3J5LFxuICAgIGVsZW1lbnRSZWdpc3RyeSwgdHJhbnNsYXRlLCB0ZXh0UmVuZGVyZXIpIHtcblxuICB0aGlzLl9ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX2VsZW1lbnRGYWN0b3J5ID0gZWxlbWVudEZhY3Rvcnk7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbiAgdGhpcy5fdHJhbnNsYXRlID0gdHJhbnNsYXRlO1xuICB0aGlzLl90ZXh0UmVuZGVyZXIgPSB0ZXh0UmVuZGVyZXI7XG59XG5cbkJwbW5JbXBvcnRlci4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXG4gICd0cmFuc2xhdGUnLFxuICAndGV4dFJlbmRlcmVyJ1xuXTtcblxuXG4vKipcbiAqIEFkZCBicG1uIGVsZW1lbnQgKHNlbWFudGljKSB0byB0aGUgY2FudmFzIG9udG8gdGhlXG4gKiBzcGVjaWZpZWQgcGFyZW50IHNoYXBlLlxuICovXG5CcG1uSW1wb3J0ZXIucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKHNlbWFudGljLCBwYXJlbnRFbGVtZW50KSB7XG5cbiAgdmFyIGRpID0gc2VtYW50aWMuZGksXG4gICAgICBlbGVtZW50LFxuICAgICAgdHJhbnNsYXRlID0gdGhpcy5fdHJhbnNsYXRlLFxuICAgICAgaGlkZGVuO1xuXG4gIHZhciBwYXJlbnRJbmRleDtcblxuICAvLyBST09UIEVMRU1FTlRcbiAgLy8gaGFuZGxlIHRoZSBzcGVjaWFsIGNhc2UgdGhhdCB3ZSBkZWFsIHdpdGggYVxuICAvLyBpbnZpc2libGUgcm9vdCBlbGVtZW50IChwcm9jZXNzIG9yIGNvbGxhYm9yYXRpb24pXG4gIGlmIChpcyhkaSwgJ2JwbW5kaTpCUE1OUGxhbmUnKSkge1xuXG4gICAgLy8gYWRkIGEgdmlydHVhbCBlbGVtZW50IChub3QgYmVpbmcgZHJhd24pXG4gICAgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRGYWN0b3J5LmNyZWF0ZVJvb3QoZWxlbWVudERhdGEoc2VtYW50aWMpKTtcblxuICAgIHRoaXMuX2NhbnZhcy5zZXRSb290RWxlbWVudChlbGVtZW50KTtcbiAgfVxuXG4gIC8vIFNIQVBFXG4gIGVsc2UgaWYgKGlzKGRpLCAnYnBtbmRpOkJQTU5TaGFwZScpKSB7XG5cbiAgICB2YXIgY29sbGFwc2VkID0gIWlzRXhwYW5kZWQoc2VtYW50aWMpLFxuICAgICAgICBpc0ZyYW1lID0gaXNGcmFtZUVsZW1lbnQoc2VtYW50aWMpO1xuICAgIGhpZGRlbiA9IHBhcmVudEVsZW1lbnQgJiYgKHBhcmVudEVsZW1lbnQuaGlkZGVuIHx8IHBhcmVudEVsZW1lbnQuY29sbGFwc2VkKTtcblxuICAgIHZhciBib3VuZHMgPSBzZW1hbnRpYy5kaS5ib3VuZHM7XG5cbiAgICBlbGVtZW50ID0gdGhpcy5fZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoZWxlbWVudERhdGEoc2VtYW50aWMsIHtcbiAgICAgIGNvbGxhcHNlZDogY29sbGFwc2VkLFxuICAgICAgaGlkZGVuOiBoaWRkZW4sXG4gICAgICB4OiBNYXRoLnJvdW5kKGJvdW5kcy54KSxcbiAgICAgIHk6IE1hdGgucm91bmQoYm91bmRzLnkpLFxuICAgICAgd2lkdGg6IE1hdGgucm91bmQoYm91bmRzLndpZHRoKSxcbiAgICAgIGhlaWdodDogTWF0aC5yb3VuZChib3VuZHMuaGVpZ2h0KSxcbiAgICAgIGlzRnJhbWU6IGlzRnJhbWVcbiAgICB9KSk7XG5cbiAgICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSkge1xuICAgICAgdGhpcy5fYXR0YWNoQm91bmRhcnkoc2VtYW50aWMsIGVsZW1lbnQpO1xuICAgIH1cblxuICAgIC8vIGluc2VydCBsYW5lcyBiZWhpbmQgb3RoZXIgZmxvdyBub2RlcyAoY2YuICM3MjcpXG4gICAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpMYW5lJykpIHtcbiAgICAgIHBhcmVudEluZGV4ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpKSB7XG5cbiAgICAgIC8vIGNoZWNrIHdoZXRoZXIgZGF0YSBzdG9yZSBpcyBpbnNpZGUgb3VyIG91dHNpZGUgb2YgaXRzIHNlbWFudGljIHBhcmVudFxuICAgICAgaWYgKCFpc1BvaW50SW5zaWRlQkJveChwYXJlbnRFbGVtZW50LCBnZXRNaWQoYm91bmRzKSkpIHtcbiAgICAgICAgcGFyZW50RWxlbWVudCA9IHRoaXMuX2NhbnZhcy5nZXRSb290RWxlbWVudCgpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuX2NhbnZhcy5hZGRTaGFwZShlbGVtZW50LCBwYXJlbnRFbGVtZW50LCBwYXJlbnRJbmRleCk7XG4gIH1cblxuICAvLyBDT05ORUNUSU9OXG4gIGVsc2UgaWYgKGlzKGRpLCAnYnBtbmRpOkJQTU5FZGdlJykpIHtcblxuICAgIHZhciBzb3VyY2UgPSB0aGlzLl9nZXRTb3VyY2Uoc2VtYW50aWMpLFxuICAgICAgICB0YXJnZXQgPSB0aGlzLl9nZXRUYXJnZXQoc2VtYW50aWMpO1xuXG4gICAgaGlkZGVuID0gcGFyZW50RWxlbWVudCAmJiAocGFyZW50RWxlbWVudC5oaWRkZW4gfHwgcGFyZW50RWxlbWVudC5jb2xsYXBzZWQpO1xuXG4gICAgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRGYWN0b3J5LmNyZWF0ZUNvbm5lY3Rpb24oZWxlbWVudERhdGEoc2VtYW50aWMsIHtcbiAgICAgIGhpZGRlbjogaGlkZGVuLFxuICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICAgIHdheXBvaW50czogZ2V0V2F5cG9pbnRzKHNlbWFudGljLCBzb3VyY2UsIHRhcmdldClcbiAgICB9KSk7XG5cbiAgICBpZiAoaXMoc2VtYW50aWMsICdicG1uOkRhdGFBc3NvY2lhdGlvbicpKSB7XG5cbiAgICAgIC8vIHJlbmRlciBhbHdheXMgb24gdG9wOyB0aGlzIGVuc3VyZXMgRGF0YUFzc29jaWF0aW9uc1xuICAgICAgLy8gYXJlIHJlbmRlcmVkIGNvcnJlY3RseSBhY3Jvc3MgZGlmZmVyZW50IFwiaGFja3NcIiBwZW9wbGVcbiAgICAgIC8vIGxvdmUgdG8gbW9kZWwgc3VjaCBhcyBjcm9zcyBwYXJ0aWNpcGFudCAvIHN1YiBwcm9jZXNzXG4gICAgICAvLyBhc3NvY2lhdGlvbnNcbiAgICAgIHBhcmVudEVsZW1lbnQgPSBudWxsO1xuICAgIH1cblxuICAgIC8vIGluc2VydCBzZXF1ZW5jZSBmbG93cyBiZWhpbmQgb3RoZXIgZmxvdyBub2RlcyAoY2YuICM3MjcpXG4gICAgaWYgKGlzKHNlbWFudGljLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgICAgcGFyZW50SW5kZXggPSAwO1xuICAgIH1cblxuICAgIHRoaXMuX2NhbnZhcy5hZGRDb25uZWN0aW9uKGVsZW1lbnQsIHBhcmVudEVsZW1lbnQsIHBhcmVudEluZGV4KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodHJhbnNsYXRlKCd1bmtub3duIGRpIHtkaX0gZm9yIGVsZW1lbnQge3NlbWFudGljfScsIHtcbiAgICAgIGRpOiBlbGVtZW50VG9TdHJpbmcoZGkpLFxuICAgICAgc2VtYW50aWM6IGVsZW1lbnRUb1N0cmluZyhzZW1hbnRpYylcbiAgICB9KSk7XG4gIH1cblxuICAvLyAob3B0aW9uYWwpIExBQkVMXG4gIGlmIChpc0xhYmVsRXh0ZXJuYWwoc2VtYW50aWMpICYmIGdldExhYmVsKGVsZW1lbnQpKSB7XG4gICAgdGhpcy5hZGRMYWJlbChzZW1hbnRpYywgZWxlbWVudCk7XG4gIH1cblxuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ2JwbW5FbGVtZW50LmFkZGVkJywgeyBlbGVtZW50OiBlbGVtZW50IH0pO1xuXG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuXG4vKipcbiAqIEF0dGFjaCB0aGUgYm91bmRhcnkgZWxlbWVudCB0byB0aGUgZ2l2ZW4gaG9zdFxuICpcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gYm91bmRhcnlTZW1hbnRpY1xuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gYm91bmRhcnlFbGVtZW50XG4gKi9cbkJwbW5JbXBvcnRlci5wcm90b3R5cGUuX2F0dGFjaEJvdW5kYXJ5ID0gZnVuY3Rpb24oYm91bmRhcnlTZW1hbnRpYywgYm91bmRhcnlFbGVtZW50KSB7XG4gIHZhciB0cmFuc2xhdGUgPSB0aGlzLl90cmFuc2xhdGU7XG4gIHZhciBob3N0U2VtYW50aWMgPSBib3VuZGFyeVNlbWFudGljLmF0dGFjaGVkVG9SZWY7XG5cbiAgaWYgKCFob3N0U2VtYW50aWMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IodHJhbnNsYXRlKCdtaXNzaW5nIHtzZW1hbnRpY30jYXR0YWNoZWRUb1JlZicsIHtcbiAgICAgIHNlbWFudGljOiBlbGVtZW50VG9TdHJpbmcoYm91bmRhcnlTZW1hbnRpYylcbiAgICB9KSk7XG4gIH1cblxuICB2YXIgaG9zdCA9IHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXQoaG9zdFNlbWFudGljLmlkKSxcbiAgICAgIGF0dGFjaGVycyA9IGhvc3QgJiYgaG9zdC5hdHRhY2hlcnM7XG5cbiAgaWYgKCFob3N0KSB7XG4gICAgdGhyb3cgbm90WWV0RHJhd24odHJhbnNsYXRlLCBib3VuZGFyeVNlbWFudGljLCBob3N0U2VtYW50aWMsICdhdHRhY2hlZFRvUmVmJyk7XG4gIH1cblxuICAvLyB3aXJlIGVsZW1lbnQuaG9zdCA8PiBob3N0LmF0dGFjaGVyc1xuICBib3VuZGFyeUVsZW1lbnQuaG9zdCA9IGhvc3Q7XG5cbiAgaWYgKCFhdHRhY2hlcnMpIHtcbiAgICBob3N0LmF0dGFjaGVycyA9IGF0dGFjaGVycyA9IFtdO1xuICB9XG5cbiAgaWYgKGF0dGFjaGVycy5pbmRleE9mKGJvdW5kYXJ5RWxlbWVudCkgPT09IC0xKSB7XG4gICAgYXR0YWNoZXJzLnB1c2goYm91bmRhcnlFbGVtZW50KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIGFkZCBsYWJlbCBmb3IgYW4gZWxlbWVudFxuICovXG5CcG1uSW1wb3J0ZXIucHJvdG90eXBlLmFkZExhYmVsID0gZnVuY3Rpb24oc2VtYW50aWMsIGVsZW1lbnQpIHtcbiAgdmFyIGJvdW5kcyxcbiAgICAgIHRleHQsXG4gICAgICBsYWJlbDtcblxuICBib3VuZHMgPSBnZXRFeHRlcm5hbExhYmVsQm91bmRzKHNlbWFudGljLCBlbGVtZW50KTtcblxuICB0ZXh0ID0gZ2V0TGFiZWwoZWxlbWVudCk7XG5cbiAgaWYgKHRleHQpIHtcblxuICAgIC8vIGdldCBjb3JyZWN0ZWQgYm91bmRzIGZyb20gYWN0dWFsIGxheW91dGVkIHRleHRcbiAgICBib3VuZHMgPSB0aGlzLl90ZXh0UmVuZGVyZXIuZ2V0RXh0ZXJuYWxMYWJlbEJvdW5kcyhib3VuZHMsIHRleHQpO1xuICB9XG5cbiAgbGFiZWwgPSB0aGlzLl9lbGVtZW50RmFjdG9yeS5jcmVhdGVMYWJlbChlbGVtZW50RGF0YShzZW1hbnRpYywge1xuICAgIGlkOiBzZW1hbnRpYy5pZCArICdfbGFiZWwnLFxuICAgIGxhYmVsVGFyZ2V0OiBlbGVtZW50LFxuICAgIHR5cGU6ICdsYWJlbCcsXG4gICAgaGlkZGVuOiBlbGVtZW50LmhpZGRlbiB8fCAhZ2V0TGFiZWwoZWxlbWVudCksXG4gICAgeDogTWF0aC5yb3VuZChib3VuZHMueCksXG4gICAgeTogTWF0aC5yb3VuZChib3VuZHMueSksXG4gICAgd2lkdGg6IE1hdGgucm91bmQoYm91bmRzLndpZHRoKSxcbiAgICBoZWlnaHQ6IE1hdGgucm91bmQoYm91bmRzLmhlaWdodClcbiAgfSkpO1xuXG4gIHJldHVybiB0aGlzLl9jYW52YXMuYWRkU2hhcGUobGFiZWwsIGVsZW1lbnQucGFyZW50KTtcbn07XG5cbi8qKlxuICogUmV0dXJuIHRoZSBkcmF3biBjb25uZWN0aW9uIGVuZCBiYXNlZCBvbiB0aGUgZ2l2ZW4gc2lkZS5cbiAqXG4gKiBAdGhyb3dzIHtFcnJvcn0gaWYgdGhlIGVuZCBpcyBub3QgeWV0IGRyYXduXG4gKi9cbkJwbW5JbXBvcnRlci5wcm90b3R5cGUuX2dldEVuZCA9IGZ1bmN0aW9uKHNlbWFudGljLCBzaWRlKSB7XG5cbiAgdmFyIGVsZW1lbnQsXG4gICAgICByZWZTZW1hbnRpYyxcbiAgICAgIHR5cGUgPSBzZW1hbnRpYy4kdHlwZSxcbiAgICAgIHRyYW5zbGF0ZSA9IHRoaXMuX3RyYW5zbGF0ZTtcblxuICByZWZTZW1hbnRpYyA9IHNlbWFudGljW3NpZGUgKyAnUmVmJ107XG5cbiAgLy8gaGFuZGxlIG15c3RlcmlvdXMgaXNNYW55IERhdGFBc3NvY2lhdGlvbiNzb3VyY2VSZWZcbiAgaWYgKHNpZGUgPT09ICdzb3VyY2UnICYmIHR5cGUgPT09ICdicG1uOkRhdGFJbnB1dEFzc29jaWF0aW9uJykge1xuICAgIHJlZlNlbWFudGljID0gcmVmU2VtYW50aWMgJiYgcmVmU2VtYW50aWNbMF07XG4gIH1cblxuICAvLyBmaXggc291cmNlIC8gdGFyZ2V0IGZvciBEYXRhSW5wdXRBc3NvY2lhdGlvbiAvIERhdGFPdXRwdXRBc3NvY2lhdGlvblxuICBpZiAoc2lkZSA9PT0gJ3NvdXJjZScgJiYgdHlwZSA9PT0gJ2JwbW46RGF0YU91dHB1dEFzc29jaWF0aW9uJyB8fFxuICAgICAgc2lkZSA9PT0gJ3RhcmdldCcgJiYgdHlwZSA9PT0gJ2JwbW46RGF0YUlucHV0QXNzb2NpYXRpb24nKSB7XG5cbiAgICByZWZTZW1hbnRpYyA9IHNlbWFudGljLiRwYXJlbnQ7XG4gIH1cblxuICBlbGVtZW50ID0gcmVmU2VtYW50aWMgJiYgdGhpcy5fZ2V0RWxlbWVudChyZWZTZW1hbnRpYyk7XG5cbiAgaWYgKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gZWxlbWVudDtcbiAgfVxuXG4gIGlmIChyZWZTZW1hbnRpYykge1xuICAgIHRocm93IG5vdFlldERyYXduKHRyYW5zbGF0ZSwgc2VtYW50aWMsIHJlZlNlbWFudGljLCBzaWRlICsgJ1JlZicpO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcih0cmFuc2xhdGUoJ3tzZW1hbnRpY30je3NpZGV9IFJlZiBub3Qgc3BlY2lmaWVkJywge1xuICAgICAgc2VtYW50aWM6IGVsZW1lbnRUb1N0cmluZyhzZW1hbnRpYyksXG4gICAgICBzaWRlOiBzaWRlXG4gICAgfSkpO1xuICB9XG59O1xuXG5CcG1uSW1wb3J0ZXIucHJvdG90eXBlLl9nZXRTb3VyY2UgPSBmdW5jdGlvbihzZW1hbnRpYykge1xuICByZXR1cm4gdGhpcy5fZ2V0RW5kKHNlbWFudGljLCAnc291cmNlJyk7XG59O1xuXG5CcG1uSW1wb3J0ZXIucHJvdG90eXBlLl9nZXRUYXJnZXQgPSBmdW5jdGlvbihzZW1hbnRpYykge1xuICByZXR1cm4gdGhpcy5fZ2V0RW5kKHNlbWFudGljLCAndGFyZ2V0Jyk7XG59O1xuXG5cbkJwbW5JbXBvcnRlci5wcm90b3R5cGUuX2dldEVsZW1lbnQgPSBmdW5jdGlvbihzZW1hbnRpYykge1xuICByZXR1cm4gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldChzZW1hbnRpYy5pZCk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNQb2ludEluc2lkZUJCb3goYmJveCwgcG9pbnQpIHtcbiAgdmFyIHggPSBwb2ludC54LFxuICAgICAgeSA9IHBvaW50Lnk7XG5cbiAgcmV0dXJuIHggPj0gYmJveC54ICYmXG4gICAgeCA8PSBiYm94LnggKyBiYm94LndpZHRoICYmXG4gICAgeSA+PSBiYm94LnkgJiZcbiAgICB5IDw9IGJib3gueSArIGJib3guaGVpZ2h0O1xufVxuXG5mdW5jdGlvbiBpc0ZyYW1lRWxlbWVudChzZW1hbnRpYykge1xuICByZXR1cm4gaXMoc2VtYW50aWMsICdicG1uOkdyb3VwJyk7XG59IiwiaW1wb3J0IHtcbiAgZmlsdGVyLFxuICBmaW5kLFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IFJlZnMgZnJvbSAnb2JqZWN0LXJlZnMnO1xuXG5pbXBvcnQge1xuICBlbGVtZW50VG9TdHJpbmdcbn0gZnJvbSAnLi9VdGlsJztcblxudmFyIGRpUmVmcyA9IG5ldyBSZWZzKFxuICB7IG5hbWU6ICdicG1uRWxlbWVudCcsIGVudW1lcmFibGU6IHRydWUgfSxcbiAgeyBuYW1lOiAnZGknLCBjb25maWd1cmFibGU6IHRydWUgfVxuKTtcblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgYW4gZWxlbWVudCBoYXMgdGhlIGdpdmVuIG1ldGEtbW9kZWwgdHlwZVxuICpcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnR9ICBlbGVtZW50XG4gKiBAcGFyYW0gIHtzdHJpbmd9ICAgICAgICAgdHlwZVxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbmZ1bmN0aW9uIGlzKGVsZW1lbnQsIHR5cGUpIHtcbiAgcmV0dXJuIGVsZW1lbnQuJGluc3RhbmNlT2YodHlwZSk7XG59XG5cblxuLyoqXG4gKiBGaW5kIGEgc3VpdGFibGUgZGlzcGxheSBjYW5kaWRhdGUgZm9yIGRlZmluaXRpb25zIHdoZXJlIHRoZSBESSBkb2VzIG5vdFxuICogY29ycmVjdGx5IHNwZWNpZnkgb25lLlxuICovXG5mdW5jdGlvbiBmaW5kRGlzcGxheUNhbmRpZGF0ZShkZWZpbml0aW9ucykge1xuICByZXR1cm4gZmluZChkZWZpbml0aW9ucy5yb290RWxlbWVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICByZXR1cm4gaXMoZSwgJ2JwbW46UHJvY2VzcycpIHx8IGlzKGUsICdicG1uOkNvbGxhYm9yYXRpb24nKTtcbiAgfSk7XG59XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQnBtblRyZWVXYWxrZXIoaGFuZGxlciwgdHJhbnNsYXRlKSB7XG5cbiAgLy8gbGlzdCBvZiBjb250YWluZXJzIGFscmVhZHkgd2Fsa2VkXG4gIHZhciBoYW5kbGVkRWxlbWVudHMgPSB7fTtcblxuICAvLyBsaXN0IG9mIGVsZW1lbnRzIHRvIGhhbmRsZSBkZWZlcnJlZCB0byBlbnN1cmVcbiAgLy8gcHJlcmVxdWlzaXRlcyBhcmUgZHJhd25cbiAgdmFyIGRlZmVycmVkID0gW107XG5cbiAgLy8gSGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgZnVuY3Rpb24gY29udGV4dHVhbChmbiwgY3R4KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGZuKGUsIGN0eCk7XG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZWQoZWxlbWVudCkge1xuICAgIGhhbmRsZWRFbGVtZW50c1tlbGVtZW50LmlkXSA9IGVsZW1lbnQ7XG4gIH1cblxuICBmdW5jdGlvbiBpc0hhbmRsZWQoZWxlbWVudCkge1xuICAgIHJldHVybiBoYW5kbGVkRWxlbWVudHNbZWxlbWVudC5pZF07XG4gIH1cblxuICBmdW5jdGlvbiB2aXNpdChlbGVtZW50LCBjdHgpIHtcblxuICAgIHZhciBnZnggPSBlbGVtZW50LmdmeDtcblxuICAgIC8vIGF2b2lkIG11bHRpcGxlIHJlbmRlcmluZyBvZiBlbGVtZW50c1xuICAgIGlmIChnZngpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgdHJhbnNsYXRlKCdhbHJlYWR5IHJlbmRlcmVkIHtlbGVtZW50fScsIHsgZWxlbWVudDogZWxlbWVudFRvU3RyaW5nKGVsZW1lbnQpIH0pXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIGNhbGwgaGFuZGxlclxuICAgIHJldHVybiBoYW5kbGVyLmVsZW1lbnQoZWxlbWVudCwgY3R4KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZpc2l0Um9vdChlbGVtZW50LCBkaWFncmFtKSB7XG4gICAgcmV0dXJuIGhhbmRsZXIucm9vdChlbGVtZW50LCBkaWFncmFtKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHZpc2l0SWZEaShlbGVtZW50LCBjdHgpIHtcblxuICAgIHRyeSB7XG4gICAgICB2YXIgZ2Z4ID0gZWxlbWVudC5kaSAmJiB2aXNpdChlbGVtZW50LCBjdHgpO1xuXG4gICAgICBoYW5kbGVkKGVsZW1lbnQpO1xuXG4gICAgICByZXR1cm4gZ2Z4O1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGxvZ0Vycm9yKGUubWVzc2FnZSwgeyBlbGVtZW50OiBlbGVtZW50LCBlcnJvcjogZSB9KTtcblxuICAgICAgY29uc29sZS5lcnJvcih0cmFuc2xhdGUoJ2ZhaWxlZCB0byBpbXBvcnQge2VsZW1lbnR9JywgeyBlbGVtZW50OiBlbGVtZW50VG9TdHJpbmcoZWxlbWVudCkgfSkpO1xuICAgICAgY29uc29sZS5lcnJvcihlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBsb2dFcnJvcihtZXNzYWdlLCBjb250ZXh0KSB7XG4gICAgaGFuZGxlci5lcnJvcihtZXNzYWdlLCBjb250ZXh0KTtcbiAgfVxuXG4gIC8vIERJIGhhbmRsaW5nIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuICBmdW5jdGlvbiByZWdpc3RlckRpKGRpKSB7XG4gICAgdmFyIGJwbW5FbGVtZW50ID0gZGkuYnBtbkVsZW1lbnQ7XG5cbiAgICBpZiAoYnBtbkVsZW1lbnQpIHtcbiAgICAgIGlmIChicG1uRWxlbWVudC5kaSkge1xuICAgICAgICBsb2dFcnJvcihcbiAgICAgICAgICB0cmFuc2xhdGUoJ211bHRpcGxlIERJIGVsZW1lbnRzIGRlZmluZWQgZm9yIHtlbGVtZW50fScsIHtcbiAgICAgICAgICAgIGVsZW1lbnQ6IGVsZW1lbnRUb1N0cmluZyhicG1uRWxlbWVudClcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB7IGVsZW1lbnQ6IGJwbW5FbGVtZW50IH1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpUmVmcy5iaW5kKGJwbW5FbGVtZW50LCAnZGknKTtcbiAgICAgICAgYnBtbkVsZW1lbnQuZGkgPSBkaTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbG9nRXJyb3IoXG4gICAgICAgIHRyYW5zbGF0ZSgnbm8gYnBtbkVsZW1lbnQgcmVmZXJlbmNlZCBpbiB7ZWxlbWVudH0nLCB7XG4gICAgICAgICAgZWxlbWVudDogZWxlbWVudFRvU3RyaW5nKGRpKVxuICAgICAgICB9KSxcbiAgICAgICAgeyBlbGVtZW50OiBkaSB9XG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZURpYWdyYW0oZGlhZ3JhbSkge1xuICAgIGhhbmRsZVBsYW5lKGRpYWdyYW0ucGxhbmUpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlUGxhbmUocGxhbmUpIHtcbiAgICByZWdpc3RlckRpKHBsYW5lKTtcblxuICAgIGZvckVhY2gocGxhbmUucGxhbmVFbGVtZW50LCBoYW5kbGVQbGFuZUVsZW1lbnQpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlUGxhbmVFbGVtZW50KHBsYW5lRWxlbWVudCkge1xuICAgIHJlZ2lzdGVyRGkocGxhbmVFbGVtZW50KTtcbiAgfVxuXG5cbiAgLy8gU2VtYW50aWMgaGFuZGxpbmcgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIC8qKlxuICAgKiBIYW5kbGUgZGVmaW5pdGlvbnMgYW5kIHJldHVybiB0aGUgcmVuZGVyZWQgZGlhZ3JhbSAoaWYgYW55KVxuICAgKlxuICAgKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGRlZmluaXRpb25zIHRvIHdhbGsgYW5kIGltcG9ydFxuICAgKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IFtkaWFncmFtXSBzcGVjaWZpYyBkaWFncmFtIHRvIGltcG9ydCBhbmQgZGlzcGxheVxuICAgKlxuICAgKiBAdGhyb3dzIHtFcnJvcn0gaWYgbm8gZGlhZ3JhbSB0byBkaXNwbGF5IGNvdWxkIGJlIGZvdW5kXG4gICAqL1xuICBmdW5jdGlvbiBoYW5kbGVEZWZpbml0aW9ucyhkZWZpbml0aW9ucywgZGlhZ3JhbSkge1xuXG4gICAgLy8gbWFrZSBzdXJlIHdlIHdhbGsgdGhlIGNvcnJlY3QgYnBtbkVsZW1lbnRcblxuICAgIHZhciBkaWFncmFtcyA9IGRlZmluaXRpb25zLmRpYWdyYW1zO1xuXG4gICAgaWYgKGRpYWdyYW0gJiYgZGlhZ3JhbXMuaW5kZXhPZihkaWFncmFtKSA9PT0gLTEpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcih0cmFuc2xhdGUoJ2RpYWdyYW0gbm90IHBhcnQgb2YgYnBtbjpEZWZpbml0aW9ucycpKTtcbiAgICB9XG5cbiAgICBpZiAoIWRpYWdyYW0gJiYgZGlhZ3JhbXMgJiYgZGlhZ3JhbXMubGVuZ3RoKSB7XG4gICAgICBkaWFncmFtID0gZGlhZ3JhbXNbMF07XG4gICAgfVxuXG4gICAgLy8gbm8gZGlhZ3JhbSAtPiBub3RoaW5nIHRvIGltcG9ydFxuICAgIGlmICghZGlhZ3JhbSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnbm8gZGlhZ3JhbSB0byBkaXNwbGF5JykpO1xuICAgIH1cblxuICAgIC8vIGxvYWQgREkgZnJvbSBzZWxlY3RlZCBkaWFncmFtIG9ubHlcbiAgICBoYW5kbGVEaWFncmFtKGRpYWdyYW0pO1xuXG5cbiAgICB2YXIgcGxhbmUgPSBkaWFncmFtLnBsYW5lO1xuXG4gICAgaWYgKCFwbGFuZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZShcbiAgICAgICAgJ25vIHBsYW5lIGZvciB7ZWxlbWVudH0nLFxuICAgICAgICB7IGVsZW1lbnQ6IGVsZW1lbnRUb1N0cmluZyhkaWFncmFtKSB9XG4gICAgICApKTtcbiAgICB9XG5cbiAgICB2YXIgcm9vdEVsZW1lbnQgPSBwbGFuZS5icG1uRWxlbWVudDtcblxuICAgIC8vIGVuc3VyZSB3ZSBkZWZhdWx0IHRvIGEgc3VpdGFibGUgZGlzcGxheSBjYW5kaWRhdGUgKHByb2Nlc3Mgb3IgY29sbGFib3JhdGlvbiksXG4gICAgLy8gZXZlbiBpZiBub24gaXMgc3BlY2lmaWVkIGluIERJXG4gICAgaWYgKCFyb290RWxlbWVudCkge1xuICAgICAgcm9vdEVsZW1lbnQgPSBmaW5kRGlzcGxheUNhbmRpZGF0ZShkZWZpbml0aW9ucyk7XG5cbiAgICAgIGlmICghcm9vdEVsZW1lbnQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKHRyYW5zbGF0ZSgnbm8gcHJvY2VzcyBvciBjb2xsYWJvcmF0aW9uIHRvIGRpc3BsYXknKSk7XG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIGxvZ0Vycm9yKFxuICAgICAgICAgIHRyYW5zbGF0ZSgnY29ycmVjdGluZyBtaXNzaW5nIGJwbW5FbGVtZW50IG9uIHtwbGFuZX0gdG8ge3Jvb3RFbGVtZW50fScsIHtcbiAgICAgICAgICAgIHBsYW5lOiBlbGVtZW50VG9TdHJpbmcocGxhbmUpLFxuICAgICAgICAgICAgcm9vdEVsZW1lbnQ6IGVsZW1lbnRUb1N0cmluZyhyb290RWxlbWVudClcbiAgICAgICAgICB9KVxuICAgICAgICApO1xuXG4gICAgICAgIC8vIGNvcnJlY3QgREkgb24gdGhlIGZseVxuICAgICAgICBwbGFuZS5icG1uRWxlbWVudCA9IHJvb3RFbGVtZW50O1xuICAgICAgICByZWdpc3RlckRpKHBsYW5lKTtcbiAgICAgIH1cbiAgICB9XG5cblxuICAgIHZhciBjdHggPSB2aXNpdFJvb3Qocm9vdEVsZW1lbnQsIHBsYW5lKTtcblxuICAgIGlmIChpcyhyb290RWxlbWVudCwgJ2JwbW46UHJvY2VzcycpKSB7XG4gICAgICBoYW5kbGVQcm9jZXNzKHJvb3RFbGVtZW50LCBjdHgpO1xuICAgIH0gZWxzZSBpZiAoaXMocm9vdEVsZW1lbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKSkge1xuICAgICAgaGFuZGxlQ29sbGFib3JhdGlvbihyb290RWxlbWVudCwgY3R4KTtcblxuICAgICAgLy8gZm9yY2UgZHJhd2luZyBvZiBldmVyeXRoaW5nIG5vdCB5ZXQgZHJhd24gdGhhdCBpcyBwYXJ0IG9mIHRoZSB0YXJnZXQgRElcbiAgICAgIGhhbmRsZVVuaGFuZGxlZFByb2Nlc3NlcyhkZWZpbml0aW9ucy5yb290RWxlbWVudHMsIGN0eCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgdHJhbnNsYXRlKCd1bnN1cHBvcnRlZCBicG1uRWxlbWVudCBmb3Ige3BsYW5lfToge3Jvb3RFbGVtZW50fScsIHtcbiAgICAgICAgICBwbGFuZTogZWxlbWVudFRvU3RyaW5nKHBsYW5lKSxcbiAgICAgICAgICByb290RWxlbWVudDogZWxlbWVudFRvU3RyaW5nKHJvb3RFbGVtZW50KVxuICAgICAgICB9KVxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBoYW5kbGUgYWxsIGRlZmVycmVkIGVsZW1lbnRzXG4gICAgaGFuZGxlRGVmZXJyZWQoZGVmZXJyZWQpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlRGVmZXJyZWQoKSB7XG5cbiAgICB2YXIgZm47XG5cbiAgICAvLyBkcmFpbiBkZWZlcnJlZCB1bnRpbCBlbXB0eVxuICAgIHdoaWxlIChkZWZlcnJlZC5sZW5ndGgpIHtcbiAgICAgIGZuID0gZGVmZXJyZWQuc2hpZnQoKTtcblxuICAgICAgZm4oKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVQcm9jZXNzKHByb2Nlc3MsIGNvbnRleHQpIHtcbiAgICBoYW5kbGVGbG93RWxlbWVudHNDb250YWluZXIocHJvY2VzcywgY29udGV4dCk7XG4gICAgaGFuZGxlSW9TcGVjaWZpY2F0aW9uKHByb2Nlc3MuaW9TcGVjaWZpY2F0aW9uLCBjb250ZXh0KTtcblxuICAgIGhhbmRsZUFydGlmYWN0cyhwcm9jZXNzLmFydGlmYWN0cywgY29udGV4dCk7XG5cbiAgICAvLyBsb2cgcHJvY2VzcyBoYW5kbGVkXG4gICAgaGFuZGxlZChwcm9jZXNzKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVVuaGFuZGxlZFByb2Nlc3Nlcyhyb290RWxlbWVudHMsIGN0eCkge1xuXG4gICAgLy8gd2FsayB0aHJvdWdoIGFsbCBwcm9jZXNzZXMgdGhhdCBoYXZlIG5vdCB5ZXQgYmVlbiBkcmF3biBhbmQgZHJhdyB0aGVtXG4gICAgLy8gaWYgdGhleSBjb250YWluIGxhbmVzIHdpdGggREkgaW5mb3JtYXRpb24uXG4gICAgLy8gd2UgZG8gdGhpcyB0byBwYXNzIHRoZSBmcmVlLWZsb2F0aW5nIGxhbmUgdGVzdCBjYXNlcyBpbiB0aGUgTUlXRyB0ZXN0IHN1aXRlXG4gICAgdmFyIHByb2Nlc3NlcyA9IGZpbHRlcihyb290RWxlbWVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIHJldHVybiAhaXNIYW5kbGVkKGUpICYmIGlzKGUsICdicG1uOlByb2Nlc3MnKSAmJiBlLmxhbmVTZXRzO1xuICAgIH0pO1xuXG4gICAgcHJvY2Vzc2VzLmZvckVhY2goY29udGV4dHVhbChoYW5kbGVQcm9jZXNzLCBjdHgpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZU1lc3NhZ2VGbG93KG1lc3NhZ2VGbG93LCBjb250ZXh0KSB7XG4gICAgdmlzaXRJZkRpKG1lc3NhZ2VGbG93LCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZU1lc3NhZ2VGbG93cyhtZXNzYWdlRmxvd3MsIGNvbnRleHQpIHtcbiAgICBmb3JFYWNoKG1lc3NhZ2VGbG93cywgY29udGV4dHVhbChoYW5kbGVNZXNzYWdlRmxvdywgY29udGV4dCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlRGF0YUFzc29jaWF0aW9uKGFzc29jaWF0aW9uLCBjb250ZXh0KSB7XG4gICAgdmlzaXRJZkRpKGFzc29jaWF0aW9uLCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZURhdGFJbnB1dChkYXRhSW5wdXQsIGNvbnRleHQpIHtcbiAgICB2aXNpdElmRGkoZGF0YUlucHV0LCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZURhdGFPdXRwdXQoZGF0YU91dHB1dCwgY29udGV4dCkge1xuICAgIHZpc2l0SWZEaShkYXRhT3V0cHV0LCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUFydGlmYWN0KGFydGlmYWN0LCBjb250ZXh0KSB7XG5cbiAgICAvLyBicG1uOlRleHRBbm5vdGF0aW9uXG4gICAgLy8gYnBtbjpHcm91cFxuICAgIC8vIGJwbW46QXNzb2NpYXRpb25cblxuICAgIHZpc2l0SWZEaShhcnRpZmFjdCwgY29udGV4dCk7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVBcnRpZmFjdHMoYXJ0aWZhY3RzLCBjb250ZXh0KSB7XG5cbiAgICBmb3JFYWNoKGFydGlmYWN0cywgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKGlzKGUsICdicG1uOkFzc29jaWF0aW9uJykpIHtcbiAgICAgICAgZGVmZXJyZWQucHVzaChmdW5jdGlvbigpIHtcbiAgICAgICAgICBoYW5kbGVBcnRpZmFjdChlLCBjb250ZXh0KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoYW5kbGVBcnRpZmFjdChlLCBjb250ZXh0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUlvU3BlY2lmaWNhdGlvbihpb1NwZWNpZmljYXRpb24sIGNvbnRleHQpIHtcblxuICAgIGlmICghaW9TcGVjaWZpY2F0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yRWFjaChpb1NwZWNpZmljYXRpb24uZGF0YUlucHV0cywgY29udGV4dHVhbChoYW5kbGVEYXRhSW5wdXQsIGNvbnRleHQpKTtcbiAgICBmb3JFYWNoKGlvU3BlY2lmaWNhdGlvbi5kYXRhT3V0cHV0cywgY29udGV4dHVhbChoYW5kbGVEYXRhT3V0cHV0LCBjb250ZXh0KSk7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVTdWJQcm9jZXNzKHN1YlByb2Nlc3MsIGNvbnRleHQpIHtcbiAgICBoYW5kbGVGbG93RWxlbWVudHNDb250YWluZXIoc3ViUHJvY2VzcywgY29udGV4dCk7XG4gICAgaGFuZGxlQXJ0aWZhY3RzKHN1YlByb2Nlc3MuYXJ0aWZhY3RzLCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUZsb3dOb2RlKGZsb3dOb2RlLCBjb250ZXh0KSB7XG4gICAgdmFyIGNoaWxkQ3R4ID0gdmlzaXRJZkRpKGZsb3dOb2RlLCBjb250ZXh0KTtcblxuICAgIGlmIChpcyhmbG93Tm9kZSwgJ2JwbW46U3ViUHJvY2VzcycpKSB7XG4gICAgICBoYW5kbGVTdWJQcm9jZXNzKGZsb3dOb2RlLCBjaGlsZEN0eCB8fCBjb250ZXh0KTtcbiAgICB9XG5cbiAgICBpZiAoaXMoZmxvd05vZGUsICdicG1uOkFjdGl2aXR5JykpIHtcbiAgICAgIGhhbmRsZUlvU3BlY2lmaWNhdGlvbihmbG93Tm9kZS5pb1NwZWNpZmljYXRpb24sIGNvbnRleHQpO1xuICAgIH1cblxuICAgIC8vIGRlZmVyIGhhbmRsaW5nIG9mIGFzc29jaWF0aW9uc1xuICAgIC8vIGFmZmVjdGVkIHR5cGVzOlxuICAgIC8vXG4gICAgLy8gICAqIGJwbW46QWN0aXZpdHlcbiAgICAvLyAgICogYnBtbjpUaHJvd0V2ZW50XG4gICAgLy8gICAqIGJwbW46Q2F0Y2hFdmVudFxuICAgIC8vXG4gICAgZGVmZXJyZWQucHVzaChmdW5jdGlvbigpIHtcbiAgICAgIGZvckVhY2goZmxvd05vZGUuZGF0YUlucHV0QXNzb2NpYXRpb25zLCBjb250ZXh0dWFsKGhhbmRsZURhdGFBc3NvY2lhdGlvbiwgY29udGV4dCkpO1xuICAgICAgZm9yRWFjaChmbG93Tm9kZS5kYXRhT3V0cHV0QXNzb2NpYXRpb25zLCBjb250ZXh0dWFsKGhhbmRsZURhdGFBc3NvY2lhdGlvbiwgY29udGV4dCkpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlU2VxdWVuY2VGbG93KHNlcXVlbmNlRmxvdywgY29udGV4dCkge1xuICAgIHZpc2l0SWZEaShzZXF1ZW5jZUZsb3csIGNvbnRleHQpO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlRGF0YUVsZW1lbnQoZGF0YU9iamVjdCwgY29udGV4dCkge1xuICAgIHZpc2l0SWZEaShkYXRhT2JqZWN0LCBjb250ZXh0KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUxhbmUobGFuZSwgY29udGV4dCkge1xuXG4gICAgZGVmZXJyZWQucHVzaChmdW5jdGlvbigpIHtcblxuICAgICAgdmFyIG5ld0NvbnRleHQgPSB2aXNpdElmRGkobGFuZSwgY29udGV4dCk7XG5cbiAgICAgIGlmIChsYW5lLmNoaWxkTGFuZVNldCkge1xuICAgICAgICBoYW5kbGVMYW5lU2V0KGxhbmUuY2hpbGRMYW5lU2V0LCBuZXdDb250ZXh0IHx8IGNvbnRleHQpO1xuICAgICAgfVxuXG4gICAgICB3aXJlRmxvd05vZGVSZWZzKGxhbmUpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlTGFuZVNldChsYW5lU2V0LCBjb250ZXh0KSB7XG4gICAgZm9yRWFjaChsYW5lU2V0LmxhbmVzLCBjb250ZXh0dWFsKGhhbmRsZUxhbmUsIGNvbnRleHQpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZUxhbmVTZXRzKGxhbmVTZXRzLCBjb250ZXh0KSB7XG4gICAgZm9yRWFjaChsYW5lU2V0cywgY29udGV4dHVhbChoYW5kbGVMYW5lU2V0LCBjb250ZXh0KSk7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVGbG93RWxlbWVudHNDb250YWluZXIoY29udGFpbmVyLCBjb250ZXh0KSB7XG4gICAgaGFuZGxlRmxvd0VsZW1lbnRzKGNvbnRhaW5lci5mbG93RWxlbWVudHMsIGNvbnRleHQpO1xuXG4gICAgaWYgKGNvbnRhaW5lci5sYW5lU2V0cykge1xuICAgICAgaGFuZGxlTGFuZVNldHMoY29udGFpbmVyLmxhbmVTZXRzLCBjb250ZXh0KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVGbG93RWxlbWVudHMoZmxvd0VsZW1lbnRzLCBjb250ZXh0KSB7XG4gICAgZm9yRWFjaChmbG93RWxlbWVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGlmIChpcyhlLCAnYnBtbjpTZXF1ZW5jZUZsb3cnKSkge1xuICAgICAgICBkZWZlcnJlZC5wdXNoKGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGhhbmRsZVNlcXVlbmNlRmxvdyhlLCBjb250ZXh0KTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2UgaWYgKGlzKGUsICdicG1uOkJvdW5kYXJ5RXZlbnQnKSkge1xuICAgICAgICBkZWZlcnJlZC51bnNoaWZ0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGhhbmRsZUZsb3dOb2RlKGUsIGNvbnRleHQpO1xuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSBpZiAoaXMoZSwgJ2JwbW46Rmxvd05vZGUnKSkge1xuICAgICAgICBoYW5kbGVGbG93Tm9kZShlLCBjb250ZXh0KTtcbiAgICAgIH0gZWxzZSBpZiAoaXMoZSwgJ2JwbW46RGF0YU9iamVjdCcpKSB7XG5cbiAgICAgICAgLy8gU0tJUCAoYXNzdW1lIGNvcnJlY3QgcmVmZXJlbmNpbmcgdmlhIERhdGFPYmplY3RSZWZlcmVuY2UpXG4gICAgICB9IGVsc2UgaWYgKGlzKGUsICdicG1uOkRhdGFTdG9yZVJlZmVyZW5jZScpKSB7XG4gICAgICAgIGhhbmRsZURhdGFFbGVtZW50KGUsIGNvbnRleHQpO1xuICAgICAgfSBlbHNlIGlmIChpcyhlLCAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJykpIHtcbiAgICAgICAgaGFuZGxlRGF0YUVsZW1lbnQoZSwgY29udGV4dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dFcnJvcihcbiAgICAgICAgICB0cmFuc2xhdGUoJ3VucmVjb2duaXplZCBmbG93RWxlbWVudCB7ZWxlbWVudH0gaW4gY29udGV4dCB7Y29udGV4dH0nLCB7XG4gICAgICAgICAgICBlbGVtZW50OiBlbGVtZW50VG9TdHJpbmcoZSksXG4gICAgICAgICAgICBjb250ZXh0OiAoY29udGV4dCA/IGVsZW1lbnRUb1N0cmluZyhjb250ZXh0LmJ1c2luZXNzT2JqZWN0KSA6ICdudWxsJylcbiAgICAgICAgICB9KSxcbiAgICAgICAgICB7IGVsZW1lbnQ6IGUsIGNvbnRleHQ6IGNvbnRleHQgfVxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlUGFydGljaXBhbnQocGFydGljaXBhbnQsIGNvbnRleHQpIHtcbiAgICB2YXIgbmV3Q3R4ID0gdmlzaXRJZkRpKHBhcnRpY2lwYW50LCBjb250ZXh0KTtcblxuICAgIHZhciBwcm9jZXNzID0gcGFydGljaXBhbnQucHJvY2Vzc1JlZjtcbiAgICBpZiAocHJvY2Vzcykge1xuICAgICAgaGFuZGxlUHJvY2Vzcyhwcm9jZXNzLCBuZXdDdHggfHwgY29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlQ29sbGFib3JhdGlvbihjb2xsYWJvcmF0aW9uKSB7XG5cbiAgICBmb3JFYWNoKGNvbGxhYm9yYXRpb24ucGFydGljaXBhbnRzLCBjb250ZXh0dWFsKGhhbmRsZVBhcnRpY2lwYW50KSk7XG5cbiAgICBoYW5kbGVBcnRpZmFjdHMoY29sbGFib3JhdGlvbi5hcnRpZmFjdHMpO1xuXG4gICAgLy8gaGFuZGxlIG1lc3NhZ2UgZmxvd3MgbGF0ZXN0IGluIHRoZSBwcm9jZXNzXG4gICAgZGVmZXJyZWQucHVzaChmdW5jdGlvbigpIHtcbiAgICAgIGhhbmRsZU1lc3NhZ2VGbG93cyhjb2xsYWJvcmF0aW9uLm1lc3NhZ2VGbG93cyk7XG4gICAgfSk7XG4gIH1cblxuXG4gIGZ1bmN0aW9uIHdpcmVGbG93Tm9kZVJlZnMobGFuZSkge1xuXG4gICAgLy8gd2lyZSB0aGUgdmlydHVhbCBmbG93Tm9kZVJlZnMgPC0+IHJlbGF0aW9uc2hpcFxuICAgIGZvckVhY2gobGFuZS5mbG93Tm9kZVJlZiwgZnVuY3Rpb24oZmxvd05vZGUpIHtcbiAgICAgIHZhciBsYW5lcyA9IGZsb3dOb2RlLmdldCgnbGFuZXMnKTtcblxuICAgICAgaWYgKGxhbmVzKSB7XG4gICAgICAgIGxhbmVzLnB1c2gobGFuZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBBUEkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIHJldHVybiB7XG4gICAgaGFuZGxlRGVmZXJyZWQ6IGhhbmRsZURlZmVycmVkLFxuICAgIGhhbmRsZURlZmluaXRpb25zOiBoYW5kbGVEZWZpbml0aW9ucyxcbiAgICBoYW5kbGVTdWJQcm9jZXNzOiBoYW5kbGVTdWJQcm9jZXNzLFxuICAgIHJlZ2lzdGVyRGk6IHJlZ2lzdGVyRGlcbiAgfTtcbn0iLCJpbXBvcnQgQnBtblRyZWVXYWxrZXIgZnJvbSAnLi9CcG1uVHJlZVdhbGtlcic7XG5cblxuLyoqXG4gKiBUaGUgaW1wb3J0QnBtbkRpYWdyYW0gcmVzdWx0LlxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IEltcG9ydEJQTU5EaWFncmFtUmVzdWx0XG4gKlxuICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSB3YXJuaW5nc1xuICovXG5cbi8qKlxuKiBUaGUgaW1wb3J0QnBtbkRpYWdyYW0gZXJyb3IuXG4qXG4qIEB0eXBlZGVmIHtFcnJvcn0gSW1wb3J0QlBNTkRpYWdyYW1FcnJvclxuKlxuKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IHdhcm5pbmdzXG4qL1xuXG4vKipcbiAqIEltcG9ydCB0aGUgZGVmaW5pdGlvbnMgaW50byBhIGRpYWdyYW0uXG4gKlxuICogRXJyb3JzIGFuZCB3YXJuaW5ncyBhcmUgcmVwb3J0ZWQgdGhyb3VnaCB0aGUgc3BlY2lmaWVkIGNhbGxiYWNrLlxuICpcbiAqIEBwYXJhbSAge2Rqcy5EaWFncmFtfSBkaWFncmFtXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50PERlZmluaXRpb25zPn0gZGVmaW5pdGlvbnNcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnQ8QlBNTkRpYWdyYW0+fSBbYnBtbkRpYWdyYW1dIHRoZSBkaWFncmFtIHRvIGJlIHJlbmRlcmVkXG4gKiAoaWYgbm90IHByb3ZpZGVkLCB0aGUgZmlyc3Qgb25lIHdpbGwgYmUgcmVuZGVyZWQpXG4gKlxuICogUmV0dXJucyB7UHJvbWlzZTxJbXBvcnRCUE1ORGlhZ3JhbVJlc3VsdCwgSW1wb3J0QlBNTkRpYWdyYW1FcnJvcj59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbXBvcnRCcG1uRGlhZ3JhbShkaWFncmFtLCBkZWZpbml0aW9ucywgYnBtbkRpYWdyYW0pIHtcblxuICB2YXIgaW1wb3J0ZXIsXG4gICAgICBldmVudEJ1cyxcbiAgICAgIHRyYW5zbGF0ZTtcblxuICB2YXIgZXJyb3IsXG4gICAgICB3YXJuaW5ncyA9IFtdO1xuXG4gIC8qKlxuICAgKiBXYWxrIHRoZSBkaWFncmFtIHNlbWFudGljYWxseSwgaW1wb3J0aW5nICg9ZHJhd2luZylcbiAgICogYWxsIGVsZW1lbnRzIHlvdSBlbmNvdW50ZXIuXG4gICAqXG4gICAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxEZWZpbml0aW9ucz59IGRlZmluaXRpb25zXG4gICAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudDxCUE1ORGlhZ3JhbT59IGJwbW5EaWFncmFtXG4gICAqL1xuICBmdW5jdGlvbiByZW5kZXIoZGVmaW5pdGlvbnMsIGJwbW5EaWFncmFtKSB7XG5cbiAgICB2YXIgdmlzaXRvciA9IHtcblxuICAgICAgcm9vdDogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICByZXR1cm4gaW1wb3J0ZXIuYWRkKGVsZW1lbnQpO1xuICAgICAgfSxcblxuICAgICAgZWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgcGFyZW50U2hhcGUpIHtcbiAgICAgICAgcmV0dXJuIGltcG9ydGVyLmFkZChlbGVtZW50LCBwYXJlbnRTaGFwZSk7XG4gICAgICB9LFxuXG4gICAgICBlcnJvcjogZnVuY3Rpb24obWVzc2FnZSwgY29udGV4dCkge1xuICAgICAgICB3YXJuaW5ncy5wdXNoKHsgbWVzc2FnZTogbWVzc2FnZSwgY29udGV4dDogY29udGV4dCB9KTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgdmFyIHdhbGtlciA9IG5ldyBCcG1uVHJlZVdhbGtlcih2aXNpdG9yLCB0cmFuc2xhdGUpO1xuXG4gICAgLy8gdHJhdmVyc2UgQlBNTiAyLjAgZG9jdW1lbnQgbW9kZWwsXG4gICAgLy8gc3RhcnRpbmcgYXQgZGVmaW5pdGlvbnNcbiAgICB3YWxrZXIuaGFuZGxlRGVmaW5pdGlvbnMoZGVmaW5pdGlvbnMsIGJwbW5EaWFncmFtKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcbiAgICB0cnkge1xuICAgICAgaW1wb3J0ZXIgPSBkaWFncmFtLmdldCgnYnBtbkltcG9ydGVyJyk7XG4gICAgICBldmVudEJ1cyA9IGRpYWdyYW0uZ2V0KCdldmVudEJ1cycpO1xuICAgICAgdHJhbnNsYXRlID0gZGlhZ3JhbS5nZXQoJ3RyYW5zbGF0ZScpO1xuXG4gICAgICBldmVudEJ1cy5maXJlKCdpbXBvcnQucmVuZGVyLnN0YXJ0JywgeyBkZWZpbml0aW9uczogZGVmaW5pdGlvbnMgfSk7XG5cbiAgICAgIHJlbmRlcihkZWZpbml0aW9ucywgYnBtbkRpYWdyYW0pO1xuXG4gICAgICBldmVudEJ1cy5maXJlKCdpbXBvcnQucmVuZGVyLmNvbXBsZXRlJywge1xuICAgICAgICBlcnJvcjogZXJyb3IsXG4gICAgICAgIHdhcm5pbmdzOiB3YXJuaW5nc1xuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiByZXNvbHZlKHsgd2FybmluZ3M6IHdhcm5pbmdzIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcblxuICAgICAgZS53YXJuaW5ncyA9IHdhcm5pbmdzO1xuICAgICAgcmV0dXJuIHJlamVjdChlKTtcbiAgICB9XG4gIH0pO1xufVxuIiwiZXhwb3J0IGZ1bmN0aW9uIGVsZW1lbnRUb1N0cmluZyhlKSB7XG4gIGlmICghZSkge1xuICAgIHJldHVybiAnPG51bGw+JztcbiAgfVxuXG4gIHJldHVybiAnPCcgKyBlLiR0eXBlICsgKGUuaWQgPyAnIGlkPVwiJyArIGUuaWQgOiAnJykgKyAnXCIgLz4nO1xufSIsImltcG9ydCB0cmFuc2xhdGUgZnJvbSAnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnO1xuXG5pbXBvcnQgQnBtbkltcG9ydGVyIGZyb20gJy4vQnBtbkltcG9ydGVyJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIHRyYW5zbGF0ZVxuICBdLFxuICBicG1uSW1wb3J0ZXI6IFsgJ3R5cGUnLCBCcG1uSW1wb3J0ZXIgXVxufTsiLCJpbXBvcnQgeyBpc0Z1bmN0aW9uIH0gZnJvbSAnbWluLWRhc2gnO1xuXG4vLyBUT0RPKG5pa2t1KTogcmVtb3ZlIHdpdGggZnV0dXJlIGJwbW4tanMgdmVyc2lvblxuXG4vKipcbiAqIFdyYXBzIEFQSXMgdG8gY2hlY2s6XG4gKlxuICogMSkgSWYgYSBjYWxsYmFjayBpcyBwYXNzZWQgLT4gV2FybiB1c2VycyBhYm91dCBjYWxsYmFjayBkZXByZWNhdGlvbi5cbiAqIDIpIElmIFByb21pc2UgY2xhc3MgaXMgaW1wbGVtZW50ZWQgaW4gY3VycmVudCBlbnZpcm9ubWVudC5cbiAqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gd3JhcEZvckNvbXBhdGliaWxpdHkoYXBpKSB7XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuXG4gICAgaWYgKCF3aW5kb3cuUHJvbWlzZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm9taXNlcyBpcyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgZW52aXJvbm1lbnQuIFBsZWFzZSBwb2x5ZmlsbCBQcm9taXNlLicpO1xuICAgIH1cblxuICAgIHZhciBhcmdMZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgIGlmIChhcmdMZW4gPj0gMSAmJiBpc0Z1bmN0aW9uKGFyZ3VtZW50c1thcmdMZW4gLSAxXSkpIHtcblxuICAgICAgdmFyIGNhbGxiYWNrID0gYXJndW1lbnRzW2FyZ0xlbiAtIDFdO1xuXG4gICAgICBjb25zb2xlLndhcm4obmV3IEVycm9yKFxuICAgICAgICAnUGFzc2luZyBjYWxsYmFja3MgdG8gJyArIGFwaS5uYW1lICsgJyBpcyBkZXByZWNhdGVkIGFuZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgbWFqb3IgcmVsZWFzZS4gJyArXG4gICAgICAgICdQbGVhc2Ugc3dpdGNoIHRvIHByb21pc2VzOiBodHRwczovL2JwbW4uaW8vbC9tb3ZpbmctdG8tcHJvbWlzZXMuaHRtbCdcbiAgICAgICkpO1xuXG4gICAgICB2YXIgYXJnc1dpdGhvdXRDYWxsYmFjayA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMCwgLTEpO1xuXG4gICAgICBhcGkuYXBwbHkodGhpcywgYXJnc1dpdGhvdXRDYWxsYmFjaykudGhlbihmdW5jdGlvbihyZXN1bHQpIHtcblxuICAgICAgICB2YXIgZmlyc3RLZXkgPSBPYmplY3Qua2V5cyhyZXN1bHQpWzBdO1xuXG4gICAgICAgIC8vIFRoZSBBUElzIHdlIGFyZSB3cmFwcGluZyBhbGwgcmVzb2x2ZSBhIHNpbmdsZSBpdGVtIGRlcGVuZGluZyBvbiB0aGUgQVBJLlxuICAgICAgICAvLyBGb3IgaW5zdGFuY2UsIGltcG9ydFhNTCByZXNvbHZlcyB7IHdhcm5pbmdzIH0gYW5kIHNhdmVYTUwgcmV0dXJucyB7IHhtbCB9LlxuICAgICAgICAvLyBUaGF0J3Mgd2h5IHdlIGNhbiBjYWxsIHRoZSBjYWxsYmFjayB3aXRoIHRoZSBmaXJzdCBpdGVtIG9mIHJlc3VsdC5cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHJlc3VsdFtmaXJzdEtleV0pO1xuXG4gICAgICAgIC8vIFBhc3NpbmcgYSBzZWNvbmQgcGFyYW10ZXIgaW5zdGVhZCBvZiBjYXRjaCBiZWNhdXNlIHdlIGRvbid0IHdhbnQgdG9cbiAgICAgICAgLy8gY2F0Y2ggZXJyb3JzIHRocm93biBieSBjYWxsYmFjaygpLlxuICAgICAgfSwgZnVuY3Rpb24oZXJyKSB7XG5cbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgZXJyLndhcm5pbmdzKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIHJldHVybiBhcGkuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB9XG4gIH07XG59XG4iLCJpbXBvcnQge1xuICBpcyxcbiAgZ2V0QnVzaW5lc3NPYmplY3Rcbn0gZnJvbSAnLi9Nb2RlbFV0aWwnO1xuXG5pbXBvcnQge1xuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG5leHBvcnQgZnVuY3Rpb24gaXNFeHBhbmRlZChlbGVtZW50KSB7XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOkNhbGxBY3Rpdml0eScpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlN1YlByb2Nlc3MnKSkge1xuICAgIHJldHVybiAhIWdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLmRpLmlzRXhwYW5kZWQ7XG4gIH1cblxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xuICAgIHJldHVybiAhIWdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLnByb2Nlc3NSZWY7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzSW50ZXJydXB0aW5nKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQgJiYgZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkuaXNJbnRlcnJ1cHRpbmcgIT09IGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNFdmVudFN1YlByb2Nlc3MoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudCAmJiAhIWdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLnRyaWdnZXJlZEJ5RXZlbnQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgZXZlbnRUeXBlKSB7XG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxuICAgICAgaGFzRXZlbnREZWZpbml0aW9uID0gZmFsc2U7XG5cbiAgaWYgKGJvLmV2ZW50RGVmaW5pdGlvbnMpIHtcbiAgICBmb3JFYWNoKGJvLmV2ZW50RGVmaW5pdGlvbnMsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICBpZiAoaXMoZXZlbnQsIGV2ZW50VHlwZSkpIHtcbiAgICAgICAgaGFzRXZlbnREZWZpbml0aW9uID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBoYXNFdmVudERlZmluaXRpb247XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNFcnJvckV2ZW50RGVmaW5pdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiBoYXNFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46RXJyb3JFdmVudERlZmluaXRpb24nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0VzY2FsYXRpb25FdmVudERlZmluaXRpb24oZWxlbWVudCkge1xuICByZXR1cm4gaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOkVzY2FsYXRpb25FdmVudERlZmluaXRpb24nKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc0NvbXBlbnNhdGVFdmVudERlZmluaXRpb24oZWxlbWVudCkge1xuICByZXR1cm4gaGFzRXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOkNvbXBlbnNhdGVFdmVudERlZmluaXRpb24nKTtcbn1cbiIsImltcG9ydCB7XG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IGlzIH0gZnJvbSAnLi9Nb2RlbFV0aWwnO1xuXG5cbmV4cG9ydCB2YXIgREVGQVVMVF9MQUJFTF9TSVpFID0ge1xuICB3aWR0aDogOTAsXG4gIGhlaWdodDogMjBcbn07XG5cbmV4cG9ydCB2YXIgRkxPV19MQUJFTF9JTkRFTlQgPSAxNTtcblxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gc2VtYW50aWMgaGFzIGFuIGV4dGVybmFsIGxhYmVsXG4gKlxuICogQHBhcmFtIHtCcG1uRWxlbWVudH0gc2VtYW50aWNcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgaGFzIGxhYmVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0xhYmVsRXh0ZXJuYWwoc2VtYW50aWMpIHtcbiAgcmV0dXJuIGlzKHNlbWFudGljLCAnYnBtbjpFdmVudCcpIHx8XG4gICAgICAgICBpcyhzZW1hbnRpYywgJ2JwbW46R2F0ZXdheScpIHx8XG4gICAgICAgICBpcyhzZW1hbnRpYywgJ2JwbW46RGF0YVN0b3JlUmVmZXJlbmNlJykgfHxcbiAgICAgICAgIGlzKHNlbWFudGljLCAnYnBtbjpEYXRhT2JqZWN0UmVmZXJlbmNlJykgfHxcbiAgICAgICAgIGlzKHNlbWFudGljLCAnYnBtbjpEYXRhSW5wdXQnKSB8fFxuICAgICAgICAgaXMoc2VtYW50aWMsICdicG1uOkRhdGFPdXRwdXQnKSB8fFxuICAgICAgICAgaXMoc2VtYW50aWMsICdicG1uOlNlcXVlbmNlRmxvdycpIHx8XG4gICAgICAgICBpcyhzZW1hbnRpYywgJ2JwbW46TWVzc2FnZUZsb3cnKSB8fFxuICAgICAgICAgaXMoc2VtYW50aWMsICdicG1uOkdyb3VwJyk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBnaXZlbiBlbGVtZW50IGhhcyBhbiBleHRlcm5hbCBsYWJlbFxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLnNoYXBlfSBlbGVtZW50XG4gKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIGhhcyBsYWJlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzRXh0ZXJuYWxMYWJlbChlbGVtZW50KSB7XG4gIHJldHVybiBpc0xhYmVsKGVsZW1lbnQubGFiZWwpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgcG9zaXRpb24gZm9yIHNlcXVlbmNlIGZsb3cgbGFiZWxzXG4gKlxuICogQHBhcmFtICB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAqIEByZXR1cm4ge1BvaW50fSB0aGUgbGFiZWwgcG9zaXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEZsb3dMYWJlbFBvc2l0aW9uKHdheXBvaW50cykge1xuXG4gIC8vIGdldCB0aGUgd2F5cG9pbnRzIG1pZFxuICB2YXIgbWlkID0gd2F5cG9pbnRzLmxlbmd0aCAvIDIgLSAxO1xuXG4gIHZhciBmaXJzdCA9IHdheXBvaW50c1tNYXRoLmZsb29yKG1pZCldO1xuICB2YXIgc2Vjb25kID0gd2F5cG9pbnRzW01hdGguY2VpbChtaWQgKyAwLjAxKV07XG5cbiAgLy8gZ2V0IHBvc2l0aW9uXG4gIHZhciBwb3NpdGlvbiA9IGdldFdheXBvaW50c01pZCh3YXlwb2ludHMpO1xuXG4gIC8vIGNhbGN1bGF0ZSBhbmdsZVxuICB2YXIgYW5nbGUgPSBNYXRoLmF0YW4oKHNlY29uZC55IC0gZmlyc3QueSkgLyAoc2Vjb25kLnggLSBmaXJzdC54KSk7XG5cbiAgdmFyIHggPSBwb3NpdGlvbi54LFxuICAgICAgeSA9IHBvc2l0aW9uLnk7XG5cbiAgaWYgKE1hdGguYWJzKGFuZ2xlKSA8IE1hdGguUEkgLyAyKSB7XG4gICAgeSAtPSBGTE9XX0xBQkVMX0lOREVOVDtcbiAgfSBlbHNlIHtcbiAgICB4ICs9IEZMT1dfTEFCRUxfSU5ERU5UO1xuICB9XG5cbiAgcmV0dXJuIHsgeDogeCwgeTogeSB9O1xufVxuXG5cbi8qKlxuICogR2V0IHRoZSBtaWRkbGUgb2YgYSBudW1iZXIgb2Ygd2F5cG9pbnRzXG4gKlxuICogQHBhcmFtICB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAqIEByZXR1cm4ge1BvaW50fSB0aGUgbWlkIHBvaW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRXYXlwb2ludHNNaWQod2F5cG9pbnRzKSB7XG5cbiAgdmFyIG1pZCA9IHdheXBvaW50cy5sZW5ndGggLyAyIC0gMTtcblxuICB2YXIgZmlyc3QgPSB3YXlwb2ludHNbTWF0aC5mbG9vcihtaWQpXTtcbiAgdmFyIHNlY29uZCA9IHdheXBvaW50c1tNYXRoLmNlaWwobWlkICsgMC4wMSldO1xuXG4gIHJldHVybiB7XG4gICAgeDogZmlyc3QueCArIChzZWNvbmQueCAtIGZpcnN0LngpIC8gMixcbiAgICB5OiBmaXJzdC55ICsgKHNlY29uZC55IC0gZmlyc3QueSkgLyAyXG4gIH07XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldEV4dGVybmFsTGFiZWxNaWQoZWxlbWVudCkge1xuXG4gIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgIHJldHVybiBnZXRGbG93TGFiZWxQb3NpdGlvbihlbGVtZW50LndheXBvaW50cyk7XG4gIH0gZWxzZSBpZiAoaXMoZWxlbWVudCwgJ2JwbW46R3JvdXAnKSkge1xuICAgIHJldHVybiB7XG4gICAgICB4OiBlbGVtZW50LnggKyBlbGVtZW50LndpZHRoIC8gMixcbiAgICAgIHk6IGVsZW1lbnQueSArIERFRkFVTFRfTEFCRUxfU0laRS5oZWlnaHQgLyAyXG4gICAgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogZWxlbWVudC54ICsgZWxlbWVudC53aWR0aCAvIDIsXG4gICAgICB5OiBlbGVtZW50LnkgKyBlbGVtZW50LmhlaWdodCArIERFRkFVTFRfTEFCRUxfU0laRS5oZWlnaHQgLyAyXG4gICAgfTtcbiAgfVxufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgYm91bmRzIG9mIGFuIGVsZW1lbnRzIGxhYmVsLCBwYXJzZWQgZnJvbSB0aGUgZWxlbWVudHMgREkgb3JcbiAqIGdlbmVyYXRlZCBmcm9tIGl0cyBib3VuZHMuXG4gKlxuICogQHBhcmFtIHtCcG1uRWxlbWVudH0gc2VtYW50aWNcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEV4dGVybmFsTGFiZWxCb3VuZHMoc2VtYW50aWMsIGVsZW1lbnQpIHtcblxuICB2YXIgbWlkLFxuICAgICAgc2l6ZSxcbiAgICAgIGJvdW5kcyxcbiAgICAgIGRpID0gc2VtYW50aWMuZGksXG4gICAgICBsYWJlbCA9IGRpLmxhYmVsO1xuXG4gIGlmIChsYWJlbCAmJiBsYWJlbC5ib3VuZHMpIHtcbiAgICBib3VuZHMgPSBsYWJlbC5ib3VuZHM7XG5cbiAgICBzaXplID0ge1xuICAgICAgd2lkdGg6IE1hdGgubWF4KERFRkFVTFRfTEFCRUxfU0laRS53aWR0aCwgYm91bmRzLndpZHRoKSxcbiAgICAgIGhlaWdodDogYm91bmRzLmhlaWdodFxuICAgIH07XG5cbiAgICBtaWQgPSB7XG4gICAgICB4OiBib3VuZHMueCArIGJvdW5kcy53aWR0aCAvIDIsXG4gICAgICB5OiBib3VuZHMueSArIGJvdW5kcy5oZWlnaHQgLyAyXG4gICAgfTtcbiAgfSBlbHNlIHtcblxuICAgIG1pZCA9IGdldEV4dGVybmFsTGFiZWxNaWQoZWxlbWVudCk7XG5cbiAgICBzaXplID0gREVGQVVMVF9MQUJFTF9TSVpFO1xuICB9XG5cbiAgcmV0dXJuIGFzc2lnbih7XG4gICAgeDogbWlkLnggLSBzaXplLndpZHRoIC8gMixcbiAgICB5OiBtaWQueSAtIHNpemUuaGVpZ2h0IC8gMlxuICB9LCBzaXplKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudCAmJiAhIWVsZW1lbnQubGFiZWxUYXJnZXQ7XG59XG4iLCIvKipcbiAqIElzIGFuIGVsZW1lbnQgb2YgdGhlIGdpdmVuIEJQTU4gdHlwZT9cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZXxNb2RkbGVFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0gIHtzdHJpbmd9IHR5cGVcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXMoZWxlbWVudCwgdHlwZSkge1xuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcblxuICByZXR1cm4gYm8gJiYgKHR5cGVvZiBiby4kaW5zdGFuY2VPZiA9PT0gJ2Z1bmN0aW9uJykgJiYgYm8uJGluc3RhbmNlT2YodHlwZSk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGJ1c2luZXNzIG9iamVjdCBmb3IgYSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfE1vZGRsZUVsZW1lbnR9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkge1xuICByZXR1cm4gKGVsZW1lbnQgJiYgZWxlbWVudC5idXNpbmVzc09iamVjdCkgfHwgZWxlbWVudDtcbn0iLCIvKipcbiAqIFRoaXMgZmlsZSBtdXN0IG5vdCBiZSBjaGFuZ2VkIG9yIGV4Y2hhbmdlZC5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9icG1uLmlvL2xpY2Vuc2UgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gKi9cblxuaW1wb3J0IHtcbiAgZG9taWZ5LFxuICBkZWxlZ2F0ZSBhcyBkb21EZWxlZ2F0ZVxufSBmcm9tICdtaW4tZG9tJztcblxuXG4vLyBpbmxpbmVkIC4uLy4uL3Jlc291cmNlcy9sb2dvLnN2Z1xudmFyIEJQTU5JT19MT0dPX1NWRyA9ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2aWV3Qm94PVwiMCAwIDE0LjAyIDUuNTdcIiB3aWR0aD1cIjUzXCIgaGVpZ2h0PVwiMjFcIiBzdHlsZT1cInZlcnRpY2FsLWFsaWduOm1pZGRsZVwiPjxwYXRoIGZpbGw9XCJjdXJyZW50Q29sb3JcIiBkPVwiTTEuODguOTJ2LjE0YzAgLjQxLS4xMy42OC0uNC44LjMzLjE0LjQ2LjQ0LjQ2Ljg2di4zM2MwIC42MS0uMzMuOTUtLjk1Ljk1SDBWMGguOTVjLjY1IDAgLjkzLjMuOTMuOTJ6TS42My41N3YxLjA2aC4yNGMuMjQgMCAuMzgtLjEuMzgtLjQzVi45OGMwLS4yOC0uMS0uNC0uMzItLjR6bTAgMS42M3YxLjIyaC4zNmMuMiAwIC4zMi0uMS4zMi0uMzl2LS4zNWMwLS4zNy0uMTItLjQ4LS40LS40OEguNjN6TTQuMTguOTl2LjUyYzAgLjY0LS4zMS45OC0uOTQuOThoLS4zVjRoLS42MlYwaC45MmMuNjMgMCAuOTQuMzUuOTQuOTl6TTIuOTQuNTd2MS4zNWguM2MuMiAwIC4zLS4wOS4zLS4zN3YtLjZjMC0uMjktLjEtLjM4LS4zLS4zOGgtLjN6bTIuODkgMi4yN0w2LjI1IDBoLjg4djRoLS42VjEuMTJMNi4xIDMuOTloLS42bC0uNDYtMi44MnYyLjgyaC0uNTVWMGguODd6TTguMTQgMS4xVjRoLS41NlYwaC43OUw5IDIuNFYwaC41NnY0aC0uNjR6bTIuNDkgMi4yOXYuNmgtLjZ2LS42ek0xMi4xMiAxYzAtLjYzLjMzLTEgLjk1LTEgLjYxIDAgLjk1LjM3Ljk1IDF2Mi4wNGMwIC42NC0uMzQgMS0uOTUgMS0uNjIgMC0uOTUtLjM3LS45NS0xem0uNjIgMi4wOGMwIC4yOC4xMy4zOS4zMy4zOXMuMzItLjEuMzItLjRWLjk4YzAtLjI5LS4xMi0uNC0uMzItLjRzLS4zMy4xMS0uMzMuNHpcIi8+PHBhdGggZmlsbD1cImN1cnJlbnRDb2xvclwiIGQ9XCJNMCA0LjUzaDE0LjAydjEuMDRIMHpNMTEuMDggMGguNjN2LjYyaC0uNjN6bS42MyA0VjFoLS42M3YyLjk4elwiLz48L3N2Zz4nO1xuXG5leHBvcnQgdmFyIEJQTU5JT19JTUcgPSBCUE1OSU9fTE9HT19TVkc7XG5cbmZ1bmN0aW9uIGNzcyhhdHRycykge1xuICByZXR1cm4gYXR0cnMuam9pbignOycpO1xufVxuXG5leHBvcnQgdmFyIExJTktfU1RZTEVTID0gY3NzKFtcbiAgJ2NvbG9yOiAjNDA0MDQwJ1xuXSk7XG5cbnZhciBMSUdIVEJPWF9TVFlMRVMgPSBjc3MoW1xuICAnei1pbmRleDogMTAwMScsXG4gICdwb3NpdGlvbjogZml4ZWQnLFxuICAndG9wOiAwJyxcbiAgJ2xlZnQ6IDAnLFxuICAncmlnaHQ6IDAnLFxuICAnYm90dG9tOiAwJ1xuXSk7XG5cbnZhciBCQUNLRFJPUF9TVFlMRVMgPSBjc3MoW1xuICAnd2lkdGg6IDEwMCUnLFxuICAnaGVpZ2h0OiAxMDAlJyxcbiAgJ2JhY2tncm91bmQ6IHJnYmEoNDAsNDAsNDAsMC4yKSdcbl0pO1xuXG52YXIgTk9USUNFX1NUWUxFUyA9IGNzcyhbXG4gICdwb3NpdGlvbjogYWJzb2x1dGUnLFxuICAnbGVmdDogNTAlJyxcbiAgJ3RvcDogNDAlJyxcbiAgJ3RyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUpJyxcbiAgJ3dpZHRoOiAyNjBweCcsXG4gICdwYWRkaW5nOiAxMHB4JyxcbiAgJ2JhY2tncm91bmQ6IHdoaXRlJyxcbiAgJ2JveC1zaGFkb3c6IDAgMXB4IDRweCByZ2JhKDAsMCwwLDAuMyknLFxuICAnZm9udC1mYW1pbHk6IEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWYnLFxuICAnZm9udC1zaXplOiAxNHB4JyxcbiAgJ2Rpc3BsYXk6IGZsZXgnLFxuICAnbGluZS1oZWlnaHQ6IDEuMydcbl0pO1xuXG52YXIgTElHSFRCT1hfTUFSS1VQID1cbiAgJzxkaXYgY2xhc3M9XCJianMtcG93ZXJlZC1ieS1saWdodGJveFwiIHN0eWxlPVwiJyArIExJR0hUQk9YX1NUWUxFUyArICdcIj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImJhY2tkcm9wXCIgc3R5bGU9XCInICsgQkFDS0RST1BfU1RZTEVTICsgJ1wiPjwvZGl2PicgK1xuICAgICc8ZGl2IGNsYXNzPVwibm90aWNlXCIgc3R5bGU9XCInICsgTk9USUNFX1NUWUxFUyArICdcIj4nICtcbiAgICAgICc8YSBocmVmPVwiaHR0cHM6Ly9icG1uLmlvXCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9vcGVuZXJcIiBzdHlsZT1cIm1hcmdpbjogMTVweCAyMHB4IDE1cHggMTBweDsgYWxpZ24tc2VsZjogY2VudGVyOycgKyBMSU5LX1NUWUxFUyArICdcIj4nICtcbiAgICAgICAgQlBNTklPX0lNRyArXG4gICAgICAnPC9hPicgK1xuICAgICAgJzxzcGFuPicgK1xuICAgICAgICAnV2ViLWJhc2VkIHRvb2xpbmcgZm9yIEJQTU4sIERNTiBhbmQgQ01NTiBkaWFncmFtcyAnICtcbiAgICAgICAgJ3Bvd2VyZWQgYnkgPGEgaHJlZj1cImh0dHBzOi8vYnBtbi5pb1wiIHRhcmdldD1cIl9ibGFua1wiIHJlbD1cIm5vb3BlbmVyXCI+YnBtbi5pbzwvYT4uJyArXG4gICAgICAnPC9zcGFuPicgK1xuICAgICc8L2Rpdj4nICtcbiAgJzwvZGl2Pic7XG5cblxudmFyIGxpZ2h0Ym94O1xuXG5leHBvcnQgZnVuY3Rpb24gb3BlbigpIHtcblxuICBpZiAoIWxpZ2h0Ym94KSB7XG4gICAgbGlnaHRib3ggPSBkb21pZnkoTElHSFRCT1hfTUFSS1VQKTtcblxuICAgIGRvbURlbGVnYXRlLmJpbmQobGlnaHRib3gsICcuYmFja2Ryb3AnLCAnY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChsaWdodGJveCk7XG4gICAgfSk7XG4gIH1cblxuICBkb2N1bWVudC5ib2R5LmFwcGVuZENoaWxkKGxpZ2h0Ym94KTtcbn1cbiIsImV4cG9ydCB7IGRlZmF1bHQgfSBmcm9tICcuL2xpYi9EaWFncmFtJzsiLCJpbXBvcnQgeyBJbmplY3RvciB9IGZyb20gJ2RpZGknO1xuXG5pbXBvcnQgQ29yZU1vZHVsZSBmcm9tICcuL2NvcmUnO1xuXG5cbi8qKlxuICogQm9vdHN0cmFwIGFuIGluamVjdG9yIGZyb20gYSBsaXN0IG9mIG1vZHVsZXMsIGluc3RhbnRpYXRpbmcgYSBudW1iZXIgb2YgZGVmYXVsdCBjb21wb25lbnRzXG4gKlxuICogQGlnbm9yZVxuICogQHBhcmFtIHtBcnJheTxkaWRpLk1vZHVsZT59IGJvb3RzdHJhcE1vZHVsZXNcbiAqXG4gKiBAcmV0dXJuIHtkaWRpLkluamVjdG9yfSBhIGluamVjdG9yIHRvIHVzZSB0byBhY2Nlc3MgdGhlIGNvbXBvbmVudHNcbiAqL1xuZnVuY3Rpb24gYm9vdHN0cmFwKGJvb3RzdHJhcE1vZHVsZXMpIHtcblxuICB2YXIgbW9kdWxlcyA9IFtdLFxuICAgICAgY29tcG9uZW50cyA9IFtdO1xuXG4gIGZ1bmN0aW9uIGhhc01vZHVsZShtKSB7XG4gICAgcmV0dXJuIG1vZHVsZXMuaW5kZXhPZihtKSA+PSAwO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkTW9kdWxlKG0pIHtcbiAgICBtb2R1bGVzLnB1c2gobSk7XG4gIH1cblxuICBmdW5jdGlvbiB2aXNpdChtKSB7XG4gICAgaWYgKGhhc01vZHVsZShtKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIChtLl9fZGVwZW5kc19fIHx8IFtdKS5mb3JFYWNoKHZpc2l0KTtcblxuICAgIGlmIChoYXNNb2R1bGUobSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhZGRNb2R1bGUobSk7XG5cbiAgICAobS5fX2luaXRfXyB8fCBbXSkuZm9yRWFjaChmdW5jdGlvbihjKSB7XG4gICAgICBjb21wb25lbnRzLnB1c2goYyk7XG4gICAgfSk7XG4gIH1cblxuICBib290c3RyYXBNb2R1bGVzLmZvckVhY2godmlzaXQpO1xuXG4gIHZhciBpbmplY3RvciA9IG5ldyBJbmplY3Rvcihtb2R1bGVzKTtcblxuICBjb21wb25lbnRzLmZvckVhY2goZnVuY3Rpb24oYykge1xuXG4gICAgdHJ5IHtcblxuICAgICAgLy8gZWFnZXJseSByZXNvbHZlIGNvbXBvbmVudCAoZm4gb3Igc3RyaW5nKVxuICAgICAgaW5qZWN0b3JbdHlwZW9mIGMgPT09ICdzdHJpbmcnID8gJ2dldCcgOiAnaW52b2tlJ10oYyk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGluc3RhbnRpYXRlIGNvbXBvbmVudCcpO1xuICAgICAgY29uc29sZS5lcnJvcihlLnN0YWNrKTtcblxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBpbmplY3Rvcjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGluamVjdG9yIGZyb20gcGFzc2VkIG9wdGlvbnMuXG4gKlxuICogQGlnbm9yZVxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcmV0dXJuIHtkaWRpLkluamVjdG9yfVxuICovXG5mdW5jdGlvbiBjcmVhdGVJbmplY3RvcihvcHRpb25zKSB7XG5cbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgdmFyIGNvbmZpZ01vZHVsZSA9IHtcbiAgICAnY29uZmlnJzogWyd2YWx1ZScsIG9wdGlvbnNdXG4gIH07XG5cbiAgdmFyIG1vZHVsZXMgPSBbIGNvbmZpZ01vZHVsZSwgQ29yZU1vZHVsZSBdLmNvbmNhdChvcHRpb25zLm1vZHVsZXMgfHwgW10pO1xuXG4gIHJldHVybiBib290c3RyYXAobW9kdWxlcyk7XG59XG5cblxuLyoqXG4gKiBUaGUgbWFpbiBkaWFncmFtLWpzIGVudHJ5IHBvaW50IHRoYXQgYm9vdHN0cmFwcyB0aGUgZGlhZ3JhbSB3aXRoIHRoZSBnaXZlblxuICogY29uZmlndXJhdGlvbi5cbiAqXG4gKiBUbyByZWdpc3RlciBleHRlbnNpb25zIHdpdGggdGhlIGRpYWdyYW0sIHBhc3MgdGhlbSBhcyBBcnJheTxkaWRpLk1vZHVsZT4gdG8gdGhlIGNvbnN0cnVjdG9yLlxuICpcbiAqIEBjbGFzcyBkanMuRGlhZ3JhbVxuICogQG1lbWJlck9mIGRqc1xuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiA8Y2FwdGlvbj5DcmVhdGluZyBhIHBsdWctaW4gdGhhdCBsb2dzIHdoZW5ldmVyIGEgc2hhcGUgaXMgYWRkZWQgdG8gdGhlIGNhbnZhcy48L2NhcHRpb24+XG4gKlxuICogLy8gcGx1Zy1pbiBpbXBsZW1lbmVudGF0aW9uXG4gKiBmdW5jdGlvbiBNeUxvZ2dpbmdQbHVnaW4oZXZlbnRCdXMpIHtcbiAqICAgZXZlbnRCdXMub24oJ3NoYXBlLmFkZGVkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgICBjb25zb2xlLmxvZygnc2hhcGUgJywgZXZlbnQuc2hhcGUsICcgd2FzIGFkZGVkIHRvIHRoZSBkaWFncmFtJyk7XG4gKiAgIH0pO1xuICogfVxuICpcbiAqIC8vIGV4cG9ydCBhcyBtb2R1bGVcbiAqIGV4cG9ydCBkZWZhdWx0IHtcbiAqICAgX19pbml0X186IFsgJ215TG9nZ2luZ1BsdWdpbicgXSxcbiAqICAgICBteUxvZ2dpbmdQbHVnaW46IFsgJ3R5cGUnLCBNeUxvZ2dpbmdQbHVnaW4gXVxuICogfTtcbiAqXG4gKlxuICogLy8gaW5zdGFudGlhdGUgdGhlIGRpYWdyYW0gd2l0aCB0aGUgbmV3IHBsdWctaW5cbiAqXG4gKiBpbXBvcnQgTXlMb2dnaW5nTW9kdWxlIGZyb20gJ3BhdGgtdG8tbXktbG9nZ2luZy1wbHVnaW4nO1xuICpcbiAqIHZhciBkaWFncmFtID0gbmV3IERpYWdyYW0oe1xuICogICBtb2R1bGVzOiBbXG4gKiAgICAgTXlMb2dnaW5nTW9kdWxlXG4gKiAgIF1cbiAqIH0pO1xuICpcbiAqIGRpYWdyYW0uaW52b2tlKFsgJ2NhbnZhcycsIGZ1bmN0aW9uKGNhbnZhcykge1xuICogICAvLyBhZGQgc2hhcGUgdG8gZHJhd2luZyBjYW52YXNcbiAqICAgY2FudmFzLmFkZFNoYXBlKHsgeDogMTAsIHk6IDEwIH0pO1xuICogfSk7XG4gKlxuICogLy8gJ3NoYXBlIC4uLiB3YXMgYWRkZWQgdG8gdGhlIGRpYWdyYW0nIGxvZ2dlZCB0byBjb25zb2xlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7QXJyYXk8ZGlkaS5Nb2R1bGU+fSBbb3B0aW9ucy5tb2R1bGVzXSBleHRlcm5hbCBtb2R1bGVzIHRvIGluc3RhbnRpYXRlIHdpdGggdGhlIGRpYWdyYW1cbiAqIEBwYXJhbSB7ZGlkaS5JbmplY3Rvcn0gW2luamVjdG9yXSBhbiAob3B0aW9uYWwpIGluamVjdG9yIHRvIGJvb3RzdHJhcCB0aGUgZGlhZ3JhbSB3aXRoXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERpYWdyYW0ob3B0aW9ucywgaW5qZWN0b3IpIHtcblxuICAvLyBjcmVhdGUgaW5qZWN0b3IgdW5sZXNzIGV4cGxpY2l0bHkgc3BlY2lmaWVkXG4gIHRoaXMuaW5qZWN0b3IgPSBpbmplY3RvciA9IGluamVjdG9yIHx8IGNyZWF0ZUluamVjdG9yKG9wdGlvbnMpO1xuXG4gIC8vIEFQSVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIGRpYWdyYW0gc2VydmljZVxuICAgKlxuICAgKiBAbWV0aG9kIERpYWdyYW0jZ2V0XG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBkaWFncmFtIHNlcnZpY2UgdG8gYmUgcmV0cmlldmVkXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3N0cmljdD10cnVlXSBpZiBmYWxzZSwgcmVzb2x2ZSBtaXNzaW5nIHNlcnZpY2VzIHRvIG51bGxcbiAgICovXG4gIHRoaXMuZ2V0ID0gaW5qZWN0b3IuZ2V0O1xuXG4gIC8qKlxuICAgKiBFeGVjdXRlcyBhIGZ1bmN0aW9uIGludG8gd2hpY2ggZGlhZ3JhbSBzZXJ2aWNlcyBhcmUgaW5qZWN0ZWRcbiAgICpcbiAgICogQG1ldGhvZCBEaWFncmFtI2ludm9rZVxuICAgKlxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufE9iamVjdFtdfSBmbiB0aGUgZnVuY3Rpb24gdG8gcmVzb2x2ZVxuICAgKiBAcGFyYW0ge09iamVjdH0gbG9jYWxzIGEgbnVtYmVyIG9mIGxvY2FscyB0byB1c2UgdG8gcmVzb2x2ZSBjZXJ0YWluIGRlcGVuZGVuY2llc1xuICAgKi9cbiAgdGhpcy5pbnZva2UgPSBpbmplY3Rvci5pbnZva2U7XG5cbiAgLy8gaW5pdFxuXG4gIC8vIGluZGljYXRlIHZpYSBldmVudFxuXG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhbGwgcGx1Zy1pbnMgYXJlIGxvYWRlZC5cbiAgICpcbiAgICogVXNlIHRoaXMgZXZlbnQgdG8gZmlyZSBvdGhlciBldmVudHMgdG8gaW50ZXJlc3RlZCBwbHVnLWluc1xuICAgKlxuICAgKiBAbWVtYmVyT2YgRGlhZ3JhbVxuICAgKlxuICAgKiBAZXZlbnQgZGlhZ3JhbS5pbml0XG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqXG4gICAqIGV2ZW50QnVzLm9uKCdkaWFncmFtLmluaXQnLCBmdW5jdGlvbigpIHtcbiAgICogICBldmVudEJ1cy5maXJlKCdteS1jdXN0b20tZXZlbnQnLCB7IGZvbzogJ0JBUicgfSk7XG4gICAqIH0pO1xuICAgKlxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKi9cbiAgdGhpcy5nZXQoJ2V2ZW50QnVzJykuZmlyZSgnZGlhZ3JhbS5pbml0Jyk7XG59XG5cblxuLyoqXG4gKiBEZXN0cm95cyB0aGUgZGlhZ3JhbVxuICpcbiAqIEBtZXRob2QgIERpYWdyYW0jZGVzdHJveVxuICovXG5EaWFncmFtLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuZ2V0KCdldmVudEJ1cycpLmZpcmUoJ2RpYWdyYW0uZGVzdHJveScpO1xufTtcblxuLyoqXG4gKiBDbGVhciB0aGUgZGlhZ3JhbSwgcmVtb3ZpbmcgYWxsIGNvbnRlbnRzLlxuICovXG5EaWFncmFtLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmdldCgnZXZlbnRCdXMnKS5maXJlKCdkaWFncmFtLmNsZWFyJyk7XG59O1xuIiwiaW1wb3J0IHtcbiAgZm9yRWFjaCxcbiAgaXNGdW5jdGlvbixcbiAgaXNBcnJheSxcbiAgaXNOdW1iZXIsXG4gIGlzT2JqZWN0XG59IGZyb20gJ21pbi1kYXNoJztcblxuXG52YXIgREVGQVVMVF9QUklPUklUWSA9IDEwMDA7XG5cbi8qKlxuICogQSB1dGlsaXR5IHRoYXQgY2FuIGJlIHVzZWQgdG8gcGx1Zy1pbiBpbnRvIHRoZSBjb21tYW5kIGV4ZWN1dGlvbiBmb3JcbiAqIGV4dGVuc2lvbiBhbmQvb3IgdmFsaWRhdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICpcbiAqIEBleGFtcGxlXG4gKlxuICogaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcbiAqXG4gKiBpbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJ2RpYWdyYW0tanMvbGliL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcbiAqXG4gKiBmdW5jdGlvbiBDb21tYW5kTG9nZ2VyKGV2ZW50QnVzKSB7XG4gKiAgIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcbiAqXG4gKiAgIHRoaXMucHJlRXhlY3V0ZShmdW5jdGlvbihldmVudCkge1xuICogICAgIGNvbnNvbGUubG9nKCdjb21tYW5kIHByZS1leGVjdXRlJywgZXZlbnQpO1xuICogICB9KTtcbiAqIH1cbiAqXG4gKiBpbmhlcml0cyhDb21tYW5kTG9nZ2VyLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xuICpcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ29tbWFuZEludGVyY2VwdG9yKGV2ZW50QnVzKSB7XG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG59XG5cbkNvbW1hbmRJbnRlcmNlcHRvci4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07XG5cbmZ1bmN0aW9uIHVud3JhcEV2ZW50KGZuLCB0aGF0KSB7XG4gIHJldHVybiBmdW5jdGlvbihldmVudCkge1xuICAgIHJldHVybiBmbi5jYWxsKHRoYXQgfHwgbnVsbCwgZXZlbnQuY29udGV4dCwgZXZlbnQuY29tbWFuZCwgZXZlbnQpO1xuICB9O1xufVxuXG4vKipcbiAqIFJlZ2lzdGVyIGFuIGludGVyY2VwdG9yIGZvciBhIGNvbW1hbmQgZXhlY3V0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gW2V2ZW50c10gbGlzdCBvZiBjb21tYW5kcyB0byByZWdpc3RlciBvblxuICogQHBhcmFtIHtzdHJpbmd9IFtob29rXSBjb21tYW5kIGhvb2ssIGkuZS4gcHJlRXhlY3V0ZSwgZXhlY3V0ZWQgdG8gbGlzdGVuIG9uXG4gKiBAcGFyYW0ge251bWJlcn0gW3ByaW9yaXR5XSB0aGUgcHJpb3JpdHkgb24gd2hpY2ggdG8gaG9vayBpbnRvIHRoZSBleGVjdXRpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJGbiBpbnRlcmNlcHRvciB0byBiZSBpbnZva2VkIHdpdGggKGV2ZW50KVxuICogQHBhcmFtIHtib29sZWFufSB1bndyYXAgaWYgdHJ1ZSwgdW53cmFwIHRoZSBldmVudCBhbmQgcGFzcyAoY29udGV4dCwgY29tbWFuZCwgZXZlbnQpIHRvIHRoZVxuICogICAgICAgICAgICAgICAgICAgICAgICAgIGxpc3RlbmVyIGluc3RlYWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBbdGhhdF0gUGFzcyBjb250ZXh0IChgdGhpc2ApIHRvIHRoZSBoYW5kbGVyIGZ1bmN0aW9uXG4gKi9cbkNvbW1hbmRJbnRlcmNlcHRvci5wcm90b3R5cGUub24gPSBmdW5jdGlvbihldmVudHMsIGhvb2ssIHByaW9yaXR5LCBoYW5kbGVyRm4sIHVud3JhcCwgdGhhdCkge1xuXG4gIGlmIChpc0Z1bmN0aW9uKGhvb2spIHx8IGlzTnVtYmVyKGhvb2spKSB7XG4gICAgdGhhdCA9IHVud3JhcDtcbiAgICB1bndyYXAgPSBoYW5kbGVyRm47XG4gICAgaGFuZGxlckZuID0gcHJpb3JpdHk7XG4gICAgcHJpb3JpdHkgPSBob29rO1xuICAgIGhvb2sgPSBudWxsO1xuICB9XG5cbiAgaWYgKGlzRnVuY3Rpb24ocHJpb3JpdHkpKSB7XG4gICAgdGhhdCA9IHVud3JhcDtcbiAgICB1bndyYXAgPSBoYW5kbGVyRm47XG4gICAgaGFuZGxlckZuID0gcHJpb3JpdHk7XG4gICAgcHJpb3JpdHkgPSBERUZBVUxUX1BSSU9SSVRZO1xuICB9XG5cbiAgaWYgKGlzT2JqZWN0KHVud3JhcCkpIHtcbiAgICB0aGF0ID0gdW53cmFwO1xuICAgIHVud3JhcCA9IGZhbHNlO1xuICB9XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGhhbmRsZXJGbikpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2hhbmRsZXJGbiBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcbiAgfVxuXG4gIGlmICghaXNBcnJheShldmVudHMpKSB7XG4gICAgZXZlbnRzID0gWyBldmVudHMgXTtcbiAgfVxuXG4gIHZhciBldmVudEJ1cyA9IHRoaXMuX2V2ZW50QnVzO1xuXG4gIGZvckVhY2goZXZlbnRzLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgLy8gY29uY2F0IGNvbW1hbmRTdGFjayguZXZlbnQpPyguaG9vayk/XG4gICAgdmFyIGZ1bGxFdmVudCA9IFsgJ2NvbW1hbmRTdGFjaycsIGV2ZW50LCBob29rIF0uZmlsdGVyKGZ1bmN0aW9uKGUpIHsgcmV0dXJuIGU7IH0pLmpvaW4oJy4nKTtcblxuICAgIGV2ZW50QnVzLm9uKGZ1bGxFdmVudCwgcHJpb3JpdHksIHVud3JhcCA/IHVud3JhcEV2ZW50KGhhbmRsZXJGbiwgdGhhdCkgOiBoYW5kbGVyRm4sIHRoYXQpO1xuICB9KTtcbn07XG5cblxudmFyIGhvb2tzID0gW1xuICAnY2FuRXhlY3V0ZScsXG4gICdwcmVFeGVjdXRlJyxcbiAgJ3ByZUV4ZWN1dGVkJyxcbiAgJ2V4ZWN1dGUnLFxuICAnZXhlY3V0ZWQnLFxuICAncG9zdEV4ZWN1dGUnLFxuICAncG9zdEV4ZWN1dGVkJyxcbiAgJ3JldmVydCcsXG4gICdyZXZlcnRlZCdcbl07XG5cbi8qXG4gKiBJbnN0YWxsIGhvb2sgc2hvcnRjdXRzXG4gKlxuICogVGhpcyB3aWxsIGdlbmVyYXRlIHRoZSBDb21tYW5kSW50ZXJjZXB0b3IjKHByZUV4ZWN1dGV8Li4ufHJldmVydGVkKSBtZXRob2RzXG4gKiB3aGljaCB3aWxsIGluIHRlcm0gZm9yd2FyZCB0byBDb21tYW5kSW50ZXJjZXB0b3Ijb24uXG4gKi9cbmZvckVhY2goaG9va3MsIGZ1bmN0aW9uKGhvb2spIHtcblxuICAvKipcbiAgICoge2NhbkV4ZWN1dGV8cHJlRXhlY3V0ZXxwcmVFeGVjdXRlZHxleGVjdXRlfGV4ZWN1dGVkfHBvc3RFeGVjdXRlfHBvc3RFeGVjdXRlZHxyZXZlcnR8cmV2ZXJ0ZWR9XG4gICAqXG4gICAqIEEgbmFtZWQgaG9vayBmb3IgcGx1Z2dpbmcgaW50byB0aGUgY29tbWFuZCBleGVjdXRpb25cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gW2V2ZW50c10gbGlzdCBvZiBjb21tYW5kcyB0byByZWdpc3RlciBvblxuICAgKiBAcGFyYW0ge251bWJlcn0gW3ByaW9yaXR5XSB0aGUgcHJpb3JpdHkgb24gd2hpY2ggdG8gaG9vayBpbnRvIHRoZSBleGVjdXRpb25cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlckZuIGludGVyY2VwdG9yIHRvIGJlIGludm9rZWQgd2l0aCAoZXZlbnQpXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3Vud3JhcD1mYWxzZV0gaWYgdHJ1ZSwgdW53cmFwIHRoZSBldmVudCBhbmQgcGFzcyAoY29udGV4dCwgY29tbWFuZCwgZXZlbnQpIHRvIHRoZVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgbGlzdGVuZXIgaW5zdGVhZFxuICAgKiBAcGFyYW0ge09iamVjdH0gW3RoYXRdIFBhc3MgY29udGV4dCAoYHRoaXNgKSB0byB0aGUgaGFuZGxlciBmdW5jdGlvblxuICAgKi9cbiAgQ29tbWFuZEludGVyY2VwdG9yLnByb3RvdHlwZVtob29rXSA9IGZ1bmN0aW9uKGV2ZW50cywgcHJpb3JpdHksIGhhbmRsZXJGbiwgdW53cmFwLCB0aGF0KSB7XG5cbiAgICBpZiAoaXNGdW5jdGlvbihldmVudHMpIHx8IGlzTnVtYmVyKGV2ZW50cykpIHtcbiAgICAgIHRoYXQgPSB1bndyYXA7XG4gICAgICB1bndyYXAgPSBoYW5kbGVyRm47XG4gICAgICBoYW5kbGVyRm4gPSBwcmlvcml0eTtcbiAgICAgIHByaW9yaXR5ID0gZXZlbnRzO1xuICAgICAgZXZlbnRzID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLm9uKGV2ZW50cywgaG9vaywgcHJpb3JpdHksIGhhbmRsZXJGbiwgdW53cmFwLCB0aGF0KTtcbiAgfTtcbn0pO1xuIiwiaW1wb3J0IHtcbiAgdW5pcXVlQnksXG4gIGlzQXJyYXlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5cbi8qKlxuICogQSBzZXJ2aWNlIHRoYXQgb2ZmZXJzIHVuLSBhbmQgcmVkb2FibGUgZXhlY3V0aW9uIG9mIGNvbW1hbmRzLlxuICpcbiAqIFRoZSBjb21tYW5kIHN0YWNrIGlzIHJlc3BvbnNpYmxlIGZvciBleGVjdXRpbmcgbW9kZWxpbmcgYWN0aW9uc1xuICogaW4gYSB1bi0gYW5kIHJlZG9hYmxlIG1hbm5lci4gVG8gZG8gdGhpcyBpdCBkZWxlZ2F0ZXMgdGhlIGFjdHVhbFxuICogY29tbWFuZCBleGVjdXRpb24gdG8ge0BsaW5rIENvbW1hbmRIYW5kbGVyfXMuXG4gKlxuICogQ29tbWFuZCBoYW5kbGVycyBwcm92aWRlIHtAbGluayBDb21tYW5kSGFuZGxlciNleGVjdXRlKGN0eCl9IGFuZFxuICoge0BsaW5rIENvbW1hbmRIYW5kbGVyI3JldmVydChjdHgpfSBtZXRob2RzIHRvIHVuLSBhbmQgcmVkbyBhIGNvbW1hbmRcbiAqIGlkZW50aWZpZWQgYnkgYSBjb21tYW5kIGNvbnRleHQuXG4gKlxuICpcbiAqICMjIExpZmUtQ3ljbGUgZXZlbnRzXG4gKlxuICogSW4gdGhlIHByb2Nlc3MgdGhlIGNvbW1hbmQgc3RhY2sgZmlyZXMgYSBudW1iZXIgb2YgbGlmZS1jeWNsZSBldmVudHNcbiAqIHRoYXQgb3RoZXIgY29tcG9uZW50cyB0byBwYXJ0aWNpcGF0ZSBpbiB0aGUgY29tbWFuZCBleGVjdXRpb24uXG4gKlxuICogICAgKiBwcmVFeGVjdXRlXG4gKiAgICAqIHByZUV4ZWN1dGVkXG4gKiAgICAqIGV4ZWN1dGVcbiAqICAgICogZXhlY3V0ZWRcbiAqICAgICogcG9zdEV4ZWN1dGVcbiAqICAgICogcG9zdEV4ZWN1dGVkXG4gKiAgICAqIHJldmVydFxuICogICAgKiByZXZlcnRlZFxuICpcbiAqIEEgc3BlY2lhbCBldmVudCBpcyB1c2VkIGZvciB2YWxpZGF0aW5nLCB3aGV0aGVyIGEgY29tbWFuZCBjYW4gYmVcbiAqIHBlcmZvcm1lZCBwcmlvciB0byBpdHMgZXhlY3V0aW9uLlxuICpcbiAqICAgICogY2FuRXhlY3V0ZVxuICpcbiAqIEVhY2ggb2YgdGhlIGV2ZW50cyBpcyBmaXJlZCBhcyBgY29tbWFuZFN0YWNrLntldmVudE5hbWV9YCBhbmRcbiAqIGBjb21tYW5kU3RhY2sue2NvbW1hbmROYW1lfS57ZXZlbnROYW1lfWAsIHJlc3BlY3RpdmVseS4gVGhpcyBnaXZlc1xuICogY29tcG9uZW50cyBmaW5lIGdyYWluZWQgY29udHJvbCBvbiB3aGVyZSB0byBob29rIGludG8uXG4gKlxuICogVGhlIGV2ZW50IG9iamVjdCBmaXJlZCB0cmFuc3BvcnRzIGBjb21tYW5kYCwgdGhlIG5hbWUgb2YgdGhlXG4gKiBjb21tYW5kIGFuZCBgY29udGV4dGAsIHRoZSBjb21tYW5kIGNvbnRleHQuXG4gKlxuICpcbiAqICMjIENyZWF0aW5nIENvbW1hbmQgSGFuZGxlcnNcbiAqXG4gKiBDb21tYW5kIGhhbmRsZXJzIHNob3VsZCBwcm92aWRlIHRoZSB7QGxpbmsgQ29tbWFuZEhhbmRsZXIjZXhlY3V0ZShjdHgpfVxuICogYW5kIHtAbGluayBDb21tYW5kSGFuZGxlciNyZXZlcnQoY3R4KX0gbWV0aG9kcyB0byBpbXBsZW1lbnRcbiAqIHJlZG9pbmcgYW5kIHVuZG9pbmcgb2YgYSBjb21tYW5kLlxuICpcbiAqIEEgY29tbWFuZCBoYW5kbGVyIF9tdXN0XyBlbnN1cmUgdW5kbyBpcyBwZXJmb3JtZWQgcHJvcGVybHkgaW4gb3JkZXJcbiAqIG5vdCB0byBicmVhayB0aGUgdW5kbyBjaGFpbi4gSXQgbXVzdCBhbHNvIHJldHVybiB0aGUgc2hhcGVzIHRoYXRcbiAqIGdvdCBjaGFuZ2VkIGR1cmluZyB0aGUgYGV4ZWN1dGVgIGFuZCBgcmV2ZXJ0YCBvcGVyYXRpb25zLlxuICpcbiAqIENvbW1hbmQgaGFuZGxlcnMgbWF5IGV4ZWN1dGUgb3RoZXIgbW9kZWxpbmcgb3BlcmF0aW9ucyAoYW5kIHRodXNcbiAqIGNvbW1hbmRzKSBpbiB0aGVpciBgcHJlRXhlY3V0ZWAgYW5kIGBwb3N0RXhlY3V0ZWAgcGhhc2VzLiBUaGUgY29tbWFuZFxuICogc3RhY2sgd2lsbCBwcm9wZXJseSBncm91cCBhbGwgY29tbWFuZHMgdG9nZXRoZXIgaW50byBhIGxvZ2ljYWwgdW5pdFxuICogdGhhdCBtYXkgYmUgcmUtIGFuZCB1bmRvbmUgYXRvbWljYWxseS5cbiAqXG4gKiBDb21tYW5kIGhhbmRsZXJzIG11c3Qgbm90IGV4ZWN1dGUgb3RoZXIgY29tbWFuZHMgZnJvbSB3aXRoaW4gdGhlaXJcbiAqIGNvcmUgaW1wbGVtZW50YXRpb24gKGBleGVjdXRlYCwgYHJldmVydGApLlxuICpcbiAqXG4gKiAjIyBDaGFuZ2UgVHJhY2tpbmdcbiAqXG4gKiBEdXJpbmcgdGhlIGV4ZWN1dGlvbiBvZiB0aGUgQ29tbWFuZFN0YWNrIGl0IHdpbGwga2VlcCB0cmFjayBvZiBhbGxcbiAqIGVsZW1lbnRzIHRoYXQgaGF2ZSBiZWVuIHRvdWNoZWQgZHVyaW5nIHRoZSBjb21tYW5kJ3MgZXhlY3V0aW9uLlxuICpcbiAqIEF0IHRoZSBlbmQgb2YgdGhlIENvbW1hbmRTdGFjayBleGVjdXRpb24gaXQgd2lsbCBub3RpZnkgaW50ZXJlc3RlZFxuICogY29tcG9uZW50cyB2aWEgYW4gJ2VsZW1lbnRzLmNoYW5nZWQnIGV2ZW50IHdpdGggYWxsIHRoZSBkaXJ0eVxuICogZWxlbWVudHMuXG4gKlxuICogVGhlIGV2ZW50IGNhbiBiZSBwaWNrZWQgdXAgYnkgY29tcG9uZW50cyB0aGF0IGFyZSBpbnRlcmVzdGVkIGluIHRoZSBmYWN0XG4gKiB0aGF0IGVsZW1lbnRzIGhhdmUgYmVlbiBjaGFuZ2VkLiBPbmUgdXNlIGNhc2UgZm9yIHRoaXMgaXMgdXBkYXRpbmdcbiAqIHRoZWlyIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBhZnRlciBtb3ZpbmcgLyByZXNpemluZyBvciBkZWxldGlvbi5cbiAqXG4gKiBAc2VlIENvbW1hbmRIYW5kbGVyXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvbW1hbmRTdGFjayhldmVudEJ1cywgaW5qZWN0b3IpIHtcblxuICAvKipcbiAgICogQSBtYXAgb2YgYWxsIHJlZ2lzdGVyZWQgY29tbWFuZCBoYW5kbGVycy5cbiAgICpcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHRoaXMuX2hhbmRsZXJNYXAgPSB7fTtcblxuICAvKipcbiAgICogQSBzdGFjayBjb250YWluaW5nIGFsbCByZS91bmRvYWJsZSBhY3Rpb25zIG9uIHRoZSBkaWFncmFtXG4gICAqXG4gICAqIEB0eXBlIHtBcnJheTxPYmplY3Q+fVxuICAgKi9cbiAgdGhpcy5fc3RhY2sgPSBbXTtcblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgaW5kZXggb24gdGhlIHN0YWNrXG4gICAqXG4gICAqIEB0eXBlIHtudW1iZXJ9XG4gICAqL1xuICB0aGlzLl9zdGFja0lkeCA9IC0xO1xuXG4gIC8qKlxuICAgKiBDdXJyZW50IGFjdGl2ZSBjb21tYW5kU3RhY2sgZXhlY3V0aW9uXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLl9jdXJyZW50RXhlY3V0aW9uID0ge1xuICAgIGFjdGlvbnM6IFtdLFxuICAgIGRpcnR5OiBbXVxuICB9O1xuXG5cbiAgdGhpcy5faW5qZWN0b3IgPSBpbmplY3RvcjtcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcblxuICB0aGlzLl91aWQgPSAxO1xuXG4gIGV2ZW50QnVzLm9uKFtcbiAgICAnZGlhZ3JhbS5kZXN0cm95JyxcbiAgICAnZGlhZ3JhbS5jbGVhcidcbiAgXSwgZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5jbGVhcihmYWxzZSk7XG4gIH0sIHRoaXMpO1xufVxuXG5Db21tYW5kU3RhY2suJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2luamVjdG9yJyBdO1xuXG5cbi8qKlxuICogRXhlY3V0ZSBhIGNvbW1hbmRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gY29tbWFuZCB0aGUgY29tbWFuZCB0byBleGVjdXRlXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dCB0aGUgZW52aXJvbm1lbnQgdG8gZXhlY3V0ZSB0aGUgY29tbWFuZCBpblxuICovXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb21tYW5kLCBjb250ZXh0KSB7XG4gIGlmICghY29tbWFuZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignY29tbWFuZCByZXF1aXJlZCcpO1xuICB9XG5cbiAgdmFyIGFjdGlvbiA9IHsgY29tbWFuZDogY29tbWFuZCwgY29udGV4dDogY29udGV4dCB9O1xuXG4gIHRoaXMuX3B1c2hBY3Rpb24oYWN0aW9uKTtcbiAgdGhpcy5faW50ZXJuYWxFeGVjdXRlKGFjdGlvbik7XG4gIHRoaXMuX3BvcEFjdGlvbihhY3Rpb24pO1xufTtcblxuXG4vKipcbiAqIEFzayB3aGV0aGVyIGEgZ2l2ZW4gY29tbWFuZCBjYW4gYmUgZXhlY3V0ZWQuXG4gKlxuICogSW1wbGVtZW50b3JzIG1heSBob29rIGludG8gdGhlIG1lY2hhbmlzbSBvbiB0d28gd2F5czpcbiAqXG4gKiAgICogaW4gZXZlbnQgbGlzdGVuZXJzOlxuICpcbiAqICAgICBVc2VycyBtYXkgcHJldmVudCB0aGUgZXhlY3V0aW9uIHZpYSBhbiBldmVudCBsaXN0ZW5lci5cbiAqICAgICBJdCBtdXN0IHByZXZlbnQgdGhlIGRlZmF1bHQgYWN0aW9uIGZvciBgY29tbWFuZFN0YWNrLig8Y29tbWFuZD4uKWNhbkV4ZWN1dGVgIGV2ZW50cy5cbiAqXG4gKiAgICogaW4gY29tbWFuZCBoYW5kbGVyczpcbiAqXG4gKiAgICAgSWYgdGhlIG1ldGhvZCB7QGxpbmsgQ29tbWFuZEhhbmRsZXIjY2FuRXhlY3V0ZX0gaXMgaW1wbGVtZW50ZWQgaW4gYSBoYW5kbGVyXG4gKiAgICAgaXQgd2lsbCBiZSBjYWxsZWQgdG8gZmlndXJlIG91dCB3aGV0aGVyIHRoZSBleGVjdXRpb24gaXMgYWxsb3dlZC5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGNvbW1hbmQgdGhlIGNvbW1hbmQgdG8gZXhlY3V0ZVxuICogQHBhcmFtICB7T2JqZWN0fSBjb250ZXh0IHRoZSBlbnZpcm9ubWVudCB0byBleGVjdXRlIHRoZSBjb21tYW5kIGluXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgY29tbWFuZCBjYW4gYmUgZXhlY3V0ZWRcbiAqL1xuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5jYW5FeGVjdXRlID0gZnVuY3Rpb24oY29tbWFuZCwgY29udGV4dCkge1xuXG4gIHZhciBhY3Rpb24gPSB7IGNvbW1hbmQ6IGNvbW1hbmQsIGNvbnRleHQ6IGNvbnRleHQgfTtcblxuICB2YXIgaGFuZGxlciA9IHRoaXMuX2dldEhhbmRsZXIoY29tbWFuZCk7XG5cbiAgdmFyIHJlc3VsdCA9IHRoaXMuX2ZpcmUoY29tbWFuZCwgJ2NhbkV4ZWN1dGUnLCBhY3Rpb24pO1xuXG4gIC8vIGhhbmRsZXIjY2FuRXhlY3V0ZSB3aWxsIG9ubHkgYmUgY2FsbGVkIGlmIG5vIGxpc3RlbmVyXG4gIC8vIGRlY2lkZWQgb24gYSByZXN1bHQgYWxyZWFkeVxuICBpZiAocmVzdWx0ID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoIWhhbmRsZXIpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoaGFuZGxlci5jYW5FeGVjdXRlKSB7XG4gICAgICByZXN1bHQgPSBoYW5kbGVyLmNhbkV4ZWN1dGUoY29udGV4dCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cblxuLyoqXG4gKiBDbGVhciB0aGUgY29tbWFuZCBzdGFjaywgZXJhc2luZyBhbGwgdW5kbyAvIHJlZG8gaGlzdG9yeVxuICovXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oZW1pdCkge1xuICB0aGlzLl9zdGFjay5sZW5ndGggPSAwO1xuICB0aGlzLl9zdGFja0lkeCA9IC0xO1xuXG4gIGlmIChlbWl0ICE9PSBmYWxzZSkge1xuICAgIHRoaXMuX2ZpcmUoJ2NoYW5nZWQnKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIFVuZG8gbGFzdCBjb21tYW5kKHMpXG4gKi9cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUudW5kbyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgYWN0aW9uID0gdGhpcy5fZ2V0VW5kb0FjdGlvbigpLFxuICAgICAgbmV4dDtcblxuICBpZiAoYWN0aW9uKSB7XG4gICAgdGhpcy5fcHVzaEFjdGlvbihhY3Rpb24pO1xuXG4gICAgd2hpbGUgKGFjdGlvbikge1xuICAgICAgdGhpcy5faW50ZXJuYWxVbmRvKGFjdGlvbik7XG4gICAgICBuZXh0ID0gdGhpcy5fZ2V0VW5kb0FjdGlvbigpO1xuXG4gICAgICBpZiAoIW5leHQgfHwgbmV4dC5pZCAhPT0gYWN0aW9uLmlkKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICBhY3Rpb24gPSBuZXh0O1xuICAgIH1cblxuICAgIHRoaXMuX3BvcEFjdGlvbigpO1xuICB9XG59O1xuXG5cbi8qKlxuICogUmVkbyBsYXN0IGNvbW1hbmQocylcbiAqL1xuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5yZWRvID0gZnVuY3Rpb24oKSB7XG4gIHZhciBhY3Rpb24gPSB0aGlzLl9nZXRSZWRvQWN0aW9uKCksXG4gICAgICBuZXh0O1xuXG4gIGlmIChhY3Rpb24pIHtcbiAgICB0aGlzLl9wdXNoQWN0aW9uKGFjdGlvbik7XG5cbiAgICB3aGlsZSAoYWN0aW9uKSB7XG4gICAgICB0aGlzLl9pbnRlcm5hbEV4ZWN1dGUoYWN0aW9uLCB0cnVlKTtcbiAgICAgIG5leHQgPSB0aGlzLl9nZXRSZWRvQWN0aW9uKCk7XG5cbiAgICAgIGlmICghbmV4dCB8fCBuZXh0LmlkICE9PSBhY3Rpb24uaWQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGFjdGlvbiA9IG5leHQ7XG4gICAgfVxuXG4gICAgdGhpcy5fcG9wQWN0aW9uKCk7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBSZWdpc3RlciBhIGhhbmRsZXIgaW5zdGFuY2Ugd2l0aCB0aGUgY29tbWFuZCBzdGFja1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb21tYW5kXG4gKiBAcGFyYW0ge0NvbW1hbmRIYW5kbGVyfSBoYW5kbGVyXG4gKi9cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUucmVnaXN0ZXIgPSBmdW5jdGlvbihjb21tYW5kLCBoYW5kbGVyKSB7XG4gIHRoaXMuX3NldEhhbmRsZXIoY29tbWFuZCwgaGFuZGxlcik7XG59O1xuXG5cbi8qKlxuICogUmVnaXN0ZXIgYSBoYW5kbGVyIHR5cGUgd2l0aCB0aGUgY29tbWFuZCBzdGFja1xuICogYnkgaW5zdGFudGlhdGluZyBpdCBhbmQgaW5qZWN0aW5nIGl0cyBkZXBlbmRlbmNpZXMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGNvbW1hbmRcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGEgY29uc3RydWN0b3IgZm9yIGEge0BsaW5rIENvbW1hbmRIYW5kbGVyfVxuICovXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLnJlZ2lzdGVySGFuZGxlciA9IGZ1bmN0aW9uKGNvbW1hbmQsIGhhbmRsZXJDbHMpIHtcblxuICBpZiAoIWNvbW1hbmQgfHwgIWhhbmRsZXJDbHMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2NvbW1hbmQgYW5kIGhhbmRsZXJDbHMgbXVzdCBiZSBkZWZpbmVkJyk7XG4gIH1cblxuICB2YXIgaGFuZGxlciA9IHRoaXMuX2luamVjdG9yLmluc3RhbnRpYXRlKGhhbmRsZXJDbHMpO1xuICB0aGlzLnJlZ2lzdGVyKGNvbW1hbmQsIGhhbmRsZXIpO1xufTtcblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5jYW5VbmRvID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAhIXRoaXMuX2dldFVuZG9BY3Rpb24oKTtcbn07XG5cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUuY2FuUmVkbyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gISF0aGlzLl9nZXRSZWRvQWN0aW9uKCk7XG59O1xuXG4vLyBzdGFjayBhY2Nlc3MgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fZ2V0UmVkb0FjdGlvbiA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fc3RhY2tbdGhpcy5fc3RhY2tJZHggKyAxXTtcbn07XG5cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fZ2V0VW5kb0FjdGlvbiA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fc3RhY2tbdGhpcy5fc3RhY2tJZHhdO1xufTtcblxuXG4vLyBpbnRlcm5hbCBmdW5jdGlvbmFsaXR5IC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5faW50ZXJuYWxVbmRvID0gZnVuY3Rpb24oYWN0aW9uKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgY29tbWFuZCA9IGFjdGlvbi5jb21tYW5kLFxuICAgICAgY29udGV4dCA9IGFjdGlvbi5jb250ZXh0O1xuXG4gIHZhciBoYW5kbGVyID0gdGhpcy5fZ2V0SGFuZGxlcihjb21tYW5kKTtcblxuICAvLyBndWFyZCBhZ2FpbnN0IGlsbGVnYWwgbmVzdGVkIGNvbW1hbmQgc3RhY2sgaW52b2NhdGlvbnNcbiAgdGhpcy5fYXRvbWljRG8oZnVuY3Rpb24oKSB7XG4gICAgc2VsZi5fZmlyZShjb21tYW5kLCAncmV2ZXJ0JywgYWN0aW9uKTtcblxuICAgIGlmIChoYW5kbGVyLnJldmVydCkge1xuICAgICAgc2VsZi5fbWFya0RpcnR5KGhhbmRsZXIucmV2ZXJ0KGNvbnRleHQpKTtcbiAgICB9XG5cbiAgICBzZWxmLl9yZXZlcnRlZEFjdGlvbihhY3Rpb24pO1xuXG4gICAgc2VsZi5fZmlyZShjb21tYW5kLCAncmV2ZXJ0ZWQnLCBhY3Rpb24pO1xuICB9KTtcbn07XG5cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fZmlyZSA9IGZ1bmN0aW9uKGNvbW1hbmQsIHF1YWxpZmllciwgZXZlbnQpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzKSB7XG4gICAgZXZlbnQgPSBxdWFsaWZpZXI7XG4gICAgcXVhbGlmaWVyID0gbnVsbDtcbiAgfVxuXG4gIHZhciBuYW1lcyA9IHF1YWxpZmllciA/IFsgY29tbWFuZCArICcuJyArIHF1YWxpZmllciwgcXVhbGlmaWVyIF0gOiBbIGNvbW1hbmQgXSxcbiAgICAgIGksIG5hbWUsIHJlc3VsdDtcblxuICBldmVudCA9IHRoaXMuX2V2ZW50QnVzLmNyZWF0ZUV2ZW50KGV2ZW50KTtcblxuICBmb3IgKGkgPSAwOyAobmFtZSA9IG5hbWVzW2ldKTsgaSsrKSB7XG4gICAgcmVzdWx0ID0gdGhpcy5fZXZlbnRCdXMuZmlyZSgnY29tbWFuZFN0YWNrLicgKyBuYW1lLCBldmVudCk7XG5cbiAgICBpZiAoZXZlbnQuY2FuY2VsQnViYmxlKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fY3JlYXRlSWQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX3VpZCsrO1xufTtcblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fYXRvbWljRG8gPSBmdW5jdGlvbihmbikge1xuXG4gIHZhciBleGVjdXRpb24gPSB0aGlzLl9jdXJyZW50RXhlY3V0aW9uO1xuXG4gIGV4ZWN1dGlvbi5hdG9taWMgPSB0cnVlO1xuXG4gIHRyeSB7XG4gICAgZm4oKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBleGVjdXRpb24uYXRvbWljID0gZmFsc2U7XG4gIH1cbn07XG5cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUuX2ludGVybmFsRXhlY3V0ZSA9IGZ1bmN0aW9uKGFjdGlvbiwgcmVkbykge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGNvbW1hbmQgPSBhY3Rpb24uY29tbWFuZCxcbiAgICAgIGNvbnRleHQgPSBhY3Rpb24uY29udGV4dDtcblxuICB2YXIgaGFuZGxlciA9IHRoaXMuX2dldEhhbmRsZXIoY29tbWFuZCk7XG5cbiAgaWYgKCFoYW5kbGVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdubyBjb21tYW5kIGhhbmRsZXIgcmVnaXN0ZXJlZCBmb3IgPCcgKyBjb21tYW5kICsgJz4nKTtcbiAgfVxuXG4gIHRoaXMuX3B1c2hBY3Rpb24oYWN0aW9uKTtcblxuICBpZiAoIXJlZG8pIHtcbiAgICB0aGlzLl9maXJlKGNvbW1hbmQsICdwcmVFeGVjdXRlJywgYWN0aW9uKTtcblxuICAgIGlmIChoYW5kbGVyLnByZUV4ZWN1dGUpIHtcbiAgICAgIGhhbmRsZXIucHJlRXhlY3V0ZShjb250ZXh0KTtcbiAgICB9XG5cbiAgICB0aGlzLl9maXJlKGNvbW1hbmQsICdwcmVFeGVjdXRlZCcsIGFjdGlvbik7XG4gIH1cblxuICAvLyBndWFyZCBhZ2FpbnN0IGlsbGVnYWwgbmVzdGVkIGNvbW1hbmQgc3RhY2sgaW52b2NhdGlvbnNcbiAgdGhpcy5fYXRvbWljRG8oZnVuY3Rpb24oKSB7XG5cbiAgICBzZWxmLl9maXJlKGNvbW1hbmQsICdleGVjdXRlJywgYWN0aW9uKTtcblxuICAgIGlmIChoYW5kbGVyLmV4ZWN1dGUpIHtcblxuICAgICAgLy8gYWN0dWFsIGV4ZWN1dGUgKyBtYXJrIHJldHVybiByZXN1bHRzIGFzIGRpcnR5XG4gICAgICBzZWxmLl9tYXJrRGlydHkoaGFuZGxlci5leGVjdXRlKGNvbnRleHQpKTtcbiAgICB9XG5cbiAgICAvLyBsb2cgdG8gc3RhY2tcbiAgICBzZWxmLl9leGVjdXRlZEFjdGlvbihhY3Rpb24sIHJlZG8pO1xuXG4gICAgc2VsZi5fZmlyZShjb21tYW5kLCAnZXhlY3V0ZWQnLCBhY3Rpb24pO1xuICB9KTtcblxuICBpZiAoIXJlZG8pIHtcbiAgICB0aGlzLl9maXJlKGNvbW1hbmQsICdwb3N0RXhlY3V0ZScsIGFjdGlvbik7XG5cbiAgICBpZiAoaGFuZGxlci5wb3N0RXhlY3V0ZSkge1xuICAgICAgaGFuZGxlci5wb3N0RXhlY3V0ZShjb250ZXh0KTtcbiAgICB9XG5cbiAgICB0aGlzLl9maXJlKGNvbW1hbmQsICdwb3N0RXhlY3V0ZWQnLCBhY3Rpb24pO1xuICB9XG5cbiAgdGhpcy5fcG9wQWN0aW9uKGFjdGlvbik7XG59O1xuXG5cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUuX3B1c2hBY3Rpb24gPSBmdW5jdGlvbihhY3Rpb24pIHtcblxuICB2YXIgZXhlY3V0aW9uID0gdGhpcy5fY3VycmVudEV4ZWN1dGlvbixcbiAgICAgIGFjdGlvbnMgPSBleGVjdXRpb24uYWN0aW9ucztcblxuICB2YXIgYmFzZUFjdGlvbiA9IGFjdGlvbnNbMF07XG5cbiAgaWYgKGV4ZWN1dGlvbi5hdG9taWMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2lsbGVnYWwgaW52b2NhdGlvbiBpbiA8ZXhlY3V0ZT4gb3IgPHJldmVydD4gcGhhc2UgKGFjdGlvbjogJyArIGFjdGlvbi5jb21tYW5kICsgJyknKTtcbiAgfVxuXG4gIGlmICghYWN0aW9uLmlkKSB7XG4gICAgYWN0aW9uLmlkID0gKGJhc2VBY3Rpb24gJiYgYmFzZUFjdGlvbi5pZCkgfHwgdGhpcy5fY3JlYXRlSWQoKTtcbiAgfVxuXG4gIGFjdGlvbnMucHVzaChhY3Rpb24pO1xufTtcblxuXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLl9wb3BBY3Rpb24gPSBmdW5jdGlvbigpIHtcbiAgdmFyIGV4ZWN1dGlvbiA9IHRoaXMuX2N1cnJlbnRFeGVjdXRpb24sXG4gICAgICBhY3Rpb25zID0gZXhlY3V0aW9uLmFjdGlvbnMsXG4gICAgICBkaXJ0eSA9IGV4ZWN1dGlvbi5kaXJ0eTtcblxuICBhY3Rpb25zLnBvcCgpO1xuXG4gIGlmICghYWN0aW9ucy5sZW5ndGgpIHtcbiAgICB0aGlzLl9ldmVudEJ1cy5maXJlKCdlbGVtZW50cy5jaGFuZ2VkJywgeyBlbGVtZW50czogdW5pcXVlQnkoJ2lkJywgZGlydHkucmV2ZXJzZSgpKSB9KTtcblxuICAgIGRpcnR5Lmxlbmd0aCA9IDA7XG5cbiAgICB0aGlzLl9maXJlKCdjaGFuZ2VkJyk7XG4gIH1cbn07XG5cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fbWFya0RpcnR5ID0gZnVuY3Rpb24oZWxlbWVudHMpIHtcbiAgdmFyIGV4ZWN1dGlvbiA9IHRoaXMuX2N1cnJlbnRFeGVjdXRpb247XG5cbiAgaWYgKCFlbGVtZW50cykge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGVsZW1lbnRzID0gaXNBcnJheShlbGVtZW50cykgPyBlbGVtZW50cyA6IFsgZWxlbWVudHMgXTtcblxuICBleGVjdXRpb24uZGlydHkgPSBleGVjdXRpb24uZGlydHkuY29uY2F0KGVsZW1lbnRzKTtcbn07XG5cblxuQ29tbWFuZFN0YWNrLnByb3RvdHlwZS5fZXhlY3V0ZWRBY3Rpb24gPSBmdW5jdGlvbihhY3Rpb24sIHJlZG8pIHtcbiAgdmFyIHN0YWNrSWR4ID0gKyt0aGlzLl9zdGFja0lkeDtcblxuICBpZiAoIXJlZG8pIHtcbiAgICB0aGlzLl9zdGFjay5zcGxpY2Uoc3RhY2tJZHgsIHRoaXMuX3N0YWNrLmxlbmd0aCwgYWN0aW9uKTtcbiAgfVxufTtcblxuXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLl9yZXZlcnRlZEFjdGlvbiA9IGZ1bmN0aW9uKGFjdGlvbikge1xuICB0aGlzLl9zdGFja0lkeC0tO1xufTtcblxuXG5Db21tYW5kU3RhY2sucHJvdG90eXBlLl9nZXRIYW5kbGVyID0gZnVuY3Rpb24oY29tbWFuZCkge1xuICByZXR1cm4gdGhpcy5faGFuZGxlck1hcFtjb21tYW5kXTtcbn07XG5cbkNvbW1hbmRTdGFjay5wcm90b3R5cGUuX3NldEhhbmRsZXIgPSBmdW5jdGlvbihjb21tYW5kLCBoYW5kbGVyKSB7XG4gIGlmICghY29tbWFuZCB8fCAhaGFuZGxlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignY29tbWFuZCBhbmQgaGFuZGxlciByZXF1aXJlZCcpO1xuICB9XG5cbiAgaWYgKHRoaXMuX2hhbmRsZXJNYXBbY29tbWFuZF0pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ292ZXJyaWRpbmcgaGFuZGxlciBmb3IgY29tbWFuZCA8JyArIGNvbW1hbmQgKyAnPicpO1xuICB9XG5cbiAgdGhpcy5faGFuZGxlck1hcFtjb21tYW5kXSA9IGhhbmRsZXI7XG59O1xuIiwiaW1wb3J0IENvbW1hbmRTdGFjayBmcm9tICcuL0NvbW1hbmRTdGFjayc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgY29tbWFuZFN0YWNrOiBbICd0eXBlJywgQ29tbWFuZFN0YWNrIF1cbn07XG4iLCJpbXBvcnQge1xuICBpc051bWJlcixcbiAgYXNzaWduLFxuICBmb3JFYWNoLFxuICBldmVyeSxcbiAgZGVib3VuY2UsXG4gIGJpbmQsXG4gIHJlZHVjZVxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGFkZCBhcyBjb2xsZWN0aW9uQWRkLFxuICByZW1vdmUgYXMgY29sbGVjdGlvblJlbW92ZVxufSBmcm9tICcuLi91dGlsL0NvbGxlY3Rpb25zJztcblxuaW1wb3J0IHtcbiAgZ2V0VHlwZVxufSBmcm9tICcuLi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjbGFzc2VzIGFzIHN2Z0NsYXNzZXMsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHRyYW5zZm9ybSBhcyBzdmdUcmFuc2Zvcm1cbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQgeyBjcmVhdGVNYXRyaXggYXMgY3JlYXRlTWF0cml4IH0gZnJvbSAndGlueS1zdmcnO1xuXG5cbmZ1bmN0aW9uIHJvdW5kKG51bWJlciwgcmVzb2x1dGlvbikge1xuICByZXR1cm4gTWF0aC5yb3VuZChudW1iZXIgKiByZXNvbHV0aW9uKSAvIHJlc29sdXRpb247XG59XG5cbmZ1bmN0aW9uIGVuc3VyZVB4KG51bWJlcikge1xuICByZXR1cm4gaXNOdW1iZXIobnVtYmVyKSA/IG51bWJlciArICdweCcgOiBudW1iZXI7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIEhUTUwgY29udGFpbmVyIGVsZW1lbnQgZm9yIGEgU1ZHIGVsZW1lbnQgd2l0aFxuICogdGhlIGdpdmVuIGNvbmZpZ3VyYXRpb25cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcbiAqIEByZXR1cm4ge0hUTUxFbGVtZW50fSB0aGUgY29udGFpbmVyIGVsZW1lbnRcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ29udGFpbmVyKG9wdGlvbnMpIHtcblxuICBvcHRpb25zID0gYXNzaWduKHt9LCB7IHdpZHRoOiAnMTAwJScsIGhlaWdodDogJzEwMCUnIH0sIG9wdGlvbnMpO1xuXG4gIHZhciBjb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lciB8fCBkb2N1bWVudC5ib2R5O1xuXG4gIC8vIGNyZWF0ZSBhIDxkaXY+IGFyb3VuZCB0aGUgc3ZnIGVsZW1lbnQgd2l0aCB0aGUgcmVzcGVjdGl2ZSBzaXplXG4gIC8vIHRoaXMgd2F5IHdlIGNhbiBhbHdheXMgZ2V0IHRoZSBjb3JyZWN0IGNvbnRhaW5lciBzaXplXG4gIC8vICh0aGlzIGlzIGltcG9zc2libGUgZm9yIDxzdmc+IGVsZW1lbnRzIGF0IHRoZSBtb21lbnQpXG4gIHZhciBwYXJlbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgcGFyZW50LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnZGpzLWNvbnRhaW5lcicpO1xuXG4gIGFzc2lnbihwYXJlbnQuc3R5bGUsIHtcbiAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJyxcbiAgICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gICAgd2lkdGg6IGVuc3VyZVB4KG9wdGlvbnMud2lkdGgpLFxuICAgIGhlaWdodDogZW5zdXJlUHgob3B0aW9ucy5oZWlnaHQpXG4gIH0pO1xuXG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChwYXJlbnQpO1xuXG4gIHJldHVybiBwYXJlbnQ7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUdyb3VwKHBhcmVudCwgY2xzLCBjaGlsZEluZGV4KSB7XG4gIHZhciBncm91cCA9IHN2Z0NyZWF0ZSgnZycpO1xuICBzdmdDbGFzc2VzKGdyb3VwKS5hZGQoY2xzKTtcblxuICB2YXIgaW5kZXggPSBjaGlsZEluZGV4ICE9PSB1bmRlZmluZWQgPyBjaGlsZEluZGV4IDogcGFyZW50LmNoaWxkTm9kZXMubGVuZ3RoIC0gMTtcblxuICAvLyBtdXN0IGVuc3VyZSBzZWNvbmQgYXJndW1lbnQgaXMgbm9kZSBvciBfbnVsbF9cbiAgLy8gY2YuIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9Ob2RlL2luc2VydEJlZm9yZVxuICBwYXJlbnQuaW5zZXJ0QmVmb3JlKGdyb3VwLCBwYXJlbnQuY2hpbGROb2Rlc1tpbmRleF0gfHwgbnVsbCk7XG5cbiAgcmV0dXJuIGdyb3VwO1xufVxuXG52YXIgQkFTRV9MQVlFUiA9ICdiYXNlJztcblxuXG52YXIgUkVRVUlSRURfTU9ERUxfQVRUUlMgPSB7XG4gIHNoYXBlOiBbICd4JywgJ3knLCAnd2lkdGgnLCAnaGVpZ2h0JyBdLFxuICBjb25uZWN0aW9uOiBbICd3YXlwb2ludHMnIF1cbn07XG5cbi8qKlxuICogVGhlIG1haW4gZHJhd2luZyBjYW52YXMuXG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAZW1pdHMgQ2FudmFzI2NhbnZhcy5pbml0XG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZ1xuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7R3JhcGhpY3NGYWN0b3J5fSBncmFwaGljc0ZhY3RvcnlcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ2FudmFzKGNvbmZpZywgZXZlbnRCdXMsIGdyYXBoaWNzRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5KSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fZWxlbWVudFJlZ2lzdHJ5ID0gZWxlbWVudFJlZ2lzdHJ5O1xuICB0aGlzLl9ncmFwaGljc0ZhY3RvcnkgPSBncmFwaGljc0ZhY3Rvcnk7XG5cbiAgdGhpcy5faW5pdChjb25maWcgfHwge30pO1xufVxuXG5DYW52YXMuJGluamVjdCA9IFtcbiAgJ2NvbmZpZy5jYW52YXMnLFxuICAnZXZlbnRCdXMnLFxuICAnZ3JhcGhpY3NGYWN0b3J5JyxcbiAgJ2VsZW1lbnRSZWdpc3RyeSdcbl07XG5cblxuQ2FudmFzLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uKGNvbmZpZykge1xuXG4gIHZhciBldmVudEJ1cyA9IHRoaXMuX2V2ZW50QnVzO1xuXG4gIC8vIENyZWF0ZXMgYSA8c3ZnPiBlbGVtZW50IHRoYXQgaXMgd3JhcHBlZCBpbnRvIGEgPGRpdj4uXG4gIC8vIFRoaXMgd2F5IHdlIGFyZSBhbHdheXMgYWJsZSB0byBjb3JyZWN0bHkgZmlndXJlIG91dCB0aGUgc2l6ZSBvZiB0aGUgc3ZnIGVsZW1lbnRcbiAgLy8gYnkgcXVlcnlpbmcgdGhlIHBhcmVudCBub2RlLlxuICAvL1xuICAvLyAoSXQgaXMgbm90IHBvc3NpYmxlIHRvIGdldCB0aGUgc2l6ZSBvZiBhIHN2ZyBlbGVtZW50IGNyb3NzIGJyb3dzZXIgQCAyMDE0LTA0LTAxKVxuICAvL1xuICAvLyA8ZGl2IGNsYXNzPVwiZGpzLWNvbnRhaW5lclwiIHN0eWxlPVwid2lkdGg6IHtkZXNpcmVkLXdpZHRofSwgaGVpZ2h0OiB7ZGVzaXJlZC1oZWlnaHR9XCI+XG4gIC8vICAgPHN2ZyB3aWR0aD1cIjEwMCVcIiBoZWlnaHQ9XCIxMDAlXCI+XG4gIC8vICAgIC4uLlxuICAvLyAgIDwvc3ZnPlxuICAvLyA8L2Rpdj5cblxuICAvLyBodG1sIGNvbnRhaW5lclxuICB2YXIgY29udGFpbmVyID0gdGhpcy5fY29udGFpbmVyID0gY3JlYXRlQ29udGFpbmVyKGNvbmZpZyk7XG5cbiAgdmFyIHN2ZyA9IHRoaXMuX3N2ZyA9IHN2Z0NyZWF0ZSgnc3ZnJyk7XG4gIHN2Z0F0dHIoc3ZnLCB7IHdpZHRoOiAnMTAwJScsIGhlaWdodDogJzEwMCUnIH0pO1xuXG4gIHN2Z0FwcGVuZChjb250YWluZXIsIHN2Zyk7XG5cbiAgdmFyIHZpZXdwb3J0ID0gdGhpcy5fdmlld3BvcnQgPSBjcmVhdGVHcm91cChzdmcsICd2aWV3cG9ydCcpO1xuXG4gIHRoaXMuX2xheWVycyA9IHt9O1xuXG4gIC8vIGRlYm91bmNlIGNhbnZhcy52aWV3Ym94LmNoYW5nZWQgZXZlbnRzXG4gIC8vIGZvciBzbW9vdGhlciBkaWFncmFtIGludGVyYWN0aW9uXG4gIGlmIChjb25maWcuZGVmZXJVcGRhdGUgIT09IGZhbHNlKSB7XG4gICAgdGhpcy5fdmlld2JveENoYW5nZWQgPSBkZWJvdW5jZShiaW5kKHRoaXMuX3ZpZXdib3hDaGFuZ2VkLCB0aGlzKSwgMzAwKTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdkaWFncmFtLmluaXQnLCBmdW5jdGlvbigpIHtcblxuICAgIC8qKlxuICAgICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgY2FudmFzIGlzIHJlYWR5IHRvIGJlIGRyYXduIG9uLlxuICAgICAqXG4gICAgICogQG1lbWJlck9mIENhbnZhc1xuICAgICAqXG4gICAgICogQGV2ZW50IGNhbnZhcy5pbml0XG4gICAgICpcbiAgICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgICAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gc3ZnIHRoZSBjcmVhdGVkIHN2ZyBlbGVtZW50XG4gICAgICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSB2aWV3cG9ydCB0aGUgZGlyZWN0IHBhcmVudCBvZiBkaWFncmFtIGVsZW1lbnRzIGFuZCBzaGFwZXNcbiAgICAgKi9cbiAgICBldmVudEJ1cy5maXJlKCdjYW52YXMuaW5pdCcsIHtcbiAgICAgIHN2Zzogc3ZnLFxuICAgICAgdmlld3BvcnQ6IHZpZXdwb3J0XG4gICAgfSk7XG5cbiAgfSwgdGhpcyk7XG5cbiAgLy8gcmVzZXQgdmlld2JveCBvbiBzaGFwZSBjaGFuZ2VzIHRvXG4gIC8vIHJlY29tcHV0ZSB0aGUgdmlld2JveFxuICBldmVudEJ1cy5vbihbXG4gICAgJ3NoYXBlLmFkZGVkJyxcbiAgICAnY29ubmVjdGlvbi5hZGRlZCcsXG4gICAgJ3NoYXBlLnJlbW92ZWQnLFxuICAgICdjb25uZWN0aW9uLnJlbW92ZWQnLFxuICAgICdlbGVtZW50cy5jaGFuZ2VkJ1xuICBdLCBmdW5jdGlvbigpIHtcbiAgICBkZWxldGUgdGhpcy5fY2FjaGVkVmlld2JveDtcbiAgfSwgdGhpcyk7XG5cbiAgZXZlbnRCdXMub24oJ2RpYWdyYW0uZGVzdHJveScsIDUwMCwgdGhpcy5fZGVzdHJveSwgdGhpcyk7XG4gIGV2ZW50QnVzLm9uKCdkaWFncmFtLmNsZWFyJywgNTAwLCB0aGlzLl9jbGVhciwgdGhpcyk7XG59O1xuXG5DYW52YXMucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24oZW1pdCkge1xuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjYW52YXMuZGVzdHJveScsIHtcbiAgICBzdmc6IHRoaXMuX3N2ZyxcbiAgICB2aWV3cG9ydDogdGhpcy5fdmlld3BvcnRcbiAgfSk7XG5cbiAgdmFyIHBhcmVudCA9IHRoaXMuX2NvbnRhaW5lci5wYXJlbnROb2RlO1xuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy5fY29udGFpbmVyKTtcbiAgfVxuXG4gIGRlbGV0ZSB0aGlzLl9zdmc7XG4gIGRlbGV0ZSB0aGlzLl9jb250YWluZXI7XG4gIGRlbGV0ZSB0aGlzLl9sYXllcnM7XG4gIGRlbGV0ZSB0aGlzLl9yb290RWxlbWVudDtcbiAgZGVsZXRlIHRoaXMuX3ZpZXdwb3J0O1xufTtcblxuQ2FudmFzLnByb3RvdHlwZS5fY2xlYXIgPSBmdW5jdGlvbigpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGFsbEVsZW1lbnRzID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldEFsbCgpO1xuXG4gIC8vIHJlbW92ZSBhbGwgZWxlbWVudHNcbiAgYWxsRWxlbWVudHMuZm9yRWFjaChmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgdmFyIHR5cGUgPSBnZXRUeXBlKGVsZW1lbnQpO1xuXG4gICAgaWYgKHR5cGUgPT09ICdyb290Jykge1xuICAgICAgc2VsZi5zZXRSb290RWxlbWVudChudWxsLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VsZi5fcmVtb3ZlRWxlbWVudChlbGVtZW50LCB0eXBlKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIGZvcmNlIHJlY29tcHV0YXRpb24gb2YgdmlldyBib3hcbiAgZGVsZXRlIHRoaXMuX2NhY2hlZFZpZXdib3g7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGRlZmF1bHQgbGF5ZXIgb24gd2hpY2hcbiAqIGFsbCBlbGVtZW50cyBhcmUgZHJhd24uXG4gKlxuICogQHJldHVybnMge1NWR0VsZW1lbnR9XG4gKi9cbkNhbnZhcy5wcm90b3R5cGUuZ2V0RGVmYXVsdExheWVyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmdldExheWVyKEJBU0VfTEFZRVIsIDApO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgbGF5ZXIgdGhhdCBpcyB1c2VkIHRvIGRyYXcgZWxlbWVudHNcbiAqIG9yIGFubm90YXRpb25zIG9uIGl0LlxuICpcbiAqIE5vbi1leGlzdGluZyBsYXllcnMgcmV0cmlldmVkIHRocm91Z2ggdGhpcyBtZXRob2RcbiAqIHdpbGwgYmUgY3JlYXRlZC4gRHVyaW5nIGNyZWF0aW9uLCB0aGUgb3B0aW9uYWwgaW5kZXhcbiAqIG1heSBiZSB1c2VkIHRvIGNyZWF0ZSBsYXllcnMgYmVsb3cgb3IgYWJvdmUgZXhpc3RpbmcgbGF5ZXJzLlxuICogQSBsYXllciB3aXRoIGEgY2VydGFpbiBpbmRleCBpcyBhbHdheXMgY3JlYXRlZCBhYm92ZSBhbGxcbiAqIGV4aXN0aW5nIGxheWVycyB3aXRoIHRoZSBzYW1lIGluZGV4LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXhcbiAqXG4gKiBAcmV0dXJucyB7U1ZHRWxlbWVudH1cbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5nZXRMYXllciA9IGZ1bmN0aW9uKG5hbWUsIGluZGV4KSB7XG5cbiAgaWYgKCFuYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtdXN0IHNwZWNpZnkgYSBuYW1lJyk7XG4gIH1cblxuICB2YXIgbGF5ZXIgPSB0aGlzLl9sYXllcnNbbmFtZV07XG5cbiAgaWYgKCFsYXllcikge1xuICAgIGxheWVyID0gdGhpcy5fbGF5ZXJzW25hbWVdID0gdGhpcy5fY3JlYXRlTGF5ZXIobmFtZSwgaW5kZXgpO1xuICB9XG5cbiAgLy8gdGhyb3cgYW4gZXJyb3IgaWYgbGF5ZXIgY3JlYXRpb24gLyByZXRyaXZhbCBpc1xuICAvLyByZXF1ZXN0ZWQgb24gZGlmZmVyZW50IGluZGV4XG4gIGlmICh0eXBlb2YgaW5kZXggIT09ICd1bmRlZmluZWQnICYmIGxheWVyLmluZGV4ICE9PSBpbmRleCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbGF5ZXIgPCcgKyBuYW1lICsgJz4gYWxyZWFkeSBjcmVhdGVkIGF0IGluZGV4IDwnICsgaW5kZXggKyAnPicpO1xuICB9XG5cbiAgcmV0dXJuIGxheWVyLmdyb3VwO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZ2l2ZW4gbGF5ZXIgYW5kIHJldHVybnMgaXQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7bnVtYmVyfSBbaW5kZXg9MF1cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGxheWVyIGRlc2NyaXB0b3Igd2l0aCB7IGluZGV4LCBncm91cDogU1ZHR3JvdXAgfVxuICovXG5DYW52YXMucHJvdG90eXBlLl9jcmVhdGVMYXllciA9IGZ1bmN0aW9uKG5hbWUsIGluZGV4KSB7XG5cbiAgaWYgKCFpbmRleCkge1xuICAgIGluZGV4ID0gMDtcbiAgfVxuXG4gIHZhciBjaGlsZEluZGV4ID0gcmVkdWNlKHRoaXMuX2xheWVycywgZnVuY3Rpb24oY2hpbGRJbmRleCwgbGF5ZXIpIHtcbiAgICBpZiAoaW5kZXggPj0gbGF5ZXIuaW5kZXgpIHtcbiAgICAgIGNoaWxkSW5kZXgrKztcbiAgICB9XG5cbiAgICByZXR1cm4gY2hpbGRJbmRleDtcbiAgfSwgMCk7XG5cbiAgcmV0dXJuIHtcbiAgICBncm91cDogY3JlYXRlR3JvdXAodGhpcy5fdmlld3BvcnQsICdsYXllci0nICsgbmFtZSwgY2hpbGRJbmRleCksXG4gICAgaW5kZXg6IGluZGV4XG4gIH07XG5cbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgaHRtbCBlbGVtZW50IHRoYXQgZW5jbG9zZXMgdGhlXG4gKiBkcmF3aW5nIGNhbnZhcy5cbiAqXG4gKiBAcmV0dXJuIHtET01Ob2RlfVxuICovXG5DYW52YXMucHJvdG90eXBlLmdldENvbnRhaW5lciA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fY29udGFpbmVyO1xufTtcblxuXG4vLyBtYXJrZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQ2FudmFzLnByb3RvdHlwZS5fdXBkYXRlTWFya2VyID0gZnVuY3Rpb24oZWxlbWVudCwgbWFya2VyLCBhZGQpIHtcbiAgdmFyIGNvbnRhaW5lcjtcblxuICBpZiAoIWVsZW1lbnQuaWQpIHtcbiAgICBlbGVtZW50ID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldChlbGVtZW50KTtcbiAgfVxuXG4gIC8vIHdlIG5lZWQgdG8gYWNjZXNzIGFsbFxuICBjb250YWluZXIgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuX2VsZW1lbnRzW2VsZW1lbnQuaWRdO1xuXG4gIGlmICghY29udGFpbmVyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZm9yRWFjaChbIGNvbnRhaW5lci5nZngsIGNvbnRhaW5lci5zZWNvbmRhcnlHZnggXSwgZnVuY3Rpb24oZ2Z4KSB7XG4gICAgaWYgKGdmeCkge1xuXG4gICAgICAvLyBpbnZva2UgZWl0aGVyIGFkZENsYXNzIG9yIHJlbW92ZUNsYXNzIGJhc2VkIG9uIG1vZGVcbiAgICAgIGlmIChhZGQpIHtcbiAgICAgICAgc3ZnQ2xhc3NlcyhnZngpLmFkZChtYXJrZXIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3ZnQ2xhc3NlcyhnZngpLnJlbW92ZShtYXJrZXIpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhIG1hcmtlciBoYXMgYmVlbiB1cGRhdGVkIGZvciBhbiBlbGVtZW50XG4gICAqXG4gICAqIEBldmVudCBlbGVtZW50Lm1hcmtlci51cGRhdGVcbiAgICogQHR5cGUge09iamVjdH1cbiAgICogQHByb3BlcnR5IHtkanMubW9kZWwuRWxlbWVudH0gZWxlbWVudCB0aGUgc2hhcGVcbiAgICogQHByb3BlcnR5IHtPYmplY3R9IGdmeCB0aGUgZ3JhcGhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzaGFwZVxuICAgKiBAcHJvcGVydHkge3N0cmluZ30gbWFya2VyXG4gICAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gYWRkIHRydWUgaWYgdGhlIG1hcmtlciB3YXMgYWRkZWQsIGZhbHNlIGlmIGl0IGdvdCByZW1vdmVkXG4gICAqL1xuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdlbGVtZW50Lm1hcmtlci51cGRhdGUnLCB7IGVsZW1lbnQ6IGVsZW1lbnQsIGdmeDogY29udGFpbmVyLmdmeCwgbWFya2VyOiBtYXJrZXIsIGFkZDogISFhZGQgfSk7XG59O1xuXG5cbi8qKlxuICogQWRkcyBhIG1hcmtlciB0byBhbiBlbGVtZW50IChiYXNpY2FsbHkgYSBjc3MgY2xhc3MpLlxuICpcbiAqIEZpcmVzIHRoZSBlbGVtZW50Lm1hcmtlci51cGRhdGUgZXZlbnQsIG1ha2luZyBpdCBwb3NzaWJsZSB0b1xuICogaW50ZWdyYXRlIGV4dGVuc2lvbiBpbnRvIHRoZSBtYXJrZXIgbGlmZS1jeWNsZSwgdG9vLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjYW52YXMuYWRkTWFya2VyKCdmb28nLCAnc29tZS1tYXJrZXInKTtcbiAqXG4gKiB2YXIgZm9vR2Z4ID0gY2FudmFzLmdldEdyYXBoaWNzKCdmb28nKTtcbiAqXG4gKiBmb29HZng7IC8vIDxnIGNsYXNzPVwiLi4uIHNvbWUtbWFya2VyXCI+IC4uLiA8L2c+XG4gKlxuICogQHBhcmFtIHtzdHJpbmd8ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBtYXJrZXJcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5hZGRNYXJrZXIgPSBmdW5jdGlvbihlbGVtZW50LCBtYXJrZXIpIHtcbiAgdGhpcy5fdXBkYXRlTWFya2VyKGVsZW1lbnQsIG1hcmtlciwgdHJ1ZSk7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlIGEgbWFya2VyIGZyb20gYW4gZWxlbWVudC5cbiAqXG4gKiBGaXJlcyB0aGUgZWxlbWVudC5tYXJrZXIudXBkYXRlIGV2ZW50LCBtYWtpbmcgaXQgcG9zc2libGUgdG9cbiAqIGludGVncmF0ZSBleHRlbnNpb24gaW50byB0aGUgbWFya2VyIGxpZmUtY3ljbGUsIHRvby5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd8ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSAge3N0cmluZ30gbWFya2VyXG4gKi9cbkNhbnZhcy5wcm90b3R5cGUucmVtb3ZlTWFya2VyID0gZnVuY3Rpb24oZWxlbWVudCwgbWFya2VyKSB7XG4gIHRoaXMuX3VwZGF0ZU1hcmtlcihlbGVtZW50LCBtYXJrZXIsIGZhbHNlKTtcbn07XG5cbi8qKlxuICogQ2hlY2sgdGhlIGV4aXN0ZW5jZSBvZiBhIG1hcmtlciBvbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ3xkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHBhcmFtICB7c3RyaW5nfSBtYXJrZXJcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5oYXNNYXJrZXIgPSBmdW5jdGlvbihlbGVtZW50LCBtYXJrZXIpIHtcbiAgaWYgKCFlbGVtZW50LmlkKSB7XG4gICAgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXQoZWxlbWVudCk7XG4gIH1cblxuICB2YXIgZ2Z4ID0gdGhpcy5nZXRHcmFwaGljcyhlbGVtZW50KTtcblxuICByZXR1cm4gc3ZnQ2xhc3NlcyhnZngpLmhhcyhtYXJrZXIpO1xufTtcblxuLyoqXG4gKiBUb2dnbGVzIGEgbWFya2VyIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogRmlyZXMgdGhlIGVsZW1lbnQubWFya2VyLnVwZGF0ZSBldmVudCwgbWFraW5nIGl0IHBvc3NpYmxlIHRvXG4gKiBpbnRlZ3JhdGUgZXh0ZW5zaW9uIGludG8gdGhlIG1hcmtlciBsaWZlLWN5Y2xlLCB0b28uXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfGRqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0gIHtzdHJpbmd9IG1hcmtlclxuICovXG5DYW52YXMucHJvdG90eXBlLnRvZ2dsZU1hcmtlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIG1hcmtlcikge1xuICBpZiAodGhpcy5oYXNNYXJrZXIoZWxlbWVudCwgbWFya2VyKSkge1xuICAgIHRoaXMucmVtb3ZlTWFya2VyKGVsZW1lbnQsIG1hcmtlcik7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5hZGRNYXJrZXIoZWxlbWVudCwgbWFya2VyKTtcbiAgfVxufTtcblxuQ2FudmFzLnByb3RvdHlwZS5nZXRSb290RWxlbWVudCA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuX3Jvb3RFbGVtZW50KSB7XG4gICAgdGhpcy5zZXRSb290RWxlbWVudCh7IGlkOiAnX19pbXBsaWNpdHJvb3QnLCBjaGlsZHJlbjogW10gfSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fcm9vdEVsZW1lbnQ7XG59O1xuXG5cblxuLy8gcm9vdCBlbGVtZW50IGhhbmRsaW5nIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBTZXRzIGEgZ2l2ZW4gZWxlbWVudCBhcyB0aGUgbmV3IHJvb3QgZWxlbWVudCBmb3IgdGhlIGNhbnZhc1xuICogYW5kIHJldHVybnMgdGhlIG5ldyByb290IGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R8ZGpzLm1vZGVsLlJvb3R9IGVsZW1lbnRcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW292ZXJyaWRlXSB3aGV0aGVyIHRvIG92ZXJyaWRlIHRoZSBjdXJyZW50IHJvb3QgZWxlbWVudCwgaWYgYW55XG4gKlxuICogQHJldHVybiB7T2JqZWN0fGRqcy5tb2RlbC5Sb290fSBuZXcgcm9vdCBlbGVtZW50XG4gKi9cbkNhbnZhcy5wcm90b3R5cGUuc2V0Um9vdEVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50LCBvdmVycmlkZSkge1xuXG4gIGlmIChlbGVtZW50KSB7XG4gICAgdGhpcy5fZW5zdXJlVmFsaWQoJ3Jvb3QnLCBlbGVtZW50KTtcbiAgfVxuXG4gIHZhciBjdXJyZW50Um9vdCA9IHRoaXMuX3Jvb3RFbGVtZW50LFxuICAgICAgZWxlbWVudFJlZ2lzdHJ5ID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LFxuICAgICAgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICBpZiAoY3VycmVudFJvb3QpIHtcbiAgICBpZiAoIW92ZXJyaWRlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Jvb3RFbGVtZW50IGFscmVhZHkgc2V0LCBuZWVkIHRvIHNwZWNpZnkgb3ZlcnJpZGUnKTtcbiAgICB9XG5cbiAgICAvLyBzaW11bGF0ZSBlbGVtZW50IHJlbW92ZSBldmVudCBzZXF1ZW5jZVxuICAgIGV2ZW50QnVzLmZpcmUoJ3Jvb3QucmVtb3ZlJywgeyBlbGVtZW50OiBjdXJyZW50Um9vdCB9KTtcbiAgICBldmVudEJ1cy5maXJlKCdyb290LnJlbW92ZWQnLCB7IGVsZW1lbnQ6IGN1cnJlbnRSb290IH0pO1xuXG4gICAgZWxlbWVudFJlZ2lzdHJ5LnJlbW92ZShjdXJyZW50Um9vdCk7XG4gIH1cblxuICBpZiAoZWxlbWVudCkge1xuICAgIHZhciBnZnggPSB0aGlzLmdldERlZmF1bHRMYXllcigpO1xuXG4gICAgLy8gcmVzZW1ibGUgZWxlbWVudCBhZGQgZXZlbnQgc2VxdWVuY2VcbiAgICBldmVudEJ1cy5maXJlKCdyb290LmFkZCcsIHsgZWxlbWVudDogZWxlbWVudCB9KTtcblxuICAgIGVsZW1lbnRSZWdpc3RyeS5hZGQoZWxlbWVudCwgZ2Z4LCB0aGlzLl9zdmcpO1xuXG4gICAgZXZlbnRCdXMuZmlyZSgncm9vdC5hZGRlZCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH1cblxuICB0aGlzLl9yb290RWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuXG5cblxuLy8gYWRkIGZ1bmN0aW9uYWxpdHkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5DYW52YXMucHJvdG90eXBlLl9lbnN1cmVWYWxpZCA9IGZ1bmN0aW9uKHR5cGUsIGVsZW1lbnQpIHtcbiAgaWYgKCFlbGVtZW50LmlkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbGVtZW50IG11c3QgaGF2ZSBhbiBpZCcpO1xuICB9XG5cbiAgaWYgKHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXQoZWxlbWVudC5pZCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2VsZW1lbnQgd2l0aCBpZCAnICsgZWxlbWVudC5pZCArICcgYWxyZWFkeSBleGlzdHMnKTtcbiAgfVxuXG4gIHZhciByZXF1aXJlZEF0dHJzID0gUkVRVUlSRURfTU9ERUxfQVRUUlNbdHlwZV07XG5cbiAgdmFyIHZhbGlkID0gZXZlcnkocmVxdWlyZWRBdHRycywgZnVuY3Rpb24oYXR0cikge1xuICAgIHJldHVybiB0eXBlb2YgZWxlbWVudFthdHRyXSAhPT0gJ3VuZGVmaW5lZCc7XG4gIH0pO1xuXG4gIGlmICghdmFsaWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAnbXVzdCBzdXBwbHkgeyAnICsgcmVxdWlyZWRBdHRycy5qb2luKCcsICcpICsgJyB9IHdpdGggJyArIHR5cGUpO1xuICB9XG59O1xuXG5DYW52YXMucHJvdG90eXBlLl9zZXRQYXJlbnQgPSBmdW5jdGlvbihlbGVtZW50LCBwYXJlbnQsIHBhcmVudEluZGV4KSB7XG4gIGNvbGxlY3Rpb25BZGQocGFyZW50LmNoaWxkcmVuLCBlbGVtZW50LCBwYXJlbnRJbmRleCk7XG4gIGVsZW1lbnQucGFyZW50ID0gcGFyZW50O1xufTtcblxuLyoqXG4gKiBBZGRzIGFuIGVsZW1lbnQgdG8gdGhlIGNhbnZhcy5cbiAqXG4gKiBUaGlzIHdpcmVzIHRoZSBwYXJlbnQgPC0+IGNoaWxkIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBlbGVtZW50IGFuZFxuICogYSBleHBsaWNpdGx5IHNwZWNpZmllZCBwYXJlbnQgb3IgYW4gaW1wbGljaXQgcm9vdCBlbGVtZW50LlxuICpcbiAqIER1cmluZyBhZGQgaXQgZW1pdHMgdGhlIGV2ZW50c1xuICpcbiAqICAqIDx7dHlwZX0uYWRkPiAoZWxlbWVudCwgcGFyZW50KVxuICogICogPHt0eXBlfS5hZGRlZD4gKGVsZW1lbnQsIGdmeClcbiAqXG4gKiBFeHRlbnNpb25zIG1heSBob29rIGludG8gdGhlc2UgZXZlbnRzIHRvIHBlcmZvcm0gdGhlaXIgbWFnaWMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7T2JqZWN0fGRqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdHxkanMubW9kZWwuQmFzZX0gW3BhcmVudF1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbcGFyZW50SW5kZXhdXG4gKlxuICogQHJldHVybiB7T2JqZWN0fGRqcy5tb2RlbC5CYXNlfSB0aGUgYWRkZWQgZWxlbWVudFxuICovXG5DYW52YXMucHJvdG90eXBlLl9hZGRFbGVtZW50ID0gZnVuY3Rpb24odHlwZSwgZWxlbWVudCwgcGFyZW50LCBwYXJlbnRJbmRleCkge1xuXG4gIHBhcmVudCA9IHBhcmVudCB8fCB0aGlzLmdldFJvb3RFbGVtZW50KCk7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXMsXG4gICAgICBncmFwaGljc0ZhY3RvcnkgPSB0aGlzLl9ncmFwaGljc0ZhY3Rvcnk7XG5cbiAgdGhpcy5fZW5zdXJlVmFsaWQodHlwZSwgZWxlbWVudCk7XG5cbiAgZXZlbnRCdXMuZmlyZSh0eXBlICsgJy5hZGQnLCB7IGVsZW1lbnQ6IGVsZW1lbnQsIHBhcmVudDogcGFyZW50IH0pO1xuXG4gIHRoaXMuX3NldFBhcmVudChlbGVtZW50LCBwYXJlbnQsIHBhcmVudEluZGV4KTtcblxuICAvLyBjcmVhdGUgZ3JhcGhpY3NcbiAgdmFyIGdmeCA9IGdyYXBoaWNzRmFjdG9yeS5jcmVhdGUodHlwZSwgZWxlbWVudCwgcGFyZW50SW5kZXgpO1xuXG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5hZGQoZWxlbWVudCwgZ2Z4KTtcblxuICAvLyB1cGRhdGUgaXRzIHZpc3VhbFxuICBncmFwaGljc0ZhY3RvcnkudXBkYXRlKHR5cGUsIGVsZW1lbnQsIGdmeCk7XG5cbiAgZXZlbnRCdXMuZmlyZSh0eXBlICsgJy5hZGRlZCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59O1xuXG4vKipcbiAqIEFkZHMgYSBzaGFwZSB0byB0aGUgY2FudmFzXG4gKlxuICogQHBhcmFtIHtPYmplY3R8ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZSB0byBhZGQgdG8gdGhlIGRpYWdyYW1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtwYXJlbnRdXG4gKiBAcGFyYW0ge251bWJlcn0gW3BhcmVudEluZGV4XVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5TaGFwZX0gdGhlIGFkZGVkIHNoYXBlXG4gKi9cbkNhbnZhcy5wcm90b3R5cGUuYWRkU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgcGFyZW50LCBwYXJlbnRJbmRleCkge1xuICByZXR1cm4gdGhpcy5fYWRkRWxlbWVudCgnc2hhcGUnLCBzaGFwZSwgcGFyZW50LCBwYXJlbnRJbmRleCk7XG59O1xuXG4vKipcbiAqIEFkZHMgYSBjb25uZWN0aW9uIHRvIHRoZSBjYW52YXNcbiAqXG4gKiBAcGFyYW0ge09iamVjdHxkanMubW9kZWwuQ29ubmVjdGlvbn0gY29ubmVjdGlvbiB0byBhZGQgdG8gdGhlIGRpYWdyYW1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtwYXJlbnRdXG4gKiBAcGFyYW0ge251bWJlcn0gW3BhcmVudEluZGV4XVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5Db25uZWN0aW9ufSB0aGUgYWRkZWQgY29ubmVjdGlvblxuICovXG5DYW52YXMucHJvdG90eXBlLmFkZENvbm5lY3Rpb24gPSBmdW5jdGlvbihjb25uZWN0aW9uLCBwYXJlbnQsIHBhcmVudEluZGV4KSB7XG4gIHJldHVybiB0aGlzLl9hZGRFbGVtZW50KCdjb25uZWN0aW9uJywgY29ubmVjdGlvbiwgcGFyZW50LCBwYXJlbnRJbmRleCk7XG59O1xuXG5cbi8qKlxuICogSW50ZXJuYWwgcmVtb3ZlIGVsZW1lbnRcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5fcmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHR5cGUpIHtcblxuICB2YXIgZWxlbWVudFJlZ2lzdHJ5ID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LFxuICAgICAgZ3JhcGhpY3NGYWN0b3J5ID0gdGhpcy5fZ3JhcGhpY3NGYWN0b3J5LFxuICAgICAgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICBlbGVtZW50ID0gZWxlbWVudFJlZ2lzdHJ5LmdldChlbGVtZW50LmlkIHx8IGVsZW1lbnQpO1xuXG4gIGlmICghZWxlbWVudCkge1xuXG4gICAgLy8gZWxlbWVudCB3YXMgcmVtb3ZlZCBhbHJlYWR5XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZXZlbnRCdXMuZmlyZSh0eXBlICsgJy5yZW1vdmUnLCB7IGVsZW1lbnQ6IGVsZW1lbnQgfSk7XG5cbiAgZ3JhcGhpY3NGYWN0b3J5LnJlbW92ZShlbGVtZW50KTtcblxuICAvLyB1bnNldCBwYXJlbnQgPC0+IGNoaWxkIHJlbGF0aW9uc2hpcFxuICBjb2xsZWN0aW9uUmVtb3ZlKGVsZW1lbnQucGFyZW50ICYmIGVsZW1lbnQucGFyZW50LmNoaWxkcmVuLCBlbGVtZW50KTtcbiAgZWxlbWVudC5wYXJlbnQgPSBudWxsO1xuXG4gIGV2ZW50QnVzLmZpcmUodHlwZSArICcucmVtb3ZlZCcsIHsgZWxlbWVudDogZWxlbWVudCB9KTtcblxuICBlbGVtZW50UmVnaXN0cnkucmVtb3ZlKGVsZW1lbnQpO1xuXG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuXG4vKipcbiAqIFJlbW92ZXMgYSBzaGFwZSBmcm9tIHRoZSBjYW52YXNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xkanMubW9kZWwuU2hhcGV9IHNoYXBlIG9yIHNoYXBlIGlkIHRvIGJlIHJlbW92ZWRcbiAqXG4gKiBAcmV0dXJuIHtkanMubW9kZWwuU2hhcGV9IHRoZSByZW1vdmVkIHNoYXBlXG4gKi9cbkNhbnZhcy5wcm90b3R5cGUucmVtb3ZlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSkge1xuXG4gIC8qKlxuICAgKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgYSBzaGFwZSBpcyBhYm91dCB0byBiZSByZW1vdmVkIGZyb20gdGhlIGNhbnZhcy5cbiAgICpcbiAgICogQG1lbWJlck9mIENhbnZhc1xuICAgKlxuICAgKiBAZXZlbnQgc2hhcGUucmVtb3ZlXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLlNoYXBlfSBlbGVtZW50IHRoZSBzaGFwZSBkZXNjcmlwdG9yXG4gICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBnZnggdGhlIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgc2hhcGVcbiAgICovXG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhIHNoYXBlIGhhcyBiZWVuIHJlbW92ZWQgZnJvbSB0aGUgY2FudmFzLlxuICAgKlxuICAgKiBAbWVtYmVyT2YgQ2FudmFzXG4gICAqXG4gICAqIEBldmVudCBzaGFwZS5yZW1vdmVkXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLlNoYXBlfSBlbGVtZW50IHRoZSBzaGFwZSBkZXNjcmlwdG9yXG4gICAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBnZnggdGhlIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBvZiB0aGUgc2hhcGVcbiAgICovXG4gIHJldHVybiB0aGlzLl9yZW1vdmVFbGVtZW50KHNoYXBlLCAnc2hhcGUnKTtcbn07XG5cblxuLyoqXG4gKiBSZW1vdmVzIGEgY29ubmVjdGlvbiBmcm9tIHRoZSBjYW52YXNcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ3xkanMubW9kZWwuQ29ubmVjdGlvbn0gY29ubmVjdGlvbiBvciBjb25uZWN0aW9uIGlkIHRvIGJlIHJlbW92ZWRcbiAqXG4gKiBAcmV0dXJuIHtkanMubW9kZWwuQ29ubmVjdGlvbn0gdGhlIHJlbW92ZWQgY29ubmVjdGlvblxuICovXG5DYW52YXMucHJvdG90eXBlLnJlbW92ZUNvbm5lY3Rpb24gPSBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhIGNvbm5lY3Rpb24gaXMgYWJvdXQgdG8gYmUgcmVtb3ZlZCBmcm9tIHRoZSBjYW52YXMuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBDYW52YXNcbiAgICpcbiAgICogQGV2ZW50IGNvbm5lY3Rpb24ucmVtb3ZlXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkNvbm5lY3Rpb259IGVsZW1lbnQgdGhlIGNvbm5lY3Rpb24gZGVzY3JpcHRvclxuICAgKiBAcHJvcGVydHkge09iamVjdH0gZ2Z4IHRoZSBncmFwaGljYWwgcmVwcmVzZW50YXRpb24gb2YgdGhlIGNvbm5lY3Rpb25cbiAgICovXG5cbiAgLyoqXG4gICAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCBhIGNvbm5lY3Rpb24gaGFzIGJlZW4gcmVtb3ZlZCBmcm9tIHRoZSBjYW52YXMuXG4gICAqXG4gICAqIEBtZW1iZXJPZiBDYW52YXNcbiAgICpcbiAgICogQGV2ZW50IGNvbm5lY3Rpb24ucmVtb3ZlZFxuICAgKiBAdHlwZSB7T2JqZWN0fVxuICAgKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5Db25uZWN0aW9ufSBlbGVtZW50IHRoZSBjb25uZWN0aW9uIGRlc2NyaXB0b3JcbiAgICogQHByb3BlcnR5IHtPYmplY3R9IGdmeCB0aGUgZ3JhcGhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjb25uZWN0aW9uXG4gICAqL1xuICByZXR1cm4gdGhpcy5fcmVtb3ZlRWxlbWVudChjb25uZWN0aW9uLCAnY29ubmVjdGlvbicpO1xufTtcblxuXG4vKipcbiAqIFJldHVybiB0aGUgZ3JhcGhpY2FsIG9iamVjdCB1bmRlcmxheWluZyBhIGNlcnRhaW4gZGlhZ3JhbSBlbGVtZW50XG4gKlxuICogQHBhcmFtIHtzdHJpbmd8ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnQgZGVzY3JpcHRvciBvZiB0aGUgZWxlbWVudFxuICogQHBhcmFtIHtib29sZWFufSBbc2Vjb25kYXJ5PWZhbHNlXSB3aGV0aGVyIHRvIHJldHVybiB0aGUgc2Vjb25kYXJ5IGNvbm5lY3RlZCBlbGVtZW50XG4gKlxuICogQHJldHVybiB7U1ZHRWxlbWVudH1cbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5nZXRHcmFwaGljcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHNlY29uZGFyeSkge1xuICByZXR1cm4gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGVsZW1lbnQsIHNlY29uZGFyeSk7XG59O1xuXG5cbi8qKlxuICogUGVyZm9ybSBhIHZpZXdib3ggdXBkYXRlIHZpYSBhIGdpdmVuIGNoYW5nZSBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjaGFuZ2VGblxuICovXG5DYW52YXMucHJvdG90eXBlLl9jaGFuZ2VWaWV3Ym94ID0gZnVuY3Rpb24oY2hhbmdlRm4pIHtcblxuICAvLyBub3RpZnkgb3RoZXJzIG9mIHRoZSB1cGNvbWluZyB2aWV3Ym94IGNoYW5nZVxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjYW52YXMudmlld2JveC5jaGFuZ2luZycpO1xuXG4gIC8vIHBlcmZvcm0gYWN0dWFsIGNoYW5nZVxuICBjaGFuZ2VGbi5hcHBseSh0aGlzKTtcblxuICAvLyByZXNldCB0aGUgY2FjaGVkIHZpZXdib3ggc28gdGhhdFxuICAvLyBhIG5ldyBnZXQgb3BlcmF0aW9uIG9uIHZpZXdib3ggb3Igem9vbVxuICAvLyB0cmlnZ2VycyBhIHZpZXdib3ggcmUtY29tcHV0YXRpb25cbiAgdGhpcy5fY2FjaGVkVmlld2JveCA9IG51bGw7XG5cbiAgLy8gbm90aWZ5IG90aGVycyBvZiB0aGUgY2hhbmdlOyB0aGlzIHN0ZXBcbiAgLy8gbWF5IG9yIG1heSBub3QgYmUgZGVib3VuY2VkXG4gIHRoaXMuX3ZpZXdib3hDaGFuZ2VkKCk7XG59O1xuXG5DYW52YXMucHJvdG90eXBlLl92aWV3Ym94Q2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjYW52YXMudmlld2JveC5jaGFuZ2VkJywgeyB2aWV3Ym94OiB0aGlzLnZpZXdib3goKSB9KTtcbn07XG5cblxuLyoqXG4gKiBHZXRzIG9yIHNldHMgdGhlIHZpZXcgYm94IG9mIHRoZSBjYW52YXMsIGkuZS4gdGhlXG4gKiBhcmVhIHRoYXQgaXMgY3VycmVudGx5IGRpc3BsYXllZC5cbiAqXG4gKiBUaGUgZ2V0dGVyIG1heSByZXR1cm4gYSBjYWNoZWQgdmlld2JveCAoaWYgaXQgaXMgY3VycmVudGx5XG4gKiBjaGFuZ2luZykuIFRvIGZvcmNlIGEgcmVjb21wdXRhdGlvbiwgcGFzcyBgZmFsc2VgIGFzIHRoZSBmaXJzdCBhcmd1bWVudC5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIGNhbnZhcy52aWV3Ym94KHsgeDogMTAwLCB5OiAxMDAsIHdpZHRoOiA1MDAsIGhlaWdodDogNTAwIH0pXG4gKlxuICogLy8gc2V0cyB0aGUgdmlzaWJsZSBhcmVhIG9mIHRoZSBkaWFncmFtIHRvICgxMDB8MTAwKSAtPiAoNjAwfDEwMClcbiAqIC8vIGFuZCBhbmQgc2NhbGVzIGl0IGFjY29yZGluZyB0byB0aGUgZGlhZ3JhbSB3aWR0aFxuICpcbiAqIHZhciB2aWV3Ym94ID0gY2FudmFzLnZpZXdib3goKTsgLy8gcGFzcyBgZmFsc2VgIHRvIGZvcmNlIHJlY29tcHV0aW5nIHRoZSBib3guXG4gKlxuICogY29uc29sZS5sb2codmlld2JveCk7XG4gKiAvLyB7XG4gKiAvLyAgIGlubmVyOiBEaW1lbnNpb25zLFxuICogLy8gICBvdXRlcjogRGltZW5zaW9ucyxcbiAqIC8vICAgc2NhbGUsXG4gKiAvLyAgIHgsIHksXG4gKiAvLyAgIHdpZHRoLCBoZWlnaHRcbiAqIC8vIH1cbiAqXG4gKiAvLyBpZiB0aGUgY3VycmVudCBkaWFncmFtIGlzIHpvb21lZCBhbmQgc2Nyb2xsZWQsIHlvdSBtYXkgcmVzZXQgaXQgdG8gdGhlXG4gKiAvLyBkZWZhdWx0IHpvb20gdmlhIHRoaXMgbWV0aG9kLCB0b286XG4gKlxuICogdmFyIHpvb21lZEFuZFNjcm9sbGVkVmlld2JveCA9IGNhbnZhcy52aWV3Ym94KCk7XG4gKlxuICogY2FudmFzLnZpZXdib3goe1xuICogICB4OiAwLFxuICogICB5OiAwLFxuICogICB3aWR0aDogem9vbWVkQW5kU2Nyb2xsZWRWaWV3Ym94Lm91dGVyLndpZHRoLFxuICogICBoZWlnaHQ6IHpvb21lZEFuZFNjcm9sbGVkVmlld2JveC5vdXRlci5oZWlnaHRcbiAqIH0pO1xuICpcbiAqIEBwYXJhbSAge09iamVjdH0gW2JveF0gdGhlIG5ldyB2aWV3IGJveCB0byBzZXRcbiAqIEBwYXJhbSAge251bWJlcn0gYm94LnggdGhlIHRvcCBsZWZ0IFggY29vcmRpbmF0ZSBvZiB0aGUgY2FudmFzIHZpc2libGUgaW4gdmlldyBib3hcbiAqIEBwYXJhbSAge251bWJlcn0gYm94LnkgdGhlIHRvcCBsZWZ0IFkgY29vcmRpbmF0ZSBvZiB0aGUgY2FudmFzIHZpc2libGUgaW4gdmlldyBib3hcbiAqIEBwYXJhbSAge251bWJlcn0gYm94LndpZHRoIHRoZSB2aXNpYmxlIHdpZHRoXG4gKiBAcGFyYW0gIHtudW1iZXJ9IGJveC5oZWlnaHRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSBjdXJyZW50IHZpZXcgYm94XG4gKi9cbkNhbnZhcy5wcm90b3R5cGUudmlld2JveCA9IGZ1bmN0aW9uKGJveCkge1xuXG4gIGlmIChib3ggPT09IHVuZGVmaW5lZCAmJiB0aGlzLl9jYWNoZWRWaWV3Ym94KSB7XG4gICAgcmV0dXJuIHRoaXMuX2NhY2hlZFZpZXdib3g7XG4gIH1cblxuICB2YXIgdmlld3BvcnQgPSB0aGlzLl92aWV3cG9ydCxcbiAgICAgIGlubmVyQm94LFxuICAgICAgb3V0ZXJCb3ggPSB0aGlzLmdldFNpemUoKSxcbiAgICAgIG1hdHJpeCxcbiAgICAgIHRyYW5zZm9ybSxcbiAgICAgIHNjYWxlLFxuICAgICAgeCwgeTtcblxuICBpZiAoIWJveCkge1xuXG4gICAgLy8gY29tcHV0ZSB0aGUgaW5uZXIgYm94IGJhc2VkIG9uIHRoZVxuICAgIC8vIGRpYWdyYW1zIGRlZmF1bHQgbGF5ZXIuIFRoaXMgYWxsb3dzIHVzIHRvIGV4Y2x1ZGVcbiAgICAvLyBleHRlcm5hbCBjb21wb25lbnRzLCBzdWNoIGFzIG92ZXJsYXlzXG4gICAgaW5uZXJCb3ggPSB0aGlzLmdldERlZmF1bHRMYXllcigpLmdldEJCb3goKTtcblxuICAgIHRyYW5zZm9ybSA9IHN2Z1RyYW5zZm9ybSh2aWV3cG9ydCk7XG4gICAgbWF0cml4ID0gdHJhbnNmb3JtID8gdHJhbnNmb3JtLm1hdHJpeCA6IGNyZWF0ZU1hdHJpeCgpO1xuICAgIHNjYWxlID0gcm91bmQobWF0cml4LmEsIDEwMDApO1xuXG4gICAgeCA9IHJvdW5kKC1tYXRyaXguZSB8fCAwLCAxMDAwKTtcbiAgICB5ID0gcm91bmQoLW1hdHJpeC5mIHx8IDAsIDEwMDApO1xuXG4gICAgYm94ID0gdGhpcy5fY2FjaGVkVmlld2JveCA9IHtcbiAgICAgIHg6IHggPyB4IC8gc2NhbGUgOiAwLFxuICAgICAgeTogeSA/IHkgLyBzY2FsZSA6IDAsXG4gICAgICB3aWR0aDogb3V0ZXJCb3gud2lkdGggLyBzY2FsZSxcbiAgICAgIGhlaWdodDogb3V0ZXJCb3guaGVpZ2h0IC8gc2NhbGUsXG4gICAgICBzY2FsZTogc2NhbGUsXG4gICAgICBpbm5lcjoge1xuICAgICAgICB3aWR0aDogaW5uZXJCb3gud2lkdGgsXG4gICAgICAgIGhlaWdodDogaW5uZXJCb3guaGVpZ2h0LFxuICAgICAgICB4OiBpbm5lckJveC54LFxuICAgICAgICB5OiBpbm5lckJveC55XG4gICAgICB9LFxuICAgICAgb3V0ZXI6IG91dGVyQm94XG4gICAgfTtcblxuICAgIHJldHVybiBib3g7XG4gIH0gZWxzZSB7XG5cbiAgICB0aGlzLl9jaGFuZ2VWaWV3Ym94KGZ1bmN0aW9uKCkge1xuICAgICAgc2NhbGUgPSBNYXRoLm1pbihvdXRlckJveC53aWR0aCAvIGJveC53aWR0aCwgb3V0ZXJCb3guaGVpZ2h0IC8gYm94LmhlaWdodCk7XG5cbiAgICAgIHZhciBtYXRyaXggPSB0aGlzLl9zdmcuY3JlYXRlU1ZHTWF0cml4KClcbiAgICAgICAgLnNjYWxlKHNjYWxlKVxuICAgICAgICAudHJhbnNsYXRlKC1ib3gueCwgLWJveC55KTtcblxuICAgICAgc3ZnVHJhbnNmb3JtKHZpZXdwb3J0LCBtYXRyaXgpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGJveDtcbn07XG5cblxuLyoqXG4gKiBHZXRzIG9yIHNldHMgdGhlIHNjcm9sbCBvZiB0aGUgY2FudmFzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbZGVsdGFdIHRoZSBuZXcgc2Nyb2xsIHRvIGFwcGx5LlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbZGVsdGEuZHhdXG4gKiBAcGFyYW0ge251bWJlcn0gW2RlbHRhLmR5XVxuICovXG5DYW52YXMucHJvdG90eXBlLnNjcm9sbCA9IGZ1bmN0aW9uKGRlbHRhKSB7XG5cbiAgdmFyIG5vZGUgPSB0aGlzLl92aWV3cG9ydDtcbiAgdmFyIG1hdHJpeCA9IG5vZGUuZ2V0Q1RNKCk7XG5cbiAgaWYgKGRlbHRhKSB7XG4gICAgdGhpcy5fY2hhbmdlVmlld2JveChmdW5jdGlvbigpIHtcbiAgICAgIGRlbHRhID0gYXNzaWduKHsgZHg6IDAsIGR5OiAwIH0sIGRlbHRhIHx8IHt9KTtcblxuICAgICAgbWF0cml4ID0gdGhpcy5fc3ZnLmNyZWF0ZVNWR01hdHJpeCgpLnRyYW5zbGF0ZShkZWx0YS5keCwgZGVsdGEuZHkpLm11bHRpcGx5KG1hdHJpeCk7XG5cbiAgICAgIHNldENUTShub2RlLCBtYXRyaXgpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIHsgeDogbWF0cml4LmUsIHk6IG1hdHJpeC5mIH07XG59O1xuXG5cbi8qKlxuICogR2V0cyBvciBzZXRzIHRoZSBjdXJyZW50IHpvb20gb2YgdGhlIGNhbnZhcywgb3B0aW9uYWxseSB6b29taW5nXG4gKiB0byB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLlxuICpcbiAqIFRoZSBnZXR0ZXIgbWF5IHJldHVybiBhIGNhY2hlZCB6b29tIGxldmVsLiBDYWxsIGl0IHdpdGggYGZhbHNlYCBhc1xuICogdGhlIGZpcnN0IGFyZ3VtZW50IHRvIGZvcmNlIHJlY29tcHV0YXRpb24gb2YgdGhlIGN1cnJlbnQgbGV2ZWwuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBbbmV3U2NhbGVdIHRoZSBuZXcgem9vbSBsZXZlbCwgZWl0aGVyIGEgbnVtYmVyLCBpLmUuIDAuOSxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvciBgZml0LXZpZXdwb3J0YCB0byBhZGp1c3QgdGhlIHNpemUgdG8gZml0IHRoZSBjdXJyZW50IHZpZXdwb3J0XG4gKiBAcGFyYW0ge3N0cmluZ3xQb2ludH0gW2NlbnRlcl0gdGhlIHJlZmVyZW5jZSBwb2ludCB7IHg6IC4uLCB5OiAuLn0gdG8gem9vbSB0bywgJ2F1dG8nIHRvIHpvb20gaW50byBtaWQgb3IgbnVsbFxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gdGhlIGN1cnJlbnQgc2NhbGVcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS56b29tID0gZnVuY3Rpb24obmV3U2NhbGUsIGNlbnRlcikge1xuXG4gIGlmICghbmV3U2NhbGUpIHtcbiAgICByZXR1cm4gdGhpcy52aWV3Ym94KG5ld1NjYWxlKS5zY2FsZTtcbiAgfVxuXG4gIGlmIChuZXdTY2FsZSA9PT0gJ2ZpdC12aWV3cG9ydCcpIHtcbiAgICByZXR1cm4gdGhpcy5fZml0Vmlld3BvcnQoY2VudGVyKTtcbiAgfVxuXG4gIHZhciBvdXRlcixcbiAgICAgIG1hdHJpeDtcblxuICB0aGlzLl9jaGFuZ2VWaWV3Ym94KGZ1bmN0aW9uKCkge1xuXG4gICAgaWYgKHR5cGVvZiBjZW50ZXIgIT09ICdvYmplY3QnKSB7XG4gICAgICBvdXRlciA9IHRoaXMudmlld2JveCgpLm91dGVyO1xuXG4gICAgICBjZW50ZXIgPSB7XG4gICAgICAgIHg6IG91dGVyLndpZHRoIC8gMixcbiAgICAgICAgeTogb3V0ZXIuaGVpZ2h0IC8gMlxuICAgICAgfTtcbiAgICB9XG5cbiAgICBtYXRyaXggPSB0aGlzLl9zZXRab29tKG5ld1NjYWxlLCBjZW50ZXIpO1xuICB9KTtcblxuICByZXR1cm4gcm91bmQobWF0cml4LmEsIDEwMDApO1xufTtcblxuZnVuY3Rpb24gc2V0Q1RNKG5vZGUsIG0pIHtcbiAgdmFyIG1zdHIgPSAnbWF0cml4KCcgKyBtLmEgKyAnLCcgKyBtLmIgKyAnLCcgKyBtLmMgKyAnLCcgKyBtLmQgKyAnLCcgKyBtLmUgKyAnLCcgKyBtLmYgKyAnKSc7XG4gIG5vZGUuc2V0QXR0cmlidXRlKCd0cmFuc2Zvcm0nLCBtc3RyKTtcbn1cblxuQ2FudmFzLnByb3RvdHlwZS5fZml0Vmlld3BvcnQgPSBmdW5jdGlvbihjZW50ZXIpIHtcblxuICB2YXIgdmJveCA9IHRoaXMudmlld2JveCgpLFxuICAgICAgb3V0ZXIgPSB2Ym94Lm91dGVyLFxuICAgICAgaW5uZXIgPSB2Ym94LmlubmVyLFxuICAgICAgbmV3U2NhbGUsXG4gICAgICBuZXdWaWV3Ym94O1xuXG4gIC8vIGRpc3BsYXkgdGhlIGNvbXBsZXRlIGRpYWdyYW0gd2l0aG91dCB6b29taW5nIGluLlxuICAvLyBpbnN0ZWFkIG9mIHJlbHlpbmcgb24gaW50ZXJuYWwgem9vbSwgd2UgcGVyZm9ybSBhXG4gIC8vIGhhcmQgcmVzZXQgb24gdGhlIGNhbnZhcyB2aWV3Ym94IHRvIHJlYWxpemUgdGhpc1xuICAvL1xuICAvLyBpZiBkaWFncmFtIGRvZXMgbm90IG5lZWQgdG8gYmUgem9vbWVkIGluLCB3ZSBmb2N1cyBpdCBhcm91bmRcbiAgLy8gdGhlIGRpYWdyYW0gb3JpZ2luIGluc3RlYWRcblxuICBpZiAoaW5uZXIueCA+PSAwICYmXG4gICAgICBpbm5lci55ID49IDAgJiZcbiAgICAgIGlubmVyLnggKyBpbm5lci53aWR0aCA8PSBvdXRlci53aWR0aCAmJlxuICAgICAgaW5uZXIueSArIGlubmVyLmhlaWdodCA8PSBvdXRlci5oZWlnaHQgJiZcbiAgICAgICFjZW50ZXIpIHtcblxuICAgIG5ld1ZpZXdib3ggPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMCxcbiAgICAgIHdpZHRoOiBNYXRoLm1heChpbm5lci53aWR0aCArIGlubmVyLngsIG91dGVyLndpZHRoKSxcbiAgICAgIGhlaWdodDogTWF0aC5tYXgoaW5uZXIuaGVpZ2h0ICsgaW5uZXIueSwgb3V0ZXIuaGVpZ2h0KVxuICAgIH07XG4gIH0gZWxzZSB7XG5cbiAgICBuZXdTY2FsZSA9IE1hdGgubWluKDEsIG91dGVyLndpZHRoIC8gaW5uZXIud2lkdGgsIG91dGVyLmhlaWdodCAvIGlubmVyLmhlaWdodCk7XG4gICAgbmV3Vmlld2JveCA9IHtcbiAgICAgIHg6IGlubmVyLnggKyAoY2VudGVyID8gaW5uZXIud2lkdGggLyAyIC0gb3V0ZXIud2lkdGggLyBuZXdTY2FsZSAvIDIgOiAwKSxcbiAgICAgIHk6IGlubmVyLnkgKyAoY2VudGVyID8gaW5uZXIuaGVpZ2h0IC8gMiAtIG91dGVyLmhlaWdodCAvIG5ld1NjYWxlIC8gMiA6IDApLFxuICAgICAgd2lkdGg6IG91dGVyLndpZHRoIC8gbmV3U2NhbGUsXG4gICAgICBoZWlnaHQ6IG91dGVyLmhlaWdodCAvIG5ld1NjYWxlXG4gICAgfTtcbiAgfVxuXG4gIHRoaXMudmlld2JveChuZXdWaWV3Ym94KTtcblxuICByZXR1cm4gdGhpcy52aWV3Ym94KGZhbHNlKS5zY2FsZTtcbn07XG5cblxuQ2FudmFzLnByb3RvdHlwZS5fc2V0Wm9vbSA9IGZ1bmN0aW9uKHNjYWxlLCBjZW50ZXIpIHtcblxuICB2YXIgc3ZnID0gdGhpcy5fc3ZnLFxuICAgICAgdmlld3BvcnQgPSB0aGlzLl92aWV3cG9ydDtcblxuICB2YXIgbWF0cml4ID0gc3ZnLmNyZWF0ZVNWR01hdHJpeCgpO1xuICB2YXIgcG9pbnQgPSBzdmcuY3JlYXRlU1ZHUG9pbnQoKTtcblxuICB2YXIgY2VudGVyUG9pbnQsXG4gICAgICBvcmlnaW5hbFBvaW50LFxuICAgICAgY3VycmVudE1hdHJpeCxcbiAgICAgIHNjYWxlTWF0cml4LFxuICAgICAgbmV3TWF0cml4O1xuXG4gIGN1cnJlbnRNYXRyaXggPSB2aWV3cG9ydC5nZXRDVE0oKTtcblxuICB2YXIgY3VycmVudFNjYWxlID0gY3VycmVudE1hdHJpeC5hO1xuXG4gIGlmIChjZW50ZXIpIHtcbiAgICBjZW50ZXJQb2ludCA9IGFzc2lnbihwb2ludCwgY2VudGVyKTtcblxuICAgIC8vIHJldmVydCBhcHBsaWVkIHZpZXdwb3J0IHRyYW5zZm9ybWF0aW9uc1xuICAgIG9yaWdpbmFsUG9pbnQgPSBjZW50ZXJQb2ludC5tYXRyaXhUcmFuc2Zvcm0oY3VycmVudE1hdHJpeC5pbnZlcnNlKCkpO1xuXG4gICAgLy8gY3JlYXRlIHNjYWxlIG1hdHJpeFxuICAgIHNjYWxlTWF0cml4ID0gbWF0cml4XG4gICAgICAudHJhbnNsYXRlKG9yaWdpbmFsUG9pbnQueCwgb3JpZ2luYWxQb2ludC55KVxuICAgICAgLnNjYWxlKDEgLyBjdXJyZW50U2NhbGUgKiBzY2FsZSlcbiAgICAgIC50cmFuc2xhdGUoLW9yaWdpbmFsUG9pbnQueCwgLW9yaWdpbmFsUG9pbnQueSk7XG5cbiAgICBuZXdNYXRyaXggPSBjdXJyZW50TWF0cml4Lm11bHRpcGx5KHNjYWxlTWF0cml4KTtcbiAgfSBlbHNlIHtcbiAgICBuZXdNYXRyaXggPSBtYXRyaXguc2NhbGUoc2NhbGUpO1xuICB9XG5cbiAgc2V0Q1RNKHRoaXMuX3ZpZXdwb3J0LCBuZXdNYXRyaXgpO1xuXG4gIHJldHVybiBuZXdNYXRyaXg7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgc2l6ZSBvZiB0aGUgY2FudmFzXG4gKlxuICogQHJldHVybiB7RGltZW5zaW9uc31cbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5nZXRTaXplID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB7XG4gICAgd2lkdGg6IHRoaXMuX2NvbnRhaW5lci5jbGllbnRXaWR0aCxcbiAgICBoZWlnaHQ6IHRoaXMuX2NvbnRhaW5lci5jbGllbnRIZWlnaHRcbiAgfTtcbn07XG5cblxuLyoqXG4gKiBSZXR1cm4gdGhlIGFic29sdXRlIGJvdW5kaW5nIGJveCBmb3IgdGhlIGdpdmVuIGVsZW1lbnRcbiAqXG4gKiBUaGUgYWJzb2x1dGUgYm91bmRpbmcgYm94IG1heSBiZSB1c2VkIHRvIGRpc3BsYXkgb3ZlcmxheXMgaW4gdGhlXG4gKiBjYWxsZXJzIChicm93c2VyKSBjb29yZGluYXRlIHN5c3RlbSByYXRoZXIgdGhhbiB0aGUgem9vbWVkIGluL291dFxuICogY2FudmFzIGNvb3JkaW5hdGVzLlxuICpcbiAqIEBwYXJhbSAge0VsZW1lbnREZXNjcmlwdG9yfSBlbGVtZW50XG4gKiBAcmV0dXJuIHtCb3VuZHN9IHRoZSBhYnNvbHV0ZSBib3VuZGluZyBib3hcbiAqL1xuQ2FudmFzLnByb3RvdHlwZS5nZXRBYnNvbHV0ZUJCb3ggPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciB2Ym94ID0gdGhpcy52aWV3Ym94KCk7XG4gIHZhciBiYm94O1xuXG4gIC8vIGNvbm5lY3Rpb25cbiAgLy8gdXNlIHN2ZyBiYm94XG4gIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgIHZhciBnZnggPSB0aGlzLmdldEdyYXBoaWNzKGVsZW1lbnQpO1xuXG4gICAgYmJveCA9IGdmeC5nZXRCQm94KCk7XG4gIH1cblxuICAvLyBzaGFwZXNcbiAgLy8gdXNlIGRhdGFcbiAgZWxzZSB7XG4gICAgYmJveCA9IGVsZW1lbnQ7XG4gIH1cblxuICB2YXIgeCA9IGJib3gueCAqIHZib3guc2NhbGUgLSB2Ym94LnggKiB2Ym94LnNjYWxlO1xuICB2YXIgeSA9IGJib3gueSAqIHZib3guc2NhbGUgLSB2Ym94LnkgKiB2Ym94LnNjYWxlO1xuXG4gIHZhciB3aWR0aCA9IGJib3gud2lkdGggKiB2Ym94LnNjYWxlO1xuICB2YXIgaGVpZ2h0ID0gYmJveC5oZWlnaHQgKiB2Ym94LnNjYWxlO1xuXG4gIHJldHVybiB7XG4gICAgeDogeCxcbiAgICB5OiB5LFxuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodFxuICB9O1xufTtcblxuLyoqXG4gKiBGaXJlcyBhbiBldmVudCBpbiBvcmRlciBvdGhlciBtb2R1bGVzIGNhbiByZWFjdCB0byB0aGVcbiAqIGNhbnZhcyByZXNpemluZ1xuICovXG5DYW52YXMucHJvdG90eXBlLnJlc2l6ZWQgPSBmdW5jdGlvbigpIHtcblxuICAvLyBmb3JjZSByZWNvbXB1dGF0aW9uIG9mIHZpZXcgYm94XG4gIGRlbGV0ZSB0aGlzLl9jYWNoZWRWaWV3Ym94O1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ2NhbnZhcy5yZXNpemVkJyk7XG59O1xuIiwiaW1wb3J0IHtcbiAgY3JlYXRlXG59IGZyb20gJy4uL21vZGVsJztcblxuaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnbWluLWRhc2gnO1xuXG4vKipcbiAqIEEgZmFjdG9yeSBmb3IgZGlhZ3JhbS1qcyBzaGFwZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRWxlbWVudEZhY3RvcnkoKSB7XG4gIHRoaXMuX3VpZCA9IDEyO1xufVxuXG5cbkVsZW1lbnRGYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVSb290ID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgcmV0dXJuIHRoaXMuY3JlYXRlKCdyb290JywgYXR0cnMpO1xufTtcblxuRWxlbWVudEZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZUxhYmVsID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgcmV0dXJuIHRoaXMuY3JlYXRlKCdsYWJlbCcsIGF0dHJzKTtcbn07XG5cbkVsZW1lbnRGYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVTaGFwZSA9IGZ1bmN0aW9uKGF0dHJzKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnc2hhcGUnLCBhdHRycyk7XG59O1xuXG5FbGVtZW50RmFjdG9yeS5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKGF0dHJzKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZSgnY29ubmVjdGlvbicsIGF0dHJzKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgbW9kZWwgZWxlbWVudCB3aXRoIHRoZSBnaXZlbiB0eXBlIGFuZFxuICogYSBudW1iZXIgb2YgcHJlLXNldCBhdHRyaWJ1dGVzLlxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gdHlwZVxuICogQHBhcmFtICB7T2JqZWN0fSBhdHRyc1xuICogQHJldHVybiB7ZGpzLm1vZGVsLkJhc2V9IHRoZSBuZXdseSBjcmVhdGVkIG1vZGVsIGluc3RhbmNlXG4gKi9cbkVsZW1lbnRGYWN0b3J5LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbih0eXBlLCBhdHRycykge1xuXG4gIGF0dHJzID0gYXNzaWduKHt9LCBhdHRycyB8fCB7fSk7XG5cbiAgaWYgKCFhdHRycy5pZCkge1xuICAgIGF0dHJzLmlkID0gdHlwZSArICdfJyArICh0aGlzLl91aWQrKyk7XG4gIH1cblxuICByZXR1cm4gY3JlYXRlKHR5cGUsIGF0dHJzKTtcbn07IiwidmFyIEVMRU1FTlRfSUQgPSAnZGF0YS1lbGVtZW50LWlkJztcblxuaW1wb3J0IHsgYXR0ciBhcyBzdmdBdHRyIH0gZnJvbSAndGlueS1zdmcnO1xuXG5cbi8qKlxuICogQGNsYXNzXG4gKlxuICogQSByZWdpc3RyeSB0aGF0IGtlZXBzIHRyYWNrIG9mIGFsbCBzaGFwZXMgaW4gdGhlIGRpYWdyYW0uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEVsZW1lbnRSZWdpc3RyeShldmVudEJ1cykge1xuICB0aGlzLl9lbGVtZW50cyA9IHt9O1xuXG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG59XG5cbkVsZW1lbnRSZWdpc3RyeS4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07XG5cbi8qKlxuICogUmVnaXN0ZXIgYSBwYWlyIG9mIChlbGVtZW50LCBnZngsIChzZWNvbmRhcnlHZngpKS5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGdmeFxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBbc2Vjb25kYXJ5R2Z4XSBvcHRpb25hbCBvdGhlciBlbGVtZW50IHRvIHJlZ2lzdGVyLCB0b29cbiAqL1xuRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihlbGVtZW50LCBnZngsIHNlY29uZGFyeUdmeCkge1xuXG4gIHZhciBpZCA9IGVsZW1lbnQuaWQ7XG5cbiAgdGhpcy5fdmFsaWRhdGVJZChpZCk7XG5cbiAgLy8gYXNzb2NpYXRlIGRvbSBub2RlIHdpdGggZWxlbWVudFxuICBzdmdBdHRyKGdmeCwgRUxFTUVOVF9JRCwgaWQpO1xuXG4gIGlmIChzZWNvbmRhcnlHZngpIHtcbiAgICBzdmdBdHRyKHNlY29uZGFyeUdmeCwgRUxFTUVOVF9JRCwgaWQpO1xuICB9XG5cbiAgdGhpcy5fZWxlbWVudHNbaWRdID0geyBlbGVtZW50OiBlbGVtZW50LCBnZng6IGdmeCwgc2Vjb25kYXJ5R2Z4OiBzZWNvbmRhcnlHZnggfTtcbn07XG5cbi8qKlxuICogUmVtb3ZlcyBhbiBlbGVtZW50IGZyb20gdGhlIHJlZ2lzdHJ5LlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqL1xuRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciBlbGVtZW50cyA9IHRoaXMuX2VsZW1lbnRzLFxuICAgICAgaWQgPSBlbGVtZW50LmlkIHx8IGVsZW1lbnQsXG4gICAgICBjb250YWluZXIgPSBpZCAmJiBlbGVtZW50c1tpZF07XG5cbiAgaWYgKGNvbnRhaW5lcikge1xuXG4gICAgLy8gdW5zZXQgZWxlbWVudCBpZCBvbiBnZnhcbiAgICBzdmdBdHRyKGNvbnRhaW5lci5nZngsIEVMRU1FTlRfSUQsICcnKTtcblxuICAgIGlmIChjb250YWluZXIuc2Vjb25kYXJ5R2Z4KSB7XG4gICAgICBzdmdBdHRyKGNvbnRhaW5lci5zZWNvbmRhcnlHZngsIEVMRU1FTlRfSUQsICcnKTtcbiAgICB9XG5cbiAgICBkZWxldGUgZWxlbWVudHNbaWRdO1xuICB9XG59O1xuXG4vKipcbiAqIFVwZGF0ZSB0aGUgaWQgb2YgYW4gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBuZXdJZFxuICovXG5FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLnVwZGF0ZUlkID0gZnVuY3Rpb24oZWxlbWVudCwgbmV3SWQpIHtcblxuICB0aGlzLl92YWxpZGF0ZUlkKG5ld0lkKTtcblxuICBpZiAodHlwZW9mIGVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgZWxlbWVudCA9IHRoaXMuZ2V0KGVsZW1lbnQpO1xuICB9XG5cbiAgdGhpcy5fZXZlbnRCdXMuZmlyZSgnZWxlbWVudC51cGRhdGVJZCcsIHtcbiAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgIG5ld0lkOiBuZXdJZFxuICB9KTtcblxuICB2YXIgZ2Z4ID0gdGhpcy5nZXRHcmFwaGljcyhlbGVtZW50KSxcbiAgICAgIHNlY29uZGFyeUdmeCA9IHRoaXMuZ2V0R3JhcGhpY3MoZWxlbWVudCwgdHJ1ZSk7XG5cbiAgdGhpcy5yZW1vdmUoZWxlbWVudCk7XG5cbiAgZWxlbWVudC5pZCA9IG5ld0lkO1xuXG4gIHRoaXMuYWRkKGVsZW1lbnQsIGdmeCwgc2Vjb25kYXJ5R2Z4KTtcbn07XG5cbi8qKlxuICogUmV0dXJuIHRoZSBtb2RlbCBlbGVtZW50IGZvciBhIGdpdmVuIGlkIG9yIGdyYXBoaWNzLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogZWxlbWVudFJlZ2lzdHJ5LmdldCgnU29tZUVsZW1lbnRJZF8xJyk7XG4gKiBlbGVtZW50UmVnaXN0cnkuZ2V0KGdmeCk7XG4gKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfFNWR0VsZW1lbnR9IGZpbHRlciBmb3Igc2VsZWN0aW5nIHRoZSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7ZGpzLm1vZGVsLkJhc2V9XG4gKi9cbkVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oZmlsdGVyKSB7XG4gIHZhciBpZDtcblxuICBpZiAodHlwZW9mIGZpbHRlciA9PT0gJ3N0cmluZycpIHtcbiAgICBpZCA9IGZpbHRlcjtcbiAgfSBlbHNlIHtcbiAgICBpZCA9IGZpbHRlciAmJiBzdmdBdHRyKGZpbHRlciwgRUxFTUVOVF9JRCk7XG4gIH1cblxuICB2YXIgY29udGFpbmVyID0gdGhpcy5fZWxlbWVudHNbaWRdO1xuICByZXR1cm4gY29udGFpbmVyICYmIGNvbnRhaW5lci5lbGVtZW50O1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYWxsIGVsZW1lbnRzIHRoYXQgbWF0Y2ggYSBnaXZlbiBmaWx0ZXIgZnVuY3Rpb24uXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuQmFzZT59XG4gKi9cbkVsZW1lbnRSZWdpc3RyeS5wcm90b3R5cGUuZmlsdGVyID0gZnVuY3Rpb24oZm4pIHtcblxuICB2YXIgZmlsdGVyZWQgPSBbXTtcblxuICB0aGlzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG4gICAgaWYgKGZuKGVsZW1lbnQsIGdmeCkpIHtcbiAgICAgIGZpbHRlcmVkLnB1c2goZWxlbWVudCk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gZmlsdGVyZWQ7XG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IHNhdGlzZmllcyB0aGUgcHJvdmlkZWQgdGVzdGluZyBmdW5jdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5CYXNlfVxuICovXG5FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLmZpbmQgPSBmdW5jdGlvbihmbikge1xuICB2YXIgbWFwID0gdGhpcy5fZWxlbWVudHMsXG4gICAgICBrZXlzID0gT2JqZWN0LmtleXMobWFwKTtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaWQgPSBrZXlzW2ldLFxuICAgICAgICBjb250YWluZXIgPSBtYXBbaWRdLFxuICAgICAgICBlbGVtZW50ID0gY29udGFpbmVyLmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGNvbnRhaW5lci5nZng7XG5cbiAgICBpZiAoZm4oZWxlbWVudCwgZ2Z4KSkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQ7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFJldHVybiBhbGwgcmVuZGVyZWQgbW9kZWwgZWxlbWVudHMuXG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fVxuICovXG5FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLmdldEFsbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5maWx0ZXIoZnVuY3Rpb24oZSkgeyByZXR1cm4gZTsgfSk7XG59O1xuXG4vKipcbiAqIEl0ZXJhdGUgb3ZlciBhbGwgZGlhZ3JhbSBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICovXG5FbGVtZW50UmVnaXN0cnkucHJvdG90eXBlLmZvckVhY2ggPSBmdW5jdGlvbihmbikge1xuXG4gIHZhciBtYXAgPSB0aGlzLl9lbGVtZW50cztcblxuICBPYmplY3Qua2V5cyhtYXApLmZvckVhY2goZnVuY3Rpb24oaWQpIHtcbiAgICB2YXIgY29udGFpbmVyID0gbWFwW2lkXSxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRhaW5lci5lbGVtZW50LFxuICAgICAgICBnZnggPSBjb250YWluZXIuZ2Z4O1xuXG4gICAgcmV0dXJuIGZuKGVsZW1lbnQsIGdmeCk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gdGhlIGdyYXBoaWNhbCByZXByZXNlbnRhdGlvbiBvZiBhbiBlbGVtZW50IG9yIGl0cyBpZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKCdTb21lRWxlbWVudElkXzEnKTtcbiAqIGVsZW1lbnRSZWdpc3RyeS5nZXRHcmFwaGljcyhyb290RWxlbWVudCk7IC8vIDxnIC4uLj5cbiAqXG4gKiBlbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3Mocm9vdEVsZW1lbnQsIHRydWUpOyAvLyA8c3ZnIC4uLj5cbiAqXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8ZGpzLm1vZGVsLkJhc2V9IGZpbHRlclxuICogQHBhcmFtIHtib29sZWFufSBbc2Vjb25kYXJ5PWZhbHNlXSB3aGV0aGVyIHRvIHJldHVybiB0aGUgc2Vjb25kYXJ5IGNvbm5lY3RlZCBlbGVtZW50XG4gKlxuICogQHJldHVybiB7U1ZHRWxlbWVudH1cbiAqL1xuRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5nZXRHcmFwaGljcyA9IGZ1bmN0aW9uKGZpbHRlciwgc2Vjb25kYXJ5KSB7XG4gIHZhciBpZCA9IGZpbHRlci5pZCB8fCBmaWx0ZXI7XG5cbiAgdmFyIGNvbnRhaW5lciA9IHRoaXMuX2VsZW1lbnRzW2lkXTtcbiAgcmV0dXJuIGNvbnRhaW5lciAmJiAoc2Vjb25kYXJ5ID8gY29udGFpbmVyLnNlY29uZGFyeUdmeCA6IGNvbnRhaW5lci5nZngpO1xufTtcblxuLyoqXG4gKiBWYWxpZGF0ZSB0aGUgc3VpdGFiaWxpdHkgb2YgdGhlIGdpdmVuIGlkIGFuZCBzaWduYWxzIGEgcHJvYmxlbVxuICogd2l0aCBhbiBleGNlcHRpb24uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGlkXG4gKlxuICogQHRocm93cyB7RXJyb3J9IGlmIGlkIGlzIGVtcHR5IG9yIGFscmVhZHkgYXNzaWduZWRcbiAqL1xuRWxlbWVudFJlZ2lzdHJ5LnByb3RvdHlwZS5fdmFsaWRhdGVJZCA9IGZ1bmN0aW9uKGlkKSB7XG4gIGlmICghaWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2VsZW1lbnQgbXVzdCBoYXZlIGFuIGlkJyk7XG4gIH1cblxuICBpZiAodGhpcy5fZWxlbWVudHNbaWRdKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbGVtZW50IHdpdGggaWQgJyArIGlkICsgJyBhbHJlYWR5IGFkZGVkJyk7XG4gIH1cbn07XG4iLCJpbXBvcnQge1xuICBpc0Z1bmN0aW9uLFxuICBpc0FycmF5LFxuICBpc051bWJlcixcbiAgYmluZCxcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIEZOX1JFRiA9ICdfX2ZuJztcblxudmFyIERFRkFVTFRfUFJJT1JJVFkgPSAxMDAwO1xuXG52YXIgc2xpY2UgPSBBcnJheS5wcm90b3R5cGUuc2xpY2U7XG5cbi8qKlxuICogQSBnZW5lcmFsIHB1cnBvc2UgZXZlbnQgYnVzLlxuICpcbiAqIFRoaXMgY29tcG9uZW50IGlzIHVzZWQgdG8gY29tbXVuaWNhdGUgYWNyb3NzIGEgZGlhZ3JhbSBpbnN0YW5jZS5cbiAqIE90aGVyIHBhcnRzIG9mIGEgZGlhZ3JhbSBjYW4gdXNlIGl0IHRvIGxpc3RlbiB0byBhbmQgYnJvYWRjYXN0IGV2ZW50cy5cbiAqXG4gKlxuICogIyMgUmVnaXN0ZXJpbmcgZm9yIEV2ZW50c1xuICpcbiAqIFRoZSBldmVudCBidXMgcHJvdmlkZXMgdGhlIHtAbGluayBFdmVudEJ1cyNvbn0gYW5kIHtAbGluayBFdmVudEJ1cyNvbmNlfVxuICogbWV0aG9kcyB0byByZWdpc3RlciBmb3IgZXZlbnRzLiB7QGxpbmsgRXZlbnRCdXMjb2ZmfSBjYW4gYmUgdXNlZCB0b1xuICogcmVtb3ZlIGV2ZW50IHJlZ2lzdHJhdGlvbnMuIExpc3RlbmVycyByZWNlaXZlIGFuIGluc3RhbmNlIG9mIHtAbGluayBFdmVudH1cbiAqIGFzIHRoZSBmaXJzdCBhcmd1bWVudC4gSXQgYWxsb3dzIHRoZW0gdG8gaG9vayBpbnRvIHRoZSBldmVudCBleGVjdXRpb24uXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICpcbiAqIC8vIGxpc3RlbiBmb3IgZXZlbnRcbiAqIGV2ZW50QnVzLm9uKCdmb28nLCBmdW5jdGlvbihldmVudCkge1xuICpcbiAqICAgLy8gYWNjZXNzIGV2ZW50IHR5cGVcbiAqICAgZXZlbnQudHlwZTsgLy8gJ2ZvbydcbiAqXG4gKiAgIC8vIHN0b3AgcHJvcGFnYXRpb24gdG8gb3RoZXIgbGlzdGVuZXJzXG4gKiAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICpcbiAqICAgLy8gcHJldmVudCBldmVudCBkZWZhdWx0XG4gKiAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gKiB9KTtcbiAqXG4gKiAvLyBsaXN0ZW4gZm9yIGV2ZW50IHdpdGggY3VzdG9tIHBheWxvYWRcbiAqIGV2ZW50QnVzLm9uKCdiYXInLCBmdW5jdGlvbihldmVudCwgcGF5bG9hZCkge1xuICogICBjb25zb2xlLmxvZyhwYXlsb2FkKTtcbiAqIH0pO1xuICpcbiAqIC8vIGxpc3RlbiBmb3IgZXZlbnQgcmV0dXJuaW5nIHZhbHVlXG4gKiBldmVudEJ1cy5vbignZm9vYmFyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqXG4gKiAgIC8vIHN0b3AgZXZlbnQgcHJvcGFnYXRpb24gKyBwcmV2ZW50IGRlZmF1bHRcbiAqICAgcmV0dXJuIGZhbHNlO1xuICpcbiAqICAgLy8gc3RvcCBldmVudCBwcm9wYWdhdGlvbiArIHJldHVybiBjdXN0b20gcmVzdWx0XG4gKiAgIHJldHVybiB7XG4gKiAgICAgY29tcGxleDogJ2xpc3RlbmluZyByZXN1bHQnXG4gKiAgIH07XG4gKiB9KTtcbiAqXG4gKlxuICogLy8gbGlzdGVuIHdpdGggY3VzdG9tIHByaW9yaXR5IChkZWZhdWx0PTEwMDAsIGhpZ2hlciBpcyBiZXR0ZXIpXG4gKiBldmVudEJ1cy5vbigncHJpb3JpdHlmb28nLCAxNTAwLCBmdW5jdGlvbihldmVudCkge1xuICogICBjb25zb2xlLmxvZygnaW52b2tlZCBmaXJzdCEnKTtcbiAqIH0pO1xuICpcbiAqXG4gKiAvLyBsaXN0ZW4gZm9yIGV2ZW50IGFuZCBwYXNzIHRoZSBjb250ZXh0IChgdGhpc2ApXG4gKiBldmVudEJ1cy5vbignZm9vYmFyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgdGhpcy5mb28oKTtcbiAqIH0sIHRoaXMpO1xuICogYGBgXG4gKlxuICpcbiAqICMjIEVtaXR0aW5nIEV2ZW50c1xuICpcbiAqIEV2ZW50cyBjYW4gYmUgZW1pdHRlZCB2aWEgdGhlIGV2ZW50IGJ1cyB1c2luZyB7QGxpbmsgRXZlbnRCdXMjZmlyZX0uXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICpcbiAqIC8vIGZhbHNlIGluZGljYXRlcyB0aGF0IHRoZSBkZWZhdWx0IGFjdGlvblxuICogLy8gd2FzIHByZXZlbnRlZCBieSBsaXN0ZW5lcnNcbiAqIGlmIChldmVudEJ1cy5maXJlKCdmb28nKSA9PT0gZmFsc2UpIHtcbiAqICAgY29uc29sZS5sb2coJ2RlZmF1bHQgaGFzIGJlZW4gcHJldmVudGVkIScpO1xuICogfTtcbiAqXG4gKlxuICogLy8gY3VzdG9tIGFyZ3MgKyByZXR1cm4gdmFsdWUgbGlzdGVuZXJcbiAqIGV2ZW50QnVzLm9uKCdzdW0nLCBmdW5jdGlvbihldmVudCwgYSwgYikge1xuICogICByZXR1cm4gYSArIGI7XG4gKiB9KTtcbiAqXG4gKiAvLyB5b3UgY2FuIHBhc3MgY3VzdG9tIGFyZ3VtZW50cyArIHJldHJpZXZlIHJlc3VsdCB2YWx1ZXMuXG4gKiB2YXIgc3VtID0gZXZlbnRCdXMuZmlyZSgnc3VtJywgMSwgMik7XG4gKiBjb25zb2xlLmxvZyhzdW0pOyAvLyAzXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRXZlbnRCdXMoKSB7XG4gIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xuXG4gIC8vIGNsZWFudXAgb24gZGVzdHJveSBvbiBsb3dlc3QgcHJpb3JpdHkgdG8gYWxsb3dcbiAgLy8gbWVzc2FnZSBwYXNzaW5nIHVudGlsIHRoZSBiaXR0ZXIgZW5kXG4gIHRoaXMub24oJ2RpYWdyYW0uZGVzdHJveScsIDEsIHRoaXMuX2Rlc3Ryb3ksIHRoaXMpO1xufVxuXG5cbi8qKlxuICogUmVnaXN0ZXIgYW4gZXZlbnQgbGlzdGVuZXIgZm9yIGV2ZW50cyB3aXRoIHRoZSBnaXZlbiBuYW1lLlxuICpcbiAqIFRoZSBjYWxsYmFjayB3aWxsIGJlIGludm9rZWQgd2l0aCBgZXZlbnQsIC4uLmFkZGl0aW9uYWxBcmd1bWVudHNgXG4gKiB0aGF0IGhhdmUgYmVlbiBwYXNzZWQgdG8ge0BsaW5rIEV2ZW50QnVzI2ZpcmV9LlxuICpcbiAqIFJldHVybmluZyBmYWxzZSBmcm9tIGEgbGlzdGVuZXIgd2lsbCBwcmV2ZW50IHRoZSBldmVudHMgZGVmYXVsdCBhY3Rpb25cbiAqIChpZiBhbnkgaXMgc3BlY2lmaWVkKS4gVG8gc3RvcCBhbiBldmVudCBmcm9tIGJlaW5nIHByb2Nlc3NlZCBmdXJ0aGVyIGluXG4gKiBvdGhlciBsaXN0ZW5lcnMgZXhlY3V0ZSB7QGxpbmsgRXZlbnQjc3RvcFByb3BhZ2F0aW9ufS5cbiAqXG4gKiBSZXR1cm5pbmcgYW55dGhpbmcgYnV0IGB1bmRlZmluZWRgIGZyb20gYSBsaXN0ZW5lciB3aWxsIHN0b3AgdGhlIGxpc3RlbmVyIHByb3BhZ2F0aW9uLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfEFycmF5PHN0cmluZz59IGV2ZW50c1xuICogQHBhcmFtIHtudW1iZXJ9IFtwcmlvcml0eT0xMDAwXSB0aGUgcHJpb3JpdHkgaW4gd2hpY2ggdGhpcyBsaXN0ZW5lciBpcyBjYWxsZWQsIGxhcmdlciBpcyBoaWdoZXJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcGFyYW0ge09iamVjdH0gW3RoYXRdIFBhc3MgY29udGV4dCAoYHRoaXNgKSB0byB0aGUgY2FsbGJhY2tcbiAqL1xuRXZlbnRCdXMucHJvdG90eXBlLm9uID0gZnVuY3Rpb24oZXZlbnRzLCBwcmlvcml0eSwgY2FsbGJhY2ssIHRoYXQpIHtcblxuICBldmVudHMgPSBpc0FycmF5KGV2ZW50cykgPyBldmVudHMgOiBbIGV2ZW50cyBdO1xuXG4gIGlmIChpc0Z1bmN0aW9uKHByaW9yaXR5KSkge1xuICAgIHRoYXQgPSBjYWxsYmFjaztcbiAgICBjYWxsYmFjayA9IHByaW9yaXR5O1xuICAgIHByaW9yaXR5ID0gREVGQVVMVF9QUklPUklUWTtcbiAgfVxuXG4gIGlmICghaXNOdW1iZXIocHJpb3JpdHkpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwcmlvcml0eSBtdXN0IGJlIGEgbnVtYmVyJyk7XG4gIH1cblxuICB2YXIgYWN0dWFsQ2FsbGJhY2sgPSBjYWxsYmFjaztcblxuICBpZiAodGhhdCkge1xuICAgIGFjdHVhbENhbGxiYWNrID0gYmluZChjYWxsYmFjaywgdGhhdCk7XG5cbiAgICAvLyBtYWtlIHN1cmUgd2UgcmVtZW1iZXIgYW5kIGFyZSBhYmxlIHRvIHJlbW92ZVxuICAgIC8vIGJvdW5kIGNhbGxiYWNrcyB2aWEge0BsaW5rICNvZmZ9IHVzaW5nIHRoZSBvcmlnaW5hbFxuICAgIC8vIGNhbGxiYWNrXG4gICAgYWN0dWFsQ2FsbGJhY2tbRk5fUkVGXSA9IGNhbGxiYWNrW0ZOX1JFRl0gfHwgY2FsbGJhY2s7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24oZSkge1xuICAgIHNlbGYuX2FkZExpc3RlbmVyKGUsIHtcbiAgICAgIHByaW9yaXR5OiBwcmlvcml0eSxcbiAgICAgIGNhbGxiYWNrOiBhY3R1YWxDYWxsYmFjayxcbiAgICAgIG5leHQ6IG51bGxcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmVnaXN0ZXIgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBpcyBleGVjdXRlZCBvbmx5IG9uY2UuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50IHRoZSBldmVudCBuYW1lIHRvIHJlZ2lzdGVyIGZvclxuICogQHBhcmFtIHtudW1iZXJ9IFtwcmlvcml0eT0xMDAwXSB0aGUgcHJpb3JpdHkgaW4gd2hpY2ggdGhpcyBsaXN0ZW5lciBpcyBjYWxsZWQsIGxhcmdlciBpcyBoaWdoZXJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHRoZSBjYWxsYmFjayB0byBleGVjdXRlXG4gKiBAcGFyYW0ge09iamVjdH0gW3RoYXRdIFBhc3MgY29udGV4dCAoYHRoaXNgKSB0byB0aGUgY2FsbGJhY2tcbiAqL1xuRXZlbnRCdXMucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbihldmVudCwgcHJpb3JpdHksIGNhbGxiYWNrLCB0aGF0KSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAoaXNGdW5jdGlvbihwcmlvcml0eSkpIHtcbiAgICB0aGF0ID0gY2FsbGJhY2s7XG4gICAgY2FsbGJhY2sgPSBwcmlvcml0eTtcbiAgICBwcmlvcml0eSA9IERFRkFVTFRfUFJJT1JJVFk7XG4gIH1cblxuICBpZiAoIWlzTnVtYmVyKHByaW9yaXR5KSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJpb3JpdHkgbXVzdCBiZSBhIG51bWJlcicpO1xuICB9XG5cbiAgZnVuY3Rpb24gd3JhcHBlZENhbGxiYWNrKCkge1xuICAgIHZhciByZXN1bHQgPSBjYWxsYmFjay5hcHBseSh0aGF0LCBhcmd1bWVudHMpO1xuXG4gICAgc2VsZi5vZmYoZXZlbnQsIHdyYXBwZWRDYWxsYmFjayk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gbWFrZSBzdXJlIHdlIHJlbWVtYmVyIGFuZCBhcmUgYWJsZSB0byByZW1vdmVcbiAgLy8gYm91bmQgY2FsbGJhY2tzIHZpYSB7QGxpbmsgI29mZn0gdXNpbmcgdGhlIG9yaWdpbmFsXG4gIC8vIGNhbGxiYWNrXG4gIHdyYXBwZWRDYWxsYmFja1tGTl9SRUZdID0gY2FsbGJhY2s7XG5cbiAgdGhpcy5vbihldmVudCwgcHJpb3JpdHksIHdyYXBwZWRDYWxsYmFjayk7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlcyBldmVudCBsaXN0ZW5lcnMgYnkgZXZlbnQgYW5kIGNhbGxiYWNrLlxuICpcbiAqIElmIG5vIGNhbGxiYWNrIGlzIGdpdmVuLCBhbGwgbGlzdGVuZXJzIGZvciBhIGdpdmVuIGV2ZW50IG5hbWUgYXJlIGJlaW5nIHJlbW92ZWQuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gZXZlbnRzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdXG4gKi9cbkV2ZW50QnVzLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbihldmVudHMsIGNhbGxiYWNrKSB7XG5cbiAgZXZlbnRzID0gaXNBcnJheShldmVudHMpID8gZXZlbnRzIDogWyBldmVudHMgXTtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBzZWxmLl9yZW1vdmVMaXN0ZW5lcihldmVudCwgY2FsbGJhY2spO1xuICB9KTtcblxufTtcblxuXG4vKipcbiAqIENyZWF0ZSBhbiBFdmVudEJ1cyBldmVudC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZGF0YVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gZXZlbnQsIHJlY29nbml6ZWQgYnkgdGhlIGV2ZW50QnVzXG4gKi9cbkV2ZW50QnVzLnByb3RvdHlwZS5jcmVhdGVFdmVudCA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgdmFyIGV2ZW50ID0gbmV3IEludGVybmFsRXZlbnQoKTtcblxuICBldmVudC5pbml0KGRhdGEpO1xuXG4gIHJldHVybiBldmVudDtcbn07XG5cblxuLyoqXG4gKiBGaXJlcyBhIG5hbWVkIGV2ZW50LlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gZmlyZSBldmVudCBieSBuYW1lXG4gKiBldmVudHMuZmlyZSgnZm9vJyk7XG4gKlxuICogLy8gZmlyZSBldmVudCBvYmplY3Qgd2l0aCBuZXN0ZWQgdHlwZVxuICogdmFyIGV2ZW50ID0geyB0eXBlOiAnZm9vJyB9O1xuICogZXZlbnRzLmZpcmUoZXZlbnQpO1xuICpcbiAqIC8vIGZpcmUgZXZlbnQgd2l0aCBleHBsaWNpdCB0eXBlXG4gKiB2YXIgZXZlbnQgPSB7IHg6IDEwLCB5OiAyMCB9O1xuICogZXZlbnRzLmZpcmUoJ2VsZW1lbnQubW92ZWQnLCBldmVudCk7XG4gKlxuICogLy8gcGFzcyBhZGRpdGlvbmFsIGFyZ3VtZW50cyB0byB0aGUgZXZlbnRcbiAqIGV2ZW50cy5vbignZm9vJywgZnVuY3Rpb24oZXZlbnQsIGJhcikge1xuICogICBhbGVydChiYXIpO1xuICogfSk7XG4gKlxuICogZXZlbnRzLmZpcmUoeyB0eXBlOiAnZm9vJyB9LCAnSSBhbSBiYXIhJyk7XG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtuYW1lXSB0aGUgb3B0aW9uYWwgZXZlbnQgbmFtZVxuICogQHBhcmFtIHtPYmplY3R9IFtldmVudF0gdGhlIGV2ZW50IG9iamVjdFxuICogQHBhcmFtIHsuLi5PYmplY3R9IGFkZGl0aW9uYWwgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byB0aGUgY2FsbGJhY2sgZnVuY3Rpb25zXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gdGhlIGV2ZW50cyByZXR1cm4gdmFsdWUsIGlmIHNwZWNpZmllZCBvciBmYWxzZSBpZiB0aGVcbiAqICAgICAgICAgICAgICAgICAgIGRlZmF1bHQgYWN0aW9uIHdhcyBwcmV2ZW50ZWQgYnkgbGlzdGVuZXJzXG4gKi9cbkV2ZW50QnVzLnByb3RvdHlwZS5maXJlID0gZnVuY3Rpb24odHlwZSwgZGF0YSkge1xuICB2YXIgZXZlbnQsXG4gICAgICBmaXJzdExpc3RlbmVyLFxuICAgICAgcmV0dXJuVmFsdWUsXG4gICAgICBhcmdzO1xuXG4gIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgaWYgKHR5cGVvZiB0eXBlID09PSAnb2JqZWN0Jykge1xuICAgIGRhdGEgPSB0eXBlO1xuICAgIHR5cGUgPSBkYXRhLnR5cGU7XG4gIH1cblxuICBpZiAoIXR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIGV2ZW50IHR5cGUgc3BlY2lmaWVkJyk7XG4gIH1cblxuICBmaXJzdExpc3RlbmVyID0gdGhpcy5fbGlzdGVuZXJzW3R5cGVdO1xuXG4gIGlmICghZmlyc3RMaXN0ZW5lcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIHdlIG1ha2Ugc3VyZSB3ZSBmaXJlIGluc3RhbmNlcyBvZiBvdXIgaG9tZSBtYWRlXG4gIC8vIGV2ZW50cyBoZXJlLiBXZSB3cmFwIHRoZW0gb25seSBvbmNlLCB0aG91Z2hcbiAgaWYgKGRhdGEgaW5zdGFuY2VvZiBJbnRlcm5hbEV2ZW50KSB7XG5cbiAgICAvLyB3ZSBhcmUgZmluZSwgd2UgYWxyZWFkIGhhdmUgYW4gZXZlbnRcbiAgICBldmVudCA9IGRhdGE7XG4gIH0gZWxzZSB7XG4gICAgZXZlbnQgPSB0aGlzLmNyZWF0ZUV2ZW50KGRhdGEpO1xuICB9XG5cbiAgLy8gZW5zdXJlIHdlIHBhc3MgdGhlIGV2ZW50IGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXJcbiAgYXJnc1swXSA9IGV2ZW50O1xuXG4gIC8vIG9yaWdpbmFsIGV2ZW50IHR5cGUgKGluIGNhc2Ugd2UgZGVsZWdhdGUpXG4gIHZhciBvcmlnaW5hbFR5cGUgPSBldmVudC50eXBlO1xuXG4gIC8vIHVwZGF0ZSBldmVudCB0eXBlIGJlZm9yZSBkZWxlZ2F0aW9uXG4gIGlmICh0eXBlICE9PSBvcmlnaW5hbFR5cGUpIHtcbiAgICBldmVudC50eXBlID0gdHlwZTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgcmV0dXJuVmFsdWUgPSB0aGlzLl9pbnZva2VMaXN0ZW5lcnMoZXZlbnQsIGFyZ3MsIGZpcnN0TGlzdGVuZXIpO1xuICB9IGZpbmFsbHkge1xuXG4gICAgLy8gcmVzZXQgZXZlbnQgdHlwZSBhZnRlciBkZWxlZ2F0aW9uXG4gICAgaWYgKHR5cGUgIT09IG9yaWdpbmFsVHlwZSkge1xuICAgICAgZXZlbnQudHlwZSA9IG9yaWdpbmFsVHlwZTtcbiAgICB9XG4gIH1cblxuICAvLyBzZXQgdGhlIHJldHVybiB2YWx1ZSB0byBmYWxzZSBpZiB0aGUgZXZlbnQgZGVmYXVsdFxuICAvLyBnb3QgcHJldmVudGVkIGFuZCBubyBvdGhlciByZXR1cm4gdmFsdWUgZXhpc3RzXG4gIGlmIChyZXR1cm5WYWx1ZSA9PT0gdW5kZWZpbmVkICYmIGV2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICByZXR1cm5WYWx1ZSA9IGZhbHNlO1xuICB9XG5cbiAgcmV0dXJuIHJldHVyblZhbHVlO1xufTtcblxuXG5FdmVudEJ1cy5wcm90b3R5cGUuaGFuZGxlRXJyb3IgPSBmdW5jdGlvbihlcnJvcikge1xuICByZXR1cm4gdGhpcy5maXJlKCdlcnJvcicsIHsgZXJyb3I6IGVycm9yIH0pID09PSBmYWxzZTtcbn07XG5cblxuRXZlbnRCdXMucHJvdG90eXBlLl9kZXN0cm95ID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX2xpc3RlbmVycyA9IHt9O1xufTtcblxuRXZlbnRCdXMucHJvdG90eXBlLl9pbnZva2VMaXN0ZW5lcnMgPSBmdW5jdGlvbihldmVudCwgYXJncywgbGlzdGVuZXIpIHtcblxuICB2YXIgcmV0dXJuVmFsdWU7XG5cbiAgd2hpbGUgKGxpc3RlbmVyKSB7XG5cbiAgICAvLyBoYW5kbGUgc3RvcHBlZCBwcm9wYWdhdGlvblxuICAgIGlmIChldmVudC5jYW5jZWxCdWJibGUpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVyblZhbHVlID0gdGhpcy5faW52b2tlTGlzdGVuZXIoZXZlbnQsIGFyZ3MsIGxpc3RlbmVyKTtcblxuICAgIGxpc3RlbmVyID0gbGlzdGVuZXIubmV4dDtcbiAgfVxuXG4gIHJldHVybiByZXR1cm5WYWx1ZTtcbn07XG5cbkV2ZW50QnVzLnByb3RvdHlwZS5faW52b2tlTGlzdGVuZXIgPSBmdW5jdGlvbihldmVudCwgYXJncywgbGlzdGVuZXIpIHtcblxuICB2YXIgcmV0dXJuVmFsdWU7XG5cbiAgdHJ5IHtcblxuICAgIC8vIHJldHVybmluZyBmYWxzZSBwcmV2ZW50cyB0aGUgZGVmYXVsdCBhY3Rpb25cbiAgICByZXR1cm5WYWx1ZSA9IGludm9rZUZ1bmN0aW9uKGxpc3RlbmVyLmNhbGxiYWNrLCBhcmdzKTtcblxuICAgIC8vIHN0b3AgcHJvcGFnYXRpb24gb24gcmV0dXJuIHZhbHVlXG4gICAgaWYgKHJldHVyblZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGV2ZW50LnJldHVyblZhbHVlID0gcmV0dXJuVmFsdWU7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICAvLyBwcmV2ZW50IGRlZmF1bHQgb24gcmV0dXJuIGZhbHNlXG4gICAgaWYgKHJldHVyblZhbHVlID09PSBmYWxzZSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoIXRoaXMuaGFuZGxlRXJyb3IoZSkpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ3VuaGFuZGxlZCBlcnJvciBpbiBldmVudCBsaXN0ZW5lcicpO1xuICAgICAgY29uc29sZS5lcnJvcihlLnN0YWNrKTtcblxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmV0dXJuVmFsdWU7XG59O1xuXG4vKlxuICogQWRkIG5ldyBsaXN0ZW5lciB3aXRoIGEgY2VydGFpbiBwcmlvcml0eSB0byB0aGUgbGlzdFxuICogb2YgbGlzdGVuZXJzIChmb3IgdGhlIGdpdmVuIGV2ZW50KS5cbiAqXG4gKiBUaGUgc2VtYW50aWNzIG9mIGxpc3RlbmVyIHJlZ2lzdHJhdGlvbiAvIGxpc3RlbmVyIGV4ZWN1dGlvbiBhcmVcbiAqIGZpcnN0IHJlZ2lzdGVyLCBmaXJzdCBzZXJ2ZTogTmV3IGxpc3RlbmVycyB3aWxsIGFsd2F5cyBiZSBpbnNlcnRlZFxuICogYWZ0ZXIgZXhpc3RpbmcgbGlzdGVuZXJzIHdpdGggdGhlIHNhbWUgcHJpb3JpdHkuXG4gKlxuICogRXhhbXBsZTogSW5zZXJ0aW5nIHR3byBsaXN0ZW5lcnMgd2l0aCBwcmlvcml0eSAxMDAwIGFuZCAxMzAwXG4gKlxuICogICAgKiBiZWZvcmU6IFsgMTUwMCwgMTUwMCwgMTAwMCwgMTAwMCBdXG4gKiAgICAqIGFmdGVyOiBbIDE1MDAsIDE1MDAsIChuZXc9MTMwMCksIDEwMDAsIDEwMDAsIChuZXc9MTAwMCkgXVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtPYmplY3R9IGxpc3RlbmVyIHsgcHJpb3JpdHksIGNhbGxiYWNrIH1cbiAqL1xuRXZlbnRCdXMucHJvdG90eXBlLl9hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uKGV2ZW50LCBuZXdMaXN0ZW5lcikge1xuXG4gIHZhciBsaXN0ZW5lciA9IHRoaXMuX2dldExpc3RlbmVycyhldmVudCksXG4gICAgICBwcmV2aW91c0xpc3RlbmVyO1xuXG4gIC8vIG5vIHByaW9yIGxpc3RlbmVyc1xuICBpZiAoIWxpc3RlbmVyKSB7XG4gICAgdGhpcy5fc2V0TGlzdGVuZXJzKGV2ZW50LCBuZXdMaXN0ZW5lcik7XG5cbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBlbnN1cmUgd2Ugb3JkZXIgbGlzdGVuZXJzIGJ5IHByaW9yaXR5IGZyb21cbiAgLy8gMCAoaGlnaCkgdG8gbiA+IDAgKGxvdylcbiAgd2hpbGUgKGxpc3RlbmVyKSB7XG5cbiAgICBpZiAobGlzdGVuZXIucHJpb3JpdHkgPCBuZXdMaXN0ZW5lci5wcmlvcml0eSkge1xuXG4gICAgICBuZXdMaXN0ZW5lci5uZXh0ID0gbGlzdGVuZXI7XG5cbiAgICAgIGlmIChwcmV2aW91c0xpc3RlbmVyKSB7XG4gICAgICAgIHByZXZpb3VzTGlzdGVuZXIubmV4dCA9IG5ld0xpc3RlbmVyO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fc2V0TGlzdGVuZXJzKGV2ZW50LCBuZXdMaXN0ZW5lcik7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwcmV2aW91c0xpc3RlbmVyID0gbGlzdGVuZXI7XG4gICAgbGlzdGVuZXIgPSBsaXN0ZW5lci5uZXh0O1xuICB9XG5cbiAgLy8gYWRkIG5ldyBsaXN0ZW5lciB0byBiYWNrXG4gIHByZXZpb3VzTGlzdGVuZXIubmV4dCA9IG5ld0xpc3RlbmVyO1xufTtcblxuXG5FdmVudEJ1cy5wcm90b3R5cGUuX2dldExpc3RlbmVycyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuIHRoaXMuX2xpc3RlbmVyc1tuYW1lXTtcbn07XG5cbkV2ZW50QnVzLnByb3RvdHlwZS5fc2V0TGlzdGVuZXJzID0gZnVuY3Rpb24obmFtZSwgbGlzdGVuZXIpIHtcbiAgdGhpcy5fbGlzdGVuZXJzW25hbWVdID0gbGlzdGVuZXI7XG59O1xuXG5FdmVudEJ1cy5wcm90b3R5cGUuX3JlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24oZXZlbnQsIGNhbGxiYWNrKSB7XG5cbiAgdmFyIGxpc3RlbmVyID0gdGhpcy5fZ2V0TGlzdGVuZXJzKGV2ZW50KSxcbiAgICAgIG5leHRMaXN0ZW5lcixcbiAgICAgIHByZXZpb3VzTGlzdGVuZXIsXG4gICAgICBsaXN0ZW5lckNhbGxiYWNrO1xuXG4gIGlmICghY2FsbGJhY2spIHtcblxuICAgIC8vIGNsZWFyIGxpc3RlbmVyc1xuICAgIHRoaXMuX3NldExpc3RlbmVycyhldmVudCwgbnVsbCk7XG5cbiAgICByZXR1cm47XG4gIH1cblxuICB3aGlsZSAobGlzdGVuZXIpIHtcblxuICAgIG5leHRMaXN0ZW5lciA9IGxpc3RlbmVyLm5leHQ7XG5cbiAgICBsaXN0ZW5lckNhbGxiYWNrID0gbGlzdGVuZXIuY2FsbGJhY2s7XG5cbiAgICBpZiAobGlzdGVuZXJDYWxsYmFjayA9PT0gY2FsbGJhY2sgfHwgbGlzdGVuZXJDYWxsYmFja1tGTl9SRUZdID09PSBjYWxsYmFjaykge1xuICAgICAgaWYgKHByZXZpb3VzTGlzdGVuZXIpIHtcbiAgICAgICAgcHJldmlvdXNMaXN0ZW5lci5uZXh0ID0gbmV4dExpc3RlbmVyO1xuICAgICAgfSBlbHNlIHtcblxuICAgICAgICAvLyBuZXcgZmlyc3QgbGlzdGVuZXJcbiAgICAgICAgdGhpcy5fc2V0TGlzdGVuZXJzKGV2ZW50LCBuZXh0TGlzdGVuZXIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHByZXZpb3VzTGlzdGVuZXIgPSBsaXN0ZW5lcjtcbiAgICBsaXN0ZW5lciA9IG5leHRMaXN0ZW5lcjtcbiAgfVxufTtcblxuLyoqXG4gKiBBIGV2ZW50IHRoYXQgaXMgZW1pdHRlZCB2aWEgdGhlIGV2ZW50IGJ1cy5cbiAqL1xuZnVuY3Rpb24gSW50ZXJuYWxFdmVudCgpIHsgfVxuXG5JbnRlcm5hbEV2ZW50LnByb3RvdHlwZS5zdG9wUHJvcGFnYXRpb24gPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5jYW5jZWxCdWJibGUgPSB0cnVlO1xufTtcblxuSW50ZXJuYWxFdmVudC5wcm90b3R5cGUucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5kZWZhdWx0UHJldmVudGVkID0gdHJ1ZTtcbn07XG5cbkludGVybmFsRXZlbnQucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbihkYXRhKSB7XG4gIGFzc2lnbih0aGlzLCBkYXRhIHx8IHt9KTtcbn07XG5cblxuLyoqXG4gKiBJbnZva2UgZnVuY3Rpb24uIEJlIGZhc3QuLi5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBhcmdzXG4gKlxuICogQHJldHVybiB7QW55fVxuICovXG5mdW5jdGlvbiBpbnZva2VGdW5jdGlvbihmbiwgYXJncykge1xuICByZXR1cm4gZm4uYXBwbHkobnVsbCwgYXJncyk7XG59XG4iLCJpbXBvcnQge1xuICBmb3JFYWNoLFxuICByZWR1Y2Vcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRDaGlsZHJlbixcbiAgZ2V0VmlzdWFsXG59IGZyb20gJy4uL3V0aWwvR3JhcGhpY3NVdGlsJztcblxuaW1wb3J0IHsgdHJhbnNsYXRlIH0gZnJvbSAnLi4vdXRpbC9TdmdUcmFuc2Zvcm1VdGlsJztcblxuaW1wb3J0IHsgY2xlYXIgYXMgZG9tQ2xlYXIgfSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjbGFzc2VzIGFzIHN2Z0NsYXNzZXMsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICBpc0ZyYW1lRWxlbWVudFxufSBmcm9tICcuLi91dGlsL0VsZW1lbnRzJztcblxuLyoqXG4gKiBBIGZhY3RvcnkgdGhhdCBjcmVhdGVzIGdyYXBoaWNhbCBlbGVtZW50c1xuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEdyYXBoaWNzRmFjdG9yeShldmVudEJ1cywgZWxlbWVudFJlZ2lzdHJ5KSB7XG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbn1cblxuR3JhcGhpY3NGYWN0b3J5LiRpbmplY3QgPSBbICdldmVudEJ1cycgLCAnZWxlbWVudFJlZ2lzdHJ5JyBdO1xuXG5cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUuX2dldENoaWxkcmVuQ29udGFpbmVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gIHZhciBnZnggPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZWxlbWVudCk7XG5cbiAgdmFyIGNoaWxkcmVuR2Z4O1xuXG4gIC8vIHJvb3QgZWxlbWVudFxuICBpZiAoIWVsZW1lbnQucGFyZW50KSB7XG4gICAgY2hpbGRyZW5HZnggPSBnZng7XG4gIH0gZWxzZSB7XG4gICAgY2hpbGRyZW5HZnggPSBnZXRDaGlsZHJlbihnZngpO1xuICAgIGlmICghY2hpbGRyZW5HZngpIHtcbiAgICAgIGNoaWxkcmVuR2Z4ID0gc3ZnQ3JlYXRlKCdnJyk7XG4gICAgICBzdmdDbGFzc2VzKGNoaWxkcmVuR2Z4KS5hZGQoJ2Rqcy1jaGlsZHJlbicpO1xuXG4gICAgICBzdmdBcHBlbmQoZ2Z4LnBhcmVudE5vZGUsIGNoaWxkcmVuR2Z4KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY2hpbGRyZW5HZng7XG59O1xuXG4vKipcbiAqIENsZWFycyB0aGUgZ3JhcGhpY2FsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBlbGVtZW50IGFuZCByZXR1cm5zIHRoZVxuICogY2xlYXJlZCB2aXN1YWwgKHRoZSA8ZyBjbGFzcz1cImRqcy12aXN1YWxcIiAvPiBlbGVtZW50KS5cbiAqL1xuR3JhcGhpY3NGYWN0b3J5LnByb3RvdHlwZS5fY2xlYXIgPSBmdW5jdGlvbihnZngpIHtcbiAgdmFyIHZpc3VhbCA9IGdldFZpc3VhbChnZngpO1xuXG4gIGRvbUNsZWFyKHZpc3VhbCk7XG5cbiAgcmV0dXJuIHZpc3VhbDtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyBhIGdmeCBjb250YWluZXIgZm9yIHNoYXBlcyBhbmQgY29ubmVjdGlvbnNcbiAqXG4gKiBUaGUgbGF5b3V0IGlzIGFzIGZvbGxvd3M6XG4gKlxuICogPGcgY2xhc3M9XCJkanMtZ3JvdXBcIj5cbiAqXG4gKiAgIDwhLS0gdGhlIGdmeCAtLT5cbiAqICAgPGcgY2xhc3M9XCJkanMtZWxlbWVudCBkanMtKHNoYXBlfGNvbm5lY3Rpb258ZnJhbWUpXCI+XG4gKiAgICAgPGcgY2xhc3M9XCJkanMtdmlzdWFsXCI+XG4gKiAgICAgICA8IS0tIHRoZSByZW5kZXJlciBkcmF3cyBpbiBoZXJlIC0tPlxuICogICAgIDwvZz5cbiAqXG4gKiAgICAgPCEtLSBleHRlbnNpb25zIChvdmVybGF5cywgY2xpY2sgYm94LCAuLi4pIGdvZXMgaGVyZVxuICogICA8L2c+XG4gKlxuICogICA8IS0tIHRoZSBnZnggY2hpbGQgbm9kZXMgLS0+XG4gKiAgIDxnIGNsYXNzPVwiZGpzLWNoaWxkcmVuXCI+PC9nPlxuICogPC9nPlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIHRoZSB0eXBlIG9mIHRoZSBlbGVtZW50LCBpLmUuIHNoYXBlIHwgY29ubmVjdGlvblxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBbY2hpbGRyZW5HZnhdXG4gKiBAcGFyYW0ge251bWJlcn0gW3BhcmVudEluZGV4XSBwb3NpdGlvbiB0byBjcmVhdGUgY29udGFpbmVyIGluIHBhcmVudFxuICogQHBhcmFtIHtib29sZWFufSBbaXNGcmFtZV0gaXMgZnJhbWUgZWxlbWVudFxuICpcbiAqIEByZXR1cm4ge1NWR0VsZW1lbnR9XG4gKi9cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUuX2NyZWF0ZUNvbnRhaW5lciA9IGZ1bmN0aW9uKFxuICAgIHR5cGUsIGNoaWxkcmVuR2Z4LCBwYXJlbnRJbmRleCwgaXNGcmFtZVxuKSB7XG4gIHZhciBvdXRlckdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuICBzdmdDbGFzc2VzKG91dGVyR2Z4KS5hZGQoJ2Rqcy1ncm91cCcpO1xuXG4gIC8vIGluc2VydCBub2RlIGF0IHBvc2l0aW9uXG4gIGlmICh0eXBlb2YgcGFyZW50SW5kZXggIT09ICd1bmRlZmluZWQnKSB7XG4gICAgcHJlcGVuZFRvKG91dGVyR2Z4LCBjaGlsZHJlbkdmeCwgY2hpbGRyZW5HZnguY2hpbGROb2Rlc1twYXJlbnRJbmRleF0pO1xuICB9IGVsc2Uge1xuICAgIHN2Z0FwcGVuZChjaGlsZHJlbkdmeCwgb3V0ZXJHZngpO1xuICB9XG5cbiAgdmFyIGdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuICBzdmdDbGFzc2VzKGdmeCkuYWRkKCdkanMtZWxlbWVudCcpO1xuICBzdmdDbGFzc2VzKGdmeCkuYWRkKCdkanMtJyArIHR5cGUpO1xuXG4gIGlmIChpc0ZyYW1lKSB7XG4gICAgc3ZnQ2xhc3NlcyhnZngpLmFkZCgnZGpzLWZyYW1lJyk7XG4gIH1cblxuICBzdmdBcHBlbmQob3V0ZXJHZngsIGdmeCk7XG5cbiAgLy8gY3JlYXRlIHZpc3VhbFxuICB2YXIgdmlzdWFsID0gc3ZnQ3JlYXRlKCdnJyk7XG4gIHN2Z0NsYXNzZXModmlzdWFsKS5hZGQoJ2Rqcy12aXN1YWwnKTtcblxuICBzdmdBcHBlbmQoZ2Z4LCB2aXN1YWwpO1xuXG4gIHJldHVybiBnZng7XG59O1xuXG5HcmFwaGljc0ZhY3RvcnkucHJvdG90eXBlLmNyZWF0ZSA9IGZ1bmN0aW9uKHR5cGUsIGVsZW1lbnQsIHBhcmVudEluZGV4KSB7XG4gIHZhciBjaGlsZHJlbkdmeCA9IHRoaXMuX2dldENoaWxkcmVuQ29udGFpbmVyKGVsZW1lbnQucGFyZW50KTtcbiAgcmV0dXJuIHRoaXMuX2NyZWF0ZUNvbnRhaW5lcih0eXBlLCBjaGlsZHJlbkdmeCwgcGFyZW50SW5kZXgsIGlzRnJhbWVFbGVtZW50KGVsZW1lbnQpKTtcbn07XG5cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUudXBkYXRlQ29udGFpbm1lbnRzID0gZnVuY3Rpb24oZWxlbWVudHMpIHtcblxuICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnksXG4gICAgICBwYXJlbnRzO1xuXG4gIHBhcmVudHMgPSByZWR1Y2UoZWxlbWVudHMsIGZ1bmN0aW9uKG1hcCwgZSkge1xuXG4gICAgaWYgKGUucGFyZW50KSB7XG4gICAgICBtYXBbZS5wYXJlbnQuaWRdID0gZS5wYXJlbnQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hcDtcbiAgfSwge30pO1xuXG4gIC8vIHVwZGF0ZSBhbGwgcGFyZW50cyBvZiBjaGFuZ2VkIGFuZCByZW9yZ2FuaXplZCB0aGVpciBjaGlsZHJlblxuICAvLyBpbiB0aGUgY29ycmVjdCBvcmRlciAoYXMgaW5kaWNhdGVkIGluIG91ciBtb2RlbClcbiAgZm9yRWFjaChwYXJlbnRzLCBmdW5jdGlvbihwYXJlbnQpIHtcblxuICAgIHZhciBjaGlsZHJlbiA9IHBhcmVudC5jaGlsZHJlbjtcblxuICAgIGlmICghY2hpbGRyZW4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY2hpbGRyZW5HZnggPSBzZWxmLl9nZXRDaGlsZHJlbkNvbnRhaW5lcihwYXJlbnQpO1xuXG4gICAgZm9yRWFjaChjaGlsZHJlbi5zbGljZSgpLnJldmVyc2UoKSwgZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgIHZhciBjaGlsZEdmeCA9IGVsZW1lbnRSZWdpc3RyeS5nZXRHcmFwaGljcyhjaGlsZCk7XG5cbiAgICAgIHByZXBlbmRUbyhjaGlsZEdmeC5wYXJlbnROb2RlLCBjaGlsZHJlbkdmeCk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuR3JhcGhpY3NGYWN0b3J5LnByb3RvdHlwZS5kcmF3U2hhcGUgPSBmdW5jdGlvbih2aXN1YWwsIGVsZW1lbnQpIHtcbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgcmV0dXJuIGV2ZW50QnVzLmZpcmUoJ3JlbmRlci5zaGFwZScsIHsgZ2Z4OiB2aXN1YWwsIGVsZW1lbnQ6IGVsZW1lbnQgfSk7XG59O1xuXG5HcmFwaGljc0ZhY3RvcnkucHJvdG90eXBlLmdldFNoYXBlUGF0aCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgcmV0dXJuIGV2ZW50QnVzLmZpcmUoJ3JlbmRlci5nZXRTaGFwZVBhdGgnLCBlbGVtZW50KTtcbn07XG5cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUuZHJhd0Nvbm5lY3Rpb24gPSBmdW5jdGlvbih2aXN1YWwsIGVsZW1lbnQpIHtcbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgcmV0dXJuIGV2ZW50QnVzLmZpcmUoJ3JlbmRlci5jb25uZWN0aW9uJywgeyBnZng6IHZpc3VhbCwgZWxlbWVudDogZWxlbWVudCB9KTtcbn07XG5cbkdyYXBoaWNzRmFjdG9yeS5wcm90b3R5cGUuZ2V0Q29ubmVjdGlvblBhdGggPSBmdW5jdGlvbih3YXlwb2ludHMpIHtcbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgcmV0dXJuIGV2ZW50QnVzLmZpcmUoJ3JlbmRlci5nZXRDb25uZWN0aW9uUGF0aCcsIHdheXBvaW50cyk7XG59O1xuXG5HcmFwaGljc0ZhY3RvcnkucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKHR5cGUsIGVsZW1lbnQsIGdmeCkge1xuXG4gIC8vIGRvIE5PVCB1cGRhdGUgcm9vdCBlbGVtZW50XG4gIGlmICghZWxlbWVudC5wYXJlbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgdmlzdWFsID0gdGhpcy5fY2xlYXIoZ2Z4KTtcblxuICAvLyByZWRyYXdcbiAgaWYgKHR5cGUgPT09ICdzaGFwZScpIHtcbiAgICB0aGlzLmRyYXdTaGFwZSh2aXN1YWwsIGVsZW1lbnQpO1xuXG4gICAgLy8gdXBkYXRlIHBvc2l0aW9uaW5nXG4gICAgdHJhbnNsYXRlKGdmeCwgZWxlbWVudC54LCBlbGVtZW50LnkpO1xuICB9IGVsc2VcbiAgaWYgKHR5cGUgPT09ICdjb25uZWN0aW9uJykge1xuICAgIHRoaXMuZHJhd0Nvbm5lY3Rpb24odmlzdWFsLCBlbGVtZW50KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gdHlwZTogJyArIHR5cGUpO1xuICB9XG5cbiAgaWYgKGVsZW1lbnQuaGlkZGVuKSB7XG4gICAgc3ZnQXR0cihnZngsICdkaXNwbGF5JywgJ25vbmUnKTtcbiAgfSBlbHNlIHtcbiAgICBzdmdBdHRyKGdmeCwgJ2Rpc3BsYXknLCAnYmxvY2snKTtcbiAgfVxufTtcblxuR3JhcGhpY3NGYWN0b3J5LnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciBnZnggPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZWxlbWVudCk7XG5cbiAgLy8gcmVtb3ZlXG4gIHN2Z1JlbW92ZShnZngucGFyZW50Tm9kZSk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBwcmVwZW5kVG8obmV3Tm9kZSwgcGFyZW50Tm9kZSwgc2libGluZ05vZGUpIHtcbiAgdmFyIG5vZGUgPSBzaWJsaW5nTm9kZSB8fCBwYXJlbnROb2RlLmZpcnN0Q2hpbGQ7XG5cbiAgLy8gZG8gbm90IHByZXBlbmQgbm9kZSB0byBpdHNlbGYgdG8gcHJldmVudCBJRSBmcm9tIGNyYXNoaW5nXG4gIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9icG1uLWlvL2JwbW4tanMvaXNzdWVzLzc0NlxuICBpZiAobmV3Tm9kZSA9PT0gbm9kZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld05vZGUsIG5vZGUpO1xufVxuIiwiaW1wb3J0IERyYXdNb2R1bGUgZnJvbSAnLi4vZHJhdyc7XG5cbmltcG9ydCBDYW52YXMgZnJvbSAnLi9DYW52YXMnO1xuaW1wb3J0IEVsZW1lbnRSZWdpc3RyeSBmcm9tICcuL0VsZW1lbnRSZWdpc3RyeSc7XG5pbXBvcnQgRWxlbWVudEZhY3RvcnkgZnJvbSAnLi9FbGVtZW50RmFjdG9yeSc7XG5pbXBvcnQgRXZlbnRCdXMgZnJvbSAnLi9FdmVudEJ1cyc7XG5pbXBvcnQgR3JhcGhpY3NGYWN0b3J5IGZyb20gJy4vR3JhcGhpY3NGYWN0b3J5JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogWyBEcmF3TW9kdWxlIF0sXG4gIF9faW5pdF9fOiBbICdjYW52YXMnIF0sXG4gIGNhbnZhczogWyAndHlwZScsIENhbnZhcyBdLFxuICBlbGVtZW50UmVnaXN0cnk6IFsgJ3R5cGUnLCBFbGVtZW50UmVnaXN0cnkgXSxcbiAgZWxlbWVudEZhY3Rvcnk6IFsgJ3R5cGUnLCBFbGVtZW50RmFjdG9yeSBdLFxuICBldmVudEJ1czogWyAndHlwZScsIEV2ZW50QnVzIF0sXG4gIGdyYXBoaWNzRmFjdG9yeTogWyAndHlwZScsIEdyYXBoaWNzRmFjdG9yeSBdXG59OyIsInZhciBERUZBVUxUX1JFTkRFUl9QUklPUklUWSA9IDEwMDA7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2Ygc2hhcGUgYW5kIGNvbm5lY3Rpb24gcmVuZGVyZXJzLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge251bWJlcn0gW3JlbmRlclByaW9yaXR5PTEwMDBdXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJhc2VSZW5kZXJlcihldmVudEJ1cywgcmVuZGVyUHJpb3JpdHkpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHJlbmRlclByaW9yaXR5ID0gcmVuZGVyUHJpb3JpdHkgfHwgREVGQVVMVF9SRU5ERVJfUFJJT1JJVFk7XG5cbiAgZXZlbnRCdXMub24oWyAncmVuZGVyLnNoYXBlJywgJ3JlbmRlci5jb25uZWN0aW9uJyBdLCByZW5kZXJQcmlvcml0eSwgZnVuY3Rpb24oZXZ0LCBjb250ZXh0KSB7XG4gICAgdmFyIHR5cGUgPSBldnQudHlwZSxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcbiAgICAgICAgdmlzdWFscyA9IGNvbnRleHQuZ2Z4O1xuXG4gICAgaWYgKHNlbGYuY2FuUmVuZGVyKGVsZW1lbnQpKSB7XG4gICAgICBpZiAodHlwZSA9PT0gJ3JlbmRlci5zaGFwZScpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuZHJhd1NoYXBlKHZpc3VhbHMsIGVsZW1lbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuZHJhd0Nvbm5lY3Rpb24odmlzdWFscywgZWxlbWVudCk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdyZW5kZXIuZ2V0U2hhcGVQYXRoJywgJ3JlbmRlci5nZXRDb25uZWN0aW9uUGF0aCddLCByZW5kZXJQcmlvcml0eSwgZnVuY3Rpb24oZXZ0LCBlbGVtZW50KSB7XG4gICAgaWYgKHNlbGYuY2FuUmVuZGVyKGVsZW1lbnQpKSB7XG4gICAgICBpZiAoZXZ0LnR5cGUgPT09ICdyZW5kZXIuZ2V0U2hhcGVQYXRoJykge1xuICAgICAgICByZXR1cm4gc2VsZi5nZXRTaGFwZVBhdGgoZWxlbWVudCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gc2VsZi5nZXRDb25uZWN0aW9uUGF0aChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufVxuXG4vKipcbiAqIFNob3VsZCBjaGVjayB3aGV0aGVyICp0aGlzKiByZW5kZXJlciBjYW4gcmVuZGVyXG4gKiB0aGUgZWxlbWVudC9jb25uZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7ZWxlbWVudH0gZWxlbWVudFxuICpcbiAqIEByZXR1cm5zIHtib29sZWFufVxuICovXG5CYXNlUmVuZGVyZXIucHJvdG90eXBlLmNhblJlbmRlciA9IGZ1bmN0aW9uKCkge307XG5cbi8qKlxuICogUHJvdmlkZXMgdGhlIHNoYXBlJ3Mgc25hcCBzdmcgZWxlbWVudCB0byBiZSBkcmF3biBvbiB0aGUgYGNhbnZhc2AuXG4gKlxuICogQHBhcmFtIHtkanMuR3JhcGhpY3N9IHZpc3VhbHNcbiAqIEBwYXJhbSB7U2hhcGV9IHNoYXBlXG4gKlxuICogQHJldHVybnMge1NuYXAuc3ZnfSBbcmV0dXJucyBhIFNuYXAuc3ZnIHBhcGVyIGVsZW1lbnQgXVxuICovXG5CYXNlUmVuZGVyZXIucHJvdG90eXBlLmRyYXdTaGFwZSA9IGZ1bmN0aW9uKCkge307XG5cbi8qKlxuICogUHJvdmlkZXMgdGhlIHNoYXBlJ3Mgc25hcCBzdmcgZWxlbWVudCB0byBiZSBkcmF3biBvbiB0aGUgYGNhbnZhc2AuXG4gKlxuICogQHBhcmFtIHtkanMuR3JhcGhpY3N9IHZpc3VhbHNcbiAqIEBwYXJhbSB7Q29ubmVjdGlvbn0gY29ubmVjdGlvblxuICpcbiAqIEByZXR1cm5zIHtTbmFwLnN2Z30gW3JldHVybnMgYSBTbmFwLnN2ZyBwYXBlciBlbGVtZW50IF1cbiAqL1xuQmFzZVJlbmRlcmVyLnByb3RvdHlwZS5kcmF3Q29ubmVjdGlvbiA9IGZ1bmN0aW9uKCkge307XG5cbi8qKlxuICogR2V0cyB0aGUgU1ZHIHBhdGggb2YgYSBzaGFwZSB0aGF0IHJlcHJlc2VudHMgaXQncyB2aXN1YWwgYm91bmRzLlxuICpcbiAqIEBwYXJhbSB7U2hhcGV9IHNoYXBlXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSBzdmcgcGF0aFxuICovXG5CYXNlUmVuZGVyZXIucHJvdG90eXBlLmdldFNoYXBlUGF0aCA9IGZ1bmN0aW9uKCkge307XG5cbi8qKlxuICogR2V0cyB0aGUgU1ZHIHBhdGggb2YgYSBjb25uZWN0aW9uIHRoYXQgcmVwcmVzZW50cyBpdCdzIHZpc3VhbCBib3VuZHMuXG4gKlxuICogQHBhcmFtIHtDb25uZWN0aW9ufSBjb25uZWN0aW9uXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSBzdmcgcGF0aFxuICovXG5CYXNlUmVuZGVyZXIucHJvdG90eXBlLmdldENvbm5lY3Rpb25QYXRoID0gZnVuY3Rpb24oKSB7fTtcbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBCYXNlUmVuZGVyZXIgZnJvbSAnLi9CYXNlUmVuZGVyZXInO1xuXG5pbXBvcnQge1xuICBjb21wb25lbnRzVG9QYXRoLFxuICBjcmVhdGVMaW5lXG59IGZyb20gJy4uL3V0aWwvUmVuZGVyVXRpbCc7XG5cbmltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY3JlYXRlIGFzIHN2Z0NyZWF0ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7XG4gIGlzRnJhbWVFbGVtZW50XG59IGZyb20gJy4uL3V0aWwvRWxlbWVudHMnO1xuXG4vLyBhcHBseSBkZWZhdWx0IHJlbmRlcmVyIHdpdGggbG93ZXN0IHBvc3NpYmxlIHByaW9yaXR5XG4vLyBzbyB0aGF0IGl0IG9ubHkga2lja3MgaW4gaWYgbm9vbmUgZWxzZSBjb3VsZCByZW5kZXJcbnZhciBERUZBVUxUX1JFTkRFUl9QUklPUklUWSA9IDE7XG5cbi8qKlxuICogVGhlIGRlZmF1bHQgcmVuZGVyZXIgdXNlZCBmb3Igc2hhcGVzIGFuZCBjb25uZWN0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtTdHlsZXN9IHN0eWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEZWZhdWx0UmVuZGVyZXIoZXZlbnRCdXMsIHN0eWxlcykge1xuXG4gIC8vXG4gIEJhc2VSZW5kZXJlci5jYWxsKHRoaXMsIGV2ZW50QnVzLCBERUZBVUxUX1JFTkRFUl9QUklPUklUWSk7XG5cbiAgdGhpcy5DT05ORUNUSU9OX1NUWUxFID0gc3R5bGVzLnN0eWxlKFsgJ25vLWZpbGwnIF0sIHsgc3Ryb2tlV2lkdGg6IDUsIHN0cm9rZTogJ2Z1Y2hzaWEnIH0pO1xuICB0aGlzLlNIQVBFX1NUWUxFID0gc3R5bGVzLnN0eWxlKHsgZmlsbDogJ3doaXRlJywgc3Ryb2tlOiAnZnVjaHNpYScsIHN0cm9rZVdpZHRoOiAyIH0pO1xuICB0aGlzLkZSQU1FX1NUWUxFID0gc3R5bGVzLnN0eWxlKFsgJ25vLWZpbGwnIF0sIHsgc3Ryb2tlOiAnZnVjaHNpYScsIHN0cm9rZURhc2hhcnJheTogNCwgc3Ryb2tlV2lkdGg6IDIgfSk7XG59XG5cbmluaGVyaXRzKERlZmF1bHRSZW5kZXJlciwgQmFzZVJlbmRlcmVyKTtcblxuXG5EZWZhdWx0UmVuZGVyZXIucHJvdG90eXBlLmNhblJlbmRlciA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbkRlZmF1bHRSZW5kZXJlci5wcm90b3R5cGUuZHJhd1NoYXBlID0gZnVuY3Rpb24gZHJhd1NoYXBlKHZpc3VhbHMsIGVsZW1lbnQpIHtcbiAgdmFyIHJlY3QgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcblxuICBzdmdBdHRyKHJlY3QsIHtcbiAgICB4OiAwLFxuICAgIHk6IDAsXG4gICAgd2lkdGg6IGVsZW1lbnQud2lkdGggfHwgMCxcbiAgICBoZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0IHx8IDBcbiAgfSk7XG5cbiAgaWYgKGlzRnJhbWVFbGVtZW50KGVsZW1lbnQpKSB7XG4gICAgc3ZnQXR0cihyZWN0LCB0aGlzLkZSQU1FX1NUWUxFKTtcbiAgfSBlbHNlIHtcbiAgICBzdmdBdHRyKHJlY3QsIHRoaXMuU0hBUEVfU1RZTEUpO1xuICB9XG5cbiAgc3ZnQXBwZW5kKHZpc3VhbHMsIHJlY3QpO1xuXG4gIHJldHVybiByZWN0O1xufTtcblxuRGVmYXVsdFJlbmRlcmVyLnByb3RvdHlwZS5kcmF3Q29ubmVjdGlvbiA9IGZ1bmN0aW9uIGRyYXdDb25uZWN0aW9uKHZpc3VhbHMsIGNvbm5lY3Rpb24pIHtcblxuICB2YXIgbGluZSA9IGNyZWF0ZUxpbmUoY29ubmVjdGlvbi53YXlwb2ludHMsIHRoaXMuQ09OTkVDVElPTl9TVFlMRSk7XG4gIHN2Z0FwcGVuZCh2aXN1YWxzLCBsaW5lKTtcblxuICByZXR1cm4gbGluZTtcbn07XG5cbkRlZmF1bHRSZW5kZXJlci5wcm90b3R5cGUuZ2V0U2hhcGVQYXRoID0gZnVuY3Rpb24gZ2V0U2hhcGVQYXRoKHNoYXBlKSB7XG5cbiAgdmFyIHggPSBzaGFwZS54LFxuICAgICAgeSA9IHNoYXBlLnksXG4gICAgICB3aWR0aCA9IHNoYXBlLndpZHRoLFxuICAgICAgaGVpZ2h0ID0gc2hhcGUuaGVpZ2h0O1xuXG4gIHZhciBzaGFwZVBhdGggPSBbXG4gICAgWydNJywgeCwgeV0sXG4gICAgWydsJywgd2lkdGgsIDBdLFxuICAgIFsnbCcsIDAsIGhlaWdodF0sXG4gICAgWydsJywgLXdpZHRoLCAwXSxcbiAgICBbJ3onXVxuICBdO1xuXG4gIHJldHVybiBjb21wb25lbnRzVG9QYXRoKHNoYXBlUGF0aCk7XG59O1xuXG5EZWZhdWx0UmVuZGVyZXIucHJvdG90eXBlLmdldENvbm5lY3Rpb25QYXRoID0gZnVuY3Rpb24gZ2V0Q29ubmVjdGlvblBhdGgoY29ubmVjdGlvbikge1xuICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG5cbiAgdmFyIGlkeCwgcG9pbnQsIGNvbm5lY3Rpb25QYXRoID0gW107XG5cbiAgZm9yIChpZHggPSAwOyAocG9pbnQgPSB3YXlwb2ludHNbaWR4XSk7IGlkeCsrKSB7XG5cbiAgICAvLyB0YWtlIGludmlzaWJsZSBkb2NraW5nIGludG8gYWNjb3VudFxuICAgIC8vIHdoZW4gY3JlYXRpbmcgdGhlIHBhdGhcbiAgICBwb2ludCA9IHBvaW50Lm9yaWdpbmFsIHx8IHBvaW50O1xuXG4gICAgY29ubmVjdGlvblBhdGgucHVzaChbIGlkeCA9PT0gMCA/ICdNJyA6ICdMJywgcG9pbnQueCwgcG9pbnQueSBdKTtcbiAgfVxuXG4gIHJldHVybiBjb21wb25lbnRzVG9QYXRoKGNvbm5lY3Rpb25QYXRoKTtcbn07XG5cblxuRGVmYXVsdFJlbmRlcmVyLiRpbmplY3QgPSBbICdldmVudEJ1cycsICdzdHlsZXMnIF07XG4iLCJpbXBvcnQge1xuICBpc0FycmF5LFxuICBhc3NpZ24sXG4gIHJlZHVjZVxufSBmcm9tICdtaW4tZGFzaCc7XG5cblxuLyoqXG4gKiBBIGNvbXBvbmVudCB0aGF0IG1hbmFnZXMgc2hhcGUgc3R5bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFN0eWxlcygpIHtcblxuICB2YXIgZGVmYXVsdFRyYWl0cyA9IHtcblxuICAgICduby1maWxsJzoge1xuICAgICAgZmlsbDogJ25vbmUnXG4gICAgfSxcbiAgICAnbm8tYm9yZGVyJzoge1xuICAgICAgc3Ryb2tlT3BhY2l0eTogMC4wXG4gICAgfSxcbiAgICAnbm8tZXZlbnRzJzoge1xuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnXG4gICAgfVxuICB9O1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvKipcbiAgICogQnVpbGRzIGEgc3R5bGUgZGVmaW5pdGlvbiBmcm9tIGEgY2xhc3NOYW1lLCBhIGxpc3Qgb2YgdHJhaXRzIGFuZCBhbiBvYmplY3Qgb2YgYWRkaXRpb25hbCBhdHRyaWJ1dGVzLlxuICAgKlxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IGNsYXNzTmFtZVxuICAgKiBAcGFyYW0gIHtBcnJheTxzdHJpbmc+fSB0cmFpdHNcbiAgICogQHBhcmFtICB7T2JqZWN0fSBhZGRpdGlvbmFsQXR0cnNcbiAgICpcbiAgICogQHJldHVybiB7T2JqZWN0fSB0aGUgc3R5bGUgZGVmaW50aW9uXG4gICAqL1xuICB0aGlzLmNscyA9IGZ1bmN0aW9uKGNsYXNzTmFtZSwgdHJhaXRzLCBhZGRpdGlvbmFsQXR0cnMpIHtcbiAgICB2YXIgYXR0cnMgPSB0aGlzLnN0eWxlKHRyYWl0cywgYWRkaXRpb25hbEF0dHJzKTtcblxuICAgIHJldHVybiBhc3NpZ24oYXR0cnMsIHsgJ2NsYXNzJzogY2xhc3NOYW1lIH0pO1xuICB9O1xuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBzdHlsZSBkZWZpbml0aW9uIGZyb20gYSBsaXN0IG9mIHRyYWl0cyBhbmQgYW4gb2JqZWN0IG9mIGFkZGl0aW9uYWwgYXR0cmlidXRlcy5cbiAgICpcbiAgICogQHBhcmFtICB7QXJyYXk8c3RyaW5nPn0gdHJhaXRzXG4gICAqIEBwYXJhbSAge09iamVjdH0gYWRkaXRpb25hbEF0dHJzXG4gICAqXG4gICAqIEByZXR1cm4ge09iamVjdH0gdGhlIHN0eWxlIGRlZmludGlvblxuICAgKi9cbiAgdGhpcy5zdHlsZSA9IGZ1bmN0aW9uKHRyYWl0cywgYWRkaXRpb25hbEF0dHJzKSB7XG5cbiAgICBpZiAoIWlzQXJyYXkodHJhaXRzKSAmJiAhYWRkaXRpb25hbEF0dHJzKSB7XG4gICAgICBhZGRpdGlvbmFsQXR0cnMgPSB0cmFpdHM7XG4gICAgICB0cmFpdHMgPSBbXTtcbiAgICB9XG5cbiAgICB2YXIgYXR0cnMgPSByZWR1Y2UodHJhaXRzLCBmdW5jdGlvbihhdHRycywgdCkge1xuICAgICAgcmV0dXJuIGFzc2lnbihhdHRycywgZGVmYXVsdFRyYWl0c1t0XSB8fCB7fSk7XG4gICAgfSwge30pO1xuXG4gICAgcmV0dXJuIGFkZGl0aW9uYWxBdHRycyA/IGFzc2lnbihhdHRycywgYWRkaXRpb25hbEF0dHJzKSA6IGF0dHJzO1xuICB9O1xuXG4gIHRoaXMuY29tcHV0ZVN0eWxlID0gZnVuY3Rpb24oY3VzdG9tLCB0cmFpdHMsIGRlZmF1bHRTdHlsZXMpIHtcbiAgICBpZiAoIWlzQXJyYXkodHJhaXRzKSkge1xuICAgICAgZGVmYXVsdFN0eWxlcyA9IHRyYWl0cztcbiAgICAgIHRyYWl0cyA9IFtdO1xuICAgIH1cblxuICAgIHJldHVybiBzZWxmLnN0eWxlKHRyYWl0cyB8fCBbXSwgYXNzaWduKHt9LCBkZWZhdWx0U3R5bGVzLCBjdXN0b20gfHwge30pKTtcbiAgfTtcbn1cbiIsImltcG9ydCBEZWZhdWx0UmVuZGVyZXIgZnJvbSAnLi9EZWZhdWx0UmVuZGVyZXInO1xuaW1wb3J0IFN0eWxlcyBmcm9tICcuL1N0eWxlcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2RlZmF1bHRSZW5kZXJlcicgXSxcbiAgZGVmYXVsdFJlbmRlcmVyOiBbICd0eXBlJywgRGVmYXVsdFJlbmRlcmVyIF0sXG4gIHN0eWxlczogWyAndHlwZScsIFN0eWxlcyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgZmlsdGVyLFxuICBmb3JFYWNoLFxuICBzb3J0Qnlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5mdW5jdGlvbiBsYXN0KGFycikge1xuICByZXR1cm4gYXJyICYmIGFyclthcnIubGVuZ3RoIC0gMV07XG59XG5cbmZ1bmN0aW9uIHNvcnRUb3BPck1pZGRsZShlbGVtZW50KSB7XG4gIHJldHVybiBlbGVtZW50Lnk7XG59XG5cbmZ1bmN0aW9uIHNvcnRMZWZ0T3JDZW50ZXIoZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudC54O1xufVxuXG4vKipcbiAqIFNvcnRpbmcgZnVuY3Rpb25zIGZvciBkaWZmZXJlbnQgdHlwZXMgb2YgYWxpZ25tZW50XG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqL1xudmFyIEFMSUdOTUVOVF9TT1JUSU5HID0ge1xuICBsZWZ0OiBzb3J0TGVmdE9yQ2VudGVyLFxuICBjZW50ZXI6IHNvcnRMZWZ0T3JDZW50ZXIsXG4gIHJpZ2h0OiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQueCArIGVsZW1lbnQud2lkdGg7XG4gIH0sXG4gIHRvcDogc29ydFRvcE9yTWlkZGxlLFxuICBtaWRkbGU6IHNvcnRUb3BPck1pZGRsZSxcbiAgYm90dG9tOiBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQueSArIGVsZW1lbnQuaGVpZ2h0O1xuICB9XG59O1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEFsaWduRWxlbWVudHMobW9kZWxpbmcpIHtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbn1cblxuQWxpZ25FbGVtZW50cy4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cblxuLyoqXG4gKiBHZXQgdGhlIHJlbGV2YW50IFwiYXhpc1wiIGFuZCBcImRpbWVuc2lvblwiIHJlbGF0ZWQgdG8gdGhlIGN1cnJlbnQgdHlwZSBvZiBhbGlnbm1lbnRcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHR5cGUgbGVmdHxyaWdodHxjZW50ZXJ8dG9wfGJvdHRvbXxtaWRkbGVcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHsgYXhpcywgZGltZW5zaW9uIH1cbiAqL1xuQWxpZ25FbGVtZW50cy5wcm90b3R5cGUuX2dldE9yaWVudGF0aW9uRGV0YWlscyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIHZlcnRpY2FsID0gWyAndG9wJywgJ2JvdHRvbScsICdtaWRkbGUnIF0sXG4gICAgICBheGlzID0gJ3gnLFxuICAgICAgZGltZW5zaW9uID0gJ3dpZHRoJztcblxuICBpZiAodmVydGljYWwuaW5kZXhPZih0eXBlKSAhPT0gLTEpIHtcbiAgICBheGlzID0gJ3knO1xuICAgIGRpbWVuc2lvbiA9ICdoZWlnaHQnO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBheGlzOiBheGlzLFxuICAgIGRpbWVuc2lvbjogZGltZW5zaW9uXG4gIH07XG59O1xuXG5BbGlnbkVsZW1lbnRzLnByb3RvdHlwZS5faXNUeXBlID0gZnVuY3Rpb24odHlwZSwgdHlwZXMpIHtcbiAgcmV0dXJuIHR5cGVzLmluZGV4T2YodHlwZSkgIT09IC0xO1xufTtcblxuLyoqXG4gKiBHZXQgYSBwb2ludCBvbiB0aGUgcmVsZXZhbnQgYXhpcyB3aGVyZSBlbGVtZW50cyBzaG91bGQgYWxpZ24gdG9cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHR5cGUgbGVmdHxyaWdodHxjZW50ZXJ8dG9wfGJvdHRvbXxtaWRkbGVcbiAqIEBwYXJhbSAge0FycmF5fSBzb3J0ZWRFbGVtZW50c1xuICpcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuQWxpZ25FbGVtZW50cy5wcm90b3R5cGUuX2FsaWdubWVudFBvc2l0aW9uID0gZnVuY3Rpb24odHlwZSwgc29ydGVkRWxlbWVudHMpIHtcbiAgdmFyIG9yaWVudGF0aW9uID0gdGhpcy5fZ2V0T3JpZW50YXRpb25EZXRhaWxzKHR5cGUpLFxuICAgICAgYXhpcyA9IG9yaWVudGF0aW9uLmF4aXMsXG4gICAgICBkaW1lbnNpb24gPSBvcmllbnRhdGlvbi5kaW1lbnNpb24sXG4gICAgICBhbGlnbm1lbnQgPSB7fSxcbiAgICAgIGNlbnRlcnMgPSB7fSxcbiAgICAgIGhhc1NoYXJlZENlbnRlcnMgPSBmYWxzZSxcbiAgICAgIGNlbnRlcmVkRWxlbWVudHMsXG4gICAgICBmaXJzdEVsZW1lbnQsXG4gICAgICBsYXN0RWxlbWVudDtcblxuICBmdW5jdGlvbiBnZXRNaWRkbGVPclRvcChmaXJzdCwgbGFzdCkge1xuICAgIHJldHVybiBNYXRoLnJvdW5kKChmaXJzdFtheGlzXSArIGxhc3RbYXhpc10gKyBsYXN0W2RpbWVuc2lvbl0pIC8gMik7XG4gIH1cblxuICBpZiAodGhpcy5faXNUeXBlKHR5cGUsIFsgJ2xlZnQnLCAndG9wJyBdKSkge1xuICAgIGFsaWdubWVudFt0eXBlXSA9IHNvcnRlZEVsZW1lbnRzWzBdW2F4aXNdO1xuXG4gIH0gZWxzZSBpZiAodGhpcy5faXNUeXBlKHR5cGUsIFsgJ3JpZ2h0JywgJ2JvdHRvbScgXSkpIHtcbiAgICBsYXN0RWxlbWVudCA9IGxhc3Qoc29ydGVkRWxlbWVudHMpO1xuXG4gICAgYWxpZ25tZW50W3R5cGVdID0gbGFzdEVsZW1lbnRbYXhpc10gKyBsYXN0RWxlbWVudFtkaW1lbnNpb25dO1xuXG4gIH0gZWxzZSBpZiAodGhpcy5faXNUeXBlKHR5cGUsIFsgJ2NlbnRlcicsICdtaWRkbGUnIF0pKSB7XG5cbiAgICAvLyBjaGVjayBpZiB0aGVyZSBpcyBhIGNlbnRlciBzaGFyZWQgYnkgbW9yZSB0aGFuIG9uZSBzaGFwZVxuICAgIC8vIGlmIG5vdCwganVzdCB0YWtlIHRoZSBtaWRkbGUgb2YgdGhlIHJhbmdlXG4gICAgZm9yRWFjaChzb3J0ZWRFbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgdmFyIGNlbnRlciA9IGVsZW1lbnRbYXhpc10gKyBNYXRoLnJvdW5kKGVsZW1lbnRbZGltZW5zaW9uXSAvIDIpO1xuXG4gICAgICBpZiAoY2VudGVyc1tjZW50ZXJdKSB7XG4gICAgICAgIGNlbnRlcnNbY2VudGVyXS5lbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2VudGVyc1tjZW50ZXJdID0ge1xuICAgICAgICAgIGVsZW1lbnRzOiBbIGVsZW1lbnQgXSxcbiAgICAgICAgICBjZW50ZXI6IGNlbnRlclxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgY2VudGVyZWRFbGVtZW50cyA9IHNvcnRCeShjZW50ZXJzLCBmdW5jdGlvbihjZW50ZXIpIHtcbiAgICAgIGlmIChjZW50ZXIuZWxlbWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgICBoYXNTaGFyZWRDZW50ZXJzID0gdHJ1ZTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNlbnRlci5lbGVtZW50cy5sZW5ndGg7XG4gICAgfSk7XG5cbiAgICBpZiAoaGFzU2hhcmVkQ2VudGVycykge1xuICAgICAgYWxpZ25tZW50W3R5cGVdID0gbGFzdChjZW50ZXJlZEVsZW1lbnRzKS5jZW50ZXI7XG5cbiAgICAgIHJldHVybiBhbGlnbm1lbnQ7XG4gICAgfVxuXG4gICAgZmlyc3RFbGVtZW50ID0gc29ydGVkRWxlbWVudHNbMF07XG5cbiAgICBzb3J0ZWRFbGVtZW50cyA9IHNvcnRCeShzb3J0ZWRFbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnRbYXhpc10gKyBlbGVtZW50W2RpbWVuc2lvbl07XG4gICAgfSk7XG5cbiAgICBsYXN0RWxlbWVudCA9IGxhc3Qoc29ydGVkRWxlbWVudHMpO1xuXG4gICAgYWxpZ25tZW50W3R5cGVdID0gZ2V0TWlkZGxlT3JUb3AoZmlyc3RFbGVtZW50LCBsYXN0RWxlbWVudCk7XG4gIH1cblxuICByZXR1cm4gYWxpZ25tZW50O1xufTtcblxuLyoqXG4gKiBFeGVjdXRlcyB0aGUgYWxpZ25tZW50IG9mIGEgc2VsZWN0aW9uIG9mIGVsZW1lbnRzXG4gKlxuICogQHBhcmFtICB7QXJyYXl9IGVsZW1lbnRzIFtkZXNjcmlwdGlvbl1cbiAqIEBwYXJhbSAge3N0cmluZ30gdHlwZSBsZWZ0fHJpZ2h0fGNlbnRlcnx0b3B8Ym90dG9tfG1pZGRsZVxuICovXG5BbGlnbkVsZW1lbnRzLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oZWxlbWVudHMsIHR5cGUpIHtcbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmc7XG5cbiAgdmFyIGZpbHRlcmVkRWxlbWVudHMgPSBmaWx0ZXIoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gIShlbGVtZW50LndheXBvaW50cyB8fCBlbGVtZW50Lmhvc3QgfHwgZWxlbWVudC5sYWJlbFRhcmdldCk7XG4gIH0pO1xuXG4gIHZhciBzb3J0Rm4gPSBBTElHTk1FTlRfU09SVElOR1t0eXBlXTtcblxuICB2YXIgc29ydGVkRWxlbWVudHMgPSBzb3J0QnkoZmlsdGVyZWRFbGVtZW50cywgc29ydEZuKTtcblxuICB2YXIgYWxpZ25tZW50ID0gdGhpcy5fYWxpZ25tZW50UG9zaXRpb24odHlwZSwgc29ydGVkRWxlbWVudHMpO1xuXG4gIG1vZGVsaW5nLmFsaWduRWxlbWVudHMoc29ydGVkRWxlbWVudHMsIGFsaWdubWVudCk7XG59O1xuIiwiaW1wb3J0IEFsaWduRWxlbWVudHMgZnJvbSAnLi9BbGlnbkVsZW1lbnRzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnYWxpZ25FbGVtZW50cycgXSxcbiAgYWxpZ25FbGVtZW50czogWyAndHlwZScsIEFsaWduRWxlbWVudHMgXVxufTtcbiIsImltcG9ydCB7XG4gIGZsYXR0ZW4sXG4gIGZpbHRlcixcbiAgZm9yRWFjaCxcbiAgZ3JvdXBCeSxcbiAgbWFwLFxuICB1bmlvbkJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgc2F2ZUNsZWFyIH0gZnJvbSAnLi4vLi4vdXRpbC9SZW1vdmFsJztcblxuaW1wb3J0IHsgZ2V0TmV3QXR0YWNoU2hhcGVEZWx0YSB9IGZyb20gJy4uLy4uL3V0aWwvQXR0YWNoVXRpbCc7XG5cbmltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnLi4vLi4vY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gMjUxLFxuICAgIEhJR0hfUFJJT1JJVFkgPSAxNDAxO1xuXG52YXIgTUFSS0VSX0FUVEFDSCA9ICdhdHRhY2gtb2snO1xuXG5cbi8qKlxuICogQWRkcyB0aGUgbm90aW9uIG9mIGF0dGFjaGVkIGVsZW1lbnRzIHRvIHRoZSBtb2RlbGVyLlxuICpcbiAqIE9wdGlvbmFsbHkgZGVwZW5kcyBvbiBgZGlhZ3JhbS1qcy9saWIvZmVhdHVyZXMvbW92ZWAgdG8gcmVuZGVyXG4gKiB0aGUgYXR0YWNoZWQgZWxlbWVudHMgZHVyaW5nIG1vdmUgcHJldmlldy5cbiAqXG4gKiBPcHRpb25hbGx5IGRlcGVuZHMgb24gYGRpYWdyYW0tanMvbGliL2ZlYXR1cmVzL2xhYmVsLXN1cHBvcnRgXG4gKiB0byByZW5kZXIgYXR0YWNoZWQgbGFiZWxzIGR1cmluZyBtb3ZlIHByZXZpZXcuXG4gKlxuICogQHBhcmFtIHtkaWRpLkluamVjdG9yfSBpbmplY3RvclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBBdHRhY2hTdXBwb3J0KGluamVjdG9yLCBldmVudEJ1cywgY2FudmFzLCBydWxlcywgbW9kZWxpbmcpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdmFyIG1vdmVQcmV2aWV3ID0gaW5qZWN0b3IuZ2V0KCdtb3ZlUHJldmlldycsIGZhbHNlKTtcblxuXG4gIC8vIHJlbW92ZSBhbGwgdGhlIGF0dGFjaGVkIGVsZW1lbnRzIGZyb20gdGhlIHNoYXBlcyB0byBiZSB2YWxpZGF0ZWRcbiAgLy8gYWRkIGFsbCB0aGUgYXR0YWNoZWQgc2hhcGVzIHRvIHRoZSBvdmVyYWxsIGxpc3Qgb2YgbW92ZWQgc2hhcGVzXG4gIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLnN0YXJ0JywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzLFxuICAgICAgICB2YWxpZGF0ZWRTaGFwZXMgPSBjb250ZXh0LnZhbGlkYXRlZFNoYXBlcztcblxuICAgIGNvbnRleHQuc2hhcGVzID0gYWRkQXR0YWNoZWQoc2hhcGVzKTtcblxuICAgIGNvbnRleHQudmFsaWRhdGVkU2hhcGVzID0gcmVtb3ZlQXR0YWNoZWQodmFsaWRhdGVkU2hhcGVzKTtcbiAgfSk7XG5cbiAgLy8gYWRkIGF0dGFjaGVycyB0byB0aGUgdmlzdWFsJ3MgZ3JvdXBcbiAgbW92ZVByZXZpZXcgJiYgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUuc3RhcnQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgYXR0YWNoZXJzID0gZ2V0QXR0YWNoZXJzKHNoYXBlcyk7XG5cbiAgICBmb3JFYWNoKGF0dGFjaGVycywgZnVuY3Rpb24oYXR0YWNoZXIpIHtcbiAgICAgIG1vdmVQcmV2aWV3Lm1ha2VEcmFnZ2FibGUoY29udGV4dCwgYXR0YWNoZXIsIHRydWUpO1xuXG4gICAgICBmb3JFYWNoKGF0dGFjaGVyLmxhYmVscywgZnVuY3Rpb24obGFiZWwpIHtcbiAgICAgICAgbW92ZVByZXZpZXcubWFrZURyYWdnYWJsZShjb250ZXh0LCBsYWJlbCwgdHJ1ZSk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gYWRkIGF0dGFjaC1vayBtYXJrZXIgdG8gY3VycmVudCBob3N0XG4gIG1vdmVQcmV2aWV3ICYmIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzO1xuXG4gICAgaWYgKHNoYXBlcy5sZW5ndGggIT09IDEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgc2hhcGUgPSBzaGFwZXNbMF07XG5cbiAgICB2YXIgaG9zdCA9IHNoYXBlLmhvc3Q7XG5cbiAgICBpZiAoaG9zdCkge1xuICAgICAgY2FudmFzLmFkZE1hcmtlcihob3N0LCBNQVJLRVJfQVRUQUNIKTtcblxuICAgICAgZXZlbnRCdXMub25jZShbXG4gICAgICAgICdzaGFwZS5tb3ZlLm91dCcsXG4gICAgICAgICdzaGFwZS5tb3ZlLmNsZWFudXAnXG4gICAgICBdLCBmdW5jdGlvbigpIHtcbiAgICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3N0LCBNQVJLRVJfQVRUQUNIKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWRkIGFsbCBhdHRhY2hlcnMgdG8gbW92ZSBjbG9zdXJlXG4gIHRoaXMucHJlRXhlY3V0ZWQoJ2VsZW1lbnRzLm1vdmUnLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIGNsb3N1cmUgPSBjb250ZXh0LmNsb3N1cmUsXG4gICAgICAgIHNoYXBlcyA9IGNvbnRleHQuc2hhcGVzLFxuICAgICAgICBhdHRhY2hlcnMgPSBnZXRBdHRhY2hlcnMoc2hhcGVzKTtcblxuICAgIGZvckVhY2goYXR0YWNoZXJzLCBmdW5jdGlvbihhdHRhY2hlcikge1xuICAgICAgY2xvc3VyZS5hZGQoYXR0YWNoZXIsIGNsb3N1cmUudG9wTGV2ZWxbYXR0YWNoZXIuaG9zdC5pZF0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBwZXJmb3JtIHRoZSBhdHRhY2hpbmcgYWZ0ZXIgc2hhcGVzIGFyZSBkb25lIG1vdmluZ1xuICB0aGlzLnBvc3RFeGVjdXRlZCgnZWxlbWVudHMubW92ZScsIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZS5jb250ZXh0LFxuICAgICAgICBzaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgbmV3SG9zdCA9IGNvbnRleHQubmV3SG9zdCxcbiAgICAgICAgYXR0YWNoZXJzO1xuXG4gICAgLy8gb25seSBzaW5nbGUgZWxlbWVudHMgY2FuIGJlIGF0dGFjaGVkXG4gICAgLy8gbXVsdGlwbHkgZWxlbWVudHMgY2FuIGJlIGRldGFjaGVkXG4gICAgaWYgKG5ld0hvc3QgJiYgc2hhcGVzLmxlbmd0aCAhPT0gMSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChuZXdIb3N0KSB7XG4gICAgICBhdHRhY2hlcnMgPSBzaGFwZXM7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gZmluZCBhdHRhY2hlcnMgbW92ZWQgd2l0aG91dCBob3N0XG4gICAgICBhdHRhY2hlcnMgPSBmaWx0ZXIoc2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgICAgICB2YXIgaG9zdCA9IHNoYXBlLmhvc3Q7XG5cbiAgICAgICAgcmV0dXJuIGlzQXR0YWNoZXIoc2hhcGUpICYmICFpbmNsdWRlcyhzaGFwZXMsIGhvc3QpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgZm9yRWFjaChhdHRhY2hlcnMsIGZ1bmN0aW9uKGF0dGFjaGVyKSB7XG4gICAgICBtb2RlbGluZy51cGRhdGVBdHRhY2htZW50KGF0dGFjaGVyLCBuZXdIb3N0KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gZW5zdXJlIGludmFsaWQgYXR0YWNobWVudCBjb25uZWN0aW9ucyBhcmUgcmVtb3ZlZFxuICB0aGlzLnBvc3RFeGVjdXRlZCgnZWxlbWVudHMubW92ZScsIGZ1bmN0aW9uKGUpIHtcblxuICAgIHZhciBzaGFwZXMgPSBlLmNvbnRleHQuc2hhcGVzO1xuXG4gICAgZm9yRWFjaChzaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG5cbiAgICAgIGZvckVhY2goc2hhcGUuYXR0YWNoZXJzLCBmdW5jdGlvbihhdHRhY2hlcikge1xuXG4gICAgICAgIC8vIHJlbW92ZSBpbnZhbGlkIG91dGdvaW5nIGNvbm5lY3Rpb25zXG4gICAgICAgIGZvckVhY2goYXR0YWNoZXIub3V0Z29pbmcuc2xpY2UoKSwgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgICAgIHZhciBhbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCB7XG4gICAgICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgICAgICAgICAgc291cmNlOiBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgICAgIHRhcmdldDogY29ubmVjdGlvbi50YXJnZXRcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmICghYWxsb3dlZCkge1xuICAgICAgICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihjb25uZWN0aW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIHJlbW92ZSBpbnZhbGlkIGluY29taW5nIGNvbm5lY3Rpb25zXG4gICAgICAgIGZvckVhY2goYXR0YWNoZXIuaW5jb21pbmcuc2xpY2UoKSwgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgICAgIHZhciBhbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCB7XG4gICAgICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgICAgICAgICAgc291cmNlOiBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgICAgIHRhcmdldDogY29ubmVjdGlvbi50YXJnZXRcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmICghYWxsb3dlZCkge1xuICAgICAgICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihjb25uZWN0aW9uKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ3NoYXBlLmNyZWF0ZScsIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBob3N0ID0gY29udGV4dC5ob3N0O1xuXG4gICAgaWYgKGhvc3QpIHtcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZUF0dGFjaG1lbnQoc2hhcGUsIGhvc3QpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gdXBkYXRlIGF0dGFjaG1lbnRzIGlmIHRoZSBob3N0IGlzIHJlcGxhY2VkXG4gIHRoaXMucG9zdEV4ZWN1dGUoJ3NoYXBlLnJlcGxhY2UnLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgb2xkU2hhcGUgPSBjb250ZXh0Lm9sZFNoYXBlLFxuICAgICAgICBuZXdTaGFwZSA9IGNvbnRleHQubmV3U2hhcGU7XG5cbiAgICAvLyBtb3ZlIHRoZSBhdHRhY2hlcnMgdG8gdGhlIG5ldyBob3N0XG4gICAgc2F2ZUNsZWFyKG9sZFNoYXBlLmF0dGFjaGVycywgZnVuY3Rpb24oYXR0YWNoZXIpIHtcbiAgICAgIHZhciBhbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMubW92ZScsIHtcbiAgICAgICAgdGFyZ2V0OiBuZXdTaGFwZSxcbiAgICAgICAgc2hhcGVzOiBbYXR0YWNoZXJdXG4gICAgICB9KTtcblxuICAgICAgaWYgKGFsbG93ZWQgPT09ICdhdHRhY2gnKSB7XG4gICAgICAgIG1vZGVsaW5nLnVwZGF0ZUF0dGFjaG1lbnQoYXR0YWNoZXIsIG5ld1NoYXBlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1vZGVsaW5nLnJlbW92ZVNoYXBlKGF0dGFjaGVyKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIG1vdmUgYXR0YWNoZXJzIGlmIG5ldyBob3N0IGhhcyBkaWZmZXJlbnQgc2l6ZVxuICAgIGlmIChuZXdTaGFwZS5hdHRhY2hlcnMubGVuZ3RoKSB7XG5cbiAgICAgIGZvckVhY2gobmV3U2hhcGUuYXR0YWNoZXJzLCBmdW5jdGlvbihhdHRhY2hlcikge1xuICAgICAgICB2YXIgZGVsdGEgPSBnZXROZXdBdHRhY2hTaGFwZURlbHRhKGF0dGFjaGVyLCBvbGRTaGFwZSwgbmV3U2hhcGUpO1xuICAgICAgICBtb2RlbGluZy5tb3ZlU2hhcGUoYXR0YWNoZXIsIGRlbHRhLCBhdHRhY2hlci5wYXJlbnQpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gIH0pO1xuXG4gIC8vIG1vdmUgc2hhcGUgb24gaG9zdCByZXNpemVcbiAgdGhpcy5wb3N0RXhlY3V0ZSgnc2hhcGUucmVzaXplJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgb2xkQm91bmRzID0gY29udGV4dC5vbGRCb3VuZHMsXG4gICAgICAgIG5ld0JvdW5kcyA9IGNvbnRleHQubmV3Qm91bmRzLFxuICAgICAgICBhdHRhY2hlcnMgPSBzaGFwZS5hdHRhY2hlcnMsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fTtcblxuICAgIGlmIChoaW50cy5hdHRhY2hTdXBwb3J0ID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGZvckVhY2goYXR0YWNoZXJzLCBmdW5jdGlvbihhdHRhY2hlcikge1xuICAgICAgdmFyIGRlbHRhID0gZ2V0TmV3QXR0YWNoU2hhcGVEZWx0YShhdHRhY2hlciwgb2xkQm91bmRzLCBuZXdCb3VuZHMpO1xuXG4gICAgICBtb2RlbGluZy5tb3ZlU2hhcGUoYXR0YWNoZXIsIGRlbHRhLCBhdHRhY2hlci5wYXJlbnQpO1xuXG4gICAgICBmb3JFYWNoKGF0dGFjaGVyLmxhYmVscywgZnVuY3Rpb24obGFiZWwpIHtcbiAgICAgICAgbW9kZWxpbmcubW92ZVNoYXBlKGxhYmVsLCBkZWx0YSwgbGFiZWwucGFyZW50KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyByZW1vdmUgYXR0YWNobWVudHNcbiAgdGhpcy5wcmVFeGVjdXRlKCdzaGFwZS5kZWxldGUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIHNoYXBlID0gZXZlbnQuY29udGV4dC5zaGFwZTtcblxuICAgIHNhdmVDbGVhcihzaGFwZS5hdHRhY2hlcnMsIGZ1bmN0aW9uKGF0dGFjaGVyKSB7XG4gICAgICBtb2RlbGluZy5yZW1vdmVTaGFwZShhdHRhY2hlcik7XG4gICAgfSk7XG5cbiAgICBpZiAoc2hhcGUuaG9zdCkge1xuICAgICAgbW9kZWxpbmcudXBkYXRlQXR0YWNobWVudChzaGFwZSwgbnVsbCk7XG4gICAgfVxuICB9KTtcbn1cblxuaW5oZXJpdHMoQXR0YWNoU3VwcG9ydCwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuQXR0YWNoU3VwcG9ydC4kaW5qZWN0ID0gW1xuICAnaW5qZWN0b3InLFxuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3J1bGVzJyxcbiAgJ21vZGVsaW5nJ1xuXTtcblxuXG4vKipcbiAqIFJldHVybiBhdHRhY2hlcnMgb2YgdGhlIGdpdmVuIHNoYXBlc1xuICpcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBzaGFwZXNcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn1cbiAqL1xuZnVuY3Rpb24gZ2V0QXR0YWNoZXJzKHNoYXBlcykge1xuICByZXR1cm4gZmxhdHRlbihtYXAoc2hhcGVzLCBmdW5jdGlvbihzKSB7XG4gICAgcmV0dXJuIHMuYXR0YWNoZXJzIHx8IFtdO1xuICB9KSk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgY29tYmluZWQgbGlzdCBvZiBlbGVtZW50cyBhbmRcbiAqIGF0dGFjaGVycy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHNcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZmlsdGVyZWRcbiAqL1xuZnVuY3Rpb24gYWRkQXR0YWNoZWQoZWxlbWVudHMpIHtcbiAgdmFyIGF0dGFjaGVycyA9IGdldEF0dGFjaGVycyhlbGVtZW50cyk7XG5cbiAgcmV0dXJuIHVuaW9uQnkoJ2lkJywgZWxlbWVudHMsIGF0dGFjaGVycyk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgZmlsdGVyZWQgbGlzdCBvZiBlbGVtZW50cyB0aGF0IGRvIG5vdFxuICogY29udGFpbiBhdHRhY2hlZCBlbGVtZW50cyB3aXRoIGhvc3RzIGJlaW5nIHBhcnRcbiAqIG9mIHRoZSBzZWxlY3Rpb24uXG4gKlxuICogQHBhcmFtICB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICpcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZmlsdGVyZWRcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlQXR0YWNoZWQoZWxlbWVudHMpIHtcblxuICB2YXIgaWRzID0gZ3JvdXBCeShlbGVtZW50cywgJ2lkJyk7XG5cbiAgcmV0dXJuIGZpbHRlcihlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHdoaWxlIChlbGVtZW50KSB7XG5cbiAgICAgIC8vIGhvc3QgaW4gc2VsZWN0aW9uXG4gICAgICBpZiAoZWxlbWVudC5ob3N0ICYmIGlkc1tlbGVtZW50Lmhvc3QuaWRdKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50O1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gaXNBdHRhY2hlcihzaGFwZSkge1xuICByZXR1cm4gISFzaGFwZS5ob3N0O1xufVxuXG5mdW5jdGlvbiBpbmNsdWRlcyhhcnJheSwgaXRlbSkge1xuICByZXR1cm4gYXJyYXkuaW5kZXhPZihpdGVtKSAhPT0gLTE7XG59IiwiaW1wb3J0IFJ1bGVzTW9kdWxlIGZyb20gJy4uL3J1bGVzJztcblxuaW1wb3J0IEF0dGFjaFN1cHBvcnQgZnJvbSAnLi9BdHRhY2hTdXBwb3J0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIFJ1bGVzTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdhdHRhY2hTdXBwb3J0JyBdLFxuICBhdHRhY2hTdXBwb3J0OiBbICd0eXBlJywgQXR0YWNoU3VwcG9ydCBdXG59O1xuIiwiaW1wb3J0IHtcbiAgYXNUUkJMLFxuICBnZXRNaWRcbn0gZnJvbSAnLi4vLi4vbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQgeyBERUZBVUxUX0RJU1RBTkNFIH0gZnJvbSAnLi9BdXRvUGxhY2VVdGlsJztcblxudmFyIExPV19QUklPUklUWSA9IDEwMDtcblxuXG4vKipcbiAqIEEgc2VydmljZSB0aGF0IHBsYWNlcyBlbGVtZW50cyBjb25uZWN0ZWQgdG8gZXhpc3Rpbmcgb25lc1xuICogdG8gYW4gYXBwcm9wcmlhdGUgcG9zaXRpb24gaW4gYW4gX2F1dG9tYXRlZF8gZmFzaGlvbi5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1BsYWNlKGV2ZW50QnVzLCBtb2RlbGluZykge1xuXG4gIGV2ZW50QnVzLm9uKCdhdXRvUGxhY2UnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBzb3VyY2UgPSBjb250ZXh0LnNvdXJjZTtcblxuICAgIHJldHVybiBnZXROZXdTaGFwZVBvc2l0aW9uKHNvdXJjZSwgc2hhcGUpO1xuICB9KTtcblxuICAvKipcbiAgICogQXBwZW5kIHNoYXBlIHRvIHNvdXJjZSBhdCBhcHByb3ByaWF0ZSBwb3NpdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHNvdXJjZVxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAgICpcbiAgICogQHJldHVybiB7ZGpzLm1vZGVsLlNoYXBlfSBhcHBlbmRlZCBzaGFwZVxuICAgKi9cbiAgdGhpcy5hcHBlbmQgPSBmdW5jdGlvbihzb3VyY2UsIHNoYXBlLCBoaW50cykge1xuXG4gICAgZXZlbnRCdXMuZmlyZSgnYXV0b1BsYWNlLnN0YXJ0Jywge1xuICAgICAgc291cmNlOiBzb3VyY2UsXG4gICAgICBzaGFwZTogc2hhcGVcbiAgICB9KTtcblxuICAgIC8vIGFsbG93IG90aGVycyB0byBwcm92aWRlIHRoZSBwb3NpdGlvblxuICAgIHZhciBwb3NpdGlvbiA9IGV2ZW50QnVzLmZpcmUoJ2F1dG9QbGFjZScsIHtcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgc2hhcGU6IHNoYXBlXG4gICAgfSk7XG5cbiAgICB2YXIgbmV3U2hhcGUgPSBtb2RlbGluZy5hcHBlbmRTaGFwZShzb3VyY2UsIHNoYXBlLCBwb3NpdGlvbiwgc291cmNlLnBhcmVudCwgaGludHMpO1xuXG4gICAgZXZlbnRCdXMuZmlyZSgnYXV0b1BsYWNlLmVuZCcsIHtcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgc2hhcGU6IG5ld1NoYXBlXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbmV3U2hhcGU7XG4gIH07XG5cbn1cblxuQXV0b1BsYWNlLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG4vKipcbiAqIEZpbmQgdGhlIG5ldyBwb3NpdGlvbiBmb3IgdGhlIHRhcmdldCBlbGVtZW50IHRvXG4gKiBjb25uZWN0IHRvIHNvdXJjZS5cbiAqXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuU2hhcGV9IHNvdXJjZVxuICogQHBhcmFtICB7ZGpzLm1vZGVsLlNoYXBlfSBlbGVtZW50XG4gKiBAcGFyYW0gIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSAge09iamVjdH0gW2hpbnRzLmRlZmF1bHREaXN0YW5jZV1cbiAqXG4gKiBAcmV0dXJucyB7UG9pbnR9XG4gKi9cbmZ1bmN0aW9uIGdldE5ld1NoYXBlUG9zaXRpb24oc291cmNlLCBlbGVtZW50LCBoaW50cykge1xuICBpZiAoIWhpbnRzKSB7XG4gICAgaGludHMgPSB7fTtcbiAgfVxuXG4gIHZhciBkaXN0YW5jZSA9IGhpbnRzLmRlZmF1bHREaXN0YW5jZSB8fCBERUZBVUxUX0RJU1RBTkNFO1xuXG4gIHZhciBzb3VyY2VNaWQgPSBnZXRNaWQoc291cmNlKSxcbiAgICAgIHNvdXJjZVRyYmwgPSBhc1RSQkwoc291cmNlKTtcblxuICAvLyBzaW1wbHkgcHV0IGVsZW1lbnQgcmlnaHQgbmV4dCB0byBzb3VyY2VcbiAgcmV0dXJuIHtcbiAgICB4OiBzb3VyY2VUcmJsLnJpZ2h0ICsgZGlzdGFuY2UgKyBlbGVtZW50LndpZHRoIC8gMixcbiAgICB5OiBzb3VyY2VNaWQueVxuICB9O1xufSIsIi8qKlxuICogU2VsZWN0IGVsZW1lbnQgYWZ0ZXIgYXV0byBwbGFjZW1lbnQuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7U2VsZWN0aW9ufSBzZWxlY3Rpb25cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1BsYWNlU2VsZWN0aW9uQmVoYXZpb3IoZXZlbnRCdXMsIHNlbGVjdGlvbikge1xuXG4gIGV2ZW50QnVzLm9uKCdhdXRvUGxhY2UuZW5kJywgNTAwLCBmdW5jdGlvbihlKSB7XG4gICAgc2VsZWN0aW9uLnNlbGVjdChlLnNoYXBlKTtcbiAgfSk7XG5cbn1cblxuQXV0b1BsYWNlU2VsZWN0aW9uQmVoYXZpb3IuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ3NlbGVjdGlvbidcbl07IiwiaW1wb3J0IHtcbiAgYXNUUkJMLFxuICBnZXRPcmllbnRhdGlvbixcbiAgZ2V0TWlkXG59IGZyb20gJy4uLy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgZmluZCxcbiAgcmVkdWNlXG59IGZyb20gJ21pbi1kYXNoJztcblxuLy8gcGFkZGluZyB0byBkZXRlY3QgZWxlbWVudCBwbGFjZW1lbnRcbnZhciBQTEFDRU1FTlRfREVURUNUSU9OX1BBRCA9IDEwO1xuXG5leHBvcnQgdmFyIERFRkFVTFRfRElTVEFOQ0UgPSA1MDtcblxudmFyIERFRkFVTFRfTUFYX0RJU1RBTkNFID0gMjUwO1xuXG5cbi8qKlxuICogR2V0IGZyZWUgcG9zaXRpb24gc3RhcnRpbmcgZnJvbSBnaXZlbiBwb3NpdGlvbi5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc291cmNlXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gZWxlbWVudFxuICogQHBhcmFtIHtQb2ludH0gcG9zaXRpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGdldE5leHRQb3NpdGlvblxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZEZyZWVQb3NpdGlvbihzb3VyY2UsIGVsZW1lbnQsIHBvc2l0aW9uLCBnZXROZXh0UG9zaXRpb24pIHtcbiAgdmFyIGNvbm5lY3RlZEF0UG9zaXRpb247XG5cbiAgd2hpbGUgKChjb25uZWN0ZWRBdFBvc2l0aW9uID0gZ2V0Q29ubmVjdGVkQXRQb3NpdGlvbihzb3VyY2UsIHBvc2l0aW9uLCBlbGVtZW50KSkpIHtcbiAgICBwb3NpdGlvbiA9IGdldE5leHRQb3NpdGlvbihlbGVtZW50LCBwb3NpdGlvbiwgY29ubmVjdGVkQXRQb3NpdGlvbik7XG4gIH1cblxuICByZXR1cm4gcG9zaXRpb247XG59XG5cbi8qKlxuICogUmV0dXJucyBmdW5jdGlvbiB0aGF0IHJldHVybnMgbmV4dCBwb3NpdGlvbi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gbmV4dFBvc2l0aW9uRGlyZWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gW25leHRQb3NpdGlvbkRpcmVjdGlvbi54XVxuICogQHBhcmFtIHtPYmplY3R9IFtuZXh0UG9zaXRpb25EaXJlY3Rpb24ueV1cbiAqXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUdldE5leHRQb3NpdGlvbihuZXh0UG9zaXRpb25EaXJlY3Rpb24pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIHByZXZpb3VzUG9zaXRpb24sIGNvbm5lY3RlZEF0UG9zaXRpb24pIHtcbiAgICB2YXIgbmV4dFBvc2l0aW9uID0ge1xuICAgICAgeDogcHJldmlvdXNQb3NpdGlvbi54LFxuICAgICAgeTogcHJldmlvdXNQb3NpdGlvbi55XG4gICAgfTtcblxuICAgIFsgJ3gnLCAneScgXS5mb3JFYWNoKGZ1bmN0aW9uKGF4aXMpIHtcblxuICAgICAgdmFyIG5leHRQb3NpdGlvbkRpcmVjdGlvbkZvckF4aXMgPSBuZXh0UG9zaXRpb25EaXJlY3Rpb25bIGF4aXMgXTtcblxuICAgICAgaWYgKCFuZXh0UG9zaXRpb25EaXJlY3Rpb25Gb3JBeGlzKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGRpbWVuc2lvbiA9IGF4aXMgPT09ICd4JyA/ICd3aWR0aCcgOiAnaGVpZ2h0JztcblxuICAgICAgdmFyIG1hcmdpbiA9IG5leHRQb3NpdGlvbkRpcmVjdGlvbkZvckF4aXMubWFyZ2luLFxuICAgICAgICAgIG1pbkRpc3RhbmNlID0gbmV4dFBvc2l0aW9uRGlyZWN0aW9uRm9yQXhpcy5taW5EaXN0YW5jZTtcblxuICAgICAgaWYgKG1hcmdpbiA8IDApIHtcbiAgICAgICAgbmV4dFBvc2l0aW9uWyBheGlzIF0gPSBNYXRoLm1pbihcbiAgICAgICAgICBjb25uZWN0ZWRBdFBvc2l0aW9uWyBheGlzIF0gKyBtYXJnaW4gLSBlbGVtZW50WyBkaW1lbnNpb24gXSAvIDIsXG4gICAgICAgICAgcHJldmlvdXNQb3NpdGlvblsgYXhpcyBdIC0gbWluRGlzdGFuY2UgKyBtYXJnaW5cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5leHRQb3NpdGlvblsgYXhpcyBdID0gTWF0aC5tYXgoXG4gICAgICAgICAgY29ubmVjdGVkQXRQb3NpdGlvblsgYXhpcyBdICsgY29ubmVjdGVkQXRQb3NpdGlvblsgZGltZW5zaW9uIF0gKyBtYXJnaW4gKyBlbGVtZW50WyBkaW1lbnNpb24gXSAvIDIsXG4gICAgICAgICAgcHJldmlvdXNQb3NpdGlvblsgYXhpcyBdICsgbWluRGlzdGFuY2UgKyBtYXJnaW5cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBuZXh0UG9zaXRpb247XG4gIH07XG59XG5cbi8qKlxuICogUmV0dXJuIHRhcmdldCBhdCBnaXZlbiBwb3NpdGlvbiwgaWYgZGVmaW5lZC5cbiAqXG4gKiBUaGlzIHRha2VzIGNvbm5lY3RlZCBlbGVtZW50cyBmcm9tIGhvc3QgYW5kIGF0dGFjaGVyc1xuICogaW50byBhY2NvdW50LCB0b28uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb25uZWN0ZWRBdFBvc2l0aW9uKHNvdXJjZSwgcG9zaXRpb24sIGVsZW1lbnQpIHtcblxuICB2YXIgYm91bmRzID0ge1xuICAgIHg6IHBvc2l0aW9uLnggLSAoZWxlbWVudC53aWR0aCAvIDIpLFxuICAgIHk6IHBvc2l0aW9uLnkgLSAoZWxlbWVudC5oZWlnaHQgLyAyKSxcbiAgICB3aWR0aDogZWxlbWVudC53aWR0aCxcbiAgICBoZWlnaHQ6IGVsZW1lbnQuaGVpZ2h0XG4gIH07XG5cbiAgdmFyIGNsb3N1cmUgPSBnZXRBdXRvUGxhY2VDbG9zdXJlKHNvdXJjZSwgZWxlbWVudCk7XG5cbiAgcmV0dXJuIGZpbmQoY2xvc3VyZSwgZnVuY3Rpb24odGFyZ2V0KSB7XG5cbiAgICBpZiAodGFyZ2V0ID09PSBlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIG9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24odGFyZ2V0LCBib3VuZHMsIFBMQUNFTUVOVF9ERVRFQ1RJT05fUEFEKTtcblxuICAgIHJldHVybiBvcmllbnRhdGlvbiA9PT0gJ2ludGVyc2VjdCc7XG4gIH0pO1xufVxuXG4vKipcbiogQ29tcHV0ZSBvcHRpbWFsIGRpc3RhbmNlIGJldHdlZW4gc291cmNlIGFuZCB0YXJnZXQgYmFzZWQgb24gZXhpc3RpbmcgY29ubmVjdGlvbnMgdG8gYW5kIGZyb20gc291cmNlLlxuKiBBc3N1bWVzIGxlZnQtdG8tcmlnaHQgYW5kIHRvcC10by1kb3duIG1vZGVsaW5nLlxuKlxuKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc291cmNlXG4qIEBwYXJhbSB7T2JqZWN0fSBbaGludHNdXG4qIEBwYXJhbSB7bnVtYmVyfSBbaGludHMuZGVmYXVsdERpc3RhbmNlXVxuKiBAcGFyYW0ge3N0cmluZ30gW2hpbnRzLmRpcmVjdGlvbl1cbiogQHBhcmFtIHtGdW5jdGlvbn0gW2hpbnRzLmZpbHRlcl1cbiogQHBhcmFtIHtGdW5jdGlvbn0gW2hpbnRzLmdldFdlaWdodF1cbiogQHBhcmFtIHtudW1iZXJ9IFtoaW50cy5tYXhEaXN0YW5jZV1cbiogQHBhcmFtIHtzdHJpbmd9IFtoaW50cy5yZWZlcmVuY2VdXG4qXG4qIEByZXR1cm4ge251bWJlcn1cbiovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q29ubmVjdGVkRGlzdGFuY2Uoc291cmNlLCBoaW50cykge1xuICBpZiAoIWhpbnRzKSB7XG4gICAgaGludHMgPSB7fTtcbiAgfVxuXG4gIC8vIHRhcmdldHMgPiBzb3VyY2VzIGJ5IGRlZmF1bHRcbiAgZnVuY3Rpb24gZ2V0RGVmYXVsdFdlaWdodChjb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuIGNvbm5lY3Rpb24uc291cmNlID09PSBzb3VyY2UgPyAxIDogLTE7XG4gIH1cblxuICB2YXIgZGVmYXVsdERpc3RhbmNlID0gaGludHMuZGVmYXVsdERpc3RhbmNlIHx8IERFRkFVTFRfRElTVEFOQ0UsXG4gICAgICBkaXJlY3Rpb24gPSBoaW50cy5kaXJlY3Rpb24gfHwgJ2UnLFxuICAgICAgZmlsdGVyID0gaGludHMuZmlsdGVyLFxuICAgICAgZ2V0V2VpZ2h0ID0gaGludHMuZ2V0V2VpZ2h0IHx8IGdldERlZmF1bHRXZWlnaHQsXG4gICAgICBtYXhEaXN0YW5jZSA9IGhpbnRzLm1heERpc3RhbmNlIHx8IERFRkFVTFRfTUFYX0RJU1RBTkNFLFxuICAgICAgcmVmZXJlbmNlID0gaGludHMucmVmZXJlbmNlIHx8ICdzdGFydCc7XG5cbiAgaWYgKCFmaWx0ZXIpIHtcbiAgICBmaWx0ZXIgPSBub25lRmlsdGVyO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0RGlzdGFuY2UoYSwgYikge1xuICAgIGlmIChkaXJlY3Rpb24gPT09ICduJykge1xuICAgICAgaWYgKHJlZmVyZW5jZSA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICByZXR1cm4gYXNUUkJMKGEpLnRvcCAtIGFzVFJCTChiKS5ib3R0b207XG4gICAgICB9IGVsc2UgaWYgKHJlZmVyZW5jZSA9PT0gJ2NlbnRlcicpIHtcbiAgICAgICAgcmV0dXJuIGFzVFJCTChhKS50b3AgLSBnZXRNaWQoYikueTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhc1RSQkwoYSkudG9wIC0gYXNUUkJMKGIpLnRvcDtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ3cnKSB7XG4gICAgICBpZiAocmVmZXJlbmNlID09PSAnc3RhcnQnKSB7XG4gICAgICAgIHJldHVybiBhc1RSQkwoYSkubGVmdCAtIGFzVFJCTChiKS5yaWdodDtcbiAgICAgIH0gZWxzZSBpZiAocmVmZXJlbmNlID09PSAnY2VudGVyJykge1xuICAgICAgICByZXR1cm4gYXNUUkJMKGEpLmxlZnQgLSBnZXRNaWQoYikueDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhc1RSQkwoYSkubGVmdCAtIGFzVFJCTChiKS5sZWZ0O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAncycpIHtcbiAgICAgIGlmIChyZWZlcmVuY2UgPT09ICdzdGFydCcpIHtcbiAgICAgICAgcmV0dXJuIGFzVFJCTChiKS50b3AgLSBhc1RSQkwoYSkuYm90dG9tO1xuICAgICAgfSBlbHNlIGlmIChyZWZlcmVuY2UgPT09ICdjZW50ZXInKSB7XG4gICAgICAgIHJldHVybiBnZXRNaWQoYikueSAtIGFzVFJCTChhKS5ib3R0b207XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gYXNUUkJMKGIpLmJvdHRvbSAtIGFzVFJCTChhKS5ib3R0b207XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChyZWZlcmVuY2UgPT09ICdzdGFydCcpIHtcbiAgICAgICAgcmV0dXJuIGFzVFJCTChiKS5sZWZ0IC0gYXNUUkJMKGEpLnJpZ2h0O1xuICAgICAgfSBlbHNlIGlmIChyZWZlcmVuY2UgPT09ICdjZW50ZXInKSB7XG4gICAgICAgIHJldHVybiBnZXRNaWQoYikueCAtIGFzVFJCTChhKS5yaWdodDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBhc1RSQkwoYikucmlnaHQgLSBhc1RSQkwoYSkucmlnaHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdmFyIHNvdXJjZXNEaXN0YW5jZXMgPSBzb3VyY2UuaW5jb21pbmdcbiAgICAuZmlsdGVyKGZpbHRlcilcbiAgICAubWFwKGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgIHZhciB3ZWlnaHQgPSBnZXRXZWlnaHQoY29ubmVjdGlvbik7XG5cbiAgICAgIHZhciBkaXN0YW5jZSA9IHdlaWdodCA8IDBcbiAgICAgICAgPyBnZXREaXN0YW5jZShjb25uZWN0aW9uLnNvdXJjZSwgc291cmNlKVxuICAgICAgICA6IGdldERpc3RhbmNlKHNvdXJjZSwgY29ubmVjdGlvbi5zb3VyY2UpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBpZDogY29ubmVjdGlvbi5zb3VyY2UuaWQsXG4gICAgICAgIGRpc3RhbmNlOiBkaXN0YW5jZSxcbiAgICAgICAgd2VpZ2h0OiB3ZWlnaHRcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgdmFyIHRhcmdldHNEaXN0YW5jZXMgPSBzb3VyY2Uub3V0Z29pbmdcbiAgICAuZmlsdGVyKGZpbHRlcilcbiAgICAubWFwKGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgIHZhciB3ZWlnaHQgPSBnZXRXZWlnaHQoY29ubmVjdGlvbik7XG5cbiAgICAgIHZhciBkaXN0YW5jZSA9IHdlaWdodCA+IDBcbiAgICAgICAgPyBnZXREaXN0YW5jZShzb3VyY2UsIGNvbm5lY3Rpb24udGFyZ2V0KVxuICAgICAgICA6IGdldERpc3RhbmNlKGNvbm5lY3Rpb24udGFyZ2V0LCBzb3VyY2UpO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBpZDogY29ubmVjdGlvbi50YXJnZXQuaWQsXG4gICAgICAgIGRpc3RhbmNlOiBkaXN0YW5jZSxcbiAgICAgICAgd2VpZ2h0OiB3ZWlnaHRcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgdmFyIGRpc3RhbmNlcyA9IHNvdXJjZXNEaXN0YW5jZXMuY29uY2F0KHRhcmdldHNEaXN0YW5jZXMpLnJlZHVjZShmdW5jdGlvbihhY2N1bXVsYXRvciwgY3VycmVudFZhbHVlKSB7XG4gICAgYWNjdW11bGF0b3JbIGN1cnJlbnRWYWx1ZS5pZCArICdfX3dlaWdodF8nICsgY3VycmVudFZhbHVlLndlaWdodCBdID0gY3VycmVudFZhbHVlO1xuXG4gICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICB9LCB7fSk7XG5cbiAgdmFyIGRpc3RhbmNlc0dyb3VwZWQgPSByZWR1Y2UoZGlzdGFuY2VzLCBmdW5jdGlvbihhY2N1bXVsYXRvciwgY3VycmVudFZhbHVlKSB7XG4gICAgdmFyIGRpc3RhbmNlID0gY3VycmVudFZhbHVlLmRpc3RhbmNlLFxuICAgICAgICB3ZWlnaHQgPSBjdXJyZW50VmFsdWUud2VpZ2h0O1xuXG4gICAgaWYgKGRpc3RhbmNlIDwgMCB8fCBkaXN0YW5jZSA+IG1heERpc3RhbmNlKSB7XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfVxuXG4gICAgaWYgKCFhY2N1bXVsYXRvclsgU3RyaW5nKGRpc3RhbmNlKSBdKSB7XG4gICAgICBhY2N1bXVsYXRvclsgU3RyaW5nKGRpc3RhbmNlKSBdID0gMDtcbiAgICB9XG5cbiAgICBhY2N1bXVsYXRvclsgU3RyaW5nKGRpc3RhbmNlKSBdICs9IDEgKiB3ZWlnaHQ7XG5cbiAgICBpZiAoIWFjY3VtdWxhdG9yLmRpc3RhbmNlIHx8IGFjY3VtdWxhdG9yWyBhY2N1bXVsYXRvci5kaXN0YW5jZSBdIDwgYWNjdW11bGF0b3JbIFN0cmluZyhkaXN0YW5jZSkgXSkge1xuICAgICAgYWNjdW11bGF0b3IuZGlzdGFuY2UgPSBkaXN0YW5jZTtcbiAgICB9XG5cbiAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gIH0sIHt9KTtcblxuICByZXR1cm4gZGlzdGFuY2VzR3JvdXBlZC5kaXN0YW5jZSB8fCBkZWZhdWx0RGlzdGFuY2U7XG59XG5cbi8qKlxuICogUmV0dXJucyBhbGwgY29ubmVjdGVkIGVsZW1lbnRzIGFyb3VuZCB0aGUgZ2l2ZW4gc291cmNlLlxuICpcbiAqIFRoaXMgaW5jbHVkZXM6XG4gKlxuICogICAtIGNvbm5lY3RlZCBlbGVtZW50c1xuICogICAtIGhvc3QgY29ubmVjdGVkIGVsZW1lbnRzXG4gKiAgIC0gYXR0YWNoZXJzIGNvbm5lY3RlZCBlbGVtZW50c1xuICpcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5TaGFwZX0gc291cmNlXG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLlNoYXBlPn1cbiAqL1xuZnVuY3Rpb24gZ2V0QXV0b1BsYWNlQ2xvc3VyZShzb3VyY2UpIHtcblxuICB2YXIgYWxsQ29ubmVjdGVkID0gZ2V0Q29ubmVjdGVkKHNvdXJjZSk7XG5cbiAgaWYgKHNvdXJjZS5ob3N0KSB7XG4gICAgYWxsQ29ubmVjdGVkID0gYWxsQ29ubmVjdGVkLmNvbmNhdChnZXRDb25uZWN0ZWQoc291cmNlLmhvc3QpKTtcbiAgfVxuXG4gIGlmIChzb3VyY2UuYXR0YWNoZXJzKSB7XG4gICAgYWxsQ29ubmVjdGVkID0gYWxsQ29ubmVjdGVkLmNvbmNhdChzb3VyY2UuYXR0YWNoZXJzLnJlZHVjZShmdW5jdGlvbihzaGFwZXMsIGF0dGFjaGVyKSB7XG4gICAgICByZXR1cm4gc2hhcGVzLmNvbmNhdChnZXRDb25uZWN0ZWQoYXR0YWNoZXIpKTtcbiAgICB9LCBbXSkpO1xuICB9XG5cbiAgcmV0dXJuIGFsbENvbm5lY3RlZDtcbn1cblxuZnVuY3Rpb24gZ2V0Q29ubmVjdGVkKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGdldFRhcmdldHMoZWxlbWVudCkuY29uY2F0KGdldFNvdXJjZXMoZWxlbWVudCkpO1xufVxuXG5mdW5jdGlvbiBnZXRTb3VyY2VzKHNoYXBlKSB7XG4gIHJldHVybiBzaGFwZS5pbmNvbWluZy5tYXAoZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgIHJldHVybiBjb25uZWN0aW9uLnNvdXJjZTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldFRhcmdldHMoc2hhcGUpIHtcbiAgcmV0dXJuIHNoYXBlLm91dGdvaW5nLm1hcChmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuIGNvbm5lY3Rpb24udGFyZ2V0O1xuICB9KTtcbn1cblxuZnVuY3Rpb24gbm9uZUZpbHRlcigpIHtcbiAgcmV0dXJuIHRydWU7XG59XG4iLCJpbXBvcnQgQXV0b1BsYWNlIGZyb20gJy4vQXV0b1BsYWNlJztcbmltcG9ydCBBdXRvUGxhY2VTZWxlY3Rpb25CZWhhdmlvciBmcm9tICcuL0F1dG9QbGFjZVNlbGVjdGlvbkJlaGF2aW9yJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnYXV0b1BsYWNlU2VsZWN0aW9uQmVoYXZpb3InIF0sXG4gIGF1dG9QbGFjZTogWyAndHlwZScsIEF1dG9QbGFjZSBdLFxuICBhdXRvUGxhY2VTZWxlY3Rpb25CZWhhdmlvcjogWyAndHlwZScsIEF1dG9QbGFjZVNlbGVjdGlvbkJlaGF2aW9yIF1cbn07IiwiaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IHsgZ2V0QkJveCBhcyBnZXRCb3VuZGluZ0JveCB9IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG5pbXBvcnQge1xuICBhc1RSQkwsXG4gIGFzQm91bmRzXG59IGZyb20gJy4uLy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmbGF0dGVuLFxuICBmaW5kLFxuICBmb3JFYWNoLFxuICBncm91cEJ5LFxuICBpc0FycmF5LFxuICBtYXRjaFBhdHRlcm4sXG4gIHBpY2ssXG4gIHZhbHVlc1xufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnLi4vLi4vY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5cbi8qKlxuICogQW4gYXV0byByZXNpemUgY29tcG9uZW50IHRoYXQgdGFrZXMgY2FyZSBvZiBleHBhbmRpbmcgYSBwYXJlbnQgZWxlbWVudFxuICogaWYgY2hpbGQgZWxlbWVudHMgYXJlIGNyZWF0ZWQgb3IgbW92ZWQgY2xvc2UgdGhlIHBhcmVudHMgZWRnZS5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtFbGVtZW50UmVnaXN0cnl9IGVsZW1lbnRSZWdpc3RyeVxuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEF1dG9SZXNpemUoZXZlbnRCdXMsIGVsZW1lbnRSZWdpc3RyeSwgbW9kZWxpbmcsIHJ1bGVzKSB7XG5cbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fcnVsZXMgPSBydWxlcztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoWyAnc2hhcGUuY3JlYXRlJyBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50IHx8IGNvbnRleHQubmV3UGFyZW50O1xuXG4gICAgaWYgKGhpbnRzLmF1dG9SZXNpemUgPT09IGZhbHNlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc2VsZi5fZXhwYW5kKFsgc2hhcGUgXSwgcGFyZW50KTtcbiAgfSk7XG5cbiAgdGhpcy5wb3N0RXhlY3V0ZWQoWyAnZWxlbWVudHMubW92ZScgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnRzID0gZmxhdHRlbih2YWx1ZXMoY29udGV4dC5jbG9zdXJlLnRvcExldmVsKSksXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cztcblxuICAgIHZhciBhdXRvUmVzaXplID0gaGludHMgPyBoaW50cy5hdXRvUmVzaXplIDogdHJ1ZTtcblxuICAgIGlmIChhdXRvUmVzaXplID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBleHBhbmRpbmdzID0gZ3JvdXBCeShlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnQucGFyZW50LmlkO1xuICAgIH0pO1xuXG4gICAgZm9yRWFjaChleHBhbmRpbmdzLCBmdW5jdGlvbihlbGVtZW50cywgcGFyZW50SWQpIHtcblxuICAgICAgLy8gb3B0aW9uYWxseSBmaWx0ZXIgZWxlbWVudHMgdG8gYmUgY29uc2lkZXJlZCB3aGVuIHJlc2l6aW5nXG4gICAgICBpZiAoaXNBcnJheShhdXRvUmVzaXplKSkge1xuICAgICAgICBlbGVtZW50cyA9IGVsZW1lbnRzLmZpbHRlcihmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICAgICAgcmV0dXJuIGZpbmQoYXV0b1Jlc2l6ZSwgbWF0Y2hQYXR0ZXJuKHsgaWQ6IGVsZW1lbnQuaWQgfSkpO1xuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgc2VsZi5fZXhwYW5kKGVsZW1lbnRzLCBwYXJlbnRJZCk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKFsgJ3NoYXBlLnRvZ2dsZUNvbGxhcHNlJyBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzLFxuICAgICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgICBpZiAoaGludHMgJiYgaGludHMuYXV0b1Jlc2l6ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoc2hhcGUuY29sbGFwc2VkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgc2VsZi5fZXhwYW5kKHNoYXBlLmNoaWxkcmVuIHx8IFtdLCBzaGFwZSk7XG4gIH0pO1xuXG4gIHRoaXMucG9zdEV4ZWN1dGVkKFsgJ3NoYXBlLnJlc2l6ZScgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBwYXJlbnQgPSBzaGFwZS5wYXJlbnQ7XG5cbiAgICBpZiAoaGludHMgJiYgaGludHMuYXV0b1Jlc2l6ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAocGFyZW50KSB7XG4gICAgICBzZWxmLl9leHBhbmQoWyBzaGFwZSBdLCBwYXJlbnQpO1xuICAgIH1cbiAgfSk7XG5cbn1cblxuQXV0b1Jlc2l6ZS4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ21vZGVsaW5nJyxcbiAgJ3J1bGVzJ1xuXTtcblxuaW5oZXJpdHMoQXV0b1Jlc2l6ZSwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuXG4vKipcbiAqIENhbGN1bGF0ZSB0aGUgbmV3IGJvdW5kcyBvZiB0aGUgdGFyZ2V0IHNoYXBlLCBnaXZlblxuICogYSBudW1iZXIgb2YgZWxlbWVudHMgaGF2ZSBiZWVuIG1vdmVkIG9yIGFkZGVkIGludG8gdGhlIHBhcmVudC5cbiAqXG4gKiBUaGlzIG1ldGhvZCBjb25zaWRlcnMgdGhlIGN1cnJlbnQgc2l6ZSwgdGhlIGFkZGVkIGVsZW1lbnRzIGFzIHdlbGwgYXNcbiAqIHRoZSBwcm92aWRlZCBwYWRkaW5nIGZvciB0aGUgbmV3IGJvdW5kcy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gdGFyZ2V0XG4gKi9cbkF1dG9SZXNpemUucHJvdG90eXBlLl9nZXRPcHRpbWFsQm91bmRzID0gZnVuY3Rpb24oZWxlbWVudHMsIHRhcmdldCkge1xuXG4gIHZhciBvZmZzZXQgPSB0aGlzLmdldE9mZnNldCh0YXJnZXQpLFxuICAgICAgcGFkZGluZyA9IHRoaXMuZ2V0UGFkZGluZyh0YXJnZXQpO1xuXG4gIHZhciBlbGVtZW50c1RyYmwgPSBhc1RSQkwoZ2V0Qm91bmRpbmdCb3goZWxlbWVudHMpKSxcbiAgICAgIHRhcmdldFRyYmwgPSBhc1RSQkwodGFyZ2V0KTtcblxuICB2YXIgbmV3VHJibCA9IHt9O1xuXG4gIGlmIChlbGVtZW50c1RyYmwudG9wIC0gdGFyZ2V0VHJibC50b3AgPCBwYWRkaW5nLnRvcCkge1xuICAgIG5ld1RyYmwudG9wID0gZWxlbWVudHNUcmJsLnRvcCAtIG9mZnNldC50b3A7XG4gIH1cblxuICBpZiAoZWxlbWVudHNUcmJsLmxlZnQgLSB0YXJnZXRUcmJsLmxlZnQgPCBwYWRkaW5nLmxlZnQpIHtcbiAgICBuZXdUcmJsLmxlZnQgPSBlbGVtZW50c1RyYmwubGVmdCAtIG9mZnNldC5sZWZ0O1xuICB9XG5cbiAgaWYgKHRhcmdldFRyYmwucmlnaHQgLSBlbGVtZW50c1RyYmwucmlnaHQgPCBwYWRkaW5nLnJpZ2h0KSB7XG4gICAgbmV3VHJibC5yaWdodCA9IGVsZW1lbnRzVHJibC5yaWdodCArIG9mZnNldC5yaWdodDtcbiAgfVxuXG4gIGlmICh0YXJnZXRUcmJsLmJvdHRvbSAtIGVsZW1lbnRzVHJibC5ib3R0b20gPCBwYWRkaW5nLmJvdHRvbSkge1xuICAgIG5ld1RyYmwuYm90dG9tID0gZWxlbWVudHNUcmJsLmJvdHRvbSArIG9mZnNldC5ib3R0b207XG4gIH1cblxuICByZXR1cm4gYXNCb3VuZHMoYXNzaWduKHt9LCB0YXJnZXRUcmJsLCBuZXdUcmJsKSk7XG59O1xuXG5cbi8qKlxuICogRXhwYW5kIHRoZSB0YXJnZXQgc2hhcGUgcmVzcGVjdGluZyBydWxlcywgb2Zmc2V0IGFuZCBwYWRkaW5nXG4gKlxuICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuU2hhcGU+fSBlbGVtZW50c1xuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV8c3RyaW5nfSB0YXJnZXR8dGFyZ2V0SWRcbiAqL1xuQXV0b1Jlc2l6ZS5wcm90b3R5cGUuX2V4cGFuZCA9IGZ1bmN0aW9uKGVsZW1lbnRzLCB0YXJnZXQpIHtcblxuICBpZiAodHlwZW9mIHRhcmdldCA9PT0gJ3N0cmluZycpIHtcbiAgICB0YXJnZXQgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0KHRhcmdldCk7XG4gIH1cblxuICB2YXIgYWxsb3dlZCA9IHRoaXMuX3J1bGVzLmFsbG93ZWQoJ2VsZW1lbnQuYXV0b1Jlc2l6ZScsIHtcbiAgICBlbGVtZW50czogZWxlbWVudHMsXG4gICAgdGFyZ2V0OiB0YXJnZXRcbiAgfSk7XG5cbiAgaWYgKCFhbGxvd2VkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gY2FsY3VsYXRlIHRoZSBuZXcgYm91bmRzXG4gIHZhciBuZXdCb3VuZHMgPSB0aGlzLl9nZXRPcHRpbWFsQm91bmRzKGVsZW1lbnRzLCB0YXJnZXQpO1xuXG4gIGlmICghYm91bmRzQ2hhbmdlZChuZXdCb3VuZHMsIHRhcmdldCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgcmVzaXplRGlyZWN0aW9ucyA9IGdldFJlc2l6ZURpcmVjdGlvbnMocGljayh0YXJnZXQsIFsgJ3gnLCAneScsICd3aWR0aCcsICdoZWlnaHQnIF0pLCBuZXdCb3VuZHMpO1xuXG4gIC8vIHJlc2l6ZSB0aGUgcGFyZW50IHNoYXBlXG4gIHRoaXMucmVzaXplKHRhcmdldCwgbmV3Qm91bmRzLCB7XG4gICAgYXV0b1Jlc2l6ZTogcmVzaXplRGlyZWN0aW9uc1xuICB9KTtcblxuICB2YXIgcGFyZW50ID0gdGFyZ2V0LnBhcmVudDtcblxuICAvLyByZWN1cnNpdmVseSBleHBhbmQgcGFyZW50IGVsZW1lbnRzXG4gIGlmIChwYXJlbnQpIHtcbiAgICB0aGlzLl9leHBhbmQoWyB0YXJnZXQgXSwgcGFyZW50KTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEdldCB0aGUgYW1vdW50IHRvIGV4cGFuZCB0aGUgZ2l2ZW4gc2hhcGUgaW4gZWFjaCBkaXJlY3Rpb24uXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHNoYXBlXG4gKlxuICogQHJldHVybiB7VFJCTH1cbiAqL1xuQXV0b1Jlc2l6ZS5wcm90b3R5cGUuZ2V0T2Zmc2V0ID0gZnVuY3Rpb24oc2hhcGUpIHtcbiAgcmV0dXJuIHsgdG9wOiA2MCwgYm90dG9tOiA2MCwgbGVmdDogMTAwLCByaWdodDogMTAwIH07XG59O1xuXG5cbi8qKlxuICogR2V0IHRoZSBhY3RpdmF0aW9uIHRocmVzaG9sZCBmb3IgZWFjaCBzaWRlIGZvciB3aGljaFxuICogcmVzaXplIHRyaWdnZXJzLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICpcbiAqIEByZXR1cm4ge1RSQkx9XG4gKi9cbkF1dG9SZXNpemUucHJvdG90eXBlLmdldFBhZGRpbmcgPSBmdW5jdGlvbihzaGFwZSkge1xuICByZXR1cm4geyB0b3A6IDIsIGJvdHRvbTogMiwgbGVmdDogMTUsIHJpZ2h0OiAxNSB9O1xufTtcblxuXG4vKipcbiAqIFBlcmZvcm0gdGhlIGFjdHVhbCByZXNpemUgb3BlcmF0aW9uLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICogQHBhcmFtIHtCb3VuZHN9IG5ld0JvdW5kc1xuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7c3RyaW5nfSBbaGludHMuYXV0b1Jlc2l6ZV1cbiAqL1xuQXV0b1Jlc2l6ZS5wcm90b3R5cGUucmVzaXplID0gZnVuY3Rpb24oc2hhcGUsIG5ld0JvdW5kcywgaGludHMpIHtcbiAgdGhpcy5fbW9kZWxpbmcucmVzaXplU2hhcGUoc2hhcGUsIG5ld0JvdW5kcywgbnVsbCwgaGludHMpO1xufTtcblxuXG5mdW5jdGlvbiBib3VuZHNDaGFuZ2VkKG5ld0JvdW5kcywgb2xkQm91bmRzKSB7XG4gIHJldHVybiAoXG4gICAgbmV3Qm91bmRzLnggIT09IG9sZEJvdW5kcy54IHx8XG4gICAgbmV3Qm91bmRzLnkgIT09IG9sZEJvdW5kcy55IHx8XG4gICAgbmV3Qm91bmRzLndpZHRoICE9PSBvbGRCb3VuZHMud2lkdGggfHxcbiAgICBuZXdCb3VuZHMuaGVpZ2h0ICE9PSBvbGRCb3VuZHMuaGVpZ2h0XG4gICk7XG59XG5cbi8qKlxuICogR2V0IGRpcmVjdGlvbnMgb2YgcmVzaXplIGFzIHtufHd8c3xlfSBlLmcuIFwibndcIi5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc30gb2xkQm91bmRzXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXG4gKlxuICogQHJldHVybnMge3N0cmluZ30gUmVzaXplIGRpcmVjdGlvbnMgYXMge258d3xzfGV9LlxuICovXG5mdW5jdGlvbiBnZXRSZXNpemVEaXJlY3Rpb25zKG9sZEJvdW5kcywgbmV3Qm91bmRzKSB7XG4gIHZhciBkaXJlY3Rpb25zID0gJyc7XG5cbiAgb2xkQm91bmRzID0gYXNUUkJMKG9sZEJvdW5kcyk7XG4gIG5ld0JvdW5kcyA9IGFzVFJCTChuZXdCb3VuZHMpO1xuXG4gIGlmIChvbGRCb3VuZHMudG9wID4gbmV3Qm91bmRzLnRvcCkge1xuICAgIGRpcmVjdGlvbnMgPSBkaXJlY3Rpb25zLmNvbmNhdCgnbicpO1xuICB9XG5cbiAgaWYgKG9sZEJvdW5kcy5yaWdodCA8IG5ld0JvdW5kcy5yaWdodCkge1xuICAgIGRpcmVjdGlvbnMgPSBkaXJlY3Rpb25zLmNvbmNhdCgndycpO1xuICB9XG5cbiAgaWYgKG9sZEJvdW5kcy5ib3R0b20gPCBuZXdCb3VuZHMuYm90dG9tKSB7XG4gICAgZGlyZWN0aW9ucyA9IGRpcmVjdGlvbnMuY29uY2F0KCdzJyk7XG4gIH1cblxuICBpZiAob2xkQm91bmRzLmxlZnQgPiBuZXdCb3VuZHMubGVmdCkge1xuICAgIGRpcmVjdGlvbnMgPSBkaXJlY3Rpb25zLmNvbmNhdCgnZScpO1xuICB9XG5cbiAgcmV0dXJuIGRpcmVjdGlvbnM7XG59IiwiaW1wb3J0IFJ1bGVQcm92aWRlciBmcm9tICcuLi9ydWxlcy9SdWxlUHJvdmlkZXInO1xuXG5pbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG4vKipcbiAqIFRoaXMgaXMgYSBiYXNlIHJ1bGUgcHJvdmlkZXIgZm9yIHRoZSBlbGVtZW50LmF1dG9SZXNpemUgcnVsZS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1Jlc2l6ZVByb3ZpZGVyKGV2ZW50QnVzKSB7XG5cbiAgUnVsZVByb3ZpZGVyLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLmFkZFJ1bGUoJ2VsZW1lbnQuYXV0b1Jlc2l6ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICByZXR1cm4gc2VsZi5jYW5SZXNpemUoY29udGV4dC5lbGVtZW50cywgY29udGV4dC50YXJnZXQpO1xuICB9KTtcbn1cblxuQXV0b1Jlc2l6ZVByb3ZpZGVyLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTtcblxuaW5oZXJpdHMoQXV0b1Jlc2l6ZVByb3ZpZGVyLCBSdWxlUHJvdmlkZXIpO1xuXG4vKipcbiAqIE5lZWRzIHRvIGJlIGltcGxlbWVudGVkIGJ5IHN1YiBjbGFzc2VzIHRvIGFsbG93IGFjdHVhbCBhdXRvIHJlc2l6ZVxuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuU2hhcGV9IHRhcmdldFxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbkF1dG9SZXNpemVQcm92aWRlci5wcm90b3R5cGUuY2FuUmVzaXplID0gZnVuY3Rpb24oZWxlbWVudHMsIHRhcmdldCkge1xuICByZXR1cm4gZmFsc2U7XG59OyIsImltcG9ydCB7IGFzc2lnbiB9IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgdG9Qb2ludFxufSBmcm9tICcuLi8uLi91dGlsL0V2ZW50JztcblxuXG4vKipcbiAqIEluaXRpYXRlcyBjYW52YXMgc2Nyb2xsaW5nIGlmIGN1cnJlbnQgY3Vyc29yIHBvaW50IGlzIGNsb3NlIHRvIGEgYm9yZGVyLlxuICogQ2FuY2VsbGVkIHdoZW4gY3VycmVudCBwb2ludCBtb3ZlcyBiYWNrIGluc2lkZSB0aGUgc2Nyb2xsaW5nIGJvcmRlcnNcbiAqIG9yIGNhbmNlbGxlZCBtYW51YWxseS5cbiAqXG4gKiBEZWZhdWx0IG9wdGlvbnMgOlxuICogICBzY3JvbGxUaHJlc2hvbGRJbjogWyAyMCwgMjAsIDIwLCAyMCBdLFxuICogICBzY3JvbGxUaHJlc2hvbGRPdXQ6IFsgMCwgMCwgMCwgMCBdLFxuICogICBzY3JvbGxSZXBlYXRUaW1lb3V0OiAxNSxcbiAqICAgc2Nyb2xsU3RlcDogMTBcbiAqXG4gKiBUaHJlc2hvbGQgb3JkZXI6XG4gKiAgIFsgbGVmdCwgdG9wLCByaWdodCwgYm90dG9tIF1cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXV0b1Njcm9sbChjb25maWcsIGV2ZW50QnVzLCBjYW52YXMpIHtcblxuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG5cbiAgdGhpcy5fb3B0cyA9IGFzc2lnbih7XG4gICAgc2Nyb2xsVGhyZXNob2xkSW46IFsgMjAsIDIwLCAyMCwgMjAgXSxcbiAgICBzY3JvbGxUaHJlc2hvbGRPdXQ6IFsgMCwgMCwgMCwgMCBdLFxuICAgIHNjcm9sbFJlcGVhdFRpbWVvdXQ6IDE1LFxuICAgIHNjcm9sbFN0ZXA6IDEwXG4gIH0sIGNvbmZpZyk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGV2ZW50QnVzLm9uKCdkcmFnLm1vdmUnLCBmdW5jdGlvbihlKSB7XG4gICAgdmFyIHBvaW50ID0gc2VsZi5fdG9Cb3JkZXJQb2ludChlKTtcblxuICAgIHNlbGYuc3RhcnRTY3JvbGwocG9pbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdkcmFnLmNsZWFudXAnIF0sIGZ1bmN0aW9uKCkge1xuICAgIHNlbGYuc3RvcFNjcm9sbCgpO1xuICB9KTtcbn1cblxuQXV0b1Njcm9sbC4kaW5qZWN0ID0gW1xuICAnY29uZmlnLmF1dG9TY3JvbGwnLFxuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJ1xuXTtcblxuXG4vKipcbiAqIFN0YXJ0cyBzY3JvbGxpbmcgbG9vcC5cbiAqIFBvaW50IGlzIGdpdmVuIGluIGdsb2JhbCBzY2FsZSBpbiBjYW52YXMgY29udGFpbmVyIGJveCBwbGFuZS5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IHBvaW50IHsgeDogWCwgeTogWSB9XG4gKi9cbkF1dG9TY3JvbGwucHJvdG90eXBlLnN0YXJ0U2Nyb2xsID0gZnVuY3Rpb24ocG9pbnQpIHtcblxuICB2YXIgY2FudmFzID0gdGhpcy5fY2FudmFzO1xuICB2YXIgb3B0cyA9IHRoaXMuX29wdHM7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgY2xpZW50UmVjdCA9IGNhbnZhcy5nZXRDb250YWluZXIoKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICB2YXIgZGlmZiA9IFtcbiAgICBwb2ludC54LFxuICAgIHBvaW50LnksXG4gICAgY2xpZW50UmVjdC53aWR0aCAtIHBvaW50LngsXG4gICAgY2xpZW50UmVjdC5oZWlnaHQgLSBwb2ludC55XG4gIF07XG5cbiAgdGhpcy5zdG9wU2Nyb2xsKCk7XG5cbiAgdmFyIGR4ID0gMCxcbiAgICAgIGR5ID0gMDtcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykge1xuICAgIGlmIChiZXR3ZWVuKGRpZmZbaV0sIG9wdHMuc2Nyb2xsVGhyZXNob2xkT3V0W2ldLCBvcHRzLnNjcm9sbFRocmVzaG9sZEluW2ldKSkge1xuICAgICAgaWYgKGkgPT09IDApIHtcbiAgICAgICAgZHggPSBvcHRzLnNjcm9sbFN0ZXA7XG4gICAgICB9IGVsc2UgaWYgKGkgPT0gMSkge1xuICAgICAgICBkeSA9IG9wdHMuc2Nyb2xsU3RlcDtcbiAgICAgIH0gZWxzZSBpZiAoaSA9PSAyKSB7XG4gICAgICAgIGR4ID0gLW9wdHMuc2Nyb2xsU3RlcDtcbiAgICAgIH0gZWxzZSBpZiAoaSA9PSAzKSB7XG4gICAgICAgIGR5ID0gLW9wdHMuc2Nyb2xsU3RlcDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBpZiAoZHggIT09IDAgfHwgZHkgIT09IDApIHtcbiAgICBjYW52YXMuc2Nyb2xsKHsgZHg6IGR4LCBkeTogZHkgfSk7XG5cbiAgICB0aGlzLl9zY3JvbGxpbmcgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgc2VsZi5zdGFydFNjcm9sbChwb2ludCk7XG4gICAgfSwgb3B0cy5zY3JvbGxSZXBlYXRUaW1lb3V0KTtcbiAgfVxufTtcblxuZnVuY3Rpb24gYmV0d2Vlbih2YWwsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0IDwgdmFsICYmIHZhbCA8IGVuZCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5cbi8qKlxuICogU3RvcHMgc2Nyb2xsaW5nIGxvb3AuXG4gKi9cbkF1dG9TY3JvbGwucHJvdG90eXBlLnN0b3BTY3JvbGwgPSBmdW5jdGlvbigpIHtcbiAgY2xlYXJUaW1lb3V0KHRoaXMuX3Njcm9sbGluZyk7XG59O1xuXG5cbi8qKlxuICogT3ZlcnJpZGVzIGRlZmF1bHRzIG9wdGlvbnMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gKi9cbkF1dG9TY3JvbGwucHJvdG90eXBlLnNldE9wdGlvbnMgPSBmdW5jdGlvbihvcHRpb25zKSB7XG4gIHRoaXMuX29wdHMgPSBhc3NpZ24oe30sIHRoaXMuX29wdHMsIG9wdGlvbnMpO1xufTtcblxuXG4vKipcbiAqIENvbnZlcnRzIGV2ZW50IHRvIGEgcG9pbnQgaW4gY2FudmFzIGNvbnRhaW5lciBwbGFuZSBpbiBnbG9iYWwgc2NhbGUuXG4gKlxuICogQHBhcmFtICB7RXZlbnR9IGV2ZW50XG4gKiBAcmV0dXJuIHtQb2ludH1cbiAqL1xuQXV0b1Njcm9sbC5wcm90b3R5cGUuX3RvQm9yZGVyUG9pbnQgPSBmdW5jdGlvbihldmVudCkge1xuICB2YXIgY2xpZW50UmVjdCA9IHRoaXMuX2NhbnZhcy5fY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gIHZhciBnbG9iYWxQb3NpdGlvbiA9IHRvUG9pbnQoZXZlbnQub3JpZ2luYWxFdmVudCk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBnbG9iYWxQb3NpdGlvbi54IC0gY2xpZW50UmVjdC5sZWZ0LFxuICAgIHk6IGdsb2JhbFBvc2l0aW9uLnkgLSBjbGllbnRSZWN0LnRvcFxuICB9O1xufTsiLCJpbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuXG5pbXBvcnQgQXV0b1Njcm9sbCBmcm9tICcuL0F1dG9TY3JvbGwnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBEcmFnZ2luZ01vZHVsZSxcbiAgXSxcbiAgX19pbml0X186IFsgJ2F1dG9TY3JvbGwnIF0sXG4gIGF1dG9TY3JvbGw6IFsgJ3R5cGUnLCBBdXRvU2Nyb2xsIF1cbn07IiwiaW1wb3J0IHsgZmlsdGVyUmVkdW5kYW50V2F5cG9pbnRzIH0gZnJvbSAnLi4vLi4vbGF5b3V0L0xheW91dFV0aWwnO1xuXG52YXIgcm91bmQgPSBNYXRoLnJvdW5kO1xuXG52YXIgUkVDT05ORUNUX1NUQVJUID0gJ3JlY29ubmVjdFN0YXJ0JyxcbiAgICBSRUNPTk5FQ1RfRU5EID0gJ3JlY29ubmVjdEVuZCcsXG4gICAgVVBEQVRFX1dBWVBPSU5UUyA9ICd1cGRhdGVXYXlwb2ludHMnO1xuXG5cbi8qKlxuICogTW92ZSBiZW5kcG9pbnRzIHRocm91Z2ggZHJhZyBhbmQgZHJvcCB0byBhZGQvcmVtb3ZlIGJlbmRwb2ludHMgb3IgcmVjb25uZWN0IGNvbm5lY3Rpb24uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEJlbmRwb2ludE1vdmUoaW5qZWN0b3IsIGV2ZW50QnVzLCBjYW52YXMsIGRyYWdnaW5nLCBydWxlcywgbW9kZWxpbmcpIHtcbiAgdGhpcy5faW5qZWN0b3IgPSBpbmplY3RvcjtcblxuICB0aGlzLnN0YXJ0ID0gZnVuY3Rpb24oZXZlbnQsIGNvbm5lY3Rpb24sIGJlbmRwb2ludEluZGV4LCBpbnNlcnQpIHtcbiAgICB2YXIgZ2Z4ID0gY2FudmFzLmdldEdyYXBoaWNzKGNvbm5lY3Rpb24pLFxuICAgICAgICBzb3VyY2UgPSBjb25uZWN0aW9uLnNvdXJjZSxcbiAgICAgICAgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIHdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzLFxuICAgICAgICB0eXBlO1xuXG4gICAgaWYgKCFpbnNlcnQgJiYgYmVuZHBvaW50SW5kZXggPT09IDApIHtcbiAgICAgIHR5cGUgPSBSRUNPTk5FQ1RfU1RBUlQ7XG4gICAgfSBlbHNlXG4gICAgaWYgKCFpbnNlcnQgJiYgYmVuZHBvaW50SW5kZXggPT09IHdheXBvaW50cy5sZW5ndGggLSAxKSB7XG4gICAgICB0eXBlID0gUkVDT05ORUNUX0VORDtcbiAgICB9IGVsc2Uge1xuICAgICAgdHlwZSA9IFVQREFURV9XQVlQT0lOVFM7XG4gICAgfVxuXG4gICAgdmFyIGNvbW1hbmQgPSB0eXBlID09PSBVUERBVEVfV0FZUE9JTlRTID8gJ2Nvbm5lY3Rpb24udXBkYXRlV2F5cG9pbnRzJyA6ICdjb25uZWN0aW9uLnJlY29ubmVjdCc7XG5cbiAgICB2YXIgYWxsb3dlZCA9IHJ1bGVzLmFsbG93ZWQoY29tbWFuZCwge1xuICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICB9KTtcblxuICAgIGlmIChhbGxvd2VkID09PSBmYWxzZSkge1xuICAgICAgYWxsb3dlZCA9IHJ1bGVzLmFsbG93ZWQoY29tbWFuZCwge1xuICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgICAgICBzb3VyY2U6IHRhcmdldCxcbiAgICAgICAgdGFyZ2V0OiBzb3VyY2VcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChhbGxvd2VkID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGRyYWdnaW5nLmluaXQoZXZlbnQsICdiZW5kcG9pbnQubW92ZScsIHtcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgICAgY29ubmVjdGlvbkdmeDogZ2Z4LFxuICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgYWxsb3dlZDogYWxsb3dlZCxcbiAgICAgICAgICBiZW5kcG9pbnRJbmRleDogYmVuZHBvaW50SW5kZXgsXG4gICAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgICAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICAgICAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICAgICAgICBpbnNlcnQ6IGluc2VydCxcbiAgICAgICAgICB0eXBlOiB0eXBlXG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICBldmVudEJ1cy5vbignYmVuZHBvaW50Lm1vdmUuaG92ZXInLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0LFxuICAgICAgICBob3ZlciA9IGV2ZW50LmhvdmVyLFxuICAgICAgICB0eXBlID0gY29udGV4dC50eXBlO1xuXG4gICAgLy8gY2FjaGUgaG92ZXIgc3RhdGVcbiAgICBjb250ZXh0LmhvdmVyID0gaG92ZXI7XG5cbiAgICB2YXIgYWxsb3dlZDtcblxuICAgIGlmICghaG92ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgY29tbWFuZCA9IHR5cGUgPT09IFVQREFURV9XQVlQT0lOVFMgPyAnY29ubmVjdGlvbi51cGRhdGVXYXlwb2ludHMnIDogJ2Nvbm5lY3Rpb24ucmVjb25uZWN0JztcblxuICAgIGFsbG93ZWQgPSBjb250ZXh0LmFsbG93ZWQgPSBydWxlcy5hbGxvd2VkKGNvbW1hbmQsIHtcbiAgICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgICBzb3VyY2U6IHR5cGUgPT09IFJFQ09OTkVDVF9TVEFSVCA/IGhvdmVyIDogc291cmNlLFxuICAgICAgdGFyZ2V0OiB0eXBlID09PSBSRUNPTk5FQ1RfRU5EID8gaG92ZXIgOiB0YXJnZXRcbiAgICB9KTtcblxuICAgIGlmIChhbGxvd2VkKSB7XG4gICAgICBjb250ZXh0LnNvdXJjZSA9IHR5cGUgPT09IFJFQ09OTkVDVF9TVEFSVCA/IGhvdmVyIDogc291cmNlO1xuICAgICAgY29udGV4dC50YXJnZXQgPSB0eXBlID09PSBSRUNPTk5FQ1RfRU5EID8gaG92ZXIgOiB0YXJnZXQ7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoYWxsb3dlZCA9PT0gZmFsc2UpIHtcbiAgICAgIGFsbG93ZWQgPSBjb250ZXh0LmFsbG93ZWQgPSBydWxlcy5hbGxvd2VkKGNvbW1hbmQsIHtcbiAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgICAgc291cmNlOiB0eXBlID09PSBSRUNPTk5FQ1RfRU5EID8gaG92ZXIgOiB0YXJnZXQsXG4gICAgICAgIHRhcmdldDogdHlwZSA9PT0gUkVDT05ORUNUX1NUQVJUID8gaG92ZXIgOiBzb3VyY2VcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChhbGxvd2VkKSB7XG4gICAgICBjb250ZXh0LnNvdXJjZSA9IHR5cGUgPT09IFJFQ09OTkVDVF9FTkQgPyBob3ZlciA6IHRhcmdldDtcbiAgICAgIGNvbnRleHQudGFyZ2V0ID0gdHlwZSA9PT0gUkVDT05ORUNUX1NUQVJUID8gaG92ZXIgOiBzb3VyY2U7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdiZW5kcG9pbnQubW92ZS5vdXQnLCAnYmVuZHBvaW50Lm1vdmUuY2xlYW51cCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQ7XG5cbiAgICBjb250ZXh0LmhvdmVyID0gbnVsbDtcbiAgICBjb250ZXh0LnNvdXJjZSA9IG51bGw7XG4gICAgY29udGV4dC50YXJnZXQgPSBudWxsO1xuXG4gICAgY29udGV4dC5hbGxvd2VkID0gZmFsc2U7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdiZW5kcG9pbnQubW92ZS5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgYWxsb3dlZCA9IGNvbnRleHQuYWxsb3dlZCxcbiAgICAgICAgYmVuZHBvaW50SW5kZXggPSBjb250ZXh0LmJlbmRwb2ludEluZGV4LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBpbnNlcnQgPSBjb250ZXh0Lmluc2VydCxcbiAgICAgICAgbmV3V2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHMuc2xpY2UoKSxcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICB0eXBlID0gY29udGV4dC50eXBlLFxuICAgICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgICAvLyBlbnN1cmUgaW50ZWdlciB2YWx1ZXMgKGltcG9ydGFudCBpZiB6b29tIGxldmVsIHdhcyA+IDEgZHVyaW5nIG1vdmUpXG4gICAgdmFyIGRvY2tpbmcgPSB7XG4gICAgICB4OiByb3VuZChldmVudC54KSxcbiAgICAgIHk6IHJvdW5kKGV2ZW50LnkpXG4gICAgfTtcblxuICAgIGlmICghYWxsb3dlZCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0eXBlID09PSBVUERBVEVfV0FZUE9JTlRTKSB7XG4gICAgICBpZiAoaW5zZXJ0KSB7XG5cbiAgICAgICAgLy8gaW5zZXJ0IG5ldyBiZW5kcG9pbnRcbiAgICAgICAgbmV3V2F5cG9pbnRzLnNwbGljZShiZW5kcG9pbnRJbmRleCwgMCwgZG9ja2luZyk7XG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIC8vIHN3YXAgcHJldmlvdXMgd2F5cG9pbnQgd2l0aCBtb3ZlZCBvbmVcbiAgICAgICAgbmV3V2F5cG9pbnRzW2JlbmRwb2ludEluZGV4XSA9IGRvY2tpbmc7XG4gICAgICB9XG5cbiAgICAgIC8vIHBhc3MgaGludHMgYWJvdXQgYWN0dWFsIG1vdmVkIGJlbmRwb2ludFxuICAgICAgLy8gdXNlZnVsIGZvciBjb25uZWN0aW9uL2xhYmVsIGxheW91dFxuICAgICAgaGludHMuYmVuZHBvaW50TW92ZSA9IHtcbiAgICAgICAgaW5zZXJ0OiBpbnNlcnQsXG4gICAgICAgIGJlbmRwb2ludEluZGV4OiBiZW5kcG9pbnRJbmRleFxuICAgICAgfTtcblxuICAgICAgbmV3V2F5cG9pbnRzID0gdGhpcy5jcm9wV2F5cG9pbnRzKGNvbm5lY3Rpb24sIG5ld1dheXBvaW50cyk7XG5cbiAgICAgIG1vZGVsaW5nLnVwZGF0ZVdheXBvaW50cyhjb25uZWN0aW9uLCBmaWx0ZXJSZWR1bmRhbnRXYXlwb2ludHMobmV3V2F5cG9pbnRzKSwgaGludHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodHlwZSA9PT0gUkVDT05ORUNUX1NUQVJUKSB7XG4gICAgICAgIGhpbnRzLmRvY2tpbmcgPSAnc291cmNlJztcblxuICAgICAgICBpZiAoaXNSZXZlcnNlKGNvbnRleHQpKSB7XG4gICAgICAgICAgaGludHMuZG9ja2luZyA9ICd0YXJnZXQnO1xuXG4gICAgICAgICAgaGludHMubmV3V2F5cG9pbnRzID0gbmV3V2F5cG9pbnRzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBSRUNPTk5FQ1RfRU5EKSB7XG4gICAgICAgIGhpbnRzLmRvY2tpbmcgPSAndGFyZ2V0JztcblxuICAgICAgICBpZiAoaXNSZXZlcnNlKGNvbnRleHQpKSB7XG4gICAgICAgICAgaGludHMuZG9ja2luZyA9ICdzb3VyY2UnO1xuXG4gICAgICAgICAgaGludHMubmV3V2F5cG9pbnRzID0gbmV3V2F5cG9pbnRzLnJldmVyc2UoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBtb2RlbGluZy5yZWNvbm5lY3QoY29ubmVjdGlvbiwgc291cmNlLCB0YXJnZXQsIGRvY2tpbmcsIGhpbnRzKTtcbiAgICB9XG4gIH0sIHRoaXMpO1xufVxuXG5CZW5kcG9pbnRNb3ZlLiRpbmplY3QgPSBbXG4gICdpbmplY3RvcicsXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnLFxuICAnZHJhZ2dpbmcnLFxuICAncnVsZXMnLFxuICAnbW9kZWxpbmcnXG5dO1xuXG5CZW5kcG9pbnRNb3ZlLnByb3RvdHlwZS5jcm9wV2F5cG9pbnRzID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgbmV3V2F5cG9pbnRzKSB7XG4gIHZhciBjb25uZWN0aW9uRG9ja2luZyA9IHRoaXMuX2luamVjdG9yLmdldCgnY29ubmVjdGlvbkRvY2tpbmcnLCBmYWxzZSk7XG5cbiAgaWYgKCFjb25uZWN0aW9uRG9ja2luZykge1xuICAgIHJldHVybiBuZXdXYXlwb2ludHM7XG4gIH1cblxuICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG5cbiAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBuZXdXYXlwb2ludHM7XG5cbiAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBjb25uZWN0aW9uRG9ja2luZy5nZXRDcm9wcGVkV2F5cG9pbnRzKGNvbm5lY3Rpb24pO1xuXG4gIG5ld1dheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzO1xuXG4gIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gd2F5cG9pbnRzO1xuXG4gIHJldHVybiBuZXdXYXlwb2ludHM7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXZlcnNlKGNvbnRleHQpIHtcbiAgdmFyIGhvdmVyID0gY29udGV4dC5ob3ZlcixcbiAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgdGFyZ2V0ID0gY29udGV4dC50YXJnZXQsXG4gICAgICB0eXBlID0gY29udGV4dC50eXBlO1xuXG4gIGlmICh0eXBlID09PSBSRUNPTk5FQ1RfU1RBUlQpIHtcbiAgICByZXR1cm4gaG92ZXIgJiYgdGFyZ2V0ICYmIGhvdmVyID09PSB0YXJnZXQgJiYgc291cmNlICE9PSB0YXJnZXQ7XG4gIH1cblxuICBpZiAodHlwZSA9PT0gUkVDT05ORUNUX0VORCkge1xuICAgIHJldHVybiBob3ZlciAmJiBzb3VyY2UgJiYgaG92ZXIgPT09IHNvdXJjZSAmJiBzb3VyY2UgIT09IHRhcmdldDtcbiAgfVxufSIsImltcG9ydCB7XG4gIGNsYXNzZXMgYXMgc3ZnQ2xhc3NlcyxcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7IGFkZEJlbmRwb2ludCB9IGZyb20gJy4vQmVuZHBvaW50VXRpbCc7XG5cbmltcG9ydCB7IHRyYW5zbGF0ZSB9IGZyb20gJy4uLy4uL3V0aWwvU3ZnVHJhbnNmb3JtVXRpbCc7XG5cbmltcG9ydCB7IGlzUmV2ZXJzZSB9IGZyb20gJy4vQmVuZHBvaW50TW92ZSc7XG5cbnZhciBSRUNPTk5FQ1RfU1RBUlQgPSAncmVjb25uZWN0U3RhcnQnLFxuICAgIFJFQ09OTkVDVF9FTkQgPSAncmVjb25uZWN0RW5kJyxcbiAgICBVUERBVEVfV0FZUE9JTlRTID0gJ3VwZGF0ZVdheXBvaW50cyc7XG5cbnZhciBNQVJLRVJfT0sgPSAnY29ubmVjdC1vaycsXG4gICAgTUFSS0VSX05PVF9PSyA9ICdjb25uZWN0LW5vdC1vaycsXG4gICAgTUFSS0VSX0NPTk5FQ1RfSE9WRVIgPSAnY29ubmVjdC1ob3ZlcicsXG4gICAgTUFSS0VSX0NPTk5FQ1RfVVBEQVRJTkcgPSAnZGpzLXVwZGF0aW5nJyxcbiAgICBNQVJLRVJfRUxFTUVOVF9ISURERU4gPSAnZGpzLWVsZW1lbnQtaGlkZGVuJztcblxudmFyIEhJR0hfUFJJT1JJVFkgPSAxMTAwO1xuXG4vKipcbiAqIFByZXZpZXcgY29ubmVjdGlvbiB3aGlsZSBtb3ZpbmcgYmVuZHBvaW50cy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmVuZHBvaW50TW92ZVByZXZpZXcoYmVuZHBvaW50TW92ZSwgaW5qZWN0b3IsIGV2ZW50QnVzLCBjYW52YXMpIHtcbiAgdGhpcy5faW5qZWN0b3IgPSBpbmplY3RvcjtcblxuICB2YXIgY29ubmVjdGlvblByZXZpZXcgPSBpbmplY3Rvci5nZXQoJ2Nvbm5lY3Rpb25QcmV2aWV3JywgZmFsc2UpO1xuXG4gIGV2ZW50QnVzLm9uKCdiZW5kcG9pbnQubW92ZS5zdGFydCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBiZW5kcG9pbnRJbmRleCA9IGNvbnRleHQuYmVuZHBvaW50SW5kZXgsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIGluc2VydCA9IGNvbnRleHQuaW5zZXJ0LFxuICAgICAgICB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgICAgbmV3V2F5cG9pbnRzID0gd2F5cG9pbnRzLnNsaWNlKCk7XG5cbiAgICBjb250ZXh0LndheXBvaW50cyA9IHdheXBvaW50cztcblxuICAgIGlmIChpbnNlcnQpIHtcblxuICAgICAgLy8gaW5zZXJ0IHBsYWNlaG9sZGVyIGZvciBuZXcgYmVuZHBvaW50XG4gICAgICBuZXdXYXlwb2ludHMuc3BsaWNlKGJlbmRwb2ludEluZGV4LCAwLCB7IHg6IGV2ZW50LngsIHk6IGV2ZW50LnkgfSk7XG4gICAgfVxuXG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBuZXdXYXlwb2ludHM7XG5cbiAgICAvLyBhZGQgZHJhZ2dlciBnZnhcbiAgICB2YXIgZHJhZ2dlckdmeCA9IGNvbnRleHQuZHJhZ2dlckdmeCA9IGFkZEJlbmRwb2ludChjYW52YXMuZ2V0TGF5ZXIoJ292ZXJsYXlzJykpO1xuXG4gICAgc3ZnQ2xhc3NlcyhkcmFnZ2VyR2Z4KS5hZGQoJ2Rqcy1kcmFnZ2luZycpO1xuXG4gICAgY2FudmFzLmFkZE1hcmtlcihjb25uZWN0aW9uLCBNQVJLRVJfRUxFTUVOVF9ISURERU4pO1xuICAgIGNhbnZhcy5hZGRNYXJrZXIoY29ubmVjdGlvbiwgTUFSS0VSX0NPTk5FQ1RfVVBEQVRJTkcpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignYmVuZHBvaW50Lm1vdmUuaG92ZXInLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgYWxsb3dlZCA9IGNvbnRleHQuYWxsb3dlZCxcbiAgICAgICAgaG92ZXIgPSBjb250ZXh0LmhvdmVyLFxuICAgICAgICB0eXBlID0gY29udGV4dC50eXBlO1xuXG4gICAgaWYgKGhvdmVyKSB7XG4gICAgICBjYW52YXMuYWRkTWFya2VyKGhvdmVyLCBNQVJLRVJfQ09OTkVDVF9IT1ZFUik7XG5cbiAgICAgIGlmICh0eXBlID09PSBVUERBVEVfV0FZUE9JTlRTKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGFsbG93ZWQpIHtcbiAgICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgTUFSS0VSX05PVF9PSyk7XG4gICAgICAgIGNhbnZhcy5hZGRNYXJrZXIoaG92ZXIsIE1BUktFUl9PSyk7XG4gICAgICB9IGVsc2UgaWYgKGFsbG93ZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoaG92ZXIsIE1BUktFUl9PSyk7XG4gICAgICAgIGNhbnZhcy5hZGRNYXJrZXIoaG92ZXIsIE1BUktFUl9OT1RfT0spO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oW1xuICAgICdiZW5kcG9pbnQubW92ZS5vdXQnLFxuICAgICdiZW5kcG9pbnQubW92ZS5jbGVhbnVwJ1xuICBdLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgaG92ZXIgPSBjb250ZXh0LmhvdmVyLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIGlmIChob3Zlcikge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgTUFSS0VSX0NPTk5FQ1RfSE9WRVIpO1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgdGFyZ2V0ID8gTUFSS0VSX09LIDogTUFSS0VSX05PVF9PSyk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignYmVuZHBvaW50Lm1vdmUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBhbGxvd2VkID0gY29udGV4dC5hbGxvd2VkLFxuICAgICAgICBiZW5kcG9pbnRJbmRleCA9IGNvbnRleHQuYmVuZHBvaW50SW5kZXgsXG4gICAgICAgIGRyYWdnZXJHZnggPSBjb250ZXh0LmRyYWdnZXJHZngsXG4gICAgICAgIGhvdmVyID0gY29udGV4dC5ob3ZlcixcbiAgICAgICAgdHlwZSA9IGNvbnRleHQudHlwZSxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgICAgc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0LFxuICAgICAgICBuZXdXYXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cy5zbGljZSgpLFxuICAgICAgICBiZW5kcG9pbnQgPSB7IHg6IGV2ZW50LngsIHk6IGV2ZW50LnkgfSxcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgICBkcmF3UHJldmlld0hpbnRzID0ge307XG5cbiAgICBpZiAoY29ubmVjdGlvblByZXZpZXcpIHtcbiAgICAgIGlmIChoaW50cy5jb25uZWN0aW9uU3RhcnQpIHtcbiAgICAgICAgZHJhd1ByZXZpZXdIaW50cy5jb25uZWN0aW9uU3RhcnQgPSBoaW50cy5jb25uZWN0aW9uU3RhcnQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChoaW50cy5jb25uZWN0aW9uRW5kKSB7XG4gICAgICAgIGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvbkVuZCA9IGhpbnRzLmNvbm5lY3Rpb25FbmQ7XG4gICAgICB9XG5cblxuICAgICAgaWYgKHR5cGUgPT09IFJFQ09OTkVDVF9TVEFSVCkge1xuICAgICAgICBpZiAoaXNSZXZlcnNlKGNvbnRleHQpKSB7XG4gICAgICAgICAgZHJhd1ByZXZpZXdIaW50cy5jb25uZWN0aW9uRW5kID0gZHJhd1ByZXZpZXdIaW50cy5jb25uZWN0aW9uRW5kIHx8IGJlbmRwb2ludDtcblxuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMuc291cmNlID0gdGFyZ2V0O1xuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMudGFyZ2V0ID0gaG92ZXIgfHwgc291cmNlO1xuXG4gICAgICAgICAgbmV3V2F5cG9pbnRzID0gbmV3V2F5cG9pbnRzLnJldmVyc2UoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkcmF3UHJldmlld0hpbnRzLmNvbm5lY3Rpb25TdGFydCA9IGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvblN0YXJ0IHx8IGJlbmRwb2ludDtcblxuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMuc291cmNlID0gaG92ZXIgfHwgc291cmNlO1xuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFJFQ09OTkVDVF9FTkQpIHtcbiAgICAgICAgaWYgKGlzUmV2ZXJzZShjb250ZXh0KSkge1xuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvblN0YXJ0ID0gZHJhd1ByZXZpZXdIaW50cy5jb25uZWN0aW9uU3RhcnQgfHwgYmVuZHBvaW50O1xuXG4gICAgICAgICAgZHJhd1ByZXZpZXdIaW50cy5zb3VyY2UgPSBob3ZlciB8fCB0YXJnZXQ7XG4gICAgICAgICAgZHJhd1ByZXZpZXdIaW50cy50YXJnZXQgPSBzb3VyY2U7XG5cbiAgICAgICAgICBuZXdXYXlwb2ludHMgPSBuZXdXYXlwb2ludHMucmV2ZXJzZSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvbkVuZCA9IGRyYXdQcmV2aWV3SGludHMuY29ubmVjdGlvbkVuZCB8fCBiZW5kcG9pbnQ7XG5cbiAgICAgICAgICBkcmF3UHJldmlld0hpbnRzLnNvdXJjZSA9IHNvdXJjZTtcbiAgICAgICAgICBkcmF3UHJldmlld0hpbnRzLnRhcmdldCA9IGhvdmVyIHx8IHRhcmdldDtcbiAgICAgICAgfVxuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkcmF3UHJldmlld0hpbnRzLm5vQ3JvcHBpbmcgPSB0cnVlO1xuICAgICAgICBkcmF3UHJldmlld0hpbnRzLm5vTGF5b3V0ID0gdHJ1ZTtcbiAgICAgICAgbmV3V2F5cG9pbnRzWyBiZW5kcG9pbnRJbmRleCBdID0gYmVuZHBvaW50O1xuICAgICAgfVxuXG4gICAgICBpZiAodHlwZSA9PT0gVVBEQVRFX1dBWVBPSU5UUykge1xuICAgICAgICBuZXdXYXlwb2ludHMgPSBiZW5kcG9pbnRNb3ZlLmNyb3BXYXlwb2ludHMoY29ubmVjdGlvbiwgbmV3V2F5cG9pbnRzKTtcbiAgICAgIH1cblxuICAgICAgZHJhd1ByZXZpZXdIaW50cy53YXlwb2ludHMgPSBuZXdXYXlwb2ludHM7XG5cbiAgICAgIGNvbm5lY3Rpb25QcmV2aWV3LmRyYXdQcmV2aWV3KGNvbnRleHQsIGFsbG93ZWQsIGRyYXdQcmV2aWV3SGludHMpO1xuICAgIH1cblxuICAgIHRyYW5zbGF0ZShkcmFnZ2VyR2Z4LCBldmVudC54LCBldmVudC55KTtcbiAgfSwgdGhpcyk7XG5cbiAgZXZlbnRCdXMub24oW1xuICAgICdiZW5kcG9pbnQubW92ZS5lbmQnLFxuICAgICdiZW5kcG9pbnQubW92ZS5jYW5jZWwnXG4gIF0sIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBkcmFnZ2VyR2Z4ID0gY29udGV4dC5kcmFnZ2VyR2Z4LFxuICAgICAgICBob3ZlciA9IGNvbnRleHQuaG92ZXIsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICB3YXlwb2ludHMgPSBjb250ZXh0LndheXBvaW50cztcblxuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gd2F5cG9pbnRzO1xuXG4gICAgLy8gcmVtb3ZlIGRyYWdnZXIgZ2Z4XG4gICAgc3ZnUmVtb3ZlKGRyYWdnZXJHZngpO1xuXG4gICAgY2FudmFzLnJlbW92ZU1hcmtlcihjb25uZWN0aW9uLCBNQVJLRVJfQ09OTkVDVF9VUERBVElORyk7XG4gICAgY2FudmFzLnJlbW92ZU1hcmtlcihjb25uZWN0aW9uLCBNQVJLRVJfRUxFTUVOVF9ISURERU4pO1xuXG4gICAgaWYgKGhvdmVyKSB7XG4gICAgICBjYW52YXMucmVtb3ZlTWFya2VyKGhvdmVyLCBNQVJLRVJfT0spO1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgdGFyZ2V0ID8gTUFSS0VSX09LIDogTUFSS0VSX05PVF9PSyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbm5lY3Rpb25QcmV2aWV3KSB7XG4gICAgICBjb25uZWN0aW9uUHJldmlldy5jbGVhblVwKGNvbnRleHQpO1xuICAgIH1cbiAgfSk7XG59XG5cbkJlbmRwb2ludE1vdmVQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdiZW5kcG9pbnRNb3ZlJyxcbiAgJ2luamVjdG9yJyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcydcbl07IiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmb3JFYWNoLFxuICBpc0FycmF5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgc2V0U25hcHBlZCB9IGZyb20gJy4uL3NuYXBwaW5nL1NuYXBVdGlsJztcblxudmFyIGFicz0gTWF0aC5hYnMsXG4gICAgcm91bmQgPSBNYXRoLnJvdW5kO1xuXG52YXIgVE9MRVJBTkNFID0gMTA7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmVuZHBvaW50U25hcHBpbmcoZXZlbnRCdXMpIHtcblxuICBmdW5jdGlvbiBzbmFwVG8odmFsdWVzLCB2YWx1ZSkge1xuXG4gICAgaWYgKGlzQXJyYXkodmFsdWVzKSkge1xuICAgICAgdmFyIGkgPSB2YWx1ZXMubGVuZ3RoO1xuXG4gICAgICB3aGlsZSAoaS0tKSBpZiAoYWJzKHZhbHVlc1tpXSAtIHZhbHVlKSA8PSBUT0xFUkFOQ0UpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlc1tpXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWVzID0gK3ZhbHVlcztcbiAgICAgIHZhciByZW0gPSB2YWx1ZSAlIHZhbHVlcztcblxuICAgICAgaWYgKHJlbSA8IFRPTEVSQU5DRSkge1xuICAgICAgICByZXR1cm4gdmFsdWUgLSByZW07XG4gICAgICB9XG5cbiAgICAgIGlmIChyZW0gPiB2YWx1ZXMgLSBUT0xFUkFOQ0UpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlIC0gcmVtICsgdmFsdWVzO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG1pZChlbGVtZW50KSB7XG4gICAgaWYgKGVsZW1lbnQud2lkdGgpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHg6IHJvdW5kKGVsZW1lbnQud2lkdGggLyAyICsgZWxlbWVudC54KSxcbiAgICAgICAgeTogcm91bmQoZWxlbWVudC5oZWlnaHQgLyAyICsgZWxlbWVudC55KVxuICAgICAgfTtcbiAgICB9XG4gIH1cblxuICAvLyBjb25uZWN0aW9uIHNlZ21lbnQgc25hcHBpbmcgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIGZ1bmN0aW9uIGdldENvbm5lY3Rpb25TZWdtZW50U25hcHMoY29udGV4dCkge1xuXG4gICAgdmFyIHNuYXBQb2ludHMgPSBjb250ZXh0LnNuYXBQb2ludHMsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzLFxuICAgICAgICBzZWdtZW50U3RhcnQgPSBjb250ZXh0LnNlZ21lbnRTdGFydCxcbiAgICAgICAgc2VnbWVudFN0YXJ0SW5kZXggPSBjb250ZXh0LnNlZ21lbnRTdGFydEluZGV4LFxuICAgICAgICBzZWdtZW50RW5kID0gY29udGV4dC5zZWdtZW50RW5kLFxuICAgICAgICBzZWdtZW50RW5kSW5kZXggPSBjb250ZXh0LnNlZ21lbnRFbmRJbmRleCxcbiAgICAgICAgYXhpcyA9IGNvbnRleHQuYXhpcztcblxuICAgIGlmIChzbmFwUG9pbnRzKSB7XG4gICAgICByZXR1cm4gc25hcFBvaW50cztcbiAgICB9XG5cbiAgICB2YXIgcmVmZXJlbmNlV2F5cG9pbnRzID0gW1xuICAgICAgd2F5cG9pbnRzW3NlZ21lbnRTdGFydEluZGV4IC0gMV0sXG4gICAgICBzZWdtZW50U3RhcnQsXG4gICAgICBzZWdtZW50RW5kLFxuICAgICAgd2F5cG9pbnRzW3NlZ21lbnRFbmRJbmRleCArIDFdXG4gICAgXTtcblxuICAgIGlmIChzZWdtZW50U3RhcnRJbmRleCA8IDIpIHtcbiAgICAgIHJlZmVyZW5jZVdheXBvaW50cy51bnNoaWZ0KG1pZChjb25uZWN0aW9uLnNvdXJjZSkpO1xuICAgIH1cblxuICAgIGlmIChzZWdtZW50RW5kSW5kZXggPiB3YXlwb2ludHMubGVuZ3RoIC0gMykge1xuICAgICAgcmVmZXJlbmNlV2F5cG9pbnRzLnVuc2hpZnQobWlkKGNvbm5lY3Rpb24udGFyZ2V0KSk7XG4gICAgfVxuXG4gICAgY29udGV4dC5zbmFwUG9pbnRzID0gc25hcFBvaW50cyA9IHsgaG9yaXpvbnRhbDogW10gLCB2ZXJ0aWNhbDogW10gfTtcblxuICAgIGZvckVhY2gocmVmZXJlbmNlV2F5cG9pbnRzLCBmdW5jdGlvbihwKSB7XG5cbiAgICAgIC8vIHdlIHNuYXAgb24gZXhpc3RpbmcgYmVuZHBvaW50cyBvbmx5LFxuICAgICAgLy8gbm90IHBsYWNlaG9sZGVycyB0aGF0IGFyZSBpbnNlcnRlZCBkdXJpbmcgYWRkXG4gICAgICBpZiAocCkge1xuICAgICAgICBwID0gcC5vcmlnaW5hbCB8fCBwO1xuXG4gICAgICAgIGlmIChheGlzID09PSAneScpIHtcbiAgICAgICAgICBzbmFwUG9pbnRzLmhvcml6b250YWwucHVzaChwLnkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGF4aXMgPT09ICd4Jykge1xuICAgICAgICAgIHNuYXBQb2ludHMudmVydGljYWwucHVzaChwLngpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gc25hcFBvaW50cztcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjb25uZWN0aW9uU2VnbWVudC5tb3ZlLm1vdmUnLCAxNTAwLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc25hcFBvaW50cyA9IGdldENvbm5lY3Rpb25TZWdtZW50U25hcHMoY29udGV4dCksXG4gICAgICAgIHggPSBldmVudC54LFxuICAgICAgICB5ID0gZXZlbnQueSxcbiAgICAgICAgc3gsIHN5O1xuXG4gICAgaWYgKCFzbmFwUG9pbnRzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gc25hcFxuICAgIHN4ID0gc25hcFRvKHNuYXBQb2ludHMudmVydGljYWwsIHgpO1xuICAgIHN5ID0gc25hcFRvKHNuYXBQb2ludHMuaG9yaXpvbnRhbCwgeSk7XG5cblxuICAgIC8vIGNvcnJlY3Rpb24geC95XG4gICAgdmFyIGN4ID0gKHggLSBzeCksXG4gICAgICAgIGN5ID0gKHkgLSBzeSk7XG5cbiAgICAvLyB1cGRhdGUgZGVsdGFcbiAgICBhc3NpZ24oZXZlbnQsIHtcbiAgICAgIGR4OiBldmVudC5keCAtIGN4LFxuICAgICAgZHk6IGV2ZW50LmR5IC0gY3ksXG4gICAgICB4OiBzeCxcbiAgICAgIHk6IHN5XG4gICAgfSk7XG5cbiAgICAvLyBvbmx5IHNldCBzbmFwcGVkIGlmIGFjdHVhbGx5IHNuYXBwZWRcbiAgICBpZiAoY3ggfHwgc25hcFBvaW50cy52ZXJ0aWNhbC5pbmRleE9mKHgpICE9PSAtMSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgJ3gnLCBzeCk7XG4gICAgfVxuXG4gICAgaWYgKGN5IHx8IHNuYXBQb2ludHMuaG9yaXpvbnRhbC5pbmRleE9mKHkpICE9PSAtMSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgJ3knLCBzeSk7XG4gICAgfVxuICB9KTtcblxuXG4gIC8vIGJlbmRwb2ludCBzbmFwcGluZyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgZnVuY3Rpb24gZ2V0QmVuZHBvaW50U25hcHMoY29udGV4dCkge1xuXG4gICAgdmFyIHNuYXBQb2ludHMgPSBjb250ZXh0LnNuYXBQb2ludHMsXG4gICAgICAgIHdheXBvaW50cyA9IGNvbnRleHQuY29ubmVjdGlvbi53YXlwb2ludHMsXG4gICAgICAgIGJlbmRwb2ludEluZGV4ID0gY29udGV4dC5iZW5kcG9pbnRJbmRleDtcblxuICAgIGlmIChzbmFwUG9pbnRzKSB7XG4gICAgICByZXR1cm4gc25hcFBvaW50cztcbiAgICB9XG5cbiAgICB2YXIgcmVmZXJlbmNlV2F5cG9pbnRzID0gWyB3YXlwb2ludHNbYmVuZHBvaW50SW5kZXggLSAxXSwgd2F5cG9pbnRzW2JlbmRwb2ludEluZGV4ICsgMV0gXTtcblxuICAgIGNvbnRleHQuc25hcFBvaW50cyA9IHNuYXBQb2ludHMgPSB7IGhvcml6b250YWw6IFtdICwgdmVydGljYWw6IFtdIH07XG5cbiAgICBmb3JFYWNoKHJlZmVyZW5jZVdheXBvaW50cywgZnVuY3Rpb24ocCkge1xuXG4gICAgICAvLyB3ZSBzbmFwIG9uIGV4aXN0aW5nIGJlbmRwb2ludHMgb25seSxcbiAgICAgIC8vIG5vdCBwbGFjZWhvbGRlcnMgdGhhdCBhcmUgaW5zZXJ0ZWQgZHVyaW5nIGFkZFxuICAgICAgaWYgKHApIHtcbiAgICAgICAgcCA9IHAub3JpZ2luYWwgfHwgcDtcblxuICAgICAgICBzbmFwUG9pbnRzLmhvcml6b250YWwucHVzaChwLnkpO1xuICAgICAgICBzbmFwUG9pbnRzLnZlcnRpY2FsLnB1c2gocC54KTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBzbmFwUG9pbnRzO1xuICB9XG5cblxuICBldmVudEJ1cy5vbihbICdiZW5kcG9pbnQubW92ZS5tb3ZlJywgJ2JlbmRwb2ludC5tb3ZlLmVuZCcgXSwgMTUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgc25hcFBvaW50cyA9IGdldEJlbmRwb2ludFNuYXBzKGNvbnRleHQpLFxuICAgICAgICBob3ZlciA9IGNvbnRleHQuaG92ZXIsXG4gICAgICAgIGhvdmVyTWlkID0gaG92ZXIgJiYgbWlkKGhvdmVyKSxcbiAgICAgICAgeCA9IGV2ZW50LngsXG4gICAgICAgIHkgPSBldmVudC55LFxuICAgICAgICBzeCwgc3k7XG5cbiAgICBpZiAoIXNuYXBQb2ludHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBzbmFwIHRvIGhvdmVyIG1pZFxuICAgIHN4ID0gc25hcFRvKGhvdmVyTWlkID8gc25hcFBvaW50cy52ZXJ0aWNhbC5jb25jYXQoWyBob3Zlck1pZC54IF0pIDogc25hcFBvaW50cy52ZXJ0aWNhbCwgeCk7XG4gICAgc3kgPSBzbmFwVG8oaG92ZXJNaWQgPyBzbmFwUG9pbnRzLmhvcml6b250YWwuY29uY2F0KFsgaG92ZXJNaWQueSBdKSA6IHNuYXBQb2ludHMuaG9yaXpvbnRhbCwgeSk7XG5cbiAgICAvLyBjb3JyZWN0aW9uIHgveVxuICAgIHZhciBjeCA9ICh4IC0gc3gpLFxuICAgICAgICBjeSA9ICh5IC0gc3kpO1xuXG4gICAgLy8gdXBkYXRlIGRlbHRhXG4gICAgYXNzaWduKGV2ZW50LCB7XG4gICAgICBkeDogZXZlbnQuZHggLSBjeCxcbiAgICAgIGR5OiBldmVudC5keSAtIGN5LFxuICAgICAgeDogZXZlbnQueCAtIGN4LFxuICAgICAgeTogZXZlbnQueSAtIGN5XG4gICAgfSk7XG5cbiAgICAvLyBvbmx5IHNldCBzbmFwcGVkIGlmIGFjdHVhbGx5IHNuYXBwZWRcbiAgICBpZiAoY3ggfHwgc25hcFBvaW50cy52ZXJ0aWNhbC5pbmRleE9mKHgpICE9PSAtMSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgJ3gnLCBzeCk7XG4gICAgfVxuXG4gICAgaWYgKGN5IHx8IHNuYXBQb2ludHMuaG9yaXpvbnRhbC5pbmRleE9mKHkpICE9PSAtMSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgJ3knLCBzeSk7XG4gICAgfVxuICB9KTtcbn1cblxuXG5CZW5kcG9pbnRTbmFwcGluZy4kaW5qZWN0ID0gWyAnZXZlbnRCdXMnIF07IiwiaW1wb3J0IHtcbiAgdG9Qb2ludFxufSBmcm9tICcuLi8uLi91dGlsL0V2ZW50JztcblxuaW1wb3J0IHtcbiAgZ2V0TWlkUG9pbnQsXG4gIHBvaW50c0FsaWduZWRcbn0gZnJvbSAnLi4vLi4vdXRpbC9HZW9tZXRyeSc7XG5cbmltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxuaW1wb3J0IHtcbiAgcm90YXRlLFxuICB0cmFuc2xhdGVcbn0gZnJvbSAnLi4vLi4vdXRpbC9TdmdUcmFuc2Zvcm1VdGlsJztcblxuaW1wb3J0IHtcbiAgZ2V0QXBwcm94SW50ZXJzZWN0aW9uXG59IGZyb20gJy4uLy4uL3V0aWwvTGluZUludGVyc2VjdGlvbic7XG5cbmV4cG9ydCB2YXIgQkVORFBPSU5UX0NMUyA9ICdkanMtYmVuZHBvaW50JztcbmV4cG9ydCB2YXIgU0VHTUVOVF9EUkFHR0VSX0NMUyA9ICdkanMtc2VnbWVudC1kcmFnZ2VyJztcblxuZXhwb3J0IGZ1bmN0aW9uIHRvQ2FudmFzQ29vcmRpbmF0ZXMoY2FudmFzLCBldmVudCkge1xuXG4gIHZhciBwb3NpdGlvbiA9IHRvUG9pbnQoZXZlbnQpLFxuICAgICAgY2xpZW50UmVjdCA9IGNhbnZhcy5fY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxuICAgICAgb2Zmc2V0O1xuXG4gIC8vIGNhbnZhcyByZWxhdGl2ZSBwb3NpdGlvblxuXG4gIG9mZnNldCA9IHtcbiAgICB4OiBjbGllbnRSZWN0LmxlZnQsXG4gICAgeTogY2xpZW50UmVjdC50b3BcbiAgfTtcblxuICAvLyB1cGRhdGUgYWN0dWFsIGV2ZW50IHBheWxvYWQgd2l0aCBjYW52YXMgcmVsYXRpdmUgbWVhc3VyZXNcblxuICB2YXIgdmlld2JveCA9IGNhbnZhcy52aWV3Ym94KCk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiB2aWV3Ym94LnggKyAocG9zaXRpb24ueCAtIG9mZnNldC54KSAvIHZpZXdib3guc2NhbGUsXG4gICAgeTogdmlld2JveC55ICsgKHBvc2l0aW9uLnkgLSBvZmZzZXQueSkgLyB2aWV3Ym94LnNjYWxlXG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb25uZWN0aW9uSW50ZXJzZWN0aW9uKGNhbnZhcywgd2F5cG9pbnRzLCBldmVudCkge1xuICB2YXIgbG9jYWxQb3NpdGlvbiA9IHRvQ2FudmFzQ29vcmRpbmF0ZXMoY2FudmFzLCBldmVudCksXG4gICAgICBpbnRlcnNlY3Rpb24gPSBnZXRBcHByb3hJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCBsb2NhbFBvc2l0aW9uKTtcblxuICByZXR1cm4gaW50ZXJzZWN0aW9uO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYWRkQmVuZHBvaW50KHBhcmVudEdmeCwgY2xzKSB7XG4gIHZhciBncm91cEdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuICBzdmdDbGFzc2VzKGdyb3VwR2Z4KS5hZGQoQkVORFBPSU5UX0NMUyk7XG5cbiAgc3ZnQXBwZW5kKHBhcmVudEdmeCwgZ3JvdXBHZngpO1xuXG4gIHZhciB2aXN1YWwgPSBzdmdDcmVhdGUoJ2NpcmNsZScpO1xuICBzdmdBdHRyKHZpc3VhbCwge1xuICAgIGN4OiAwLFxuICAgIGN5OiAwLFxuICAgIHI6IDRcbiAgfSk7XG4gIHN2Z0NsYXNzZXModmlzdWFsKS5hZGQoJ2Rqcy12aXN1YWwnKTtcblxuICBzdmdBcHBlbmQoZ3JvdXBHZngsIHZpc3VhbCk7XG5cbiAgdmFyIGhpdCA9IHN2Z0NyZWF0ZSgnY2lyY2xlJyk7XG4gIHN2Z0F0dHIoaGl0LCB7XG4gICAgY3g6IDAsXG4gICAgY3k6IDAsXG4gICAgcjogMTBcbiAgfSk7XG4gIHN2Z0NsYXNzZXMoaGl0KS5hZGQoJ2Rqcy1oaXQnKTtcblxuICBzdmdBcHBlbmQoZ3JvdXBHZngsIGhpdCk7XG5cbiAgaWYgKGNscykge1xuICAgIHN2Z0NsYXNzZXMoZ3JvdXBHZngpLmFkZChjbHMpO1xuICB9XG5cbiAgcmV0dXJuIGdyb3VwR2Z4O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVQYXJhbGxlbERyYWdnZXIocGFyZW50R2Z4LCBzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQsIGFsaWdubWVudCkge1xuICB2YXIgZHJhZ2dlckdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuXG4gIHN2Z0FwcGVuZChwYXJlbnRHZngsIGRyYWdnZXJHZngpO1xuXG4gIHZhciB3aWR0aCA9IDE0LFxuICAgICAgaGVpZ2h0ID0gMyxcbiAgICAgIHBhZGRpbmcgPSAxMSxcbiAgICAgIGhpdFdpZHRoID0gY2FsY3VsYXRlSGl0V2lkdGgoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kLCBhbGlnbm1lbnQpLFxuICAgICAgaGl0SGVpZ2h0ID0gaGVpZ2h0ICsgcGFkZGluZztcblxuICB2YXIgdmlzdWFsID0gc3ZnQ3JlYXRlKCdyZWN0Jyk7XG4gIHN2Z0F0dHIodmlzdWFsLCB7XG4gICAgeDogLXdpZHRoIC8gMixcbiAgICB5OiAtaGVpZ2h0IC8gMixcbiAgICB3aWR0aDogd2lkdGgsXG4gICAgaGVpZ2h0OiBoZWlnaHRcbiAgfSk7XG4gIHN2Z0NsYXNzZXModmlzdWFsKS5hZGQoJ2Rqcy12aXN1YWwnKTtcblxuICBzdmdBcHBlbmQoZHJhZ2dlckdmeCwgdmlzdWFsKTtcblxuICB2YXIgaGl0ID0gc3ZnQ3JlYXRlKCdyZWN0Jyk7XG4gIHN2Z0F0dHIoaGl0LCB7XG4gICAgeDogLWhpdFdpZHRoIC8gMixcbiAgICB5OiAtaGl0SGVpZ2h0IC8gMixcbiAgICB3aWR0aDogaGl0V2lkdGgsXG4gICAgaGVpZ2h0OiBoaXRIZWlnaHRcbiAgfSk7XG4gIHN2Z0NsYXNzZXMoaGl0KS5hZGQoJ2Rqcy1oaXQnKTtcblxuICBzdmdBcHBlbmQoZHJhZ2dlckdmeCwgaGl0KTtcblxuICByb3RhdGUoZHJhZ2dlckdmeCwgYWxpZ25tZW50ID09PSAndicgPyA5MCA6IDAsIDAsIDApO1xuXG4gIHJldHVybiBkcmFnZ2VyR2Z4O1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRTZWdtZW50RHJhZ2dlcihwYXJlbnRHZngsIHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCkge1xuXG4gIHZhciBncm91cEdmeCA9IHN2Z0NyZWF0ZSgnZycpLFxuICAgICAgbWlkID0gZ2V0TWlkUG9pbnQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKSxcbiAgICAgIGFsaWdubWVudCA9IHBvaW50c0FsaWduZWQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKTtcblxuICBzdmdBcHBlbmQocGFyZW50R2Z4LCBncm91cEdmeCk7XG5cbiAgY3JlYXRlUGFyYWxsZWxEcmFnZ2VyKGdyb3VwR2Z4LCBzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQsIGFsaWdubWVudCk7XG5cbiAgc3ZnQ2xhc3Nlcyhncm91cEdmeCkuYWRkKFNFR01FTlRfRFJBR0dFUl9DTFMpO1xuICBzdmdDbGFzc2VzKGdyb3VwR2Z4KS5hZGQoYWxpZ25tZW50ID09PSAnaCcgPyAnaG9yaXpvbnRhbCcgOiAndmVydGljYWwnKTtcblxuICB0cmFuc2xhdGUoZ3JvdXBHZngsIG1pZC54LCBtaWQueSk7XG5cbiAgcmV0dXJuIGdyb3VwR2Z4O1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZXMgcmVnaW9uIGZvciBzZWdtZW50IG1vdmUgd2hpY2ggaXMgMi8zIG9mIHRoZSBmdWxsIHNlZ21lbnQgbGVuZ3RoXG4gKiBAcGFyYW0ge251bWJlcn0gc2VnbWVudExlbmd0aFxuICpcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNhbGN1bGF0ZVNlZ21lbnRNb3ZlUmVnaW9uKHNlZ21lbnRMZW5ndGgpIHtcbiAgcmV0dXJuIE1hdGguYWJzKE1hdGgucm91bmQoc2VnbWVudExlbmd0aCAqIDIgLyAzKSk7XG59XG5cbi8vIGhlbHBlciAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNhbGN1bGF0ZUhpdFdpZHRoKHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCwgYWxpZ25tZW50KSB7XG4gIHZhciBzZWdtZW50TGVuZ3RoWEF4aXMgPSBzZWdtZW50RW5kLnggLSBzZWdtZW50U3RhcnQueCxcbiAgICAgIHNlZ21lbnRMZW5ndGhZQXhpcyA9IHNlZ21lbnRFbmQueSAtIHNlZ21lbnRTdGFydC55O1xuXG4gIHJldHVybiBhbGlnbm1lbnQgPT09ICdoJyA/XG4gICAgY2FsY3VsYXRlU2VnbWVudE1vdmVSZWdpb24oc2VnbWVudExlbmd0aFhBeGlzKSA6XG4gICAgY2FsY3VsYXRlU2VnbWVudE1vdmVSZWdpb24oc2VnbWVudExlbmd0aFlBeGlzKTtcbn1cbiIsImltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50LFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgcXVlcnlBbGwgYXMgZG9tUXVlcnlBbGxcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIEJFTkRQT0lOVF9DTFMsXG4gIFNFR01FTlRfRFJBR0dFUl9DTFMsXG4gIGFkZEJlbmRwb2ludCxcbiAgYWRkU2VnbWVudERyYWdnZXIsXG4gIGNhbGN1bGF0ZVNlZ21lbnRNb3ZlUmVnaW9uLFxuICBnZXRDb25uZWN0aW9uSW50ZXJzZWN0aW9uXG59IGZyb20gJy4vQmVuZHBvaW50VXRpbCc7XG5cbmltcG9ydCB7XG4gIGVzY2FwZUNTU1xufSBmcm9tICcuLi8uLi91dGlsL0VzY2FwZVV0aWwnO1xuXG5pbXBvcnQge1xuICBwb2ludHNBbGlnbmVkLFxuICBnZXRNaWRQb2ludFxufSBmcm9tICcuLi8uLi91dGlsL0dlb21ldHJ5JztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjbGFzc2VzIGFzIHN2Z0NsYXNzZXMsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICB0cmFuc2xhdGVcbn0gZnJvbSAnLi4vLi4vdXRpbC9TdmdUcmFuc2Zvcm1VdGlsJztcblxuXG4vKipcbiAqIEEgc2VydmljZSB0aGF0IGFkZHMgZWRpdGFibGUgYmVuZHBvaW50cyB0byBjb25uZWN0aW9ucy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmVuZHBvaW50cyhcbiAgICBldmVudEJ1cywgY2FudmFzLCBpbnRlcmFjdGlvbkV2ZW50cyxcbiAgICBiZW5kcG9pbnRNb3ZlLCBjb25uZWN0aW9uU2VnbWVudE1vdmUpIHtcblxuICAvKipcbiAgICogUmV0dXJucyB0cnVlIGlmIGludGVyc2VjdGlvbiBwb2ludCBpcyBpbnNpZGUgbWlkZGxlIHJlZ2lvbiBvZiBzZWdtZW50LCBhZGp1c3RlZCBieVxuICAgKiBvcHRpb25hbCB0aHJlc2hvbGRcbiAgICovXG4gIGZ1bmN0aW9uIGlzSW50ZXJzZWN0aW9uTWlkZGxlKGludGVyc2VjdGlvbiwgd2F5cG9pbnRzLCB0cmVzaG9sZCkge1xuICAgIHZhciBpZHggPSBpbnRlcnNlY3Rpb24uaW5kZXgsXG4gICAgICAgIHAgPSBpbnRlcnNlY3Rpb24ucG9pbnQsXG4gICAgICAgIHAwLCBwMSwgbWlkLCBhbGlnbmVkLCB4RGVsdGEsIHlEZWx0YTtcblxuICAgIGlmIChpZHggPD0gMCB8fCBpbnRlcnNlY3Rpb24uYmVuZHBvaW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcDAgPSB3YXlwb2ludHNbaWR4IC0gMV07XG4gICAgcDEgPSB3YXlwb2ludHNbaWR4XTtcbiAgICBtaWQgPSBnZXRNaWRQb2ludChwMCwgcDEpLFxuICAgIGFsaWduZWQgPSBwb2ludHNBbGlnbmVkKHAwLCBwMSk7XG4gICAgeERlbHRhID0gTWF0aC5hYnMocC54IC0gbWlkLngpO1xuICAgIHlEZWx0YSA9IE1hdGguYWJzKHAueSAtIG1pZC55KTtcblxuICAgIHJldHVybiBhbGlnbmVkICYmIHhEZWx0YSA8PSB0cmVzaG9sZCAmJiB5RGVsdGEgPD0gdHJlc2hvbGQ7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgdGhyZXNob2xkIGZyb20gYSBjb25uZWN0aW9uJ3MgbWlkZGxlIHdoaWNoIGZpdHMgdGhlIHR3by10aGlyZC1yZWdpb25cbiAgICovXG4gIGZ1bmN0aW9uIGNhbGN1bGF0ZUludGVyc2VjdGlvblRocmVzaG9sZChjb25uZWN0aW9uLCBpbnRlcnNlY3Rpb24pIHtcbiAgICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHMsXG4gICAgICAgIHJlbGV2YW50U2VnbWVudCwgYWxpZ25tZW50LCBzZWdtZW50TGVuZ3RoLCB0aHJlc2hvbGQ7XG5cbiAgICBpZiAoaW50ZXJzZWN0aW9uLmluZGV4IDw9IDAgfHwgaW50ZXJzZWN0aW9uLmJlbmRwb2ludCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLy8gc2VnbWVudCByZWxhdGl2ZSB0byBjb25uZWN0aW9uIGludGVyc2VjdGlvblxuICAgIHJlbGV2YW50U2VnbWVudCA9IHtcbiAgICAgIHN0YXJ0OiB3YXlwb2ludHNbaW50ZXJzZWN0aW9uLmluZGV4IC0gMV0sXG4gICAgICBlbmQ6IHdheXBvaW50c1tpbnRlcnNlY3Rpb24uaW5kZXhdXG4gICAgfTtcblxuICAgIGFsaWdubWVudCA9IHBvaW50c0FsaWduZWQocmVsZXZhbnRTZWdtZW50LnN0YXJ0LCByZWxldmFudFNlZ21lbnQuZW5kKTtcblxuICAgIGlmICghYWxpZ25tZW50KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoYWxpZ25tZW50ID09PSAnaCcpIHtcbiAgICAgIHNlZ21lbnRMZW5ndGggPSByZWxldmFudFNlZ21lbnQuZW5kLnggLSByZWxldmFudFNlZ21lbnQuc3RhcnQueDtcbiAgICB9IGVsc2Uge1xuICAgICAgc2VnbWVudExlbmd0aCA9IHJlbGV2YW50U2VnbWVudC5lbmQueSAtIHJlbGV2YW50U2VnbWVudC5zdGFydC55O1xuICAgIH1cblxuICAgIC8vIGNhbGN1bGF0ZSB0aHJlc2hvbGQgcmVsYXRpdmUgdG8gMi8zIG9mIHNlZ21lbnQgbGVuZ3RoXG4gICAgdGhyZXNob2xkID0gY2FsY3VsYXRlU2VnbWVudE1vdmVSZWdpb24oc2VnbWVudExlbmd0aCkgLyAyO1xuXG4gICAgcmV0dXJuIHRocmVzaG9sZDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFjdGl2YXRlQmVuZHBvaW50TW92ZShldmVudCwgY29ubmVjdGlvbikge1xuICAgIHZhciB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgICAgaW50ZXJzZWN0aW9uID0gZ2V0Q29ubmVjdGlvbkludGVyc2VjdGlvbihjYW52YXMsIHdheXBvaW50cywgZXZlbnQpLFxuICAgICAgICB0aHJlc2hvbGQ7XG5cbiAgICBpZiAoIWludGVyc2VjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRocmVzaG9sZCA9IGNhbGN1bGF0ZUludGVyc2VjdGlvblRocmVzaG9sZChjb25uZWN0aW9uLCBpbnRlcnNlY3Rpb24pO1xuXG4gICAgaWYgKGlzSW50ZXJzZWN0aW9uTWlkZGxlKGludGVyc2VjdGlvbiwgd2F5cG9pbnRzLCB0aHJlc2hvbGQpKSB7XG4gICAgICBjb25uZWN0aW9uU2VnbWVudE1vdmUuc3RhcnQoZXZlbnQsIGNvbm5lY3Rpb24sIGludGVyc2VjdGlvbi5pbmRleCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJlbmRwb2ludE1vdmUuc3RhcnQoZXZlbnQsIGNvbm5lY3Rpb24sIGludGVyc2VjdGlvbi5pbmRleCwgIWludGVyc2VjdGlvbi5iZW5kcG9pbnQpO1xuICAgIH1cblxuICAgIC8vIHdlJ3ZlIGhhbmRsZWQgdGhlIGV2ZW50XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiBiaW5kSW50ZXJhY3Rpb25FdmVudHMobm9kZSwgZXZlbnROYW1lLCBlbGVtZW50KSB7XG5cbiAgICBkb21FdmVudC5iaW5kKG5vZGUsIGV2ZW50TmFtZSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIGludGVyYWN0aW9uRXZlbnRzLnRyaWdnZXJNb3VzZUV2ZW50KGV2ZW50TmFtZSwgZXZlbnQsIGVsZW1lbnQpO1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRCZW5kcG9pbnRzQ29udGFpbmVyKGVsZW1lbnQsIGNyZWF0ZSkge1xuXG4gICAgdmFyIGxheWVyID0gY2FudmFzLmdldExheWVyKCdvdmVybGF5cycpLFxuICAgICAgICBnZnggPSBkb21RdWVyeSgnLmRqcy1iZW5kcG9pbnRzW2RhdGEtZWxlbWVudC1pZD1cIicgKyBlc2NhcGVDU1MoZWxlbWVudC5pZCkgKyAnXCJdJywgbGF5ZXIpO1xuXG4gICAgaWYgKCFnZnggJiYgY3JlYXRlKSB7XG4gICAgICBnZnggPSBzdmdDcmVhdGUoJ2cnKTtcbiAgICAgIHN2Z0F0dHIoZ2Z4LCB7ICdkYXRhLWVsZW1lbnQtaWQnOiBlbGVtZW50LmlkIH0pO1xuICAgICAgc3ZnQ2xhc3NlcyhnZngpLmFkZCgnZGpzLWJlbmRwb2ludHMnKTtcblxuICAgICAgc3ZnQXBwZW5kKGxheWVyLCBnZngpO1xuXG4gICAgICBiaW5kSW50ZXJhY3Rpb25FdmVudHMoZ2Z4LCAnbW91c2Vkb3duJywgZWxlbWVudCk7XG4gICAgICBiaW5kSW50ZXJhY3Rpb25FdmVudHMoZ2Z4LCAnY2xpY2snLCBlbGVtZW50KTtcbiAgICAgIGJpbmRJbnRlcmFjdGlvbkV2ZW50cyhnZngsICdkYmxjbGljaycsIGVsZW1lbnQpO1xuICAgIH1cblxuICAgIHJldHVybiBnZng7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRTZWdtZW50RHJhZ2dlcihpZHgsIHBhcmVudEdmeCkge1xuICAgIHJldHVybiBkb21RdWVyeShcbiAgICAgICcuZGpzLXNlZ21lbnQtZHJhZ2dlcltkYXRhLXNlZ21lbnQtaWR4PVwiJyArIGlkeCArICdcIl0nLFxuICAgICAgcGFyZW50R2Z4XG4gICAgKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNyZWF0ZUJlbmRwb2ludHMoZ2Z4LCBjb25uZWN0aW9uKSB7XG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMuZm9yRWFjaChmdW5jdGlvbihwLCBpZHgpIHtcbiAgICAgIHZhciBiZW5kcG9pbnQgPSBhZGRCZW5kcG9pbnQoZ2Z4KTtcblxuICAgICAgc3ZnQXBwZW5kKGdmeCwgYmVuZHBvaW50KTtcblxuICAgICAgdHJhbnNsYXRlKGJlbmRwb2ludCwgcC54LCBwLnkpO1xuICAgIH0pO1xuXG4gICAgLy8gYWRkIGZsb2F0aW5nIGJlbmRwb2ludFxuICAgIGFkZEJlbmRwb2ludChnZngsICdmbG9hdGluZycpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlU2VnbWVudERyYWdnZXJzKGdmeCwgY29ubmVjdGlvbikge1xuXG4gICAgdmFyIHdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzO1xuXG4gICAgdmFyIHNlZ21lbnRTdGFydCxcbiAgICAgICAgc2VnbWVudEVuZCxcbiAgICAgICAgc2VnbWVudERyYWdnZXJHZng7XG5cbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IHdheXBvaW50cy5sZW5ndGg7IGkrKykge1xuXG4gICAgICBzZWdtZW50U3RhcnQgPSB3YXlwb2ludHNbaSAtIDFdO1xuICAgICAgc2VnbWVudEVuZCA9IHdheXBvaW50c1tpXTtcblxuICAgICAgaWYgKHBvaW50c0FsaWduZWQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKSkge1xuICAgICAgICBzZWdtZW50RHJhZ2dlckdmeCA9IGFkZFNlZ21lbnREcmFnZ2VyKGdmeCwgc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKTtcblxuICAgICAgICBzdmdBdHRyKHNlZ21lbnREcmFnZ2VyR2Z4LCB7ICdkYXRhLXNlZ21lbnQtaWR4JzogaSB9KTtcblxuICAgICAgICBiaW5kSW50ZXJhY3Rpb25FdmVudHMoc2VnbWVudERyYWdnZXJHZngsICdtb3VzZW1vdmUnLCBjb25uZWN0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjbGVhckJlbmRwb2ludHMoZ2Z4KSB7XG4gICAgZm9yRWFjaChkb21RdWVyeUFsbCgnLicgKyBCRU5EUE9JTlRfQ0xTLCBnZngpLCBmdW5jdGlvbihub2RlKSB7XG4gICAgICBzdmdSZW1vdmUobm9kZSk7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBjbGVhclNlZ21lbnREcmFnZ2VycyhnZngpIHtcbiAgICBmb3JFYWNoKGRvbVF1ZXJ5QWxsKCcuJyArIFNFR01FTlRfRFJBR0dFUl9DTFMsIGdmeCksIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIHN2Z1JlbW92ZShub2RlKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZEhhbmRsZXMoY29ubmVjdGlvbikge1xuXG4gICAgdmFyIGdmeCA9IGdldEJlbmRwb2ludHNDb250YWluZXIoY29ubmVjdGlvbik7XG5cbiAgICBpZiAoIWdmeCkge1xuICAgICAgZ2Z4ID0gZ2V0QmVuZHBvaW50c0NvbnRhaW5lcihjb25uZWN0aW9uLCB0cnVlKTtcblxuICAgICAgY3JlYXRlQmVuZHBvaW50cyhnZngsIGNvbm5lY3Rpb24pO1xuICAgICAgY3JlYXRlU2VnbWVudERyYWdnZXJzKGdmeCwgY29ubmVjdGlvbik7XG4gICAgfVxuXG4gICAgcmV0dXJuIGdmeDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUhhbmRsZXMoY29ubmVjdGlvbikge1xuXG4gICAgdmFyIGdmeCA9IGdldEJlbmRwb2ludHNDb250YWluZXIoY29ubmVjdGlvbik7XG5cbiAgICBpZiAoZ2Z4KSB7XG4gICAgICBjbGVhclNlZ21lbnREcmFnZ2VycyhnZngpO1xuICAgICAgY2xlYXJCZW5kcG9pbnRzKGdmeCk7XG4gICAgICBjcmVhdGVTZWdtZW50RHJhZ2dlcnMoZ2Z4LCBjb25uZWN0aW9uKTtcbiAgICAgIGNyZWF0ZUJlbmRwb2ludHMoZ2Z4LCBjb25uZWN0aW9uKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVGbG9hdGluZ0JlbmRwb2ludFBvc2l0aW9uKHBhcmVudEdmeCwgaW50ZXJzZWN0aW9uKSB7XG4gICAgdmFyIGZsb2F0aW5nID0gZG9tUXVlcnkoJy5mbG9hdGluZycsIHBhcmVudEdmeCksXG4gICAgICAgIHBvaW50ID0gaW50ZXJzZWN0aW9uLnBvaW50O1xuXG4gICAgaWYgKCFmbG9hdGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyYW5zbGF0ZShmbG9hdGluZywgcG9pbnQueCwgcG9pbnQueSk7XG5cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVNlZ21lbnREcmFnZ2VyUG9zaXRpb24ocGFyZW50R2Z4LCBpbnRlcnNlY3Rpb24sIHdheXBvaW50cykge1xuXG4gICAgdmFyIGRyYWdnZXJHZnggPSBnZXRTZWdtZW50RHJhZ2dlcihpbnRlcnNlY3Rpb24uaW5kZXgsIHBhcmVudEdmeCksXG4gICAgICAgIHNlZ21lbnRTdGFydCA9IHdheXBvaW50c1tpbnRlcnNlY3Rpb24uaW5kZXggLSAxXSxcbiAgICAgICAgc2VnbWVudEVuZCA9IHdheXBvaW50c1tpbnRlcnNlY3Rpb24uaW5kZXhdLFxuICAgICAgICBwb2ludCA9IGludGVyc2VjdGlvbi5wb2ludCxcbiAgICAgICAgbWlkID0gZ2V0TWlkUG9pbnQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKSxcbiAgICAgICAgYWxpZ25tZW50ID0gcG9pbnRzQWxpZ25lZChzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQpLFxuICAgICAgICBkcmFnZ2VyVmlzdWFsLCByZWxhdGl2ZVBvc2l0aW9uO1xuXG4gICAgaWYgKCFkcmFnZ2VyR2Z4KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZHJhZ2dlclZpc3VhbCA9IGdldERyYWdnZXJWaXN1YWwoZHJhZ2dlckdmeCk7XG5cbiAgICByZWxhdGl2ZVBvc2l0aW9uID0ge1xuICAgICAgeDogcG9pbnQueCAtIG1pZC54LFxuICAgICAgeTogcG9pbnQueSAtIG1pZC55XG4gICAgfTtcblxuICAgIGlmIChhbGlnbm1lbnQgPT09ICd2Jykge1xuXG4gICAgICAvLyByb3RhdGUgcG9zaXRpb25cbiAgICAgIHJlbGF0aXZlUG9zaXRpb24gPSB7XG4gICAgICAgIHg6IHJlbGF0aXZlUG9zaXRpb24ueSxcbiAgICAgICAgeTogcmVsYXRpdmVQb3NpdGlvbi54XG4gICAgICB9O1xuICAgIH1cblxuICAgIHRyYW5zbGF0ZShkcmFnZ2VyVmlzdWFsLCByZWxhdGl2ZVBvc2l0aW9uLngsIHJlbGF0aXZlUG9zaXRpb24ueSk7XG4gIH1cblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvbi5jaGFuZ2VkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB1cGRhdGVIYW5kbGVzKGV2ZW50LmVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvbi5yZW1vdmUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBnZnggPSBnZXRCZW5kcG9pbnRzQ29udGFpbmVyKGV2ZW50LmVsZW1lbnQpO1xuXG4gICAgaWYgKGdmeCkge1xuICAgICAgc3ZnUmVtb3ZlKGdmeCk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tYXJrZXIudXBkYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBlbGVtZW50ID0gZXZlbnQuZWxlbWVudCxcbiAgICAgICAgYmVuZHBvaW50c0dmeDtcblxuICAgIGlmICghZWxlbWVudC53YXlwb2ludHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBiZW5kcG9pbnRzR2Z4ID0gYWRkSGFuZGxlcyhlbGVtZW50KTtcblxuICAgIGlmIChldmVudC5hZGQpIHtcbiAgICAgIHN2Z0NsYXNzZXMoYmVuZHBvaW50c0dmeCkuYWRkKGV2ZW50Lm1hcmtlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN2Z0NsYXNzZXMoYmVuZHBvaW50c0dmeCkucmVtb3ZlKGV2ZW50Lm1hcmtlcik7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tb3VzZW1vdmUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICB3YXlwb2ludHMgPSBlbGVtZW50LndheXBvaW50cyxcbiAgICAgICAgYmVuZHBvaW50c0dmeCxcbiAgICAgICAgaW50ZXJzZWN0aW9uO1xuXG4gICAgaWYgKHdheXBvaW50cykge1xuICAgICAgYmVuZHBvaW50c0dmeCA9IGdldEJlbmRwb2ludHNDb250YWluZXIoZWxlbWVudCwgdHJ1ZSk7XG5cbiAgICAgIGludGVyc2VjdGlvbiA9IGdldENvbm5lY3Rpb25JbnRlcnNlY3Rpb24oY2FudmFzLCB3YXlwb2ludHMsIGV2ZW50Lm9yaWdpbmFsRXZlbnQpO1xuXG4gICAgICBpZiAoIWludGVyc2VjdGlvbikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHVwZGF0ZUZsb2F0aW5nQmVuZHBvaW50UG9zaXRpb24oYmVuZHBvaW50c0dmeCwgaW50ZXJzZWN0aW9uKTtcblxuICAgICAgaWYgKCFpbnRlcnNlY3Rpb24uYmVuZHBvaW50KSB7XG4gICAgICAgIHVwZGF0ZVNlZ21lbnREcmFnZ2VyUG9zaXRpb24oYmVuZHBvaW50c0dmeCwgaW50ZXJzZWN0aW9uLCB3YXlwb2ludHMpO1xuICAgICAgfVxuXG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tb3VzZWRvd24nLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIG9yaWdpbmFsRXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50LFxuICAgICAgICBlbGVtZW50ID0gZXZlbnQuZWxlbWVudDtcblxuICAgIGlmICghZWxlbWVudC53YXlwb2ludHMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICByZXR1cm4gYWN0aXZhdGVCZW5kcG9pbnRNb3ZlKG9yaWdpbmFsRXZlbnQsIGVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignc2VsZWN0aW9uLmNoYW5nZWQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBuZXdTZWxlY3Rpb24gPSBldmVudC5uZXdTZWxlY3Rpb24sXG4gICAgICAgIHByaW1hcnkgPSBuZXdTZWxlY3Rpb25bMF07XG5cbiAgICBpZiAocHJpbWFyeSAmJiBwcmltYXJ5LndheXBvaW50cykge1xuICAgICAgYWRkSGFuZGxlcyhwcmltYXJ5KTtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudC53YXlwb2ludHMpIHtcbiAgICAgIGFkZEhhbmRsZXMoZWxlbWVudCk7XG4gICAgICBpbnRlcmFjdGlvbkV2ZW50cy5yZWdpc3RlckV2ZW50KGV2ZW50LmdmeCwgJ21vdXNlbW92ZScsICdlbGVtZW50Lm1vdXNlbW92ZScpO1xuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQub3V0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBpbnRlcmFjdGlvbkV2ZW50cy51bnJlZ2lzdGVyRXZlbnQoZXZlbnQuZ2Z4LCAnbW91c2Vtb3ZlJywgJ2VsZW1lbnQubW91c2Vtb3ZlJyk7XG4gIH0pO1xuXG4gIC8vIHVwZGF0ZSBiZW5kcG9pbnQgY29udGFpbmVyIGRhdGEgYXR0cmlidXRlIG9uIGVsZW1lbnQgSUQgY2hhbmdlXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LnVwZGF0ZUlkJywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBuZXdJZCA9IGNvbnRleHQubmV3SWQ7XG5cbiAgICBpZiAoZWxlbWVudC53YXlwb2ludHMpIHtcbiAgICAgIHZhciBiZW5kcG9pbnRDb250YWluZXIgPSBnZXRCZW5kcG9pbnRzQ29udGFpbmVyKGVsZW1lbnQpO1xuXG4gICAgICBpZiAoYmVuZHBvaW50Q29udGFpbmVyKSB7XG4gICAgICAgIHN2Z0F0dHIoYmVuZHBvaW50Q29udGFpbmVyLCB7ICdkYXRhLWVsZW1lbnQtaWQnOiBuZXdJZCB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIEFQSVxuXG4gIHRoaXMuYWRkSGFuZGxlcyA9IGFkZEhhbmRsZXM7XG4gIHRoaXMudXBkYXRlSGFuZGxlcyA9IHVwZGF0ZUhhbmRsZXM7XG4gIHRoaXMuZ2V0QmVuZHBvaW50c0NvbnRhaW5lciA9IGdldEJlbmRwb2ludHNDb250YWluZXI7XG4gIHRoaXMuZ2V0U2VnbWVudERyYWdnZXIgPSBnZXRTZWdtZW50RHJhZ2dlcjtcbn1cblxuQmVuZHBvaW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ2ludGVyYWN0aW9uRXZlbnRzJyxcbiAgJ2JlbmRwb2ludE1vdmUnLFxuICAnY29ubmVjdGlvblNlZ21lbnRNb3ZlJ1xuXTtcblxuXG5cbi8vIGhlbHBlciAvLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldERyYWdnZXJWaXN1YWwoZHJhZ2dlckdmeCkge1xuICByZXR1cm4gZG9tUXVlcnkoJy5kanMtdmlzdWFsJywgZHJhZ2dlckdmeCk7XG59IiwiaW1wb3J0IHtcbiAgcG9pbnRzQWxpZ25lZCxcbiAgcG9pbnRzT25MaW5lXG59IGZyb20gJy4uLy4uL3V0aWwvR2VvbWV0cnknO1xuXG5pbXBvcnQge1xuICBhZGRTZWdtZW50RHJhZ2dlcixcbiAgZ2V0Q29ubmVjdGlvbkludGVyc2VjdGlvblxufSBmcm9tICcuL0JlbmRwb2ludFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRNaWQsXG4gIGdldE9yaWVudGF0aW9uXG59IGZyb20gJy4uLy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxudmFyIE1BUktFUl9DT05ORUNUX0hPVkVSID0gJ2Nvbm5lY3QtaG92ZXInLFxuICAgIE1BUktFUl9DT05ORUNUX1VQREFUSU5HID0gJ2Rqcy11cGRhdGluZyc7XG5cbmltcG9ydCB7XG4gIGNsYXNzZXMgYXMgc3ZnQ2xhc3NlcyxcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7XG4gIHRyYW5zbGF0ZVxufSBmcm9tICcuLi8uLi91dGlsL1N2Z1RyYW5zZm9ybVV0aWwnO1xuXG5cbmZ1bmN0aW9uIGF4aXNBZGQocG9pbnQsIGF4aXMsIGRlbHRhKSB7XG4gIHJldHVybiBheGlzU2V0KHBvaW50LCBheGlzLCBwb2ludFtheGlzXSArIGRlbHRhKTtcbn1cblxuZnVuY3Rpb24gYXhpc1NldChwb2ludCwgYXhpcywgdmFsdWUpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiAoYXhpcyA9PT0gJ3gnID8gdmFsdWUgOiBwb2ludC54KSxcbiAgICB5OiAoYXhpcyA9PT0gJ3knID8gdmFsdWUgOiBwb2ludC55KVxuICB9O1xufVxuXG5mdW5jdGlvbiBheGlzRmVuY2VkKHBvc2l0aW9uLCBzZWdtZW50U3RhcnQsIHNlZ21lbnRFbmQsIGF4aXMpIHtcblxuICB2YXIgbWF4VmFsdWUgPSBNYXRoLm1heChzZWdtZW50U3RhcnRbYXhpc10sIHNlZ21lbnRFbmRbYXhpc10pLFxuICAgICAgbWluVmFsdWUgPSBNYXRoLm1pbihzZWdtZW50U3RhcnRbYXhpc10sIHNlZ21lbnRFbmRbYXhpc10pO1xuXG4gIHZhciBwYWRkaW5nID0gMjA7XG5cbiAgdmFyIGZlbmNlZFZhbHVlID0gTWF0aC5taW4oTWF0aC5tYXgobWluVmFsdWUgKyBwYWRkaW5nLCBwb3NpdGlvbltheGlzXSksIG1heFZhbHVlIC0gcGFkZGluZyk7XG5cbiAgcmV0dXJuIGF4aXNTZXQoc2VnbWVudFN0YXJ0LCBheGlzLCBmZW5jZWRWYWx1ZSk7XG59XG5cbmZ1bmN0aW9uIGZsaXBBeGlzKGF4aXMpIHtcbiAgcmV0dXJuIGF4aXMgPT09ICd4JyA/ICd5JyA6ICd4Jztcbn1cblxuLyoqXG4gKiBHZXQgdGhlIGRvY2tpbmcgcG9pbnQgb24gdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogQ29tcHV0ZSBhIHJlYXNvbmFibGUgZG9ja2luZywgaWYgbm9uIGV4aXN0cy5cbiAqXG4gKiBAcGFyYW0gIHtQb2ludH0gcG9pbnRcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5TaGFwZX0gcmVmZXJlbmNlRWxlbWVudFxuICogQHBhcmFtICB7c3RyaW5nfSBtb3ZlQXhpcyAoeHx5KVxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5mdW5jdGlvbiBnZXREb2NraW5nKHBvaW50LCByZWZlcmVuY2VFbGVtZW50LCBtb3ZlQXhpcykge1xuXG4gIHZhciByZWZlcmVuY2VNaWQsXG4gICAgICBpbnZlcnNlQXhpcztcblxuICBpZiAocG9pbnQub3JpZ2luYWwpIHtcbiAgICByZXR1cm4gcG9pbnQub3JpZ2luYWw7XG4gIH0gZWxzZSB7XG4gICAgcmVmZXJlbmNlTWlkID0gZ2V0TWlkKHJlZmVyZW5jZUVsZW1lbnQpO1xuICAgIGludmVyc2VBeGlzID0gZmxpcEF4aXMobW92ZUF4aXMpO1xuXG4gICAgcmV0dXJuIGF4aXNTZXQocG9pbnQsIGludmVyc2VBeGlzLCByZWZlcmVuY2VNaWRbaW52ZXJzZUF4aXNdKTtcbiAgfVxufVxuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgaW1wbGVtZW50cyBtb3Zpbmcgb2YgYmVuZHBvaW50c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDb25uZWN0aW9uU2VnbWVudE1vdmUoXG4gICAgaW5qZWN0b3IsIGV2ZW50QnVzLCBjYW52YXMsXG4gICAgZHJhZ2dpbmcsIGdyYXBoaWNzRmFjdG9yeSwgbW9kZWxpbmcpIHtcblxuICAvLyBvcHRpb25hbCBjb25uZWN0aW9uIGRvY2tpbmcgaW50ZWdyYXRpb25cbiAgdmFyIGNvbm5lY3Rpb25Eb2NraW5nID0gaW5qZWN0b3IuZ2V0KCdjb25uZWN0aW9uRG9ja2luZycsIGZhbHNlKTtcblxuXG4gIC8vIEFQSVxuXG4gIHRoaXMuc3RhcnQgPSBmdW5jdGlvbihldmVudCwgY29ubmVjdGlvbiwgaWR4KSB7XG5cbiAgICB2YXIgY29udGV4dCxcbiAgICAgICAgZ2Z4ID0gY2FudmFzLmdldEdyYXBoaWNzKGNvbm5lY3Rpb24pLFxuICAgICAgICBzZWdtZW50U3RhcnRJbmRleCA9IGlkeCAtIDEsXG4gICAgICAgIHNlZ21lbnRFbmRJbmRleCA9IGlkeCxcbiAgICAgICAgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHMsXG4gICAgICAgIHNlZ21lbnRTdGFydCA9IHdheXBvaW50c1tzZWdtZW50U3RhcnRJbmRleF0sXG4gICAgICAgIHNlZ21lbnRFbmQgPSB3YXlwb2ludHNbc2VnbWVudEVuZEluZGV4XSxcbiAgICAgICAgaW50ZXJzZWN0aW9uID0gZ2V0Q29ubmVjdGlvbkludGVyc2VjdGlvbihjYW52YXMsIHdheXBvaW50cywgZXZlbnQpLFxuICAgICAgICBkaXJlY3Rpb24sIGF4aXMsIGRyYWdQb3NpdGlvbjtcblxuICAgIGRpcmVjdGlvbiA9IHBvaW50c0FsaWduZWQoc2VnbWVudFN0YXJ0LCBzZWdtZW50RW5kKTtcblxuICAgIC8vIGRvIG5vdCBtb3ZlIGRpYWdvbmFsIGNvbm5lY3Rpb25cbiAgICBpZiAoIWRpcmVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIHRoZSBheGlzIHdoZXJlIHdlIGFyZSBnb2luZyB0byBtb3ZlIHRoaW5nc1xuICAgIGF4aXMgPSBkaXJlY3Rpb24gPT09ICd2JyA/ICd4JyA6ICd5JztcblxuICAgIGlmIChzZWdtZW50U3RhcnRJbmRleCA9PT0gMCkge1xuICAgICAgc2VnbWVudFN0YXJ0ID0gZ2V0RG9ja2luZyhzZWdtZW50U3RhcnQsIGNvbm5lY3Rpb24uc291cmNlLCBheGlzKTtcbiAgICB9XG5cbiAgICBpZiAoc2VnbWVudEVuZEluZGV4ID09PSB3YXlwb2ludHMubGVuZ3RoIC0gMSkge1xuICAgICAgc2VnbWVudEVuZCA9IGdldERvY2tpbmcoc2VnbWVudEVuZCwgY29ubmVjdGlvbi50YXJnZXQsIGF4aXMpO1xuICAgIH1cblxuICAgIGlmIChpbnRlcnNlY3Rpb24pIHtcbiAgICAgIGRyYWdQb3NpdGlvbiA9IGludGVyc2VjdGlvbi5wb2ludDtcbiAgICB9IGVsc2Uge1xuXG4gICAgICAvLyBzZXQgdG8gc2VnbWVudCBjZW50ZXIgYXMgZGVmYXVsdFxuICAgICAgZHJhZ1Bvc2l0aW9uID0ge1xuICAgICAgICB4OiAoc2VnbWVudFN0YXJ0LnggKyBzZWdtZW50RW5kLngpIC8gMixcbiAgICAgICAgeTogKHNlZ21lbnRTdGFydC55ICsgc2VnbWVudEVuZC55KSAvIDJcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29udGV4dCA9IHtcbiAgICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgICBzZWdtZW50U3RhcnRJbmRleDogc2VnbWVudFN0YXJ0SW5kZXgsXG4gICAgICBzZWdtZW50RW5kSW5kZXg6IHNlZ21lbnRFbmRJbmRleCxcbiAgICAgIHNlZ21lbnRTdGFydDogc2VnbWVudFN0YXJ0LFxuICAgICAgc2VnbWVudEVuZDogc2VnbWVudEVuZCxcbiAgICAgIGF4aXM6IGF4aXMsXG4gICAgICBkcmFnUG9zaXRpb246IGRyYWdQb3NpdGlvblxuICAgIH07XG5cbiAgICBkcmFnZ2luZy5pbml0KGV2ZW50LCBkcmFnUG9zaXRpb24sICdjb25uZWN0aW9uU2VnbWVudC5tb3ZlJywge1xuICAgICAgY3Vyc29yOiBheGlzID09PSAneCcgPyAncmVzaXplLWV3JyA6ICdyZXNpemUtbnMnLFxuICAgICAgZGF0YToge1xuICAgICAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgICAgICBjb25uZWN0aW9uR2Z4OiBnZngsXG4gICAgICAgIGNvbnRleHQ6IGNvbnRleHRcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICAvKipcbiAgICogQ3JvcCBjb25uZWN0aW9uIGlmIGNvbm5lY3Rpb24gY3JvcHBpbmcgaXMgcHJvdmlkZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7Q29ubmVjdGlvbn0gY29ubmVjdGlvblxuICAgKiBAcGFyYW0ge0FycmF5PFBvaW50Pn0gbmV3V2F5cG9pbnRzXG4gICAqXG4gICAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gY3JvcHBlZCBjb25uZWN0aW9uIHdheXBvaW50c1xuICAgKi9cbiAgZnVuY3Rpb24gY3JvcENvbm5lY3Rpb24oY29ubmVjdGlvbiwgbmV3V2F5cG9pbnRzKSB7XG5cbiAgICAvLyBjcm9wIGNvbm5lY3Rpb24sIGlmIGRvY2tpbmcgc2VydmljZSBpcyBwcm92aWRlZCBvbmx5XG4gICAgaWYgKCFjb25uZWN0aW9uRG9ja2luZykge1xuICAgICAgcmV0dXJuIG5ld1dheXBvaW50cztcbiAgICB9XG5cbiAgICB2YXIgb2xkV2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHMsXG4gICAgICAgIGNyb3BwZWRXYXlwb2ludHM7XG5cbiAgICAvLyB0ZW1wb3Jhcnkgc2V0IG5ldyB3YXlwb2ludHNcbiAgICBjb25uZWN0aW9uLndheXBvaW50cyA9IG5ld1dheXBvaW50cztcblxuICAgIGNyb3BwZWRXYXlwb2ludHMgPSBjb25uZWN0aW9uRG9ja2luZy5nZXRDcm9wcGVkV2F5cG9pbnRzKGNvbm5lY3Rpb24pO1xuXG4gICAgLy8gcmVzdG9yZSBvbGQgd2F5cG9pbnRzXG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBvbGRXYXlwb2ludHM7XG5cbiAgICByZXR1cm4gY3JvcHBlZFdheXBvaW50cztcbiAgfVxuXG4gIC8vIERSQUdHSU5HIElNUExFTUVOVEFUSU9OXG5cbiAgZnVuY3Rpb24gcmVkcmF3Q29ubmVjdGlvbihkYXRhKSB7XG4gICAgZ3JhcGhpY3NGYWN0b3J5LnVwZGF0ZSgnY29ubmVjdGlvbicsIGRhdGEuY29ubmVjdGlvbiwgZGF0YS5jb25uZWN0aW9uR2Z4KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZURyYWdnZXIoY29udGV4dCwgc2VnbWVudE9mZnNldCwgZXZlbnQpIHtcblxuICAgIHZhciBuZXdXYXlwb2ludHMgPSBjb250ZXh0Lm5ld1dheXBvaW50cyxcbiAgICAgICAgc2VnbWVudFN0YXJ0SW5kZXggPSBjb250ZXh0LnNlZ21lbnRTdGFydEluZGV4ICsgc2VnbWVudE9mZnNldCxcbiAgICAgICAgc2VnbWVudFN0YXJ0ID0gbmV3V2F5cG9pbnRzW3NlZ21lbnRTdGFydEluZGV4XSxcbiAgICAgICAgc2VnbWVudEVuZEluZGV4ID0gY29udGV4dC5zZWdtZW50RW5kSW5kZXggKyBzZWdtZW50T2Zmc2V0LFxuICAgICAgICBzZWdtZW50RW5kID0gbmV3V2F5cG9pbnRzW3NlZ21lbnRFbmRJbmRleF0sXG4gICAgICAgIGF4aXMgPSBmbGlwQXhpcyhjb250ZXh0LmF4aXMpO1xuXG4gICAgLy8gbWFrZSBzdXJlIHRoZSBkcmFnZ2VyIGRvZXMgbm90IG1vdmVcbiAgICAvLyBvdXRzaWRlIHRoZSBjb25uZWN0aW9uXG4gICAgdmFyIGRyYWdnZXJQb3NpdGlvbiA9IGF4aXNGZW5jZWQoZXZlbnQsIHNlZ21lbnRTdGFydCwgc2VnbWVudEVuZCwgYXhpcyk7XG5cbiAgICAvLyB1cGRhdGUgZHJhZ2dlclxuICAgIHRyYW5zbGF0ZShjb250ZXh0LmRyYWdnZXJHZngsIGRyYWdnZXJQb3NpdGlvbi54LCBkcmFnZ2VyUG9zaXRpb24ueSk7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVyIHdheXBvaW50cyBmb3IgcmVkdW5kYW50IG9uZXMgKGkuZS4gb24gdGhlIHNhbWUgYXhpcykuXG4gICAqIFJldHVybnMgdGhlIGZpbHRlcmVkIHdheXBvaW50cyBhbmQgdGhlIG9mZnNldCByZWxhdGVkIHRvIHRoZSBzZWdtZW50IG1vdmUuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAgICogQHBhcmFtIHtJbnRlZ2VyfSBzZWdtZW50U3RhcnRJbmRleCBvZiBtb3ZlZCBzZWdtZW50IHN0YXJ0XG4gICAqXG4gICAqIEByZXR1cm4ge09iamVjdH0geyBmaWx0ZXJlZFdheXBvaW50cywgc2VnbWVudE9mZnNldCB9XG4gICAqL1xuICBmdW5jdGlvbiBmaWx0ZXJSZWR1bmRhbnRXYXlwb2ludHMod2F5cG9pbnRzLCBzZWdtZW50U3RhcnRJbmRleCkge1xuXG4gICAgdmFyIHNlZ21lbnRPZmZzZXQgPSAwO1xuXG4gICAgdmFyIGZpbHRlcmVkV2F5cG9pbnRzID0gd2F5cG9pbnRzLmZpbHRlcihmdW5jdGlvbihyLCBpZHgpIHtcbiAgICAgIGlmIChwb2ludHNPbkxpbmUod2F5cG9pbnRzW2lkeCAtIDFdLCB3YXlwb2ludHNbaWR4ICsgMV0sIHIpKSB7XG5cbiAgICAgICAgLy8gcmVtb3ZlIHBvaW50IGFuZCBpbmNyZW1lbnQgb2Zmc2V0XG4gICAgICAgIHNlZ21lbnRPZmZzZXQgPSBpZHggPD0gc2VnbWVudFN0YXJ0SW5kZXggPyBzZWdtZW50T2Zmc2V0IC0gMSA6IHNlZ21lbnRPZmZzZXQ7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgLy8gZG9udCByZW1vdmUgcG9pbnRcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHdheXBvaW50czogZmlsdGVyZWRXYXlwb2ludHMsXG4gICAgICBzZWdtZW50T2Zmc2V0OiBzZWdtZW50T2Zmc2V0XG4gICAgfTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjb25uZWN0aW9uU2VnbWVudC5tb3ZlLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGV2ZW50LmNvbm5lY3Rpb24sXG4gICAgICAgIGxheWVyID0gY2FudmFzLmdldExheWVyKCdvdmVybGF5cycpO1xuXG4gICAgY29udGV4dC5vcmlnaW5hbFdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzLnNsaWNlKCk7XG5cbiAgICAvLyBhZGQgZHJhZ2dlciBnZnhcbiAgICBjb250ZXh0LmRyYWdnZXJHZnggPSBhZGRTZWdtZW50RHJhZ2dlcihsYXllciwgY29udGV4dC5zZWdtZW50U3RhcnQsIGNvbnRleHQuc2VnbWVudEVuZCk7XG4gICAgc3ZnQ2xhc3Nlcyhjb250ZXh0LmRyYWdnZXJHZngpLmFkZCgnZGpzLWRyYWdnaW5nJyk7XG5cbiAgICBjYW52YXMuYWRkTWFya2VyKGNvbm5lY3Rpb24sIE1BUktFUl9DT05ORUNUX1VQREFUSU5HKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHNlZ21lbnRTdGFydEluZGV4ID0gY29udGV4dC5zZWdtZW50U3RhcnRJbmRleCxcbiAgICAgICAgc2VnbWVudEVuZEluZGV4ID0gY29udGV4dC5zZWdtZW50RW5kSW5kZXgsXG4gICAgICAgIHNlZ21lbnRTdGFydCA9IGNvbnRleHQuc2VnbWVudFN0YXJ0LFxuICAgICAgICBzZWdtZW50RW5kID0gY29udGV4dC5zZWdtZW50RW5kLFxuICAgICAgICBheGlzID0gY29udGV4dC5heGlzO1xuXG4gICAgdmFyIG5ld1dheXBvaW50cyA9IGNvbnRleHQub3JpZ2luYWxXYXlwb2ludHMuc2xpY2UoKSxcbiAgICAgICAgbmV3U2VnbWVudFN0YXJ0ID0gYXhpc0FkZChzZWdtZW50U3RhcnQsIGF4aXMsIGV2ZW50WydkJyArIGF4aXNdKSxcbiAgICAgICAgbmV3U2VnbWVudEVuZCA9IGF4aXNBZGQoc2VnbWVudEVuZCwgYXhpcywgZXZlbnRbJ2QnICsgYXhpc10pO1xuXG4gICAgLy8gb3JpZ2luYWwgd2F5cG9pbnQgY291bnQgYW5kIGFkZGVkIC8gcmVtb3ZlZFxuICAgIC8vIGZyb20gc3RhcnQgd2F5cG9pbnQgZGVsdGEuIFdlIHVzZSB0aGUgbGF0ZXJcbiAgICAvLyB0byByZXRyaWV2ZSB0aGUgdXBkYXRlZCBzZWdtZW50U3RhcnRJbmRleCAvIHNlZ21lbnRFbmRJbmRleFxuICAgIHZhciB3YXlwb2ludENvdW50ID0gbmV3V2F5cG9pbnRzLmxlbmd0aCxcbiAgICAgICAgc2VnbWVudE9mZnNldCA9IDA7XG5cbiAgICAvLyBtb3ZlIHNlZ21lbnQgc3RhcnQgLyBlbmQgYnkgYXhpcyBkZWx0YVxuICAgIG5ld1dheXBvaW50c1tzZWdtZW50U3RhcnRJbmRleF0gPSBuZXdTZWdtZW50U3RhcnQ7XG4gICAgbmV3V2F5cG9pbnRzW3NlZ21lbnRFbmRJbmRleF0gPSBuZXdTZWdtZW50RW5kO1xuXG4gICAgdmFyIHNvdXJjZVRvU2VnbWVudE9yaWVudGF0aW9uLFxuICAgICAgICB0YXJnZXRUb1NlZ21lbnRPcmllbnRhdGlvbjtcblxuICAgIC8vIGhhbmRsZSBmaXJzdCBzZWdtZW50XG4gICAgaWYgKHNlZ21lbnRTdGFydEluZGV4IDwgMikge1xuICAgICAgc291cmNlVG9TZWdtZW50T3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihjb25uZWN0aW9uLnNvdXJjZSwgbmV3U2VnbWVudFN0YXJ0KTtcblxuICAgICAgLy8gZmlyc3QgYmVuZHBvaW50LCByZW1vdmUgZmlyc3Qgc2VnbWVudCBpZiBpbnRlcnNlY3RpbmdcbiAgICAgIGlmIChzZWdtZW50U3RhcnRJbmRleCA9PT0gMSkge1xuXG4gICAgICAgIGlmIChzb3VyY2VUb1NlZ21lbnRPcmllbnRhdGlvbiA9PT0gJ2ludGVyc2VjdCcpIHtcbiAgICAgICAgICBuZXdXYXlwb2ludHMuc2hpZnQoKTtcbiAgICAgICAgICBuZXdXYXlwb2ludHNbMF0gPSBuZXdTZWdtZW50U3RhcnQ7XG4gICAgICAgICAgc2VnbWVudE9mZnNldC0tO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGRvY2tpbmcgcG9pbnQsIGFkZCBzZWdtZW50IGlmIG5vdCBpbnRlcnNlY3RpbmcgYW55bW9yZVxuICAgICAgZWxzZSB7XG4gICAgICAgIGlmIChzb3VyY2VUb1NlZ21lbnRPcmllbnRhdGlvbiAhPT0gJ2ludGVyc2VjdCcpIHtcbiAgICAgICAgICBuZXdXYXlwb2ludHMudW5zaGlmdChzZWdtZW50U3RhcnQpO1xuICAgICAgICAgIHNlZ21lbnRPZmZzZXQrKztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGhhbmRsZSBsYXN0IHNlZ21lbnRcbiAgICBpZiAoc2VnbWVudEVuZEluZGV4ID4gd2F5cG9pbnRDb3VudCAtIDMpIHtcbiAgICAgIHRhcmdldFRvU2VnbWVudE9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24oY29ubmVjdGlvbi50YXJnZXQsIG5ld1NlZ21lbnRFbmQpO1xuXG4gICAgICAvLyBsYXN0IGJlbmRwb2ludCwgcmVtb3ZlIGxhc3Qgc2VnbWVudCBpZiBpbnRlcnNlY3RpbmdcbiAgICAgIGlmIChzZWdtZW50RW5kSW5kZXggPT09IHdheXBvaW50Q291bnQgLSAyKSB7XG5cbiAgICAgICAgaWYgKHRhcmdldFRvU2VnbWVudE9yaWVudGF0aW9uID09PSAnaW50ZXJzZWN0Jykge1xuICAgICAgICAgIG5ld1dheXBvaW50cy5wb3AoKTtcbiAgICAgICAgICBuZXdXYXlwb2ludHNbbmV3V2F5cG9pbnRzLmxlbmd0aCAtIDFdID0gbmV3U2VnbWVudEVuZDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBsYXN0IGJlbmRwb2ludCwgcmVtb3ZlIGxhc3Qgc2VnbWVudCBpZiBpbnRlcnNlY3RpbmdcbiAgICAgIGVsc2Uge1xuICAgICAgICBpZiAodGFyZ2V0VG9TZWdtZW50T3JpZW50YXRpb24gIT09ICdpbnRlcnNlY3QnKSB7XG4gICAgICAgICAgbmV3V2F5cG9pbnRzLnB1c2goc2VnbWVudEVuZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyB1cGRhdGUgY29ubmVjdGlvbiB3YXlwb2ludHNcbiAgICBjb250ZXh0Lm5ld1dheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gY3JvcENvbm5lY3Rpb24oY29ubmVjdGlvbiwgbmV3V2F5cG9pbnRzKTtcblxuICAgIC8vIHVwZGF0ZSBkcmFnZ2VyIHBvc2l0aW9uXG4gICAgdXBkYXRlRHJhZ2dlcihjb250ZXh0LCBzZWdtZW50T2Zmc2V0LCBldmVudCk7XG5cbiAgICAvLyBzYXZlIHNlZ21lbnRPZmZzZXQgaW4gY29udGV4dFxuICAgIGNvbnRleHQubmV3U2VnbWVudFN0YXJ0SW5kZXggPSBzZWdtZW50U3RhcnRJbmRleCArIHNlZ21lbnRPZmZzZXQ7XG5cbiAgICAvLyByZWRyYXcgY29ubmVjdGlvblxuICAgIHJlZHJhd0Nvbm5lY3Rpb24oZXZlbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvblNlZ21lbnQubW92ZS5ob3ZlcicsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICBldmVudC5jb250ZXh0LmhvdmVyID0gZXZlbnQuaG92ZXI7XG4gICAgY2FudmFzLmFkZE1hcmtlcihldmVudC5ob3ZlciwgTUFSS0VSX0NPTk5FQ1RfSE9WRVIpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbXG4gICAgJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUub3V0JyxcbiAgICAnY29ubmVjdGlvblNlZ21lbnQubW92ZS5jbGVhbnVwJ1xuICBdLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgLy8gcmVtb3ZlIGNvbm5lY3QgbWFya2VyXG4gICAgLy8gaWYgaXQgd2FzIGFkZGVkXG4gICAgdmFyIGhvdmVyID0gZXZlbnQuY29udGV4dC5ob3ZlcjtcblxuICAgIGlmIChob3Zlcikge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgTUFSS0VSX0NPTk5FQ1RfSE9WRVIpO1xuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUuY2xlYW51cCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb247XG5cbiAgICAvLyByZW1vdmUgZHJhZ2dlciBnZnhcbiAgICBpZiAoY29udGV4dC5kcmFnZ2VyR2Z4KSB7XG4gICAgICBzdmdSZW1vdmUoY29udGV4dC5kcmFnZ2VyR2Z4KTtcbiAgICB9XG5cbiAgICBjYW52YXMucmVtb3ZlTWFya2VyKGNvbm5lY3Rpb24sIE1BUktFUl9DT05ORUNUX1VQREFUSU5HKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oW1xuICAgICdjb25uZWN0aW9uU2VnbWVudC5tb3ZlLmNhbmNlbCcsXG4gICAgJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUuZW5kJ1xuICBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbjtcblxuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gY29udGV4dC5vcmlnaW5hbFdheXBvaW50cztcblxuICAgIHJlZHJhd0Nvbm5lY3Rpb24oZXZlbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvblNlZ21lbnQubW92ZS5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgICBuZXdXYXlwb2ludHMgPSBjb250ZXh0Lm5ld1dheXBvaW50cyxcbiAgICAgICAgbmV3U2VnbWVudFN0YXJ0SW5kZXggPSBjb250ZXh0Lm5ld1NlZ21lbnRTdGFydEluZGV4O1xuXG4gICAgLy8gZW5zdXJlIHdlIGhhdmUgYWN0dWFsIHBpeGVsIHZhbHVlcyBiZW5kcG9pbnRcbiAgICAvLyBjb29yZGluYXRlcyAoaW1wb3J0YW50IHdoZW4gem9vbSBsZXZlbCB3YXMgPiAxIGR1cmluZyBtb3ZlKVxuICAgIG5ld1dheXBvaW50cyA9IG5ld1dheXBvaW50cy5tYXAoZnVuY3Rpb24ocCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgb3JpZ2luYWw6IHAub3JpZ2luYWwsXG4gICAgICAgIHg6IE1hdGgucm91bmQocC54KSxcbiAgICAgICAgeTogTWF0aC5yb3VuZChwLnkpXG4gICAgICB9O1xuICAgIH0pO1xuXG4gICAgLy8gYXBwbHkgZmlsdGVyIHJlZHVuYW50IHdheXBvaW50c1xuICAgIHZhciBmaWx0ZXJlZCA9IGZpbHRlclJlZHVuZGFudFdheXBvaW50cyhuZXdXYXlwb2ludHMsIG5ld1NlZ21lbnRTdGFydEluZGV4KTtcblxuICAgIC8vIGdldCBmaWx0ZXJlZCB3YXlwb2ludHNcbiAgICB2YXIgZmlsdGVyZWRXYXlwb2ludHMgPSBmaWx0ZXJlZC53YXlwb2ludHMsXG4gICAgICAgIGNyb3BwZWRXYXlwb2ludHMgPSBjcm9wQ29ubmVjdGlvbihjb25uZWN0aW9uLCBmaWx0ZXJlZFdheXBvaW50cyksXG4gICAgICAgIHNlZ21lbnRPZmZzZXQgPSBmaWx0ZXJlZC5zZWdtZW50T2Zmc2V0O1xuXG4gICAgdmFyIGhpbnRzID0ge1xuICAgICAgc2VnbWVudE1vdmU6IHtcbiAgICAgICAgc2VnbWVudFN0YXJ0SW5kZXg6IGNvbnRleHQuc2VnbWVudFN0YXJ0SW5kZXgsXG4gICAgICAgIG5ld1NlZ21lbnRTdGFydEluZGV4OiBuZXdTZWdtZW50U3RhcnRJbmRleCArIHNlZ21lbnRPZmZzZXRcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgbW9kZWxpbmcudXBkYXRlV2F5cG9pbnRzKGNvbm5lY3Rpb24sIGNyb3BwZWRXYXlwb2ludHMsIGhpbnRzKTtcbiAgfSk7XG59XG5cbkNvbm5lY3Rpb25TZWdtZW50TW92ZS4kaW5qZWN0ID0gW1xuICAnaW5qZWN0b3InLFxuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ2RyYWdnaW5nJyxcbiAgJ2dyYXBoaWNzRmFjdG9yeScsXG4gICdtb2RlbGluZydcbl07XG4iLCJpbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuaW1wb3J0IFJ1bGVzTW9kdWxlIGZyb20gJy4uL3J1bGVzJztcblxuaW1wb3J0IEJlbmRwb2ludHMgZnJvbSAnLi9CZW5kcG9pbnRzJztcbmltcG9ydCBCZW5kcG9pbnRNb3ZlIGZyb20gJy4vQmVuZHBvaW50TW92ZSc7XG5pbXBvcnQgQmVuZHBvaW50TW92ZVByZXZpZXcgZnJvbSAnLi9CZW5kcG9pbnRNb3ZlUHJldmlldyc7XG5pbXBvcnQgQ29ubmVjdGlvblNlZ21lbnRNb3ZlIGZyb20gJy4vQ29ubmVjdGlvblNlZ21lbnRNb3ZlJztcbmltcG9ydCBCZW5kcG9pbnRTbmFwcGluZyBmcm9tICcuL0JlbmRwb2ludFNuYXBwaW5nJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgRHJhZ2dpbmdNb2R1bGUsXG4gICAgUnVsZXNNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2JlbmRwb2ludHMnLCAnYmVuZHBvaW50U25hcHBpbmcnLCAnYmVuZHBvaW50TW92ZVByZXZpZXcnIF0sXG4gIGJlbmRwb2ludHM6IFsgJ3R5cGUnLCBCZW5kcG9pbnRzIF0sXG4gIGJlbmRwb2ludE1vdmU6IFsgJ3R5cGUnLCBCZW5kcG9pbnRNb3ZlIF0sXG4gIGJlbmRwb2ludE1vdmVQcmV2aWV3OiBbICd0eXBlJywgQmVuZHBvaW50TW92ZVByZXZpZXcgXSxcbiAgY29ubmVjdGlvblNlZ21lbnRNb3ZlOiBbICd0eXBlJywgQ29ubmVjdGlvblNlZ21lbnRNb3ZlIF0sXG4gIGJlbmRwb2ludFNuYXBwaW5nOiBbICd0eXBlJywgQmVuZHBvaW50U25hcHBpbmcgXVxufTtcbiIsImltcG9ydCB7XG4gIGdldFR5cGUgYXMgZ2V0RWxlbWVudFR5cGVcbn0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbi8qKlxuICogQWRkcyBjaGFuZ2Ugc3VwcG9ydCB0byB0aGUgZGlhZ3JhbSwgaW5jbHVkaW5nXG4gKlxuICogPHVsPlxuICogICA8bGk+cmVkcmF3aW5nIHNoYXBlcyBhbmQgY29ubmVjdGlvbnMgb24gY2hhbmdlPC9saT5cbiAqIDwvdWw+XG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcbiAqIEBwYXJhbSB7R3JhcGhpY3NGYWN0b3J5fSBncmFwaGljc0ZhY3RvcnlcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ2hhbmdlU3VwcG9ydChcbiAgICBldmVudEJ1cywgY2FudmFzLCBlbGVtZW50UmVnaXN0cnksXG4gICAgZ3JhcGhpY3NGYWN0b3J5KSB7XG5cblxuICAvLyByZWRyYXcgc2hhcGVzIC8gY29ubmVjdGlvbnMgb24gY2hhbmdlXG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQuY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQ7XG5cbiAgICAvLyBlbGVtZW50IG1pZ2h0IGhhdmUgYmVlbiBkZWxldGVkIGFuZCByZXBsYWNlZCBieSBuZXcgZWxlbWVudCB3aXRoIHNhbWUgSURcbiAgICAvLyB0aHVzIGNoZWNrIGZvciBwYXJlbnQgb2YgZWxlbWVudCBleGNlcHQgZm9yIHJvb3QgZWxlbWVudFxuICAgIGlmIChlbGVtZW50LnBhcmVudCB8fCBlbGVtZW50ID09PSBjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSkge1xuICAgICAgZXZlbnQuZ2Z4ID0gZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIC8vIHNoYXBlICsgZ2Z4IG1heSBoYXZlIGJlZW4gZGVsZXRlZFxuICAgIGlmICghZXZlbnQuZ2Z4KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZXZlbnRCdXMuZmlyZShnZXRFbGVtZW50VHlwZShlbGVtZW50KSArICcuY2hhbmdlZCcsIGV2ZW50KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnRzLmNoYW5nZWQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGVsZW1lbnRzID0gZXZlbnQuZWxlbWVudHM7XG5cbiAgICBlbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uKGUpIHtcbiAgICAgIGV2ZW50QnVzLmZpcmUoJ2VsZW1lbnQuY2hhbmdlZCcsIHsgZWxlbWVudDogZSB9KTtcbiAgICB9KTtcblxuICAgIGdyYXBoaWNzRmFjdG9yeS51cGRhdGVDb250YWlubWVudHMoZWxlbWVudHMpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignc2hhcGUuY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZ3JhcGhpY3NGYWN0b3J5LnVwZGF0ZSgnc2hhcGUnLCBldmVudC5lbGVtZW50LCBldmVudC5nZngpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdGlvbi5jaGFuZ2VkJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBncmFwaGljc0ZhY3RvcnkudXBkYXRlKCdjb25uZWN0aW9uJywgZXZlbnQuZWxlbWVudCwgZXZlbnQuZ2Z4KTtcbiAgfSk7XG59XG5cbkNoYW5nZVN1cHBvcnQuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcycsXG4gICdlbGVtZW50UmVnaXN0cnknLFxuICAnZ3JhcGhpY3NGYWN0b3J5J1xuXTsiLCJpbXBvcnQgQ2hhbmdlU3VwcG9ydCBmcm9tICcuL0NoYW5nZVN1cHBvcnQnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdjaGFuZ2VTdXBwb3J0J10sXG4gIGNoYW5nZVN1cHBvcnQ6IFsgJ3R5cGUnLCBDaGFuZ2VTdXBwb3J0IF1cbn07IiwiLyoqXG4gKiBBIGNsaXAgYm9hcmQgc3R1YlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDbGlwYm9hcmQoKSB7fVxuXG5cbkNsaXBib2FyZC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9kYXRhO1xufTtcblxuQ2xpcGJvYXJkLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbihkYXRhKSB7XG4gIHRoaXMuX2RhdGEgPSBkYXRhO1xufTtcblxuQ2xpcGJvYXJkLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICB2YXIgZGF0YSA9IHRoaXMuX2RhdGE7XG5cbiAgZGVsZXRlIHRoaXMuX2RhdGE7XG5cbiAgcmV0dXJuIGRhdGE7XG59O1xuXG5DbGlwYm9hcmQucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuICF0aGlzLl9kYXRhO1xufTsiLCJpbXBvcnQgQ2xpcGJvYXJkIGZyb20gJy4vQ2xpcGJvYXJkJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBjbGlwYm9hcmQ6IFsgJ3R5cGUnLCBDbGlwYm9hcmQgXVxufTtcbiIsImltcG9ydCB7XG4gIGdldE1pZFxufSBmcm9tICcuLi8uLi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7XG4gIGlzTmlsLFxuICBpc09iamVjdFxufSBmcm9tICdtaW4tZGFzaCc7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ29ubmVjdChldmVudEJ1cywgZHJhZ2dpbmcsIG1vZGVsaW5nLCBydWxlcykge1xuXG4gIC8vIHJ1bGVzXG5cbiAgZnVuY3Rpb24gY2FuQ29ubmVjdChzb3VyY2UsIHRhcmdldCkge1xuICAgIHJldHVybiBydWxlcy5hbGxvd2VkKCdjb25uZWN0aW9uLmNyZWF0ZScsIHtcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNhbkNvbm5lY3RSZXZlcnNlKHNvdXJjZSwgdGFyZ2V0KSB7XG4gICAgcmV0dXJuIGNhbkNvbm5lY3QodGFyZ2V0LCBzb3VyY2UpO1xuICB9XG5cblxuICAvLyBldmVudCBoYW5kbGVyc1xuXG4gIGV2ZW50QnVzLm9uKCdjb25uZWN0LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHN0YXJ0ID0gY29udGV4dC5zdGFydCxcbiAgICAgICAgaG92ZXIgPSBldmVudC5ob3ZlcixcbiAgICAgICAgY2FuRXhlY3V0ZTtcblxuICAgIC8vIGNhY2hlIGhvdmVyIHN0YXRlXG4gICAgY29udGV4dC5ob3ZlciA9IGhvdmVyO1xuXG4gICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSA9IGNhbkNvbm5lY3Qoc3RhcnQsIGhvdmVyKTtcblxuICAgIC8vIGlnbm9yZSBob3ZlclxuICAgIGlmIChpc05pbChjYW5FeGVjdXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjYW5FeGVjdXRlICE9PSBmYWxzZSkge1xuICAgICAgY29udGV4dC5zb3VyY2UgPSBzdGFydDtcbiAgICAgIGNvbnRleHQudGFyZ2V0ID0gaG92ZXI7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlID0gY2FuQ29ubmVjdFJldmVyc2Uoc3RhcnQsIGhvdmVyKTtcblxuICAgIC8vIGlnbm9yZSBob3ZlclxuICAgIGlmIChpc05pbChjYW5FeGVjdXRlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChjYW5FeGVjdXRlICE9PSBmYWxzZSkge1xuICAgICAgY29udGV4dC5zb3VyY2UgPSBob3ZlcjtcbiAgICAgIGNvbnRleHQudGFyZ2V0ID0gc3RhcnQ7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdjb25uZWN0Lm91dCcsICdjb25uZWN0LmNsZWFudXAnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0O1xuXG4gICAgY29udGV4dC5ob3ZlciA9IG51bGw7XG4gICAgY29udGV4dC5zb3VyY2UgPSBudWxsO1xuICAgIGNvbnRleHQudGFyZ2V0ID0gbnVsbDtcblxuICAgIGNvbnRleHQuY2FuRXhlY3V0ZSA9IGZhbHNlO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdC5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSxcbiAgICAgICAgY29ubmVjdGlvblN0YXJ0ID0gY29udGV4dC5jb25uZWN0aW9uU3RhcnQsXG4gICAgICAgIGNvbm5lY3Rpb25FbmQgPSB7XG4gICAgICAgICAgeDogZXZlbnQueCxcbiAgICAgICAgICB5OiBldmVudC55XG4gICAgICAgIH0sXG4gICAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIGlmICghY2FuRXhlY3V0ZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHZhciBhdHRycyA9IG51bGwsXG4gICAgICAgIGhpbnRzID0ge1xuICAgICAgICAgIGNvbm5lY3Rpb25TdGFydDogaXNSZXZlcnNlKGNvbnRleHQpID8gY29ubmVjdGlvbkVuZCA6IGNvbm5lY3Rpb25TdGFydCxcbiAgICAgICAgICBjb25uZWN0aW9uRW5kOiBpc1JldmVyc2UoY29udGV4dCkgPyBjb25uZWN0aW9uU3RhcnQgOiBjb25uZWN0aW9uRW5kXG4gICAgICAgIH07XG5cbiAgICBpZiAoaXNPYmplY3QoY2FuRXhlY3V0ZSkpIHtcbiAgICAgIGF0dHJzID0gY2FuRXhlY3V0ZTtcbiAgICB9XG5cbiAgICBtb2RlbGluZy5jb25uZWN0KHNvdXJjZSwgdGFyZ2V0LCBhdHRycywgaGludHMpO1xuICB9KTtcblxuXG4gIC8vIEFQSVxuXG4gIC8qKlxuICAgKiBTdGFydCBjb25uZWN0IG9wZXJhdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtET01FdmVudH0gZXZlbnRcbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gc3RhcnRcbiAgICogQHBhcmFtIHtQb2ludH0gW2Nvbm5lY3Rpb25TdGFydF1cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXV0b0FjdGl2YXRlPWZhbHNlXVxuICAgKi9cbiAgdGhpcy5zdGFydCA9IGZ1bmN0aW9uKGV2ZW50LCBzdGFydCwgY29ubmVjdGlvblN0YXJ0LCBhdXRvQWN0aXZhdGUpIHtcbiAgICBpZiAoIWlzT2JqZWN0KGNvbm5lY3Rpb25TdGFydCkpIHtcbiAgICAgIGF1dG9BY3RpdmF0ZSA9IGNvbm5lY3Rpb25TdGFydDtcbiAgICAgIGNvbm5lY3Rpb25TdGFydCA9IGdldE1pZChzdGFydCk7XG4gICAgfVxuXG4gICAgZHJhZ2dpbmcuaW5pdChldmVudCwgJ2Nvbm5lY3QnLCB7XG4gICAgICBhdXRvQWN0aXZhdGU6IGF1dG9BY3RpdmF0ZSxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgc2hhcGU6IHN0YXJ0LFxuICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgIGNvbm5lY3Rpb25TdGFydDogY29ubmVjdGlvblN0YXJ0XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn1cblxuQ29ubmVjdC4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZHJhZ2dpbmcnLFxuICAnbW9kZWxpbmcnLFxuICAncnVsZXMnXG5dO1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5leHBvcnQgZnVuY3Rpb24gaXNSZXZlcnNlKGNvbnRleHQpIHtcbiAgdmFyIGhvdmVyID0gY29udGV4dC5ob3ZlcixcbiAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgdGFyZ2V0ID0gY29udGV4dC50YXJnZXQ7XG5cbiAgcmV0dXJuIGhvdmVyICYmIHNvdXJjZSAmJiBob3ZlciA9PT0gc291cmNlICYmIHNvdXJjZSAhPT0gdGFyZ2V0O1xufSIsImltcG9ydCB7IGlzUmV2ZXJzZSB9IGZyb20gJy4vQ29ubmVjdCc7XG5cbnZhciBISUdIX1BSSU9SSVRZID0gMTEwMCxcbiAgICBMT1dfUFJJT1JJVFkgPSA5MDA7XG5cbnZhciBNQVJLRVJfT0sgPSAnY29ubmVjdC1vaycsXG4gICAgTUFSS0VSX05PVF9PSyA9ICdjb25uZWN0LW5vdC1vayc7XG5cbi8qKlxuICogU2hvd3MgY29ubmVjdGlvbiBwcmV2aWV3IGR1cmluZyBjb25uZWN0LlxuICpcbiAqIEBwYXJhbSB7ZGlkaS5JbmplY3Rvcn0gaW5qZWN0b3JcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvbm5lY3RQcmV2aWV3KGluamVjdG9yLCBldmVudEJ1cywgY2FudmFzKSB7XG4gIHZhciBjb25uZWN0aW9uUHJldmlldyA9IGluamVjdG9yLmdldCgnY29ubmVjdGlvblByZXZpZXcnLCBmYWxzZSk7XG5cbiAgY29ubmVjdGlvblByZXZpZXcgJiYgZXZlbnRCdXMub24oJ2Nvbm5lY3QubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjYW5Db25uZWN0ID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBob3ZlciA9IGNvbnRleHQuaG92ZXIsXG4gICAgICAgIHNvdXJjZSA9IGNvbnRleHQuc291cmNlLFxuICAgICAgICBzdGFydCA9IGNvbnRleHQuc3RhcnQsXG4gICAgICAgIHN0YXJ0UG9zaXRpb24gPSBjb250ZXh0LnN0YXJ0UG9zaXRpb24sXG4gICAgICAgIGNvbm5lY3Rpb25TdGFydCA9IGNvbnRleHQuY29ubmVjdGlvblN0YXJ0LFxuICAgICAgICBjb25uZWN0aW9uRW5kID0gY29udGV4dC5jb25uZWN0aW9uRW5kLFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIGlmICghY29ubmVjdGlvblN0YXJ0KSB7XG4gICAgICBjb25uZWN0aW9uU3RhcnQgPSBpc1JldmVyc2UoY29udGV4dCkgPyB7XG4gICAgICAgIHg6IGV2ZW50LngsXG4gICAgICAgIHk6IGV2ZW50LnlcbiAgICAgIH0gOiBzdGFydFBvc2l0aW9uO1xuICAgIH1cblxuICAgIGlmICghY29ubmVjdGlvbkVuZCkge1xuICAgICAgY29ubmVjdGlvbkVuZCA9IGlzUmV2ZXJzZShjb250ZXh0KSA/IHN0YXJ0UG9zaXRpb24gOiB7XG4gICAgICAgIHg6IGV2ZW50LngsXG4gICAgICAgIHk6IGV2ZW50LnlcbiAgICAgIH07XG4gICAgfVxuXG4gICAgY29ubmVjdGlvblByZXZpZXcuZHJhd1ByZXZpZXcoY29udGV4dCwgY2FuQ29ubmVjdCwge1xuICAgICAgc291cmNlOiBzb3VyY2UgfHwgc3RhcnQsXG4gICAgICB0YXJnZXQ6IHRhcmdldCB8fCBob3ZlcixcbiAgICAgIGNvbm5lY3Rpb25TdGFydDogY29ubmVjdGlvblN0YXJ0LFxuICAgICAgY29ubmVjdGlvbkVuZDogY29ubmVjdGlvbkVuZFxuICAgIH0pO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY29ubmVjdC5ob3ZlcicsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGhvdmVyID0gZXZlbnQuaG92ZXIsXG4gICAgICAgIGNhbkV4ZWN1dGUgPSBjb250ZXh0LmNhbkV4ZWN1dGU7XG5cbiAgICAvLyBpZ25vcmUgaG92ZXJcbiAgICBpZiAoY2FuRXhlY3V0ZSA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNhbnZhcy5hZGRNYXJrZXIoaG92ZXIsIGNhbkV4ZWN1dGUgPyBNQVJLRVJfT0sgOiBNQVJLRVJfTk9UX09LKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oW1xuICAgICdjb25uZWN0Lm91dCcsXG4gICAgJ2Nvbm5lY3QuY2xlYW51cCdcbiAgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgaG92ZXIgPSBldmVudC5ob3ZlcjtcblxuICAgIGlmIChob3Zlcikge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihob3ZlciwgTUFSS0VSX09LKTtcbiAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoaG92ZXIsIE1BUktFUl9OT1RfT0spO1xuICAgIH1cbiAgfSk7XG5cbiAgY29ubmVjdGlvblByZXZpZXcgJiYgZXZlbnRCdXMub24oJ2Nvbm5lY3QuY2xlYW51cCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgY29ubmVjdGlvblByZXZpZXcuY2xlYW5VcChldmVudC5jb250ZXh0KTtcbiAgfSk7XG59XG5cbkNvbm5lY3RQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdpbmplY3RvcicsXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnXG5dO1xuIiwiaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuaW1wb3J0IFJ1bGVzTW9kdWxlIGZyb20gJy4uL3J1bGVzJztcbmltcG9ydCBEcmFnZ2luZ01vZHVsZSBmcm9tICcuLi9kcmFnZ2luZyc7XG5cbmltcG9ydCBDb25uZWN0IGZyb20gJy4vQ29ubmVjdCc7XG5pbXBvcnQgQ29ubmVjdFByZXZpZXcgZnJvbSAnLi9Db25uZWN0UHJldmlldyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBTZWxlY3Rpb25Nb2R1bGUsXG4gICAgUnVsZXNNb2R1bGUsXG4gICAgRHJhZ2dpbmdNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFtcbiAgICAnY29ubmVjdFByZXZpZXcnXG4gIF0sXG4gIGNvbm5lY3Q6IFsgJ3R5cGUnLCBDb25uZWN0IF0sXG4gIGNvbm5lY3RQcmV2aWV3OiBbICd0eXBlJywgQ29ubmVjdFByZXZpZXcgXVxufTtcbiIsImltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICByZW1vdmUgYXMgc3ZnUmVtb3ZlLFxuICBjbGVhciBhcyBzdmdDbGVhclxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7XG4gIGlzT2JqZWN0XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0RWxlbWVudExpbmVJbnRlcnNlY3Rpb24sXG4gIGdldE1pZFxufSBmcm9tICcuLi8uLi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cblxudmFyIE1BUktFUl9DT05ORUNUSU9OX1BSRVZJRVcgPSAnZGpzLWNvbm5lY3Rpb24tcHJldmlldyc7XG5cbi8qKlxuICogRHJhd3MgY29ubmVjdGlvbiBwcmV2aWV3LiBPcHRpb25hbGx5LCB0aGlzIGNhbiB1c2UgbGF5b3V0ZXIgYW5kIGNvbm5lY3Rpb24gZG9ja2luZyB0byBkcmF3XG4gKiBiZXR0ZXIgbG9va2luZyBwcmV2aWV3cy5cbiAqXG4gKiBAcGFyYW0ge2RpZGkuSW5qZWN0b3J9IGluamVjdG9yXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge0dyYXBoaWNzRmFjdG9yeX0gZ3JhcGhpY3NGYWN0b3J5XG4gKiBAcGFyYW0ge0VsZW1lbnRGYWN0b3J5fSBlbGVtZW50RmFjdG9yeVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDb25uZWN0aW9uUHJldmlldyhcbiAgICBpbmplY3RvcixcbiAgICBjYW52YXMsXG4gICAgZ3JhcGhpY3NGYWN0b3J5LFxuICAgIGVsZW1lbnRGYWN0b3J5XG4pIHtcbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xuICB0aGlzLl9ncmFwaGljc0ZhY3RvcnkgPSBncmFwaGljc0ZhY3Rvcnk7XG4gIHRoaXMuX2VsZW1lbnRGYWN0b3J5ID0gZWxlbWVudEZhY3Rvcnk7XG5cbiAgLy8gb3B0aW9uYWwgY29tcG9uZW50c1xuICB0aGlzLl9jb25uZWN0aW9uRG9ja2luZyA9IGluamVjdG9yLmdldCgnY29ubmVjdGlvbkRvY2tpbmcnLCBmYWxzZSk7XG4gIHRoaXMuX2xheW91dGVyID0gaW5qZWN0b3IuZ2V0KCdsYXlvdXRlcicsIGZhbHNlKTtcbn1cblxuQ29ubmVjdGlvblByZXZpZXcuJGluamVjdCA9IFtcbiAgJ2luamVjdG9yJyxcbiAgJ2NhbnZhcycsXG4gICdncmFwaGljc0ZhY3RvcnknLFxuICAnZWxlbWVudEZhY3RvcnknXG5dO1xuXG4vKipcbiAqIERyYXcgY29ubmVjdGlvbiBwcmV2aWV3LlxuICpcbiAqIFByb3ZpZGUgYXQgbGVhc3Qgb25lIG9mIDxzb3VyY2UsIGNvbm5lY3Rpb25TdGFydD4gYW5kIDx0YXJnZXQsIGNvbm5lY3Rpb25FbmQ+IHRvIGNyZWF0ZSBhIHByZXZpZXcuXG4gKiBJbiB0aGUgY2xlYW4gdXAgc3RhZ2UsIGNhbGwgYGNvbm5lY3Rpb25QcmV2aWV3I2NsZWFuVXBgIHdpdGggdGhlIGNvbnRleHQgdG8gcmVtb3ZlIHByZXZpZXcuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7T2JqZWN0fGJvb2xlYW59IGNhbkNvbm5lY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBoaW50c1xuICogQHBhcmFtIHtkanMubW9kZWwuc2hhcGV9IFtoaW50cy5zb3VyY2VdIHNvdXJjZSBlbGVtZW50XG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5zaGFwZX0gW2hpbnRzLnRhcmdldF0gdGFyZ2V0IGVsZW1lbnRcbiAqIEBwYXJhbSB7UG9pbnR9IFtoaW50cy5jb25uZWN0aW9uU3RhcnRdIGNvbm5lY3Rpb24gcHJldmlldyBzdGFydFxuICogQHBhcmFtIHtQb2ludH0gW2hpbnRzLmNvbm5lY3Rpb25FbmRdIGNvbm5lY3Rpb24gcHJldmlldyBlbmRcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSBbaGludHMud2F5cG9pbnRzXSBwcm92aWRlZCB3YXlwb2ludHMgZm9yIHByZXZpZXdcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2hpbnRzLm5vTGF5b3V0XSB0cnVlIGlmIHByZXZpZXcgc2hvdWxkIG5vdCBiZSBsYWlkIG91dFxuICogQHBhcmFtIHtib29sZWFufSBbaGludHMubm9Dcm9wcGluZ10gdHJ1ZSBpZiBwcmV2aWV3IHNob3VsZCBub3QgYmUgY3JvcHBlZFxuICogQHBhcmFtIHtib29sZWFufSBbaGludHMubm9Ob29wXSB0cnVlIGlmIHNpbXBsZSBjb25uZWN0aW9uIHNob3VsZCBub3QgYmUgZHJhd25cbiAqL1xuQ29ubmVjdGlvblByZXZpZXcucHJvdG90eXBlLmRyYXdQcmV2aWV3ID0gZnVuY3Rpb24oY29udGV4dCwgY2FuQ29ubmVjdCwgaGludHMpIHtcblxuICBoaW50cyA9IGhpbnRzIHx8IHt9O1xuXG4gIHZhciBjb25uZWN0aW9uUHJldmlld0dmeCA9IGNvbnRleHQuY29ubmVjdGlvblByZXZpZXdHZngsXG4gICAgICBnZXRDb25uZWN0aW9uID0gY29udGV4dC5nZXRDb25uZWN0aW9uLFxuICAgICAgc291cmNlID0gaGludHMuc291cmNlLFxuICAgICAgdGFyZ2V0ID0gaGludHMudGFyZ2V0LFxuICAgICAgd2F5cG9pbnRzID0gaGludHMud2F5cG9pbnRzLFxuICAgICAgY29ubmVjdGlvblN0YXJ0ID0gaGludHMuY29ubmVjdGlvblN0YXJ0LFxuICAgICAgY29ubmVjdGlvbkVuZCA9IGhpbnRzLmNvbm5lY3Rpb25FbmQsXG4gICAgICBub0xheW91dCA9IGhpbnRzLm5vTGF5b3V0LFxuICAgICAgbm9Dcm9wcGluZyA9IGhpbnRzLm5vQ3JvcHBpbmcsXG4gICAgICBub05vb3AgPSBoaW50cy5ub05vb3AsXG4gICAgICBjb25uZWN0aW9uO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBpZiAoIWNvbm5lY3Rpb25QcmV2aWV3R2Z4KSB7XG4gICAgY29ubmVjdGlvblByZXZpZXdHZnggPSBjb250ZXh0LmNvbm5lY3Rpb25QcmV2aWV3R2Z4ID0gdGhpcy5jcmVhdGVDb25uZWN0aW9uUHJldmlld0dmeCgpO1xuICB9XG5cbiAgc3ZnQ2xlYXIoY29ubmVjdGlvblByZXZpZXdHZngpO1xuXG4gIGlmICghZ2V0Q29ubmVjdGlvbikge1xuICAgIGdldENvbm5lY3Rpb24gPSBjb250ZXh0LmdldENvbm5lY3Rpb24gPSBjYWNoZVJldHVyblZhbHVlcyhmdW5jdGlvbihjYW5Db25uZWN0LCBzb3VyY2UsIHRhcmdldCkge1xuICAgICAgcmV0dXJuIHNlbGYuZ2V0Q29ubmVjdGlvbihjYW5Db25uZWN0LCBzb3VyY2UsIHRhcmdldCk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoY2FuQ29ubmVjdCkge1xuICAgIGNvbm5lY3Rpb24gPSBnZXRDb25uZWN0aW9uKGNhbkNvbm5lY3QsIHNvdXJjZSwgdGFyZ2V0KTtcbiAgfVxuXG4gIGlmICghY29ubmVjdGlvbikge1xuICAgICFub05vb3AgJiYgdGhpcy5kcmF3Tm9vcFByZXZpZXcoY29ubmVjdGlvblByZXZpZXdHZngsIGhpbnRzKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25uZWN0aW9uLndheXBvaW50cyA9IHdheXBvaW50cyB8fCBbXTtcblxuICAvLyBvcHRpb25hbCBsYXlvdXRcbiAgaWYgKHRoaXMuX2xheW91dGVyICYmICFub0xheW91dCkge1xuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gdGhpcy5fbGF5b3V0ZXIubGF5b3V0Q29ubmVjdGlvbihjb25uZWN0aW9uLCB7XG4gICAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICAgIHRhcmdldDogdGFyZ2V0LFxuICAgICAgY29ubmVjdGlvblN0YXJ0OiBjb25uZWN0aW9uU3RhcnQsXG4gICAgICBjb25uZWN0aW9uRW5kOiBjb25uZWN0aW9uRW5kLFxuICAgICAgd2F5cG9pbnRzOiBoaW50cy53YXlwb2ludHMgfHwgY29ubmVjdGlvbi53YXlwb2ludHNcbiAgICB9KTtcbiAgfVxuXG4gIC8vIGZhbGxiYWNrIGlmIG5vIHdheXBvaW50cyB3ZXJlIHByb3ZpZGVkIG5vciBjcmVhdGVkIHdpdGggbGF5b3V0ZXJcbiAgaWYgKCFjb25uZWN0aW9uLndheXBvaW50cyB8fCAhY29ubmVjdGlvbi53YXlwb2ludHMubGVuZ3RoKSB7XG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBbXG4gICAgICBzb3VyY2UgPyBnZXRNaWQoc291cmNlKSA6IGNvbm5lY3Rpb25TdGFydCxcbiAgICAgIHRhcmdldCA/IGdldE1pZCh0YXJnZXQpIDogY29ubmVjdGlvbkVuZFxuICAgIF07XG4gIH1cblxuICAvLyBvcHRpb25hbCBjcm9wcGluZ1xuICBpZiAodGhpcy5fY29ubmVjdGlvbkRvY2tpbmcgJiYgKHNvdXJjZSB8fCB0YXJnZXQpICYmICFub0Nyb3BwaW5nKSB7XG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSB0aGlzLl9jb25uZWN0aW9uRG9ja2luZy5nZXRDcm9wcGVkV2F5cG9pbnRzKGNvbm5lY3Rpb24sIHNvdXJjZSwgdGFyZ2V0KTtcbiAgfVxuXG4gIHRoaXMuX2dyYXBoaWNzRmFjdG9yeS5kcmF3Q29ubmVjdGlvbihjb25uZWN0aW9uUHJldmlld0dmeCwgY29ubmVjdGlvbik7XG59O1xuXG4vKipcbiAqIERyYXcgc2ltcGxlIGNvbm5lY3Rpb24gYmV0d2VlbiBzb3VyY2UgYW5kIHRhcmdldCBvciBwcm92aWRlZCBwb2ludHMuXG4gKlxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBjb25uZWN0aW9uUHJldmlld0dmeCBjb250YWluZXIgZm9yIHRoZSBjb25uZWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gaGludHNcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLnNoYXBlfSBbaGludHMuc291cmNlXSBzb3VyY2UgZWxlbWVudFxuICogQHBhcmFtIHtkanMubW9kZWwuc2hhcGV9IFtoaW50cy50YXJnZXRdIHRhcmdldCBlbGVtZW50XG4gKiBAcGFyYW0ge1BvaW50fSBbaGludHMuY29ubmVjdGlvblN0YXJ0XSByZXF1aXJlZCBpZiBzb3VyY2UgaXMgbm90IHByb3ZpZGVkXG4gKiBAcGFyYW0ge1BvaW50fSBbaGludHMuY29ubmVjdGlvbkVuZF0gcmVxdWlyZWQgaWYgdGFyZ2V0IGlzIG5vdCBwcm92aWRlZFxuICovXG5Db25uZWN0aW9uUHJldmlldy5wcm90b3R5cGUuZHJhd05vb3BQcmV2aWV3ID0gZnVuY3Rpb24oY29ubmVjdGlvblByZXZpZXdHZngsIGhpbnRzKSB7XG4gIHZhciBzb3VyY2UgPSBoaW50cy5zb3VyY2UsXG4gICAgICB0YXJnZXQgPSBoaW50cy50YXJnZXQsXG4gICAgICBzdGFydCA9IGhpbnRzLmNvbm5lY3Rpb25TdGFydCB8fCBnZXRNaWQoc291cmNlKSxcbiAgICAgIGVuZCA9IGhpbnRzLmNvbm5lY3Rpb25FbmQgfHwgZ2V0TWlkKHRhcmdldCk7XG5cbiAgdmFyIHdheXBvaW50cyA9IHRoaXMuY3JvcFdheXBvaW50cyhzdGFydCwgZW5kLCBzb3VyY2UsIHRhcmdldCk7XG5cbiAgdmFyIGNvbm5lY3Rpb24gPSB0aGlzLmNyZWF0ZU5vb3BDb25uZWN0aW9uKHdheXBvaW50c1swXSwgd2F5cG9pbnRzWzFdKTtcblxuICBzdmdBcHBlbmQoY29ubmVjdGlvblByZXZpZXdHZngsIGNvbm5lY3Rpb24pO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gY3JvcHBlZCB3YXlwb2ludHMuXG4gKlxuICogQHBhcmFtIHtQb2ludH0gc3RhcnRcbiAqIEBwYXJhbSB7UG9pbnR9IGVuZFxuICogQHBhcmFtIHtkanMubW9kZWwuc2hhcGV9IHNvdXJjZVxuICogQHBhcmFtIHtkanMubW9kZWwuc2hhcGV9IHRhcmdldFxuICpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqL1xuQ29ubmVjdGlvblByZXZpZXcucHJvdG90eXBlLmNyb3BXYXlwb2ludHMgPSBmdW5jdGlvbihzdGFydCwgZW5kLCBzb3VyY2UsIHRhcmdldCkge1xuICB2YXIgZ3JhcGhpY3NGYWN0b3J5ID0gdGhpcy5fZ3JhcGhpY3NGYWN0b3J5LFxuICAgICAgc291cmNlUGF0aCA9IHNvdXJjZSAmJiBncmFwaGljc0ZhY3RvcnkuZ2V0U2hhcGVQYXRoKHNvdXJjZSksXG4gICAgICB0YXJnZXRQYXRoID0gdGFyZ2V0ICYmIGdyYXBoaWNzRmFjdG9yeS5nZXRTaGFwZVBhdGgodGFyZ2V0KSxcbiAgICAgIGNvbm5lY3Rpb25QYXRoID0gZ3JhcGhpY3NGYWN0b3J5LmdldENvbm5lY3Rpb25QYXRoKHsgd2F5cG9pbnRzOiBbIHN0YXJ0LCBlbmQgXSB9KTtcblxuICBzdGFydCA9IChzb3VyY2UgJiYgZ2V0RWxlbWVudExpbmVJbnRlcnNlY3Rpb24oc291cmNlUGF0aCwgY29ubmVjdGlvblBhdGgsIHRydWUpKSB8fCBzdGFydDtcbiAgZW5kID0gKHRhcmdldCAmJiBnZXRFbGVtZW50TGluZUludGVyc2VjdGlvbih0YXJnZXRQYXRoLCBjb25uZWN0aW9uUGF0aCwgZmFsc2UpKSB8fCBlbmQ7XG5cbiAgcmV0dXJuIFsgc3RhcnQsIGVuZCBdO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgY29ubmVjdGlvbiBwcmV2aWV3IGNvbnRhaW5lciBpZiBpdCBleGlzdHMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtjb250ZXh0XVxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBbY29udGV4dC5jb25uZWN0aW9uUHJldmlld0dmeF0gcHJldmlldyBjb250YWluZXJcbiAqL1xuQ29ubmVjdGlvblByZXZpZXcucHJvdG90eXBlLmNsZWFuVXAgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIGlmIChjb250ZXh0ICYmIGNvbnRleHQuY29ubmVjdGlvblByZXZpZXdHZngpIHtcbiAgICBzdmdSZW1vdmUoY29udGV4dC5jb25uZWN0aW9uUHJldmlld0dmeCk7XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGNvbm5lY3Rpb24gdGhhdCBjb25uZWN0cyBzb3VyY2UgYW5kIHRhcmdldC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxib29sZWFufSBjYW5Db25uZWN0XG4gKlxuICogQHJldHVybnMge2Rqcy5tb2RlbC5jb25uZWN0aW9ufVxuICovXG5Db25uZWN0aW9uUHJldmlldy5wcm90b3R5cGUuZ2V0Q29ubmVjdGlvbiA9IGZ1bmN0aW9uKGNhbkNvbm5lY3QpIHtcbiAgdmFyIGF0dHJzID0gZW5zdXJlQ29ubmVjdGlvbkF0dHJzKGNhbkNvbm5lY3QpO1xuXG4gIHJldHVybiB0aGlzLl9lbGVtZW50RmFjdG9yeS5jcmVhdGVDb25uZWN0aW9uKGF0dHJzKTtcbn07XG5cblxuLyoqXG4gKiBBZGQgYW5kIHJldHVybiBwcmV2aWV3IGdyYXBoaWNzLlxuICpcbiAqIEByZXR1cm5zIHtTVkdFbGVtZW50fVxuICovXG5Db25uZWN0aW9uUHJldmlldy5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvblByZXZpZXdHZnggPSBmdW5jdGlvbigpIHtcbiAgdmFyIGdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xuXG4gIHN2Z0F0dHIoZ2Z4LCB7XG4gICAgcG9pbnRlckV2ZW50czogJ25vbmUnXG4gIH0pO1xuXG4gIHN2Z0NsYXNzZXMoZ2Z4KS5hZGQoTUFSS0VSX0NPTk5FQ1RJT05fUFJFVklFVyk7XG5cbiAgc3ZnQXBwZW5kKHRoaXMuX2NhbnZhcy5nZXREZWZhdWx0TGF5ZXIoKSwgZ2Z4KTtcblxuICByZXR1cm4gZ2Z4O1xufTtcblxuLyoqXG4gKiBDcmVhdGUgYW5kIHJldHVybiBzaW1wbGUgY29ubmVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBzdGFydFxuICogQHBhcmFtIHtQb2ludH0gZW5kXG4gKlxuICogQHJldHVybnMge1NWR0VsZW1lbnR9XG4gKi9cbkNvbm5lY3Rpb25QcmV2aWV3LnByb3RvdHlwZS5jcmVhdGVOb29wQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGNvbm5lY3Rpb24gPSBzdmdDcmVhdGUoJ3BvbHlsaW5lJyk7XG5cbiAgc3ZnQXR0cihjb25uZWN0aW9uLCB7XG4gICAgJ3N0cm9rZSc6ICcjMzMzJyxcbiAgICAnc3Ryb2tlRGFzaGFycmF5JzogWyAxIF0sXG4gICAgJ3N0cm9rZVdpZHRoJzogMixcbiAgICAncG9pbnRlci1ldmVudHMnOiAnbm9uZSdcbiAgfSk7XG5cbiAgc3ZnQXR0cihjb25uZWN0aW9uLCB7ICdwb2ludHMnOiBbIHN0YXJ0LngsIHN0YXJ0LnksIGVuZC54LCBlbmQueSBdIH0pO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTtcblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbi8qKlxuICogUmV0dXJucyBmdW5jdGlvbiB0aGF0IHJldHVybnMgY2FjaGVkIHJldHVybiB2YWx1ZXMgcmVmZXJlbmNlZCBieSBzdHJpbmdpZmllZCBmaXJzdCBhcmd1bWVudC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICpcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICovXG5mdW5jdGlvbiBjYWNoZVJldHVyblZhbHVlcyhmbikge1xuICB2YXIgcmV0dXJuVmFsdWVzID0ge307XG5cbiAgLyoqXG4gICAqIFJldHVybiBjYWNoZWQgcmV0dXJuIHZhbHVlIHJlZmVyZW5jZWQgYnkgc3RyaW5naWZpZWQgZmlyc3QgYXJndW1lbnQuXG4gICAqXG4gICAqIEByZXR1cm5zIHsqfVxuICAgKi9cbiAgcmV0dXJuIGZ1bmN0aW9uKGZpcnN0QXJndW1lbnQpIHtcbiAgICB2YXIga2V5ID0gSlNPTi5zdHJpbmdpZnkoZmlyc3RBcmd1bWVudCk7XG5cbiAgICB2YXIgcmV0dXJuVmFsdWUgPSByZXR1cm5WYWx1ZXNba2V5XTtcblxuICAgIGlmICghcmV0dXJuVmFsdWUpIHtcbiAgICAgIHJldHVyblZhbHVlID0gcmV0dXJuVmFsdWVzW2tleV0gPSBmbi5hcHBseShudWxsLCBhcmd1bWVudHMpO1xuICAgIH1cblxuICAgIHJldHVybiByZXR1cm5WYWx1ZTtcbiAgfTtcbn1cblxuLyoqXG4gKiBFbnN1cmUgY29ubmVjdGlvbiBhdHRyaWJ1dGVzIGlzIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdHxib29sZWFufSBjYW5Db25uZWN0XG4gKlxuICogQHJldHVybnMge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gZW5zdXJlQ29ubmVjdGlvbkF0dHJzKGNhbkNvbm5lY3QpIHtcbiAgaWYgKGlzT2JqZWN0KGNhbkNvbm5lY3QpKSB7XG4gICAgcmV0dXJuIGNhbkNvbm5lY3Q7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG59XG4iLCJpbXBvcnQgQ29ubmVjdGlvblByZXZpZXcgZnJvbSAnLi9Db25uZWN0aW9uUHJldmlldyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2Nvbm5lY3Rpb25QcmV2aWV3JyBdLFxuICBjb25uZWN0aW9uUHJldmlldzogWyAndHlwZScsIENvbm5lY3Rpb25QcmV2aWV3IF1cbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGlzRnVuY3Rpb24sXG4gIGlzQXJyYXksXG4gIGZvckVhY2gsXG4gIGlzRGVmaW5lZFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBldmVudCBhcyBkb21FdmVudCxcbiAgYXR0ciBhcyBkb21BdHRyLFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgY2xhc3NlcyBhcyBkb21DbGFzc2VzLFxuICBkb21pZnkgYXMgZG9taWZ5XG59IGZyb20gJ21pbi1kb20nO1xuXG52YXIgZW50cnlTZWxlY3RvciA9ICcuZW50cnknO1xuXG52YXIgREVGQVVMVF9QUklPUklUWSA9IDEwMDA7XG5cblxuLyoqXG4gKiBBIGNvbnRleHQgcGFkIHRoYXQgZGlzcGxheXMgZWxlbWVudCBzcGVjaWZpYywgY29udGV4dHVhbCBhY3Rpb25zIG5leHRcbiAqIHRvIGEgZGlhZ3JhbSBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWdcbiAqIEBwYXJhbSB7Ym9vbGVhbnxPYmplY3R9IFtjb25maWcuc2NhbGU9eyBtaW46IDEuMCwgbWF4OiAxLjUgfV1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbY29uZmlnLnNjYWxlLm1pbl1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbY29uZmlnLnNjYWxlLm1heF1cbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge092ZXJsYXlzfSBvdmVybGF5c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDb250ZXh0UGFkKGNvbmZpZywgZXZlbnRCdXMsIG92ZXJsYXlzKSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fb3ZlcmxheXMgPSBvdmVybGF5cztcblxuICB2YXIgc2NhbGUgPSBpc0RlZmluZWQoY29uZmlnICYmIGNvbmZpZy5zY2FsZSkgPyBjb25maWcuc2NhbGUgOiB7XG4gICAgbWluOiAxLFxuICAgIG1heDogMS41XG4gIH07XG5cbiAgdGhpcy5fb3ZlcmxheXNDb25maWcgPSB7XG4gICAgcG9zaXRpb246IHtcbiAgICAgIHJpZ2h0OiAtOSxcbiAgICAgIHRvcDogLTZcbiAgICB9LFxuICAgIHNjYWxlOiBzY2FsZVxuICB9O1xuXG4gIHRoaXMuX2N1cnJlbnQgPSBudWxsO1xuXG4gIHRoaXMuX2luaXQoKTtcbn1cblxuQ29udGV4dFBhZC4kaW5qZWN0ID0gW1xuICAnY29uZmlnLmNvbnRleHRQYWQnLFxuICAnZXZlbnRCdXMnLFxuICAnb3ZlcmxheXMnXG5dO1xuXG5cbi8qKlxuICogUmVnaXN0ZXJzIGV2ZW50cyBuZWVkZWQgZm9yIGludGVyYWN0aW9uIHdpdGggb3RoZXIgY29tcG9uZW50c1xuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBldmVudEJ1cyA9IHRoaXMuX2V2ZW50QnVzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbignc2VsZWN0aW9uLmNoYW5nZWQnLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgc2VsZWN0aW9uID0gZS5uZXdTZWxlY3Rpb247XG5cbiAgICBpZiAoc2VsZWN0aW9uLmxlbmd0aCA9PT0gMSkge1xuICAgICAgc2VsZi5vcGVuKHNlbGVjdGlvblswXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlbGYuY2xvc2UoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50cy5kZWxldGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBlbGVtZW50cyA9IGV2ZW50LmVsZW1lbnRzO1xuXG4gICAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKHNlbGYuaXNPcGVuKGUpKSB7XG4gICAgICAgIHNlbGYuY2xvc2UoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQuY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBjdXJyZW50ID0gc2VsZi5fY3VycmVudDtcblxuICAgIC8vIGZvcmNlIHJlb3BlbiBpZiBlbGVtZW50IGZvciB3aGljaCB3ZSBhcmUgY3VycmVudGx5IG9wZW5lZCBjaGFuZ2VkXG4gICAgaWYgKGN1cnJlbnQgJiYgY3VycmVudC5lbGVtZW50ID09PSBlbGVtZW50KSB7XG4gICAgICBzZWxmLm9wZW4oZWxlbWVudCwgdHJ1ZSk7XG4gICAgfVxuICB9KTtcbn07XG5cblxuLyoqXG4gKiBSZWdpc3RlciBhIHByb3ZpZGVyIHdpdGggdGhlIGNvbnRleHQgcGFkXG4gKlxuICogQHBhcmFtICB7bnVtYmVyfSBbcHJpb3JpdHk9MTAwMF1cbiAqIEBwYXJhbSAge0NvbnRleHRQYWRQcm92aWRlcn0gcHJvdmlkZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY29udGV4dFBhZFByb3ZpZGVyID0ge1xuICAqICAgZ2V0Q29udGV4dFBhZEVudHJpZXM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgKiAgICAgcmV0dXJuIGZ1bmN0aW9uKGVudHJpZXMpIHtcbiAgKiAgICAgICByZXR1cm4ge1xuICAqICAgICAgICAgLi4uZW50cmllcyxcbiAgKiAgICAgICAgICdlbnRyeS0xJzoge1xuICAqICAgICAgICAgICBsYWJlbDogJ015IEVudHJ5JyxcbiAgKiAgICAgICAgICAgYWN0aW9uOiBmdW5jdGlvbigpIHsgYWxlcnQoXCJJIGhhdmUgYmVlbiBjbGlja2VkIVwiKTsgfVxuICAqICAgICAgICAgfVxuICAqICAgICAgIH07XG4gICogICAgIH1cbiAgKiAgIH1cbiAgKiB9O1xuICAqXG4gKiBjb250ZXh0UGFkLnJlZ2lzdGVyUHJvdmlkZXIoODAwLCBjb250ZXh0UGFkUHJvdmlkZXIpO1xuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS5yZWdpc3RlclByb3ZpZGVyID0gZnVuY3Rpb24ocHJpb3JpdHksIHByb3ZpZGVyKSB7XG4gIGlmICghcHJvdmlkZXIpIHtcbiAgICBwcm92aWRlciA9IHByaW9yaXR5O1xuICAgIHByaW9yaXR5ID0gREVGQVVMVF9QUklPUklUWTtcbiAgfVxuXG4gIHRoaXMuX2V2ZW50QnVzLm9uKCdjb250ZXh0UGFkLmdldFByb3ZpZGVycycsIHByaW9yaXR5LCBmdW5jdGlvbihldmVudCkge1xuICAgIGV2ZW50LnByb3ZpZGVycy5wdXNoKHByb3ZpZGVyKTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgY29udGV4dCBwYWQgZW50cmllcyBmb3IgYSBnaXZlbiBlbGVtZW50XG4gKlxuICogQHBhcmFtIHtkanMuZWxlbWVudC5CYXNlfSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7QXJyYXk8Q29udGV4dFBhZEVudHJ5RGVzY3JpcHRvcj59IGxpc3Qgb2YgZW50cmllc1xuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS5nZXRFbnRyaWVzID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICB2YXIgcHJvdmlkZXJzID0gdGhpcy5fZ2V0UHJvdmlkZXJzKCk7XG5cbiAgdmFyIGVudHJpZXMgPSB7fTtcblxuICAvLyBsb29wIHRocm91Z2ggYWxsIHByb3ZpZGVycyBhbmQgdGhlaXIgZW50cmllcy5cbiAgLy8gZ3JvdXAgZW50cmllcyBieSBpZCBzbyB0aGF0IG92ZXJyaWRpbmcgYW4gZW50cnkgaXMgcG9zc2libGVcbiAgZm9yRWFjaChwcm92aWRlcnMsIGZ1bmN0aW9uKHByb3ZpZGVyKSB7XG4gICAgdmFyIGVudHJpZXNPclVwZGF0ZXIgPSBwcm92aWRlci5nZXRDb250ZXh0UGFkRW50cmllcyhlbGVtZW50KTtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGVudHJpZXNPclVwZGF0ZXIpKSB7XG4gICAgICBlbnRyaWVzID0gZW50cmllc09yVXBkYXRlcihlbnRyaWVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yRWFjaChlbnRyaWVzT3JVcGRhdGVyLCBmdW5jdGlvbihlbnRyeSwgaWQpIHtcbiAgICAgICAgZW50cmllc1tpZF0gPSBlbnRyeTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGVudHJpZXM7XG59O1xuXG5cbi8qKlxuICogVHJpZ2dlciBhbiBhY3Rpb24gYXZhaWxhYmxlIG9uIHRoZSBvcGVuZWQgY29udGV4dCBwYWRcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGFjdGlvblxuICogQHBhcmFtICB7RXZlbnR9IGV2ZW50XG4gKiBAcGFyYW0gIHtib29sZWFufSBbYXV0b0FjdGl2YXRlPWZhbHNlXVxuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oYWN0aW9uLCBldmVudCwgYXV0b0FjdGl2YXRlKSB7XG5cbiAgdmFyIGVsZW1lbnQgPSB0aGlzLl9jdXJyZW50LmVsZW1lbnQsXG4gICAgICBlbnRyaWVzID0gdGhpcy5fY3VycmVudC5lbnRyaWVzLFxuICAgICAgZW50cnksXG4gICAgICBoYW5kbGVyLFxuICAgICAgb3JpZ2luYWxFdmVudCxcbiAgICAgIGJ1dHRvbiA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0IHx8IGV2ZW50LnRhcmdldDtcblxuICBpZiAoIWJ1dHRvbikge1xuICAgIHJldHVybiBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cbiAgZW50cnkgPSBlbnRyaWVzW2RvbUF0dHIoYnV0dG9uLCAnZGF0YS1hY3Rpb24nKV07XG4gIGhhbmRsZXIgPSBlbnRyeS5hY3Rpb247XG5cbiAgb3JpZ2luYWxFdmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQ7XG5cbiAgLy8gc2ltcGxlIGFjdGlvbiAodmlhIGNhbGxiYWNrIGZ1bmN0aW9uKVxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIGlmIChhY3Rpb24gPT09ICdjbGljaycpIHtcbiAgICAgIHJldHVybiBoYW5kbGVyKG9yaWdpbmFsRXZlbnQsIGVsZW1lbnQsIGF1dG9BY3RpdmF0ZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChoYW5kbGVyW2FjdGlvbl0pIHtcbiAgICAgIHJldHVybiBoYW5kbGVyW2FjdGlvbl0ob3JpZ2luYWxFdmVudCwgZWxlbWVudCwgYXV0b0FjdGl2YXRlKTtcbiAgICB9XG4gIH1cblxuICAvLyBzaWxlbmNlIG90aGVyIGFjdGlvbnNcbiAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbn07XG5cblxuLyoqXG4gKiBPcGVuIHRoZSBjb250ZXh0IHBhZCBmb3IgdGhlIGdpdmVuIGVsZW1lbnRcbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcGFyYW0ge2Jvb2xlYW59IGZvcmNlIGlmIHRydWUsIGZvcmNlIHJlb3BlbmluZyB0aGUgY29udGV4dCBwYWRcbiAqL1xuQ29udGV4dFBhZC5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uKGVsZW1lbnQsIGZvcmNlKSB7XG4gIGlmICghZm9yY2UgJiYgdGhpcy5pc09wZW4oZWxlbWVudCkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLmNsb3NlKCk7XG4gIHRoaXMuX3VwZGF0ZUFuZE9wZW4oZWxlbWVudCk7XG59O1xuXG5Db250ZXh0UGFkLnByb3RvdHlwZS5fZ2V0UHJvdmlkZXJzID0gZnVuY3Rpb24oaWQpIHtcblxuICB2YXIgZXZlbnQgPSB0aGlzLl9ldmVudEJ1cy5jcmVhdGVFdmVudCh7XG4gICAgdHlwZTogJ2NvbnRleHRQYWQuZ2V0UHJvdmlkZXJzJyxcbiAgICBwcm92aWRlcnM6IFtdXG4gIH0pO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoZXZlbnQpO1xuXG4gIHJldHVybiBldmVudC5wcm92aWRlcnM7XG59O1xuXG5Db250ZXh0UGFkLnByb3RvdHlwZS5fdXBkYXRlQW5kT3BlbiA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICB2YXIgZW50cmllcyA9IHRoaXMuZ2V0RW50cmllcyhlbGVtZW50KSxcbiAgICAgIHBhZCA9IHRoaXMuZ2V0UGFkKGVsZW1lbnQpLFxuICAgICAgaHRtbCA9IHBhZC5odG1sO1xuXG4gIGZvckVhY2goZW50cmllcywgZnVuY3Rpb24oZW50cnksIGlkKSB7XG4gICAgdmFyIGdyb3VwaW5nID0gZW50cnkuZ3JvdXAgfHwgJ2RlZmF1bHQnLFxuICAgICAgICBjb250cm9sID0gZG9taWZ5KGVudHJ5Lmh0bWwgfHwgJzxkaXYgY2xhc3M9XCJlbnRyeVwiIGRyYWdnYWJsZT1cInRydWVcIj48L2Rpdj4nKSxcbiAgICAgICAgY29udGFpbmVyO1xuXG4gICAgZG9tQXR0cihjb250cm9sLCAnZGF0YS1hY3Rpb24nLCBpZCk7XG5cbiAgICBjb250YWluZXIgPSBkb21RdWVyeSgnW2RhdGEtZ3JvdXA9JyArIGdyb3VwaW5nICsgJ10nLCBodG1sKTtcbiAgICBpZiAoIWNvbnRhaW5lcikge1xuICAgICAgY29udGFpbmVyID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiZ3JvdXBcIiBkYXRhLWdyb3VwPVwiJyArIGdyb3VwaW5nICsgJ1wiPjwvZGl2PicpO1xuICAgICAgaHRtbC5hcHBlbmRDaGlsZChjb250YWluZXIpO1xuICAgIH1cblxuICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZChjb250cm9sKTtcblxuICAgIGlmIChlbnRyeS5jbGFzc05hbWUpIHtcbiAgICAgIGFkZENsYXNzZXMoY29udHJvbCwgZW50cnkuY2xhc3NOYW1lKTtcbiAgICB9XG5cbiAgICBpZiAoZW50cnkudGl0bGUpIHtcbiAgICAgIGRvbUF0dHIoY29udHJvbCwgJ3RpdGxlJywgZW50cnkudGl0bGUpO1xuICAgIH1cblxuICAgIGlmIChlbnRyeS5pbWFnZVVybCkge1xuICAgICAgY29udHJvbC5hcHBlbmRDaGlsZChkb21pZnkoJzxpbWcgc3JjPVwiJyArIGVudHJ5LmltYWdlVXJsICsgJ1wiPicpKTtcbiAgICB9XG4gIH0pO1xuXG4gIGRvbUNsYXNzZXMoaHRtbCkuYWRkKCdvcGVuJyk7XG5cbiAgdGhpcy5fY3VycmVudCA9IHtcbiAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgIHBhZDogcGFkLFxuICAgIGVudHJpZXM6IGVudHJpZXNcbiAgfTtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb250ZXh0UGFkLm9wZW4nLCB7IGN1cnJlbnQ6IHRoaXMuX2N1cnJlbnQgfSk7XG59O1xuXG5cbkNvbnRleHRQYWQucHJvdG90eXBlLmdldFBhZCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudC5wYWQ7XG4gIH1cblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIG92ZXJsYXlzID0gdGhpcy5fb3ZlcmxheXM7XG5cbiAgdmFyIGh0bWwgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJkanMtY29udGV4dC1wYWRcIj48L2Rpdj4nKTtcblxuICB2YXIgb3ZlcmxheXNDb25maWcgPSBhc3NpZ24oe1xuICAgIGh0bWw6IGh0bWxcbiAgfSwgdGhpcy5fb3ZlcmxheXNDb25maWcpO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQoaHRtbCwgZW50cnlTZWxlY3RvciwgJ2NsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBzZWxmLnRyaWdnZXIoJ2NsaWNrJywgZXZlbnQpO1xuICB9KTtcblxuICBkb21EZWxlZ2F0ZS5iaW5kKGh0bWwsIGVudHJ5U2VsZWN0b3IsICdkcmFnc3RhcnQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHNlbGYudHJpZ2dlcignZHJhZ3N0YXJ0JywgZXZlbnQpO1xuICB9KTtcblxuICAvLyBzdG9wIHByb3BhZ2F0aW9uIG9mIG1vdXNlIGV2ZW50c1xuICBkb21FdmVudC5iaW5kKGh0bWwsICdtb3VzZWRvd24nLCBmdW5jdGlvbihldmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICB9KTtcblxuICB0aGlzLl9vdmVybGF5SWQgPSBvdmVybGF5cy5hZGQoZWxlbWVudCwgJ2NvbnRleHQtcGFkJywgb3ZlcmxheXNDb25maWcpO1xuXG4gIHZhciBwYWQgPSBvdmVybGF5cy5nZXQodGhpcy5fb3ZlcmxheUlkKTtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb250ZXh0UGFkLmNyZWF0ZScsIHsgZWxlbWVudDogZWxlbWVudCwgcGFkOiBwYWQgfSk7XG5cbiAgcmV0dXJuIHBhZDtcbn07XG5cblxuLyoqXG4gKiBDbG9zZSB0aGUgY29udGV4dCBwYWRcbiAqL1xuQ29udGV4dFBhZC5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLmlzT3BlbigpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fb3ZlcmxheXMucmVtb3ZlKHRoaXMuX292ZXJsYXlJZCk7XG5cbiAgdGhpcy5fb3ZlcmxheUlkID0gbnVsbDtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb250ZXh0UGFkLmNsb3NlJywgeyBjdXJyZW50OiB0aGlzLl9jdXJyZW50IH0pO1xuXG4gIHRoaXMuX2N1cnJlbnQgPSBudWxsO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBwYWQgaXMgb3Blbi4gSWYgZWxlbWVudCBpcyBnaXZlbiwgd2lsbCBjaGVja1xuICogaWYgcGFkIGlzIG9wZW5lZCB3aXRoIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5Db250ZXh0UGFkLnByb3RvdHlwZS5pc09wZW4gPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiAhIXRoaXMuX2N1cnJlbnQgJiYgKCFlbGVtZW50ID8gdHJ1ZSA6IHRoaXMuX2N1cnJlbnQuZWxlbWVudCA9PT0gZWxlbWVudCk7XG59O1xuXG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gYWRkQ2xhc3NlcyhlbGVtZW50LCBjbGFzc05hbWVzKSB7XG5cbiAgdmFyIGNsYXNzZXMgPSBkb21DbGFzc2VzKGVsZW1lbnQpO1xuXG4gIHZhciBhY3R1YWxDbGFzc05hbWVzID0gaXNBcnJheShjbGFzc05hbWVzKSA/IGNsYXNzTmFtZXMgOiBjbGFzc05hbWVzLnNwbGl0KC9cXHMrL2cpO1xuICBhY3R1YWxDbGFzc05hbWVzLmZvckVhY2goZnVuY3Rpb24oY2xzKSB7XG4gICAgY2xhc3Nlcy5hZGQoY2xzKTtcbiAgfSk7XG59IiwiaW1wb3J0IEludGVyYWN0aW9uRXZlbnRzTW9kdWxlIGZyb20gJy4uL2ludGVyYWN0aW9uLWV2ZW50cyc7XG5pbXBvcnQgT3ZlcmxheXNNb2R1bGUgZnJvbSAnLi4vb3ZlcmxheXMnO1xuXG5pbXBvcnQgQ29udGV4dFBhZCBmcm9tICcuL0NvbnRleHRQYWQnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSxcbiAgICBPdmVybGF5c01vZHVsZVxuICBdLFxuICBjb250ZXh0UGFkOiBbICd0eXBlJywgQ29udGV4dFBhZCBdXG59OyIsImltcG9ydCB7XG4gIGFzc2lnbixcbiAgZmluZCxcbiAgZm9yRWFjaCxcbiAgaXNBcnJheSxcbiAgaXNOdW1iZXIsXG4gIG1hcCxcbiAgbWF0Y2hQYXR0ZXJuLFxuICBvbWl0LFxuICBzb3J0Qnlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRCQm94LFxuICBnZXRQYXJlbnRzXG59IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG5pbXBvcnQgeyBlYWNoRWxlbWVudCB9IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG4vKipcbiAqIEB0eXBlZGVmIHtGdW5jdGlvbn0gPGNvcHlQYXN0ZS5jYW5Db3B5RWxlbWVudHM+IGxpc3RlbmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBjb250ZXh0LmVsZW1lbnRzXG4gKlxuICogQHJldHVybnMge0FycmF5PGRqcy5tb2RlbC5CYXNlPnxib29sZWFufSAtIFJldHVybiBlbGVtZW50cyB0byBiZSBjb3BpZWQgb3IgZmFsc2UgdG8gZGlzYWxsb3dcbiAqIGNvcHlpbmcuXG4gKi9cblxuLyoqXG4gKiBAdHlwZWRlZiB7RnVuY3Rpb259IDxjb3B5UGFzdGUuY29weUVsZW1lbnQ+IGxpc3RlbmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LmRlc2NyaXB0b3JcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGNvbnRleHQuZWxlbWVudFxuICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGNvbnRleHQuZWxlbWVudHNcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtGdW5jdGlvbn0gPGNvcHlQYXN0ZS5lbGVtZW50c0NvcGllZD4gbGlzdGVuZXJcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQuZWxlbWVudHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LnRyZWVcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtGdW5jdGlvbn0gPGNvcHlQYXN0ZS5wYXN0ZUVsZW1lbnQ+IGxpc3RlbmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LmNhY2hlIC0gQWxyZWFkeSBjcmVhdGVkIGVsZW1lbnRzLlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQuZGVzY3JpcHRvclxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge0Z1bmN0aW9ufSA8Y29weVBhc3RlLnBhc3RlRWxlbWVudHM+IGxpc3RlbmVyXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0LmhpbnRzIC0gQWRkIGhpbnRzIGJlZm9yZSBwYXN0aW5nLlxuICovXG5cbi8qKlxuICogQ29weSBhbmQgcGFzdGUgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICogQHBhcmFtIHtDcmVhdGV9IGNyZWF0ZVxuICogQHBhcmFtIHtDbGlwYm9hcmR9IGNsaXBib2FyZFxuICogQHBhcmFtIHtFbGVtZW50RmFjdG9yeX0gZWxlbWVudEZhY3RvcnlcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICogQHBhcmFtIHtNb3VzZX0gbW91c2VcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvcHlQYXN0ZShcbiAgICBjYW52YXMsXG4gICAgY3JlYXRlLFxuICAgIGNsaXBib2FyZCxcbiAgICBlbGVtZW50RmFjdG9yeSxcbiAgICBldmVudEJ1cyxcbiAgICBtb2RlbGluZyxcbiAgICBtb3VzZSxcbiAgICBydWxlc1xuKSB7XG5cbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xuICB0aGlzLl9jcmVhdGUgPSBjcmVhdGU7XG4gIHRoaXMuX2NsaXBib2FyZCA9IGNsaXBib2FyZDtcbiAgdGhpcy5fZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fbW91c2UgPSBtb3VzZTtcbiAgdGhpcy5fcnVsZXMgPSBydWxlcztcblxuICBldmVudEJ1cy5vbignY29weVBhc3RlLmNvcHlFbGVtZW50JywgZnVuY3Rpb24oY29udGV4dCkge1xuICAgIHZhciBkZXNjcmlwdG9yID0gY29udGV4dC5kZXNjcmlwdG9yLFxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5lbGVtZW50LFxuICAgICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHM7XG5cbiAgICAvLyBkZWZhdWx0IHByaW9yaXR5IChwcmlvcml0eSA9IDEpXG4gICAgZGVzY3JpcHRvci5wcmlvcml0eSA9IDE7XG5cbiAgICBkZXNjcmlwdG9yLmlkID0gZWxlbWVudC5pZDtcblxuICAgIHZhciBwYXJlbnRDb3BpZWQgPSBmaW5kKGVsZW1lbnRzLCBmdW5jdGlvbihlKSB7XG4gICAgICByZXR1cm4gZSA9PT0gZWxlbWVudC5wYXJlbnQ7XG4gICAgfSk7XG5cbiAgICAvLyBkbyBOT1QgcmVmZXJlbmNlIHBhcmVudCBpZiBwYXJlbnQgd2Fzbid0IGNvcGllZFxuICAgIGlmIChwYXJlbnRDb3BpZWQpIHtcbiAgICAgIGRlc2NyaXB0b3IucGFyZW50ID0gZWxlbWVudC5wYXJlbnQuaWQ7XG4gICAgfVxuXG4gICAgLy8gYXR0YWNoZXJzIChwcmlvcml0eSA9IDIpXG4gICAgaWYgKGlzQXR0YWNoZXIoZWxlbWVudCkpIHtcbiAgICAgIGRlc2NyaXB0b3IucHJpb3JpdHkgPSAyO1xuXG4gICAgICBkZXNjcmlwdG9yLmhvc3QgPSBlbGVtZW50Lmhvc3QuaWQ7XG4gICAgfVxuXG4gICAgLy8gY29ubmVjdGlvbnMgKHByaW9yaXR5ID0gMylcbiAgICBpZiAoaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICBkZXNjcmlwdG9yLnByaW9yaXR5ID0gMztcblxuICAgICAgZGVzY3JpcHRvci5zb3VyY2UgPSBlbGVtZW50LnNvdXJjZS5pZDtcbiAgICAgIGRlc2NyaXB0b3IudGFyZ2V0ID0gZWxlbWVudC50YXJnZXQuaWQ7XG5cbiAgICAgIGRlc2NyaXB0b3Iud2F5cG9pbnRzID0gY29weVdheXBvaW50cyhlbGVtZW50KTtcbiAgICB9XG5cbiAgICAvLyBsYWJlbHMgKHByaW9yaXR5ID0gNClcbiAgICBpZiAoaXNMYWJlbChlbGVtZW50KSkge1xuICAgICAgZGVzY3JpcHRvci5wcmlvcml0eSA9IDQ7XG5cbiAgICAgIGRlc2NyaXB0b3IubGFiZWxUYXJnZXQgPSBlbGVtZW50LmxhYmVsVGFyZ2V0LmlkO1xuICAgIH1cblxuICAgIGZvckVhY2goWyAneCcsICd5JywgJ3dpZHRoJywgJ2hlaWdodCcgXSwgZnVuY3Rpb24ocHJvcGVydHkpIHtcbiAgICAgIGlmIChpc051bWJlcihlbGVtZW50WyBwcm9wZXJ0eSBdKSkge1xuICAgICAgICBkZXNjcmlwdG9yWyBwcm9wZXJ0eSBdID0gZWxlbWVudFsgcHJvcGVydHkgXTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGRlc2NyaXB0b3IuaGlkZGVuID0gZWxlbWVudC5oaWRkZW47XG4gICAgZGVzY3JpcHRvci5jb2xsYXBzZWQgPSBlbGVtZW50LmNvbGxhcHNlZDtcblxuICB9KTtcblxuICBldmVudEJ1cy5vbignY29weVBhc3RlLnBhc3RlRWxlbWVudHMnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgdmFyIGhpbnRzID0gY29udGV4dC5oaW50cztcblxuICAgIGFzc2lnbihoaW50cywge1xuICAgICAgY3JlYXRlRWxlbWVudHNCZWhhdmlvcjogZmFsc2VcbiAgICB9KTtcbiAgfSk7XG59XG5cbkNvcHlQYXN0ZS4kaW5qZWN0ID0gW1xuICAnY2FudmFzJyxcbiAgJ2NyZWF0ZScsXG4gICdjbGlwYm9hcmQnLFxuICAnZWxlbWVudEZhY3RvcnknLFxuICAnZXZlbnRCdXMnLFxuICAnbW9kZWxpbmcnLFxuICAnbW91c2UnLFxuICAncnVsZXMnXG5dO1xuXG5cbi8qKlxuICogQ29weSBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHNcbiAqXG4gKiBAcmV0dXJucyB7T2JqZWN0fVxuICovXG5Db3B5UGFzdGUucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbihlbGVtZW50cykge1xuICB2YXIgYWxsb3dlZCxcbiAgICAgIHRyZWU7XG5cbiAgaWYgKCFpc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gZWxlbWVudHMgPyBbIGVsZW1lbnRzIF0gOiBbXTtcbiAgfVxuXG4gIGFsbG93ZWQgPSB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb3B5UGFzdGUuY2FuQ29weUVsZW1lbnRzJywge1xuICAgIGVsZW1lbnRzOiBlbGVtZW50c1xuICB9KTtcblxuICBpZiAoYWxsb3dlZCA9PT0gZmFsc2UpIHtcbiAgICB0cmVlID0ge307XG4gIH0gZWxzZSB7XG4gICAgdHJlZSA9IHRoaXMuY3JlYXRlVHJlZShpc0FycmF5KGFsbG93ZWQpID8gYWxsb3dlZCA6IGVsZW1lbnRzKTtcbiAgfVxuXG4gIC8vIHdlIHNldCBhbiBlbXB0eSB0cmVlLCBzZWxlY3Rpb24gb2YgZWxlbWVudHNcbiAgLy8gdG8gY29weSB3YXMgZW1wdHkuXG4gIHRoaXMuX2NsaXBib2FyZC5zZXQodHJlZSk7XG5cbiAgdGhpcy5fZXZlbnRCdXMuZmlyZSgnY29weVBhc3RlLmVsZW1lbnRzQ29waWVkJywge1xuICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICB0cmVlOiB0cmVlXG4gIH0pO1xuXG4gIHJldHVybiB0cmVlO1xufTtcblxuLyoqXG4gKiBQYXN0ZSBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW2NvbnRleHRdXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5iYXNlfSBbY29udGV4dC5lbGVtZW50XSAtIFBhcmVudC5cbiAqIEBwYXJhbSB7UG9pbnR9IFtjb250ZXh0LnBvaW50XSAtIFBvc2l0aW9uLlxuICogQHBhcmFtIHtPYmplY3R9IFtjb250ZXh0LmhpbnRzXSAtIEhpbnRzLlxuICovXG5Db3B5UGFzdGUucHJvdG90eXBlLnBhc3RlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgdHJlZSA9IHRoaXMuX2NsaXBib2FyZC5nZXQoKTtcblxuICBpZiAodGhpcy5fY2xpcGJvYXJkLmlzRW1wdHkoKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBoaW50cyA9IGNvbnRleHQgJiYgY29udGV4dC5oaW50cyB8fCB7fTtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdjb3B5UGFzdGUucGFzdGVFbGVtZW50cycsIHtcbiAgICBoaW50czogaGludHNcbiAgfSk7XG5cbiAgdmFyIGVsZW1lbnRzID0gdGhpcy5fY3JlYXRlRWxlbWVudHModHJlZSk7XG5cbiAgLy8gcGFzdGUgZGlyZWN0bHlcbiAgaWYgKGNvbnRleHQgJiYgY29udGV4dC5lbGVtZW50ICYmIGNvbnRleHQucG9pbnQpIHtcbiAgICByZXR1cm4gdGhpcy5fcGFzdGUoZWxlbWVudHMsIGNvbnRleHQuZWxlbWVudCwgY29udGV4dC5wb2ludCwgaGludHMpO1xuICB9XG5cbiAgdGhpcy5fY3JlYXRlLnN0YXJ0KHRoaXMuX21vdXNlLmdldExhc3RNb3ZlRXZlbnQoKSwgZWxlbWVudHMsIHtcbiAgICBoaW50czogaGludHMgfHwge31cbiAgfSk7XG59O1xuXG4vKipcbiAqIFBhc3RlIGVsZW1lbnRzIGRpcmVjdGx5LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICogQHBhcmFtIHtkanMubW9kZWwuYmFzZX0gdGFyZ2V0XG4gKiBAcGFyYW0ge1BvaW50fSBwb3NpdGlvblxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqL1xuQ29weVBhc3RlLnByb3RvdHlwZS5fcGFzdGUgPSBmdW5jdGlvbihlbGVtZW50cywgdGFyZ2V0LCBwb3NpdGlvbiwgaGludHMpIHtcblxuICAvLyBtYWtlIHN1cmUgZWFjaCBlbGVtZW50IGhhcyB4IGFuZCB5XG4gIGZvckVhY2goZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBpZiAoIWlzTnVtYmVyKGVsZW1lbnQueCkpIHtcbiAgICAgIGVsZW1lbnQueCA9IDA7XG4gICAgfVxuXG4gICAgaWYgKCFpc051bWJlcihlbGVtZW50LnkpKSB7XG4gICAgICBlbGVtZW50LnkgPSAwO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIGJib3ggPSBnZXRCQm94KGVsZW1lbnRzKTtcblxuICAvLyBjZW50ZXIgZWxlbWVudHMgYXJvdW5kIGN1cnNvclxuICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgaWYgKGlzQ29ubmVjdGlvbihlbGVtZW50KSkge1xuICAgICAgZWxlbWVudC53YXlwb2ludHMgPSBtYXAoZWxlbWVudC53YXlwb2ludHMsIGZ1bmN0aW9uKHdheXBvaW50KSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgeDogd2F5cG9pbnQueCAtIGJib3gueCAtIGJib3gud2lkdGggLyAyLFxuICAgICAgICAgIHk6IHdheXBvaW50LnkgLSBiYm94LnkgLSBiYm94LmhlaWdodCAvIDJcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGFzc2lnbihlbGVtZW50LCB7XG4gICAgICB4OiBlbGVtZW50LnggLSBiYm94LnggLSBiYm94LndpZHRoIC8gMixcbiAgICAgIHk6IGVsZW1lbnQueSAtIGJib3gueSAtIGJib3guaGVpZ2h0IC8gMlxuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gdGhpcy5fbW9kZWxpbmcuY3JlYXRlRWxlbWVudHMoZWxlbWVudHMsIHBvc2l0aW9uLCB0YXJnZXQsIGFzc2lnbih7fSwgaGludHMpKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGVsZW1lbnRzIGZyb20gdHJlZS5cbiAqL1xuQ29weVBhc3RlLnByb3RvdHlwZS5fY3JlYXRlRWxlbWVudHMgPSBmdW5jdGlvbih0cmVlKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICB2YXIgY2FjaGUgPSB7fTtcblxuICB2YXIgZWxlbWVudHMgPSBbXTtcblxuICBmb3JFYWNoKHRyZWUsIGZ1bmN0aW9uKGJyYW5jaCwgZGVwdGgpIHtcblxuICAgIGRlcHRoID0gcGFyc2VJbnQoZGVwdGgsIDEwKTtcblxuICAgIC8vIHNvcnQgYnkgcHJpb3JpdHlcbiAgICBicmFuY2ggPSBzb3J0QnkoYnJhbmNoLCAncHJpb3JpdHknKTtcblxuICAgIGZvckVhY2goYnJhbmNoLCBmdW5jdGlvbihkZXNjcmlwdG9yKSB7XG5cbiAgICAgIC8vIHJlbW92ZSBwcmlvcml0eVxuICAgICAgdmFyIGF0dHJzID0gYXNzaWduKHt9LCBvbWl0KGRlc2NyaXB0b3IsIFsgJ3ByaW9yaXR5JyBdKSk7XG5cbiAgICAgIGlmIChjYWNoZVsgZGVzY3JpcHRvci5wYXJlbnQgXSkge1xuICAgICAgICBhdHRycy5wYXJlbnQgPSBjYWNoZVsgZGVzY3JpcHRvci5wYXJlbnQgXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlbGV0ZSBhdHRycy5wYXJlbnQ7XG4gICAgICB9XG5cbiAgICAgIGV2ZW50QnVzLmZpcmUoJ2NvcHlQYXN0ZS5wYXN0ZUVsZW1lbnQnLCB7XG4gICAgICAgIGNhY2hlOiBjYWNoZSxcbiAgICAgICAgZGVzY3JpcHRvcjogYXR0cnNcbiAgICAgIH0pO1xuXG4gICAgICB2YXIgZWxlbWVudDtcblxuICAgICAgaWYgKGlzQ29ubmVjdGlvbihhdHRycykpIHtcbiAgICAgICAgYXR0cnMuc291cmNlID0gY2FjaGVbIGRlc2NyaXB0b3Iuc291cmNlIF07XG4gICAgICAgIGF0dHJzLnRhcmdldCA9IGNhY2hlWyBkZXNjcmlwdG9yLnRhcmdldCBdO1xuXG4gICAgICAgIGVsZW1lbnQgPSBjYWNoZVsgZGVzY3JpcHRvci5pZCBdID0gc2VsZi5jcmVhdGVDb25uZWN0aW9uKGF0dHJzKTtcblxuICAgICAgICBlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzTGFiZWwoYXR0cnMpKSB7XG4gICAgICAgIGF0dHJzLmxhYmVsVGFyZ2V0ID0gY2FjaGVbIGF0dHJzLmxhYmVsVGFyZ2V0IF07XG5cbiAgICAgICAgZWxlbWVudCA9IGNhY2hlWyBkZXNjcmlwdG9yLmlkIF0gPSBzZWxmLmNyZWF0ZUxhYmVsKGF0dHJzKTtcblxuICAgICAgICBlbGVtZW50cy5wdXNoKGVsZW1lbnQpO1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGF0dHJzLmhvc3QpIHtcbiAgICAgICAgYXR0cnMuaG9zdCA9IGNhY2hlWyBhdHRycy5ob3N0IF07XG4gICAgICB9XG5cbiAgICAgIGVsZW1lbnQgPSBjYWNoZVsgZGVzY3JpcHRvci5pZCBdID0gc2VsZi5jcmVhdGVTaGFwZShhdHRycyk7XG5cbiAgICAgIGVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgfSk7XG5cbiAgfSk7XG5cbiAgcmV0dXJuIGVsZW1lbnRzO1xufTtcblxuQ29weVBhc3RlLnByb3RvdHlwZS5jcmVhdGVDb25uZWN0aW9uID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgdmFyIGNvbm5lY3Rpb24gPSB0aGlzLl9lbGVtZW50RmFjdG9yeS5jcmVhdGVDb25uZWN0aW9uKG9taXQoYXR0cnMsIFsgJ2lkJyBdKSk7XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59O1xuXG5Db3B5UGFzdGUucHJvdG90eXBlLmNyZWF0ZUxhYmVsID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgdmFyIGxhYmVsID0gdGhpcy5fZWxlbWVudEZhY3RvcnkuY3JlYXRlTGFiZWwob21pdChhdHRycywgWyAnaWQnIF0pKTtcblxuICByZXR1cm4gbGFiZWw7XG59O1xuXG5Db3B5UGFzdGUucHJvdG90eXBlLmNyZWF0ZVNoYXBlID0gZnVuY3Rpb24oYXR0cnMpIHtcbiAgdmFyIHNoYXBlID0gdGhpcy5fZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUob21pdChhdHRycywgWyAnaWQnIF0pKTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG4vKipcbiAqIENoZWNrIHdldGhlciBlbGVtZW50IGhhcyByZWxhdGlvbnMgdG8gb3RoZXIgZWxlbWVudHMgZS5nLiBhdHRhY2hlcnMsIGxhYmVscyBhbmQgY29ubmVjdGlvbnMuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBlbGVtZW50XG4gKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGVsZW1lbnRzXG4gKlxuICogQHJldHVybnMge2Jvb2xlYW59XG4gKi9cbkNvcHlQYXN0ZS5wcm90b3R5cGUuaGFzUmVsYXRpb25zID0gZnVuY3Rpb24oZWxlbWVudCwgZWxlbWVudHMpIHtcbiAgdmFyIGxhYmVsVGFyZ2V0LFxuICAgICAgc291cmNlLFxuICAgICAgdGFyZ2V0O1xuXG4gIGlmIChpc0Nvbm5lY3Rpb24oZWxlbWVudCkpIHtcbiAgICBzb3VyY2UgPSBmaW5kKGVsZW1lbnRzLCBtYXRjaFBhdHRlcm4oeyBpZDogZWxlbWVudC5zb3VyY2UuaWQgfSkpO1xuICAgIHRhcmdldCA9IGZpbmQoZWxlbWVudHMsIG1hdGNoUGF0dGVybih7IGlkOiBlbGVtZW50LnRhcmdldC5pZCB9KSk7XG5cbiAgICBpZiAoIXNvdXJjZSB8fCAhdGFyZ2V0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzTGFiZWwoZWxlbWVudCkpIHtcbiAgICBsYWJlbFRhcmdldCA9IGZpbmQoZWxlbWVudHMsIG1hdGNoUGF0dGVybih7IGlkOiBlbGVtZW50LmxhYmVsVGFyZ2V0LmlkIH0pKTtcblxuICAgIGlmICghbGFiZWxUYXJnZXQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgdHJlZS1saWtlIHN0cnVjdHVyZSBmcm9tIGVsZW1lbnRzLlxuICpcbiAqIEBleGFtcGxlXG4gKiB0cmVlOiB7XG4gICogIDA6IFtcbiAgKiAgICB7IGlkOiAnU2hhcGVfMScsIHByaW9yaXR5OiAxLCAuLi4gfSxcbiAgKiAgICB7IGlkOiAnU2hhcGVfMicsIHByaW9yaXR5OiAxLCAuLi4gfSxcbiAgKiAgICB7IGlkOiAnQ29ubmVjdGlvbl8xJywgc291cmNlOiAnU2hhcGVfMScsIHRhcmdldDogJ1NoYXBlXzInLCBwcmlvcml0eTogMywgLi4uIH0sXG4gICogICAgLi4uXG4gICogIF0sXG4gICogIDE6IFtcbiAgKiAgICB7IGlkOiAnU2hhcGVfMycsIHBhcmVudDogJ1NoYXBlMScsIHByaW9yaXR5OiAxLCAuLi4gfSxcbiAgKiAgICAuLi5cbiAgKiAgXVxuICAqIH07XG4gICpcbiAgKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuYmFzZT59IGVsZW1lbnRzXG4gICpcbiAgKiBAcmV0dXJuIHtPYmplY3R9XG4gICovXG5Db3B5UGFzdGUucHJvdG90eXBlLmNyZWF0ZVRyZWUgPSBmdW5jdGlvbihlbGVtZW50cykge1xuICB2YXIgcnVsZXMgPSB0aGlzLl9ydWxlcyxcbiAgICAgIHNlbGYgPSB0aGlzO1xuXG4gIHZhciB0cmVlID0ge30sXG4gICAgICBlbGVtZW50c0RhdGEgPSBbXTtcblxuICB2YXIgcGFyZW50cyA9IGdldFBhcmVudHMoZWxlbWVudHMpO1xuXG4gIGZ1bmN0aW9uIGNhbkNvcHkoZWxlbWVudCwgZWxlbWVudHMpIHtcbiAgICByZXR1cm4gcnVsZXMuYWxsb3dlZCgnZWxlbWVudC5jb3B5Jywge1xuICAgICAgZWxlbWVudDogZWxlbWVudCxcbiAgICAgIGVsZW1lbnRzOiBlbGVtZW50c1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gYWRkRWxlbWVudERhdGEoZWxlbWVudCwgZGVwdGgpIHtcblxuICAgIC8vICgxKSBjaGVjayB3ZXRoZXIgZWxlbWVudCBoYXMgYWxyZWFkeSBiZWVuIGFkZGVkXG4gICAgdmFyIGZvdW5kRWxlbWVudERhdGEgPSBmaW5kKGVsZW1lbnRzRGF0YSwgZnVuY3Rpb24oZWxlbWVudHNEYXRhKSB7XG4gICAgICByZXR1cm4gZWxlbWVudCA9PT0gZWxlbWVudHNEYXRhLmVsZW1lbnQ7XG4gICAgfSk7XG5cbiAgICAvLyAoMikgYWRkIGVsZW1lbnQgaWYgbm90IGFscmVhZHkgYWRkZWRcbiAgICBpZiAoIWZvdW5kRWxlbWVudERhdGEpIHtcbiAgICAgIGVsZW1lbnRzRGF0YS5wdXNoKHtcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcbiAgICAgICAgZGVwdGg6IGRlcHRoXG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vICgzKSB1cGRhdGUgZGVwdGhcbiAgICBpZiAoZm91bmRFbGVtZW50RGF0YS5kZXB0aCA8IGRlcHRoKSB7XG4gICAgICBlbGVtZW50c0RhdGEgPSByZW1vdmVFbGVtZW50RGF0YShmb3VuZEVsZW1lbnREYXRhLCBlbGVtZW50c0RhdGEpO1xuXG4gICAgICBlbGVtZW50c0RhdGEucHVzaCh7XG4gICAgICAgIGVsZW1lbnQ6IGZvdW5kRWxlbWVudERhdGEuZWxlbWVudCxcbiAgICAgICAgZGVwdGg6IGRlcHRoXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVFbGVtZW50RGF0YShlbGVtZW50RGF0YSwgZWxlbWVudHNEYXRhKSB7XG4gICAgdmFyIGluZGV4ID0gZWxlbWVudHNEYXRhLmluZGV4T2YoZWxlbWVudERhdGEpO1xuXG4gICAgaWYgKGluZGV4ICE9PSAtMSkge1xuICAgICAgZWxlbWVudHNEYXRhLnNwbGljZShpbmRleCwgMSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGVsZW1lbnRzRGF0YTtcbiAgfVxuXG4gIC8vICgxKSBhZGQgZWxlbWVudHNcbiAgZWFjaEVsZW1lbnQocGFyZW50cywgZnVuY3Rpb24oZWxlbWVudCwgX2luZGV4LCBkZXB0aCkge1xuXG4gICAgLy8gZG8gTk9UIGFkZCBleHRlcm5hbCBsYWJlbHMgZGlyZWN0bHlcbiAgICBpZiAoaXNMYWJlbChlbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGFsd2F5cyBjb3B5IGV4dGVybmFsIGxhYmVsc1xuICAgIGZvckVhY2goZWxlbWVudC5sYWJlbHMsIGZ1bmN0aW9uKGxhYmVsKSB7XG4gICAgICBhZGRFbGVtZW50RGF0YShsYWJlbCwgZGVwdGgpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gYWRkUmVsYXRlZEVsZW1lbnRzKGVsZW1lbnRzKSB7XG4gICAgICBlbGVtZW50cyAmJiBlbGVtZW50cy5sZW5ndGggJiYgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgICAgIC8vIGFkZCBleHRlcm5hbCBsYWJlbHNcbiAgICAgICAgZm9yRWFjaChlbGVtZW50LmxhYmVscywgZnVuY3Rpb24obGFiZWwpIHtcbiAgICAgICAgICBhZGRFbGVtZW50RGF0YShsYWJlbCwgZGVwdGgpO1xuICAgICAgICB9KTtcblxuICAgICAgICBhZGRFbGVtZW50RGF0YShlbGVtZW50LCBkZXB0aCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBmb3JFYWNoKFsgZWxlbWVudC5hdHRhY2hlcnMsIGVsZW1lbnQuaW5jb21pbmcsIGVsZW1lbnQub3V0Z29pbmcgXSwgYWRkUmVsYXRlZEVsZW1lbnRzKTtcblxuICAgIGFkZEVsZW1lbnREYXRhKGVsZW1lbnQsIGRlcHRoKTtcblxuICAgIHJldHVybiBlbGVtZW50LmNoaWxkcmVuO1xuICB9KTtcblxuICBlbGVtZW50cyA9IG1hcChlbGVtZW50c0RhdGEsIGZ1bmN0aW9uKGVsZW1lbnREYXRhKSB7XG4gICAgcmV0dXJuIGVsZW1lbnREYXRhLmVsZW1lbnQ7XG4gIH0pO1xuXG4gIC8vICgyKSBjb3B5IGVsZW1lbnRzXG4gIGVsZW1lbnRzRGF0YSA9IG1hcChlbGVtZW50c0RhdGEsIGZ1bmN0aW9uKGVsZW1lbnREYXRhKSB7XG4gICAgZWxlbWVudERhdGEuZGVzY3JpcHRvciA9IHt9O1xuXG4gICAgc2VsZi5fZXZlbnRCdXMuZmlyZSgnY29weVBhc3RlLmNvcHlFbGVtZW50Jywge1xuICAgICAgZGVzY3JpcHRvcjogZWxlbWVudERhdGEuZGVzY3JpcHRvcixcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnREYXRhLmVsZW1lbnQsXG4gICAgICBlbGVtZW50czogZWxlbWVudHNcbiAgICB9KTtcblxuICAgIHJldHVybiBlbGVtZW50RGF0YTtcbiAgfSk7XG5cbiAgLy8gKDMpIHNvcnQgZWxlbWVudHMgYnkgcHJpb3JpdHlcbiAgZWxlbWVudHNEYXRhID0gc29ydEJ5KGVsZW1lbnRzRGF0YSwgZnVuY3Rpb24oZWxlbWVudERhdGEpIHtcbiAgICByZXR1cm4gZWxlbWVudERhdGEuZGVzY3JpcHRvci5wcmlvcml0eTtcbiAgfSk7XG5cbiAgZWxlbWVudHMgPSBtYXAoZWxlbWVudHNEYXRhLCBmdW5jdGlvbihlbGVtZW50RGF0YSkge1xuICAgIHJldHVybiBlbGVtZW50RGF0YS5lbGVtZW50O1xuICB9KTtcblxuICAvLyAoNCkgY3JlYXRlIHRyZWVcbiAgZm9yRWFjaChlbGVtZW50c0RhdGEsIGZ1bmN0aW9uKGVsZW1lbnREYXRhKSB7XG4gICAgdmFyIGRlcHRoID0gZWxlbWVudERhdGEuZGVwdGg7XG5cbiAgICBpZiAoIXNlbGYuaGFzUmVsYXRpb25zKGVsZW1lbnREYXRhLmVsZW1lbnQsIGVsZW1lbnRzKSkge1xuICAgICAgcmVtb3ZlRWxlbWVudChlbGVtZW50RGF0YS5lbGVtZW50LCBlbGVtZW50cyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWNhbkNvcHkoZWxlbWVudERhdGEuZWxlbWVudCwgZWxlbWVudHMpKSB7XG4gICAgICByZW1vdmVFbGVtZW50KGVsZW1lbnREYXRhLmVsZW1lbnQsIGVsZW1lbnRzKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghdHJlZVtkZXB0aF0pIHtcbiAgICAgIHRyZWVbZGVwdGhdID0gW107XG4gICAgfVxuXG4gICAgdHJlZVtkZXB0aF0ucHVzaChlbGVtZW50RGF0YS5kZXNjcmlwdG9yKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHRyZWU7XG59O1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaXNBdHRhY2hlcihlbGVtZW50KSB7XG4gIHJldHVybiAhIWVsZW1lbnQuaG9zdDtcbn1cblxuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuICEhZWxlbWVudC53YXlwb2ludHM7XG59XG5cbmZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gISFlbGVtZW50LmxhYmVsVGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBjb3B5V2F5cG9pbnRzKGVsZW1lbnQpIHtcbiAgcmV0dXJuIG1hcChlbGVtZW50LndheXBvaW50cywgZnVuY3Rpb24od2F5cG9pbnQpIHtcblxuICAgIHdheXBvaW50ID0gY29weVdheXBvaW50KHdheXBvaW50KTtcblxuICAgIGlmICh3YXlwb2ludC5vcmlnaW5hbCkge1xuICAgICAgd2F5cG9pbnQub3JpZ2luYWwgPSBjb3B5V2F5cG9pbnQod2F5cG9pbnQub3JpZ2luYWwpO1xuICAgIH1cblxuICAgIHJldHVybiB3YXlwb2ludDtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGNvcHlXYXlwb2ludCh3YXlwb2ludCkge1xuICByZXR1cm4gYXNzaWduKHt9LCB3YXlwb2ludCk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUVsZW1lbnQoZWxlbWVudCwgZWxlbWVudHMpIHtcbiAgdmFyIGluZGV4ID0gZWxlbWVudHMuaW5kZXhPZihlbGVtZW50KTtcblxuICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgcmV0dXJuIGVsZW1lbnRzO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnRzLnNwbGljZShpbmRleCwgMSk7XG59XG4iLCJpbXBvcnQgQ2xpcGJvYXJkTW9kdWxlIGZyb20gJy4uL2NsaXBib2FyZCc7XG5pbXBvcnQgQ3JlYXRlTW9kdWxlIGZyb20gJy4uL2NyZWF0ZSc7XG5pbXBvcnQgTW91c2VNb2R1bGUgZnJvbSAnLi4vbW91c2UnO1xuaW1wb3J0IFJ1bGVzTW9kdWxlIGZyb20gJy4uL3J1bGVzJztcblxuaW1wb3J0IENvcHlQYXN0ZSBmcm9tICcuL0NvcHlQYXN0ZSc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIENsaXBib2FyZE1vZHVsZSxcbiAgICBDcmVhdGVNb2R1bGUsXG4gICAgTW91c2VNb2R1bGUsXG4gICAgUnVsZXNNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2NvcHlQYXN0ZScgXSxcbiAgY29weVBhc3RlOiBbICd0eXBlJywgQ29weVBhc3RlIF1cbn07XG4iLCJ2YXIgTUFSS0VSX09LID0gJ2Ryb3Atb2snLFxuICAgIE1BUktFUl9OT1RfT0sgPSAnZHJvcC1ub3Qtb2snLFxuICAgIE1BUktFUl9BVFRBQ0ggPSAnYXR0YWNoLW9rJyxcbiAgICBNQVJLRVJfTkVXX1BBUkVOVCA9ICduZXctcGFyZW50JztcblxuaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaWx0ZXIsXG4gIGZpbmQsXG4gIGZvckVhY2gsXG4gIGlzQXJyYXksXG4gIGlzTnVtYmVyLFxuICBtYXBcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgeyBnZXRCQm94IH0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbnZhciBQUkVGSVggPSAnY3JlYXRlJztcblxudmFyIEhJR0hfUFJJT1JJVFkgPSAyMDAwO1xuXG5cbi8qKlxuICogQ3JlYXRlIG5ldyBlbGVtZW50cyB0aHJvdWdoIGRyYWcgYW5kIGRyb3AuXG4gKlxuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICogQHBhcmFtIHtEcmFnZ2luZ30gZHJhZ2dpbmdcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICogQHBhcmFtIHtSdWxlc30gcnVsZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ3JlYXRlKFxuICAgIGNhbnZhcyxcbiAgICBkcmFnZ2luZyxcbiAgICBldmVudEJ1cyxcbiAgICBtb2RlbGluZyxcbiAgICBydWxlc1xuKSB7XG5cbiAgLy8gcnVsZXMgLy8vLy8vLy8vL1xuXG4gIC8qKlxuICAgKiBDaGVjayB3ZXRoZXIgZWxlbWVudHMgY2FuIGJlIGNyZWF0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSB0YXJnZXRcbiAgICogQHBhcmFtIHtQb2ludH0gcG9zaXRpb25cbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gW3NvdXJjZV1cbiAgICpcbiAgICogQHJldHVybnMge2Jvb2xlYW58bnVsbHxPYmplY3R9XG4gICAqL1xuICBmdW5jdGlvbiBjYW5DcmVhdGUoZWxlbWVudHMsIHRhcmdldCwgcG9zaXRpb24sIHNvdXJjZSwgaGludHMpIHtcbiAgICBpZiAoIXRhcmdldCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIGlnbm9yZSBjaGlsZCBlbGVtZW50cyBhbmQgZXh0ZXJuYWwgbGFiZWxzXG4gICAgZWxlbWVudHMgPSBmaWx0ZXIoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgIHZhciBsYWJlbFRhcmdldCA9IGVsZW1lbnQubGFiZWxUYXJnZXQ7XG5cbiAgICAgIHJldHVybiAhZWxlbWVudC5wYXJlbnQgJiYgIShpc0xhYmVsKGVsZW1lbnQpICYmIGVsZW1lbnRzLmluZGV4T2YobGFiZWxUYXJnZXQpICE9PSAtMSk7XG4gICAgfSk7XG5cbiAgICB2YXIgc2hhcGUgPSBmaW5kKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gIWlzQ29ubmVjdGlvbihlbGVtZW50KTtcbiAgICB9KTtcblxuICAgIHZhciBhdHRhY2ggPSBmYWxzZSxcbiAgICAgICAgY29ubmVjdCA9IGZhbHNlLFxuICAgICAgICBjcmVhdGUgPSBmYWxzZTtcblxuICAgIC8vICgxKSBhdHRhY2hpbmcgc2luZ2xlIHNoYXBlc1xuICAgIGlmIChpc1NpbmdsZVNoYXBlKGVsZW1lbnRzKSkge1xuICAgICAgYXR0YWNoID0gcnVsZXMuYWxsb3dlZCgnc2hhcGUuYXR0YWNoJywge1xuICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgIHNoYXBlOiBzaGFwZSxcbiAgICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICghYXR0YWNoKSB7XG5cbiAgICAgIC8vICgyKSBjcmVhdGluZyBlbGVtZW50c1xuICAgICAgaWYgKGlzU2luZ2xlU2hhcGUoZWxlbWVudHMpKSB7XG4gICAgICAgIGNyZWF0ZSA9IHJ1bGVzLmFsbG93ZWQoJ3NoYXBlLmNyZWF0ZScsIHtcbiAgICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgICAgc2hhcGU6IHNoYXBlLFxuICAgICAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgICAgIHRhcmdldDogdGFyZ2V0XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3JlYXRlID0gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMuY3JlYXRlJywge1xuICAgICAgICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICAgICAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICB9XG5cbiAgICB2YXIgY29ubmVjdGlvblRhcmdldCA9IGhpbnRzLmNvbm5lY3Rpb25UYXJnZXQ7XG5cbiAgICAvLyAoMykgYXBwZW5kaW5nIHNpbmdsZSBzaGFwZXNcbiAgICBpZiAoY3JlYXRlIHx8IGF0dGFjaCkge1xuICAgICAgaWYgKHNoYXBlICYmIHNvdXJjZSkge1xuICAgICAgICBjb25uZWN0ID0gcnVsZXMuYWxsb3dlZCgnY29ubmVjdGlvbi5jcmVhdGUnLCB7XG4gICAgICAgICAgc291cmNlOiBjb25uZWN0aW9uVGFyZ2V0ID09PSBzb3VyY2UgPyBzaGFwZSA6IHNvdXJjZSxcbiAgICAgICAgICB0YXJnZXQ6IGNvbm5lY3Rpb25UYXJnZXQgPT09IHNvdXJjZSA/IHNvdXJjZSA6IHNoYXBlLFxuICAgICAgICAgIGhpbnRzOiB7XG4gICAgICAgICAgICB0YXJnZXRQYXJlbnQ6IHRhcmdldCxcbiAgICAgICAgICAgIHRhcmdldEF0dGFjaDogYXR0YWNoXG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgYXR0YWNoOiBhdHRhY2gsXG4gICAgICAgIGNvbm5lY3Q6IGNvbm5lY3RcbiAgICAgIH07XG4gICAgfVxuXG4gICAgLy8gaWdub3JlIHdldGhlciBvciBub3QgZWxlbWVudHMgY2FuIGJlIGNyZWF0ZWRcbiAgICBpZiAoY3JlYXRlID09PSBudWxsIHx8IGF0dGFjaCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gc2V0TWFya2VyKGVsZW1lbnQsIG1hcmtlcikge1xuICAgIFsgTUFSS0VSX0FUVEFDSCwgTUFSS0VSX09LLCBNQVJLRVJfTk9UX09LLCBNQVJLRVJfTkVXX1BBUkVOVCBdLmZvckVhY2goZnVuY3Rpb24obSkge1xuXG4gICAgICBpZiAobSA9PT0gbWFya2VyKSB7XG4gICAgICAgIGNhbnZhcy5hZGRNYXJrZXIoZWxlbWVudCwgbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYW52YXMucmVtb3ZlTWFya2VyKGVsZW1lbnQsIG0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gZXZlbnQgaGFuZGxpbmcgLy8vLy8vLy8vL1xuXG4gIGV2ZW50QnVzLm9uKFsgJ2NyZWF0ZS5tb3ZlJywgJ2NyZWF0ZS5ob3ZlcicgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGVsZW1lbnRzID0gY29udGV4dC5lbGVtZW50cyxcbiAgICAgICAgaG92ZXIgPSBldmVudC5ob3ZlcixcbiAgICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fTtcblxuICAgIGlmICghaG92ZXIpIHtcbiAgICAgIGNvbnRleHQuY2FuRXhlY3V0ZSA9IGZhbHNlO1xuICAgICAgY29udGV4dC50YXJnZXQgPSBudWxsO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZW5zdXJlQ29uc3RyYWludHMoZXZlbnQpO1xuXG4gICAgdmFyIHBvc2l0aW9uID0ge1xuICAgICAgeDogZXZlbnQueCxcbiAgICAgIHk6IGV2ZW50LnlcbiAgICB9O1xuXG4gICAgdmFyIGNhbkV4ZWN1dGUgPSBjb250ZXh0LmNhbkV4ZWN1dGUgPSBob3ZlciAmJiBjYW5DcmVhdGUoZWxlbWVudHMsIGhvdmVyLCBwb3NpdGlvbiwgc291cmNlLCBoaW50cyk7XG5cbiAgICBpZiAoaG92ZXIgJiYgY2FuRXhlY3V0ZSAhPT0gbnVsbCkge1xuICAgICAgY29udGV4dC50YXJnZXQgPSBob3ZlcjtcblxuICAgICAgaWYgKGNhbkV4ZWN1dGUgJiYgY2FuRXhlY3V0ZS5hdHRhY2gpIHtcbiAgICAgICAgc2V0TWFya2VyKGhvdmVyLCBNQVJLRVJfQVRUQUNIKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNldE1hcmtlcihob3ZlciwgY2FuRXhlY3V0ZSA/IE1BUktFUl9ORVdfUEFSRU5UIDogTUFSS0VSX05PVF9PSyk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdjcmVhdGUuZW5kJywgJ2NyZWF0ZS5vdXQnLCAnY3JlYXRlLmNsZWFudXAnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGhvdmVyID0gZXZlbnQuaG92ZXI7XG5cbiAgICBpZiAoaG92ZXIpIHtcbiAgICAgIHNldE1hcmtlcihob3ZlciwgbnVsbCk7XG4gICAgfVxuICB9KTtcblxuICBldmVudEJ1cy5vbignY3JlYXRlLmVuZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzb3VyY2UgPSBjb250ZXh0LnNvdXJjZSxcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBhdHRhY2ggPSBjYW5FeGVjdXRlICYmIGNhbkV4ZWN1dGUuYXR0YWNoLFxuICAgICAgICBjb25uZWN0ID0gY2FuRXhlY3V0ZSAmJiBjYW5FeGVjdXRlLmNvbm5lY3QsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fTtcblxuICAgIGlmIChjYW5FeGVjdXRlID09PSBmYWxzZSB8fCAhdGFyZ2V0KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgZW5zdXJlQ29uc3RyYWludHMoZXZlbnQpO1xuXG4gICAgdmFyIHBvc2l0aW9uID0ge1xuICAgICAgeDogZXZlbnQueCxcbiAgICAgIHk6IGV2ZW50LnlcbiAgICB9O1xuXG4gICAgaWYgKGNvbm5lY3QpIHtcbiAgICAgIHNoYXBlID0gbW9kZWxpbmcuYXBwZW5kU2hhcGUoc291cmNlLCBzaGFwZSwgcG9zaXRpb24sIHRhcmdldCwge1xuICAgICAgICBhdHRhY2g6IGF0dGFjaCxcbiAgICAgICAgY29ubmVjdGlvbjogY29ubmVjdCA9PT0gdHJ1ZSA/IHt9IDogY29ubmVjdCxcbiAgICAgICAgY29ubmVjdGlvblRhcmdldDogaGludHMuY29ubmVjdGlvblRhcmdldFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnRzID0gbW9kZWxpbmcuY3JlYXRlRWxlbWVudHMoZWxlbWVudHMsIHBvc2l0aW9uLCB0YXJnZXQsIGFzc2lnbih7fSwgaGludHMsIHtcbiAgICAgICAgYXR0YWNoOiBhdHRhY2hcbiAgICAgIH0pKTtcblxuICAgICAgLy8gdXBkYXRlIHNoYXBlXG4gICAgICBzaGFwZSA9IGZpbmQoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgICAgcmV0dXJuICFpc0Nvbm5lY3Rpb24oZWxlbWVudCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyB1cGRhdGUgZWxlbWVudHMgYW5kIHNoYXBlXG4gICAgYXNzaWduKGNvbnRleHQsIHtcbiAgICAgIGVsZW1lbnRzOiBlbGVtZW50cyxcbiAgICAgIHNoYXBlOiBzaGFwZVxuICAgIH0pO1xuXG4gICAgYXNzaWduKGV2ZW50LCB7XG4gICAgICBlbGVtZW50czogZWxlbWVudHMsXG4gICAgICBzaGFwZTogc2hhcGVcbiAgICB9KTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gY2FuY2VsKCkge1xuICAgIHZhciBjb250ZXh0ID0gZHJhZ2dpbmcuY29udGV4dCgpO1xuXG4gICAgaWYgKGNvbnRleHQgJiYgY29udGV4dC5wcmVmaXggPT09IFBSRUZJWCkge1xuICAgICAgZHJhZ2dpbmcuY2FuY2VsKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gY2FuY2VsIG9uIDxlbGVtZW50cy5jaGFuZ2VkPiB0aGF0IGlzIG5vdCByZXN1bHQgb2YgPGRyYWcuZW5kPlxuICBldmVudEJ1cy5vbignY3JlYXRlLmluaXQnLCBmdW5jdGlvbigpIHtcbiAgICBldmVudEJ1cy5vbignZWxlbWVudHMuY2hhbmdlZCcsIGNhbmNlbCk7XG5cbiAgICBldmVudEJ1cy5vbmNlKFsgJ2NyZWF0ZS5jYW5jZWwnLCAnY3JlYXRlLmVuZCcgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oKSB7XG4gICAgICBldmVudEJ1cy5vZmYoJ2VsZW1lbnRzLmNoYW5nZWQnLCBjYW5jZWwpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBBUEkgLy8vLy8vLy8vL1xuXG4gIHRoaXMuc3RhcnQgPSBmdW5jdGlvbihldmVudCwgZWxlbWVudHMsIGNvbnRleHQpIHtcbiAgICBpZiAoIWlzQXJyYXkoZWxlbWVudHMpKSB7XG4gICAgICBlbGVtZW50cyA9IFsgZWxlbWVudHMgXTtcbiAgICB9XG5cbiAgICB2YXIgc2hhcGUgPSBmaW5kKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gIWlzQ29ubmVjdGlvbihlbGVtZW50KTtcbiAgICB9KTtcblxuICAgIGlmICghc2hhcGUpIHtcblxuICAgICAgLy8gYXQgbGVhc3Qgb25lIHNoYXBlIGlzIHJlcXVpcmVkXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29udGV4dCA9IGFzc2lnbih7XG4gICAgICBlbGVtZW50czogZWxlbWVudHMsXG4gICAgICBoaW50czoge30sXG4gICAgICBzaGFwZTogc2hhcGVcbiAgICB9LCBjb250ZXh0IHx8IHt9KTtcblxuICAgIC8vIG1ha2Ugc3VyZSBlYWNoIGVsZW1lbnQgaGFzIHggYW5kIHlcbiAgICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICBpZiAoIWlzTnVtYmVyKGVsZW1lbnQueCkpIHtcbiAgICAgICAgZWxlbWVudC54ID0gMDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc051bWJlcihlbGVtZW50LnkpKSB7XG4gICAgICAgIGVsZW1lbnQueSA9IDA7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB2YXIgYmJveCA9IGdldEJCb3goZWxlbWVudHMpO1xuXG4gICAgLy8gY2VudGVyIGVsZW1lbnRzIGFyb3VuZCBjdXJzb3JcbiAgICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICBpZiAoaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICAgIGVsZW1lbnQud2F5cG9pbnRzID0gbWFwKGVsZW1lbnQud2F5cG9pbnRzLCBmdW5jdGlvbih3YXlwb2ludCkge1xuICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiB3YXlwb2ludC54IC0gYmJveC54IC0gYmJveC53aWR0aCAvIDIsXG4gICAgICAgICAgICB5OiB3YXlwb2ludC55IC0gYmJveC55IC0gYmJveC5oZWlnaHQgLyAyXG4gICAgICAgICAgfTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGFzc2lnbihlbGVtZW50LCB7XG4gICAgICAgIHg6IGVsZW1lbnQueCAtIGJib3gueCAtIGJib3gud2lkdGggLyAyLFxuICAgICAgICB5OiBlbGVtZW50LnkgLSBiYm94LnkgLSBiYm94LmhlaWdodCAvIDJcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZHJhZ2dpbmcuaW5pdChldmVudCwgUFJFRklYLCB7XG4gICAgICBjdXJzb3I6ICdncmFiYmluZycsXG4gICAgICBhdXRvQWN0aXZhdGU6IHRydWUsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIHNoYXBlOiBzaGFwZSxcbiAgICAgICAgZWxlbWVudHM6IGVsZW1lbnRzLFxuICAgICAgICBjb250ZXh0OiBjb250ZXh0XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59XG5cbkNyZWF0ZS4kaW5qZWN0ID0gW1xuICAnY2FudmFzJyxcbiAgJ2RyYWdnaW5nJyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ21vZGVsaW5nJyxcbiAgJ3J1bGVzJ1xuXTtcblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGVuc3VyZUNvbnN0cmFpbnRzKGV2ZW50KSB7XG4gIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgIGNyZWF0ZUNvbnN0cmFpbnRzID0gY29udGV4dC5jcmVhdGVDb25zdHJhaW50cztcblxuICBpZiAoIWNyZWF0ZUNvbnN0cmFpbnRzKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGNyZWF0ZUNvbnN0cmFpbnRzLmxlZnQpIHtcbiAgICBldmVudC54ID0gTWF0aC5tYXgoZXZlbnQueCwgY3JlYXRlQ29uc3RyYWludHMubGVmdCk7XG4gIH1cblxuICBpZiAoY3JlYXRlQ29uc3RyYWludHMucmlnaHQpIHtcbiAgICBldmVudC54ID0gTWF0aC5taW4oZXZlbnQueCwgY3JlYXRlQ29uc3RyYWludHMucmlnaHQpO1xuICB9XG5cbiAgaWYgKGNyZWF0ZUNvbnN0cmFpbnRzLnRvcCkge1xuICAgIGV2ZW50LnkgPSBNYXRoLm1heChldmVudC55LCBjcmVhdGVDb25zdHJhaW50cy50b3ApO1xuICB9XG5cbiAgaWYgKGNyZWF0ZUNvbnN0cmFpbnRzLmJvdHRvbSkge1xuICAgIGV2ZW50LnkgPSBNYXRoLm1pbihldmVudC55LCBjcmVhdGVDb25zdHJhaW50cy5ib3R0b20pO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzQ29ubmVjdGlvbihlbGVtZW50KSB7XG4gIHJldHVybiAhIWVsZW1lbnQud2F5cG9pbnRzO1xufVxuXG5mdW5jdGlvbiBpc1NpbmdsZVNoYXBlKGVsZW1lbnRzKSB7XG4gIHJldHVybiBlbGVtZW50cyAmJiBlbGVtZW50cy5sZW5ndGggPT09IDEgJiYgIWlzQ29ubmVjdGlvbihlbGVtZW50c1swXSk7XG59XG5cbmZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gISFlbGVtZW50LmxhYmVsVGFyZ2V0O1xufVxuIiwiaW1wb3J0IHtcclxuICB0cmFuc2xhdGVcclxufSBmcm9tICcuLi8uLi91dGlsL1N2Z1RyYW5zZm9ybVV0aWwnO1xyXG5cclxuaW1wb3J0IHsgZ2V0VmlzdWFsIH0gZnJvbSAnLi4vLi4vdXRpbC9HcmFwaGljc1V0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxyXG4gIGF0dHIgYXMgc3ZnQXR0cixcclxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxyXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcclxufSBmcm9tICd0aW55LXN2Zyc7XHJcblxyXG52YXIgTE9XX1BSSU9SSVRZID0gNzUwO1xyXG5cclxuXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENyZWF0ZVByZXZpZXcoXHJcbiAgICBjYW52YXMsXHJcbiAgICBldmVudEJ1cyxcclxuICAgIGdyYXBoaWNzRmFjdG9yeSxcclxuICAgIHByZXZpZXdTdXBwb3J0LFxyXG4gICAgc3R5bGVzXHJcbikge1xyXG4gIGZ1bmN0aW9uIGNyZWF0ZURyYWdHcm91cChlbGVtZW50cykge1xyXG4gICAgdmFyIGRyYWdHcm91cCA9IHN2Z0NyZWF0ZSgnZycpO1xyXG5cclxuICAgIHN2Z0F0dHIoZHJhZ0dyb3VwLCBzdHlsZXMuY2xzKCdkanMtZHJhZy1ncm91cCcsIFsgJ25vLWV2ZW50cycgXSkpO1xyXG5cclxuICAgIHZhciBjaGlsZHJlbkdmeCA9IHN2Z0NyZWF0ZSgnZycpO1xyXG5cclxuICAgIGVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cclxuICAgICAgLy8gY3JlYXRlIGdyYXBoaWNzXHJcbiAgICAgIHZhciBnZng7XHJcblxyXG4gICAgICBpZiAoZWxlbWVudC5oaWRkZW4pIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChlbGVtZW50LndheXBvaW50cykge1xyXG4gICAgICAgIGdmeCA9IGdyYXBoaWNzRmFjdG9yeS5fY3JlYXRlQ29udGFpbmVyKCdjb25uZWN0aW9uJywgY2hpbGRyZW5HZngpO1xyXG5cclxuICAgICAgICBncmFwaGljc0ZhY3RvcnkuZHJhd0Nvbm5lY3Rpb24oZ2V0VmlzdWFsKGdmeCksIGVsZW1lbnQpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGdmeCA9IGdyYXBoaWNzRmFjdG9yeS5fY3JlYXRlQ29udGFpbmVyKCdzaGFwZScsIGNoaWxkcmVuR2Z4KTtcclxuXHJcbiAgICAgICAgZ3JhcGhpY3NGYWN0b3J5LmRyYXdTaGFwZShnZXRWaXN1YWwoZ2Z4KSwgZWxlbWVudCk7XHJcblxyXG4gICAgICAgIHRyYW5zbGF0ZShnZngsIGVsZW1lbnQueCwgZWxlbWVudC55KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gYWRkIHByZXZpZXdcclxuICAgICAgcHJldmlld1N1cHBvcnQuYWRkRHJhZ2dlcihlbGVtZW50LCBkcmFnR3JvdXAsIGdmeCk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gZHJhZ0dyb3VwO1xyXG4gIH1cclxuXHJcbiAgZXZlbnRCdXMub24oJ2NyZWF0ZS5tb3ZlJywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xyXG5cclxuICAgIHZhciBob3ZlciA9IGV2ZW50LmhvdmVyLFxyXG4gICAgICAgIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIGVsZW1lbnRzID0gY29udGV4dC5lbGVtZW50cyxcclxuICAgICAgICBkcmFnR3JvdXAgPSBjb250ZXh0LmRyYWdHcm91cDtcclxuXHJcbiAgICAvLyBsYXppbHkgY3JlYXRlIHByZXZpZXdzXHJcbiAgICBpZiAoIWRyYWdHcm91cCkge1xyXG4gICAgICBkcmFnR3JvdXAgPSBjb250ZXh0LmRyYWdHcm91cCA9IGNyZWF0ZURyYWdHcm91cChlbGVtZW50cyk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGRlZmF1bHRMYXllcjtcclxuXHJcbiAgICBpZiAoaG92ZXIpIHtcclxuICAgICAgaWYgKCFkcmFnR3JvdXAucGFyZW50Tm9kZSkge1xyXG4gICAgICAgIGRlZmF1bHRMYXllciA9IGNhbnZhcy5nZXREZWZhdWx0TGF5ZXIoKTtcclxuXHJcbiAgICAgICAgc3ZnQXBwZW5kKGRlZmF1bHRMYXllciwgZHJhZ0dyb3VwKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdHJhbnNsYXRlKGRyYWdHcm91cCwgZXZlbnQueCwgZXZlbnQueSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzdmdSZW1vdmUoZHJhZ0dyb3VwKTtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgZXZlbnRCdXMub24oJ2NyZWF0ZS5jbGVhbnVwJywgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgICBkcmFnR3JvdXAgPSBjb250ZXh0LmRyYWdHcm91cDtcclxuXHJcbiAgICBpZiAoZHJhZ0dyb3VwKSB7XHJcbiAgICAgIHN2Z1JlbW92ZShkcmFnR3JvdXApO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5DcmVhdGVQcmV2aWV3LiRpbmplY3QgPSBbXHJcbiAgJ2NhbnZhcycsXHJcbiAgJ2V2ZW50QnVzJyxcclxuICAnZ3JhcGhpY3NGYWN0b3J5JyxcclxuICAncHJldmlld1N1cHBvcnQnLFxyXG4gICdzdHlsZXMnXHJcbl07XHJcbiIsImltcG9ydCBEcmFnZ2luZ01vZHVsZSBmcm9tICcuLi9kcmFnZ2luZyc7XG5pbXBvcnQgUHJldmlld1N1cHBvcnRNb2R1bGUgZnJvbSAnLi4vcHJldmlldy1zdXBwb3J0JztcbmltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgU2VsZWN0aW9uTW9kdWxlIGZyb20gJy4uL3NlbGVjdGlvbic7XG5cbmltcG9ydCBDcmVhdGUgZnJvbSAnLi9DcmVhdGUnO1xuaW1wb3J0IENyZWF0ZVByZXZpZXcgZnJvbSAnLi9DcmVhdGVQcmV2aWV3JztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgRHJhZ2dpbmdNb2R1bGUsXG4gICAgUHJldmlld1N1cHBvcnRNb2R1bGUsXG4gICAgUnVsZXNNb2R1bGUsXG4gICAgU2VsZWN0aW9uTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbXG4gICAgJ2NyZWF0ZScsXG4gICAgJ2NyZWF0ZVByZXZpZXcnXG4gIF0sXG4gIGNyZWF0ZTogWyAndHlwZScsIENyZWF0ZSBdLFxuICBjcmVhdGVQcmV2aWV3OiBbICd0eXBlJywgQ3JlYXRlUHJldmlldyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgc29ydEJ5LFxuICBmb3JFYWNoLFxuICBmaWx0ZXJcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgQVhJU19ESU1FTlNJT05TID0ge1xuICBob3Jpem9udGFsOiBbICd4JywgJ3dpZHRoJyBdLFxuICB2ZXJ0aWNhbDogWyAneScsICdoZWlnaHQnIF1cbn07XG5cbnZhciBUSFJFU0hPTEQgPSA1O1xuXG5cbi8qKlxuICogR3JvdXBzIGFuZCBmaWx0ZXJzIGVsZW1lbnRzIGFuZCB0aGVuIHRyaWdnZXIgZXZlbiBkaXN0cmlidXRpb24uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERpc3RyaWJ1dGVFbGVtZW50cyhtb2RlbGluZykge1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xuXG4gIHRoaXMuX2ZpbHRlcnMgPSBbXTtcblxuICAvLyByZWdpc3RlciBmaWx0ZXIgZm9yIGZpbHRlcmluZyBiaWcgZWxlbWVudHNcbiAgdGhpcy5yZWdpc3RlckZpbHRlcihmdW5jdGlvbihlbGVtZW50cywgYXhpcywgZGltZW5zaW9uKSB7XG4gICAgdmFyIGVsZW1lbnRzU2l6ZSA9IDAsXG4gICAgICAgIG51bU9mU2hhcGVzID0gMCxcbiAgICAgICAgYXZnRGltZW5zaW9uO1xuXG4gICAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzIHx8IGVsZW1lbnQubGFiZWxUYXJnZXQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBlbGVtZW50c1NpemUgKz0gZWxlbWVudFtkaW1lbnNpb25dO1xuXG4gICAgICBudW1PZlNoYXBlcyArPSAxO1xuICAgIH0pO1xuXG4gICAgYXZnRGltZW5zaW9uID0gTWF0aC5yb3VuZChlbGVtZW50c1NpemUgLyBudW1PZlNoYXBlcyk7XG5cbiAgICByZXR1cm4gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZWxlbWVudFtkaW1lbnNpb25dIDwgKGF2Z0RpbWVuc2lvbiArIDUwKTtcbiAgICB9KTtcbiAgfSk7XG5cbn1cblxuRGlzdHJpYnV0ZUVsZW1lbnRzLiRpbmplY3QgPSBbICdtb2RlbGluZycgXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVycyBmaWx0ZXIgZnVuY3Rpb25zIHRoYXQgYWxsb3cgZXh0ZXJuYWwgcGFydGllcyB0byBmaWx0ZXJcbiAqIG91dCBjZXJ0YWluIGVsZW1lbnRzLlxuICpcbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmaWx0ZXJGblxuICovXG5EaXN0cmlidXRlRWxlbWVudHMucHJvdG90eXBlLnJlZ2lzdGVyRmlsdGVyID0gZnVuY3Rpb24oZmlsdGVyRm4pIHtcbiAgaWYgKHR5cGVvZiBmaWx0ZXJGbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcigndGhlIGZpbHRlciBoYXMgdG8gYmUgYSBmdW5jdGlvbicpO1xuICB9XG5cbiAgdGhpcy5fZmlsdGVycy5wdXNoKGZpbHRlckZuKTtcbn07XG5cbi8qKlxuICogRGlzdHJpYnV0ZXMgdGhlIGVsZW1lbnRzIHdpdGggYSBnaXZlbiBvcmllbnRhdGlvblxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBlbGVtZW50cyAgICBbZGVzY3JpcHRpb25dXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9yaWVudGF0aW9uIFtkZXNjcmlwdGlvbl1cbiAqL1xuRGlzdHJpYnV0ZUVsZW1lbnRzLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oZWxlbWVudHMsIG9yaWVudGF0aW9uKSB7XG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nO1xuXG4gIHZhciBncm91cHMsXG4gICAgICBkaXN0cmlidXRhYmxlRWxlbWVudHM7XG5cbiAgaWYgKGVsZW1lbnRzLmxlbmd0aCA8IDMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9zZXRPcmllbnRhdGlvbihvcmllbnRhdGlvbik7XG5cbiAgZGlzdHJpYnV0YWJsZUVsZW1lbnRzID0gdGhpcy5fZmlsdGVyRWxlbWVudHMoZWxlbWVudHMpO1xuXG4gIGdyb3VwcyA9IHRoaXMuX2NyZWF0ZUdyb3VwcyhkaXN0cmlidXRhYmxlRWxlbWVudHMpO1xuXG4gIC8vIG5vdGhpbmcgdG8gZGlzdHJpYnV0ZVxuICBpZiAoZ3JvdXBzLmxlbmd0aCA8PSAyKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbW9kZWxpbmcuZGlzdHJpYnV0ZUVsZW1lbnRzKGdyb3VwcywgdGhpcy5fYXhpcywgdGhpcy5fZGltZW5zaW9uKTtcblxuICByZXR1cm4gZ3JvdXBzO1xufTtcblxuLyoqXG4gKiBGaWx0ZXJzIHRoZSBlbGVtZW50cyB3aXRoIHByb3ZpZGVkIGZpbHRlcnMgYnkgZXh0ZXJuYWwgcGFydGllc1xuICpcbiAqIEBwYXJhbSAge0FycmF5W0VsZW1lbnRzXX0gZWxlbWVudHNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheVtFbGVtZW50c119XG4gKi9cbkRpc3RyaWJ1dGVFbGVtZW50cy5wcm90b3R5cGUuX2ZpbHRlckVsZW1lbnRzID0gZnVuY3Rpb24oZWxlbWVudHMpIHtcbiAgdmFyIGZpbHRlcnMgPSB0aGlzLl9maWx0ZXJzLFxuICAgICAgYXhpcyA9IHRoaXMuX2F4aXMsXG4gICAgICBkaW1lbnNpb24gPSB0aGlzLl9kaW1lbnNpb24sXG4gICAgICBkaXN0cmlidXRhYmxlRWxlbWVudHMgPSBbXS5jb25jYXQoZWxlbWVudHMpO1xuXG4gIGlmICghZmlsdGVycy5sZW5ndGgpIHtcbiAgICByZXR1cm4gZWxlbWVudHM7XG4gIH1cblxuICBmb3JFYWNoKGZpbHRlcnMsIGZ1bmN0aW9uKGZpbHRlckZuKSB7XG4gICAgZGlzdHJpYnV0YWJsZUVsZW1lbnRzID0gZmlsdGVyRm4oZGlzdHJpYnV0YWJsZUVsZW1lbnRzLCBheGlzLCBkaW1lbnNpb24pO1xuICB9KTtcblxuICByZXR1cm4gZGlzdHJpYnV0YWJsZUVsZW1lbnRzO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZSByYW5nZSAobWluLCBtYXgpIGdyb3Vwcy4gQWxzbyB0cmllcyB0byBncm91cCBlbGVtZW50c1xuICogdG9nZXRoZXIgdGhhdCBzaGFyZSB0aGUgc2FtZSByYW5nZS5cbiAqXG4gKiBAZXhhbXBsZVxuICogXHR2YXIgZGlzdHJpYnV0YWJsZUVsZW1lbnRzID0gW1xuICogXHRcdHtcbiAqIFx0XHRcdHJhbmdlOiB7XG4gKiBcdFx0XHRcdG1pbjogMTAwLFxuICogXHRcdFx0XHRtYXg6IDIwMFxuICogXHRcdFx0fSxcbiAqIFx0XHRcdGVsZW1lbnRzOiBbIHsgaWQ6ICdzaGFwZTEnLCAuLiB9XVxuICogXHRcdH1cbiAqIFx0XVxuICpcbiAqIEBwYXJhbSAge0FycmF5fSBlbGVtZW50c1xuICpcbiAqIEByZXR1cm4ge0FycmF5W09iamVjdHNdfVxuICovXG5EaXN0cmlidXRlRWxlbWVudHMucHJvdG90eXBlLl9jcmVhdGVHcm91cHMgPSBmdW5jdGlvbihlbGVtZW50cykge1xuICB2YXIgcmFuZ2VHcm91cHMgPSBbXSxcbiAgICAgIHNlbGYgPSB0aGlzLFxuICAgICAgYXhpcyA9IHRoaXMuX2F4aXMsXG4gICAgICBkaW1lbnNpb24gPSB0aGlzLl9kaW1lbnNpb247XG5cbiAgaWYgKCFheGlzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdtdXN0IGhhdmUgYSBkZWZpbmVkIFwiYXhpc1wiIGFuZCBcImRpbWVuc2lvblwiJyk7XG4gIH1cblxuICAvLyBzb3J0IGJ5ICdsZWZ0LT5yaWdodCcgb3IgJ3RvcC0+Ym90dG9tJ1xuICB2YXIgc29ydGVkRWxlbWVudHMgPSBzb3J0QnkoZWxlbWVudHMsIGF4aXMpO1xuXG4gIGZvckVhY2goc29ydGVkRWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQsIGlkeCkge1xuICAgIHZhciBlbGVtZW50UmFuZ2UgPSBzZWxmLl9maW5kUmFuZ2UoZWxlbWVudCwgYXhpcywgZGltZW5zaW9uKSxcbiAgICAgICAgcmFuZ2U7XG5cbiAgICB2YXIgcHJldmlvdXMgPSByYW5nZUdyb3Vwc1tyYW5nZUdyb3Vwcy5sZW5ndGggLSAxXTtcblxuICAgIGlmIChwcmV2aW91cyAmJiBzZWxmLl9oYXNJbnRlcnNlY3Rpb24ocHJldmlvdXMucmFuZ2UsIGVsZW1lbnRSYW5nZSkpIHtcbiAgICAgIHJhbmdlR3JvdXBzW3JhbmdlR3JvdXBzLmxlbmd0aCAtIDFdLmVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJhbmdlID0geyByYW5nZTogZWxlbWVudFJhbmdlLCBlbGVtZW50czogWyBlbGVtZW50IF0gfTtcblxuICAgICAgcmFuZ2VHcm91cHMucHVzaChyYW5nZSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmFuZ2VHcm91cHM7XG59O1xuXG5cbi8qKlxuICogTWFwcyBhIGRpcmVjdGlvbiB0byB0aGUgYWNjb3JkaW5nIGF4aXMgYW5kIGRpbWVuc2lvblxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gZGlyZWN0aW9uICdob3Jpem9udGFsJyBvciAndmVydGljYWwnXG4gKi9cbkRpc3RyaWJ1dGVFbGVtZW50cy5wcm90b3R5cGUuX3NldE9yaWVudGF0aW9uID0gZnVuY3Rpb24oZGlyZWN0aW9uKSB7XG4gIHZhciBvcmllbnRhdGlvbiA9IEFYSVNfRElNRU5TSU9OU1tkaXJlY3Rpb25dO1xuXG4gIHRoaXMuX2F4aXMgPSBvcmllbnRhdGlvblswXTtcbiAgdGhpcy5fZGltZW5zaW9uID0gb3JpZW50YXRpb25bMV07XG59O1xuXG5cbi8qKlxuICogQ2hlY2tzIGlmIHRoZSB0d28gcmFuZ2VzIGludGVyY2VwdCBlYWNoIG90aGVyXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSByYW5nZUEge21pbiwgbWF4fVxuICogQHBhcmFtICB7T2JqZWN0fSByYW5nZUIge21pbiwgbWF4fVxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbkRpc3RyaWJ1dGVFbGVtZW50cy5wcm90b3R5cGUuX2hhc0ludGVyc2VjdGlvbiA9IGZ1bmN0aW9uKHJhbmdlQSwgcmFuZ2VCKSB7XG4gIHJldHVybiBNYXRoLm1heChyYW5nZUEubWluLCByYW5nZUEubWF4KSA+PSBNYXRoLm1pbihyYW5nZUIubWluLCByYW5nZUIubWF4KSAmJlxuICAgICAgICAgTWF0aC5taW4ocmFuZ2VBLm1pbiwgcmFuZ2VBLm1heCkgPD0gTWF0aC5tYXgocmFuZ2VCLm1pbiwgcmFuZ2VCLm1heCk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWluIGFuZCBtYXggdmFsdWVzIGZvciBhbiBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7W3R5cGVdfSBlbGVtZW50ICAgW2Rlc2NyaXB0aW9uXVxuICogQHBhcmFtICB7W3R5cGVdfSBheGlzICAgICAgW2Rlc2NyaXB0aW9uXVxuICogQHBhcmFtICB7W3R5cGVdfSBkaW1lbnNpb24gW2Rlc2NyaXB0aW9uXVxuICpcbiAqIEByZXR1cm4ge1t0eXBlXX0gICAgICAgICAgIFtkZXNjcmlwdGlvbl1cbiAqL1xuRGlzdHJpYnV0ZUVsZW1lbnRzLnByb3RvdHlwZS5fZmluZFJhbmdlID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICB2YXIgYXhpcyA9IGVsZW1lbnRbdGhpcy5fYXhpc10sXG4gICAgICBkaW1lbnNpb24gPSBlbGVtZW50W3RoaXMuX2RpbWVuc2lvbl07XG5cbiAgcmV0dXJuIHtcbiAgICBtaW46IGF4aXMgKyBUSFJFU0hPTEQsXG4gICAgbWF4OiBheGlzICsgZGltZW5zaW9uIC0gVEhSRVNIT0xEXG4gIH07XG59O1xuIiwiaW1wb3J0IERpc3RyaWJ1dGVFbGVtZW50cyBmcm9tICcuL0Rpc3RyaWJ1dGVFbGVtZW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2Rpc3RyaWJ1dGVFbGVtZW50cycgXSxcbiAgZGlzdHJpYnV0ZUVsZW1lbnRzOiBbICd0eXBlJywgRGlzdHJpYnV0ZUVsZW1lbnRzIF1cbn07XG4iLCIvKiBnbG9iYWwgVG91Y2hFdmVudCAqL1xuXG52YXIgcm91bmQgPSBNYXRoLnJvdW5kO1xuXG5pbXBvcnQgeyBhc3NpZ24gfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50XG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICBnZXRPcmlnaW5hbCxcbiAgdG9Qb2ludCxcbiAgc3RvcFByb3BhZ2F0aW9uXG59IGZyb20gJy4uLy4uL3V0aWwvRXZlbnQnO1xuXG5pbXBvcnQge1xuICBzZXQgYXMgY3Vyc29yU2V0LFxuICB1bnNldCBhcyBjdXJzb3JVbnNldFxufSBmcm9tICcuLi8uLi91dGlsL0N1cnNvcic7XG5cbmltcG9ydCB7XG4gIGluc3RhbGwgYXMgaW5zdGFsbENsaWNrVHJhcFxufSBmcm9tICcuLi8uLi91dGlsL0NsaWNrVHJhcCc7XG5cbmltcG9ydCB7XG4gIGRlbHRhIGFzIGRlbHRhUG9zXG59IGZyb20gJy4uLy4uL3V0aWwvUG9zaXRpb25VdGlsJztcblxudmFyIERSQUdfQUNUSVZFX0NMUyA9ICdkanMtZHJhZy1hY3RpdmUnO1xuXG5cbmZ1bmN0aW9uIHByZXZlbnREZWZhdWx0KGV2ZW50KSB7XG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG59XG5cbmZ1bmN0aW9uIGlzVG91Y2hFdmVudChldmVudCkge1xuXG4gIC8vIGNoZWNrIGZvciBUb3VjaEV2ZW50IGJlaW5nIGF2YWlsYWJsZSBmaXJzdFxuICAvLyAoaS5lLiBub3QgYXZhaWxhYmxlIG9uIGRlc2t0b3AgRmlyZWZveClcbiAgcmV0dXJuIHR5cGVvZiBUb3VjaEV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBldmVudCBpbnN0YW5jZW9mIFRvdWNoRXZlbnQ7XG59XG5cbmZ1bmN0aW9uIGdldExlbmd0aChwb2ludCkge1xuICByZXR1cm4gTWF0aC5zcXJ0KE1hdGgucG93KHBvaW50LngsIDIpICsgTWF0aC5wb3cocG9pbnQueSwgMikpO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIHRoYXQgZmlyZXMgY2FudmFzIGxvY2FsaXplZCBkcmFnIGV2ZW50cyBhbmQgcmVhbGl6ZXNcbiAqIHRoZSBnZW5lcmFsIFwiZHJhZy1hbmQtZHJvcFwiIGxvb2sgYW5kIGZlZWwuXG4gKlxuICogQ2FsbGluZyB7QGxpbmsgRHJhZ2dpbmcjYWN0aXZhdGV9IGFjdGl2YXRlcyBkcmFnZ2luZyBvbiBhIGNhbnZhcy5cbiAqXG4gKiBJdCBwcm92aWRlcyB0aGUgZm9sbG93aW5nOlxuICpcbiAqICAgKiBlbWl0cyBsaWZlIGN5Y2xlIGV2ZW50cywgbmFtZXNwYWNlZCB3aXRoIGEgcHJlZml4IGFzc2lnbmVkXG4gKiAgICAgZHVyaW5nIGRyYWdnaW5nIGFjdGl2YXRpb25cbiAqICAgKiBzZXRzIGFuZCByZXN0b3JlcyB0aGUgY3Vyc29yXG4gKiAgICogc2V0cyBhbmQgcmVzdG9yZXMgdGhlIHNlbGVjdGlvbiBpZiBlbGVtZW50cyBzdGlsbCBleGlzdFxuICogICAqIGVuc3VyZXMgdGhlcmUgY2FuIGJlIG9ubHkgb25lIGRyYWcgb3BlcmF0aW9uIGFjdGl2ZSBhdCBhIHRpbWVcbiAqXG4gKiBEcmFnZ2luZyBtYXkgYmUgY2FuY2VsZWQgbWFudWFsbHkgYnkgY2FsbGluZyB7QGxpbmsgRHJhZ2dpbmcjY2FuY2VsfVxuICogb3IgYnkgcHJlc3NpbmcgRVNDLlxuICpcbiAqXG4gKiAjIyBMaWZlLWN5Y2xlIGV2ZW50c1xuICpcbiAqIERyYWdnaW5nIGNhbiBiZSBpbiB0aHJlZSBkaWZmZXJlbnQgc3RhdGVzLCBvZmYsIGluaXRpYWxpemVkXG4gKiBhbmQgYWN0aXZlLlxuICpcbiAqICgxKSBvZmY6IG5vIGRyYWdnaW5nIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzc1xuICogKDIpIGluaXRpYWxpemVkOiBhIG5ldyBkcmFnIG9wZXJhdGlvbiBnb3QgaW5pdGlhbGl6ZWQgYnV0IG5vdCB5ZXRcbiAqICAgICAgICAgICAgICAgICAgc3RhcnRlZCAoaS5lLiBiZWNhdXNlIG9mIG5vIGluaXRpYWwgbW92ZSlcbiAqICgzKSBzdGFydGVkOiBkcmFnZ2luZyBpcyBpbiBwcm9ncmVzc1xuICpcbiAqIEV2ZW50dWFsbHkgZHJhZ2dpbmcgd2lsbCBiZSBvZmYgYWdhaW4gYWZ0ZXIgYSBkcmFnIG9wZXJhdGlvbiBoYXNcbiAqIGJlZW4gZW5kZWQgb3IgY2FuY2VsZWQgdmlhIHVzZXIgY2xpY2sgb3IgRVNDIGtleSBwcmVzcy5cbiAqXG4gKiBUbyBpbmRpY2F0ZSB0cmFuc2l0aW9ucyBiZXR3ZWVuIHRoZXNlIHN0YXRlcyBkcmFnZ2luZyBlbWl0cyBnZW5lcmljXG4gKiBsaWZlLWN5Y2xlIGV2ZW50cyB3aXRoIHRoZSBgZHJhZy5gIHByZWZpeCBfYW5kXyBldmVudHMgbmFtZXNwYWNlZFxuICogdG8gYSBwcmVmaXggY2hvb3NlbiBieSBhIHVzZXIgZHVyaW5nIGRyYWcgaW5pdGlhbGl6YXRpb24uXG4gKlxuICogVGhlIGZvbGxvd2luZyBldmVudHMgYXJlIGVtaXR0ZWQgKGFwcHJvcHJpYXRlbHkgcHJlZml4ZWQpIHZpYVxuICogdGhlIHtAbGluayBFdmVudEJ1c30uXG4gKlxuICogKiBgaW5pdGBcbiAqICogYHN0YXJ0YFxuICogKiBgbW92ZWBcbiAqICogYGVuZGBcbiAqICogYGVuZGVkYCAoZHJhZ2dpbmcgYWxyZWFkeSBpbiBvZmYgc3RhdGUpXG4gKiAqIGBjYW5jZWxgIChvbmx5IGlmIHByZXZpb3VzbHkgc3RhcnRlZClcbiAqICogYGNhbmNlbGVkYCAoZHJhZ2dpbmcgYWxyZWFkeSBpbiBvZmYgc3RhdGUsIG9ubHkgaWYgcHJldmlvdXNseSBzdGFydGVkKVxuICogKiBgY2xlYW51cGBcbiAqXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBNeURyYWdDb21wb25lbnQoZXZlbnRCdXMsIGRyYWdnaW5nKSB7XG4gKlxuICogICBldmVudEJ1cy5vbignbXlkcmFnLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgICBjb25zb2xlLmxvZygneWVzLCB3ZSBzdGFydCBkcmFnZ2luZycpO1xuICogICB9KTtcbiAqXG4gKiAgIGV2ZW50QnVzLm9uKCdteWRyYWcubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gKiAgICAgY29uc29sZS5sb2coJ2NhbnZhcyBsb2NhbCBjb29yZGluYXRlcycsIGV2ZW50LngsIGV2ZW50LnksIGV2ZW50LmR4LCBldmVudC5keSk7XG4gKlxuICogICAgIC8vIGxvY2FsIGRyYWcgZGF0YSBpcyBwYXNzZWQgd2l0aCB0aGUgZXZlbnRcbiAqICAgICBldmVudC5jb250ZXh0LmZvbzsgLy8gXCJCQVJcIlxuICpcbiAqICAgICAvLyB0aGUgb3JpZ2luYWwgbW91c2UgZXZlbnQsIHRvb1xuICogICAgIGV2ZW50Lm9yaWdpbmFsRXZlbnQ7IC8vIE1vdXNlRXZlbnQoLi4uKVxuICogICB9KTtcbiAqXG4gKiAgIGV2ZW50QnVzLm9uKCdlbGVtZW50LmNsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAqICAgICBkcmFnZ2luZy5pbml0KGV2ZW50LCAnbXlkcmFnJywge1xuICogICAgICAgY3Vyc29yOiAnZ3JhYmJpbmcnLFxuICogICAgICAgZGF0YToge1xuICogICAgICAgICBjb250ZXh0OiB7XG4gKiAgICAgICAgICAgZm9vOiBcIkJBUlwiXG4gKiAgICAgICAgIH1cbiAqICAgICAgIH1cbiAqICAgICB9KTtcbiAqICAgfSk7XG4gKiB9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERyYWdnaW5nKGV2ZW50QnVzLCBjYW52YXMsIHNlbGVjdGlvbiwgZWxlbWVudFJlZ2lzdHJ5KSB7XG5cbiAgdmFyIGRlZmF1bHRPcHRpb25zID0ge1xuICAgIHRocmVzaG9sZDogNSxcbiAgICB0cmFwQ2xpY2s6IHRydWVcbiAgfTtcblxuICAvLyB0aGUgY3VycmVudGx5IGFjdGl2ZSBkcmFnIG9wZXJhdGlvblxuICAvLyBkcmFnZ2luZyBpcyBhY3RpdmUgYXMgc29vbiBhcyB0aGlzIGNvbnRleHQgZXhpc3RzLlxuICAvL1xuICAvLyBpdCBpcyB2aXN1YWxseSBfYWN0aXZlXyBvbmx5IHdoZW4gYSBjb250ZXh0LmFjdGl2ZSBmbGFnIGlzIHNldCB0byB0cnVlLlxuICB2YXIgY29udGV4dDtcblxuICAvKiBjb252ZXJ0IGEgZ2xvYmFsIGV2ZW50IGludG8gbG9jYWwgY29vcmRpbmF0ZXMgKi9cbiAgZnVuY3Rpb24gdG9Mb2NhbFBvaW50KGdsb2JhbFBvc2l0aW9uKSB7XG5cbiAgICB2YXIgdmlld2JveCA9IGNhbnZhcy52aWV3Ym94KCk7XG5cbiAgICB2YXIgY2xpZW50UmVjdCA9IGNhbnZhcy5fY29udGFpbmVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHZpZXdib3gueCArIChnbG9iYWxQb3NpdGlvbi54IC0gY2xpZW50UmVjdC5sZWZ0KSAvIHZpZXdib3guc2NhbGUsXG4gICAgICB5OiB2aWV3Ym94LnkgKyAoZ2xvYmFsUG9zaXRpb24ueSAtIGNsaWVudFJlY3QudG9wKSAvIHZpZXdib3guc2NhbGVcbiAgICB9O1xuICB9XG5cbiAgLy8gaGVscGVyc1xuXG4gIGZ1bmN0aW9uIGZpcmUodHlwZSwgZHJhZ0NvbnRleHQpIHtcbiAgICBkcmFnQ29udGV4dCA9IGRyYWdDb250ZXh0IHx8IGNvbnRleHQ7XG5cbiAgICB2YXIgZXZlbnQgPSBldmVudEJ1cy5jcmVhdGVFdmVudChcbiAgICAgIGFzc2lnbihcbiAgICAgICAge30sXG4gICAgICAgIGRyYWdDb250ZXh0LnBheWxvYWQsXG4gICAgICAgIGRyYWdDb250ZXh0LmRhdGEsXG4gICAgICAgIHsgaXNUb3VjaDogZHJhZ0NvbnRleHQuaXNUb3VjaCB9XG4gICAgICApXG4gICAgKTtcblxuICAgIC8vIGRlZmF1bHQgaW50ZWdyYXRpb25cbiAgICBpZiAoZXZlbnRCdXMuZmlyZSgnZHJhZy4nICsgdHlwZSwgZXZlbnQpID09PSBmYWxzZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiBldmVudEJ1cy5maXJlKGRyYWdDb250ZXh0LnByZWZpeCArICcuJyArIHR5cGUsIGV2ZW50KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc3RvcmVTZWxlY3Rpb24ocHJldmlvdXNTZWxlY3Rpb24pIHtcbiAgICB2YXIgZXhpc3RpbmdTZWxlY3Rpb24gPSBwcmV2aW91c1NlbGVjdGlvbi5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIGVsZW1lbnRSZWdpc3RyeS5nZXQoZWxlbWVudC5pZCk7XG4gICAgfSk7XG5cbiAgICBleGlzdGluZ1NlbGVjdGlvbi5sZW5ndGggJiYgc2VsZWN0aW9uLnNlbGVjdChleGlzdGluZ1NlbGVjdGlvbik7XG4gIH1cblxuICAvLyBldmVudCBsaXN0ZW5lcnNcblxuICBmdW5jdGlvbiBtb3ZlKGV2ZW50LCBhY3RpdmF0ZSkge1xuICAgIHZhciBwYXlsb2FkID0gY29udGV4dC5wYXlsb2FkLFxuICAgICAgICBkaXNwbGFjZW1lbnQgPSBjb250ZXh0LmRpc3BsYWNlbWVudDtcblxuICAgIHZhciBnbG9iYWxTdGFydCA9IGNvbnRleHQuZ2xvYmFsU3RhcnQsXG4gICAgICAgIGdsb2JhbEN1cnJlbnQgPSB0b1BvaW50KGV2ZW50KSxcbiAgICAgICAgZ2xvYmFsRGVsdGEgPSBkZWx0YVBvcyhnbG9iYWxDdXJyZW50LCBnbG9iYWxTdGFydCk7XG5cbiAgICB2YXIgbG9jYWxTdGFydCA9IGNvbnRleHQubG9jYWxTdGFydCxcbiAgICAgICAgbG9jYWxDdXJyZW50ID0gdG9Mb2NhbFBvaW50KGdsb2JhbEN1cnJlbnQpLFxuICAgICAgICBsb2NhbERlbHRhID0gZGVsdGFQb3MobG9jYWxDdXJyZW50LCBsb2NhbFN0YXJ0KTtcblxuXG4gICAgLy8gYWN0aXZhdGUgY29udGV4dCBleHBsaWNpdGx5IG9yIG9uY2UgdGhyZXNob2xkIGlzIHJlYWNoZWRcbiAgICBpZiAoIWNvbnRleHQuYWN0aXZlICYmIChhY3RpdmF0ZSB8fCBnZXRMZW5ndGgoZ2xvYmFsRGVsdGEpID4gY29udGV4dC50aHJlc2hvbGQpKSB7XG5cbiAgICAgIC8vIGZpcmUgc3RhcnQgZXZlbnQgd2l0aCBvcmlnaW5hbFxuICAgICAgLy8gc3RhcnRpbmcgY29vcmRpbmF0ZXNcblxuICAgICAgYXNzaWduKHBheWxvYWQsIHtcbiAgICAgICAgeDogcm91bmQobG9jYWxTdGFydC54ICsgZGlzcGxhY2VtZW50LngpLFxuICAgICAgICB5OiByb3VuZChsb2NhbFN0YXJ0LnkgKyBkaXNwbGFjZW1lbnQueSksXG4gICAgICAgIGR4OiAwLFxuICAgICAgICBkeTogMFxuICAgICAgfSwgeyBvcmlnaW5hbEV2ZW50OiBldmVudCB9KTtcblxuICAgICAgaWYgKGZhbHNlID09PSBmaXJlKCdzdGFydCcpKSB7XG4gICAgICAgIHJldHVybiBjYW5jZWwoKTtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5hY3RpdmUgPSB0cnVlO1xuXG4gICAgICAvLyB1bnNldCBzZWxlY3Rpb24gYW5kIHJlbWVtYmVyIG9sZCBzZWxlY3Rpb25cbiAgICAgIC8vIHRoZSBwcmV2aW91cyAob2xkKSBzZWxlY3Rpb24gd2lsbCBhbHdheXMgcGFzc2VkXG4gICAgICAvLyB3aXRoIHRoZSBldmVudCB2aWEgdGhlIGV2ZW50LnByZXZpb3VzU2VsZWN0aW9uIHByb3BlcnR5XG4gICAgICBpZiAoIWNvbnRleHQua2VlcFNlbGVjdGlvbikge1xuICAgICAgICBwYXlsb2FkLnByZXZpb3VzU2VsZWN0aW9uID0gc2VsZWN0aW9uLmdldCgpO1xuICAgICAgICBzZWxlY3Rpb24uc2VsZWN0KG51bGwpO1xuICAgICAgfVxuXG4gICAgICAvLyBhbGxvdyBjdXN0b20gY3Vyc29yXG4gICAgICBpZiAoY29udGV4dC5jdXJzb3IpIHtcbiAgICAgICAgY3Vyc29yU2V0KGNvbnRleHQuY3Vyc29yKTtcbiAgICAgIH1cblxuICAgICAgLy8gaW5kaWNhdGUgZHJhZ2dpbmcgdmlhIG1hcmtlciBvbiByb290IGVsZW1lbnRcbiAgICAgIGNhbnZhcy5hZGRNYXJrZXIoY2FudmFzLmdldFJvb3RFbGVtZW50KCksIERSQUdfQUNUSVZFX0NMUyk7XG4gICAgfVxuXG4gICAgc3RvcFByb3BhZ2F0aW9uKGV2ZW50KTtcblxuICAgIGlmIChjb250ZXh0LmFjdGl2ZSkge1xuXG4gICAgICAvLyB1cGRhdGUgcGF5bG9hZCB3aXRoIGFjdHVhbCBjb29yZGluYXRlc1xuICAgICAgYXNzaWduKHBheWxvYWQsIHtcbiAgICAgICAgeDogcm91bmQobG9jYWxDdXJyZW50LnggKyBkaXNwbGFjZW1lbnQueCksXG4gICAgICAgIHk6IHJvdW5kKGxvY2FsQ3VycmVudC55ICsgZGlzcGxhY2VtZW50LnkpLFxuICAgICAgICBkeDogcm91bmQobG9jYWxEZWx0YS54KSxcbiAgICAgICAgZHk6IHJvdW5kKGxvY2FsRGVsdGEueSlcbiAgICAgIH0sIHsgb3JpZ2luYWxFdmVudDogZXZlbnQgfSk7XG5cbiAgICAgIC8vIGVtaXQgbW92ZSBldmVudFxuICAgICAgZmlyZSgnbW92ZScpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGVuZChldmVudCkge1xuICAgIHZhciBwcmV2aW91c0NvbnRleHQsXG4gICAgICAgIHJldHVyblZhbHVlID0gdHJ1ZTtcblxuICAgIGlmIChjb250ZXh0LmFjdGl2ZSkge1xuXG4gICAgICBpZiAoZXZlbnQpIHtcbiAgICAgICAgY29udGV4dC5wYXlsb2FkLm9yaWdpbmFsRXZlbnQgPSBldmVudDtcblxuICAgICAgICAvLyBzdXBwcmVzcyBvcmlnaW5hbCBldmVudCAoY2xpY2ssIC4uLilcbiAgICAgICAgLy8gYmVjYXVzZSB3ZSBqdXN0IGVuZGVkIGEgZHJhZyBvcGVyYXRpb25cbiAgICAgICAgc3RvcFByb3BhZ2F0aW9uKGV2ZW50KTtcbiAgICAgIH1cblxuICAgICAgLy8gaW1wbGVtZW50YXRpb25zIG1heSBzdG9wIHJlc3RvcmluZyB0aGVcbiAgICAgIC8vIG9yaWdpbmFsIHN0YXRlIChzZWxlY3Rpb25zLCAuLi4pIGJ5IHByZXZlbnRpbmcgdGhlXG4gICAgICAvLyBlbmQgZXZlbnRzIGRlZmF1bHQgYWN0aW9uXG4gICAgICByZXR1cm5WYWx1ZSA9IGZpcmUoJ2VuZCcpO1xuICAgIH1cblxuICAgIGlmIChyZXR1cm5WYWx1ZSA9PT0gZmFsc2UpIHtcbiAgICAgIGZpcmUoJ3JlamVjdGVkJyk7XG4gICAgfVxuXG4gICAgcHJldmlvdXNDb250ZXh0ID0gY2xlYW51cChyZXR1cm5WYWx1ZSAhPT0gdHJ1ZSk7XG5cbiAgICAvLyBsYXN0IGV2ZW50IHRvIGJlIGZpcmVkIHdoZW4gYWxsIGRyYWcgb3BlcmF0aW9ucyBhcmUgZG9uZVxuICAgIC8vIGF0IHRoaXMgcG9pbnQgaW4gdGltZSBubyBkcmFnIG9wZXJhdGlvbiBpcyBpbiBwcm9ncmVzcyBhbnltb3JlXG4gICAgZmlyZSgnZW5kZWQnLCBwcmV2aW91c0NvbnRleHQpO1xuICB9XG5cblxuICAvLyBjYW5jZWwgYWN0aXZlIGRyYWcgb3BlcmF0aW9uIGlmIHRoZSB1c2VyIHByZXNzZXNcbiAgLy8gdGhlIEVTQyBrZXkgb24gdGhlIGtleWJvYXJkXG5cbiAgZnVuY3Rpb24gY2hlY2tDYW5jZWwoZXZlbnQpIHtcblxuICAgIGlmIChldmVudC53aGljaCA9PT0gMjcpIHtcbiAgICAgIHByZXZlbnREZWZhdWx0KGV2ZW50KTtcblxuICAgICAgY2FuY2VsKCk7XG4gICAgfVxuICB9XG5cblxuICAvLyBwcmV2ZW50IGdob3N0IGNsaWNrIHRoYXQgbWlnaHQgb2NjdXIgYWZ0ZXIgYSBmaW5pc2hlZFxuICAvLyBkcmFnIGFuZCBkcm9wIHNlc3Npb25cblxuICBmdW5jdGlvbiB0cmFwQ2xpY2tBbmRFbmQoZXZlbnQpIHtcblxuICAgIHZhciB1bnRyYXA7XG5cbiAgICAvLyB0cmFwIHRoZSBjbGljayBpbiBjYXNlIHdlIGFyZSBwYXJ0IG9mIGFuIGFjdGl2ZVxuICAgIC8vIGRyYWcgb3BlcmF0aW9uLiBUaGlzIHdpbGwgZWZmZWN0aXZlbHkgcHJldmVudFxuICAgIC8vIHRoZSBnaG9zdCBjbGljayB0aGF0IGNhbm5vdCBiZSBjYW5jZWxlZCBvdGhlcndpc2UuXG4gICAgaWYgKGNvbnRleHQuYWN0aXZlKSB7XG5cbiAgICAgIHVudHJhcCA9IGluc3RhbGxDbGlja1RyYXAoZXZlbnRCdXMpO1xuXG4gICAgICAvLyByZW1vdmUgdHJhcCBhZnRlciBtaW5pbWFsIGRlbGF5XG4gICAgICBzZXRUaW1lb3V0KHVudHJhcCwgNDAwKTtcblxuICAgICAgLy8gcHJldmVudCBkZWZhdWx0IGFjdGlvbiAoY2xpY2spXG4gICAgICBwcmV2ZW50RGVmYXVsdChldmVudCk7XG4gICAgfVxuXG4gICAgZW5kKGV2ZW50KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYXBUb3VjaChldmVudCkge1xuICAgIG1vdmUoZXZlbnQpO1xuICB9XG5cbiAgLy8gdXBkYXRlIHRoZSBkcmFnIGV2ZW50cyBob3ZlciAoZGpzLm1vZGVsLkJhc2UpIGFuZCBob3ZlckdmeCAoU25hcDxTVkdFbGVtZW50PilcbiAgLy8gcHJvcGVydGllcyBkdXJpbmcgaG92ZXIgYW5kIG91dCBhbmQgZmlyZSB7cHJlZml4fS5ob3ZlciBhbmQge3ByZWZpeH0ub3V0IHByb3BlcnRpZXNcbiAgLy8gcmVzcGVjdGl2ZWx5XG5cbiAgZnVuY3Rpb24gaG92ZXIoZXZlbnQpIHtcbiAgICB2YXIgcGF5bG9hZCA9IGNvbnRleHQucGF5bG9hZDtcblxuICAgIHBheWxvYWQuaG92ZXJHZnggPSBldmVudC5nZng7XG4gICAgcGF5bG9hZC5ob3ZlciA9IGV2ZW50LmVsZW1lbnQ7XG5cbiAgICBmaXJlKCdob3ZlcicpO1xuICB9XG5cbiAgZnVuY3Rpb24gb3V0KGV2ZW50KSB7XG4gICAgZmlyZSgnb3V0Jyk7XG5cbiAgICB2YXIgcGF5bG9hZCA9IGNvbnRleHQucGF5bG9hZDtcblxuICAgIHBheWxvYWQuaG92ZXJHZnggPSBudWxsO1xuICAgIHBheWxvYWQuaG92ZXIgPSBudWxsO1xuICB9XG5cblxuICAvLyBsaWZlLWN5Y2xlIG1ldGhvZHNcblxuICBmdW5jdGlvbiBjYW5jZWwocmVzdG9yZSkge1xuICAgIHZhciBwcmV2aW91c0NvbnRleHQ7XG5cbiAgICBpZiAoIWNvbnRleHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgd2FzQWN0aXZlID0gY29udGV4dC5hY3RpdmU7XG5cbiAgICBpZiAod2FzQWN0aXZlKSB7XG4gICAgICBmaXJlKCdjYW5jZWwnKTtcbiAgICB9XG5cbiAgICBwcmV2aW91c0NvbnRleHQgPSBjbGVhbnVwKHJlc3RvcmUpO1xuXG4gICAgaWYgKHdhc0FjdGl2ZSkge1xuXG4gICAgICAvLyBsYXN0IGV2ZW50IHRvIGJlIGZpcmVkIHdoZW4gYWxsIGRyYWcgb3BlcmF0aW9ucyBhcmUgZG9uZVxuICAgICAgLy8gYXQgdGhpcyBwb2ludCBpbiB0aW1lIG5vIGRyYWcgb3BlcmF0aW9uIGlzIGluIHByb2dyZXNzIGFueW1vcmVcbiAgICAgIGZpcmUoJ2NhbmNlbGVkJywgcHJldmlvdXNDb250ZXh0KTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjbGVhbnVwKHJlc3RvcmUpIHtcbiAgICB2YXIgcHJldmlvdXNDb250ZXh0LFxuICAgICAgICBlbmREcmFnO1xuXG4gICAgZmlyZSgnY2xlYW51cCcpO1xuXG4gICAgLy8gcmVzZXQgY3Vyc29yXG4gICAgY3Vyc29yVW5zZXQoKTtcblxuICAgIGlmIChjb250ZXh0LnRyYXBDbGljaykge1xuICAgICAgZW5kRHJhZyA9IHRyYXBDbGlja0FuZEVuZDtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5kRHJhZyA9IGVuZDtcbiAgICB9XG5cbiAgICAvLyByZXNldCBkb20gbGlzdGVuZXJzXG4gICAgZG9tRXZlbnQudW5iaW5kKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgbW92ZSk7XG5cbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdkcmFnc3RhcnQnLCBwcmV2ZW50RGVmYXVsdCk7XG4gICAgZG9tRXZlbnQudW5iaW5kKGRvY3VtZW50LCAnc2VsZWN0c3RhcnQnLCBwcmV2ZW50RGVmYXVsdCk7XG5cbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdtb3VzZWRvd24nLCBlbmREcmFnLCB0cnVlKTtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdtb3VzZXVwJywgZW5kRHJhZywgdHJ1ZSk7XG5cbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdrZXl1cCcsIGNoZWNrQ2FuY2VsKTtcblxuICAgIGRvbUV2ZW50LnVuYmluZChkb2N1bWVudCwgJ3RvdWNoc3RhcnQnLCB0cmFwVG91Y2gsIHRydWUpO1xuICAgIGRvbUV2ZW50LnVuYmluZChkb2N1bWVudCwgJ3RvdWNoY2FuY2VsJywgY2FuY2VsLCB0cnVlKTtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICd0b3VjaG1vdmUnLCBtb3ZlLCB0cnVlKTtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICd0b3VjaGVuZCcsIGVuZCwgdHJ1ZSk7XG5cbiAgICBldmVudEJ1cy5vZmYoJ2VsZW1lbnQuaG92ZXInLCBob3Zlcik7XG4gICAgZXZlbnRCdXMub2ZmKCdlbGVtZW50Lm91dCcsIG91dCk7XG5cbiAgICAvLyByZW1vdmUgZHJhZyBtYXJrZXIgb24gcm9vdCBlbGVtZW50XG4gICAgY2FudmFzLnJlbW92ZU1hcmtlcihjYW52YXMuZ2V0Um9vdEVsZW1lbnQoKSwgRFJBR19BQ1RJVkVfQ0xTKTtcblxuICAgIC8vIHJlc3RvcmUgc2VsZWN0aW9uLCB1bmxlc3MgaXQgaGFzIGNoYW5nZWRcbiAgICB2YXIgcHJldmlvdXNTZWxlY3Rpb24gPSBjb250ZXh0LnBheWxvYWQucHJldmlvdXNTZWxlY3Rpb247XG5cbiAgICBpZiAocmVzdG9yZSAhPT0gZmFsc2UgJiYgcHJldmlvdXNTZWxlY3Rpb24gJiYgIXNlbGVjdGlvbi5nZXQoKS5sZW5ndGgpIHtcbiAgICAgIHJlc3RvcmVTZWxlY3Rpb24ocHJldmlvdXNTZWxlY3Rpb24pO1xuICAgIH1cblxuICAgIHByZXZpb3VzQ29udGV4dCA9IGNvbnRleHQ7XG5cbiAgICBjb250ZXh0ID0gbnVsbDtcblxuICAgIHJldHVybiBwcmV2aW91c0NvbnRleHQ7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSBhIGRyYWcgb3BlcmF0aW9uLlxuICAgKlxuICAgKiBJZiBgbG9jYWxQb3NpdGlvbmAgaXMgZ2l2ZW4sIGRyYWcgZXZlbnRzIHdpbGwgYmUgZW1pdHRlZFxuICAgKiByZWxhdGl2ZSB0byBpdC5cbiAgICpcbiAgICogQHBhcmFtIHtNb3VzZUV2ZW50fFRvdWNoRXZlbnR9IFtldmVudF1cbiAgICogQHBhcmFtIHtQb2ludH0gW2xvY2FsUG9zaXRpb25dIGFjdHVhbCBkaWFncmFtIGxvY2FsIHBvc2l0aW9uIHRoaXMgZHJhZyBvcGVyYXRpb24gc2hvdWxkIHN0YXJ0IGF0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcmVmaXhcbiAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICAgKi9cbiAgZnVuY3Rpb24gaW5pdChldmVudCwgcmVsYXRpdmVUbywgcHJlZml4LCBvcHRpb25zKSB7XG5cbiAgICAvLyBvbmx5IG9uZSBkcmFnIG9wZXJhdGlvbiBtYXkgYmUgYWN0aXZlLCBhdCBhIHRpbWVcbiAgICBpZiAoY29udGV4dCkge1xuICAgICAgY2FuY2VsKGZhbHNlKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHJlbGF0aXZlVG8gPT09ICdzdHJpbmcnKSB7XG4gICAgICBvcHRpb25zID0gcHJlZml4O1xuICAgICAgcHJlZml4ID0gcmVsYXRpdmVUbztcbiAgICAgIHJlbGF0aXZlVG8gPSBudWxsO1xuICAgIH1cblxuICAgIG9wdGlvbnMgPSBhc3NpZ24oe30sIGRlZmF1bHRPcHRpb25zLCBvcHRpb25zIHx8IHt9KTtcblxuICAgIHZhciBkYXRhID0gb3B0aW9ucy5kYXRhIHx8IHt9LFxuICAgICAgICBvcmlnaW5hbEV2ZW50LFxuICAgICAgICBnbG9iYWxTdGFydCxcbiAgICAgICAgbG9jYWxTdGFydCxcbiAgICAgICAgZW5kRHJhZyxcbiAgICAgICAgaXNUb3VjaDtcblxuICAgIGlmIChvcHRpb25zLnRyYXBDbGljaykge1xuICAgICAgZW5kRHJhZyA9IHRyYXBDbGlja0FuZEVuZDtcbiAgICB9IGVsc2Uge1xuICAgICAgZW5kRHJhZyA9IGVuZDtcbiAgICB9XG5cbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIG9yaWdpbmFsRXZlbnQgPSBnZXRPcmlnaW5hbChldmVudCkgfHwgZXZlbnQ7XG4gICAgICBnbG9iYWxTdGFydCA9IHRvUG9pbnQoZXZlbnQpO1xuXG4gICAgICBzdG9wUHJvcGFnYXRpb24oZXZlbnQpO1xuXG4gICAgICAvLyBwcmV2ZW50IGRlZmF1bHQgYnJvd3NlciBkcmFnZ2luZyBiZWhhdmlvclxuICAgICAgaWYgKG9yaWdpbmFsRXZlbnQudHlwZSA9PT0gJ2RyYWdzdGFydCcpIHtcbiAgICAgICAgcHJldmVudERlZmF1bHQob3JpZ2luYWxFdmVudCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG9yaWdpbmFsRXZlbnQgPSBudWxsO1xuICAgICAgZ2xvYmFsU3RhcnQgPSB7IHg6IDAsIHk6IDAgfTtcbiAgICB9XG5cbiAgICBsb2NhbFN0YXJ0ID0gdG9Mb2NhbFBvaW50KGdsb2JhbFN0YXJ0KTtcblxuICAgIGlmICghcmVsYXRpdmVUbykge1xuICAgICAgcmVsYXRpdmVUbyA9IGxvY2FsU3RhcnQ7XG4gICAgfVxuXG4gICAgaXNUb3VjaCA9IGlzVG91Y2hFdmVudChvcmlnaW5hbEV2ZW50KTtcblxuICAgIGNvbnRleHQgPSBhc3NpZ24oe1xuICAgICAgcHJlZml4OiBwcmVmaXgsXG4gICAgICBkYXRhOiBkYXRhLFxuICAgICAgcGF5bG9hZDoge30sXG4gICAgICBnbG9iYWxTdGFydDogZ2xvYmFsU3RhcnQsXG4gICAgICBkaXNwbGFjZW1lbnQ6IGRlbHRhUG9zKHJlbGF0aXZlVG8sIGxvY2FsU3RhcnQpLFxuICAgICAgbG9jYWxTdGFydDogbG9jYWxTdGFydCxcbiAgICAgIGlzVG91Y2g6IGlzVG91Y2hcbiAgICB9LCBvcHRpb25zKTtcblxuICAgIC8vIHNraXAgZG9tIHJlZ2lzdHJhdGlvbiBpZiB0cmlnZ2VyXG4gICAgLy8gaXMgc2V0IHRvIG1hbnVhbCAoZHVyaW5nIHRlc3RpbmcpXG4gICAgaWYgKCFvcHRpb25zLm1hbnVhbCkge1xuXG4gICAgICAvLyBhZGQgZG9tIGxpc3RlbmVyc1xuXG4gICAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgICBkb21FdmVudC5iaW5kKGRvY3VtZW50LCAndG91Y2hzdGFydCcsIHRyYXBUb3VjaCwgdHJ1ZSk7XG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICd0b3VjaGNhbmNlbCcsIGNhbmNlbCwgdHJ1ZSk7XG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICd0b3VjaG1vdmUnLCBtb3ZlLCB0cnVlKTtcbiAgICAgICAgZG9tRXZlbnQuYmluZChkb2N1bWVudCwgJ3RvdWNoZW5kJywgZW5kLCB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gYXNzdW1lIHdlIHVzZSB0aGUgbW91c2UgdG8gaW50ZXJhY3QgcGVyIGRlZmF1bHRcbiAgICAgICAgZG9tRXZlbnQuYmluZChkb2N1bWVudCwgJ21vdXNlbW92ZScsIG1vdmUpO1xuXG4gICAgICAgIC8vIHByZXZlbnQgZGVmYXVsdCBicm93c2VyIGRyYWcgYW5kIHRleHQgc2VsZWN0aW9uIGJlaGF2aW9yXG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICdkcmFnc3RhcnQnLCBwcmV2ZW50RGVmYXVsdCk7XG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICdzZWxlY3RzdGFydCcsIHByZXZlbnREZWZhdWx0KTtcblxuICAgICAgICBkb21FdmVudC5iaW5kKGRvY3VtZW50LCAnbW91c2Vkb3duJywgZW5kRHJhZywgdHJ1ZSk7XG4gICAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICdtb3VzZXVwJywgZW5kRHJhZywgdHJ1ZSk7XG4gICAgICB9XG5cbiAgICAgIGRvbUV2ZW50LmJpbmQoZG9jdW1lbnQsICdrZXl1cCcsIGNoZWNrQ2FuY2VsKTtcblxuICAgICAgZXZlbnRCdXMub24oJ2VsZW1lbnQuaG92ZXInLCBob3Zlcik7XG4gICAgICBldmVudEJ1cy5vbignZWxlbWVudC5vdXQnLCBvdXQpO1xuICAgIH1cblxuICAgIGZpcmUoJ2luaXQnKTtcblxuICAgIGlmIChvcHRpb25zLmF1dG9BY3RpdmF0ZSkge1xuICAgICAgbW92ZShldmVudCwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gY2FuY2VsIG9uIGRpYWdyYW0gZGVzdHJ1Y3Rpb25cbiAgZXZlbnRCdXMub24oJ2RpYWdyYW0uZGVzdHJveScsIGNhbmNlbCk7XG5cblxuICAvLyBBUElcblxuICB0aGlzLmluaXQgPSBpbml0O1xuICB0aGlzLm1vdmUgPSBtb3ZlO1xuICB0aGlzLmhvdmVyID0gaG92ZXI7XG4gIHRoaXMub3V0ID0gb3V0O1xuICB0aGlzLmVuZCA9IGVuZDtcblxuICB0aGlzLmNhbmNlbCA9IGNhbmNlbDtcblxuICAvLyBmb3IgaW50cm9zcGVjdGlvblxuXG4gIHRoaXMuY29udGV4dCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBjb250ZXh0O1xuICB9O1xuXG4gIHRoaXMuc2V0T3B0aW9ucyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICBhc3NpZ24oZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpO1xuICB9O1xufVxuXG5EcmFnZ2luZy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3NlbGVjdGlvbicsXG4gICdlbGVtZW50UmVnaXN0cnknXG5dO1xuIiwiaW1wb3J0IHtcbiAgY2xvc2VzdCBhcyBkb21DbG9zZXN0XG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICB0b1BvaW50XG59IGZyb20gJy4uLy4uL3V0aWwvRXZlbnQnO1xuXG52YXIgSElHSF9QUklPUklUWSA9IDE1MDA7XG5cblxuLyoqXG4gKiBCcm93c2VycyBtYXkgc3dhbGxvdyBjZXJ0YWluIGV2ZW50cyAoaG92ZXIsIG91dCAuLi4pIGlmIHVzZXJzIGFyZSB0b1xuICogZmFzdCB3aXRoIHRoZSBtb3VzZS5cbiAqXG4gKiBAc2VlIGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNzQ0ODQ2OC93aHktY2FudC1pLXJlbGlhYmx5LWNhcHR1cmUtYS1tb3VzZW91dC1ldmVudFxuICpcbiAqIFRoZSBmaXggaW1wbGVtZW50ZWQgaW4gdGhpcyBjb21wb25lbnQgZW5zdXJlIHRoYXQgd2VcbiAqXG4gKiAxKSBoYXZlIGEgaG92ZXIgc3RhdGUgYWZ0ZXIgYSBzdWNjZXNzZnVsIGRyYWcubW92ZSBldmVudFxuICogMikgaGF2ZSBhbiBvdXQgZXZlbnQgd2hlbiBkcmFnZ2luZyBsZWF2ZXMgYW4gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0RyYWdnaW5nfSBkcmFnZ2luZ1xuICogQHBhcmFtIHtFbGVtZW50UmVnaXN0cnl9IGVsZW1lbnRSZWdpc3RyeVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBIb3ZlckZpeChldmVudEJ1cywgZHJhZ2dpbmcsIGVsZW1lbnRSZWdpc3RyeSkge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvKipcbiAgICogTWFrZSBzdXJlIHdlIGFyZSBnb2QgZGFtbiBob3ZlcmluZyFcbiAgICpcbiAgICogQHBhcmFtIHtFdmVudH0gZHJhZ2dpbmcgZXZlbnRcbiAgICovXG4gIGZ1bmN0aW9uIGVuc3VyZUhvdmVyKGV2ZW50KSB7XG5cbiAgICBpZiAoZXZlbnQuaG92ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgb3JpZ2luYWxFdmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG5cbiAgICB2YXIgZ2Z4ID0gc2VsZi5fZmluZFRhcmdldEdmeChvcmlnaW5hbEV2ZW50KTtcblxuICAgIHZhciBlbGVtZW50ID0gZ2Z4ICYmIGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcblxuICAgIGlmIChnZnggJiYgZWxlbWVudCkge1xuXG4gICAgICAvLyAxKSBjYW5jZWwgY3VycmVudCBtb3VzZW1vdmVcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuXG4gICAgICAvLyAyKSBlbWl0IGZha2UgaG92ZXIgZm9yIG5ldyB0YXJnZXRcbiAgICAgIGRyYWdnaW5nLmhvdmVyKHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG5cbiAgICAgIC8vIDMpIHJlLXRyaWdnZXIgbW92ZSBldmVudFxuICAgICAgZHJhZ2dpbmcubW92ZShvcmlnaW5hbEV2ZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV2Ugd2FpdCBmb3IgYSBzcGVjaWZpYyBzZXF1ZW5jZSBvZiBldmVudHMgYmVmb3JlXG4gICAqIGVtaXR0aW5nIGEgZmFrZSBkcmFnLmhvdmVyIGV2ZW50LlxuICAgKlxuICAgKiBFdmVudCBTZXF1ZW5jZTpcbiAgICpcbiAgICogZHJhZy5zdGFydFxuICAgKiBkcmFnLm1vdmUgPj4gZW5zdXJlIHdlIGFyZSBob3ZlcmluZ1xuICAgKi9cbiAgZXZlbnRCdXMub24oJ2RyYWcuc3RhcnQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgZXZlbnRCdXMub25jZSgnZHJhZy5tb3ZlJywgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgICAgZW5zdXJlSG92ZXIoZXZlbnQpO1xuXG4gICAgfSk7XG5cbiAgfSk7XG5cblxuICAvKipcbiAgICogV2UgbWFrZSBzdXJlIHRoYXQgZHJhZy5vdXQgaXMgYWx3YXlzIGZpcmVkLCBldmVuIGlmIHRoZVxuICAgKiBicm93c2VyIHN3YWxsb3dzIGFuIGVsZW1lbnQub3V0IGV2ZW50LlxuICAgKlxuICAgKiBFdmVudCBzZXF1ZW5jZTpcbiAgICpcbiAgICogZHJhZy5ob3ZlclxuICAgKiAoZWxlbWVudC5vdXQgPj4gc29tZXRpbWVzIHN3YWxsb3dlZClcbiAgICogZWxlbWVudC5ob3ZlciA+PiBlbnN1cmUgd2UgZmlyZWQgZHJhZy5vdXRcbiAgICovXG4gIGV2ZW50QnVzLm9uKCdkcmFnLmluaXQnLCBmdW5jdGlvbigpIHtcblxuICAgIHZhciBob3ZlciwgaG92ZXJHZng7XG5cbiAgICBmdW5jdGlvbiBzZXREcmFnSG92ZXIoZXZlbnQpIHtcbiAgICAgIGhvdmVyID0gZXZlbnQuaG92ZXI7XG4gICAgICBob3ZlckdmeCA9IGV2ZW50LmhvdmVyR2Z4O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHVuc2V0SG92ZXIoKSB7XG4gICAgICBob3ZlciA9IG51bGw7XG4gICAgICBob3ZlckdmeCA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZW5zdXJlT3V0KCkge1xuXG4gICAgICBpZiAoIWhvdmVyKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIGVsZW1lbnQgPSBob3ZlcixcbiAgICAgICAgICBnZnggPSBob3ZlckdmeDtcblxuICAgICAgaG92ZXIgPSBudWxsO1xuICAgICAgaG92ZXJHZnggPSBudWxsO1xuXG4gICAgICAvLyBlbWl0IHN5bnRoZXRpYyBvdXQgZXZlbnRcbiAgICAgIGRyYWdnaW5nLm91dCh7XG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICAgIGdmeDogZ2Z4XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBldmVudEJ1cy5vbignZHJhZy5ob3ZlcicsIHNldERyYWdIb3Zlcik7XG4gICAgZXZlbnRCdXMub24oJ2VsZW1lbnQub3V0JywgdW5zZXRIb3Zlcik7XG4gICAgZXZlbnRCdXMub24oJ2VsZW1lbnQuaG92ZXInLCBISUdIX1BSSU9SSVRZLCBlbnN1cmVPdXQpO1xuXG4gICAgZXZlbnRCdXMub25jZSgnZHJhZy5jbGVhbnVwJywgZnVuY3Rpb24oKSB7XG4gICAgICBldmVudEJ1cy5vZmYoJ2RyYWcuaG92ZXInLCBzZXREcmFnSG92ZXIpO1xuICAgICAgZXZlbnRCdXMub2ZmKCdlbGVtZW50Lm91dCcsIHVuc2V0SG92ZXIpO1xuICAgICAgZXZlbnRCdXMub2ZmKCdlbGVtZW50LmhvdmVyJywgZW5zdXJlT3V0KTtcbiAgICB9KTtcblxuICB9KTtcblxuICB0aGlzLl9maW5kVGFyZ2V0R2Z4ID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgcG9zaXRpb24sXG4gICAgICAgIHRhcmdldDtcblxuICAgIGlmICghKGV2ZW50IGluc3RhbmNlb2YgTW91c2VFdmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwb3NpdGlvbiA9IHRvUG9pbnQoZXZlbnQpO1xuXG4gICAgLy8gZGFtbiBleHBlbnNpdmUgb3BlcmF0aW9uLCBvdWNoIVxuICAgIHRhcmdldCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQocG9zaXRpb24ueCwgcG9zaXRpb24ueSk7XG5cbiAgICByZXR1cm4gZ2V0R2Z4KHRhcmdldCk7XG4gIH07XG5cbn1cblxuSG92ZXJGaXguJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2RyYWdnaW5nJyxcbiAgJ2VsZW1lbnRSZWdpc3RyeSdcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZ2V0R2Z4KHRhcmdldCkge1xuICByZXR1cm4gZG9tQ2xvc2VzdCh0YXJnZXQsICdzdmcsIC5kanMtZWxlbWVudCcsIHRydWUpO1xufSIsImltcG9ydCBTZWxlY3Rpb25Nb2R1bGUgZnJvbSAnLi4vc2VsZWN0aW9uJztcblxuaW1wb3J0IERyYWdnaW5nIGZyb20gJy4vRHJhZ2dpbmcnO1xuaW1wb3J0IEhvdmVyRml4IGZyb20gJy4vSG92ZXJGaXgnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbXG4gICAgJ2hvdmVyRml4J1xuICBdLFxuICBfX2RlcGVuZHNfXzogW1xuICAgIFNlbGVjdGlvbk1vZHVsZVxuICBdLFxuICBkcmFnZ2luZzogWyAndHlwZScsIERyYWdnaW5nIF0sXG4gIGhvdmVyRml4OiBbICd0eXBlJywgSG92ZXJGaXggXVxufTsiLCJpbXBvcnQge1xuICBmb3JFYWNoLFxuICBpc0FycmF5XG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIE5PVF9SRUdJU1RFUkVEX0VSUk9SID0gJ2lzIG5vdCBhIHJlZ2lzdGVyZWQgYWN0aW9uJyxcbiAgICBJU19SRUdJU1RFUkVEX0VSUk9SID0gJ2lzIGFscmVhZHkgcmVnaXN0ZXJlZCc7XG5cblxuLyoqXG4gKiBBbiBpbnRlcmZhY2UgdGhhdCBwcm92aWRlcyBhY2Nlc3MgdG8gbW9kZWxpbmcgYWN0aW9ucyBieSBkZWNvdXBsaW5nXG4gKiB0aGUgb25lIHdobyByZXF1ZXN0cyB0aGUgYWN0aW9uIHRvIGJlIHRyaWdnZXJlZCBhbmQgdGhlIHRyaWdnZXIgaXRzZWxmLlxuICpcbiAqIEl0J3MgcG9zc2libGUgdG8gYWRkIG5ldyBhY3Rpb25zIGJ5IHJlZ2lzdGVyaW5nIHRoZW0gd2l0aCDCtHJlZ2lzdGVyQWN0aW9uwrRcbiAqIGFuZCBsaWtld2lzZSB1bnJlZ2lzdGVyIGV4aXN0aW5nIG9uZXMgd2l0aCDCtHVucmVnaXN0ZXJBY3Rpb27CtC5cbiAqXG4gKlxuICogIyMgTGlmZS1DeWNsZSBhbmQgY29uZmlndXJhdGlvblxuICpcbiAqIFRoZSBlZGl0b3IgYWN0aW9ucyB3aWxsIHdhaXQgZm9yIGRpYWdyYW0gaW5pdGlhbGl6YXRpb24gYmVmb3JlXG4gKiByZWdpc3RlcmluZyBkZWZhdWx0IGFjdGlvbnMgX2FuZF8gZmlyaW5nIGFuIGBlZGl0b3JBY3Rpb25zLmluaXRgIGV2ZW50LlxuICpcbiAqIEludGVyZXN0ZWQgcGFydGllcyBtYXkgbGlzdGVuIHRvIHRoZSBgZWRpdG9yQWN0aW9ucy5pbml0YCBldmVudCB3aXRoXG4gKiBsb3cgcHJpb3JpdHkgdG8gY2hlY2ssIHdoaWNoIGFjdGlvbnMgZ290IHJlZ2lzdGVyZWQuIE90aGVyIGNvbXBvbmVudHNcbiAqIG1heSB1c2UgdGhlIGV2ZW50IHRvIHJlZ2lzdGVyIHRoZWlyIG93biBhY3Rpb25zIHZpYSBgcmVnaXN0ZXJBY3Rpb25gLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0luamVjdG9yfSBpbmplY3RvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBFZGl0b3JBY3Rpb25zKGV2ZW50QnVzLCBpbmplY3Rvcikge1xuXG4gIC8vIGluaXRpYWxpemUgYWN0aW9uc1xuICB0aGlzLl9hY3Rpb25zID0ge307XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGV2ZW50QnVzLm9uKCdkaWFncmFtLmluaXQnLCBmdW5jdGlvbigpIHtcblxuICAgIC8vIGFsbCBkaWFncmFtIG1vZHVsZXMgZ290IGxvYWRlZDsgY2hlY2sgd2hpY2ggb25lc1xuICAgIC8vIGFyZSBhdmFpbGFibGUgYW5kIHJlZ2lzdGVyIHRoZSByZXNwZWN0aXZlIGRlZmF1bHQgYWN0aW9uc1xuICAgIHNlbGYuX3JlZ2lzdGVyRGVmYXVsdEFjdGlvbnMoaW5qZWN0b3IpO1xuXG4gICAgLy8gYXNrIGludGVyZXN0ZWQgcGFydGllcyB0byByZWdpc3RlciBhdmFpbGFibGUgZWRpdG9yXG4gICAgLy8gYWN0aW9ucyBvbiBkaWFncmFtIGluaXRpYWxpemF0aW9uXG4gICAgZXZlbnRCdXMuZmlyZSgnZWRpdG9yQWN0aW9ucy5pbml0Jywge1xuICAgICAgZWRpdG9yQWN0aW9uczogc2VsZlxuICAgIH0pO1xuICB9KTtcblxufVxuXG5FZGl0b3JBY3Rpb25zLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdpbmplY3Rvcidcbl07XG5cbi8qKlxuICogUmVnaXN0ZXIgZGVmYXVsdCBhY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7SW5qZWN0b3J9IGluamVjdG9yXG4gKi9cbkVkaXRvckFjdGlvbnMucHJvdG90eXBlLl9yZWdpc3RlckRlZmF1bHRBY3Rpb25zID0gZnVuY3Rpb24oaW5qZWN0b3IpIHtcblxuICAvLyAoMSkgcmV0cmlldmUgb3B0aW9uYWwgY29tcG9uZW50cyB0byBpbnRlZ3JhdGUgd2l0aFxuXG4gIHZhciBjb21tYW5kU3RhY2sgPSBpbmplY3Rvci5nZXQoJ2NvbW1hbmRTdGFjaycsIGZhbHNlKTtcbiAgdmFyIG1vZGVsaW5nID0gaW5qZWN0b3IuZ2V0KCdtb2RlbGluZycsIGZhbHNlKTtcbiAgdmFyIHNlbGVjdGlvbiA9IGluamVjdG9yLmdldCgnc2VsZWN0aW9uJywgZmFsc2UpO1xuICB2YXIgem9vbVNjcm9sbCA9IGluamVjdG9yLmdldCgnem9vbVNjcm9sbCcsIGZhbHNlKTtcbiAgdmFyIGNvcHlQYXN0ZSA9IGluamVjdG9yLmdldCgnY29weVBhc3RlJywgZmFsc2UpO1xuICB2YXIgY2FudmFzID0gaW5qZWN0b3IuZ2V0KCdjYW52YXMnLCBmYWxzZSk7XG4gIHZhciBydWxlcyA9IGluamVjdG9yLmdldCgncnVsZXMnLCBmYWxzZSk7XG4gIHZhciBrZXlib2FyZE1vdmUgPSBpbmplY3Rvci5nZXQoJ2tleWJvYXJkTW92ZScsIGZhbHNlKTtcbiAgdmFyIGtleWJvYXJkTW92ZVNlbGVjdGlvbiA9IGluamVjdG9yLmdldCgna2V5Ym9hcmRNb3ZlU2VsZWN0aW9uJywgZmFsc2UpO1xuXG4gIC8vICgyKSBjaGVjayBjb21wb25lbnRzIGFuZCByZWdpc3RlciBhY3Rpb25zXG5cbiAgaWYgKGNvbW1hbmRTdGFjaykge1xuICAgIHRoaXMucmVnaXN0ZXIoJ3VuZG8nLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvbW1hbmRTdGFjay51bmRvKCk7XG4gICAgfSk7XG5cbiAgICB0aGlzLnJlZ2lzdGVyKCdyZWRvJywgZnVuY3Rpb24oKSB7XG4gICAgICBjb21tYW5kU3RhY2sucmVkbygpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGNvcHlQYXN0ZSAmJiBzZWxlY3Rpb24pIHtcbiAgICB0aGlzLnJlZ2lzdGVyKCdjb3B5JywgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgc2VsZWN0ZWRFbGVtZW50cyA9IHNlbGVjdGlvbi5nZXQoKTtcblxuICAgICAgY29weVBhc3RlLmNvcHkoc2VsZWN0ZWRFbGVtZW50cyk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoY29weVBhc3RlKSB7XG4gICAgdGhpcy5yZWdpc3RlcigncGFzdGUnLCBmdW5jdGlvbigpIHtcbiAgICAgIGNvcHlQYXN0ZS5wYXN0ZSgpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHpvb21TY3JvbGwpIHtcbiAgICB0aGlzLnJlZ2lzdGVyKCdzdGVwWm9vbScsIGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgIHpvb21TY3JvbGwuc3RlcFpvb20ob3B0cy52YWx1ZSk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoY2FudmFzKSB7XG4gICAgdGhpcy5yZWdpc3Rlcignem9vbScsIGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgIGNhbnZhcy56b29tKG9wdHMudmFsdWUpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKG1vZGVsaW5nICYmIHNlbGVjdGlvbiAmJiBydWxlcykge1xuICAgIHRoaXMucmVnaXN0ZXIoJ3JlbW92ZVNlbGVjdGlvbicsIGZ1bmN0aW9uKCkge1xuXG4gICAgICB2YXIgc2VsZWN0ZWRFbGVtZW50cyA9IHNlbGVjdGlvbi5nZXQoKTtcblxuICAgICAgaWYgKCFzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBhbGxvd2VkID0gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMuZGVsZXRlJywgeyBlbGVtZW50czogc2VsZWN0ZWRFbGVtZW50cyB9KSxcbiAgICAgICAgICByZW1vdmFibGVFbGVtZW50cztcblxuICAgICAgaWYgKGFsbG93ZWQgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGVsc2UgaWYgKGlzQXJyYXkoYWxsb3dlZCkpIHtcbiAgICAgICAgcmVtb3ZhYmxlRWxlbWVudHMgPSBhbGxvd2VkO1xuICAgICAgfVxuICAgICAgZWxzZSB7XG4gICAgICAgIHJlbW92YWJsZUVsZW1lbnRzID0gc2VsZWN0ZWRFbGVtZW50cztcbiAgICAgIH1cblxuICAgICAgaWYgKHJlbW92YWJsZUVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgICBtb2RlbGluZy5yZW1vdmVFbGVtZW50cyhyZW1vdmFibGVFbGVtZW50cy5zbGljZSgpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChrZXlib2FyZE1vdmUpIHtcbiAgICB0aGlzLnJlZ2lzdGVyKCdtb3ZlQ2FudmFzJywgZnVuY3Rpb24ob3B0cykge1xuICAgICAga2V5Ym9hcmRNb3ZlLm1vdmVDYW52YXMob3B0cyk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoa2V5Ym9hcmRNb3ZlU2VsZWN0aW9uKSB7XG4gICAgdGhpcy5yZWdpc3RlcignbW92ZVNlbGVjdGlvbicsIGZ1bmN0aW9uKG9wdHMpIHtcbiAgICAgIGtleWJvYXJkTW92ZVNlbGVjdGlvbi5tb3ZlU2VsZWN0aW9uKG9wdHMuZGlyZWN0aW9uLCBvcHRzLmFjY2VsZXJhdGVkKTtcbiAgICB9KTtcbiAgfVxuXG59O1xuXG5cbi8qKlxuICogVHJpZ2dlcnMgYSByZWdpc3RlcmVkIGFjdGlvblxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gYWN0aW9uXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdHNcbiAqXG4gKiBAcmV0dXJuIHtVbmtub3dufSBSZXR1cm5zIHdoYXQgdGhlIHJlZ2lzdGVyZWQgbGlzdGVuZXIgcmV0dXJuc1xuICovXG5FZGl0b3JBY3Rpb25zLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oYWN0aW9uLCBvcHRzKSB7XG4gIGlmICghdGhpcy5fYWN0aW9uc1thY3Rpb25dKSB7XG4gICAgdGhyb3cgZXJyb3IoYWN0aW9uLCBOT1RfUkVHSVNURVJFRF9FUlJPUik7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fYWN0aW9uc1thY3Rpb25dKG9wdHMpO1xufTtcblxuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGNvbGxlY3Rpb25zIG9mIGFjdGlvbnMuXG4gKiBUaGUga2V5IG9mIHRoZSBvYmplY3Qgd2lsbCBiZSB0aGUgbmFtZSBvZiB0aGUgYWN0aW9uLlxuICpcbiAqIEBleGFtcGxlXG4gKiDCtMK0wrRcbiAqIHZhciBhY3Rpb25zID0ge1xuICogICBzcGFjZVRvb2w6IGZ1bmN0aW9uKCkge1xuICogICAgIHNwYWNlVG9vbC5hY3RpdmF0ZVNlbGVjdGlvbigpO1xuICogICB9LFxuICogICBsYXNzb1Rvb2w6IGZ1bmN0aW9uKCkge1xuICogICAgIGxhc3NvVG9vbC5hY3RpdmF0ZVNlbGVjdGlvbigpO1xuICogICB9XG4gKiBdO1xuICpcbiAqIGVkaXRvckFjdGlvbnMucmVnaXN0ZXIoYWN0aW9ucyk7XG4gKlxuICogZWRpdG9yQWN0aW9ucy5pc1JlZ2lzdGVyZWQoJ3NwYWNlVG9vbCcpOyAvLyB0cnVlXG4gKiDCtMK0wrRcbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGFjdGlvbnNcbiAqL1xuRWRpdG9yQWN0aW9ucy5wcm90b3R5cGUucmVnaXN0ZXIgPSBmdW5jdGlvbihhY3Rpb25zLCBsaXN0ZW5lcikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHR5cGVvZiBhY3Rpb25zID09PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB0aGlzLl9yZWdpc3RlckFjdGlvbihhY3Rpb25zLCBsaXN0ZW5lcik7XG4gIH1cblxuICBmb3JFYWNoKGFjdGlvbnMsIGZ1bmN0aW9uKGxpc3RlbmVyLCBhY3Rpb24pIHtcbiAgICBzZWxmLl9yZWdpc3RlckFjdGlvbihhY3Rpb24sIGxpc3RlbmVyKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIFJlZ2lzdGVycyBhIGxpc3RlbmVyIHRvIGFuIGFjdGlvbiBrZXlcbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGFjdGlvblxuICogQHBhcmFtICB7RnVuY3Rpb259IGxpc3RlbmVyXG4gKi9cbkVkaXRvckFjdGlvbnMucHJvdG90eXBlLl9yZWdpc3RlckFjdGlvbiA9IGZ1bmN0aW9uKGFjdGlvbiwgbGlzdGVuZXIpIHtcbiAgaWYgKHRoaXMuaXNSZWdpc3RlcmVkKGFjdGlvbikpIHtcbiAgICB0aHJvdyBlcnJvcihhY3Rpb24sIElTX1JFR0lTVEVSRURfRVJST1IpO1xuICB9XG5cbiAgdGhpcy5fYWN0aW9uc1thY3Rpb25dID0gbGlzdGVuZXI7XG59O1xuXG4vKipcbiAqIFVucmVnaXN0ZXIgYW4gZXhpc3RpbmcgYWN0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvblxuICovXG5FZGl0b3JBY3Rpb25zLnByb3RvdHlwZS51bnJlZ2lzdGVyID0gZnVuY3Rpb24oYWN0aW9uKSB7XG4gIGlmICghdGhpcy5pc1JlZ2lzdGVyZWQoYWN0aW9uKSkge1xuICAgIHRocm93IGVycm9yKGFjdGlvbiwgTk9UX1JFR0lTVEVSRURfRVJST1IpO1xuICB9XG5cbiAgdGhpcy5fYWN0aW9uc1thY3Rpb25dID0gdW5kZWZpbmVkO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYWN0aW9ucyB0aGF0IGFyZSBjdXJyZW50bHkgcmVnaXN0ZXJlZFxuICpcbiAqIEByZXR1cm4ge251bWJlcn1cbiAqL1xuRWRpdG9yQWN0aW9ucy5wcm90b3R5cGUuZ2V0QWN0aW9ucyA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5fYWN0aW9ucyk7XG59O1xuXG4vKipcbiAqIENoZWNrcyB3ZXRoZXIgdGhlIGdpdmVuIGFjdGlvbiBpcyByZWdpc3RlcmVkXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvblxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59XG4gKi9cbkVkaXRvckFjdGlvbnMucHJvdG90eXBlLmlzUmVnaXN0ZXJlZCA9IGZ1bmN0aW9uKGFjdGlvbikge1xuICByZXR1cm4gISF0aGlzLl9hY3Rpb25zW2FjdGlvbl07XG59O1xuXG5cbmZ1bmN0aW9uIGVycm9yKGFjdGlvbiwgbWVzc2FnZSkge1xuICByZXR1cm4gbmV3IEVycm9yKGFjdGlvbiArICcgJyArIG1lc3NhZ2UpO1xufVxuIiwiaW1wb3J0IEVkaXRvckFjdGlvbnMgZnJvbSAnLi9FZGl0b3JBY3Rpb25zJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnZWRpdG9yQWN0aW9ucycgXSxcbiAgZWRpdG9yQWN0aW9uczogWyAndHlwZScsIEVkaXRvckFjdGlvbnMgXVxufTtcbiIsInZhciBNQVJLRVJfT0sgPSAnY29ubmVjdC1vaycsXG4gICAgTUFSS0VSX05PVF9PSyA9ICdjb25uZWN0LW5vdC1vayc7XG5cbi8qKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtEcmFnZ2luZ30gZHJhZ2dpbmdcbiAqIEBwYXJhbSB7Q29ubmVjdH0gY29ubmVjdFxuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICogQHBhcmFtIHtUb29sTWFuYWdlcn0gdG9vbE1hbmFnZXJcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEdsb2JhbENvbm5lY3QoXG4gICAgZXZlbnRCdXMsIGRyYWdnaW5nLCBjb25uZWN0LFxuICAgIGNhbnZhcywgdG9vbE1hbmFnZXIsIHJ1bGVzKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRoaXMuX2RyYWdnaW5nID0gZHJhZ2dpbmc7XG4gIHRoaXMuX3J1bGVzID0gcnVsZXM7XG5cbiAgdG9vbE1hbmFnZXIucmVnaXN0ZXJUb29sKCdnbG9iYWwtY29ubmVjdCcsIHtcbiAgICB0b29sOiAnZ2xvYmFsLWNvbm5lY3QnLFxuICAgIGRyYWdnaW5nOiAnZ2xvYmFsLWNvbm5lY3QuZHJhZydcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2dsb2JhbC1jb25uZWN0LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHN0YXJ0VGFyZ2V0ID0gZXZlbnQuaG92ZXI7XG5cbiAgICB2YXIgY2FuU3RhcnRDb25uZWN0ID0gY29udGV4dC5jYW5TdGFydENvbm5lY3QgPSBzZWxmLmNhblN0YXJ0Q29ubmVjdChzdGFydFRhcmdldCk7XG5cbiAgICAvLyBzaW1wbHkgaWdub3JlIGhvdmVyXG4gICAgaWYgKGNhblN0YXJ0Q29ubmVjdCA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnRleHQuc3RhcnRUYXJnZXQgPSBzdGFydFRhcmdldDtcblxuICAgIGNhbnZhcy5hZGRNYXJrZXIoc3RhcnRUYXJnZXQsIGNhblN0YXJ0Q29ubmVjdCA/IE1BUktFUl9PSyA6IE1BUktFUl9OT1RfT0spO1xuICB9KTtcblxuXG4gIGV2ZW50QnVzLm9uKFsgJ2dsb2JhbC1jb25uZWN0Lm91dCcsICdnbG9iYWwtY29ubmVjdC5jbGVhbnVwJyBdLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBzdGFydFRhcmdldCA9IGV2ZW50LmNvbnRleHQuc3RhcnRUYXJnZXQsXG4gICAgICAgIGNhblN0YXJ0Q29ubmVjdCA9IGV2ZW50LmNvbnRleHQuY2FuU3RhcnRDb25uZWN0O1xuXG4gICAgaWYgKHN0YXJ0VGFyZ2V0KSB7XG4gICAgICBjYW52YXMucmVtb3ZlTWFya2VyKHN0YXJ0VGFyZ2V0LCBjYW5TdGFydENvbm5lY3QgPyBNQVJLRVJfT0sgOiBNQVJLRVJfTk9UX09LKTtcbiAgICB9XG4gIH0pO1xuXG5cbiAgZXZlbnRCdXMub24oWyAnZ2xvYmFsLWNvbm5lY3QuZW5kZWQnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBzdGFydFRhcmdldCA9IGNvbnRleHQuc3RhcnRUYXJnZXQsXG4gICAgICAgIHN0YXJ0UG9zaXRpb24gPSB7XG4gICAgICAgICAgeDogZXZlbnQueCxcbiAgICAgICAgICB5OiBldmVudC55XG4gICAgICAgIH07XG5cbiAgICB2YXIgY2FuU3RhcnRDb25uZWN0ID0gc2VsZi5jYW5TdGFydENvbm5lY3Qoc3RhcnRUYXJnZXQpO1xuXG4gICAgaWYgKCFjYW5TdGFydENvbm5lY3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBldmVudEJ1cy5vbmNlKCdlbGVtZW50Lm91dCcsIGZ1bmN0aW9uKCkge1xuICAgICAgZXZlbnRCdXMub25jZShbICdjb25uZWN0LmVuZGVkJywgJ2Nvbm5lY3QuY2FuY2VsZWQnIF0sIGZ1bmN0aW9uKCkge1xuICAgICAgICBldmVudEJ1cy5maXJlKCdnbG9iYWwtY29ubmVjdC5kcmFnLmVuZGVkJyk7XG4gICAgICB9KTtcblxuICAgICAgY29ubmVjdC5zdGFydChudWxsLCBzdGFydFRhcmdldCwgc3RhcnRQb3NpdGlvbik7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pO1xufVxuXG5HbG9iYWxDb25uZWN0LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdkcmFnZ2luZycsXG4gICdjb25uZWN0JyxcbiAgJ2NhbnZhcycsXG4gICd0b29sTWFuYWdlcicsXG4gICdydWxlcydcbl07XG5cbi8qKlxuICogSW5pdGlhdGVzIHRvb2wgYWN0aXZpdHkuXG4gKi9cbkdsb2JhbENvbm5lY3QucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgdGhpcy5fZHJhZ2dpbmcuaW5pdChldmVudCwgJ2dsb2JhbC1jb25uZWN0Jywge1xuICAgIHRyYXBDbGljazogZmFsc2UsXG4gICAgZGF0YToge1xuICAgICAgY29udGV4dDoge31cbiAgICB9XG4gIH0pO1xufTtcblxuR2xvYmFsQ29ubmVjdC5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24oKSB7XG4gIGlmICh0aGlzLmlzQWN0aXZlKCkpIHtcbiAgICB0aGlzLl9kcmFnZ2luZy5jYW5jZWwoKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnN0YXJ0KCk7XG4gIH1cbn07XG5cbkdsb2JhbENvbm5lY3QucHJvdG90eXBlLmlzQWN0aXZlID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjb250ZXh0ID0gdGhpcy5fZHJhZ2dpbmcuY29udGV4dCgpO1xuXG4gIHJldHVybiBjb250ZXh0ICYmIC9eZ2xvYmFsLWNvbm5lY3QvLnRlc3QoY29udGV4dC5wcmVmaXgpO1xufTtcblxuLyoqXG4gKiBDaGVjayBpZiBzb3VyY2Ugc2hhcGUgY2FuIGluaXRpYXRlIGNvbm5lY3Rpb24uXG4gKlxuICogQHBhcmFtICB7U2hhcGV9IHN0YXJ0VGFyZ2V0XG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5HbG9iYWxDb25uZWN0LnByb3RvdHlwZS5jYW5TdGFydENvbm5lY3QgPSBmdW5jdGlvbihzdGFydFRhcmdldCkge1xuICByZXR1cm4gdGhpcy5fcnVsZXMuYWxsb3dlZCgnY29ubmVjdGlvbi5zdGFydCcsIHsgc291cmNlOiBzdGFydFRhcmdldCB9KTtcbn07XG4iLCJpbXBvcnQgQ29ubmVjdE1vZHVsZSBmcm9tICcuLi9jb25uZWN0JztcbmltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuaW1wb3J0IFRvb2xNYW5hZ2VyTW9kdWxlIGZyb20gJy4uL3Rvb2wtbWFuYWdlcic7XG5cbmltcG9ydCBHbG9iYWxDb25uZWN0IGZyb20gJy4vR2xvYmFsQ29ubmVjdCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBDb25uZWN0TW9kdWxlLFxuICAgIFJ1bGVzTW9kdWxlLFxuICAgIERyYWdnaW5nTW9kdWxlLFxuICAgIFRvb2xNYW5hZ2VyTW9kdWxlXG4gIF0sXG4gIGdsb2JhbENvbm5lY3Q6IFsgJ3R5cGUnLCBHbG9iYWxDb25uZWN0IF1cbn07XG4iLCJpbXBvcnQge1xyXG4gIHNldFNuYXBwZWQsXHJcbiAgaXNTbmFwcGVkXHJcbn0gZnJvbSAnLi4vc25hcHBpbmcvU25hcFV0aWwnO1xyXG5cclxuaW1wb3J0IHsgaXNDbWQgfSBmcm9tICcuLi9rZXlib2FyZC9LZXlib2FyZFV0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBhc3NpZ24sXHJcbiAgaXNOdW1iZXJcclxufSBmcm9tICdtaW4tZGFzaCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIFNQQUNJTkcsXHJcbiAgcXVhbnRpemVcclxufSBmcm9tICcuL0dyaWRVdGlsJztcclxuXHJcbnZhciBMT1dFUl9QUklPUklUWSA9IDEyMDA7XHJcbnZhciBMT1dfUFJJT1JJVFkgPSA4MDA7XHJcblxyXG4vKipcclxuICogQmFzaWMgZ3JpZCBzbmFwcGluZyB0aGF0IGNvdmVycyBjb25uZWN0aW5nLCBjcmVhdGluZywgbW92aW5nLCByZXNpemluZyBzaGFwZXMsIG1vdmluZyBiZW5kcG9pbnRzXHJcbiAqIGFuZCBjb25uZWN0aW9uIHNlZ21lbnRzLlxyXG4gKi9cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gR3JpZFNuYXBwaW5nKGVsZW1lbnRSZWdpc3RyeSwgZXZlbnRCdXMsIGNvbmZpZykge1xyXG5cclxuICB2YXIgYWN0aXZlID0gIWNvbmZpZyB8fCBjb25maWcuYWN0aXZlICE9PSBmYWxzZTtcclxuXHJcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcclxuXHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5pbml0JywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbigpIHtcclxuICAgIHNlbGYuc2V0QWN0aXZlKGFjdGl2ZSk7XHJcbiAgfSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKFtcclxuICAgICdjcmVhdGUubW92ZScsXHJcbiAgICAnY3JlYXRlLmVuZCcsXHJcbiAgICAnYmVuZHBvaW50Lm1vdmUubW92ZScsXHJcbiAgICAnYmVuZHBvaW50Lm1vdmUuZW5kJyxcclxuICAgICdjb25uZWN0Lm1vdmUnLFxyXG4gICAgJ2Nvbm5lY3QuZW5kJyxcclxuICAgICdjb25uZWN0aW9uU2VnbWVudC5tb3ZlLm1vdmUnLFxyXG4gICAgJ2Nvbm5lY3Rpb25TZWdtZW50Lm1vdmUuZW5kJyxcclxuICAgICdyZXNpemUubW92ZScsXHJcbiAgICAncmVzaXplLmVuZCcsXHJcbiAgICAnc2hhcGUubW92ZS5tb3ZlJyxcclxuICAgICdzaGFwZS5tb3ZlLmVuZCdcclxuICBdLCBMT1dFUl9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBvcmlnaW5hbEV2ZW50ID0gZXZlbnQub3JpZ2luYWxFdmVudDtcclxuXHJcbiAgICBpZiAoIXNlbGYuYWN0aXZlIHx8IChvcmlnaW5hbEV2ZW50ICYmIGlzQ21kKG9yaWdpbmFsRXZlbnQpKSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIGdyaWRTbmFwcGluZ0NvbnRleHQgPSBjb250ZXh0LmdyaWRTbmFwcGluZ0NvbnRleHQ7XHJcblxyXG4gICAgaWYgKCFncmlkU25hcHBpbmdDb250ZXh0KSB7XHJcbiAgICAgIGdyaWRTbmFwcGluZ0NvbnRleHQgPSBjb250ZXh0LmdyaWRTbmFwcGluZ0NvbnRleHQgPSB7fTtcclxuICAgIH1cclxuXHJcbiAgICBbICd4JywgJ3knIF0uZm9yRWFjaChmdW5jdGlvbihheGlzKSB7XHJcbiAgICAgIHZhciBvcHRpb25zID0ge307XHJcblxyXG4gICAgICAvLyBhbGxvdyBzbmFwcGluZyB3aXRoIG9mZnNldFxyXG4gICAgICB2YXIgc25hcE9mZnNldCA9IGdldFNuYXBPZmZzZXQoZXZlbnQsIGF4aXMsIGVsZW1lbnRSZWdpc3RyeSk7XHJcblxyXG4gICAgICBpZiAoc25hcE9mZnNldCkge1xyXG4gICAgICAgIG9wdGlvbnMub2Zmc2V0ID0gc25hcE9mZnNldDtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gYWxsb3cgc25hcHBpbmcgd2l0aCBtaW4gYW5kIG1heFxyXG4gICAgICB2YXIgc25hcENvbnN0cmFpbnRzID0gZ2V0U25hcENvbnN0cmFpbnRzKGV2ZW50LCBheGlzKTtcclxuXHJcbiAgICAgIGlmIChzbmFwQ29uc3RyYWludHMpIHtcclxuICAgICAgICBhc3NpZ24ob3B0aW9ucywgc25hcENvbnN0cmFpbnRzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFpc1NuYXBwZWQoZXZlbnQsIGF4aXMpKSB7XHJcbiAgICAgICAgc2VsZi5zbmFwRXZlbnQoZXZlbnQsIGF4aXMsIG9wdGlvbnMpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFNuYXAgYW4gZXZlbnRzIHggb3IgeSB3aXRoIG9wdGlvbmFsIG1pbiwgbWF4IGFuZCBvZmZzZXQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gYXhpc1xyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWluXVxyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4XVxyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMub2Zmc2V0XVxyXG4gKi9cclxuR3JpZFNuYXBwaW5nLnByb3RvdHlwZS5zbmFwRXZlbnQgPSBmdW5jdGlvbihldmVudCwgYXhpcywgb3B0aW9ucykge1xyXG4gIHZhciBzbmFwcGVkVmFsdWUgPSB0aGlzLnNuYXBWYWx1ZShldmVudFsgYXhpcyBdLCBvcHRpb25zKTtcclxuXHJcbiAgc2V0U25hcHBlZChldmVudCwgYXhpcywgc25hcHBlZFZhbHVlKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBFeHBvc2UgZ3JpZCBzcGFjaW5nIGZvciB0aGlyZCBwYXJ0aWVzIChpLmUuIGV4dGVuc2lvbnMpLlxyXG4gKlxyXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHNwYWNpbmcgb2YgZ3JpZCBkb3RzXHJcbiAqL1xyXG5HcmlkU25hcHBpbmcucHJvdG90eXBlLmdldEdyaWRTcGFjaW5nID0gZnVuY3Rpb24oKSB7XHJcbiAgcmV0dXJuIFNQQUNJTkc7XHJcbn07XHJcblxyXG4vKipcclxuICogU25hcCB2YWx1ZSB3aXRoIG9wdGlvbmFsIG1pbiwgbWF4IGFuZCBvZmZzZXQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWluXVxyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4XVxyXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMub2Zmc2V0XVxyXG4gKi9cclxuR3JpZFNuYXBwaW5nLnByb3RvdHlwZS5zbmFwVmFsdWUgPSBmdW5jdGlvbih2YWx1ZSwgb3B0aW9ucykge1xyXG4gIHZhciBvZmZzZXQgPSAwO1xyXG5cclxuICBpZiAob3B0aW9ucyAmJiBvcHRpb25zLm9mZnNldCkge1xyXG4gICAgb2Zmc2V0ID0gb3B0aW9ucy5vZmZzZXQ7XHJcbiAgfVxyXG5cclxuICB2YWx1ZSArPSBvZmZzZXQ7XHJcblxyXG4gIHZhbHVlID0gcXVhbnRpemUodmFsdWUsIFNQQUNJTkcpO1xyXG5cclxuICB2YXIgbWluLCBtYXg7XHJcblxyXG4gIGlmIChvcHRpb25zICYmIG9wdGlvbnMubWluKSB7XHJcbiAgICBtaW4gPSBvcHRpb25zLm1pbjtcclxuXHJcbiAgICBpZiAoaXNOdW1iZXIobWluKSkge1xyXG4gICAgICBtaW4gPSBxdWFudGl6ZShtaW4gKyBvZmZzZXQsIFNQQUNJTkcsICdjZWlsJyk7XHJcblxyXG4gICAgICB2YWx1ZSA9IE1hdGgubWF4KHZhbHVlLCBtaW4pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKG9wdGlvbnMgJiYgb3B0aW9ucy5tYXgpIHtcclxuICAgIG1heCA9IG9wdGlvbnMubWF4O1xyXG5cclxuICAgIGlmIChpc051bWJlcihtYXgpKSB7XHJcbiAgICAgIG1heCA9IHF1YW50aXplKG1heCArIG9mZnNldCwgU1BBQ0lORywgJ2Zsb29yJyk7XHJcblxyXG4gICAgICB2YWx1ZSA9IE1hdGgubWluKHZhbHVlLCBtYXgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdmFsdWUgLT0gb2Zmc2V0O1xyXG5cclxuICByZXR1cm4gdmFsdWU7XHJcbn07XHJcblxyXG5HcmlkU25hcHBpbmcucHJvdG90eXBlLmlzQWN0aXZlID0gZnVuY3Rpb24oKSB7XHJcbiAgcmV0dXJuIHRoaXMuYWN0aXZlO1xyXG59O1xyXG5cclxuR3JpZFNuYXBwaW5nLnByb3RvdHlwZS5zZXRBY3RpdmUgPSBmdW5jdGlvbihhY3RpdmUpIHtcclxuICB0aGlzLmFjdGl2ZSA9IGFjdGl2ZTtcclxuXHJcbiAgdGhpcy5fZXZlbnRCdXMuZmlyZSgnZ3JpZFNuYXBwaW5nLnRvZ2dsZScsIHsgYWN0aXZlOiBhY3RpdmUgfSk7XHJcbn07XHJcblxyXG5HcmlkU25hcHBpbmcucHJvdG90eXBlLnRvZ2dsZUFjdGl2ZSA9IGZ1bmN0aW9uKCkge1xyXG4gIHRoaXMuc2V0QWN0aXZlKCF0aGlzLmFjdGl2ZSk7XHJcbn07XHJcblxyXG5HcmlkU25hcHBpbmcuJGluamVjdCA9IFtcclxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcclxuICAnZXZlbnRCdXMnLFxyXG4gICdjb25maWcuZ3JpZFNuYXBwaW5nJ1xyXG5dO1xyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG4vKipcclxuICogR2V0IG1pbmltdW0gYW5kIG1heGltdW0gc25hcCBjb25zdHJhaW50cy5cclxuICogQ29uc3RyYWludHMgYXJlIGNhY2hlZC5cclxuICpcclxuICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBldmVudC5jb250ZXh0XHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtib29sZWFufE9iamVjdH1cclxuICovXHJcbmZ1bmN0aW9uIGdldFNuYXBDb25zdHJhaW50cyhldmVudCwgYXhpcykge1xyXG4gIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgY3JlYXRlQ29uc3RyYWludHMgPSBjb250ZXh0LmNyZWF0ZUNvbnN0cmFpbnRzLFxyXG4gICAgICByZXNpemVDb25zdHJhaW50cyA9IGNvbnRleHQucmVzaXplQ29uc3RyYWludHMgfHwge30sXHJcbiAgICAgIGdyaWRTbmFwcGluZ0NvbnRleHQgPSBjb250ZXh0LmdyaWRTbmFwcGluZ0NvbnRleHQsXHJcbiAgICAgIHNuYXBDb25zdHJhaW50cyA9IGdyaWRTbmFwcGluZ0NvbnRleHQuc25hcENvbnN0cmFpbnRzO1xyXG5cclxuICAvLyBjYWNoZSBzbmFwIGNvbnN0cmFpbnRzXHJcbiAgaWYgKHNuYXBDb25zdHJhaW50cyAmJiBzbmFwQ29uc3RyYWludHNbIGF4aXMgXSkge1xyXG4gICAgcmV0dXJuIHNuYXBDb25zdHJhaW50c1sgYXhpcyBdO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFzbmFwQ29uc3RyYWludHMpIHtcclxuICAgIHNuYXBDb25zdHJhaW50cyA9IGdyaWRTbmFwcGluZ0NvbnRleHQuc25hcENvbnN0cmFpbnRzID0ge307XHJcbiAgfVxyXG5cclxuICBpZiAoIXNuYXBDb25zdHJhaW50c1sgYXhpcyBdKSB7XHJcbiAgICBzbmFwQ29uc3RyYWludHNbIGF4aXMgXSA9IHt9O1xyXG4gIH1cclxuXHJcbiAgdmFyIGRpcmVjdGlvbiA9IGNvbnRleHQuZGlyZWN0aW9uO1xyXG5cclxuICAvLyBjcmVhdGVcclxuICBpZiAoY3JlYXRlQ29uc3RyYWludHMpIHtcclxuICAgIGlmIChpc0hvcml6b250YWwoYXhpcykpIHtcclxuICAgICAgc25hcENvbnN0cmFpbnRzLngubWluID0gY3JlYXRlQ29uc3RyYWludHMubGVmdDtcclxuICAgICAgc25hcENvbnN0cmFpbnRzLngubWF4ID0gY3JlYXRlQ29uc3RyYWludHMucmlnaHQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzbmFwQ29uc3RyYWludHMueS5taW4gPSBjcmVhdGVDb25zdHJhaW50cy50b3A7XHJcbiAgICAgIHNuYXBDb25zdHJhaW50cy55Lm1heCA9IGNyZWF0ZUNvbnN0cmFpbnRzLmJvdHRvbTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIHJlc2l6ZVxyXG4gIHZhciBtaW5SZXNpemVDb25zdHJhaW50cyA9IHJlc2l6ZUNvbnN0cmFpbnRzLm1pbixcclxuICAgICAgbWF4UmVzaXplQ29uc3RyYWludHMgPSByZXNpemVDb25zdHJhaW50cy5tYXg7XHJcblxyXG4gIGlmIChtaW5SZXNpemVDb25zdHJhaW50cykge1xyXG4gICAgaWYgKGlzSG9yaXpvbnRhbChheGlzKSkge1xyXG5cclxuICAgICAgaWYgKGlzV2VzdChkaXJlY3Rpb24pKSB7XHJcbiAgICAgICAgc25hcENvbnN0cmFpbnRzLngubWF4ID0gbWluUmVzaXplQ29uc3RyYWludHMubGVmdDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzbmFwQ29uc3RyYWludHMueC5taW4gPSBtaW5SZXNpemVDb25zdHJhaW50cy5yaWdodDtcclxuICAgICAgfVxyXG5cclxuICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICBpZiAoaXNOb3J0aChkaXJlY3Rpb24pKSB7XHJcbiAgICAgICAgc25hcENvbnN0cmFpbnRzLnkubWF4ID0gbWluUmVzaXplQ29uc3RyYWludHMudG9wO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNuYXBDb25zdHJhaW50cy55Lm1pbiA9IG1pblJlc2l6ZUNvbnN0cmFpbnRzLmJvdHRvbTtcclxuICAgICAgfVxyXG5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChtYXhSZXNpemVDb25zdHJhaW50cykge1xyXG4gICAgaWYgKGlzSG9yaXpvbnRhbChheGlzKSkge1xyXG5cclxuICAgICAgaWYgKGlzV2VzdChkaXJlY3Rpb24pKSB7XHJcbiAgICAgICAgc25hcENvbnN0cmFpbnRzLngubWluID0gbWF4UmVzaXplQ29uc3RyYWludHMubGVmdDtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzbmFwQ29uc3RyYWludHMueC5tYXggPSBtYXhSZXNpemVDb25zdHJhaW50cy5yaWdodDtcclxuICAgICAgfVxyXG5cclxuICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICBpZiAoaXNOb3J0aChkaXJlY3Rpb24pKSB7XHJcbiAgICAgICAgc25hcENvbnN0cmFpbnRzLnkubWluID0gbWF4UmVzaXplQ29uc3RyYWludHMudG9wO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNuYXBDb25zdHJhaW50cy55Lm1heCA9IG1heFJlc2l6ZUNvbnN0cmFpbnRzLmJvdHRvbTtcclxuICAgICAgfVxyXG5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBzbmFwQ29uc3RyYWludHNbIGF4aXMgXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBzbmFwIG9mZnNldC5cclxuICogT2Zmc2V0IGlzIGNhY2hlZC5cclxuICpcclxuICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzXHJcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcclxuICpcclxuICogQHJldHVybnMge251bWJlcn1cclxuICovXHJcbmZ1bmN0aW9uIGdldFNuYXBPZmZzZXQoZXZlbnQsIGF4aXMsIGVsZW1lbnRSZWdpc3RyeSkge1xyXG4gIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcclxuICAgICAgc2hhcGUgPSBldmVudC5zaGFwZSxcclxuICAgICAgZ3JpZFNuYXBwaW5nQ29udGV4dCA9IGNvbnRleHQuZ3JpZFNuYXBwaW5nQ29udGV4dCxcclxuICAgICAgc25hcExvY2F0aW9uID0gZ3JpZFNuYXBwaW5nQ29udGV4dC5zbmFwTG9jYXRpb24sXHJcbiAgICAgIHNuYXBPZmZzZXQgPSBncmlkU25hcHBpbmdDb250ZXh0LnNuYXBPZmZzZXQ7XHJcblxyXG4gIC8vIGNhY2hlIHNuYXAgb2Zmc2V0XHJcbiAgaWYgKHNuYXBPZmZzZXQgJiYgaXNOdW1iZXIoc25hcE9mZnNldFsgYXhpcyBdKSkge1xyXG4gICAgcmV0dXJuIHNuYXBPZmZzZXRbIGF4aXMgXTtcclxuICB9XHJcblxyXG4gIGlmICghc25hcE9mZnNldCkge1xyXG4gICAgc25hcE9mZnNldCA9IGdyaWRTbmFwcGluZ0NvbnRleHQuc25hcE9mZnNldCA9IHt9O1xyXG4gIH1cclxuXHJcbiAgaWYgKCFpc051bWJlcihzbmFwT2Zmc2V0WyBheGlzIF0pKSB7XHJcbiAgICBzbmFwT2Zmc2V0WyBheGlzIF0gPSAwO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFzaGFwZSkge1xyXG4gICAgcmV0dXJuIHNuYXBPZmZzZXRbIGF4aXMgXTtcclxuICB9XHJcblxyXG4gIGlmICghZWxlbWVudFJlZ2lzdHJ5LmdldChzaGFwZS5pZCkpIHtcclxuXHJcbiAgICBpZiAoaXNIb3Jpem9udGFsKGF4aXMpKSB7XHJcbiAgICAgIHNuYXBPZmZzZXRbIGF4aXMgXSArPSBzaGFwZVsgYXhpcyBdICsgc2hhcGUud2lkdGggLyAyO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc25hcE9mZnNldFsgYXhpcyBdICs9IHNoYXBlWyBheGlzIF0gKyBzaGFwZS5oZWlnaHQgLyAyO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKCFzbmFwTG9jYXRpb24pIHtcclxuICAgIHJldHVybiBzbmFwT2Zmc2V0WyBheGlzIF07XHJcbiAgfVxyXG5cclxuICBpZiAoYXhpcyA9PT0gJ3gnKSB7XHJcbiAgICBpZiAoL2xlZnQvLnRlc3Qoc25hcExvY2F0aW9uKSkge1xyXG4gICAgICBzbmFwT2Zmc2V0WyBheGlzIF0gLT0gc2hhcGUud2lkdGggLyAyO1xyXG4gICAgfSBlbHNlIGlmICgvcmlnaHQvLnRlc3Qoc25hcExvY2F0aW9uKSkge1xyXG4gICAgICBzbmFwT2Zmc2V0WyBheGlzIF0gKz0gc2hhcGUud2lkdGggLyAyO1xyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICBpZiAoL3RvcC8udGVzdChzbmFwTG9jYXRpb24pKSB7XHJcbiAgICAgIHNuYXBPZmZzZXRbIGF4aXMgXSAtPSBzaGFwZS5oZWlnaHQgLyAyO1xyXG4gICAgfSBlbHNlIGlmICgvYm90dG9tLy50ZXN0KHNuYXBMb2NhdGlvbikpIHtcclxuICAgICAgc25hcE9mZnNldFsgYXhpcyBdICs9IHNoYXBlLmhlaWdodCAvIDI7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gc25hcE9mZnNldFsgYXhpcyBdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0hvcml6b250YWwoYXhpcykge1xyXG4gIHJldHVybiBheGlzID09PSAneCc7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTm9ydGgoZGlyZWN0aW9uKSB7XHJcbiAgcmV0dXJuIGRpcmVjdGlvbi5pbmRleE9mKCduJykgIT09IC0xO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc1dlc3QoZGlyZWN0aW9uKSB7XHJcbiAgcmV0dXJuIGRpcmVjdGlvbi5pbmRleE9mKCd3JykgIT09IC0xO1xyXG59IiwiZXhwb3J0IHZhciBTUEFDSU5HID0gMTA7XG5cbmV4cG9ydCBmdW5jdGlvbiBxdWFudGl6ZSh2YWx1ZSwgcXVhbnR1bSwgZm4pIHtcbiAgaWYgKCFmbikge1xuICAgIGZuID0gJ3JvdW5kJztcbiAgfVxuXG4gIHJldHVybiBNYXRoWyBmbiBdKHZhbHVlIC8gcXVhbnR1bSkgKiBxdWFudHVtO1xufSIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XHJcblxyXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJy4uLy4uLy4uL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcclxuXHJcbmltcG9ydCB7XHJcbiAgYXNzaWduLFxyXG4gIGlzU3RyaW5nXHJcbn0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBJbnRlZ3JhdGVzIHJlc2l6aW5nIHdpdGggZ3JpZCBzbmFwcGluZy5cclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlc2l6ZUJlaGF2aW9yKGV2ZW50QnVzLCBncmlkU25hcHBpbmcpIHtcclxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XHJcblxyXG4gIHRoaXMuX2dyaWRTbmFwcGluZyA9IGdyaWRTbmFwcGluZztcclxuXHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICB0aGlzLnByZUV4ZWN1dGUoJ3NoYXBlLnJlc2l6ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxyXG4gICAgICAgIGF1dG9SZXNpemUgPSBoaW50cy5hdXRvUmVzaXplO1xyXG5cclxuICAgIGlmICghYXV0b1Jlc2l6ZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcclxuICAgICAgICBuZXdCb3VuZHMgPSBjb250ZXh0Lm5ld0JvdW5kcztcclxuXHJcbiAgICBpZiAoaXNTdHJpbmcoYXV0b1Jlc2l6ZSkpIHtcclxuICAgICAgY29udGV4dC5uZXdCb3VuZHMgPSBzZWxmLnNuYXBDb21wbGV4KG5ld0JvdW5kcywgYXV0b1Jlc2l6ZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0Lm5ld0JvdW5kcyA9IHNlbGYuc25hcFNpbXBsZShzaGFwZSwgbmV3Qm91bmRzKTtcclxuICAgIH1cclxuICB9KTtcclxufVxyXG5cclxuUmVzaXplQmVoYXZpb3IuJGluamVjdCA9IFtcclxuICAnZXZlbnRCdXMnLFxyXG4gICdncmlkU25hcHBpbmcnLFxyXG4gICdtb2RlbGluZydcclxuXTtcclxuXHJcbmluaGVyaXRzKFJlc2l6ZUJlaGF2aW9yLCBDb21tYW5kSW50ZXJjZXB0b3IpO1xyXG5cclxuLyoqXHJcbiAqIFNuYXAgd2lkdGggYW5kIGhlaWdodCBpbiByZWxhdGlvbiB0byBjZW50ZXIuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLnNoYXBlfSBzaGFwZVxyXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtCb3VuZHN9IFNuYXBwZWQgYm91bmRzLlxyXG4gKi9cclxuUmVzaXplQmVoYXZpb3IucHJvdG90eXBlLnNuYXBTaW1wbGUgPSBmdW5jdGlvbihzaGFwZSwgbmV3Qm91bmRzKSB7XHJcbiAgdmFyIGdyaWRTbmFwcGluZyA9IHRoaXMuX2dyaWRTbmFwcGluZztcclxuXHJcbiAgbmV3Qm91bmRzLndpZHRoID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShuZXdCb3VuZHMud2lkdGgsIHtcclxuICAgIG1pbjogbmV3Qm91bmRzLndpZHRoXHJcbiAgfSk7XHJcblxyXG4gIG5ld0JvdW5kcy5oZWlnaHQgPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKG5ld0JvdW5kcy5oZWlnaHQsIHtcclxuICAgIG1pbjogbmV3Qm91bmRzLmhlaWdodFxyXG4gIH0pO1xyXG5cclxuICBuZXdCb3VuZHMueCA9IHNoYXBlLnggKyAoc2hhcGUud2lkdGggLyAyKSAtIChuZXdCb3VuZHMud2lkdGggLyAyKTtcclxuICBuZXdCb3VuZHMueSA9IHNoYXBlLnkgKyAoc2hhcGUuaGVpZ2h0IC8gMikgLSAobmV3Qm91bmRzLmhlaWdodCAvIDIpO1xyXG5cclxuICByZXR1cm4gbmV3Qm91bmRzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFNuYXAgeCwgeSwgd2lkdGggYW5kIGhlaWdodCBhY2NvcmRpbmcgdG8gZ2l2ZW4gZGlyZWN0aW9ucy5cclxuICpcclxuICogQHBhcmFtIHtCb3VuZHN9IG5ld0JvdW5kc1xyXG4gKiBAcGFyYW0ge3N0cmluZ30gZGlyZWN0aW9ucyAtIERpcmVjdGlvbnMgYXMge258d3xzfGV9LlxyXG4gKlxyXG4gKiBAcmV0dXJucyB7Qm91bmRzfSBTbmFwcGVkIGJvdW5kcy5cclxuICovXHJcblJlc2l6ZUJlaGF2aW9yLnByb3RvdHlwZS5zbmFwQ29tcGxleCA9IGZ1bmN0aW9uKG5ld0JvdW5kcywgZGlyZWN0aW9ucykge1xyXG4gIGlmICgvd3xlLy50ZXN0KGRpcmVjdGlvbnMpKSB7XHJcbiAgICBuZXdCb3VuZHMgPSB0aGlzLnNuYXBIb3Jpem9udGFsbHkobmV3Qm91bmRzLCBkaXJlY3Rpb25zKTtcclxuICB9XHJcblxyXG4gIGlmICgvbnxzLy50ZXN0KGRpcmVjdGlvbnMpKSB7XHJcbiAgICBuZXdCb3VuZHMgPSB0aGlzLnNuYXBWZXJ0aWNhbGx5KG5ld0JvdW5kcywgZGlyZWN0aW9ucyk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbmV3Qm91bmRzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFNuYXAgaW4gb25lIG9yIGJvdGggZGlyZWN0aW9ucyBob3Jpem9udGFsbHkuXHJcbiAqXHJcbiAqIEBwYXJhbSB7Qm91bmRzfSBuZXdCb3VuZHNcclxuICogQHBhcmFtIHtzdHJpbmd9IGRpcmVjdGlvbnMgLSBEaXJlY3Rpb25zIGFzIHtufHd8c3xlfS5cclxuICpcclxuICogQHJldHVybnMge0JvdW5kc30gU25hcHBlZCBib3VuZHMuXHJcbiAqL1xyXG5SZXNpemVCZWhhdmlvci5wcm90b3R5cGUuc25hcEhvcml6b250YWxseSA9IGZ1bmN0aW9uKG5ld0JvdW5kcywgZGlyZWN0aW9ucykge1xyXG4gIHZhciBncmlkU25hcHBpbmcgPSB0aGlzLl9ncmlkU25hcHBpbmcsXHJcbiAgICAgIHdlc3QgPSAvdy8udGVzdChkaXJlY3Rpb25zKSxcclxuICAgICAgZWFzdCA9IC9lLy50ZXN0KGRpcmVjdGlvbnMpO1xyXG5cclxuICB2YXIgc25hcHBlZE5ld0JvdW5kcyA9IHt9O1xyXG5cclxuICBzbmFwcGVkTmV3Qm91bmRzLndpZHRoID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShuZXdCb3VuZHMud2lkdGgsIHtcclxuICAgIG1pbjogbmV3Qm91bmRzLndpZHRoXHJcbiAgfSk7XHJcblxyXG4gIGlmIChlYXN0KSB7XHJcblxyXG4gICAgLy8gaGFuZGxlIDx3ZT5cclxuICAgIGlmICh3ZXN0KSB7XHJcbiAgICAgIHNuYXBwZWROZXdCb3VuZHMueCA9IGdyaWRTbmFwcGluZy5zbmFwVmFsdWUobmV3Qm91bmRzLngsIHtcclxuICAgICAgICBtYXg6IG5ld0JvdW5kcy54XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgc25hcHBlZE5ld0JvdW5kcy53aWR0aCArPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKG5ld0JvdW5kcy54IC0gc25hcHBlZE5ld0JvdW5kcy54LCB7XHJcbiAgICAgICAgbWluOiBuZXdCb3VuZHMueCAtIHNuYXBwZWROZXdCb3VuZHMueFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBoYW5kbGUgPGU+XHJcbiAgICBlbHNlIHtcclxuICAgICAgbmV3Qm91bmRzLnggPSBuZXdCb3VuZHMueCArIG5ld0JvdW5kcy53aWR0aCAtIHNuYXBwZWROZXdCb3VuZHMud2lkdGg7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBhc3NpZ24gc25hcHBlZCB4IGFuZCB3aWR0aFxyXG4gIGFzc2lnbihuZXdCb3VuZHMsIHNuYXBwZWROZXdCb3VuZHMpO1xyXG5cclxuICByZXR1cm4gbmV3Qm91bmRzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFNuYXAgaW4gb25lIG9yIGJvdGggZGlyZWN0aW9ucyB2ZXJ0aWNhbGx5LlxyXG4gKlxyXG4gKiBAcGFyYW0ge0JvdW5kc30gbmV3Qm91bmRzXHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXJlY3Rpb25zIC0gRGlyZWN0aW9ucyBhcyB7bnx3fHN8ZX0uXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtCb3VuZHN9IFNuYXBwZWQgYm91bmRzLlxyXG4gKi9cclxuUmVzaXplQmVoYXZpb3IucHJvdG90eXBlLnNuYXBWZXJ0aWNhbGx5ID0gZnVuY3Rpb24obmV3Qm91bmRzLCBkaXJlY3Rpb25zKSB7XHJcbiAgdmFyIGdyaWRTbmFwcGluZyA9IHRoaXMuX2dyaWRTbmFwcGluZyxcclxuICAgICAgbm9ydGggPSAvbi8udGVzdChkaXJlY3Rpb25zKSxcclxuICAgICAgc291dGggPSAvcy8udGVzdChkaXJlY3Rpb25zKTtcclxuXHJcbiAgdmFyIHNuYXBwZWROZXdCb3VuZHMgPSB7fTtcclxuXHJcbiAgc25hcHBlZE5ld0JvdW5kcy5oZWlnaHQgPSBncmlkU25hcHBpbmcuc25hcFZhbHVlKG5ld0JvdW5kcy5oZWlnaHQsIHtcclxuICAgIG1pbjogbmV3Qm91bmRzLmhlaWdodFxyXG4gIH0pO1xyXG5cclxuICBpZiAobm9ydGgpIHtcclxuXHJcbiAgICAvLyBoYW5kbGUgPG5zPlxyXG4gICAgaWYgKHNvdXRoKSB7XHJcbiAgICAgIHNuYXBwZWROZXdCb3VuZHMueSA9IGdyaWRTbmFwcGluZy5zbmFwVmFsdWUobmV3Qm91bmRzLnksIHtcclxuICAgICAgICBtYXg6IG5ld0JvdW5kcy55XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgc25hcHBlZE5ld0JvdW5kcy5oZWlnaHQgKz0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShuZXdCb3VuZHMueSAtIHNuYXBwZWROZXdCb3VuZHMueSwge1xyXG4gICAgICAgIG1pbjogbmV3Qm91bmRzLnkgLSBzbmFwcGVkTmV3Qm91bmRzLnlcclxuICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaGFuZGxlIDxuPlxyXG4gICAgZWxzZSB7XHJcbiAgICAgIG5ld0JvdW5kcy55ID0gbmV3Qm91bmRzLnkgKyBuZXdCb3VuZHMuaGVpZ2h0IC0gc25hcHBlZE5ld0JvdW5kcy5oZWlnaHQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBhc3NpZ24gc25hcHBlZCB5IGFuZCBoZWlnaHRcclxuICBhc3NpZ24obmV3Qm91bmRzLCBzbmFwcGVkTmV3Qm91bmRzKTtcclxuXHJcbiAgcmV0dXJuIG5ld0JvdW5kcztcclxufTsiLCJ2YXIgSElHSF9QUklPUklUWSA9IDIwMDA7XHJcblxyXG4vKipcclxuICogSW50ZWdyYXRlcyBzcGFjZSB0b29sIHdpdGggZ3JpZCBzbmFwcGluZy5cclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNwYWNlVG9vbEJlaGF2aW9yKGV2ZW50QnVzLCBncmlkU25hcHBpbmcpIHtcclxuICBldmVudEJ1cy5vbihbXHJcbiAgICAnc3BhY2VUb29sLm1vdmUnLFxyXG4gICAgJ3NwYWNlVG9vbC5lbmQnXHJcbiAgXSwgSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dDtcclxuXHJcbiAgICBpZiAoIWNvbnRleHQuaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBheGlzID0gY29udGV4dC5heGlzO1xyXG5cclxuICAgIHZhciBzbmFwcGVkO1xyXG5cclxuICAgIGlmIChheGlzID09PSAneCcpIHtcclxuXHJcbiAgICAgIC8vIHNuYXAgZGVsdGEgeCB0byBtdWx0aXBsZSBvZiAxMFxyXG4gICAgICBzbmFwcGVkID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShldmVudC5keCk7XHJcblxyXG4gICAgICBldmVudC54ID0gZXZlbnQueCArIHNuYXBwZWQgLSBldmVudC5keDtcclxuICAgICAgZXZlbnQuZHggPSBzbmFwcGVkO1xyXG4gICAgfSBlbHNlIHtcclxuXHJcbiAgICAgIC8vIHNuYXAgZGVsdGEgeSB0byBtdWx0aXBsZSBvZiAxMFxyXG4gICAgICBzbmFwcGVkID0gZ3JpZFNuYXBwaW5nLnNuYXBWYWx1ZShldmVudC5keSk7XHJcblxyXG4gICAgICBldmVudC55ID0gZXZlbnQueSArIHNuYXBwZWQgLSBldmVudC5keTtcclxuICAgICAgZXZlbnQuZHkgPSBzbmFwcGVkO1xyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG5TcGFjZVRvb2xCZWhhdmlvci4kaW5qZWN0ID0gW1xyXG4gICdldmVudEJ1cycsXHJcbiAgJ2dyaWRTbmFwcGluZydcclxuXTsiLCJpbXBvcnQgUmVzaXplQmVoYXZpb3IgZnJvbSAnLi9SZXNpemVCZWhhdmlvcic7XHJcbmltcG9ydCBTcGFjZVRvb2xCZWhhdmlvciBmcm9tICcuL1NwYWNlVG9vbEJlaGF2aW9yJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBfX2luaXRfXzogW1xyXG4gICAgJ2dyaWRTbmFwcGluZ1Jlc2l6ZUJlaGF2aW9yJyxcclxuICAgICdncmlkU25hcHBpbmdTcGFjZVRvb2xCZWhhdmlvcidcclxuICBdLFxyXG4gIGdyaWRTbmFwcGluZ1Jlc2l6ZUJlaGF2aW9yOiBbICd0eXBlJywgUmVzaXplQmVoYXZpb3IgXSxcclxuICBncmlkU25hcHBpbmdTcGFjZVRvb2xCZWhhdmlvcjogWyAndHlwZScsIFNwYWNlVG9vbEJlaGF2aW9yIF1cclxufTsiLCJpbXBvcnQgR3JpZFNuYXBwaW5nIGZyb20gJy4vR3JpZFNuYXBwaW5nJztcclxuXHJcbmltcG9ydCBHcmlkU25hcHBpbmdCZWhhdmlvck1vZHVsZSBmcm9tICcuL2JlaGF2aW9yJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBfX2RlcGVuZHNfXzogWyBHcmlkU25hcHBpbmdCZWhhdmlvck1vZHVsZSBdLFxyXG4gIF9faW5pdF9fOiBbICdncmlkU25hcHBpbmcnIF0sXHJcbiAgZ3JpZFNuYXBwaW5nOiBbICd0eXBlJywgR3JpZFNuYXBwaW5nIF1cclxufTsiLCJpbXBvcnQgeyBoYXNQcmltYXJ5TW9kaWZpZXIgfSBmcm9tICcuLi8uLi91dGlsL01vdXNlJztcblxuaW1wb3J0IHsgaXNLZXkgfSBmcm9tICcuLi8uLi9mZWF0dXJlcy9rZXlib2FyZC9LZXlib2FyZFV0aWwnO1xuXG52YXIgSElHSF9QUklPUklUWSA9IDE1MDA7XG52YXIgSEFORF9DVVJTT1IgPSAnZ3JhYic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gSGFuZFRvb2woZXZlbnRCdXMsIGNhbnZhcywgZHJhZ2dpbmcsIGluamVjdG9yLCB0b29sTWFuYWdlcikge1xuICB0aGlzLl9kcmFnZ2luZyA9IGRyYWdnaW5nO1xuXG4gIHZhciBzZWxmID0gdGhpcyxcbiAgICAgIGtleWJvYXJkID0gaW5qZWN0b3IuZ2V0KCdrZXlib2FyZCcsIGZhbHNlKTtcblxuICB0b29sTWFuYWdlci5yZWdpc3RlclRvb2woJ2hhbmQnLCB7XG4gICAgdG9vbDogJ2hhbmQnLFxuICAgIGRyYWdnaW5nOiAnaGFuZC5tb3ZlJ1xuICB9KTtcblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tb3VzZWRvd24nLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIGlmIChoYXNQcmltYXJ5TW9kaWZpZXIoZXZlbnQpKSB7XG4gICAgICB0aGlzLmFjdGl2YXRlTW92ZShldmVudC5vcmlnaW5hbEV2ZW50KTtcblxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSwgdGhpcyk7XG5cbiAga2V5Ym9hcmQgJiYga2V5Ym9hcmQuYWRkTGlzdGVuZXIoSElHSF9QUklPUklUWSwgZnVuY3Rpb24oZSkge1xuICAgIGlmICghaXNTcGFjZShlLmtleUV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChzZWxmLmlzQWN0aXZlKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBhY3RpdmF0ZU1vdmUoZXZlbnQpIHtcbiAgICAgIHNlbGYuYWN0aXZhdGVNb3ZlKGV2ZW50KTtcblxuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGFjdGl2YXRlTW92ZSk7XG4gICAgfVxuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIGFjdGl2YXRlTW92ZSk7XG5cbiAgICBmdW5jdGlvbiBkZWFjdGl2YXRlTW92ZShlKSB7XG4gICAgICBpZiAoIWlzU3BhY2UoZS5rZXlFdmVudCkpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgYWN0aXZhdGVNb3ZlKTtcblxuICAgICAga2V5Ym9hcmQucmVtb3ZlTGlzdGVuZXIoZGVhY3RpdmF0ZU1vdmUsICdrZXlib2FyZC5rZXl1cCcpO1xuXG4gICAgICBkcmFnZ2luZy5jYW5jZWwoKTtcbiAgICB9XG5cbiAgICBrZXlib2FyZC5hZGRMaXN0ZW5lcihISUdIX1BSSU9SSVRZLCBkZWFjdGl2YXRlTW92ZSwgJ2tleWJvYXJkLmtleXVwJyk7XG4gIH0sICdrZXlib2FyZC5rZXlkb3duJyk7XG5cbiAgZXZlbnRCdXMub24oJ2hhbmQuZW5kJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gZXZlbnQub3JpZ2luYWxFdmVudC50YXJnZXQ7XG5cbiAgICAvLyBvbmx5IHJlYWN0aXZlIG9uIGRpYWdyYW0gY2xpY2tcbiAgICAvLyBvbiBzb21lIG9jY2FzaW9ucywgZXZlbnQuaG92ZXIgaXMgbm90IHNldCBhbmQgd2UgaGF2ZSB0byBjaGVjayBpZiB0aGUgdGFyZ2V0IGlzIGFuIHN2Z1xuICAgIGlmICghZXZlbnQuaG92ZXIgJiYgISh0YXJnZXQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGV2ZW50QnVzLm9uY2UoJ2hhbmQuZW5kZWQnLCBmdW5jdGlvbigpIHtcbiAgICAgIHRoaXMuYWN0aXZhdGVNb3ZlKGV2ZW50Lm9yaWdpbmFsRXZlbnQsIHsgcmVhY3RpdmF0ZTogdHJ1ZSB9KTtcbiAgICB9LCB0aGlzKTtcblxuICB9LCB0aGlzKTtcblxuXG4gIGV2ZW50QnVzLm9uKCdoYW5kLm1vdmUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIHNjYWxlID0gY2FudmFzLnZpZXdib3goKS5zY2FsZTtcblxuICAgIGNhbnZhcy5zY3JvbGwoe1xuICAgICAgZHg6IGV2ZW50LmR4ICogc2NhbGUsXG4gICAgICBkeTogZXZlbnQuZHkgKiBzY2FsZVxuICAgIH0pO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignaGFuZC5tb3ZlLmVuZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICByZWFjdGl2YXRlID0gY29udGV4dC5yZWFjdGl2YXRlO1xuXG4gICAgLy8gRG9uJ3QgcmVhY3RpdmF0ZSBpZiB0aGUgdXNlciBpcyB1c2luZyB0aGUga2V5Ym9hcmQga2V5YmluZGluZ1xuICAgIGlmICghaGFzUHJpbWFyeU1vZGlmaWVyKGV2ZW50KSAmJiByZWFjdGl2YXRlKSB7XG5cbiAgICAgIGV2ZW50QnVzLm9uY2UoJ2hhbmQubW92ZS5lbmRlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIHRoaXMuYWN0aXZhdGVIYW5kKGV2ZW50Lm9yaWdpbmFsRXZlbnQsIHRydWUsIHRydWUpO1xuICAgICAgfSwgdGhpcyk7XG5cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0sIHRoaXMpO1xuXG59XG5cbkhhbmRUb29sLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnLFxuICAnZHJhZ2dpbmcnLFxuICAnaW5qZWN0b3InLFxuICAndG9vbE1hbmFnZXInXG5dO1xuXG5cbkhhbmRUb29sLnByb3RvdHlwZS5hY3RpdmF0ZU1vdmUgPSBmdW5jdGlvbihldmVudCwgYXV0b0FjdGl2YXRlLCBjb250ZXh0KSB7XG4gIGlmICh0eXBlb2YgYXV0b0FjdGl2YXRlID09PSAnb2JqZWN0Jykge1xuICAgIGNvbnRleHQgPSBhdXRvQWN0aXZhdGU7XG4gICAgYXV0b0FjdGl2YXRlID0gZmFsc2U7XG4gIH1cblxuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnaGFuZC5tb3ZlJywge1xuICAgIGF1dG9BY3RpdmF0ZTogYXV0b0FjdGl2YXRlLFxuICAgIGN1cnNvcjogSEFORF9DVVJTT1IsXG4gICAgZGF0YToge1xuICAgICAgY29udGV4dDogY29udGV4dCB8fCB7fVxuICAgIH1cbiAgfSk7XG59O1xuXG5IYW5kVG9vbC5wcm90b3R5cGUuYWN0aXZhdGVIYW5kID0gZnVuY3Rpb24oZXZlbnQsIGF1dG9BY3RpdmF0ZSwgcmVhY3RpdmF0ZSkge1xuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnaGFuZCcsIHtcbiAgICB0cmFwQ2xpY2s6IGZhbHNlLFxuICAgIGF1dG9BY3RpdmF0ZTogYXV0b0FjdGl2YXRlLFxuICAgIGN1cnNvcjogSEFORF9DVVJTT1IsXG4gICAgZGF0YToge1xuICAgICAgY29udGV4dDoge1xuICAgICAgICByZWFjdGl2YXRlOiByZWFjdGl2YXRlXG4gICAgICB9XG4gICAgfVxuICB9KTtcbn07XG5cbkhhbmRUb29sLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuaXNBY3RpdmUoKSkge1xuICAgIHRoaXMuX2RyYWdnaW5nLmNhbmNlbCgpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuYWN0aXZhdGVIYW5kKCk7XG4gIH1cbn07XG5cbkhhbmRUb29sLnByb3RvdHlwZS5pc0FjdGl2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29udGV4dCA9IHRoaXMuX2RyYWdnaW5nLmNvbnRleHQoKTtcblxuICBpZiAoY29udGV4dCkge1xuICAgIHJldHVybiAvXihoYW5kfGhhbmRcXC5tb3ZlKSQvLnRlc3QoY29udGV4dC5wcmVmaXgpO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGlzU3BhY2Uoa2V5RXZlbnQpIHtcbiAgcmV0dXJuIGlzS2V5KCcgJywga2V5RXZlbnQpO1xufSIsImltcG9ydCBUb29sTWFuYWdlck1vZHVsZSBmcm9tICcuLi90b29sLW1hbmFnZXInO1xuXG5pbXBvcnQgSGFuZFRvb2wgZnJvbSAnLi9IYW5kVG9vbCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBUb29sTWFuYWdlck1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogWyAnaGFuZFRvb2wnIF0sXG4gIGhhbmRUb29sOiBbICd0eXBlJywgSGFuZFRvb2wgXVxufTtcbiIsImltcG9ydCB7XG4gIGZvckVhY2gsXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgcXVlcnlBbGwgYXMgZG9tUXVlcnlBbGxcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7IGlzUHJpbWFyeUJ1dHRvbiB9IGZyb20gJy4uLy4uL3V0aWwvTW91c2UnO1xuXG5pbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVMaW5lLFxuICB1cGRhdGVMaW5lXG59IGZyb20gJy4uLy4uL3V0aWwvUmVuZGVyVXRpbCc7XG5cbmZ1bmN0aW9uIGFsbG93QWxsKGUpIHsgcmV0dXJuIHRydWU7IH1cblxudmFyIExPV19QUklPUklUWSA9IDUwMDtcblxuXG4vKipcbiAqIEEgcGx1Z2luIHRoYXQgcHJvdmlkZXMgaW50ZXJhY3Rpb24gZXZlbnRzIGZvciBkaWFncmFtIGVsZW1lbnRzLlxuICpcbiAqIEl0IGVtaXRzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICpcbiAqICAgKiBlbGVtZW50LmNsaWNrXG4gKiAgICogZWxlbWVudC5jb250ZXh0bWVudVxuICogICAqIGVsZW1lbnQuZGJsY2xpY2tcbiAqICAgKiBlbGVtZW50LmhvdmVyXG4gKiAgICogZWxlbWVudC5tb3VzZWRvd25cbiAqICAgKiBlbGVtZW50Lm1vdXNlbW92ZVxuICogICAqIGVsZW1lbnQubW91c2V1cFxuICogICAqIGVsZW1lbnQub3V0XG4gKlxuICogRWFjaCBldmVudCBpcyBhIHR1cGxlIHsgZWxlbWVudCwgZ2Z4LCBvcmlnaW5hbEV2ZW50IH0uXG4gKlxuICogQ2FuY2VsaW5nIHRoZSBldmVudCB2aWEgRXZlbnQjcHJldmVudERlZmF1bHQoKVxuICogcHJldmVudHMgdGhlIG9yaWdpbmFsIERPTSBvcGVyYXRpb24uXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gSW50ZXJhY3Rpb25FdmVudHMoZXZlbnRCdXMsIGVsZW1lbnRSZWdpc3RyeSwgc3R5bGVzKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8qKlxuICAgKiBGaXJlIGFuIGludGVyYWN0aW9uIGV2ZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdHlwZSBsb2NhbCBldmVudCBuYW1lLCBlLmcuIGVsZW1lbnQuY2xpY2suXG4gICAqIEBwYXJhbSB7RE9NRXZlbnR9IGV2ZW50IG5hdGl2ZSBldmVudFxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBbZWxlbWVudF0gdGhlIGRpYWdyYW0gZWxlbWVudCB0byBlbWl0IHRoZSBldmVudCBvbjtcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzIHRvIHRoZSBldmVudCB0YXJnZXRcbiAgICovXG4gIGZ1bmN0aW9uIGZpcmUodHlwZSwgZXZlbnQsIGVsZW1lbnQpIHtcblxuICAgIGlmIChpc0lnbm9yZWQodHlwZSwgZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRhcmdldCwgZ2Z4LCByZXR1cm5WYWx1ZTtcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgdGFyZ2V0ID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQgfHwgZXZlbnQudGFyZ2V0O1xuXG4gICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgIGdmeCA9IHRhcmdldDtcbiAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZ2Z4ID0gZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGlmICghZ2Z4IHx8ICFlbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuVmFsdWUgPSBldmVudEJ1cy5maXJlKHR5cGUsIHtcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBnZng6IGdmeCxcbiAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2ZW50XG4gICAgfSk7XG5cbiAgICBpZiAocmV0dXJuVmFsdWUgPT09IGZhbHNlKSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVE9ETyhuaWtrdSk6IGRvY3VtZW50IHRoaXNcbiAgdmFyIGhhbmRsZXJzID0ge307XG5cbiAgZnVuY3Rpb24gbW91c2VIYW5kbGVyKGxvY2FsRXZlbnROYW1lKSB7XG4gICAgcmV0dXJuIGhhbmRsZXJzW2xvY2FsRXZlbnROYW1lXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSWdub3JlZChsb2NhbEV2ZW50TmFtZSwgZXZlbnQpIHtcblxuICAgIHZhciBmaWx0ZXIgPSBpZ25vcmVkRmlsdGVyc1tsb2NhbEV2ZW50TmFtZV0gfHwgaXNQcmltYXJ5QnV0dG9uO1xuXG4gICAgLy8gb25seSByZWFjdCBvbiBsZWZ0IG1vdXNlIGJ1dHRvbiBpbnRlcmFjdGlvbnNcbiAgICAvLyBleGNlcHQgZm9yIGludGVyYWN0aW9uIGV2ZW50cyB0aGF0IGFyZSBlbmFibGVkXG4gICAgLy8gZm9yIHNlY3VuZGFyeSBtb3VzZSBidXR0b25cbiAgICByZXR1cm4gIWZpbHRlcihldmVudCk7XG4gIH1cblxuICB2YXIgYmluZGluZ3MgPSB7XG4gICAgY2xpY2s6ICdlbGVtZW50LmNsaWNrJyxcbiAgICBjb250ZXh0bWVudTogJ2VsZW1lbnQuY29udGV4dG1lbnUnLFxuICAgIGRibGNsaWNrOiAnZWxlbWVudC5kYmxjbGljaycsXG4gICAgbW91c2Vkb3duOiAnZWxlbWVudC5tb3VzZWRvd24nLFxuICAgIG1vdXNlbW92ZTogJ2VsZW1lbnQubW91c2Vtb3ZlJyxcbiAgICBtb3VzZW92ZXI6ICdlbGVtZW50LmhvdmVyJyxcbiAgICBtb3VzZW91dDogJ2VsZW1lbnQub3V0JyxcbiAgICBtb3VzZXVwOiAnZWxlbWVudC5tb3VzZXVwJyxcbiAgfTtcblxuICB2YXIgaWdub3JlZEZpbHRlcnMgPSB7XG4gICAgJ2VsZW1lbnQuY29udGV4dG1lbnUnOiBhbGxvd0FsbFxuICB9O1xuXG5cbiAgLy8gbWFudWFsIGV2ZW50IHRyaWdnZXIgLy8vLy8vLy8vL1xuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIGFuIGludGVyYWN0aW9uIGV2ZW50IChiYXNlZCBvbiBhIG5hdGl2ZSBkb20gZXZlbnQpXG4gICAqIG9uIHRoZSB0YXJnZXQgc2hhcGUgb3IgY29ubmVjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50TmFtZSB0aGUgbmFtZSBvZiB0aGUgdHJpZ2dlcmVkIERPTSBldmVudFxuICAgKiBAcGFyYW0ge01vdXNlRXZlbnR9IGV2ZW50XG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IHRhcmdldEVsZW1lbnRcbiAgICovXG4gIGZ1bmN0aW9uIHRyaWdnZXJNb3VzZUV2ZW50KGV2ZW50TmFtZSwgZXZlbnQsIHRhcmdldEVsZW1lbnQpIHtcblxuICAgIC8vIGkuZS4gZWxlbWVudC5tb3VzZWRvd24uLi5cbiAgICB2YXIgbG9jYWxFdmVudE5hbWUgPSBiaW5kaW5nc1tldmVudE5hbWVdO1xuXG4gICAgaWYgKCFsb2NhbEV2ZW50TmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bm1hcHBlZCBET00gZXZlbnQgbmFtZSA8JyArIGV2ZW50TmFtZSArICc+Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpcmUobG9jYWxFdmVudE5hbWUsIGV2ZW50LCB0YXJnZXRFbGVtZW50KTtcbiAgfVxuXG5cbiAgdmFyIEVMRU1FTlRfU0VMRUNUT1IgPSAnc3ZnLCAuZGpzLWVsZW1lbnQnO1xuXG4gIC8vIGV2ZW50IGhhbmRsaW5nIC8vLy8vLy9cblxuICBmdW5jdGlvbiByZWdpc3RlckV2ZW50KG5vZGUsIGV2ZW50LCBsb2NhbEV2ZW50LCBpZ25vcmVkRmlsdGVyKSB7XG5cbiAgICB2YXIgaGFuZGxlciA9IGhhbmRsZXJzW2xvY2FsRXZlbnRdID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIGZpcmUobG9jYWxFdmVudCwgZXZlbnQpO1xuICAgIH07XG5cbiAgICBpZiAoaWdub3JlZEZpbHRlcikge1xuICAgICAgaWdub3JlZEZpbHRlcnNbbG9jYWxFdmVudF0gPSBpZ25vcmVkRmlsdGVyO1xuICAgIH1cblxuICAgIGhhbmRsZXIuJGRlbGVnYXRlID0gZG9tRGVsZWdhdGUuYmluZChub2RlLCBFTEVNRU5UX1NFTEVDVE9SLCBldmVudCwgaGFuZGxlcik7XG4gIH1cblxuICBmdW5jdGlvbiB1bnJlZ2lzdGVyRXZlbnQobm9kZSwgZXZlbnQsIGxvY2FsRXZlbnQpIHtcblxuICAgIHZhciBoYW5kbGVyID0gbW91c2VIYW5kbGVyKGxvY2FsRXZlbnQpO1xuXG4gICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZG9tRGVsZWdhdGUudW5iaW5kKG5vZGUsIGV2ZW50LCBoYW5kbGVyLiRkZWxlZ2F0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiByZWdpc3RlckV2ZW50cyhzdmcpIHtcbiAgICBmb3JFYWNoKGJpbmRpbmdzLCBmdW5jdGlvbih2YWwsIGtleSkge1xuICAgICAgcmVnaXN0ZXJFdmVudChzdmcsIGtleSwgdmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVucmVnaXN0ZXJFdmVudHMoc3ZnKSB7XG4gICAgZm9yRWFjaChiaW5kaW5ncywgZnVuY3Rpb24odmFsLCBrZXkpIHtcbiAgICAgIHVucmVnaXN0ZXJFdmVudChzdmcsIGtleSwgdmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuZGVzdHJveScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdW5yZWdpc3RlckV2ZW50cyhldmVudC5zdmcpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY2FudmFzLmluaXQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHJlZ2lzdGVyRXZlbnRzKGV2ZW50LnN2Zyk7XG4gIH0pO1xuXG5cbiAgLy8gaGl0IGJveCB1cGRhdGluZyAvLy8vLy8vLy8vLy8vLy8vXG5cbiAgZXZlbnRCdXMub24oWyAnc2hhcGUuYWRkZWQnLCAnY29ubmVjdGlvbi5hZGRlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUhpdCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH0pO1xuXG4gIC8vIFVwZGF0ZSBkanMtaGl0IG9uIGNoYW5nZS5cbiAgLy8gQSBsb3cgcHJpb3J0aXR5IGlzIG5lY2Vzc2FyeSwgYmVjYXVzZSBkanMtaGl0IG9mIGxhYmVscyBoYXMgdG8gYmUgdXBkYXRlZFxuICAvLyBhZnRlciB0aGUgbGFiZWwgYm91bmRzIGhhdmUgYmVlbiB1cGRhdGVkIGluIHRoZSByZW5kZXJlci5cbiAgZXZlbnRCdXMub24oW1xuICAgICdzaGFwZS5jaGFuZ2VkJyxcbiAgICAnY29ubmVjdGlvbi5jaGFuZ2VkJ1xuICBdLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdpbnRlcmFjdGlvbkV2ZW50cy5jcmVhdGVIaXQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICBzZWxmLmNyZWF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICBzZWxmLnVwZGF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgfSk7XG5cblxuICAvLyBoaXQgc3R5bGVzIC8vLy8vLy8vLy8vL1xuXG4gIHZhciBTVFJPS0VfSElUX1NUWUxFID0gY3JlYXRlSGl0U3R5bGUoJ2Rqcy1oaXQgZGpzLWhpdC1zdHJva2UnKTtcblxuICB2YXIgQ0xJQ0tfU1RST0tFX0hJVF9TVFlMRSA9IGNyZWF0ZUhpdFN0eWxlKCdkanMtaGl0IGRqcy1oaXQtY2xpY2stc3Ryb2tlJyk7XG5cbiAgdmFyIEFMTF9ISVRfU1RZTEUgPSBjcmVhdGVIaXRTdHlsZSgnZGpzLWhpdCBkanMtaGl0LWFsbCcpO1xuXG4gIHZhciBISVRfVFlQRVMgPSB7XG4gICAgJ2FsbCc6IEFMTF9ISVRfU1RZTEUsXG4gICAgJ2NsaWNrLXN0cm9rZSc6IENMSUNLX1NUUk9LRV9ISVRfU1RZTEUsXG4gICAgJ3N0cm9rZSc6IFNUUk9LRV9ISVRfU1RZTEVcbiAgfTtcblxuICBmdW5jdGlvbiBjcmVhdGVIaXRTdHlsZShjbGFzc05hbWVzLCBhdHRycykge1xuXG4gICAgYXR0cnMgPSBhc3NpZ24oe1xuICAgICAgc3Ryb2tlOiAnd2hpdGUnLFxuICAgICAgc3Ryb2tlV2lkdGg6IDE1XG4gICAgfSwgYXR0cnMgfHwge30pO1xuXG4gICAgcmV0dXJuIHN0eWxlcy5jbHMoY2xhc3NOYW1lcywgWyAnbm8tZmlsbCcsICduby1ib3JkZXInIF0sIGF0dHJzKTtcbiAgfVxuXG5cbiAgLy8gc3R5bGUgaGVscGVycyAvLy8vLy8vLy8vLy8vLy9cblxuICBmdW5jdGlvbiBhcHBseVN0eWxlKGhpdCwgdHlwZSkge1xuXG4gICAgdmFyIGF0dHJzID0gSElUX1RZUEVTW3R5cGVdO1xuXG4gICAgaWYgKCFhdHRycykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGhpdCB0eXBlIDwnICsgdHlwZSArICc+Jyk7XG4gICAgfVxuXG4gICAgc3ZnQXR0cihoaXQsIGF0dHJzKTtcblxuICAgIHJldHVybiBoaXQ7XG4gIH1cblxuICBmdW5jdGlvbiBhcHBlbmRIaXQoZ2Z4LCBoaXQpIHtcbiAgICBzdmdBcHBlbmQoZ2Z4LCBoaXQpO1xuICB9XG5cblxuICAvLyBBUElcblxuICAvKipcbiAgICogUmVtb3ZlIGhpbnRzIG9uIHRoZSBnaXZlbiBncmFwaGljcy5cbiAgICpcbiAgICogQHBhcmFtIHtTVkdFbGVtZW50fSBnZnhcbiAgICovXG4gIHRoaXMucmVtb3ZlSGl0cyA9IGZ1bmN0aW9uKGdmeCkge1xuICAgIHZhciBoaXRzID0gZG9tUXVlcnlBbGwoJy5kanMtaGl0JywgZ2Z4KTtcblxuICAgIGZvckVhY2goaGl0cywgc3ZnUmVtb3ZlKTtcbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGRlZmF1bHQgaGl0IGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGdmeFxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSBjcmVhdGVkIGhpdFxuICAgKi9cbiAgdGhpcy5jcmVhdGVEZWZhdWx0SGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG4gICAgdmFyIHdheXBvaW50cyA9IGVsZW1lbnQud2F5cG9pbnRzLFxuICAgICAgICBpc0ZyYW1lID0gZWxlbWVudC5pc0ZyYW1lLFxuICAgICAgICBib3hUeXBlO1xuXG4gICAgaWYgKHdheXBvaW50cykge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlV2F5cG9pbnRzSGl0KGdmeCwgd2F5cG9pbnRzKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICBib3hUeXBlID0gaXNGcmFtZSA/ICdzdHJva2UnIDogJ2FsbCc7XG5cbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUJveEhpdChnZngsIGJveFR5cGUsIHtcbiAgICAgICAgd2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGhlaWdodDogZWxlbWVudC5oZWlnaHRcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGhpdHMgZm9yIHRoZSBnaXZlbiB3YXlwb2ludHMuXG4gICAqXG4gICAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ2Z4XG4gICAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAgICpcbiAgICogQHJldHVybiB7U1ZHRWxlbWVudH1cbiAgICovXG4gIHRoaXMuY3JlYXRlV2F5cG9pbnRzSGl0ID0gZnVuY3Rpb24oZ2Z4LCB3YXlwb2ludHMpIHtcblxuICAgIHZhciBoaXQgPSBjcmVhdGVMaW5lKHdheXBvaW50cyk7XG5cbiAgICBhcHBseVN0eWxlKGhpdCwgJ3N0cm9rZScpO1xuXG4gICAgYXBwZW5kSGl0KGdmeCwgaGl0KTtcblxuICAgIHJldHVybiBoaXQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBoaXRzIGZvciBhIGJveC5cbiAgICpcbiAgICogQHBhcmFtIHtTVkdFbGVtZW50fSBnZnhcbiAgICogQHBhcmFtIHtzdHJpbmd9IGhpdFR5cGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGF0dHJzXG4gICAqXG4gICAqIEByZXR1cm4ge1NWR0VsZW1lbnR9XG4gICAqL1xuICB0aGlzLmNyZWF0ZUJveEhpdCA9IGZ1bmN0aW9uKGdmeCwgdHlwZSwgYXR0cnMpIHtcblxuICAgIGF0dHJzID0gYXNzaWduKHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwXG4gICAgfSwgYXR0cnMpO1xuXG4gICAgdmFyIGhpdCA9IHN2Z0NyZWF0ZSgncmVjdCcpO1xuXG4gICAgYXBwbHlTdHlsZShoaXQsIHR5cGUpO1xuXG4gICAgc3ZnQXR0cihoaXQsIGF0dHJzKTtcblxuICAgIGFwcGVuZEhpdChnZngsIGhpdCk7XG5cbiAgICByZXR1cm4gaGl0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgZGVmYXVsdCBoaXQgb2YgdGhlIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gICAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IGdmeFxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSB1cGRhdGVkIGhpdFxuICAgKi9cbiAgdGhpcy51cGRhdGVEZWZhdWx0SGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG5cbiAgICB2YXIgaGl0ID0gZG9tUXVlcnkoJy5kanMtaGl0JywgZ2Z4KTtcblxuICAgIGlmICghaGl0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICB1cGRhdGVMaW5lKGhpdCwgZWxlbWVudC53YXlwb2ludHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdmdBdHRyKGhpdCwge1xuICAgICAgICB3aWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhpdDtcbiAgfTtcblxuICB0aGlzLmZpcmUgPSBmaXJlO1xuXG4gIHRoaXMudHJpZ2dlck1vdXNlRXZlbnQgPSB0cmlnZ2VyTW91c2VFdmVudDtcblxuICB0aGlzLm1vdXNlSGFuZGxlciA9IG1vdXNlSGFuZGxlcjtcblxuICB0aGlzLnJlZ2lzdGVyRXZlbnQgPSByZWdpc3RlckV2ZW50O1xuICB0aGlzLnVucmVnaXN0ZXJFdmVudCA9IHVucmVnaXN0ZXJFdmVudDtcbn1cblxuXG5JbnRlcmFjdGlvbkV2ZW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ3N0eWxlcydcbl07XG5cblxuLyoqXG4gKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vdXNlIGhvdmVyZWQgb3ZlciBhbiBlbGVtZW50XG4gKlxuICogQGV2ZW50IGVsZW1lbnQuaG92ZXJcbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSBnZnhcbiAqIEBwcm9wZXJ0eSB7RXZlbnR9IG9yaWdpbmFsRXZlbnRcbiAqL1xuXG4vKipcbiAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgbW91c2UgaGFzIGxlZnQgYW4gZWxlbWVudFxuICpcbiAqIEBldmVudCBlbGVtZW50Lm91dFxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBtb3VzZSBoYXMgY2xpY2tlZCBhbiBlbGVtZW50XG4gKlxuICogQGV2ZW50IGVsZW1lbnQuY2xpY2tcbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSBnZnhcbiAqIEBwcm9wZXJ0eSB7RXZlbnR9IG9yaWdpbmFsRXZlbnRcbiAqL1xuXG4vKipcbiAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgbW91c2UgaGFzIGRvdWJsZSBjbGlja2VkIGFuIGVsZW1lbnRcbiAqXG4gKiBAZXZlbnQgZWxlbWVudC5kYmxjbGlja1xuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBtb3VzZSBoYXMgZ29uZSBkb3duIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogQGV2ZW50IGVsZW1lbnQubW91c2Vkb3duXG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gZ2Z4XG4gKiBAcHJvcGVydHkge0V2ZW50fSBvcmlnaW5hbEV2ZW50XG4gKi9cblxuLyoqXG4gKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vdXNlIGhhcyBnb25lIHVwIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogQGV2ZW50IGVsZW1lbnQubW91c2V1cFxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBjb250ZXh0IG1lbnUgYWN0aW9uIGlzIHRyaWdnZXJlZFxuICogdmlhIG1vdXNlIG9yIHRvdWNoIGNvbnRyb2xzLlxuICpcbiAqIEBldmVudCBlbGVtZW50LmNvbnRleHRtZW51XG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gZ2Z4XG4gKiBAcHJvcGVydHkge0V2ZW50fSBvcmlnaW5hbEV2ZW50XG4gKi8iLCJpbXBvcnQgSW50ZXJhY3Rpb25FdmVudHMgZnJvbSAnLi9JbnRlcmFjdGlvbkV2ZW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ2ludGVyYWN0aW9uRXZlbnRzJyBdLFxuICBpbnRlcmFjdGlvbkV2ZW50czogWyAndHlwZScsIEludGVyYWN0aW9uRXZlbnRzIF1cbn07IiwiaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG52YXIgREVGQVVMVF9DT05GSUcgPSB7XG4gIG1vdmVTcGVlZDogMSxcbiAgbW92ZVNwZWVkQWNjZWxlcmF0ZWQ6IDEwXG59O1xuXG52YXIgSElHSEVSX1BSSU9SSVRZID0gMTUwMDtcblxudmFyIExFRlQgPSAnbGVmdCc7XG52YXIgVVAgPSAndXAnO1xudmFyIFJJR0hUID0gJ3JpZ2h0JztcbnZhciBET1dOID0gJ2Rvd24nO1xuXG52YXIgS0VZX1RPX0RJUkVDVElPTiA9IHtcbiAgQXJyb3dMZWZ0OiBMRUZULFxuICBMZWZ0OiBMRUZULFxuICBBcnJvd1VwOiBVUCxcbiAgVXA6IFVQLFxuICBBcnJvd1JpZ2h0OiBSSUdIVCxcbiAgUmlnaHQ6IFJJR0hULFxuICBBcnJvd0Rvd246IERPV04sXG4gIERvd246IERPV05cbn07XG5cbnZhciBESVJFQ1RJT05TX0RFTFRBID0ge1xuICBsZWZ0OiBmdW5jdGlvbihzcGVlZCkge1xuICAgIHJldHVybiB7XG4gICAgICB4OiAtc3BlZWQsXG4gICAgICB5OiAwXG4gICAgfTtcbiAgfSxcbiAgdXA6IGZ1bmN0aW9uKHNwZWVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAtc3BlZWRcbiAgICB9O1xuICB9LFxuICByaWdodDogZnVuY3Rpb24oc3BlZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogc3BlZWQsXG4gICAgICB5OiAwXG4gICAgfTtcbiAgfSxcbiAgZG93bjogZnVuY3Rpb24oc3BlZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IHNwZWVkXG4gICAgfTtcbiAgfVxufTtcblxuXG4vKipcbiAqIEVuYWJsZXMgdG8gbW92ZSBzZWxlY3Rpb24gd2l0aCBrZXlib2FyZCBhcnJvd3MuXG4gKiBVc2Ugd2l0aCBTaGlmdCBmb3IgbW9kaWZpZWQgc3BlZWQgKGRlZmF1bHQ9MSwgd2l0aCBTaGlmdD0xMCkuXG4gKiBQcmVzc2VkIENtZC9DdHJsIHR1cm5zIHRoZSBmZWF0dXJlIG9mZi5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmZpZy5tb3ZlU3BlZWQ9MV1cbiAqIEBwYXJhbSB7bnVtYmVyfSBbY29uZmlnLm1vdmVTcGVlZEFjY2VsZXJhdGVkPTEwXVxuICogQHBhcmFtIHtLZXlib2FyZH0ga2V5Ym9hcmRcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKiBAcGFyYW0ge1NlbGVjdGlvbn0gc2VsZWN0aW9uXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIEtleWJvYXJkTW92ZVNlbGVjdGlvbihcbiAgICBjb25maWcsXG4gICAga2V5Ym9hcmQsXG4gICAgbW9kZWxpbmcsXG4gICAgcnVsZXMsXG4gICAgc2VsZWN0aW9uXG4pIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5fY29uZmlnID0gYXNzaWduKHt9LCBERUZBVUxUX0NPTkZJRywgY29uZmlnIHx8IHt9KTtcblxuICBrZXlib2FyZC5hZGRMaXN0ZW5lcihISUdIRVJfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIga2V5RXZlbnQgPSBldmVudC5rZXlFdmVudDtcblxuICAgIHZhciBkaXJlY3Rpb24gPSBLRVlfVE9fRElSRUNUSU9OW2tleUV2ZW50LmtleV07XG5cbiAgICBpZiAoIWRpcmVjdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChrZXlib2FyZC5pc0NtZChrZXlFdmVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgYWNjZWxlcmF0ZWQgPSBrZXlib2FyZC5pc1NoaWZ0KGtleUV2ZW50KTtcblxuICAgIHNlbGYubW92ZVNlbGVjdGlvbihkaXJlY3Rpb24sIGFjY2VsZXJhdGVkKTtcblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcblxuXG4gIC8qKlxuICAgKiBNb3ZlIHNlbGVjdGVkIGVsZW1lbnRzIGluIHRoZSBnaXZlbiBkaXJlY3Rpb24sXG4gICAqIG9wdGlvbmFsbHkgc3BlY2lmeWluZyBhY2NlbGVyYXRlZCBtb3ZlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGRpcmVjdGlvblxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthY2NlbGVyYXRlZD1mYWxzZV1cbiAgICovXG4gIHRoaXMubW92ZVNlbGVjdGlvbiA9IGZ1bmN0aW9uKGRpcmVjdGlvbiwgYWNjZWxlcmF0ZWQpIHtcblxuICAgIHZhciBzZWxlY3RlZEVsZW1lbnRzID0gc2VsZWN0aW9uLmdldCgpO1xuXG4gICAgaWYgKCFzZWxlY3RlZEVsZW1lbnRzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBzcGVlZCA9IHRoaXMuX2NvbmZpZ1tcbiAgICAgIGFjY2VsZXJhdGVkID9cbiAgICAgICAgJ21vdmVTcGVlZEFjY2VsZXJhdGVkJyA6XG4gICAgICAgICdtb3ZlU3BlZWQnXG4gICAgXTtcblxuICAgIHZhciBkZWx0YSA9IERJUkVDVElPTlNfREVMVEFbZGlyZWN0aW9uXShzcGVlZCk7XG5cbiAgICB2YXIgY2FuTW92ZSA9IHJ1bGVzLmFsbG93ZWQoJ2VsZW1lbnRzLm1vdmUnLCB7XG4gICAgICBzaGFwZXM6IHNlbGVjdGVkRWxlbWVudHNcbiAgICB9KTtcblxuICAgIGlmIChjYW5Nb3ZlKSB7XG4gICAgICBtb2RlbGluZy5tb3ZlRWxlbWVudHMoc2VsZWN0ZWRFbGVtZW50cywgZGVsdGEpO1xuICAgIH1cbiAgfTtcblxufVxuXG5LZXlib2FyZE1vdmVTZWxlY3Rpb24uJGluamVjdCA9IFtcbiAgJ2NvbmZpZy5rZXlib2FyZE1vdmVTZWxlY3Rpb24nLFxuICAna2V5Ym9hcmQnLFxuICAnbW9kZWxpbmcnLFxuICAncnVsZXMnLFxuICAnc2VsZWN0aW9uJ1xuXTsiLCJpbXBvcnQgS2V5Ym9hcmRNb2R1bGUgZnJvbSAnLi4va2V5Ym9hcmQnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuXG5pbXBvcnQgS2V5Ym9hcmRNb3ZlU2VsZWN0aW9uIGZyb20gJy4vS2V5Ym9hcmRNb3ZlU2VsZWN0aW9uJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIEtleWJvYXJkTW9kdWxlLFxuICAgIFNlbGVjdGlvbk1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogW1xuICAgICdrZXlib2FyZE1vdmVTZWxlY3Rpb24nXG4gIF0sXG4gIGtleWJvYXJkTW92ZVNlbGVjdGlvbjogWyAndHlwZScsIEtleWJvYXJkTW92ZVNlbGVjdGlvbiBdXG59O1xuIiwiaW1wb3J0IHtcbiAgaXNGdW5jdGlvblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50LFxuICBtYXRjaGVzIGFzIGRvbU1hdGNoZXNcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIGhhc01vZGlmaWVyLFxuICBpc0NtZCxcbiAgaXNLZXksXG4gIGlzU2hpZnRcbn0gZnJvbSAnLi9LZXlib2FyZFV0aWwnO1xuXG52YXIgS0VZRE9XTl9FVkVOVCA9ICdrZXlib2FyZC5rZXlkb3duJyxcbiAgICBLRVlVUF9FVkVOVCA9ICdrZXlib2FyZC5rZXl1cCc7XG5cbnZhciBERUZBVUxUX1BSSU9SSVRZID0gMTAwMDtcblxuXG4vKipcbiAqIEEga2V5Ym9hcmQgYWJzdHJhY3Rpb24gdGhhdCBtYXkgYmUgYWN0aXZhdGVkIGFuZFxuICogZGVhY3RpdmF0ZWQgYnkgdXNlcnMgYXQgd2lsbCwgY29uc3VtaW5nIGtleSBldmVudHNcbiAqIGFuZCB0cmlnZ2VyaW5nIGRpYWdyYW0gYWN0aW9ucy5cbiAqXG4gKiBGb3Iga2V5cyBwcmVzc2VkIGRvd24sIGtleWJvYXJkIGZpcmVzIGBrZXlib2FyZC5rZXlkb3duYCBldmVudC5cbiAqIFRoZSBldmVudCBjb250ZXh0IGNvbnRhaW5zIG9uZSBmaWVsZCB3aGljaCBpcyBgS2V5Ym9hcmRFdmVudGAgZXZlbnQuXG4gKlxuICogVGhlIGltcGxlbWVudGF0aW9uIGZpcmVzIHRoZSBmb2xsb3dpbmcga2V5IGV2ZW50cyB0aGF0IGFsbG93XG4gKiBvdGhlciBjb21wb25lbnRzIHRvIGhvb2sgaW50byBrZXkgaGFuZGxpbmc6XG4gKlxuICogIC0ga2V5Ym9hcmQuYmluZFxuICogIC0ga2V5Ym9hcmQudW5iaW5kXG4gKiAgLSBrZXlib2FyZC5pbml0XG4gKiAgLSBrZXlib2FyZC5kZXN0cm95XG4gKlxuICogQWxsIGV2ZW50cyBjb250YWluIG9uZSBmaWVsZCB3aGljaCBpcyBub2RlLlxuICpcbiAqIEEgZGVmYXVsdCBiaW5kaW5nIGZvciB0aGUga2V5Ym9hcmQgbWF5IGJlIHNwZWNpZmllZCB2aWEgdGhlXG4gKiBga2V5Ym9hcmQuYmluZFRvYCBjb25maWd1cmF0aW9uIG9wdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0NvbmZpZ30gY29uZmlnXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBLZXlib2FyZChjb25maWcsIGV2ZW50QnVzKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9jb25maWcgPSBjb25maWcgfHwge307XG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG5cbiAgdGhpcy5fa2V5ZG93bkhhbmRsZXIgPSB0aGlzLl9rZXlkb3duSGFuZGxlci5iaW5kKHRoaXMpO1xuICB0aGlzLl9rZXl1cEhhbmRsZXIgPSB0aGlzLl9rZXl1cEhhbmRsZXIuYmluZCh0aGlzKTtcblxuICAvLyBwcm9wZXJseSBjbGVhbiBkb20gcmVnaXN0cmF0aW9uc1xuICBldmVudEJ1cy5vbignZGlhZ3JhbS5kZXN0cm95JywgZnVuY3Rpb24oKSB7XG4gICAgc2VsZi5fZmlyZSgnZGVzdHJveScpO1xuXG4gICAgc2VsZi51bmJpbmQoKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2RpYWdyYW0uaW5pdCcsIGZ1bmN0aW9uKCkge1xuICAgIHNlbGYuX2ZpcmUoJ2luaXQnKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2F0dGFjaCcsIGZ1bmN0aW9uKCkge1xuICAgIGlmIChjb25maWcgJiYgY29uZmlnLmJpbmRUbykge1xuICAgICAgc2VsZi5iaW5kKGNvbmZpZy5iaW5kVG8pO1xuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2RldGFjaCcsIGZ1bmN0aW9uKCkge1xuICAgIHNlbGYudW5iaW5kKCk7XG4gIH0pO1xufVxuXG5LZXlib2FyZC4kaW5qZWN0ID0gW1xuICAnY29uZmlnLmtleWJvYXJkJyxcbiAgJ2V2ZW50QnVzJ1xuXTtcblxuS2V5Ym9hcmQucHJvdG90eXBlLl9rZXlkb3duSGFuZGxlciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2tleUhhbmRsZXIoZXZlbnQsIEtFWURPV05fRVZFTlQpO1xufTtcblxuS2V5Ym9hcmQucHJvdG90eXBlLl9rZXl1cEhhbmRsZXIgPSBmdW5jdGlvbihldmVudCkge1xuICB0aGlzLl9rZXlIYW5kbGVyKGV2ZW50LCBLRVlVUF9FVkVOVCk7XG59O1xuXG5LZXlib2FyZC5wcm90b3R5cGUuX2tleUhhbmRsZXIgPSBmdW5jdGlvbihldmVudCwgdHlwZSkge1xuICB2YXIgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0LFxuICAgICAgZXZlbnRCdXNSZXN1bHQ7XG5cbiAgaWYgKGlzSW5wdXQodGFyZ2V0KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGtleUV2ZW50OiBldmVudFxuICB9O1xuXG4gIGV2ZW50QnVzUmVzdWx0ID0gdGhpcy5fZXZlbnRCdXMuZmlyZSh0eXBlIHx8IEtFWURPV05fRVZFTlQsIGNvbnRleHQpO1xuXG4gIGlmIChldmVudEJ1c1Jlc3VsdCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cbn07XG5cbktleWJvYXJkLnByb3RvdHlwZS5iaW5kID0gZnVuY3Rpb24obm9kZSkge1xuXG4gIC8vIG1ha2Ugc3VyZSB0aGF0IHRoZSBrZXlib2FyZCBpcyBvbmx5IGJvdW5kIG9uY2UgdG8gdGhlIERPTVxuICB0aGlzLnVuYmluZCgpO1xuXG4gIHRoaXMuX25vZGUgPSBub2RlO1xuXG4gIC8vIGJpbmQga2V5IGV2ZW50c1xuICBkb21FdmVudC5iaW5kKG5vZGUsICdrZXlkb3duJywgdGhpcy5fa2V5ZG93bkhhbmRsZXIsIHRydWUpO1xuICBkb21FdmVudC5iaW5kKG5vZGUsICdrZXl1cCcsIHRoaXMuX2tleXVwSGFuZGxlciwgdHJ1ZSk7XG5cbiAgdGhpcy5fZmlyZSgnYmluZCcpO1xufTtcblxuS2V5Ym9hcmQucHJvdG90eXBlLmdldEJpbmRpbmcgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX25vZGU7XG59O1xuXG5LZXlib2FyZC5wcm90b3R5cGUudW5iaW5kID0gZnVuY3Rpb24oKSB7XG4gIHZhciBub2RlID0gdGhpcy5fbm9kZTtcblxuICBpZiAobm9kZSkge1xuICAgIHRoaXMuX2ZpcmUoJ3VuYmluZCcpO1xuXG4gICAgLy8gdW5iaW5kIGtleSBldmVudHNcbiAgICBkb21FdmVudC51bmJpbmQobm9kZSwgJ2tleWRvd24nLCB0aGlzLl9rZXlkb3duSGFuZGxlciwgdHJ1ZSk7XG4gICAgZG9tRXZlbnQudW5iaW5kKG5vZGUsICdrZXl1cCcsIHRoaXMuX2tleXVwSGFuZGxlciwgdHJ1ZSk7XG4gIH1cblxuICB0aGlzLl9ub2RlID0gbnVsbDtcbn07XG5cbktleWJvYXJkLnByb3RvdHlwZS5fZmlyZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ2tleWJvYXJkLicgKyBldmVudCwgeyBub2RlOiB0aGlzLl9ub2RlIH0pO1xufTtcblxuLyoqXG4gKiBBZGQgYSBsaXN0ZW5lciBmdW5jdGlvbiB0aGF0IGlzIG5vdGlmaWVkIHdpdGggYEtleWJvYXJkRXZlbnRgIHdoZW5ldmVyXG4gKiB0aGUga2V5Ym9hcmQgaXMgYm91bmQgYW5kIHRoZSB1c2VyIHByZXNzZXMgYSBrZXkuIElmIG5vIHByaW9yaXR5IGlzXG4gKiBwcm92aWRlZCwgdGhlIGRlZmF1bHQgdmFsdWUgb2YgMTAwMCBpcyB1c2VkLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBbcHJpb3JpdHldXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBsaXN0ZW5lclxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGVcbiAqL1xuS2V5Ym9hcmQucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24ocHJpb3JpdHksIGxpc3RlbmVyLCB0eXBlKSB7XG4gIGlmIChpc0Z1bmN0aW9uKHByaW9yaXR5KSkge1xuICAgIHR5cGUgPSBsaXN0ZW5lcjtcbiAgICBsaXN0ZW5lciA9IHByaW9yaXR5O1xuICAgIHByaW9yaXR5ID0gREVGQVVMVF9QUklPUklUWTtcbiAgfVxuXG4gIHRoaXMuX2V2ZW50QnVzLm9uKHR5cGUgfHwgS0VZRE9XTl9FVkVOVCwgcHJpb3JpdHksIGxpc3RlbmVyKTtcbn07XG5cbktleWJvYXJkLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uKGxpc3RlbmVyLCB0eXBlKSB7XG4gIHRoaXMuX2V2ZW50QnVzLm9mZih0eXBlIHx8IEtFWURPV05fRVZFTlQsIGxpc3RlbmVyKTtcbn07XG5cbktleWJvYXJkLnByb3RvdHlwZS5oYXNNb2RpZmllciA9IGhhc01vZGlmaWVyO1xuS2V5Ym9hcmQucHJvdG90eXBlLmlzQ21kID0gaXNDbWQ7XG5LZXlib2FyZC5wcm90b3R5cGUuaXNTaGlmdCA9IGlzU2hpZnQ7XG5LZXlib2FyZC5wcm90b3R5cGUuaXNLZXkgPSBpc0tleTtcblxuXG5cbi8vIGhlbHBlcnMgLy8vLy8vL1xuXG5mdW5jdGlvbiBpc0lucHV0KHRhcmdldCkge1xuICByZXR1cm4gdGFyZ2V0ICYmIChkb21NYXRjaGVzKHRhcmdldCwgJ2lucHV0LCB0ZXh0YXJlYScpIHx8IHRhcmdldC5jb250ZW50RWRpdGFibGUgPT09ICd0cnVlJyk7XG59XG4iLCJpbXBvcnQge1xuICBpc0NtZCxcbiAgaXNLZXksXG4gIGlzU2hpZnRcbn0gZnJvbSAnLi9LZXlib2FyZFV0aWwnO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gNTAwO1xuXG5leHBvcnQgdmFyIEtFWUNPREVfQyA9IDY3O1xuZXhwb3J0IHZhciBLRVlDT0RFX1YgPSA4NjtcbmV4cG9ydCB2YXIgS0VZQ09ERV9ZID0gODk7XG5leHBvcnQgdmFyIEtFWUNPREVfWiA9IDkwO1xuXG5leHBvcnQgdmFyIEtFWVNfQ09QWSA9IFsnYycsICdDJywgS0VZQ09ERV9DIF07XG5leHBvcnQgdmFyIEtFWVNfUEFTVEUgPSBbICd2JywgJ1YnLCBLRVlDT0RFX1YgXTtcbmV4cG9ydCB2YXIgS0VZU19SRURPID0gWyAneScsICdZJywgS0VZQ09ERV9ZIF07XG5leHBvcnQgdmFyIEtFWVNfVU5ETyA9IFsgJ3onLCAnWicsIEtFWUNPREVfWiBdO1xuXG5cbi8qKlxuICogQWRkcyBkZWZhdWx0IGtleWJvYXJkIGJpbmRpbmdzLlxuICpcbiAqIFRoaXMgZG9lcyBub3QgcHVsbCBpbiBhbnkgZmVhdHVyZXMgd2lsbCBiaW5kIG9ubHkgYWN0aW9ucyB0aGF0XG4gKiBoYXZlIHByZXZpb3VzbHkgYmVlbiByZWdpc3RlcmVkIGFnYWluc3QgdGhlIGVkaXRvckFjdGlvbnMgY29tcG9uZW50LlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0tleWJvYXJkfSBrZXlib2FyZFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBLZXlib2FyZEJpbmRpbmdzKGV2ZW50QnVzLCBrZXlib2FyZCkge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbignZWRpdG9yQWN0aW9ucy5pbml0JywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGVkaXRvckFjdGlvbnMgPSBldmVudC5lZGl0b3JBY3Rpb25zO1xuXG4gICAgc2VsZi5yZWdpc3RlckJpbmRpbmdzKGtleWJvYXJkLCBlZGl0b3JBY3Rpb25zKTtcbiAgfSk7XG59XG5cbktleWJvYXJkQmluZGluZ3MuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2tleWJvYXJkJ1xuXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVyIGF2YWlsYWJsZSBrZXlib2FyZCBiaW5kaW5ncy5cbiAqXG4gKiBAcGFyYW0ge0tleWJvYXJkfSBrZXlib2FyZFxuICogQHBhcmFtIHtFZGl0b3JBY3Rpb25zfSBlZGl0b3JBY3Rpb25zXG4gKi9cbktleWJvYXJkQmluZGluZ3MucHJvdG90eXBlLnJlZ2lzdGVyQmluZGluZ3MgPSBmdW5jdGlvbihrZXlib2FyZCwgZWRpdG9yQWN0aW9ucykge1xuXG4gIC8qKlxuICAgKiBBZGQga2V5Ym9hcmQgYmluZGluZyBpZiByZXNwZWN0aXZlIGVkaXRvciBhY3Rpb25cbiAgICogaXMgcmVnaXN0ZXJlZC5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbiBuYW1lXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIHRoYXQgaW1wbGVtZW50cyB0aGUga2V5IGJpbmRpbmdcbiAgICovXG4gIGZ1bmN0aW9uIGFkZExpc3RlbmVyKGFjdGlvbiwgZm4pIHtcblxuICAgIGlmIChlZGl0b3JBY3Rpb25zLmlzUmVnaXN0ZXJlZChhY3Rpb24pKSB7XG4gICAgICBrZXlib2FyZC5hZGRMaXN0ZW5lcihmbik7XG4gICAgfVxuICB9XG5cblxuICAvLyB1bmRvXG4gIC8vIChDVFJMfENNRCkgKyBaXG4gIGFkZExpc3RlbmVyKCd1bmRvJywgZnVuY3Rpb24oY29udGV4dCkge1xuXG4gICAgdmFyIGV2ZW50ID0gY29udGV4dC5rZXlFdmVudDtcblxuICAgIGlmIChpc0NtZChldmVudCkgJiYgIWlzU2hpZnQoZXZlbnQpICYmIGlzS2V5KEtFWVNfVU5ETywgZXZlbnQpKSB7XG4gICAgICBlZGl0b3JBY3Rpb25zLnRyaWdnZXIoJ3VuZG8nKTtcblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9KTtcblxuICAvLyByZWRvXG4gIC8vIENUUkwgKyBZXG4gIC8vIENNRCArIFNISUZUICsgWlxuICBhZGRMaXN0ZW5lcigncmVkbycsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNDbWQoZXZlbnQpICYmIChpc0tleShLRVlTX1JFRE8sIGV2ZW50KSB8fCAoaXNLZXkoS0VZU19VTkRPLCBldmVudCkgJiYgaXNTaGlmdChldmVudCkpKSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdyZWRvJyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gY29weVxuICAvLyBDVFJML0NNRCArIENcbiAgYWRkTGlzdGVuZXIoJ2NvcHknLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGlzQ21kKGV2ZW50KSAmJiBpc0tleShLRVlTX0NPUFksIGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdjb3B5Jyk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gcGFzdGVcbiAgLy8gQ1RSTC9DTUQgKyBWXG4gIGFkZExpc3RlbmVyKCdwYXN0ZScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNDbWQoZXZlbnQpICYmIGlzS2V5KEtFWVNfUEFTVEUsIGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdwYXN0ZScpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHpvb20gaW4gb25lIHN0ZXBcbiAgLy8gQ1RSTC9DTUQgKyArXG4gIGFkZExpc3RlbmVyKCdzdGVwWm9vbScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNLZXkoWyAnKycsICdBZGQnIF0sIGV2ZW50KSAmJiBpc0NtZChldmVudCkpIHtcbiAgICAgIGVkaXRvckFjdGlvbnMudHJpZ2dlcignc3RlcFpvb20nLCB7IHZhbHVlOiAxIH0pO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHpvb20gb3V0IG9uZSBzdGVwXG4gIC8vIENUUkwgKyAtXG4gIGFkZExpc3RlbmVyKCdzdGVwWm9vbScsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNLZXkoWyAnLScsICdTdWJ0cmFjdCcgXSwgZXZlbnQpICYmIGlzQ21kKGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCdzdGVwWm9vbScsIHsgdmFsdWU6IC0xIH0pO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHpvb20gdG8gdGhlIGRlZmF1bHQgbGV2ZWxcbiAgLy8gQ1RSTCArIDBcbiAgYWRkTGlzdGVuZXIoJ3pvb20nLCBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgICB2YXIgZXZlbnQgPSBjb250ZXh0LmtleUV2ZW50O1xuXG4gICAgaWYgKGlzS2V5KCcwJywgZXZlbnQpICYmIGlzQ21kKGV2ZW50KSkge1xuICAgICAgZWRpdG9yQWN0aW9ucy50cmlnZ2VyKCd6b29tJywgeyB2YWx1ZTogMSB9KTtcblxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9KTtcblxuICAvLyBkZWxldGUgc2VsZWN0ZWQgZWxlbWVudFxuICAvLyBERUxcbiAgYWRkTGlzdGVuZXIoJ3JlbW92ZVNlbGVjdGlvbicsIGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQ7XG5cbiAgICBpZiAoaXNLZXkoWydCYWNrc3BhY2UnLCAnRGVsZXRlJywgJ0RlbCcgXSwgZXZlbnQpKSB7XG4gICAgICBlZGl0b3JBY3Rpb25zLnRyaWdnZXIoJ3JlbW92ZVNlbGVjdGlvbicpO1xuXG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xufTsiLCJpbXBvcnQgeyBpc0FycmF5IH0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgdHJ1ZSBpZiBldmVudCB3YXMgdHJpZ2dlcmVkIHdpdGggYW55IG1vZGlmaWVyXHJcbiAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudH0gZXZlbnRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBoYXNNb2RpZmllcihldmVudCkge1xyXG4gIHJldHVybiAoZXZlbnQuY3RybEtleSB8fCBldmVudC5tZXRhS2V5IHx8IGV2ZW50LnNoaWZ0S2V5IHx8IGV2ZW50LmFsdEtleSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge0tleWJvYXJkRXZlbnR9IGV2ZW50XHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNDbWQoZXZlbnQpIHtcclxuXHJcbiAgLy8gZW5zdXJlIHdlIGRvbid0IHJlYWN0IHRvIEFsdEdyXHJcbiAgLy8gKG1hcHBlZCB0byBDVFJMICsgQUxUKVxyXG4gIGlmIChldmVudC5hbHRLZXkpIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIHJldHVybiBldmVudC5jdHJsS2V5IHx8IGV2ZW50Lm1ldGFLZXk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgaWYga2V5IHByZXNzZWQgaXMgb25lIG9mIHByb3ZpZGVkIGtleXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7c3RyaW5nfEFycmF5PHN0cmluZz59IGtleXNcclxuICogQHBhcmFtIHtLZXlib2FyZEV2ZW50fSBldmVudFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGlzS2V5KGtleXMsIGV2ZW50KSB7XHJcbiAga2V5cyA9IGlzQXJyYXkoa2V5cykgPyBrZXlzIDogWyBrZXlzIF07XHJcblxyXG4gIHJldHVybiBrZXlzLmluZGV4T2YoZXZlbnQua2V5KSAhPT0gLTEgfHwga2V5cy5pbmRleE9mKGV2ZW50LmtleUNvZGUpICE9PSAtMTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7S2V5Ym9hcmRFdmVudH0gZXZlbnRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc1NoaWZ0KGV2ZW50KSB7XHJcbiAgcmV0dXJuIGV2ZW50LnNoaWZ0S2V5O1xyXG59IiwiaW1wb3J0IEtleWJvYXJkIGZyb20gJy4vS2V5Ym9hcmQnO1xuaW1wb3J0IEtleWJvYXJkQmluZGluZ3MgZnJvbSAnLi9LZXlib2FyZEJpbmRpbmdzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAna2V5Ym9hcmQnLCAna2V5Ym9hcmRCaW5kaW5ncycgXSxcbiAga2V5Ym9hcmQ6IFsgJ3R5cGUnLCBLZXlib2FyZCBdLFxuICBrZXlib2FyZEJpbmRpbmdzOiBbICd0eXBlJywgS2V5Ym9hcmRCaW5kaW5ncyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgZm9yRWFjaCxcbiAgZmlsdGVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxudmFyIExPV19QUklPUklUWSA9IDI1MCxcbiAgICBISUdIX1BSSU9SSVRZID0gMTQwMDtcblxuaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIGluZGV4T2YgYXMgY29sbGVjdGlvbklkeFxufSBmcm9tICcuLi8uLi91dGlsL0NvbGxlY3Rpb25zJztcblxuaW1wb3J0IHsgc2F2ZUNsZWFyIH0gZnJvbSAnLi4vLi4vdXRpbC9SZW1vdmFsJztcblxuaW1wb3J0IENvbW1hbmRJbnRlcmNlcHRvciBmcm9tICcuLi8uLi9jb21tYW5kL0NvbW1hbmRJbnRlcmNlcHRvcic7XG5cblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBtYWtlcyBzdXJlIGxhYmVscyBhcmUgcHJvcGVybHkgbW92ZWQgd2l0aFxuICogdGhlaXIgbGFiZWwgdGFyZ2V0cy5cbiAqXG4gKiBAcGFyYW0ge2RpZGkuSW5qZWN0b3J9IGluamVjdG9yXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGFiZWxTdXBwb3J0KGluamVjdG9yLCBldmVudEJ1cywgbW9kZWxpbmcpIHtcblxuICBDb21tYW5kSW50ZXJjZXB0b3IuY2FsbCh0aGlzLCBldmVudEJ1cyk7XG5cbiAgdmFyIG1vdmVQcmV2aWV3ID0gaW5qZWN0b3IuZ2V0KCdtb3ZlUHJldmlldycsIGZhbHNlKTtcblxuICAvLyByZW1vdmUgbGFiZWxzIGZyb20gdGhlIGNvbGxlY3Rpb24gdGhhdCBhcmUgYmVpbmdcbiAgLy8gbW92ZWQgd2l0aCBvdGhlciBlbGVtZW50cyBhbnl3YXlcbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUuc3RhcnQnLCBISUdIX1BSSU9SSVRZLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgc2hhcGVzID0gY29udGV4dC5zaGFwZXMsXG4gICAgICAgIHZhbGlkYXRlZFNoYXBlcyA9IGNvbnRleHQudmFsaWRhdGVkU2hhcGVzO1xuXG4gICAgY29udGV4dC5zaGFwZXMgPSByZW1vdmVMYWJlbHMoc2hhcGVzKTtcbiAgICBjb250ZXh0LnZhbGlkYXRlZFNoYXBlcyA9IHJlbW92ZUxhYmVscyh2YWxpZGF0ZWRTaGFwZXMpO1xuICB9KTtcblxuICAvLyBhZGQgbGFiZWxzIHRvIHZpc3VhbCdzIGdyb3VwXG4gIG1vdmVQcmV2aWV3ICYmIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLnN0YXJ0JywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgc2hhcGVzID0gY29udGV4dC5zaGFwZXM7XG5cbiAgICB2YXIgbGFiZWxzID0gW107XG5cbiAgICBmb3JFYWNoKHNoYXBlcywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgICBmb3JFYWNoKGVsZW1lbnQubGFiZWxzLCBmdW5jdGlvbihsYWJlbCkge1xuXG4gICAgICAgIGlmICghbGFiZWwuaGlkZGVuICYmIGNvbnRleHQuc2hhcGVzLmluZGV4T2YobGFiZWwpID09PSAtMSkge1xuICAgICAgICAgIGxhYmVscy5wdXNoKGxhYmVsKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbGVtZW50LmxhYmVsVGFyZ2V0KSB7XG4gICAgICAgICAgbGFiZWxzLnB1c2goZWxlbWVudCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgZm9yRWFjaChsYWJlbHMsIGZ1bmN0aW9uKGxhYmVsKSB7XG4gICAgICBtb3ZlUHJldmlldy5tYWtlRHJhZ2dhYmxlKGNvbnRleHQsIGxhYmVsLCB0cnVlKTtcbiAgICB9KTtcblxuICB9KTtcblxuICAvLyBhZGQgYWxsIGxhYmVscyB0byBtb3ZlIGNsb3N1cmVcbiAgdGhpcy5wcmVFeGVjdXRlZCgnZWxlbWVudHMubW92ZScsIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgY2xvc3VyZSA9IGNvbnRleHQuY2xvc3VyZSxcbiAgICAgICAgZW5jbG9zZWRFbGVtZW50cyA9IGNsb3N1cmUuZW5jbG9zZWRFbGVtZW50cztcblxuICAgIHZhciBlbmNsb3NlZExhYmVscyA9IFtdO1xuXG4gICAgLy8gZmluZCBsYWJlbHMgdGhhdCBhcmUgbm90IHBhcnQgb2ZcbiAgICAvLyBtb3ZlIGNsb3N1cmUgeWV0IGFuZCBhZGQgdGhlbVxuICAgIGZvckVhY2goZW5jbG9zZWRFbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgZm9yRWFjaChlbGVtZW50LmxhYmVscywgZnVuY3Rpb24obGFiZWwpIHtcblxuICAgICAgICBpZiAoIWVuY2xvc2VkRWxlbWVudHNbbGFiZWwuaWRdKSB7XG4gICAgICAgICAgZW5jbG9zZWRMYWJlbHMucHVzaChsYWJlbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgY2xvc3VyZS5hZGRBbGwoZW5jbG9zZWRMYWJlbHMpO1xuICB9KTtcblxuXG4gIHRoaXMucHJlRXhlY3V0ZShbXG4gICAgJ2Nvbm5lY3Rpb24uZGVsZXRlJyxcbiAgICAnc2hhcGUuZGVsZXRlJ1xuICBdLCBmdW5jdGlvbihlKSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGUuY29udGV4dCxcbiAgICAgICAgZWxlbWVudCA9IGNvbnRleHQuY29ubmVjdGlvbiB8fCBjb250ZXh0LnNoYXBlO1xuXG4gICAgc2F2ZUNsZWFyKGVsZW1lbnQubGFiZWxzLCBmdW5jdGlvbihsYWJlbCkge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlU2hhcGUobGFiZWwsIHsgbmVzdGVkOiB0cnVlIH0pO1xuICAgIH0pO1xuICB9KTtcblxuXG4gIHRoaXMuZXhlY3V0ZSgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgbGFiZWxUYXJnZXQgPSBzaGFwZS5sYWJlbFRhcmdldDtcblxuICAgIC8vIHVuc2V0IGxhYmVsVGFyZ2V0XG4gICAgaWYgKGxhYmVsVGFyZ2V0KSB7XG4gICAgICBjb250ZXh0LmxhYmVsVGFyZ2V0SW5kZXggPSBjb2xsZWN0aW9uSWR4KGxhYmVsVGFyZ2V0LmxhYmVscywgc2hhcGUpO1xuICAgICAgY29udGV4dC5sYWJlbFRhcmdldCA9IGxhYmVsVGFyZ2V0O1xuXG4gICAgICBzaGFwZS5sYWJlbFRhcmdldCA9IG51bGw7XG4gICAgfVxuICB9KTtcblxuICB0aGlzLnJldmVydCgnc2hhcGUuZGVsZXRlJywgZnVuY3Rpb24oZSkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBlLmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgbGFiZWxUYXJnZXQgPSBjb250ZXh0LmxhYmVsVGFyZ2V0LFxuICAgICAgICBsYWJlbFRhcmdldEluZGV4ID0gY29udGV4dC5sYWJlbFRhcmdldEluZGV4O1xuXG4gICAgLy8gcmVzdG9yZSBsYWJlbFRhcmdldFxuICAgIGlmIChsYWJlbFRhcmdldCkge1xuICAgICAgY29sbGVjdGlvbkFkZChsYWJlbFRhcmdldC5sYWJlbHMsIHNoYXBlLCBsYWJlbFRhcmdldEluZGV4KTtcblxuICAgICAgc2hhcGUubGFiZWxUYXJnZXQgPSBsYWJlbFRhcmdldDtcbiAgICB9XG4gIH0pO1xuXG59XG5cbmluaGVyaXRzKExhYmVsU3VwcG9ydCwgQ29tbWFuZEludGVyY2VwdG9yKTtcblxuTGFiZWxTdXBwb3J0LiRpbmplY3QgPSBbXG4gICdpbmplY3RvcicsXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZydcbl07XG5cblxuLyoqXG4gKiBSZXR1cm4gYSBmaWx0ZXJlZCBsaXN0IG9mIGVsZW1lbnRzIHRoYXQgZG8gbm90XG4gKiBjb250YWluIGF0dGFjaGVkIGVsZW1lbnRzIHdpdGggaG9zdHMgYmVpbmcgcGFydFxuICogb2YgdGhlIHNlbGVjdGlvbi5cbiAqXG4gKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGVsZW1lbnRzXG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBmaWx0ZXJlZFxuICovXG5mdW5jdGlvbiByZW1vdmVMYWJlbHMoZWxlbWVudHMpIHtcblxuICByZXR1cm4gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgICAvLyBmaWx0ZXIgb3V0IGxhYmVscyB0aGF0IGFyZSBtb3ZlIHRvZ2V0aGVyXG4gICAgLy8gd2l0aCB0aGVpciBsYWJlbCB0YXJnZXRzXG4gICAgcmV0dXJuIGVsZW1lbnRzLmluZGV4T2YoZWxlbWVudC5sYWJlbFRhcmdldCkgPT09IC0xO1xuICB9KTtcbn1cbiIsImltcG9ydCBMYWJlbFN1cHBvcnQgZnJvbSAnLi9MYWJlbFN1cHBvcnQnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdsYWJlbFN1cHBvcnQnXSxcbiAgbGFiZWxTdXBwb3J0OiBbICd0eXBlJywgTGFiZWxTdXBwb3J0IF1cbn07XG4iLCJpbXBvcnQgeyB2YWx1ZXMgfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7IGdldEVuY2xvc2VkRWxlbWVudHMgfSBmcm9tICcuLi8uLi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IHsgaGFzU2Vjb25kYXJ5TW9kaWZpZXIgfSBmcm9tICcuLi8uLi91dGlsL01vdXNlJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICByZW1vdmUgYXMgc3ZnUmVtb3ZlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxudmFyIExBU1NPX1RPT0xfQ1VSU09SID0gJ2Nyb3NzaGFpcic7XG5cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTGFzc29Ub29sKFxuICAgIGV2ZW50QnVzLCBjYW52YXMsIGRyYWdnaW5nLFxuICAgIGVsZW1lbnRSZWdpc3RyeSwgc2VsZWN0aW9uLCB0b29sTWFuYWdlcikge1xuXG4gIHRoaXMuX3NlbGVjdGlvbiA9IHNlbGVjdGlvbjtcbiAgdGhpcy5fZHJhZ2dpbmcgPSBkcmFnZ2luZztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgLy8gbGFzc28gdmlzdWFscyBpbXBsZW1lbnRhdGlvblxuXG4gIC8qKlxuICAqIEEgaGVscGVyIHRoYXQgcmVhbGl6ZXMgdGhlIHNlbGVjdGlvbiBib3ggdmlzdWFsXG4gICovXG4gIHZhciB2aXN1YWxzID0ge1xuXG4gICAgY3JlYXRlOiBmdW5jdGlvbihjb250ZXh0KSB7XG4gICAgICB2YXIgY29udGFpbmVyID0gY2FudmFzLmdldERlZmF1bHRMYXllcigpLFxuICAgICAgICAgIGZyYW1lO1xuXG4gICAgICBmcmFtZSA9IGNvbnRleHQuZnJhbWUgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcbiAgICAgIHN2Z0F0dHIoZnJhbWUsIHtcbiAgICAgICAgY2xhc3M6ICdkanMtbGFzc28tb3ZlcmxheScsXG4gICAgICAgIHdpZHRoOiAgMSxcbiAgICAgICAgaGVpZ2h0OiAxLFxuICAgICAgICB4OiAwLFxuICAgICAgICB5OiAwXG4gICAgICB9KTtcblxuICAgICAgc3ZnQXBwZW5kKGNvbnRhaW5lciwgZnJhbWUpO1xuICAgIH0sXG5cbiAgICB1cGRhdGU6IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgICAgIHZhciBmcmFtZSA9IGNvbnRleHQuZnJhbWUsXG4gICAgICAgICAgYmJveCA9IGNvbnRleHQuYmJveDtcblxuICAgICAgc3ZnQXR0cihmcmFtZSwge1xuICAgICAgICB4OiBiYm94LngsXG4gICAgICAgIHk6IGJib3gueSxcbiAgICAgICAgd2lkdGg6IGJib3gud2lkdGgsXG4gICAgICAgIGhlaWdodDogYmJveC5oZWlnaHRcbiAgICAgIH0pO1xuICAgIH0sXG5cbiAgICByZW1vdmU6IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICAgICAgaWYgKGNvbnRleHQuZnJhbWUpIHtcbiAgICAgICAgc3ZnUmVtb3ZlKGNvbnRleHQuZnJhbWUpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICB0b29sTWFuYWdlci5yZWdpc3RlclRvb2woJ2xhc3NvJywge1xuICAgIHRvb2w6ICdsYXNzby5zZWxlY3Rpb24nLFxuICAgIGRyYWdnaW5nOiAnbGFzc28nXG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdsYXNzby5zZWxlY3Rpb24uZW5kJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gZXZlbnQub3JpZ2luYWxFdmVudC50YXJnZXQ7XG5cbiAgICAvLyBvbmx5IHJlYWN0aXZlIG9uIGRpYWdyYW0gY2xpY2tcbiAgICAvLyBvbiBzb21lIG9jY2FzaW9ucywgZXZlbnQuaG92ZXIgaXMgbm90IHNldCBhbmQgd2UgaGF2ZSB0byBjaGVjayBpZiB0aGUgdGFyZ2V0IGlzIGFuIHN2Z1xuICAgIGlmICghZXZlbnQuaG92ZXIgJiYgISh0YXJnZXQgaW5zdGFuY2VvZiBTVkdFbGVtZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGV2ZW50QnVzLm9uY2UoJ2xhc3NvLnNlbGVjdGlvbi5lbmRlZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgc2VsZi5hY3RpdmF0ZUxhc3NvKGV2ZW50Lm9yaWdpbmFsRXZlbnQsIHRydWUpO1xuICAgIH0pO1xuICB9KTtcblxuICAvLyBsYXNzbyBpbnRlcmFjdGlvbiBpbXBsZW1lbnRhdGlvblxuXG4gIGV2ZW50QnVzLm9uKCdsYXNzby5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGJib3ggPSB0b0JCb3goZXZlbnQpO1xuXG4gICAgdmFyIGVsZW1lbnRzID0gZWxlbWVudFJlZ2lzdHJ5LmZpbHRlcihmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgICByZXR1cm4gZWxlbWVudDtcbiAgICB9KTtcblxuICAgIHNlbGYuc2VsZWN0KGVsZW1lbnRzLCBiYm94KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2xhc3NvLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dDtcblxuICAgIGNvbnRleHQuYmJveCA9IHRvQkJveChldmVudCk7XG4gICAgdmlzdWFscy5jcmVhdGUoY29udGV4dCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdsYXNzby5tb3ZlJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dDtcblxuICAgIGNvbnRleHQuYmJveCA9IHRvQkJveChldmVudCk7XG4gICAgdmlzdWFscy51cGRhdGUoY29udGV4dCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdsYXNzby5jbGVhbnVwJywgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dDtcblxuICAgIHZpc3VhbHMucmVtb3ZlKGNvbnRleHQpO1xuICB9KTtcblxuXG4gIC8vIGV2ZW50IGludGVncmF0aW9uXG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQubW91c2Vkb3duJywgMTUwMCwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIGlmIChoYXNTZWNvbmRhcnlNb2RpZmllcihldmVudCkpIHtcbiAgICAgIHNlbGYuYWN0aXZhdGVMYXNzbyhldmVudC5vcmlnaW5hbEV2ZW50KTtcblxuICAgICAgLy8gd2UndmUgaGFuZGxlZCB0aGUgZXZlbnRcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG59XG5cbkxhc3NvVG9vbC4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ2RyYWdnaW5nJyxcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXG4gICdzZWxlY3Rpb24nLFxuICAndG9vbE1hbmFnZXInXG5dO1xuXG5cbkxhc3NvVG9vbC5wcm90b3R5cGUuYWN0aXZhdGVMYXNzbyA9IGZ1bmN0aW9uKGV2ZW50LCBhdXRvQWN0aXZhdGUpIHtcblxuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnbGFzc28nLCB7XG4gICAgYXV0b0FjdGl2YXRlOiBhdXRvQWN0aXZhdGUsXG4gICAgY3Vyc29yOiBMQVNTT19UT09MX0NVUlNPUixcbiAgICBkYXRhOiB7XG4gICAgICBjb250ZXh0OiB7fVxuICAgIH1cbiAgfSk7XG59O1xuXG5MYXNzb1Rvb2wucHJvdG90eXBlLmFjdGl2YXRlU2VsZWN0aW9uID0gZnVuY3Rpb24oZXZlbnQpIHtcblxuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnbGFzc28uc2VsZWN0aW9uJywge1xuICAgIHRyYXBDbGljazogZmFsc2UsXG4gICAgY3Vyc29yOiBMQVNTT19UT09MX0NVUlNPUixcbiAgICBkYXRhOiB7XG4gICAgICBjb250ZXh0OiB7fVxuICAgIH1cbiAgfSk7XG59O1xuXG5MYXNzb1Rvb2wucHJvdG90eXBlLnNlbGVjdCA9IGZ1bmN0aW9uKGVsZW1lbnRzLCBiYm94KSB7XG4gIHZhciBzZWxlY3RlZEVsZW1lbnRzID0gZ2V0RW5jbG9zZWRFbGVtZW50cyhlbGVtZW50cywgYmJveCk7XG5cbiAgdGhpcy5fc2VsZWN0aW9uLnNlbGVjdCh2YWx1ZXMoc2VsZWN0ZWRFbGVtZW50cykpO1xufTtcblxuTGFzc29Ub29sLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuaXNBY3RpdmUoKSkge1xuICAgIHRoaXMuX2RyYWdnaW5nLmNhbmNlbCgpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuYWN0aXZhdGVTZWxlY3Rpb24oKTtcbiAgfVxufTtcblxuTGFzc29Ub29sLnByb3RvdHlwZS5pc0FjdGl2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29udGV4dCA9IHRoaXMuX2RyYWdnaW5nLmNvbnRleHQoKTtcblxuICByZXR1cm4gY29udGV4dCAmJiAvXmxhc3NvLy50ZXN0KGNvbnRleHQucHJlZml4KTtcbn07XG5cblxuXG5mdW5jdGlvbiB0b0JCb3goZXZlbnQpIHtcblxuICB2YXIgc3RhcnQgPSB7XG5cbiAgICB4OiBldmVudC54IC0gZXZlbnQuZHgsXG4gICAgeTogZXZlbnQueSAtIGV2ZW50LmR5XG4gIH07XG5cbiAgdmFyIGVuZCA9IHtcbiAgICB4OiBldmVudC54LFxuICAgIHk6IGV2ZW50LnlcbiAgfTtcblxuICB2YXIgYmJveDtcblxuICBpZiAoKHN0YXJ0LnggPD0gZW5kLnggJiYgc3RhcnQueSA8IGVuZC55KSB8fFxuICAgICAgKHN0YXJ0LnggPCBlbmQueCAmJiBzdGFydC55IDw9IGVuZC55KSkge1xuXG4gICAgYmJveCA9IHtcbiAgICAgIHg6IHN0YXJ0LngsXG4gICAgICB5OiBzdGFydC55LFxuICAgICAgd2lkdGg6ICBlbmQueCAtIHN0YXJ0LngsXG4gICAgICBoZWlnaHQ6IGVuZC55IC0gc3RhcnQueVxuICAgIH07XG4gIH0gZWxzZSBpZiAoKHN0YXJ0LnggPj0gZW5kLnggJiYgc3RhcnQueSA8IGVuZC55KSB8fFxuICAgICAgICAgICAgIChzdGFydC54ID4gZW5kLnggJiYgc3RhcnQueSA8PSBlbmQueSkpIHtcblxuICAgIGJib3ggPSB7XG4gICAgICB4OiBlbmQueCxcbiAgICAgIHk6IHN0YXJ0LnksXG4gICAgICB3aWR0aDogIHN0YXJ0LnggLSBlbmQueCxcbiAgICAgIGhlaWdodDogZW5kLnkgLSBzdGFydC55XG4gICAgfTtcbiAgfSBlbHNlIGlmICgoc3RhcnQueCA8PSBlbmQueCAmJiBzdGFydC55ID4gZW5kLnkpIHx8XG4gICAgICAgICAgICAgKHN0YXJ0LnggPCBlbmQueCAmJiBzdGFydC55ID49IGVuZC55KSkge1xuXG4gICAgYmJveCA9IHtcbiAgICAgIHg6IHN0YXJ0LngsXG4gICAgICB5OiBlbmQueSxcbiAgICAgIHdpZHRoOiAgZW5kLnggLSBzdGFydC54LFxuICAgICAgaGVpZ2h0OiBzdGFydC55IC0gZW5kLnlcbiAgICB9O1xuICB9IGVsc2UgaWYgKChzdGFydC54ID49IGVuZC54ICYmIHN0YXJ0LnkgPiBlbmQueSkgfHxcbiAgICAgICAgICAgICAoc3RhcnQueCA+IGVuZC54ICYmIHN0YXJ0LnkgPj0gZW5kLnkpKSB7XG5cbiAgICBiYm94ID0ge1xuICAgICAgeDogZW5kLngsXG4gICAgICB5OiBlbmQueSxcbiAgICAgIHdpZHRoOiAgc3RhcnQueCAtIGVuZC54LFxuICAgICAgaGVpZ2h0OiBzdGFydC55IC0gZW5kLnlcbiAgICB9O1xuICB9IGVsc2Uge1xuXG4gICAgYmJveCA9IHtcbiAgICAgIHg6IGVuZC54LFxuICAgICAgeTogZW5kLnksXG4gICAgICB3aWR0aDogIDAsXG4gICAgICBoZWlnaHQ6IDBcbiAgICB9O1xuICB9XG4gIHJldHVybiBiYm94O1xufVxuIiwiaW1wb3J0IFRvb2xNYW5hZ2VyTW9kdWxlIGZyb20gJy4uL3Rvb2wtbWFuYWdlcic7XG5cbmltcG9ydCBMYXNzb1Rvb2wgZnJvbSAnLi9MYXNzb1Rvb2wnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgVG9vbE1hbmFnZXJNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ2xhc3NvVG9vbCcgXSxcbiAgbGFzc29Ub29sOiBbICd0eXBlJywgTGFzc29Ub29sIF1cbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIGlzQXJyYXlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBCYXNlXG59IGZyb20gJy4uLy4uL21vZGVsJztcblxuaW1wb3J0IEFsaWduRWxlbWVudHNIYW5kbGVyIGZyb20gJy4vY21kL0FsaWduRWxlbWVudHNIYW5kbGVyJztcbmltcG9ydCBBcHBlbmRTaGFwZUhhbmRsZXIgZnJvbSAnLi9jbWQvQXBwZW5kU2hhcGVIYW5kbGVyJztcbmltcG9ydCBDcmVhdGVDb25uZWN0aW9uSGFuZGxlciBmcm9tICcuL2NtZC9DcmVhdGVDb25uZWN0aW9uSGFuZGxlcic7XG5pbXBvcnQgQ3JlYXRlRWxlbWVudHNIYW5kbGVyIGZyb20gJy4vY21kL0NyZWF0ZUVsZW1lbnRzSGFuZGxlcic7XG5pbXBvcnQgQ3JlYXRlTGFiZWxIYW5kbGVyIGZyb20gJy4vY21kL0NyZWF0ZUxhYmVsSGFuZGxlcic7XG5pbXBvcnQgQ3JlYXRlU2hhcGVIYW5kbGVyIGZyb20gJy4vY21kL0NyZWF0ZVNoYXBlSGFuZGxlcic7XG5pbXBvcnQgRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXIgZnJvbSAnLi9jbWQvRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXInO1xuaW1wb3J0IERlbGV0ZUVsZW1lbnRzSGFuZGxlciBmcm9tICcuL2NtZC9EZWxldGVFbGVtZW50c0hhbmRsZXInO1xuaW1wb3J0IERlbGV0ZVNoYXBlSGFuZGxlciBmcm9tICcuL2NtZC9EZWxldGVTaGFwZUhhbmRsZXInO1xuaW1wb3J0IERpc3RyaWJ1dGVFbGVtZW50c0hhbmRsZXIgZnJvbSAnLi9jbWQvRGlzdHJpYnV0ZUVsZW1lbnRzSGFuZGxlcic7XG5pbXBvcnQgTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXIgZnJvbSAnLi9jbWQvTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXInO1xuaW1wb3J0IE1vdmVDb25uZWN0aW9uSGFuZGxlciBmcm9tICcuL2NtZC9Nb3ZlQ29ubmVjdGlvbkhhbmRsZXInO1xuaW1wb3J0IE1vdmVFbGVtZW50c0hhbmRsZXIgZnJvbSAnLi9jbWQvTW92ZUVsZW1lbnRzSGFuZGxlcic7XG5pbXBvcnQgTW92ZVNoYXBlSGFuZGxlciBmcm9tICcuL2NtZC9Nb3ZlU2hhcGVIYW5kbGVyJztcbmltcG9ydCBSZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlciBmcm9tICcuL2NtZC9SZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlcic7XG5pbXBvcnQgUmVwbGFjZVNoYXBlSGFuZGxlciBmcm9tICcuL2NtZC9SZXBsYWNlU2hhcGVIYW5kbGVyJztcbmltcG9ydCBSZXNpemVTaGFwZUhhbmRsZXIgZnJvbSAnLi9jbWQvUmVzaXplU2hhcGVIYW5kbGVyJztcbmltcG9ydCBTcGFjZVRvb2xIYW5kbGVyIGZyb20gJy4vY21kL1NwYWNlVG9vbEhhbmRsZXInO1xuaW1wb3J0IFRvZ2dsZVNoYXBlQ29sbGFwc2VIYW5kbGVyIGZyb20gJy4vY21kL1RvZ2dsZVNoYXBlQ29sbGFwc2VIYW5kbGVyJztcbmltcG9ydCBVcGRhdGVBdHRhY2htZW50SGFuZGxlciBmcm9tICcuL2NtZC9VcGRhdGVBdHRhY2htZW50SGFuZGxlcic7XG5pbXBvcnQgVXBkYXRlV2F5cG9pbnRzSGFuZGxlciBmcm9tICcuL2NtZC9VcGRhdGVXYXlwb2ludHNIYW5kbGVyJztcblxuXG4vKipcbiAqIFRoZSBiYXNpYyBtb2RlbGluZyBlbnRyeSBwb2ludC5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtFbGVtZW50RmFjdG9yeX0gZWxlbWVudEZhY3RvcnlcbiAqIEBwYXJhbSB7Q29tbWFuZFN0YWNrfSBjb21tYW5kU3RhY2tcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW9kZWxpbmcoZXZlbnRCdXMsIGVsZW1lbnRGYWN0b3J5LCBjb21tYW5kU3RhY2spIHtcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcbiAgdGhpcy5fY29tbWFuZFN0YWNrID0gY29tbWFuZFN0YWNrO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5pbml0JywgZnVuY3Rpb24oKSB7XG5cbiAgICAvLyByZWdpc3RlciBtb2RlbGluZyBoYW5kbGVyc1xuICAgIHNlbGYucmVnaXN0ZXJIYW5kbGVycyhjb21tYW5kU3RhY2spO1xuICB9KTtcbn1cblxuTW9kZWxpbmcuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2VsZW1lbnRGYWN0b3J5JywgJ2NvbW1hbmRTdGFjaycgXTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUuZ2V0SGFuZGxlcnMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHtcbiAgICAnc2hhcGUuYXBwZW5kJzogQXBwZW5kU2hhcGVIYW5kbGVyLFxuICAgICdzaGFwZS5jcmVhdGUnOiBDcmVhdGVTaGFwZUhhbmRsZXIsXG4gICAgJ3NoYXBlLmRlbGV0ZSc6IERlbGV0ZVNoYXBlSGFuZGxlcixcbiAgICAnc2hhcGUubW92ZSc6IE1vdmVTaGFwZUhhbmRsZXIsXG4gICAgJ3NoYXBlLnJlc2l6ZSc6IFJlc2l6ZVNoYXBlSGFuZGxlcixcbiAgICAnc2hhcGUucmVwbGFjZSc6IFJlcGxhY2VTaGFwZUhhbmRsZXIsXG4gICAgJ3NoYXBlLnRvZ2dsZUNvbGxhcHNlJzogVG9nZ2xlU2hhcGVDb2xsYXBzZUhhbmRsZXIsXG5cbiAgICAnc3BhY2VUb29sJzogU3BhY2VUb29sSGFuZGxlcixcblxuICAgICdsYWJlbC5jcmVhdGUnOiBDcmVhdGVMYWJlbEhhbmRsZXIsXG5cbiAgICAnY29ubmVjdGlvbi5jcmVhdGUnOiBDcmVhdGVDb25uZWN0aW9uSGFuZGxlcixcbiAgICAnY29ubmVjdGlvbi5kZWxldGUnOiBEZWxldGVDb25uZWN0aW9uSGFuZGxlcixcbiAgICAnY29ubmVjdGlvbi5tb3ZlJzogTW92ZUNvbm5lY3Rpb25IYW5kbGVyLFxuICAgICdjb25uZWN0aW9uLmxheW91dCc6IExheW91dENvbm5lY3Rpb25IYW5kbGVyLFxuXG4gICAgJ2Nvbm5lY3Rpb24udXBkYXRlV2F5cG9pbnRzJzogVXBkYXRlV2F5cG9pbnRzSGFuZGxlcixcblxuICAgICdjb25uZWN0aW9uLnJlY29ubmVjdCc6IFJlY29ubmVjdENvbm5lY3Rpb25IYW5kbGVyLFxuXG4gICAgJ2VsZW1lbnRzLmNyZWF0ZSc6IENyZWF0ZUVsZW1lbnRzSGFuZGxlcixcbiAgICAnZWxlbWVudHMubW92ZSc6IE1vdmVFbGVtZW50c0hhbmRsZXIsXG4gICAgJ2VsZW1lbnRzLmRlbGV0ZSc6IERlbGV0ZUVsZW1lbnRzSGFuZGxlcixcblxuICAgICdlbGVtZW50cy5kaXN0cmlidXRlJzogRGlzdHJpYnV0ZUVsZW1lbnRzSGFuZGxlcixcbiAgICAnZWxlbWVudHMuYWxpZ24nOiBBbGlnbkVsZW1lbnRzSGFuZGxlcixcblxuICAgICdlbGVtZW50LnVwZGF0ZUF0dGFjaG1lbnQnOiBVcGRhdGVBdHRhY2htZW50SGFuZGxlclxuICB9O1xufTtcblxuLyoqXG4gKiBSZWdpc3RlciBoYW5kbGVycyB3aXRoIHRoZSBjb21tYW5kIHN0YWNrXG4gKlxuICogQHBhcmFtIHtDb21tYW5kU3RhY2t9IGNvbW1hbmRTdGFja1xuICovXG5Nb2RlbGluZy5wcm90b3R5cGUucmVnaXN0ZXJIYW5kbGVycyA9IGZ1bmN0aW9uKGNvbW1hbmRTdGFjaykge1xuICBmb3JFYWNoKHRoaXMuZ2V0SGFuZGxlcnMoKSwgZnVuY3Rpb24oaGFuZGxlciwgaWQpIHtcbiAgICBjb21tYW5kU3RhY2sucmVnaXN0ZXJIYW5kbGVyKGlkLCBoYW5kbGVyKTtcbiAgfSk7XG59O1xuXG5cbi8vIG1vZGVsaW5nIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5Nb2RlbGluZy5wcm90b3R5cGUubW92ZVNoYXBlID0gZnVuY3Rpb24oc2hhcGUsIGRlbHRhLCBuZXdQYXJlbnQsIG5ld1BhcmVudEluZGV4LCBoaW50cykge1xuXG4gIGlmICh0eXBlb2YgbmV3UGFyZW50SW5kZXggPT09ICdvYmplY3QnKSB7XG4gICAgaGludHMgPSBuZXdQYXJlbnRJbmRleDtcbiAgICBuZXdQYXJlbnRJbmRleCA9IG51bGw7XG4gIH1cblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBzaGFwZTogc2hhcGUsXG4gICAgZGVsdGE6ICBkZWx0YSxcbiAgICBuZXdQYXJlbnQ6IG5ld1BhcmVudCxcbiAgICBuZXdQYXJlbnRJbmRleDogbmV3UGFyZW50SW5kZXgsXG4gICAgaGludHM6IGhpbnRzIHx8IHt9XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3NoYXBlLm1vdmUnLCBjb250ZXh0KTtcbn07XG5cblxuLyoqXG4gKiBVcGRhdGUgdGhlIGF0dGFjaG1lbnQgb2YgdGhlIGdpdmVuIHNoYXBlLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGUuQmFzZX0gc2hhcGVcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtuZXdIb3N0XVxuICovXG5Nb2RlbGluZy5wcm90b3R5cGUudXBkYXRlQXR0YWNobWVudCA9IGZ1bmN0aW9uKHNoYXBlLCBuZXdIb3N0KSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIHNoYXBlOiBzaGFwZSxcbiAgICBuZXdIb3N0OiBuZXdIb3N0XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnQudXBkYXRlQXR0YWNobWVudCcsIGNvbnRleHQpO1xufTtcblxuXG4vKipcbiAqIE1vdmUgYSBudW1iZXIgb2Ygc2hhcGVzIHRvIGEgbmV3IHRhcmdldCwgZWl0aGVyIHNldHRpbmcgaXQgYXNcbiAqIHRoZSBuZXcgcGFyZW50IG9yIGF0dGFjaGluZyBpdC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlLkJhc2U+fSBzaGFwZXNcbiAqIEBwYXJhbSB7UG9pbnR9IGRlbHRhXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBbdGFyZ2V0XVxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2hpbnRzLmF0dGFjaD1mYWxzZV1cbiAqL1xuTW9kZWxpbmcucHJvdG90eXBlLm1vdmVFbGVtZW50cyA9IGZ1bmN0aW9uKHNoYXBlcywgZGVsdGEsIHRhcmdldCwgaGludHMpIHtcblxuICBoaW50cyA9IGhpbnRzIHx8IHt9O1xuXG4gIHZhciBhdHRhY2ggPSBoaW50cy5hdHRhY2g7XG5cbiAgdmFyIG5ld1BhcmVudCA9IHRhcmdldCxcbiAgICAgIG5ld0hvc3Q7XG5cbiAgaWYgKGF0dGFjaCA9PT0gdHJ1ZSkge1xuICAgIG5ld0hvc3QgPSB0YXJnZXQ7XG4gICAgbmV3UGFyZW50ID0gdGFyZ2V0LnBhcmVudDtcbiAgfSBlbHNlXG5cbiAgaWYgKGF0dGFjaCA9PT0gZmFsc2UpIHtcbiAgICBuZXdIb3N0ID0gbnVsbDtcbiAgfVxuXG4gIHZhciBjb250ZXh0ID0ge1xuICAgIHNoYXBlczogc2hhcGVzLFxuICAgIGRlbHRhOiBkZWx0YSxcbiAgICBuZXdQYXJlbnQ6IG5ld1BhcmVudCxcbiAgICBuZXdIb3N0OiBuZXdIb3N0LFxuICAgIGhpbnRzOiBoaW50c1xuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdlbGVtZW50cy5tb3ZlJywgY29udGV4dCk7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5tb3ZlQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIGRlbHRhLCBuZXdQYXJlbnQsIG5ld1BhcmVudEluZGV4LCBoaW50cykge1xuXG4gIGlmICh0eXBlb2YgbmV3UGFyZW50SW5kZXggPT09ICdvYmplY3QnKSB7XG4gICAgaGludHMgPSBuZXdQYXJlbnRJbmRleDtcbiAgICBuZXdQYXJlbnRJbmRleCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgZGVsdGE6IGRlbHRhLFxuICAgIG5ld1BhcmVudDogbmV3UGFyZW50LFxuICAgIG5ld1BhcmVudEluZGV4OiBuZXdQYXJlbnRJbmRleCxcbiAgICBoaW50czogaGludHMgfHwge31cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnY29ubmVjdGlvbi5tb3ZlJywgY29udGV4dCk7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5sYXlvdXRDb25uZWN0aW9uID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgaGludHMpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICBoaW50czogaGludHMgfHwge31cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnY29ubmVjdGlvbi5sYXlvdXQnLCBjb250ZXh0KTtcbn07XG5cblxuLyoqXG4gKiBDcmVhdGUgY29ubmVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBzb3VyY2VcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IHRhcmdldFxuICogQHBhcmFtIHtudW1iZXJ9IFtwYXJlbnRJbmRleF1cbiAqIEBwYXJhbSB7T2JqZWN0fGRqcy5tb2RlbC5Db25uZWN0aW9ufSBjb25uZWN0aW9uXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBwYXJlbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBoaW50c1xuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5Db25uZWN0aW9ufSB0aGUgY3JlYXRlZCBjb25uZWN0aW9uLlxuICovXG5Nb2RlbGluZy5wcm90b3R5cGUuY3JlYXRlQ29ubmVjdGlvbiA9IGZ1bmN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBwYXJlbnRJbmRleCwgY29ubmVjdGlvbiwgcGFyZW50LCBoaW50cykge1xuXG4gIGlmICh0eXBlb2YgcGFyZW50SW5kZXggPT09ICdvYmplY3QnKSB7XG4gICAgaGludHMgPSBwYXJlbnQ7XG4gICAgcGFyZW50ID0gY29ubmVjdGlvbjtcbiAgICBjb25uZWN0aW9uID0gcGFyZW50SW5kZXg7XG4gICAgcGFyZW50SW5kZXggPSB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25uZWN0aW9uID0gdGhpcy5fY3JlYXRlKCdjb25uZWN0aW9uJywgY29ubmVjdGlvbik7XG5cbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgc291cmNlOiBzb3VyY2UsXG4gICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgcGFyZW50OiBwYXJlbnQsXG4gICAgcGFyZW50SW5kZXg6IHBhcmVudEluZGV4LFxuICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgaGludHM6IGhpbnRzXG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2Nvbm5lY3Rpb24uY3JlYXRlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuY29ubmVjdGlvbjtcbn07XG5cblxuLyoqXG4gKiBDcmVhdGUgYSBzaGFwZSBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uLlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfE9iamVjdH0gc2hhcGVcbiAqIEBwYXJhbSB7UG9pbnR9IHBvc2l0aW9uXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZXxkanMubW9kZWwuUm9vdH0gdGFyZ2V0XG4gKiBAcGFyYW0ge251bWJlcn0gW3BhcmVudEluZGV4XSBwb3NpdGlvbiBpbiBwYXJlbnRzIGNoaWxkcmVuIGxpc3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBbaGludHNdXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtoaW50cy5hdHRhY2hdIHdoZXRoZXIgdG8gYXR0YWNoIHRvIHRhcmdldCBvciBiZWNvbWUgYSBjaGlsZFxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5TaGFwZX0gdGhlIGNyZWF0ZWQgc2hhcGVcbiAqL1xuTW9kZWxpbmcucHJvdG90eXBlLmNyZWF0ZVNoYXBlID0gZnVuY3Rpb24oc2hhcGUsIHBvc2l0aW9uLCB0YXJnZXQsIHBhcmVudEluZGV4LCBoaW50cykge1xuXG4gIGlmICh0eXBlb2YgcGFyZW50SW5kZXggIT09ICdudW1iZXInKSB7XG4gICAgaGludHMgPSBwYXJlbnRJbmRleDtcbiAgICBwYXJlbnRJbmRleCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGhpbnRzID0gaGludHMgfHwge307XG5cbiAgdmFyIGF0dGFjaCA9IGhpbnRzLmF0dGFjaCxcbiAgICAgIHBhcmVudCxcbiAgICAgIGhvc3Q7XG5cbiAgc2hhcGUgPSB0aGlzLl9jcmVhdGUoJ3NoYXBlJywgc2hhcGUpO1xuXG4gIGlmIChhdHRhY2gpIHtcbiAgICBwYXJlbnQgPSB0YXJnZXQucGFyZW50O1xuICAgIGhvc3QgPSB0YXJnZXQ7XG4gIH0gZWxzZSB7XG4gICAgcGFyZW50ID0gdGFyZ2V0O1xuICB9XG5cbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgIHNoYXBlOiBzaGFwZSxcbiAgICBwYXJlbnQ6IHBhcmVudCxcbiAgICBwYXJlbnRJbmRleDogcGFyZW50SW5kZXgsXG4gICAgaG9zdDogaG9zdCxcbiAgICBoaW50czogaGludHNcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnc2hhcGUuY3JlYXRlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuc2hhcGU7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5jcmVhdGVFbGVtZW50cyA9IGZ1bmN0aW9uKGVsZW1lbnRzLCBwb3NpdGlvbiwgcGFyZW50LCBwYXJlbnRJbmRleCwgaGludHMpIHtcbiAgaWYgKCFpc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gWyBlbGVtZW50cyBdO1xuICB9XG5cbiAgaWYgKHR5cGVvZiBwYXJlbnRJbmRleCAhPT0gJ251bWJlcicpIHtcbiAgICBoaW50cyA9IHBhcmVudEluZGV4O1xuICAgIHBhcmVudEluZGV4ID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgaGludHMgPSBoaW50cyB8fCB7fTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgZWxlbWVudHM6IGVsZW1lbnRzLFxuICAgIHBhcmVudDogcGFyZW50LFxuICAgIHBhcmVudEluZGV4OiBwYXJlbnRJbmRleCxcbiAgICBoaW50czogaGludHNcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnZWxlbWVudHMuY3JlYXRlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuZWxlbWVudHM7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5jcmVhdGVMYWJlbCA9IGZ1bmN0aW9uKGxhYmVsVGFyZ2V0LCBwb3NpdGlvbiwgbGFiZWwsIHBhcmVudCkge1xuXG4gIGxhYmVsID0gdGhpcy5fY3JlYXRlKCdsYWJlbCcsIGxhYmVsKTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBsYWJlbFRhcmdldDogbGFiZWxUYXJnZXQsXG4gICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgIHBhcmVudDogcGFyZW50IHx8IGxhYmVsVGFyZ2V0LnBhcmVudCxcbiAgICBzaGFwZTogbGFiZWxcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnbGFiZWwuY3JlYXRlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuc2hhcGU7XG59O1xuXG5cbi8qKlxuICogQXBwZW5kIHNoYXBlIHRvIGdpdmVuIHNvdXJjZSwgZHJhd2luZyBhIGNvbm5lY3Rpb25cbiAqIGJldHdlZW4gc291cmNlIGFuZCB0aGUgbmV3bHkgY3JlYXRlZCBzaGFwZS5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc291cmNlXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZXxPYmplY3R9IHNoYXBlXG4gKiBAcGFyYW0ge1BvaW50fSBwb3NpdGlvblxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IHRhcmdldFxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2hpbnRzLmF0dGFjaF1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkNvbm5lY3Rpb258T2JqZWN0fSBbaGludHMuY29ubmVjdGlvbl1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtoaW50cy5jb25uZWN0aW9uUGFyZW50XVxuICpcbiAqIEByZXR1cm4ge2Rqcy5tb2RlbC5TaGFwZX0gdGhlIG5ld2x5IGNyZWF0ZWQgc2hhcGVcbiAqL1xuTW9kZWxpbmcucHJvdG90eXBlLmFwcGVuZFNoYXBlID0gZnVuY3Rpb24oc291cmNlLCBzaGFwZSwgcG9zaXRpb24sIHRhcmdldCwgaGludHMpIHtcblxuICBoaW50cyA9IGhpbnRzIHx8IHt9O1xuXG4gIHNoYXBlID0gdGhpcy5fY3JlYXRlKCdzaGFwZScsIHNoYXBlKTtcblxuICB2YXIgY29udGV4dCA9IHtcbiAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICBwb3NpdGlvbjogcG9zaXRpb24sXG4gICAgdGFyZ2V0OiB0YXJnZXQsXG4gICAgc2hhcGU6IHNoYXBlLFxuICAgIGNvbm5lY3Rpb246IGhpbnRzLmNvbm5lY3Rpb24sXG4gICAgY29ubmVjdGlvblBhcmVudDogaGludHMuY29ubmVjdGlvblBhcmVudCxcbiAgICBoaW50czogaGludHNcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnc2hhcGUuYXBwZW5kJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQuc2hhcGU7XG59O1xuXG5cbk1vZGVsaW5nLnByb3RvdHlwZS5yZW1vdmVFbGVtZW50cyA9IGZ1bmN0aW9uKGVsZW1lbnRzKSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGVsZW1lbnRzOiBlbGVtZW50c1xuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdlbGVtZW50cy5kZWxldGUnLCBjb250ZXh0KTtcbn07XG5cblxuTW9kZWxpbmcucHJvdG90eXBlLmRpc3RyaWJ1dGVFbGVtZW50cyA9IGZ1bmN0aW9uKGdyb3VwcywgYXhpcywgZGltZW5zaW9uKSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGdyb3VwczogZ3JvdXBzLFxuICAgIGF4aXM6IGF4aXMsXG4gICAgZGltZW5zaW9uOiBkaW1lbnNpb25cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnZWxlbWVudHMuZGlzdHJpYnV0ZScsIGNvbnRleHQpO1xufTtcblxuXG5Nb2RlbGluZy5wcm90b3R5cGUucmVtb3ZlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgaGludHMpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgc2hhcGU6IHNoYXBlLFxuICAgIGhpbnRzOiBoaW50cyB8fCB7fVxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdzaGFwZS5kZWxldGUnLCBjb250ZXh0KTtcbn07XG5cblxuTW9kZWxpbmcucHJvdG90eXBlLnJlbW92ZUNvbm5lY3Rpb24gPSBmdW5jdGlvbihjb25uZWN0aW9uLCBoaW50cykge1xuICB2YXIgY29udGV4dCA9IHtcbiAgICBjb25uZWN0aW9uOiBjb25uZWN0aW9uLFxuICAgIGhpbnRzOiBoaW50cyB8fCB7fVxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdjb25uZWN0aW9uLmRlbGV0ZScsIGNvbnRleHQpO1xufTtcblxuTW9kZWxpbmcucHJvdG90eXBlLnJlcGxhY2VTaGFwZSA9IGZ1bmN0aW9uKG9sZFNoYXBlLCBuZXdTaGFwZSwgaGludHMpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgb2xkU2hhcGU6IG9sZFNoYXBlLFxuICAgIG5ld0RhdGE6IG5ld1NoYXBlLFxuICAgIGhpbnRzOiBoaW50cyB8fCB7fVxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdzaGFwZS5yZXBsYWNlJywgY29udGV4dCk7XG5cbiAgcmV0dXJuIGNvbnRleHQubmV3U2hhcGU7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUuYWxpZ25FbGVtZW50cyA9IGZ1bmN0aW9uKGVsZW1lbnRzLCBhbGlnbm1lbnQpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgZWxlbWVudHM6IGVsZW1lbnRzLFxuICAgIGFsaWdubWVudDogYWxpZ25tZW50XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2VsZW1lbnRzLmFsaWduJywgY29udGV4dCk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUucmVzaXplU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgbmV3Qm91bmRzLCBtaW5Cb3VuZHMsIGhpbnRzKSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIHNoYXBlOiBzaGFwZSxcbiAgICBuZXdCb3VuZHM6IG5ld0JvdW5kcyxcbiAgICBtaW5Cb3VuZHM6IG1pbkJvdW5kcyxcbiAgICBoaW50czogaGludHNcbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnc2hhcGUucmVzaXplJywgY29udGV4dCk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUuY3JlYXRlU3BhY2UgPSBmdW5jdGlvbihtb3ZpbmdTaGFwZXMsIHJlc2l6aW5nU2hhcGVzLCBkZWx0YSwgZGlyZWN0aW9uLCBzdGFydCkge1xuICB2YXIgY29udGV4dCA9IHtcbiAgICBkZWx0YTogZGVsdGEsXG4gICAgZGlyZWN0aW9uOiBkaXJlY3Rpb24sXG4gICAgbW92aW5nU2hhcGVzOiBtb3ZpbmdTaGFwZXMsXG4gICAgcmVzaXppbmdTaGFwZXM6IHJlc2l6aW5nU2hhcGVzLFxuICAgIHN0YXJ0OiBzdGFydFxuICB9O1xuXG4gIHRoaXMuX2NvbW1hbmRTdGFjay5leGVjdXRlKCdzcGFjZVRvb2wnLCBjb250ZXh0KTtcbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS51cGRhdGVXYXlwb2ludHMgPSBmdW5jdGlvbihjb25uZWN0aW9uLCBuZXdXYXlwb2ludHMsIGhpbnRzKSB7XG4gIHZhciBjb250ZXh0ID0ge1xuICAgIGNvbm5lY3Rpb246IGNvbm5lY3Rpb24sXG4gICAgbmV3V2F5cG9pbnRzOiBuZXdXYXlwb2ludHMsXG4gICAgaGludHM6IGhpbnRzIHx8IHt9XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ2Nvbm5lY3Rpb24udXBkYXRlV2F5cG9pbnRzJywgY29udGV4dCk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgc291cmNlLCB0YXJnZXQsIGRvY2tpbmdPclBvaW50cywgaGludHMpIHtcbiAgdmFyIGNvbnRleHQgPSB7XG4gICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICBuZXdTb3VyY2U6IHNvdXJjZSxcbiAgICBuZXdUYXJnZXQ6IHRhcmdldCxcbiAgICBkb2NraW5nT3JQb2ludHM6IGRvY2tpbmdPclBvaW50cyxcbiAgICBoaW50czogaGludHMgfHwge31cbiAgfTtcblxuICB0aGlzLl9jb21tYW5kU3RhY2suZXhlY3V0ZSgnY29ubmVjdGlvbi5yZWNvbm5lY3QnLCBjb250ZXh0KTtcbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS5yZWNvbm5lY3RTdGFydCA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIG5ld1NvdXJjZSwgZG9ja2luZ09yUG9pbnRzLCBoaW50cykge1xuICBpZiAoIWhpbnRzKSB7XG4gICAgaGludHMgPSB7fTtcbiAgfVxuXG4gIHRoaXMucmVjb25uZWN0KGNvbm5lY3Rpb24sIG5ld1NvdXJjZSwgY29ubmVjdGlvbi50YXJnZXQsIGRvY2tpbmdPclBvaW50cywgYXNzaWduKGhpbnRzLCB7XG4gICAgZG9ja2luZzogJ3NvdXJjZSdcbiAgfSkpO1xufTtcblxuTW9kZWxpbmcucHJvdG90eXBlLnJlY29ubmVjdEVuZCA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIG5ld1RhcmdldCwgZG9ja2luZ09yUG9pbnRzLCBoaW50cykge1xuICBpZiAoIWhpbnRzKSB7XG4gICAgaGludHMgPSB7fTtcbiAgfVxuXG4gIHRoaXMucmVjb25uZWN0KGNvbm5lY3Rpb24sIGNvbm5lY3Rpb24uc291cmNlLCBuZXdUYXJnZXQsIGRvY2tpbmdPclBvaW50cywgYXNzaWduKGhpbnRzLCB7XG4gICAgZG9ja2luZzogJ3RhcmdldCdcbiAgfSkpO1xufTtcblxuTW9kZWxpbmcucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbihzb3VyY2UsIHRhcmdldCwgYXR0cnMsIGhpbnRzKSB7XG4gIHJldHVybiB0aGlzLmNyZWF0ZUNvbm5lY3Rpb24oc291cmNlLCB0YXJnZXQsIGF0dHJzIHx8IHt9LCBzb3VyY2UucGFyZW50LCBoaW50cyk7XG59O1xuXG5Nb2RlbGluZy5wcm90b3R5cGUuX2NyZWF0ZSA9IGZ1bmN0aW9uKHR5cGUsIGF0dHJzKSB7XG4gIGlmIChhdHRycyBpbnN0YW5jZW9mIEJhc2UpIHtcbiAgICByZXR1cm4gYXR0cnM7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHRoaXMuX2VsZW1lbnRGYWN0b3J5LmNyZWF0ZSh0eXBlLCBhdHRycyk7XG4gIH1cbn07XG5cbk1vZGVsaW5nLnByb3RvdHlwZS50b2dnbGVDb2xsYXBzZSA9IGZ1bmN0aW9uKHNoYXBlLCBoaW50cykge1xuICB2YXIgY29udGV4dCA9IHtcbiAgICBzaGFwZTogc2hhcGUsXG4gICAgaGludHM6IGhpbnRzIHx8IHt9XG4gIH07XG5cbiAgdGhpcy5fY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3NoYXBlLnRvZ2dsZUNvbGxhcHNlJywgY29udGV4dCk7XG59O1xuIiwiaW1wb3J0IHsgZm9yRWFjaCB9IGZyb20gJ21pbi1kYXNoJztcblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBhbGlnbiBlbGVtZW50cyBpbiBhIGNlcnRhaW4gd2F5LlxuICpcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQWxpZ25FbGVtZW50cyhtb2RlbGluZywgY2FudmFzKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbn1cblxuQWxpZ25FbGVtZW50cy4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnLCAnY2FudmFzJyBdO1xuXG5cbkFsaWduRWxlbWVudHMucHJvdG90eXBlLnByZUV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nO1xuXG4gIHZhciBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXG4gICAgICBhbGlnbm1lbnQgPSBjb250ZXh0LmFsaWdubWVudDtcblxuXG4gIGZvckVhY2goZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICB2YXIgZGVsdGEgPSB7XG4gICAgICB4OiAwLFxuICAgICAgeTogMFxuICAgIH07XG5cbiAgICBpZiAoYWxpZ25tZW50LmxlZnQpIHtcbiAgICAgIGRlbHRhLnggPSBhbGlnbm1lbnQubGVmdCAtIGVsZW1lbnQueDtcblxuICAgIH0gZWxzZSBpZiAoYWxpZ25tZW50LnJpZ2h0KSB7XG4gICAgICBkZWx0YS54ID0gKGFsaWdubWVudC5yaWdodCAtIGVsZW1lbnQud2lkdGgpIC0gZWxlbWVudC54O1xuXG4gICAgfSBlbHNlIGlmIChhbGlnbm1lbnQuY2VudGVyKSB7XG4gICAgICBkZWx0YS54ID0gKGFsaWdubWVudC5jZW50ZXIgLSBNYXRoLnJvdW5kKGVsZW1lbnQud2lkdGggLyAyKSkgLSBlbGVtZW50Lng7XG5cbiAgICB9IGVsc2UgaWYgKGFsaWdubWVudC50b3ApIHtcbiAgICAgIGRlbHRhLnkgPSBhbGlnbm1lbnQudG9wIC0gZWxlbWVudC55O1xuXG4gICAgfSBlbHNlIGlmIChhbGlnbm1lbnQuYm90dG9tKSB7XG4gICAgICBkZWx0YS55ID0gKGFsaWdubWVudC5ib3R0b20gLSBlbGVtZW50LmhlaWdodCkgLSBlbGVtZW50Lnk7XG5cbiAgICB9IGVsc2UgaWYgKGFsaWdubWVudC5taWRkbGUpIHtcbiAgICAgIGRlbHRhLnkgPSAoYWxpZ25tZW50Lm1pZGRsZSAtIE1hdGgucm91bmQoZWxlbWVudC5oZWlnaHQgLyAyKSkgLSBlbGVtZW50Lnk7XG4gICAgfVxuXG4gICAgbW9kZWxpbmcubW92ZUVsZW1lbnRzKFsgZWxlbWVudCBdLCBkZWx0YSwgZWxlbWVudC5wYXJlbnQpO1xuICB9KTtcbn07XG5cbkFsaWduRWxlbWVudHMucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG59O1xuIiwiaW1wb3J0IHsgc29tZSB9IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgcmV2ZXJzaWJsZSBhcHBlbmRpbmcgb2Ygc2hhcGVzXG4gKiB0byBhIHNvdXJjZSBzaGFwZS5cbiAqXG4gKiBAcGFyYW0ge2NhbnZhc30gQ2FudmFzXG4gKiBAcGFyYW0ge2VsZW1lbnRGYWN0b3J5fSBFbGVtZW50RmFjdG9yeVxuICogQHBhcmFtIHttb2RlbGluZ30gTW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQXBwZW5kU2hhcGVIYW5kbGVyKG1vZGVsaW5nKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cbkFwcGVuZFNoYXBlSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgc2hhcGVcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtFbGVtZW50RGVzY3JpcHRvcn0gY29udGV4dC5zaGFwZSB0aGUgbmV3IHNoYXBlXG4gKiBAcGFyYW0ge0VsZW1lbnREZXNjcmlwdG9yfSBjb250ZXh0LnNvdXJjZSB0aGUgc291cmNlIG9iamVjdFxuICogQHBhcmFtIHtFbGVtZW50RGVzY3JpcHRvcn0gY29udGV4dC5wYXJlbnQgdGhlIHBhcmVudCBvYmplY3RcbiAqIEBwYXJhbSB7UG9pbnR9IGNvbnRleHQucG9zaXRpb24gcG9zaXRpb24gb2YgdGhlIG5ldyBlbGVtZW50XG4gKi9cbkFwcGVuZFNoYXBlSGFuZGxlci5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgc291cmNlID0gY29udGV4dC5zb3VyY2U7XG5cbiAgaWYgKCFzb3VyY2UpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSByZXF1aXJlZCcpO1xuICB9XG5cbiAgdmFyIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0IHx8IHNvdXJjZS5wYXJlbnQsXG4gICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgc2hhcGUgPSBjb250ZXh0LnNoYXBlID1cbiAgICB0aGlzLl9tb2RlbGluZy5jcmVhdGVTaGFwZShcbiAgICAgIHNoYXBlLFxuICAgICAgY29udGV4dC5wb3NpdGlvbixcbiAgICAgIHRhcmdldCwgeyBhdHRhY2g6IGhpbnRzLmF0dGFjaCB9KTtcblxuICBjb250ZXh0LnNoYXBlID0gc2hhcGU7XG59O1xuXG5BcHBlbmRTaGFwZUhhbmRsZXIucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gIGlmICghZXhpc3RzQ29ubmVjdGlvbihjb250ZXh0LnNvdXJjZSwgY29udGV4dC5zaGFwZSkpIHtcblxuICAgIC8vIGNyZWF0ZSBjb25uZWN0aW9uXG4gICAgaWYgKGhpbnRzLmNvbm5lY3Rpb25UYXJnZXQgPT09IGNvbnRleHQuc291cmNlKSB7XG4gICAgICB0aGlzLl9tb2RlbGluZy5jb25uZWN0KGNvbnRleHQuc2hhcGUsIGNvbnRleHQuc291cmNlLCBjb250ZXh0LmNvbm5lY3Rpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9tb2RlbGluZy5jb25uZWN0KGNvbnRleHQuc291cmNlLCBjb250ZXh0LnNoYXBlLCBjb250ZXh0LmNvbm5lY3Rpb24pO1xuICAgIH1cbiAgfVxufTtcblxuXG5mdW5jdGlvbiBleGlzdHNDb25uZWN0aW9uKHNvdXJjZSwgdGFyZ2V0KSB7XG4gIHJldHVybiBzb21lKHNvdXJjZS5vdXRnb2luZywgZnVuY3Rpb24oYykge1xuICAgIHJldHVybiBjLnRhcmdldCA9PT0gdGFyZ2V0O1xuICB9KTtcbn0iLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVDb25uZWN0aW9uSGFuZGxlcihjYW52YXMsIGxheW91dGVyKSB7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fbGF5b3V0ZXIgPSBsYXlvdXRlcjtcbn1cblxuQ3JlYXRlQ29ubmVjdGlvbkhhbmRsZXIuJGluamVjdCA9IFsgJ2NhbnZhcycsICdsYXlvdXRlcicgXTtcblxuXG4vLyBhcGkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5cbi8qKlxuICogQXBwZW5kcyBhIHNoYXBlIHRvIGEgdGFyZ2V0IHNoYXBlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7ZGpzLmVsZW1lbnQuQmFzZX0gY29udGV4dC5zb3VyY2UgdGhlIHNvdXJjZSBvYmplY3RcbiAqIEBwYXJhbSB7ZGpzLmVsZW1lbnQuQmFzZX0gY29udGV4dC50YXJnZXQgdGhlIHBhcmVudCBvYmplY3RcbiAqIEBwYXJhbSB7UG9pbnR9IGNvbnRleHQucG9zaXRpb24gcG9zaXRpb24gb2YgdGhlIG5ldyBlbGVtZW50XG4gKi9cbkNyZWF0ZUNvbm5lY3Rpb25IYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgc291cmNlID0gY29udGV4dC5zb3VyY2UsXG4gICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldCxcbiAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxuICAgICAgcGFyZW50SW5kZXggPSBjb250ZXh0LnBhcmVudEluZGV4LFxuICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzO1xuXG4gIGlmICghc291cmNlIHx8ICF0YXJnZXQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3NvdXJjZSBhbmQgdGFyZ2V0IHJlcXVpcmVkJyk7XG4gIH1cblxuICBpZiAoIXBhcmVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcigncGFyZW50IHJlcXVpcmVkJyk7XG4gIH1cblxuICBjb25uZWN0aW9uLnNvdXJjZSA9IHNvdXJjZTtcbiAgY29ubmVjdGlvbi50YXJnZXQgPSB0YXJnZXQ7XG5cbiAgaWYgKCFjb25uZWN0aW9uLndheXBvaW50cykge1xuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gdGhpcy5fbGF5b3V0ZXIubGF5b3V0Q29ubmVjdGlvbihjb25uZWN0aW9uLCBoaW50cyk7XG4gIH1cblxuICAvLyBhZGQgY29ubmVjdGlvblxuICB0aGlzLl9jYW52YXMuYWRkQ29ubmVjdGlvbihjb25uZWN0aW9uLCBwYXJlbnQsIHBhcmVudEluZGV4KTtcblxuICByZXR1cm4gY29ubmVjdGlvbjtcbn07XG5cbkNyZWF0ZUNvbm5lY3Rpb25IYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uO1xuXG4gIHRoaXMuX2NhbnZhcy5yZW1vdmVDb25uZWN0aW9uKGNvbm5lY3Rpb24pO1xuXG4gIGNvbm5lY3Rpb24uc291cmNlID0gbnVsbDtcbiAgY29ubmVjdGlvbi50YXJnZXQgPSBudWxsO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTsiLCJpbXBvcnQge1xyXG4gIGFzc2lnbixcclxuICBmb3JFYWNoLFxyXG4gIGlzTnVtYmVyLFxyXG4gIG1hcCxcclxuICBwaWNrLFxyXG4gIHZhbHVlc1xyXG59IGZyb20gJ21pbi1kYXNoJztcclxuXHJcbmltcG9ydCB7XHJcbiAgZ2V0QkJveCxcclxuICBnZXRQYXJlbnRzXHJcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbC9FbGVtZW50cyc7XHJcblxyXG52YXIgcm91bmQgPSBNYXRoLnJvdW5kO1xyXG5cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQ3JlYXRlRWxlbWVudHNIYW5kbGVyKG1vZGVsaW5nKSB7XHJcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcclxufVxyXG5cclxuQ3JlYXRlRWxlbWVudHNIYW5kbGVyLiRpbmplY3QgPSBbXHJcbiAgJ21vZGVsaW5nJ1xyXG5dO1xyXG5cclxuQ3JlYXRlRWxlbWVudHNIYW5kbGVyLnByb3RvdHlwZS5wcmVFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xyXG4gIHZhciBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXHJcbiAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxyXG4gICAgICBwYXJlbnRJbmRleCA9IGNvbnRleHQucGFyZW50SW5kZXgsXHJcbiAgICAgIHBvc2l0aW9uID0gY29udGV4dC5wb3NpdGlvbixcclxuICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzO1xyXG5cclxuICB2YXIgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcclxuXHJcbiAgLy8gbWFrZSBzdXJlIGVhY2ggZWxlbWVudCBoYXMgeCBhbmQgeVxyXG4gIGZvckVhY2goZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgIGlmICghaXNOdW1iZXIoZWxlbWVudC54KSkge1xyXG4gICAgICBlbGVtZW50LnggPSAwO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghaXNOdW1iZXIoZWxlbWVudC55KSkge1xyXG4gICAgICBlbGVtZW50LnkgPSAwO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICB2YXIgYmJveCA9IGdldEJCb3goZWxlbWVudHMpO1xyXG5cclxuICAvLyBjZW50ZXIgZWxlbWVudHMgYXJvdW5kIHBvc2l0aW9uXHJcbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgaWYgKGlzQ29ubmVjdGlvbihlbGVtZW50KSkge1xyXG4gICAgICBlbGVtZW50LndheXBvaW50cyA9IG1hcChlbGVtZW50LndheXBvaW50cywgZnVuY3Rpb24od2F5cG9pbnQpIHtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgeDogcm91bmQod2F5cG9pbnQueCAtIGJib3gueCAtIGJib3gud2lkdGggLyAyICsgcG9zaXRpb24ueCksXHJcbiAgICAgICAgICB5OiByb3VuZCh3YXlwb2ludC55IC0gYmJveC55IC0gYmJveC5oZWlnaHQgLyAyICsgcG9zaXRpb24ueSlcclxuICAgICAgICB9O1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBhc3NpZ24oZWxlbWVudCwge1xyXG4gICAgICB4OiByb3VuZChlbGVtZW50LnggLSBiYm94LnggLSBiYm94LndpZHRoIC8gMiArIHBvc2l0aW9uLngpLFxyXG4gICAgICB5OiByb3VuZChlbGVtZW50LnkgLSBiYm94LnkgLSBiYm94LmhlaWdodCAvIDIgKyBwb3NpdGlvbi55KVxyXG4gICAgfSk7XHJcbiAgfSk7XHJcblxyXG4gIHZhciBwYXJlbnRzID0gZ2V0UGFyZW50cyhlbGVtZW50cyk7XHJcblxyXG4gIHZhciBjYWNoZSA9IHt9O1xyXG5cclxuICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICBpZiAoaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XHJcbiAgICAgIGNhY2hlWyBlbGVtZW50LmlkIF0gPSBpc051bWJlcihwYXJlbnRJbmRleCkgP1xyXG4gICAgICAgIG1vZGVsaW5nLmNyZWF0ZUNvbm5lY3Rpb24oXHJcbiAgICAgICAgICBjYWNoZVsgZWxlbWVudC5zb3VyY2UuaWQgXSxcclxuICAgICAgICAgIGNhY2hlWyBlbGVtZW50LnRhcmdldC5pZCBdLFxyXG4gICAgICAgICAgcGFyZW50SW5kZXgsXHJcbiAgICAgICAgICBlbGVtZW50LFxyXG4gICAgICAgICAgZWxlbWVudC5wYXJlbnQgfHwgcGFyZW50LFxyXG4gICAgICAgICAgaGludHNcclxuICAgICAgICApIDpcclxuICAgICAgICBtb2RlbGluZy5jcmVhdGVDb25uZWN0aW9uKFxyXG4gICAgICAgICAgY2FjaGVbIGVsZW1lbnQuc291cmNlLmlkIF0sXHJcbiAgICAgICAgICBjYWNoZVsgZWxlbWVudC50YXJnZXQuaWQgXSxcclxuICAgICAgICAgIGVsZW1lbnQsXHJcbiAgICAgICAgICBlbGVtZW50LnBhcmVudCB8fCBwYXJlbnQsXHJcbiAgICAgICAgICBoaW50c1xyXG4gICAgICAgICk7XHJcblxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGNyZWF0ZVNoYXBlSGludHMgPSBhc3NpZ24oe30sIGhpbnRzKTtcclxuXHJcbiAgICBpZiAocGFyZW50cy5pbmRleE9mKGVsZW1lbnQpID09PSAtMSkge1xyXG4gICAgICBjcmVhdGVTaGFwZUhpbnRzLmF1dG9SZXNpemUgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICBjYWNoZVsgZWxlbWVudC5pZCBdID0gaXNOdW1iZXIocGFyZW50SW5kZXgpID9cclxuICAgICAgbW9kZWxpbmcuY3JlYXRlU2hhcGUoXHJcbiAgICAgICAgZWxlbWVudCxcclxuICAgICAgICBwaWNrKGVsZW1lbnQsIFsgJ3gnLCAneScsICd3aWR0aCcsICdoZWlnaHQnIF0pLFxyXG4gICAgICAgIGVsZW1lbnQucGFyZW50IHx8IHBhcmVudCxcclxuICAgICAgICBwYXJlbnRJbmRleCxcclxuICAgICAgICBjcmVhdGVTaGFwZUhpbnRzXHJcbiAgICAgICkgOlxyXG4gICAgICBtb2RlbGluZy5jcmVhdGVTaGFwZShcclxuICAgICAgICBlbGVtZW50LFxyXG4gICAgICAgIHBpY2soZWxlbWVudCwgWyAneCcsICd5JywgJ3dpZHRoJywgJ2hlaWdodCcgXSksXHJcbiAgICAgICAgZWxlbWVudC5wYXJlbnQgfHwgcGFyZW50LFxyXG4gICAgICAgIGNyZWF0ZVNoYXBlSGludHNcclxuICAgICAgKTtcclxuICB9KTtcclxuXHJcbiAgY29udGV4dC5lbGVtZW50cyA9IHZhbHVlcyhjYWNoZSk7XHJcbn07XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIGlzQ29ubmVjdGlvbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuICEhZWxlbWVudC53YXlwb2ludHM7XHJcbn0iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ3JlYXRlU2hhcGVIYW5kbGVyIGZyb20gJy4vQ3JlYXRlU2hhcGVIYW5kbGVyJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGF0dGFjaGVzIGEgbGFiZWwgdG8gYSBnaXZlbiB0YXJnZXQgc2hhcGUuXG4gKlxuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVMYWJlbEhhbmRsZXIoY2FudmFzKSB7XG4gIENyZWF0ZVNoYXBlSGFuZGxlci5jYWxsKHRoaXMsIGNhbnZhcyk7XG59XG5cbmluaGVyaXRzKENyZWF0ZUxhYmVsSGFuZGxlciwgQ3JlYXRlU2hhcGVIYW5kbGVyKTtcblxuQ3JlYXRlTGFiZWxIYW5kbGVyLiRpbmplY3QgPSBbICdjYW52YXMnIF07XG5cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuXG52YXIgb3JpZ2luYWxFeGVjdXRlID0gQ3JlYXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlO1xuXG4vKipcbiAqIEFwcGVuZHMgYSBsYWJlbCB0byBhIHRhcmdldCBzaGFwZS5cbiAqXG4gKiBAbWV0aG9kIENyZWF0ZUxhYmVsSGFuZGxlciNleGVjdXRlXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEBwYXJhbSB7RWxlbWVudERlc2NyaXB0b3J9IGNvbnRleHQudGFyZ2V0IHRoZSBlbGVtZW50IHRoZSBsYWJlbCBpcyBhdHRhY2hlZCB0b1xuICogQHBhcmFtIHtFbGVtZW50RGVzY3JpcHRvcn0gY29udGV4dC5wYXJlbnQgdGhlIHBhcmVudCBvYmplY3RcbiAqIEBwYXJhbSB7UG9pbnR9IGNvbnRleHQucG9zaXRpb24gcG9zaXRpb24gb2YgdGhlIG5ldyBlbGVtZW50XG4gKi9cbkNyZWF0ZUxhYmVsSGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgbGFiZWwgPSBjb250ZXh0LnNoYXBlO1xuXG4gIGVuc3VyZVZhbGlkRGltZW5zaW9ucyhsYWJlbCk7XG5cbiAgbGFiZWwubGFiZWxUYXJnZXQgPSBjb250ZXh0LmxhYmVsVGFyZ2V0O1xuXG4gIHJldHVybiBvcmlnaW5hbEV4ZWN1dGUuY2FsbCh0aGlzLCBjb250ZXh0KTtcbn07XG5cbnZhciBvcmlnaW5hbFJldmVydCA9IENyZWF0ZVNoYXBlSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0O1xuXG4vKipcbiAqIFVuZG8gYXBwZW5kIGJ5IHJlbW92aW5nIHRoZSBzaGFwZVxuICovXG5DcmVhdGVMYWJlbEhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgY29udGV4dC5zaGFwZS5sYWJlbFRhcmdldCA9IG51bGw7XG5cbiAgcmV0dXJuIG9yaWdpbmFsUmV2ZXJ0LmNhbGwodGhpcywgY29udGV4dCk7XG59O1xuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBlbnN1cmVWYWxpZERpbWVuc2lvbnMobGFiZWwpIHtcblxuICAvLyBtYWtlIHN1cmUgYSBsYWJlbCBoYXMgdmFsaWQgeyB3aWR0aCwgaGVpZ2h0IH0gZGltZW5zaW9uc1xuICBbICd3aWR0aCcsICdoZWlnaHQnIF0uZm9yRWFjaChmdW5jdGlvbihwcm9wKSB7XG4gICAgaWYgKHR5cGVvZiBsYWJlbFtwcm9wXSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIGxhYmVsW3Byb3BdID0gMDtcbiAgICB9XG4gIH0pO1xufSIsImltcG9ydCB7IGFzc2lnbiB9IGZyb20gJ21pbi1kYXNoJztcblxudmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgcmV2ZXJzaWJsZSBhZGRpdGlvbiBvZiBzaGFwZXMuXG4gKlxuICogQHBhcmFtIHtjYW52YXN9IENhbnZhc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVTaGFwZUhhbmRsZXIoY2FudmFzKSB7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbn1cblxuQ3JlYXRlU2hhcGVIYW5kbGVyLiRpbmplY3QgPSBbICdjYW52YXMnIF07XG5cblxuLy8gYXBpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuXG4vKipcbiAqIEFwcGVuZHMgYSBzaGFwZSB0byBhIHRhcmdldCBzaGFwZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBjb250ZXh0LnBhcmVudCB0aGUgcGFyZW50IG9iamVjdFxuICogQHBhcmFtIHtQb2ludH0gY29udGV4dC5wb3NpdGlvbiBwb3NpdGlvbiBvZiB0aGUgbmV3IGVsZW1lbnRcbiAqL1xuQ3JlYXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBwb3NpdGlvbk9yQm91bmRzID0gY29udGV4dC5wb3NpdGlvbixcbiAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50LFxuICAgICAgcGFyZW50SW5kZXggPSBjb250ZXh0LnBhcmVudEluZGV4O1xuXG4gIGlmICghcGFyZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdwYXJlbnQgcmVxdWlyZWQnKTtcbiAgfVxuXG4gIGlmICghcG9zaXRpb25PckJvdW5kcykge1xuICAgIHRocm93IG5ldyBFcnJvcigncG9zaXRpb24gcmVxdWlyZWQnKTtcbiAgfVxuXG4gIC8vICgxKSBhZGQgYXQgZXZlbnQgY2VudGVyIHBvc2l0aW9uIF9vcl8gYXQgZ2l2ZW4gYm91bmRzXG4gIGlmIChwb3NpdGlvbk9yQm91bmRzLndpZHRoICE9PSB1bmRlZmluZWQpIHtcbiAgICBhc3NpZ24oc2hhcGUsIHBvc2l0aW9uT3JCb3VuZHMpO1xuICB9IGVsc2Uge1xuICAgIGFzc2lnbihzaGFwZSwge1xuICAgICAgeDogcG9zaXRpb25PckJvdW5kcy54IC0gcm91bmQoc2hhcGUud2lkdGggLyAyKSxcbiAgICAgIHk6IHBvc2l0aW9uT3JCb3VuZHMueSAtIHJvdW5kKHNoYXBlLmhlaWdodCAvIDIpXG4gICAgfSk7XG4gIH1cblxuICAvLyAoMikgYWRkIHRvIGNhbnZhc1xuICB0aGlzLl9jYW52YXMuYWRkU2hhcGUoc2hhcGUsIHBhcmVudCwgcGFyZW50SW5kZXgpO1xuXG4gIHJldHVybiBzaGFwZTtcbn07XG5cblxuLyoqXG4gKiBVbmRvIGFwcGVuZCBieSByZW1vdmluZyB0aGUgc2hhcGVcbiAqL1xuQ3JlYXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZTtcblxuICAvLyAoMykgcmVtb3ZlIGZvcm0gY2FudmFzXG4gIHRoaXMuX2NhbnZhcy5yZW1vdmVTaGFwZShzaGFwZSk7XG5cbiAgcmV0dXJuIHNoYXBlO1xufTsiLCJpbXBvcnQge1xuICBhZGQgYXMgY29sbGVjdGlvbkFkZCxcbiAgaW5kZXhPZiBhcyBjb2xsZWN0aW9uSWR4XG59IGZyb20gJy4uLy4uLy4uL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyByZXZlcnNpYmxlIGRlbGV0aW9uIG9mIENvbm5lY3Rpb25zLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEZWxldGVDb25uZWN0aW9uSGFuZGxlcihjYW52YXMsIG1vZGVsaW5nKSB7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbn1cblxuRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXIuJGluamVjdCA9IFtcbiAgJ2NhbnZhcycsXG4gICdtb2RlbGluZydcbl07XG5cblxuRGVsZXRlQ29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICBwYXJlbnQgPSBjb25uZWN0aW9uLnBhcmVudDtcblxuICBjb250ZXh0LnBhcmVudCA9IHBhcmVudDtcblxuICAvLyByZW1lbWJlciBjb250YWlubWVudFxuICBjb250ZXh0LnBhcmVudEluZGV4ID0gY29sbGVjdGlvbklkeChwYXJlbnQuY2hpbGRyZW4sIGNvbm5lY3Rpb24pO1xuXG4gIGNvbnRleHQuc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2U7XG4gIGNvbnRleHQudGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQ7XG5cbiAgdGhpcy5fY2FudmFzLnJlbW92ZUNvbm5lY3Rpb24oY29ubmVjdGlvbik7XG5cbiAgY29ubmVjdGlvbi5zb3VyY2UgPSBudWxsO1xuICBjb25uZWN0aW9uLnRhcmdldCA9IG51bGw7XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59O1xuXG4vKipcbiAqIENvbW1hbmQgcmV2ZXJ0IGltcGxlbWVudGF0aW9uLlxuICovXG5EZWxldGVDb25uZWN0aW9uSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgcGFyZW50ID0gY29udGV4dC5wYXJlbnQsXG4gICAgICBwYXJlbnRJbmRleCA9IGNvbnRleHQucGFyZW50SW5kZXg7XG5cbiAgY29ubmVjdGlvbi5zb3VyY2UgPSBjb250ZXh0LnNvdXJjZTtcbiAgY29ubmVjdGlvbi50YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAvLyByZXN0b3JlIGNvbnRhaW5tZW50XG4gIGNvbGxlY3Rpb25BZGQocGFyZW50LmNoaWxkcmVuLCBjb25uZWN0aW9uLCBwYXJlbnRJbmRleCk7XG5cbiAgdGhpcy5fY2FudmFzLmFkZENvbm5lY3Rpb24oY29ubmVjdGlvbiwgcGFyZW50KTtcblxuICByZXR1cm4gY29ubmVjdGlvbjtcbn07XG4iLCJpbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIERlbGV0ZUVsZW1lbnRzSGFuZGxlcihtb2RlbGluZywgZWxlbWVudFJlZ2lzdHJ5KSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbn1cblxuRGVsZXRlRWxlbWVudHNIYW5kbGVyLiRpbmplY3QgPSBbXG4gICdtb2RlbGluZycsXG4gICdlbGVtZW50UmVnaXN0cnknXG5dO1xuXG5cbkRlbGV0ZUVsZW1lbnRzSGFuZGxlci5wcm90b3R5cGUucG9zdEV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmcsXG4gICAgICBlbGVtZW50UmVnaXN0cnkgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnksXG4gICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHM7XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgLy8gZWxlbWVudCBtYXkgaGF2ZSBiZWVuIHJlbW92ZWQgd2l0aCBwcmV2aW91c1xuICAgIC8vIHJlbW92ZSBvcGVyYXRpb25zIGFscmVhZHkgKGUuZy4gaW4gY2FzZSBvZiBuZXN0aW5nKVxuICAgIGlmICghZWxlbWVudFJlZ2lzdHJ5LmdldChlbGVtZW50LmlkKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlQ29ubmVjdGlvbihlbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbW9kZWxpbmcucmVtb3ZlU2hhcGUoZWxlbWVudCk7XG4gICAgfVxuICB9KTtcbn07IiwiaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIGluZGV4T2YgYXMgY29sbGVjdGlvbklkeFxufSBmcm9tICcuLi8uLi8uLi91dGlsL0NvbGxlY3Rpb25zJztcblxuaW1wb3J0IHsgc2F2ZUNsZWFyIH0gZnJvbSAnLi4vLi4vLi4vdXRpbC9SZW1vdmFsJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgcmV2ZXJzaWJsZSBkZWxldGlvbiBvZiBzaGFwZXMuXG4gKlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBEZWxldGVTaGFwZUhhbmRsZXIoY2FudmFzLCBtb2RlbGluZykge1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cbkRlbGV0ZVNoYXBlSGFuZGxlci4kaW5qZWN0ID0gWyAnY2FudmFzJywgJ21vZGVsaW5nJyBdO1xuXG5cbi8qKlxuICogLSBSZW1vdmUgY29ubmVjdGlvbnNcbiAqIC0gUmVtb3ZlIGFsbCBkaXJlY3QgY2hpbGRyZW5cbiAqL1xuRGVsZXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5wcmVFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBtb2RlbGluZyA9IHRoaXMuX21vZGVsaW5nO1xuXG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG5cbiAgLy8gcmVtb3ZlIGNvbm5lY3Rpb25zXG4gIHNhdmVDbGVhcihzaGFwZS5pbmNvbWluZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuXG4gICAgLy8gVG8gbWFrZSBzdXJlIHRoYXQgdGhlIGNvbm5lY3Rpb24gaXNuJ3QgcmVtb3ZlZCB0d2ljZVxuICAgIC8vIEZvciBleGFtcGxlIGlmIGEgY29udGFpbmVyIGlzIHJlbW92ZWRcbiAgICBtb2RlbGluZy5yZW1vdmVDb25uZWN0aW9uKGNvbm5lY3Rpb24sIHsgbmVzdGVkOiB0cnVlIH0pO1xuICB9KTtcblxuICBzYXZlQ2xlYXIoc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICBtb2RlbGluZy5yZW1vdmVDb25uZWN0aW9uKGNvbm5lY3Rpb24sIHsgbmVzdGVkOiB0cnVlIH0pO1xuICB9KTtcblxuICAvLyByZW1vdmUgY2hpbGQgc2hhcGVzIGFuZCBjb25uZWN0aW9uc1xuICBzYXZlQ2xlYXIoc2hhcGUuY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgaWYgKGlzQ29ubmVjdGlvbihjaGlsZCkpIHtcbiAgICAgIG1vZGVsaW5nLnJlbW92ZUNvbm5lY3Rpb24oY2hpbGQsIHsgbmVzdGVkOiB0cnVlIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBtb2RlbGluZy5yZW1vdmVTaGFwZShjaGlsZCwgeyBuZXN0ZWQ6IHRydWUgfSk7XG4gICAgfVxuICB9KTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIHNoYXBlIGFuZCByZW1lbWJlciB0aGUgcGFyZW50XG4gKi9cbkRlbGV0ZVNoYXBlSGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIGNhbnZhcyA9IHRoaXMuX2NhbnZhcztcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgb2xkUGFyZW50ID0gc2hhcGUucGFyZW50O1xuXG4gIGNvbnRleHQub2xkUGFyZW50ID0gb2xkUGFyZW50O1xuXG4gIC8vIHJlbW92ZSBjb250YWlubWVudFxuICBjb250ZXh0Lm9sZFBhcmVudEluZGV4ID0gY29sbGVjdGlvbklkeChvbGRQYXJlbnQuY2hpbGRyZW4sIHNoYXBlKTtcblxuICAvLyByZW1vdmUgc2hhcGVcbiAgY2FudmFzLnJlbW92ZVNoYXBlKHNoYXBlKTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG5cbi8qKlxuICogQ29tbWFuZCByZXZlcnQgaW1wbGVtZW50YXRpb25cbiAqL1xuRGVsZXRlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGNhbnZhcyA9IHRoaXMuX2NhbnZhcztcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgb2xkUGFyZW50ID0gY29udGV4dC5vbGRQYXJlbnQsXG4gICAgICBvbGRQYXJlbnRJbmRleCA9IGNvbnRleHQub2xkUGFyZW50SW5kZXg7XG5cbiAgLy8gcmVzdG9yZSBjb250YWlubWVudFxuICBjb2xsZWN0aW9uQWRkKG9sZFBhcmVudC5jaGlsZHJlbiwgc2hhcGUsIG9sZFBhcmVudEluZGV4KTtcblxuICBjYW52YXMuYWRkU2hhcGUoc2hhcGUsIG9sZFBhcmVudCk7XG5cbiAgcmV0dXJuIHNoYXBlO1xufTtcblxuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQud2F5cG9pbnRzO1xufVxuIiwiaW1wb3J0IHtcbiAgZm9yRWFjaCxcbiAgc29ydEJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGRpc3RyaWJ1dGVzIGVsZW1lbnRzIGV2ZW5seS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRGlzdHJpYnV0ZUVsZW1lbnRzKG1vZGVsaW5nKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cbkRpc3RyaWJ1dGVFbGVtZW50cy4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cbnZhciBPRkZfQVhJUyA9IHtcbiAgeDogJ3knLFxuICB5OiAneCdcbn07XG5cbkRpc3RyaWJ1dGVFbGVtZW50cy5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmc7XG5cbiAgdmFyIGdyb3VwcyA9IGNvbnRleHQuZ3JvdXBzLFxuICAgICAgYXhpcyA9IGNvbnRleHQuYXhpcyxcbiAgICAgIGRpbWVuc2lvbiA9IGNvbnRleHQuZGltZW5zaW9uO1xuXG4gIGZ1bmN0aW9uIHVwZGF0ZVJhbmdlKGdyb3VwLCBlbGVtZW50KSB7XG4gICAgZ3JvdXAucmFuZ2UubWluID0gTWF0aC5taW4oZWxlbWVudFtheGlzXSwgZ3JvdXAucmFuZ2UubWluKTtcbiAgICBncm91cC5yYW5nZS5tYXggPSBNYXRoLm1heChlbGVtZW50W2F4aXNdICsgZWxlbWVudFtkaW1lbnNpb25dLCBncm91cC5yYW5nZS5tYXgpO1xuICB9XG5cbiAgZnVuY3Rpb24gY2VudGVyKGVsZW1lbnQpIHtcbiAgICByZXR1cm4gZWxlbWVudFtheGlzXSArIGVsZW1lbnRbZGltZW5zaW9uXSAvIDI7XG4gIH1cblxuICBmdW5jdGlvbiBsYXN0SWR4KGFycikge1xuICAgIHJldHVybiBhcnIubGVuZ3RoIC0gMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJhbmdlRGlmZihyYW5nZSkge1xuICAgIHJldHVybiByYW5nZS5tYXggLSByYW5nZS5taW47XG4gIH1cblxuICBmdW5jdGlvbiBjZW50ZXJFbGVtZW50KHJlZkNlbnRlciwgZWxlbWVudCkge1xuICAgIHZhciBkZWx0YSA9IHsgeTogMCB9O1xuXG4gICAgZGVsdGFbYXhpc10gPSByZWZDZW50ZXIgLSBjZW50ZXIoZWxlbWVudCk7XG5cbiAgICBpZiAoZGVsdGFbYXhpc10pIHtcblxuICAgICAgZGVsdGFbT0ZGX0FYSVNbYXhpc11dID0gMDtcblxuICAgICAgbW9kZWxpbmcubW92ZUVsZW1lbnRzKFsgZWxlbWVudCBdLCBkZWx0YSwgZWxlbWVudC5wYXJlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHZhciBmaXJzdEdyb3VwID0gZ3JvdXBzWzBdLFxuICAgICAgbGFzdEdyb3VwSWR4ID0gbGFzdElkeChncm91cHMpLFxuICAgICAgbGFzdEdyb3VwID0gZ3JvdXBzWyBsYXN0R3JvdXBJZHggXTtcblxuICB2YXIgbWFyZ2luLFxuICAgICAgc3BhY2VJbkJldHdlZW4sXG4gICAgICBncm91cHNTaXplID0gMDsgLy8gdGhlIHNpemUgb2YgZWFjaCByYW5nZVxuXG4gIGZvckVhY2goZ3JvdXBzLCBmdW5jdGlvbihncm91cCwgaWR4KSB7XG4gICAgdmFyIHNvcnRlZEVsZW1lbnRzLFxuICAgICAgICByZWZFbGVtLFxuICAgICAgICByZWZDZW50ZXI7XG5cbiAgICBpZiAoZ3JvdXAuZWxlbWVudHMubGVuZ3RoIDwgMikge1xuICAgICAgaWYgKGlkeCAmJiBpZHggIT09IGdyb3Vwcy5sZW5ndGggLSAxKSB7XG4gICAgICAgIHVwZGF0ZVJhbmdlKGdyb3VwLCBncm91cC5lbGVtZW50c1swXSk7XG5cbiAgICAgICAgZ3JvdXBzU2l6ZSArPSByYW5nZURpZmYoZ3JvdXAucmFuZ2UpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHNvcnRlZEVsZW1lbnRzID0gc29ydEJ5KGdyb3VwLmVsZW1lbnRzLCBheGlzKTtcblxuICAgIHJlZkVsZW0gPSBzb3J0ZWRFbGVtZW50c1swXTtcblxuICAgIGlmIChpZHggPT09IGxhc3RHcm91cElkeCkge1xuICAgICAgcmVmRWxlbSA9IHNvcnRlZEVsZW1lbnRzW2xhc3RJZHgoc29ydGVkRWxlbWVudHMpXTtcbiAgICB9XG5cbiAgICByZWZDZW50ZXIgPSBjZW50ZXIocmVmRWxlbSk7XG5cbiAgICAvLyB3YW5uYSB1cGRhdGUgdGhlIHJhbmdlcyBhZnRlciB0aGUgc2hhcGVzIGhhdmUgYmVlbiBjZW50ZXJlZFxuICAgIGdyb3VwLnJhbmdlID0gbnVsbDtcblxuICAgIGZvckVhY2goc29ydGVkRWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICAgICAgY2VudGVyRWxlbWVudChyZWZDZW50ZXIsIGVsZW1lbnQpO1xuXG4gICAgICBpZiAoZ3JvdXAucmFuZ2UgPT09IG51bGwpIHtcbiAgICAgICAgZ3JvdXAucmFuZ2UgPSB7XG4gICAgICAgICAgbWluOiBlbGVtZW50W2F4aXNdLFxuICAgICAgICAgIG1heDogZWxlbWVudFtheGlzXSArIGVsZW1lbnRbZGltZW5zaW9uXVxuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gdXBkYXRlIGdyb3VwJ3MgcmFuZ2UgYWZ0ZXIgY2VudGVyaW5nIHRoZSByYW5nZSBlbGVtZW50c1xuICAgICAgdXBkYXRlUmFuZ2UoZ3JvdXAsIGVsZW1lbnQpO1xuICAgIH0pO1xuXG4gICAgaWYgKGlkeCAmJiBpZHggIT09IGdyb3Vwcy5sZW5ndGggLSAxKSB7XG4gICAgICBncm91cHNTaXplICs9IHJhbmdlRGlmZihncm91cC5yYW5nZSk7XG4gICAgfVxuICB9KTtcblxuICBzcGFjZUluQmV0d2VlbiA9IE1hdGguYWJzKGxhc3RHcm91cC5yYW5nZS5taW4gLSBmaXJzdEdyb3VwLnJhbmdlLm1heCk7XG5cbiAgbWFyZ2luID0gTWF0aC5yb3VuZCgoc3BhY2VJbkJldHdlZW4gLSBncm91cHNTaXplKSAvIChncm91cHMubGVuZ3RoIC0gMSkpO1xuXG4gIGlmIChtYXJnaW4gPCBncm91cHMubGVuZ3RoIC0gMSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvckVhY2goZ3JvdXBzLCBmdW5jdGlvbihncm91cCwgZ3JvdXBJZHgpIHtcbiAgICB2YXIgZGVsdGEgPSB7fSxcbiAgICAgICAgcHJldkdyb3VwO1xuXG4gICAgaWYgKGdyb3VwID09PSBmaXJzdEdyb3VwIHx8IGdyb3VwID09PSBsYXN0R3JvdXApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBwcmV2R3JvdXAgPSBncm91cHNbZ3JvdXBJZHggLSAxXTtcblxuICAgIGdyb3VwLnJhbmdlLm1heCA9IDA7XG5cbiAgICBmb3JFYWNoKGdyb3VwLmVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50LCBpZHgpIHtcbiAgICAgIGRlbHRhW09GRl9BWElTW2F4aXNdXSA9IDA7XG4gICAgICBkZWx0YVtheGlzXSA9IChwcmV2R3JvdXAucmFuZ2UubWF4IC0gZWxlbWVudFtheGlzXSkgKyBtYXJnaW47XG5cbiAgICAgIGlmIChncm91cC5yYW5nZS5taW4gIT09IGVsZW1lbnRbYXhpc10pIHtcbiAgICAgICAgZGVsdGFbYXhpc10gKz0gZWxlbWVudFtheGlzXSAtIGdyb3VwLnJhbmdlLm1pbjtcbiAgICAgIH1cblxuICAgICAgaWYgKGRlbHRhW2F4aXNdKSB7XG4gICAgICAgIG1vZGVsaW5nLm1vdmVFbGVtZW50cyhbIGVsZW1lbnQgXSwgZGVsdGEsIGVsZW1lbnQucGFyZW50KTtcbiAgICAgIH1cblxuICAgICAgZ3JvdXAucmFuZ2UubWF4ID0gTWF0aC5tYXgoZWxlbWVudFtheGlzXSArIGVsZW1lbnRbZGltZW5zaW9uXSwgaWR4ID8gZ3JvdXAucmFuZ2UubWF4IDogMCk7XG4gICAgfSk7XG4gIH0pO1xufTtcblxuRGlzdHJpYnV0ZUVsZW1lbnRzLnByb3RvdHlwZS5wb3N0RXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxufTtcbiIsImltcG9ydCB7IGFzc2lnbiB9IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IGltcGxlbWVudHMgcmV2ZXJzaWJsZSBtb3Zpbmcgb2Ygc2hhcGVzLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBMYXlvdXRDb25uZWN0aW9uSGFuZGxlcihsYXlvdXRlciwgY2FudmFzKSB7XG4gIHRoaXMuX2xheW91dGVyID0gbGF5b3V0ZXI7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbn1cblxuTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXIuJGluamVjdCA9IFsgJ2xheW91dGVyJywgJ2NhbnZhcycgXTtcblxuTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb247XG5cbiAgdmFyIG9sZFdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzO1xuXG4gIGFzc2lnbihjb250ZXh0LCB7XG4gICAgb2xkV2F5cG9pbnRzOiBvbGRXYXlwb2ludHNcbiAgfSk7XG5cbiAgY29ubmVjdGlvbi53YXlwb2ludHMgPSB0aGlzLl9sYXlvdXRlci5sYXlvdXRDb25uZWN0aW9uKGNvbm5lY3Rpb24sIGNvbnRleHQuaGludHMpO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTtcblxuTGF5b3V0Q29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbjtcblxuICBjb25uZWN0aW9uLndheXBvaW50cyA9IGNvbnRleHQub2xkV2F5cG9pbnRzO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTtcbiIsImltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cblxuaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIHJlbW92ZSBhcyBjb2xsZWN0aW9uUmVtb3ZlXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyByZXZlcnNpYmxlIG1vdmluZyBvZiBjb25uZWN0aW9ucy5cbiAqXG4gKiBUaGUgaGFuZGxlciBkaWZmZXJzIGZyb20gdGhlIGxheW91dCBjb25uZWN0aW9uIGhhbmRsZXIgaW4gYSBzZW5zZVxuICogdGhhdCBpdCBwcmVzZXJ2ZXMgdGhlIGNvbm5lY3Rpb24gbGF5b3V0LlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb3ZlQ29ubmVjdGlvbkhhbmRsZXIoKSB7IH1cblxuXG5Nb3ZlQ29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICBkZWx0YSA9IGNvbnRleHQuZGVsdGE7XG5cbiAgdmFyIG5ld1BhcmVudCA9IGNvbnRleHQubmV3UGFyZW50IHx8IGNvbm5lY3Rpb24ucGFyZW50LFxuICAgICAgbmV3UGFyZW50SW5kZXggPSBjb250ZXh0Lm5ld1BhcmVudEluZGV4LFxuICAgICAgb2xkUGFyZW50ID0gY29ubmVjdGlvbi5wYXJlbnQ7XG5cbiAgLy8gc2F2ZSBvbGQgcGFyZW50IGluIGNvbnRleHRcbiAgY29udGV4dC5vbGRQYXJlbnQgPSBvbGRQYXJlbnQ7XG4gIGNvbnRleHQub2xkUGFyZW50SW5kZXggPSBjb2xsZWN0aW9uUmVtb3ZlKG9sZFBhcmVudC5jaGlsZHJlbiwgY29ubmVjdGlvbik7XG5cbiAgLy8gYWRkIHRvIG5ldyBwYXJlbnQgYXQgcG9zaXRpb25cbiAgY29sbGVjdGlvbkFkZChuZXdQYXJlbnQuY2hpbGRyZW4sIGNvbm5lY3Rpb24sIG5ld1BhcmVudEluZGV4KTtcblxuICAvLyB1cGRhdGUgcGFyZW50XG4gIGNvbm5lY3Rpb24ucGFyZW50ID0gbmV3UGFyZW50O1xuXG4gIC8vIHVwZGF0ZSB3YXlwb2ludCBwb3NpdGlvbnNcbiAgZm9yRWFjaChjb25uZWN0aW9uLndheXBvaW50cywgZnVuY3Rpb24ocCkge1xuICAgIHAueCArPSBkZWx0YS54O1xuICAgIHAueSArPSBkZWx0YS55O1xuXG4gICAgaWYgKHAub3JpZ2luYWwpIHtcbiAgICAgIHAub3JpZ2luYWwueCArPSBkZWx0YS54O1xuICAgICAgcC5vcmlnaW5hbC55ICs9IGRlbHRhLnk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gY29ubmVjdGlvbjtcbn07XG5cbk1vdmVDb25uZWN0aW9uSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgbmV3UGFyZW50ID0gY29ubmVjdGlvbi5wYXJlbnQsXG4gICAgICBvbGRQYXJlbnQgPSBjb250ZXh0Lm9sZFBhcmVudCxcbiAgICAgIG9sZFBhcmVudEluZGV4ID0gY29udGV4dC5vbGRQYXJlbnRJbmRleCxcbiAgICAgIGRlbHRhID0gY29udGV4dC5kZWx0YTtcblxuICAvLyByZW1vdmUgZnJvbSBuZXdQYXJlbnRcbiAgY29sbGVjdGlvblJlbW92ZShuZXdQYXJlbnQuY2hpbGRyZW4sIGNvbm5lY3Rpb24pO1xuXG4gIC8vIHJlc3RvcmUgcHJldmlvdXMgbG9jYXRpb24gaW4gb2xkIHBhcmVudFxuICBjb2xsZWN0aW9uQWRkKG9sZFBhcmVudC5jaGlsZHJlbiwgY29ubmVjdGlvbiwgb2xkUGFyZW50SW5kZXgpO1xuXG4gIC8vIHJlc3RvcmUgcGFyZW50XG4gIGNvbm5lY3Rpb24ucGFyZW50ID0gb2xkUGFyZW50O1xuXG4gIC8vIHJldmVydCB0byBvbGQgd2F5cG9pbnQgcG9zaXRpb25zXG4gIGZvckVhY2goY29ubmVjdGlvbi53YXlwb2ludHMsIGZ1bmN0aW9uKHApIHtcbiAgICBwLnggLT0gZGVsdGEueDtcbiAgICBwLnkgLT0gZGVsdGEueTtcblxuICAgIGlmIChwLm9yaWdpbmFsKSB7XG4gICAgICBwLm9yaWdpbmFsLnggLT0gZGVsdGEueDtcbiAgICAgIHAub3JpZ2luYWwueSAtPSBkZWx0YS55O1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59OyIsImltcG9ydCBNb3ZlSGVscGVyIGZyb20gJy4vaGVscGVyL01vdmVIZWxwZXInO1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyByZXZlcnNpYmxlIG1vdmluZyBvZiBzaGFwZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1vdmVFbGVtZW50c0hhbmRsZXIobW9kZWxpbmcpIHtcbiAgdGhpcy5faGVscGVyID0gbmV3IE1vdmVIZWxwZXIobW9kZWxpbmcpO1xufVxuXG5Nb3ZlRWxlbWVudHNIYW5kbGVyLiRpbmplY3QgPSBbICdtb2RlbGluZycgXTtcblxuTW92ZUVsZW1lbnRzSGFuZGxlci5wcm90b3R5cGUucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgY29udGV4dC5jbG9zdXJlID0gdGhpcy5faGVscGVyLmdldENsb3N1cmUoY29udGV4dC5zaGFwZXMpO1xufTtcblxuTW92ZUVsZW1lbnRzSGFuZGxlci5wcm90b3R5cGUucG9zdEV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGhpbnRzID0gY29udGV4dC5oaW50cyxcbiAgICAgIHByaW1hcnlTaGFwZTtcblxuICBpZiAoaGludHMgJiYgaGludHMucHJpbWFyeVNoYXBlKSB7XG4gICAgcHJpbWFyeVNoYXBlID0gaGludHMucHJpbWFyeVNoYXBlO1xuICAgIGhpbnRzLm9sZFBhcmVudCA9IHByaW1hcnlTaGFwZS5wYXJlbnQ7XG4gIH1cblxuICB0aGlzLl9oZWxwZXIubW92ZUNsb3N1cmUoXG4gICAgY29udGV4dC5jbG9zdXJlLFxuICAgIGNvbnRleHQuZGVsdGEsXG4gICAgY29udGV4dC5uZXdQYXJlbnQsXG4gICAgY29udGV4dC5uZXdIb3N0LFxuICAgIHByaW1hcnlTaGFwZVxuICApO1xufTsiLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIHBpY2tcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgTW92ZUhlbHBlciBmcm9tICcuL2hlbHBlci9Nb3ZlSGVscGVyJztcblxuaW1wb3J0IHtcbiAgYWRkIGFzIGNvbGxlY3Rpb25BZGQsXG4gIHJlbW92ZSBhcyBjb2xsZWN0aW9uUmVtb3ZlXG59IGZyb20gJy4uLy4uLy4uL3V0aWwvQ29sbGVjdGlvbnMnO1xuXG5pbXBvcnQge1xuICBnZXRNb3ZlZFNvdXJjZUFuY2hvcixcbiAgZ2V0TW92ZWRUYXJnZXRBbmNob3Jcbn0gZnJvbSAnLi9oZWxwZXIvQW5jaG9yc0hlbHBlcic7XG5cblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBpbXBsZW1lbnRzIHJldmVyc2libGUgbW92aW5nIG9mIHNoYXBlcy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW92ZVNoYXBlSGFuZGxlcihtb2RlbGluZykge1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xuXG4gIHRoaXMuX2hlbHBlciA9IG5ldyBNb3ZlSGVscGVyKG1vZGVsaW5nKTtcbn1cblxuTW92ZVNoYXBlSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cblxuTW92ZVNoYXBlSGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgZGVsdGEgPSBjb250ZXh0LmRlbHRhLFxuICAgICAgbmV3UGFyZW50ID0gY29udGV4dC5uZXdQYXJlbnQgfHwgc2hhcGUucGFyZW50LFxuICAgICAgbmV3UGFyZW50SW5kZXggPSBjb250ZXh0Lm5ld1BhcmVudEluZGV4LFxuICAgICAgb2xkUGFyZW50ID0gc2hhcGUucGFyZW50O1xuXG4gIGNvbnRleHQub2xkQm91bmRzID0gcGljayhzaGFwZSwgWyAneCcsICd5JywgJ3dpZHRoJywgJ2hlaWdodCddKTtcblxuICAvLyBzYXZlIG9sZCBwYXJlbnQgaW4gY29udGV4dFxuICBjb250ZXh0Lm9sZFBhcmVudCA9IG9sZFBhcmVudDtcbiAgY29udGV4dC5vbGRQYXJlbnRJbmRleCA9IGNvbGxlY3Rpb25SZW1vdmUob2xkUGFyZW50LmNoaWxkcmVuLCBzaGFwZSk7XG5cbiAgLy8gYWRkIHRvIG5ldyBwYXJlbnQgYXQgcG9zaXRpb25cbiAgY29sbGVjdGlvbkFkZChuZXdQYXJlbnQuY2hpbGRyZW4sIHNoYXBlLCBuZXdQYXJlbnRJbmRleCk7XG5cbiAgLy8gdXBkYXRlIHNoYXBlIHBhcmVudCArIHBvc2l0aW9uXG4gIGFzc2lnbihzaGFwZSwge1xuICAgIHBhcmVudDogbmV3UGFyZW50LFxuICAgIHg6IHNoYXBlLnggKyBkZWx0YS54LFxuICAgIHk6IHNoYXBlLnkgKyBkZWx0YS55XG4gIH0pO1xuXG4gIHJldHVybiBzaGFwZTtcbn07XG5cbk1vdmVTaGFwZUhhbmRsZXIucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBkZWx0YSA9IGNvbnRleHQuZGVsdGEsXG4gICAgICBoaW50cyA9IGNvbnRleHQuaGludHM7XG5cbiAgdmFyIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmc7XG5cbiAgaWYgKGhpbnRzLmxheW91dCAhPT0gZmFsc2UpIHtcblxuICAgIGZvckVhY2goc2hhcGUuaW5jb21pbmcsIGZ1bmN0aW9uKGMpIHtcbiAgICAgIG1vZGVsaW5nLmxheW91dENvbm5lY3Rpb24oYywge1xuICAgICAgICBjb25uZWN0aW9uRW5kOiBnZXRNb3ZlZFRhcmdldEFuY2hvcihjLCBzaGFwZSwgZGVsdGEpXG4gICAgICB9KTtcbiAgICB9KTtcblxuICAgIGZvckVhY2goc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGMpIHtcbiAgICAgIG1vZGVsaW5nLmxheW91dENvbm5lY3Rpb24oYywge1xuICAgICAgICBjb25uZWN0aW9uU3RhcnQ6IGdldE1vdmVkU291cmNlQW5jaG9yKGMsIHNoYXBlLCBkZWx0YSlcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGhpbnRzLnJlY3Vyc2UgIT09IGZhbHNlKSB7XG4gICAgdGhpcy5tb3ZlQ2hpbGRyZW4oY29udGV4dCk7XG4gIH1cbn07XG5cbk1vdmVTaGFwZUhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgb2xkUGFyZW50ID0gY29udGV4dC5vbGRQYXJlbnQsXG4gICAgICBvbGRQYXJlbnRJbmRleCA9IGNvbnRleHQub2xkUGFyZW50SW5kZXgsXG4gICAgICBkZWx0YSA9IGNvbnRleHQuZGVsdGE7XG5cbiAgLy8gcmVzdG9yZSBwcmV2aW91cyBsb2NhdGlvbiBpbiBvbGQgcGFyZW50XG4gIGNvbGxlY3Rpb25BZGQob2xkUGFyZW50LmNoaWxkcmVuLCBzaGFwZSwgb2xkUGFyZW50SW5kZXgpO1xuXG4gIC8vIHJldmVydCB0byBvbGQgcG9zaXRpb24gYW5kIHBhcmVudFxuICBhc3NpZ24oc2hhcGUsIHtcbiAgICBwYXJlbnQ6IG9sZFBhcmVudCxcbiAgICB4OiBzaGFwZS54IC0gZGVsdGEueCxcbiAgICB5OiBzaGFwZS55IC0gZGVsdGEueVxuICB9KTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG5Nb3ZlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5tb3ZlQ2hpbGRyZW4gPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIGRlbHRhID0gY29udGV4dC5kZWx0YSxcbiAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZTtcblxuICB0aGlzLl9oZWxwZXIubW92ZVJlY3Vyc2l2ZShzaGFwZS5jaGlsZHJlbiwgZGVsdGEsIG51bGwpO1xufTtcblxuTW92ZVNoYXBlSGFuZGxlci5wcm90b3R5cGUuZ2V0TmV3UGFyZW50ID0gZnVuY3Rpb24oY29udGV4dCkge1xuICByZXR1cm4gY29udGV4dC5uZXdQYXJlbnQgfHwgY29udGV4dC5zaGFwZS5wYXJlbnQ7XG59O1xuIiwiaW1wb3J0IHsgaXNBcnJheSB9IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIFJlY29ubmVjdCBjb25uZWN0aW9uIGhhbmRsZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVjb25uZWN0Q29ubmVjdGlvbkhhbmRsZXIobW9kZWxpbmcpIHtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbn1cblxuUmVjb25uZWN0Q29ubmVjdGlvbkhhbmRsZXIuJGluamVjdCA9IFsgJ21vZGVsaW5nJyBdO1xuXG5SZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIG5ld1NvdXJjZSA9IGNvbnRleHQubmV3U291cmNlLFxuICAgICAgbmV3VGFyZ2V0ID0gY29udGV4dC5uZXdUYXJnZXQsXG4gICAgICBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgZG9ja2luZ09yUG9pbnRzID0gY29udGV4dC5kb2NraW5nT3JQb2ludHM7XG5cbiAgaWYgKCFuZXdTb3VyY2UgJiYgIW5ld1RhcmdldCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbmV3U291cmNlIG9yIG5ld1RhcmdldCByZXF1aXJlZCcpO1xuICB9XG5cbiAgaWYgKGlzQXJyYXkoZG9ja2luZ09yUG9pbnRzKSkge1xuICAgIGNvbnRleHQub2xkV2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG4gICAgY29ubmVjdGlvbi53YXlwb2ludHMgPSBkb2NraW5nT3JQb2ludHM7XG4gIH1cblxuICBpZiAobmV3U291cmNlKSB7XG4gICAgY29udGV4dC5vbGRTb3VyY2UgPSBjb25uZWN0aW9uLnNvdXJjZTtcbiAgICBjb25uZWN0aW9uLnNvdXJjZSA9IG5ld1NvdXJjZTtcbiAgfVxuXG4gIGlmIChuZXdUYXJnZXQpIHtcbiAgICBjb250ZXh0Lm9sZFRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0O1xuICAgIGNvbm5lY3Rpb24udGFyZ2V0ID0gbmV3VGFyZ2V0O1xuICB9XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59O1xuXG5SZWNvbm5lY3RDb25uZWN0aW9uSGFuZGxlci5wcm90b3R5cGUucG9zdEV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgbmV3U291cmNlID0gY29udGV4dC5uZXdTb3VyY2UsXG4gICAgICBuZXdUYXJnZXQgPSBjb250ZXh0Lm5ld1RhcmdldCxcbiAgICAgIGRvY2tpbmdPclBvaW50cyA9IGNvbnRleHQuZG9ja2luZ09yUG9pbnRzLFxuICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9O1xuXG4gIHZhciBsYXlvdXRDb25uZWN0aW9uSGludHMgPSB7fTtcblxuICBpZiAoaGludHMuY29ubmVjdGlvblN0YXJ0KSB7XG4gICAgbGF5b3V0Q29ubmVjdGlvbkhpbnRzLmNvbm5lY3Rpb25TdGFydCA9IGhpbnRzLmNvbm5lY3Rpb25TdGFydDtcbiAgfVxuXG4gIGlmIChoaW50cy5jb25uZWN0aW9uRW5kKSB7XG4gICAgbGF5b3V0Q29ubmVjdGlvbkhpbnRzLmNvbm5lY3Rpb25FbmQgPSBoaW50cy5jb25uZWN0aW9uRW5kO1xuICB9XG5cbiAgaWYgKGhpbnRzLmxheW91dENvbm5lY3Rpb24gPT09IGZhbHNlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKG5ld1NvdXJjZSAmJiAoIW5ld1RhcmdldCB8fCBoaW50cy5kb2NraW5nID09PSAnc291cmNlJykpIHtcbiAgICBsYXlvdXRDb25uZWN0aW9uSGludHMuY29ubmVjdGlvblN0YXJ0ID0gbGF5b3V0Q29ubmVjdGlvbkhpbnRzLmNvbm5lY3Rpb25TdGFydFxuICAgICAgfHwgZ2V0RG9ja2luZyhpc0FycmF5KGRvY2tpbmdPclBvaW50cykgPyBkb2NraW5nT3JQb2ludHNbIDAgXSA6IGRvY2tpbmdPclBvaW50cyk7XG4gIH1cblxuICBpZiAobmV3VGFyZ2V0ICYmICghbmV3U291cmNlIHx8IGhpbnRzLmRvY2tpbmcgPT09ICd0YXJnZXQnKSkge1xuICAgIGxheW91dENvbm5lY3Rpb25IaW50cy5jb25uZWN0aW9uRW5kID0gbGF5b3V0Q29ubmVjdGlvbkhpbnRzLmNvbm5lY3Rpb25FbmRcbiAgICAgIHx8IGdldERvY2tpbmcoaXNBcnJheShkb2NraW5nT3JQb2ludHMpID8gZG9ja2luZ09yUG9pbnRzWyBkb2NraW5nT3JQb2ludHMubGVuZ3RoIC0gMSBdIDogZG9ja2luZ09yUG9pbnRzKTtcbiAgfVxuXG4gIGlmIChoaW50cy5uZXdXYXlwb2ludHMpIHtcbiAgICBsYXlvdXRDb25uZWN0aW9uSGludHMud2F5cG9pbnRzID0gaGludHMubmV3V2F5cG9pbnRzO1xuICB9XG5cbiAgdGhpcy5fbW9kZWxpbmcubGF5b3V0Q29ubmVjdGlvbihjb25uZWN0aW9uLCBsYXlvdXRDb25uZWN0aW9uSGludHMpO1xufTtcblxuUmVjb25uZWN0Q29ubmVjdGlvbkhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIG9sZFNvdXJjZSA9IGNvbnRleHQub2xkU291cmNlLFxuICAgICAgb2xkVGFyZ2V0ID0gY29udGV4dC5vbGRUYXJnZXQsXG4gICAgICBvbGRXYXlwb2ludHMgPSBjb250ZXh0Lm9sZFdheXBvaW50cyxcbiAgICAgIGNvbm5lY3Rpb24gPSBjb250ZXh0LmNvbm5lY3Rpb247XG5cbiAgaWYgKG9sZFNvdXJjZSkge1xuICAgIGNvbm5lY3Rpb24uc291cmNlID0gb2xkU291cmNlO1xuICB9XG5cbiAgaWYgKG9sZFRhcmdldCkge1xuICAgIGNvbm5lY3Rpb24udGFyZ2V0ID0gb2xkVGFyZ2V0O1xuICB9XG5cbiAgaWYgKG9sZFdheXBvaW50cykge1xuICAgIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gb2xkV2F5cG9pbnRzO1xuICB9XG5cbiAgcmV0dXJuIGNvbm5lY3Rpb247XG59O1xuXG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGdldERvY2tpbmcocG9pbnQpIHtcbiAgcmV0dXJuIHBvaW50Lm9yaWdpbmFsIHx8IHBvaW50O1xufSIsImltcG9ydCB7IGZvckVhY2ggfSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGdldFJlc2l6ZWRTb3VyY2VBbmNob3IsXG4gIGdldFJlc2l6ZWRUYXJnZXRBbmNob3Jcbn0gZnJvbSAnLi9oZWxwZXIvQW5jaG9yc0hlbHBlcic7XG5cbi8qKlxuICogUmVwbGFjZSBzaGFwZSBieSBhZGRpbmcgbmV3IHNoYXBlIGFuZCByZW1vdmluZyBvbGQgc2hhcGUuIEluY29taW5nIGFuZCBvdXRnb2luZyBjb25uZWN0aW9ucyB3aWxsXG4gKiBiZSBrZXB0IGlmIHBvc3NpYmxlLlxuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqIEBwYXJhbSB7UnVsZXN9IHJ1bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlcGxhY2VTaGFwZUhhbmRsZXIobW9kZWxpbmcsIHJ1bGVzKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG4gIHRoaXMuX3J1bGVzID0gcnVsZXM7XG59XG5cblJlcGxhY2VTaGFwZUhhbmRsZXIuJGluamVjdCA9IFsgJ21vZGVsaW5nJywgJ3J1bGVzJyBdO1xuXG5cbi8qKlxuICogQWRkIG5ldyBzaGFwZS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICogQHBhcmFtIHtkanMubW9kZWwuU2hhcGV9IGNvbnRleHQub2xkU2hhcGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0Lm5ld0RhdGFcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZXh0Lm5ld0RhdGEudHlwZVxuICogQHBhcmFtIHtudW1iZXJ9IGNvbnRleHQubmV3RGF0YS54XG4gKiBAcGFyYW0ge251bWJlcn0gY29udGV4dC5uZXdEYXRhLnlcbiAqIEBwYXJhbSB7T2JqZWN0fSBbaGludHNdXG4gKi9cblJlcGxhY2VTaGFwZUhhbmRsZXIucHJvdG90eXBlLnByZUV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBzZWxmID0gdGhpcyxcbiAgICAgIG1vZGVsaW5nID0gdGhpcy5fbW9kZWxpbmcsXG4gICAgICBydWxlcyA9IHRoaXMuX3J1bGVzO1xuXG4gIHZhciBvbGRTaGFwZSA9IGNvbnRleHQub2xkU2hhcGUsXG4gICAgICBuZXdEYXRhID0gY29udGV4dC5uZXdEYXRhLFxuICAgICAgaGludHMgPSBjb250ZXh0LmhpbnRzIHx8IHt9LFxuICAgICAgbmV3U2hhcGU7XG5cbiAgZnVuY3Rpb24gY2FuUmVjb25uZWN0KHNvdXJjZSwgdGFyZ2V0LCBjb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuIHJ1bGVzLmFsbG93ZWQoJ2Nvbm5lY3Rpb24ucmVjb25uZWN0Jywge1xuICAgICAgY29ubmVjdGlvbjogY29ubmVjdGlvbixcbiAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICB9KTtcbiAgfVxuXG4gIC8vICgxKSBhZGQgbmV3IHNoYXBlIGF0IGdpdmVuIHBvc2l0aW9uXG4gIHZhciBwb3NpdGlvbiA9IHtcbiAgICB4OiBuZXdEYXRhLngsXG4gICAgeTogbmV3RGF0YS55XG4gIH07XG5cbiAgdmFyIG9sZEJvdW5kcyA9IHtcbiAgICB4OiBvbGRTaGFwZS54LFxuICAgIHk6IG9sZFNoYXBlLnksXG4gICAgd2lkdGg6IG9sZFNoYXBlLndpZHRoLFxuICAgIGhlaWdodDogb2xkU2hhcGUuaGVpZ2h0XG4gIH07XG5cbiAgbmV3U2hhcGUgPSBjb250ZXh0Lm5ld1NoYXBlID1cbiAgICBjb250ZXh0Lm5ld1NoYXBlIHx8XG4gICAgc2VsZi5jcmVhdGVTaGFwZShuZXdEYXRhLCBwb3NpdGlvbiwgb2xkU2hhcGUucGFyZW50LCBoaW50cyk7XG5cbiAgLy8gKDIpIHVwZGF0ZSBob3N0XG4gIGlmIChvbGRTaGFwZS5ob3N0KSB7XG4gICAgbW9kZWxpbmcudXBkYXRlQXR0YWNobWVudChuZXdTaGFwZSwgb2xkU2hhcGUuaG9zdCk7XG4gIH1cblxuICAvLyAoMykgYWRvcHQgYWxsIGNoaWxkcmVuIGZyb20gb2xkIHNoYXBlXG4gIHZhciBjaGlsZHJlbjtcblxuICBpZiAoaGludHMubW92ZUNoaWxkcmVuICE9PSBmYWxzZSkge1xuICAgIGNoaWxkcmVuID0gb2xkU2hhcGUuY2hpbGRyZW4uc2xpY2UoKTtcblxuICAgIG1vZGVsaW5nLm1vdmVFbGVtZW50cyhjaGlsZHJlbiwgeyB4OiAwLCB5OiAwIH0sIG5ld1NoYXBlLCBoaW50cyk7XG4gIH1cblxuICAvLyAoNCkgcmVjb25uZWN0IGNvbm5lY3Rpb25zIHRvIG5ldyBzaGFwZSBpZiBwb3NzaWJsZVxuICB2YXIgaW5jb21pbmcgPSBvbGRTaGFwZS5pbmNvbWluZy5zbGljZSgpLFxuICAgICAgb3V0Z29pbmcgPSBvbGRTaGFwZS5vdXRnb2luZy5zbGljZSgpO1xuXG4gIGZvckVhY2goaW5jb21pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2UsXG4gICAgICAgIGFsbG93ZWQgPSBjYW5SZWNvbm5lY3Qoc291cmNlLCBuZXdTaGFwZSwgY29ubmVjdGlvbik7XG5cbiAgICBpZiAoYWxsb3dlZCkge1xuICAgICAgc2VsZi5yZWNvbm5lY3RFbmQoXG4gICAgICAgIGNvbm5lY3Rpb24sIG5ld1NoYXBlLFxuICAgICAgICBnZXRSZXNpemVkVGFyZ2V0QW5jaG9yKGNvbm5lY3Rpb24sIG5ld1NoYXBlLCBvbGRCb3VuZHMpLFxuICAgICAgICBoaW50c1xuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuXG4gIGZvckVhY2gob3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgdGFyZ2V0ID0gY29ubmVjdGlvbi50YXJnZXQsXG4gICAgICAgIGFsbG93ZWQgPSBjYW5SZWNvbm5lY3QobmV3U2hhcGUsIHRhcmdldCwgY29ubmVjdGlvbik7XG5cbiAgICBpZiAoYWxsb3dlZCkge1xuICAgICAgc2VsZi5yZWNvbm5lY3RTdGFydChcbiAgICAgICAgY29ubmVjdGlvbiwgbmV3U2hhcGUsXG4gICAgICAgIGdldFJlc2l6ZWRTb3VyY2VBbmNob3IoY29ubmVjdGlvbiwgbmV3U2hhcGUsIG9sZEJvdW5kcyksXG4gICAgICAgIGhpbnRzXG4gICAgICApO1xuICAgIH1cbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlIG9sZCBzaGFwZS5cbiAqL1xuUmVwbGFjZVNoYXBlSGFuZGxlci5wcm90b3R5cGUucG9zdEV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBvbGRTaGFwZSA9IGNvbnRleHQub2xkU2hhcGU7XG5cbiAgdGhpcy5fbW9kZWxpbmcucmVtb3ZlU2hhcGUob2xkU2hhcGUpO1xufTtcblxuXG5SZXBsYWNlU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge307XG5cblxuUmVwbGFjZVNoYXBlSGFuZGxlci5wcm90b3R5cGUucmV2ZXJ0ID0gZnVuY3Rpb24oY29udGV4dCkge307XG5cblxuUmVwbGFjZVNoYXBlSGFuZGxlci5wcm90b3R5cGUuY3JlYXRlU2hhcGUgPSBmdW5jdGlvbihzaGFwZSwgcG9zaXRpb24sIHRhcmdldCwgaGludHMpIHtcbiAgcmV0dXJuIHRoaXMuX21vZGVsaW5nLmNyZWF0ZVNoYXBlKHNoYXBlLCBwb3NpdGlvbiwgdGFyZ2V0LCBoaW50cyk7XG59O1xuXG5cblJlcGxhY2VTaGFwZUhhbmRsZXIucHJvdG90eXBlLnJlY29ubmVjdFN0YXJ0ID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgbmV3U291cmNlLCBkb2NraW5nUG9pbnQsIGhpbnRzKSB7XG4gIHRoaXMuX21vZGVsaW5nLnJlY29ubmVjdFN0YXJ0KGNvbm5lY3Rpb24sIG5ld1NvdXJjZSwgZG9ja2luZ1BvaW50LCBoaW50cyk7XG59O1xuXG5cblJlcGxhY2VTaGFwZUhhbmRsZXIucHJvdG90eXBlLnJlY29ubmVjdEVuZCA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIG5ld1RhcmdldCwgZG9ja2luZ1BvaW50LCBoaW50cykge1xuICB0aGlzLl9tb2RlbGluZy5yZWNvbm5lY3RFbmQoY29ubmVjdGlvbiwgbmV3VGFyZ2V0LCBkb2NraW5nUG9pbnQsIGhpbnRzKTtcbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRSZXNpemVkU291cmNlQW5jaG9yLFxuICBnZXRSZXNpemVkVGFyZ2V0QW5jaG9yXG59IGZyb20gJy4vaGVscGVyL0FuY2hvcnNIZWxwZXInO1xuXG5cbi8qKlxuICogQSBoYW5kbGVyIHRoYXQgaW1wbGVtZW50cyByZXZlcnNpYmxlIHJlc2l6aW5nIG9mIHNoYXBlcy5cbiAqXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSZXNpemVTaGFwZUhhbmRsZXIobW9kZWxpbmcpIHtcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbn1cblxuUmVzaXplU2hhcGVIYW5kbGVyLiRpbmplY3QgPSBbICdtb2RlbGluZycgXTtcblxuLyoqXG4gKiB7XG4gKiAgIHNoYXBlOiB7Li4uLn1cbiAqICAgbmV3Qm91bmRzOiB7XG4gKiAgICAgd2lkdGg6ICAyMCxcbiAqICAgICBoZWlnaHQ6IDQwLFxuICogICAgIHg6ICAgICAgIDUsXG4gKiAgICAgeTogICAgICAxMFxuICogICB9XG4gKlxuICogfVxuICovXG5SZXNpemVTaGFwZUhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICBuZXdCb3VuZHMgPSBjb250ZXh0Lm5ld0JvdW5kcyxcbiAgICAgIG1pbkJvdW5kcyA9IGNvbnRleHQubWluQm91bmRzO1xuXG4gIGlmIChuZXdCb3VuZHMueCA9PT0gdW5kZWZpbmVkIHx8IG5ld0JvdW5kcy55ID09PSB1bmRlZmluZWQgfHxcbiAgICAgIG5ld0JvdW5kcy53aWR0aCA9PT0gdW5kZWZpbmVkIHx8IG5ld0JvdW5kcy5oZWlnaHQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbmV3Qm91bmRzIG11c3QgaGF2ZSB7eCwgeSwgd2lkdGgsIGhlaWdodH0gcHJvcGVydGllcycpO1xuICB9XG5cbiAgaWYgKG1pbkJvdW5kcyAmJiAobmV3Qm91bmRzLndpZHRoIDwgbWluQm91bmRzLndpZHRoXG4gICAgfHwgbmV3Qm91bmRzLmhlaWdodCA8IG1pbkJvdW5kcy5oZWlnaHQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd3aWR0aCBhbmQgaGVpZ2h0IGNhbm5vdCBiZSBsZXNzIHRoYW4gbWluaW11bSBoZWlnaHQgYW5kIHdpZHRoJyk7XG4gIH0gZWxzZSBpZiAoIW1pbkJvdW5kc1xuICAgICYmIG5ld0JvdW5kcy53aWR0aCA8IDEwIHx8IG5ld0JvdW5kcy5oZWlnaHQgPCAxMCkge1xuICAgIHRocm93IG5ldyBFcnJvcignd2lkdGggYW5kIGhlaWdodCBjYW5ub3QgYmUgbGVzcyB0aGFuIDEwcHgnKTtcbiAgfVxuXG4gIC8vIHNhdmUgb2xkIGJib3ggaW4gY29udGV4dFxuICBjb250ZXh0Lm9sZEJvdW5kcyA9IHtcbiAgICB3aWR0aDogIHNoYXBlLndpZHRoLFxuICAgIGhlaWdodDogc2hhcGUuaGVpZ2h0LFxuICAgIHg6ICAgICAgc2hhcGUueCxcbiAgICB5OiAgICAgIHNoYXBlLnlcbiAgfTtcblxuICAvLyB1cGRhdGUgc2hhcGVcbiAgYXNzaWduKHNoYXBlLCB7XG4gICAgd2lkdGg6ICBuZXdCb3VuZHMud2lkdGgsXG4gICAgaGVpZ2h0OiBuZXdCb3VuZHMuaGVpZ2h0LFxuICAgIHg6ICAgICAgbmV3Qm91bmRzLngsXG4gICAgeTogICAgICBuZXdCb3VuZHMueVxuICB9KTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG5SZXNpemVTaGFwZUhhbmRsZXIucHJvdG90eXBlLnBvc3RFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcblxuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgb2xkQm91bmRzID0gY29udGV4dC5vbGRCb3VuZHMsXG4gICAgICBoaW50cyA9IGNvbnRleHQuaGludHMgfHwge307XG5cbiAgaWYgKGhpbnRzLmxheW91dCA9PT0gZmFsc2UpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBmb3JFYWNoKHNoYXBlLmluY29taW5nLCBmdW5jdGlvbihjKSB7XG4gICAgbW9kZWxpbmcubGF5b3V0Q29ubmVjdGlvbihjLCB7XG4gICAgICBjb25uZWN0aW9uRW5kOiBnZXRSZXNpemVkVGFyZ2V0QW5jaG9yKGMsIHNoYXBlLCBvbGRCb3VuZHMpXG4gICAgfSk7XG4gIH0pO1xuXG4gIGZvckVhY2goc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGMpIHtcbiAgICBtb2RlbGluZy5sYXlvdXRDb25uZWN0aW9uKGMsIHtcbiAgICAgIGNvbm5lY3Rpb25TdGFydDogZ2V0UmVzaXplZFNvdXJjZUFuY2hvcihjLCBzaGFwZSwgb2xkQm91bmRzKVxuICAgIH0pO1xuICB9KTtcblxufTtcblxuUmVzaXplU2hhcGVIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG9sZEJvdW5kcyA9IGNvbnRleHQub2xkQm91bmRzO1xuXG4gIC8vIHJlc3RvcmUgcHJldmlvdXMgYmJveFxuICBhc3NpZ24oc2hhcGUsIHtcbiAgICB3aWR0aDogIG9sZEJvdW5kcy53aWR0aCxcbiAgICBoZWlnaHQ6IG9sZEJvdW5kcy5oZWlnaHQsXG4gICAgeDogICAgICBvbGRCb3VuZHMueCxcbiAgICB5OiAgICAgIG9sZEJvdW5kcy55XG4gIH0pO1xuXG4gIHJldHVybiBzaGFwZTtcbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIG1hcFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGdldFdheXBvaW50c1VwZGF0aW5nQ29ubmVjdGlvbnMsXG4gIHJlc2l6ZUJvdW5kc1xufSBmcm9tICcuLi8uLi9zcGFjZS10b29sL1NwYWNlVXRpbCc7XG5cbmltcG9ydCB7XG4gIGdldE1vdmVkU291cmNlQW5jaG9yLFxuICBnZXRNb3ZlZFRhcmdldEFuY2hvcixcbiAgZ2V0UmVzaXplZFNvdXJjZUFuY2hvcixcbiAgZ2V0UmVzaXplZFRhcmdldEFuY2hvclxufSBmcm9tICcuL2hlbHBlci9BbmNob3JzSGVscGVyJztcblxuXG4vKipcbiAqIEFkZCBvciByZW1vdmUgc3BhY2UgYnkgbW92aW5nIGFuZCByZXNpemluZyBzaGFwZXMgYW5kIHVwZGF0aW5nIGNvbm5lY3Rpb24gd2F5cG9pbnRzLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBTcGFjZVRvb2xIYW5kbGVyKG1vZGVsaW5nKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cblNwYWNlVG9vbEhhbmRsZXIuJGluamVjdCA9IFsgJ21vZGVsaW5nJyBdO1xuXG5TcGFjZVRvb2xIYW5kbGVyLnByb3RvdHlwZS5wcmVFeGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgZGVsdGEgPSBjb250ZXh0LmRlbHRhLFxuICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXG4gICAgICBtb3ZpbmdTaGFwZXMgPSBjb250ZXh0Lm1vdmluZ1NoYXBlcyxcbiAgICAgIHJlc2l6aW5nU2hhcGVzID0gY29udGV4dC5yZXNpemluZ1NoYXBlcyxcbiAgICAgIHN0YXJ0ID0gY29udGV4dC5zdGFydCxcbiAgICAgIG9sZEJvdW5kcyA9IHt9O1xuXG4gIC8vICgxKSBtb3ZlIHNoYXBlc1xuICB0aGlzLm1vdmVTaGFwZXMobW92aW5nU2hhcGVzLCBkZWx0YSk7XG5cbiAgLy8gKDJhKSBzYXZlIG9sZCBib3VuZHMgb2YgcmVzaXplZCBzaGFwZXNcbiAgZm9yRWFjaChyZXNpemluZ1NoYXBlcywgZnVuY3Rpb24oc2hhcGUpIHtcbiAgICBvbGRCb3VuZHNbc2hhcGUuaWRdID0gZ2V0Qm91bmRzKHNoYXBlKTtcbiAgfSk7XG5cbiAgLy8gKDJiKSByZXNpemUgc2hhcGVzXG4gIHRoaXMucmVzaXplU2hhcGVzKHJlc2l6aW5nU2hhcGVzLCBkZWx0YSwgZGlyZWN0aW9uKTtcblxuICAvLyAoMykgdXBkYXRlIGNvbm5lY3Rpb24gd2F5cG9pbnRzXG4gIHRoaXMudXBkYXRlQ29ubmVjdGlvbldheXBvaW50cyhcbiAgICBnZXRXYXlwb2ludHNVcGRhdGluZ0Nvbm5lY3Rpb25zKG1vdmluZ1NoYXBlcywgcmVzaXppbmdTaGFwZXMpLFxuICAgIGRlbHRhLFxuICAgIGRpcmVjdGlvbixcbiAgICBzdGFydCxcbiAgICBtb3ZpbmdTaGFwZXMsXG4gICAgcmVzaXppbmdTaGFwZXMsXG4gICAgb2xkQm91bmRzXG4gICk7XG59O1xuXG5TcGFjZVRvb2xIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oKSB7fTtcblNwYWNlVG9vbEhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKCkge307XG5cblNwYWNlVG9vbEhhbmRsZXIucHJvdG90eXBlLm1vdmVTaGFwZXMgPSBmdW5jdGlvbihzaGFwZXMsIGRlbHRhKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmb3JFYWNoKHNoYXBlcywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHNlbGYuX21vZGVsaW5nLm1vdmVTaGFwZShlbGVtZW50LCBkZWx0YSwgbnVsbCwge1xuICAgICAgYXV0b1Jlc2l6ZTogZmFsc2UsXG4gICAgICBsYXlvdXQ6IGZhbHNlLFxuICAgICAgcmVjdXJzZTogZmFsc2VcbiAgICB9KTtcbiAgfSk7XG59O1xuXG5TcGFjZVRvb2xIYW5kbGVyLnByb3RvdHlwZS5yZXNpemVTaGFwZXMgPSBmdW5jdGlvbihzaGFwZXMsIGRlbHRhLCBkaXJlY3Rpb24pIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGZvckVhY2goc2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgIHZhciBuZXdCb3VuZHMgPSByZXNpemVCb3VuZHMoc2hhcGUsIGRpcmVjdGlvbiwgZGVsdGEpO1xuXG4gICAgc2VsZi5fbW9kZWxpbmcucmVzaXplU2hhcGUoc2hhcGUsIG5ld0JvdW5kcywgbnVsbCwge1xuICAgICAgYXR0YWNoU3VwcG9ydDogZmFsc2UsXG4gICAgICBhdXRvUmVzaXplOiBmYWxzZSxcbiAgICAgIGxheW91dDogZmFsc2VcbiAgICB9KTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIFVwZGF0ZSBjb25uZWN0aW9ucyB3YXlwb2ludHMgYWNjb3JkaW5nIHRvIHRoZSBydWxlczpcbiAqICAgMS4gQm90aCBzb3VyY2UgYW5kIHRhcmdldCBhcmUgbW92ZWQvcmVzaXplZCA9PiBtb3ZlIHdheXBvaW50cyBieSB0aGUgZGVsdGFcbiAqICAgMi4gT25seSBvbmUgb2Ygc291cmNlIGFuZCB0YXJnZXQgaXMgbW92ZWQvcmVzaXplZCA9PiByZS1sYXlvdXQgY29ubmVjdGlvbiB3aXRoIG1vdmVkIHN0YXJ0L2VuZFxuICovXG5TcGFjZVRvb2xIYW5kbGVyLnByb3RvdHlwZS51cGRhdGVDb25uZWN0aW9uV2F5cG9pbnRzID0gZnVuY3Rpb24oXG4gICAgY29ubmVjdGlvbnMsXG4gICAgZGVsdGEsXG4gICAgZGlyZWN0aW9uLFxuICAgIHN0YXJ0LFxuICAgIG1vdmluZ1NoYXBlcyxcbiAgICByZXNpemluZ1NoYXBlcyxcbiAgICBvbGRCb3VuZHNcbikge1xuICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICBhZmZlY3RlZFNoYXBlcyA9IG1vdmluZ1NoYXBlcy5jb25jYXQocmVzaXppbmdTaGFwZXMpO1xuXG4gIGZvckVhY2goY29ubmVjdGlvbnMsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICB2YXIgc291cmNlID0gY29ubmVjdGlvbi5zb3VyY2UsXG4gICAgICAgIHRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0LFxuICAgICAgICB3YXlwb2ludHMgPSBjb3B5V2F5cG9pbnRzKGNvbm5lY3Rpb24pLFxuICAgICAgICBheGlzID0gZ2V0QXhpc0Zyb21EaXJlY3Rpb24oZGlyZWN0aW9uKSxcbiAgICAgICAgbGF5b3V0SGludHMgPSB7XG4gICAgICAgICAgbGFiZWxCZWhhdmlvcjogZmFsc2VcbiAgICAgICAgfTtcblxuICAgIGlmIChpbmNsdWRlcyhhZmZlY3RlZFNoYXBlcywgc291cmNlKSAmJiBpbmNsdWRlcyhhZmZlY3RlZFNoYXBlcywgdGFyZ2V0KSkge1xuXG4gICAgICAvLyBtb3ZlIHdheXBvaW50c1xuICAgICAgd2F5cG9pbnRzID0gbWFwKHdheXBvaW50cywgZnVuY3Rpb24od2F5cG9pbnQpIHtcbiAgICAgICAgaWYgKHNob3VsZE1vdmVXYXlwb2ludCh3YXlwb2ludCwgc3RhcnQsIGRpcmVjdGlvbikpIHtcblxuICAgICAgICAgIC8vIG1vdmUgd2F5cG9pbnRcbiAgICAgICAgICB3YXlwb2ludFsgYXhpcyBdID0gd2F5cG9pbnRbIGF4aXMgXSArIGRlbHRhWyBheGlzIF07XG4gICAgICAgIH1cblxuICAgICAgICBpZiAod2F5cG9pbnQub3JpZ2luYWwgJiYgc2hvdWxkTW92ZVdheXBvaW50KHdheXBvaW50Lm9yaWdpbmFsLCBzdGFydCwgZGlyZWN0aW9uKSkge1xuXG4gICAgICAgICAgLy8gbW92ZSB3YXlwb2ludCBvcmlnaW5hbFxuICAgICAgICAgIHdheXBvaW50Lm9yaWdpbmFsWyBheGlzIF0gPSB3YXlwb2ludC5vcmlnaW5hbFsgYXhpcyBdICsgZGVsdGFbIGF4aXMgXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB3YXlwb2ludDtcbiAgICAgIH0pO1xuXG4gICAgICBzZWxmLl9tb2RlbGluZy51cGRhdGVXYXlwb2ludHMoY29ubmVjdGlvbiwgd2F5cG9pbnRzLCB7XG4gICAgICAgIGxhYmVsQmVoYXZpb3I6IGZhbHNlXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGluY2x1ZGVzKGFmZmVjdGVkU2hhcGVzLCBzb3VyY2UpIHx8IGluY2x1ZGVzKGFmZmVjdGVkU2hhcGVzLCB0YXJnZXQpKSB7XG5cbiAgICAgIC8vIHJlLWxheW91dCBjb25uZWN0aW9uIHdpdGggbW92ZWQgc3RhcnQvZW5kXG4gICAgICBpZiAoaW5jbHVkZXMobW92aW5nU2hhcGVzLCBzb3VyY2UpKSB7XG4gICAgICAgIGxheW91dEhpbnRzLmNvbm5lY3Rpb25TdGFydCA9IGdldE1vdmVkU291cmNlQW5jaG9yKGNvbm5lY3Rpb24sIHNvdXJjZSwgZGVsdGEpO1xuICAgICAgfSBlbHNlIGlmIChpbmNsdWRlcyhtb3ZpbmdTaGFwZXMsIHRhcmdldCkpIHtcbiAgICAgICAgbGF5b3V0SGludHMuY29ubmVjdGlvbkVuZCA9IGdldE1vdmVkVGFyZ2V0QW5jaG9yKGNvbm5lY3Rpb24sIHRhcmdldCwgZGVsdGEpO1xuICAgICAgfSBlbHNlIGlmIChpbmNsdWRlcyhyZXNpemluZ1NoYXBlcywgc291cmNlKSkge1xuICAgICAgICBsYXlvdXRIaW50cy5jb25uZWN0aW9uU3RhcnQgPSBnZXRSZXNpemVkU291cmNlQW5jaG9yKFxuICAgICAgICAgIGNvbm5lY3Rpb24sIHNvdXJjZSwgb2xkQm91bmRzW3NvdXJjZS5pZF1cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoaW5jbHVkZXMocmVzaXppbmdTaGFwZXMsIHRhcmdldCkpIHtcbiAgICAgICAgbGF5b3V0SGludHMuY29ubmVjdGlvbkVuZCA9IGdldFJlc2l6ZWRUYXJnZXRBbmNob3IoXG4gICAgICAgICAgY29ubmVjdGlvbiwgdGFyZ2V0LCBvbGRCb3VuZHNbdGFyZ2V0LmlkXVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBzZWxmLl9tb2RlbGluZy5sYXlvdXRDb25uZWN0aW9uKGNvbm5lY3Rpb24sIGxheW91dEhpbnRzKTtcbiAgICB9XG4gIH0pO1xufTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gY29weVdheXBvaW50KHdheXBvaW50KSB7XG4gIHJldHVybiBhc3NpZ24oe30sIHdheXBvaW50KTtcbn1cblxuZnVuY3Rpb24gY29weVdheXBvaW50cyhjb25uZWN0aW9uKSB7XG4gIHJldHVybiBtYXAoY29ubmVjdGlvbi53YXlwb2ludHMsIGZ1bmN0aW9uKHdheXBvaW50KSB7XG5cbiAgICB3YXlwb2ludCA9IGNvcHlXYXlwb2ludCh3YXlwb2ludCk7XG5cbiAgICBpZiAod2F5cG9pbnQub3JpZ2luYWwpIHtcbiAgICAgIHdheXBvaW50Lm9yaWdpbmFsID0gY29weVdheXBvaW50KHdheXBvaW50Lm9yaWdpbmFsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gd2F5cG9pbnQ7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBnZXRBeGlzRnJvbURpcmVjdGlvbihkaXJlY3Rpb24pIHtcbiAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgY2FzZSAnbic6XG4gICAgcmV0dXJuICd5JztcbiAgY2FzZSAndyc6XG4gICAgcmV0dXJuICd4JztcbiAgY2FzZSAncyc6XG4gICAgcmV0dXJuICd5JztcbiAgY2FzZSAnZSc6XG4gICAgcmV0dXJuICd4JztcbiAgfVxufVxuXG5mdW5jdGlvbiBzaG91bGRNb3ZlV2F5cG9pbnQod2F5cG9pbnQsIHN0YXJ0LCBkaXJlY3Rpb24pIHtcbiAgdmFyIHJlbGV2YW50QXhpcyA9IGdldEF4aXNGcm9tRGlyZWN0aW9uKGRpcmVjdGlvbik7XG5cbiAgaWYgKC9lfHMvLnRlc3QoZGlyZWN0aW9uKSkge1xuICAgIHJldHVybiB3YXlwb2ludFsgcmVsZXZhbnRBeGlzIF0gPiBzdGFydDtcbiAgfSBlbHNlIGlmICgvbnx3Ly50ZXN0KGRpcmVjdGlvbikpIHtcbiAgICByZXR1cm4gd2F5cG9pbnRbIHJlbGV2YW50QXhpcyBdIDwgc3RhcnQ7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5jbHVkZXMoYXJyYXksIGl0ZW0pIHtcbiAgcmV0dXJuIGFycmF5LmluZGV4T2YoaXRlbSkgIT09IC0xO1xufVxuXG5mdW5jdGlvbiBnZXRCb3VuZHMoc2hhcGUpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBzaGFwZS54LFxuICAgIHk6IHNoYXBlLnksXG4gICAgaGVpZ2h0OiBzaGFwZS5oZWlnaHQsXG4gICAgd2lkdGg6IHNoYXBlLndpZHRoXG4gIH07XG59XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG4vKipcbiAqIEEgaGFuZGxlciB0aGF0IHRvZ2dsZXMgdGhlIGNvbGxhcHNlZCBzdGF0ZSBvZiBhbiBlbGVtZW50XG4gKiBhbmQgdGhlIHZpc2liaWxpdHkgb2YgYWxsIGl0cyBjaGlsZHJlbi5cbiAqXG4gKiBAcGFyYW0ge01vZGVsaW5nfSBtb2RlbGluZ1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBUb2dnbGVTaGFwZUNvbGxhcHNlSGFuZGxlcihtb2RlbGluZykge1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xufVxuXG5Ub2dnbGVTaGFwZUNvbGxhcHNlSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnIF07XG5cblxuVG9nZ2xlU2hhcGVDb2xsYXBzZUhhbmRsZXIucHJvdG90eXBlLmV4ZWN1dGUgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIGNoaWxkcmVuID0gc2hhcGUuY2hpbGRyZW47XG5cbiAgLy8gcmVjdXJzaXZlbHkgcmVtZW1iZXIgcHJldmlvdXMgdmlzaWJpbGl0eSBvZiBjaGlsZHJlblxuICBjb250ZXh0Lm9sZENoaWxkcmVuVmlzaWJpbGl0eSA9IGdldEVsZW1lbnRzVmlzaWJpbGl0eVJlY3Vyc2l2ZShjaGlsZHJlbik7XG5cbiAgLy8gdG9nZ2xlIHN0YXRlXG4gIHNoYXBlLmNvbGxhcHNlZCA9ICFzaGFwZS5jb2xsYXBzZWQ7XG5cbiAgLy8gcmVjdXJzaXZlbHkgaGlkZS9zaG93IGNoaWxkcmVuXG4gIHZhciByZXN1bHQgPSBzZXRIaWRkZW5SZWN1cnNpdmUoY2hpbGRyZW4sIHNoYXBlLmNvbGxhcHNlZCk7XG5cbiAgcmV0dXJuIFtzaGFwZV0uY29uY2F0KHJlc3VsdCk7XG59O1xuXG5cblRvZ2dsZVNoYXBlQ29sbGFwc2VIYW5kbGVyLnByb3RvdHlwZS5yZXZlcnQgPSBmdW5jdGlvbihjb250ZXh0KSB7XG5cbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG9sZENoaWxkcmVuVmlzaWJpbGl0eSA9IGNvbnRleHQub2xkQ2hpbGRyZW5WaXNpYmlsaXR5O1xuXG4gIHZhciBjaGlsZHJlbiA9IHNoYXBlLmNoaWxkcmVuO1xuXG4gIC8vIHJlY3Vyc2l2ZWx5IHNldCBvbGQgdmlzYWJpbGl0eSBvZiBjaGlsZHJlblxuICB2YXIgcmVzdWx0ID0gcmVzdG9yZVZpc2liaWxpdHlSZWN1cnNpdmUoY2hpbGRyZW4sIG9sZENoaWxkcmVuVmlzaWJpbGl0eSk7XG5cbiAgLy8gcmV0b2dnbGUgc3RhdGVcbiAgc2hhcGUuY29sbGFwc2VkID0gIXNoYXBlLmNvbGxhcHNlZDtcblxuICByZXR1cm4gW3NoYXBlXS5jb25jYXQocmVzdWx0KTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogUmV0dXJuIGEgbWFwIHsgZWxlbWVudElkIC0+IGhpZGRlblN0YXRlfS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5mdW5jdGlvbiBnZXRFbGVtZW50c1Zpc2liaWxpdHlSZWN1cnNpdmUoZWxlbWVudHMpIHtcblxuICB2YXIgcmVzdWx0ID0ge307XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHJlc3VsdFtlbGVtZW50LmlkXSA9IGVsZW1lbnQuaGlkZGVuO1xuXG4gICAgaWYgKGVsZW1lbnQuY2hpbGRyZW4pIHtcbiAgICAgIHJlc3VsdCA9IGFzc2lnbih7fSwgcmVzdWx0LCBnZXRFbGVtZW50c1Zpc2liaWxpdHlSZWN1cnNpdmUoZWxlbWVudC5jaGlsZHJlbikpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuXG5mdW5jdGlvbiBzZXRIaWRkZW5SZWN1cnNpdmUoZWxlbWVudHMsIG5ld0hpZGRlbikge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIGZvckVhY2goZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICBlbGVtZW50LmhpZGRlbiA9IG5ld0hpZGRlbjtcblxuICAgIHJlc3VsdCA9IHJlc3VsdC5jb25jYXQoZWxlbWVudCk7XG5cbiAgICBpZiAoZWxlbWVudC5jaGlsZHJlbikge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdChzZXRIaWRkZW5SZWN1cnNpdmUoZWxlbWVudC5jaGlsZHJlbiwgZWxlbWVudC5jb2xsYXBzZWQgfHwgbmV3SGlkZGVuKSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiByZXN0b3JlVmlzaWJpbGl0eVJlY3Vyc2l2ZShlbGVtZW50cywgbGFzdFN0YXRlKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGVsZW1lbnQuaGlkZGVuID0gbGFzdFN0YXRlW2VsZW1lbnQuaWRdO1xuXG4gICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdChlbGVtZW50KTtcblxuICAgIGlmIChlbGVtZW50LmNoaWxkcmVuKSB7XG4gICAgICByZXN1bHQgPSByZXN1bHQuY29uY2F0KHJlc3RvcmVWaXNpYmlsaXR5UmVjdXJzaXZlKGVsZW1lbnQuY2hpbGRyZW4sIGxhc3RTdGF0ZSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cbiIsImltcG9ydCB7XG4gIGFkZCBhcyBjb2xsZWN0aW9uQWRkLFxuICByZW1vdmUgYXMgY29sbGVjdGlvblJlbW92ZVxufSBmcm9tICcuLi8uLi8uLi91dGlsL0NvbGxlY3Rpb25zJztcblxuLyoqXG4gKiBBIGhhbmRsZXIgdGhhdCBpbXBsZW1lbnRzIHJldmVyc2libGUgYXR0YWNoaW5nL2RldGFjaGluZyBvZiBzaGFwZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFVwZGF0ZUF0dGFjaG1lbnRIYW5kbGVyKG1vZGVsaW5nKSB7XG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cblVwZGF0ZUF0dGFjaG1lbnRIYW5kbGVyLiRpbmplY3QgPSBbICdtb2RlbGluZycgXTtcblxuXG5VcGRhdGVBdHRhY2htZW50SGFuZGxlci5wcm90b3R5cGUuZXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG5ld0hvc3QgPSBjb250ZXh0Lm5ld0hvc3QsXG4gICAgICBvbGRIb3N0ID0gc2hhcGUuaG9zdDtcblxuICAvLyAoMCkgZGV0YWNoIGZyb20gb2xkIGhvc3RcbiAgY29udGV4dC5vbGRIb3N0ID0gb2xkSG9zdDtcbiAgY29udGV4dC5hdHRhY2hlcklkeCA9IHJlbW92ZUF0dGFjaGVyKG9sZEhvc3QsIHNoYXBlKTtcblxuICAvLyAoMSkgYXR0YWNoIHRvIG5ldyBob3N0XG4gIGFkZEF0dGFjaGVyKG5ld0hvc3QsIHNoYXBlKTtcblxuICAvLyAoMikgdXBkYXRlIGhvc3RcbiAgc2hhcGUuaG9zdCA9IG5ld0hvc3Q7XG5cbiAgcmV0dXJuIHNoYXBlO1xufTtcblxuVXBkYXRlQXR0YWNobWVudEhhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgIG5ld0hvc3QgPSBjb250ZXh0Lm5ld0hvc3QsXG4gICAgICBvbGRIb3N0ID0gY29udGV4dC5vbGRIb3N0LFxuICAgICAgYXR0YWNoZXJJZHggPSBjb250ZXh0LmF0dGFjaGVySWR4O1xuXG4gIC8vICgyKSB1cGRhdGUgaG9zdFxuICBzaGFwZS5ob3N0ID0gb2xkSG9zdDtcblxuICAvLyAoMSkgYXR0YWNoIHRvIG5ldyBob3N0XG4gIHJlbW92ZUF0dGFjaGVyKG5ld0hvc3QsIHNoYXBlKTtcblxuICAvLyAoMCkgZGV0YWNoIGZyb20gb2xkIGhvc3RcbiAgYWRkQXR0YWNoZXIob2xkSG9zdCwgc2hhcGUsIGF0dGFjaGVySWR4KTtcblxuICByZXR1cm4gc2hhcGU7XG59O1xuXG5cbmZ1bmN0aW9uIHJlbW92ZUF0dGFjaGVyKGhvc3QsIGF0dGFjaGVyKSB7XG5cbiAgLy8gcmVtb3ZlIGF0dGFjaGVyIGZyb20gaG9zdFxuICByZXR1cm4gY29sbGVjdGlvblJlbW92ZShob3N0ICYmIGhvc3QuYXR0YWNoZXJzLCBhdHRhY2hlcik7XG59XG5cbmZ1bmN0aW9uIGFkZEF0dGFjaGVyKGhvc3QsIGF0dGFjaGVyLCBpZHgpIHtcblxuICBpZiAoIWhvc3QpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgYXR0YWNoZXJzID0gaG9zdC5hdHRhY2hlcnM7XG5cbiAgaWYgKCFhdHRhY2hlcnMpIHtcbiAgICBob3N0LmF0dGFjaGVycyA9IGF0dGFjaGVycyA9IFtdO1xuICB9XG5cbiAgY29sbGVjdGlvbkFkZChhdHRhY2hlcnMsIGF0dGFjaGVyLCBpZHgpO1xufVxuIiwiZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVXBkYXRlV2F5cG9pbnRzSGFuZGxlcigpIHsgfVxuXG5VcGRhdGVXYXlwb2ludHNIYW5kbGVyLnByb3RvdHlwZS5leGVjdXRlID0gZnVuY3Rpb24oY29udGV4dCkge1xuXG4gIHZhciBjb25uZWN0aW9uID0gY29udGV4dC5jb25uZWN0aW9uLFxuICAgICAgbmV3V2F5cG9pbnRzID0gY29udGV4dC5uZXdXYXlwb2ludHM7XG5cbiAgY29udGV4dC5vbGRXYXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cztcblxuICBjb25uZWN0aW9uLndheXBvaW50cyA9IG5ld1dheXBvaW50cztcblxuICByZXR1cm4gY29ubmVjdGlvbjtcbn07XG5cblVwZGF0ZVdheXBvaW50c0hhbmRsZXIucHJvdG90eXBlLnJldmVydCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcblxuICB2YXIgY29ubmVjdGlvbiA9IGNvbnRleHQuY29ubmVjdGlvbixcbiAgICAgIG9sZFdheXBvaW50cyA9IGNvbnRleHQub2xkV2F5cG9pbnRzO1xuXG4gIGNvbm5lY3Rpb24ud2F5cG9pbnRzID0gb2xkV2F5cG9pbnRzO1xuXG4gIHJldHVybiBjb25uZWN0aW9uO1xufTsiLCJpbXBvcnQge1xuICBnZXROZXdBdHRhY2hQb2ludFxufSBmcm9tICcuLi8uLi8uLi8uLi91dGlsL0F0dGFjaFV0aWwnO1xuXG5pbXBvcnQge1xuICBnZXRPcmllbnRhdGlvblxufSBmcm9tICcuLi8uLi8uLi8uLi9sYXlvdXQvTGF5b3V0VXRpbCc7XG5cbmltcG9ydCB7XG4gIGZpbHRlcixcbiAgbWFwXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVzaXplZFNvdXJjZUFuY2hvcihjb25uZWN0aW9uLCBzaGFwZSwgb2xkQm91bmRzKSB7XG5cbiAgdmFyIHdheXBvaW50cyA9IHNhZmVHZXRXYXlwb2ludHMoY29ubmVjdGlvbiksXG4gICAgICB3YXlwb2ludHNJbnNpZGVOZXdCb3VuZHMgPSBnZXRXYXlwb2ludHNJbnNpZGVCb3VuZHMod2F5cG9pbnRzLCBzaGFwZSksXG4gICAgICBvbGRBbmNob3IgPSB3YXlwb2ludHNbMF07XG5cbiAgLy8gbmV3IGFuY2hvciBpcyB0aGUgbGFzdCB3YXlwb2ludCBlbmNsb3NlZCBiZSByZXNpemVkIHNvdXJjZVxuICBpZiAod2F5cG9pbnRzSW5zaWRlTmV3Qm91bmRzLmxlbmd0aCkge1xuICAgIHJldHVybiB3YXlwb2ludHNJbnNpZGVOZXdCb3VuZHNbIHdheXBvaW50c0luc2lkZU5ld0JvdW5kcy5sZW5ndGggLSAxIF07XG4gIH1cblxuICByZXR1cm4gZ2V0TmV3QXR0YWNoUG9pbnQob2xkQW5jaG9yLm9yaWdpbmFsIHx8IG9sZEFuY2hvciwgb2xkQm91bmRzLCBzaGFwZSk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFJlc2l6ZWRUYXJnZXRBbmNob3IoY29ubmVjdGlvbiwgc2hhcGUsIG9sZEJvdW5kcykge1xuXG4gIHZhciB3YXlwb2ludHMgPSBzYWZlR2V0V2F5cG9pbnRzKGNvbm5lY3Rpb24pLFxuICAgICAgd2F5cG9pbnRzSW5zaWRlTmV3Qm91bmRzID0gZ2V0V2F5cG9pbnRzSW5zaWRlQm91bmRzKHdheXBvaW50cywgc2hhcGUpLFxuICAgICAgb2xkQW5jaG9yID0gd2F5cG9pbnRzW3dheXBvaW50cy5sZW5ndGggLSAxXTtcblxuICAvLyBuZXcgYW5jaG9yIGlzIHRoZSBmaXJzdCB3YXlwb2ludCBlbmNsb3NlZCBiZSByZXNpemVkIHRhcmdldFxuICBpZiAod2F5cG9pbnRzSW5zaWRlTmV3Qm91bmRzLmxlbmd0aCkge1xuICAgIHJldHVybiB3YXlwb2ludHNJbnNpZGVOZXdCb3VuZHNbIDAgXTtcbiAgfVxuXG4gIHJldHVybiBnZXROZXdBdHRhY2hQb2ludChvbGRBbmNob3Iub3JpZ2luYWwgfHwgb2xkQW5jaG9yLCBvbGRCb3VuZHMsIHNoYXBlKTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0TW92ZWRTb3VyY2VBbmNob3IoY29ubmVjdGlvbiwgc291cmNlLCBtb3ZlRGVsdGEpIHtcblxuICB2YXIgd2F5cG9pbnRzID0gc2FmZUdldFdheXBvaW50cyhjb25uZWN0aW9uKSxcbiAgICAgIG9sZEJvdW5kcyA9IHN1YnRyYWN0KHNvdXJjZSwgbW92ZURlbHRhKSxcbiAgICAgIG9sZEFuY2hvciA9IHdheXBvaW50c1sgMCBdO1xuXG4gIHJldHVybiBnZXROZXdBdHRhY2hQb2ludChvbGRBbmNob3Iub3JpZ2luYWwgfHwgb2xkQW5jaG9yLCBvbGRCb3VuZHMsIHNvdXJjZSk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1vdmVkVGFyZ2V0QW5jaG9yKGNvbm5lY3Rpb24sIHRhcmdldCwgbW92ZURlbHRhKSB7XG5cbiAgdmFyIHdheXBvaW50cyA9IHNhZmVHZXRXYXlwb2ludHMoY29ubmVjdGlvbiksXG4gICAgICBvbGRCb3VuZHMgPSBzdWJ0cmFjdCh0YXJnZXQsIG1vdmVEZWx0YSksXG4gICAgICBvbGRBbmNob3IgPSB3YXlwb2ludHNbIHdheXBvaW50cy5sZW5ndGggLSAxIF07XG5cbiAgcmV0dXJuIGdldE5ld0F0dGFjaFBvaW50KG9sZEFuY2hvci5vcmlnaW5hbCB8fCBvbGRBbmNob3IsIG9sZEJvdW5kcywgdGFyZ2V0KTtcbn1cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gc3VidHJhY3QoYm91bmRzLCBkZWx0YSkge1xuICByZXR1cm4ge1xuICAgIHg6IGJvdW5kcy54IC0gZGVsdGEueCxcbiAgICB5OiBib3VuZHMueSAtIGRlbHRhLnksXG4gICAgd2lkdGg6IGJvdW5kcy53aWR0aCxcbiAgICBoZWlnaHQ6IGJvdW5kcy5oZWlnaHRcbiAgfTtcbn1cblxuXG4vKipcbiAqIFJldHVybiB3YXlwb2ludHMgb2YgZ2l2ZW4gY29ubmVjdGlvbjsgdGhyb3cgaWYgbm9uIGV4aXN0cyAoc2hvdWxkIG5vdCBoYXBwZW4hISkuXG4gKlxuICogQHBhcmFtIHtDb25uZWN0aW9ufSBjb25uZWN0aW9uXG4gKlxuICogQHJldHVybiB7QXJyYXk8UG9pbnQ+fVxuICovXG5mdW5jdGlvbiBzYWZlR2V0V2F5cG9pbnRzKGNvbm5lY3Rpb24pIHtcblxuICB2YXIgd2F5cG9pbnRzID0gY29ubmVjdGlvbi53YXlwb2ludHM7XG5cbiAgaWYgKCF3YXlwb2ludHMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdjb25uZWN0aW9uIycgKyBjb25uZWN0aW9uLmlkICsgJzogbm8gd2F5cG9pbnRzJyk7XG4gIH1cblxuICByZXR1cm4gd2F5cG9pbnRzO1xufVxuXG5mdW5jdGlvbiBnZXRXYXlwb2ludHNJbnNpZGVCb3VuZHMod2F5cG9pbnRzLCBib3VuZHMpIHtcbiAgdmFyIG9yaWdpbmFsV2F5cG9pbnRzID0gbWFwKHdheXBvaW50cywgZ2V0T3JpZ2luYWwpO1xuXG4gIHJldHVybiBmaWx0ZXIob3JpZ2luYWxXYXlwb2ludHMsIGZ1bmN0aW9uKHdheXBvaW50KSB7XG4gICAgcmV0dXJuIGlzSW5zaWRlQm91bmRzKHdheXBvaW50LCBib3VuZHMpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgcG9pbnQgaXMgaW5zaWRlIGJvdW5kcywgaW5jbC4gZWRnZXMuXG4gKlxuICogQHBhcmFtIHtQb2ludH0gcG9pbnRcbiAqIEBwYXJhbSB7Qm91bmRzfSBib3VuZHNcbiAqL1xuZnVuY3Rpb24gaXNJbnNpZGVCb3VuZHMocG9pbnQsIGJvdW5kcykge1xuICByZXR1cm4gZ2V0T3JpZW50YXRpb24oYm91bmRzLCBwb2ludCwgMSkgPT09ICdpbnRlcnNlY3QnO1xufVxuXG5mdW5jdGlvbiBnZXRPcmlnaW5hbChwb2ludCkge1xuICByZXR1cm4gcG9pbnQub3JpZ2luYWwgfHwgcG9pbnQ7XG59XG4iLCJpbXBvcnQge1xuICBhc3NpZ25cbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRDbG9zdXJlXG59IGZyb20gJy4uLy4uLy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE1vdmVDbG9zdXJlKCkge1xuXG4gIHRoaXMuYWxsU2hhcGVzID0ge307XG4gIHRoaXMuYWxsQ29ubmVjdGlvbnMgPSB7fTtcblxuICB0aGlzLmVuY2xvc2VkRWxlbWVudHMgPSB7fTtcbiAgdGhpcy5lbmNsb3NlZENvbm5lY3Rpb25zID0ge307XG5cbiAgdGhpcy50b3BMZXZlbCA9IHt9O1xufVxuXG5cbk1vdmVDbG9zdXJlLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbihlbGVtZW50LCBpc1RvcExldmVsKSB7XG4gIHJldHVybiB0aGlzLmFkZEFsbChbIGVsZW1lbnQgXSwgaXNUb3BMZXZlbCk7XG59O1xuXG5cbk1vdmVDbG9zdXJlLnByb3RvdHlwZS5hZGRBbGwgPSBmdW5jdGlvbihlbGVtZW50cywgaXNUb3BMZXZlbCkge1xuXG4gIHZhciBuZXdDbG9zdXJlID0gZ2V0Q2xvc3VyZShlbGVtZW50cywgISFpc1RvcExldmVsLCB0aGlzKTtcblxuICBhc3NpZ24odGhpcywgbmV3Q2xvc3VyZSk7XG5cbiAgcmV0dXJuIHRoaXM7XG59OyIsImltcG9ydCB7XG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBnZXRNb3ZlZFNvdXJjZUFuY2hvcixcbiAgZ2V0TW92ZWRUYXJnZXRBbmNob3Jcbn0gZnJvbSAnLi9BbmNob3JzSGVscGVyJztcblxuaW1wb3J0IE1vdmVDbG9zdXJlIGZyb20gJy4vTW92ZUNsb3N1cmUnO1xuXG5cbi8qKlxuICogQSBoZWxwZXIgdGhhdCBpcyBhYmxlIHRvIGNhcnJ5IG91dCBzZXJpYWxpemVkIG1vdmVcbiAqIG9wZXJhdGlvbnMgb24gbXVsdGlwbGUgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtNb2RlbGluZ30gbW9kZWxpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW92ZUhlbHBlcihtb2RlbGluZykge1xuICB0aGlzLl9tb2RlbGluZyA9IG1vZGVsaW5nO1xufVxuXG4vKipcbiAqIE1vdmUgdGhlIHNwZWNpZmllZCBlbGVtZW50cyBhbmQgYWxsIGNoaWxkcmVuIGJ5IHRoZSBnaXZlbiBkZWx0YS5cbiAqXG4gKiBUaGlzIG1vdmVzIGFsbCBlbmNsb3NlZCBjb25uZWN0aW9ucywgdG9vIGFuZCBsYXlvdXRzIGFsbCBhZmZlY3RlZFxuICogZXh0ZXJuYWwgY29ubmVjdGlvbnMuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICogQHBhcmFtICB7UG9pbnR9IGRlbHRhXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gbmV3UGFyZW50IGFwcGxpZWQgdG8gdGhlIGZpcnN0IGxldmVsIG9mIHNoYXBlc1xuICpcbiAqIEByZXR1cm4ge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gbGlzdCBvZiB0b3VjaGVkIGVsZW1lbnRzXG4gKi9cbk1vdmVIZWxwZXIucHJvdG90eXBlLm1vdmVSZWN1cnNpdmUgPSBmdW5jdGlvbihlbGVtZW50cywgZGVsdGEsIG5ld1BhcmVudCkge1xuICBpZiAoIWVsZW1lbnRzKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzLm1vdmVDbG9zdXJlKHRoaXMuZ2V0Q2xvc3VyZShlbGVtZW50cyksIGRlbHRhLCBuZXdQYXJlbnQpO1xuICB9XG59O1xuXG4vKipcbiAqIE1vdmUgdGhlIGdpdmVuIGNsb3N1cmUgb2YgZWxtZW1lbnRzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjbG9zdXJlXG4gKiBAcGFyYW0ge1BvaW50fSBkZWx0YVxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gW25ld1BhcmVudF1cbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IFtuZXdIb3N0XVxuICovXG5Nb3ZlSGVscGVyLnByb3RvdHlwZS5tb3ZlQ2xvc3VyZSA9IGZ1bmN0aW9uKGNsb3N1cmUsIGRlbHRhLCBuZXdQYXJlbnQsIG5ld0hvc3QsIHByaW1hcnlTaGFwZSkge1xuICB2YXIgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcblxuICB2YXIgYWxsU2hhcGVzID0gY2xvc3VyZS5hbGxTaGFwZXMsXG4gICAgICBhbGxDb25uZWN0aW9ucyA9IGNsb3N1cmUuYWxsQ29ubmVjdGlvbnMsXG4gICAgICBlbmNsb3NlZENvbm5lY3Rpb25zID0gY2xvc3VyZS5lbmNsb3NlZENvbm5lY3Rpb25zLFxuICAgICAgdG9wTGV2ZWwgPSBjbG9zdXJlLnRvcExldmVsLFxuICAgICAga2VlcFBhcmVudCA9IGZhbHNlO1xuXG4gIGlmIChwcmltYXJ5U2hhcGUgJiYgcHJpbWFyeVNoYXBlLnBhcmVudCA9PT0gbmV3UGFyZW50KSB7XG4gICAga2VlcFBhcmVudCA9IHRydWU7XG4gIH1cblxuICAvLyBtb3ZlIGFsbCBzaGFwZXNcbiAgZm9yRWFjaChhbGxTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG5cbiAgICAvLyBtb3ZlIHRoZSBlbGVtZW50IGFjY29yZGluZyB0byB0aGUgZ2l2ZW4gZGVsdGFcbiAgICBtb2RlbGluZy5tb3ZlU2hhcGUoc2hhcGUsIGRlbHRhLCB0b3BMZXZlbFtzaGFwZS5pZF0gJiYgIWtlZXBQYXJlbnQgJiYgbmV3UGFyZW50LCB7XG4gICAgICByZWN1cnNlOiBmYWxzZSxcbiAgICAgIGxheW91dDogZmFsc2VcbiAgICB9KTtcbiAgfSk7XG5cbiAgLy8gbW92ZSBhbGwgY2hpbGQgY29ubmVjdGlvbnMgLyBsYXlvdXQgZXh0ZXJuYWwgY29ubmVjdGlvbnNcbiAgZm9yRWFjaChhbGxDb25uZWN0aW9ucywgZnVuY3Rpb24oYykge1xuXG4gICAgdmFyIHNvdXJjZU1vdmVkID0gISFhbGxTaGFwZXNbYy5zb3VyY2UuaWRdLFxuICAgICAgICB0YXJnZXRNb3ZlZCA9ICEhYWxsU2hhcGVzW2MudGFyZ2V0LmlkXTtcblxuICAgIGlmIChlbmNsb3NlZENvbm5lY3Rpb25zW2MuaWRdICYmIHNvdXJjZU1vdmVkICYmIHRhcmdldE1vdmVkKSB7XG4gICAgICBtb2RlbGluZy5tb3ZlQ29ubmVjdGlvbihjLCBkZWx0YSwgdG9wTGV2ZWxbYy5pZF0gJiYgIWtlZXBQYXJlbnQgJiYgbmV3UGFyZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgbW9kZWxpbmcubGF5b3V0Q29ubmVjdGlvbihjLCB7XG4gICAgICAgIGNvbm5lY3Rpb25TdGFydDogc291cmNlTW92ZWQgJiYgZ2V0TW92ZWRTb3VyY2VBbmNob3IoYywgYy5zb3VyY2UsIGRlbHRhKSxcbiAgICAgICAgY29ubmVjdGlvbkVuZDogdGFyZ2V0TW92ZWQgJiYgZ2V0TW92ZWRUYXJnZXRBbmNob3IoYywgYy50YXJnZXQsIGRlbHRhKVxuICAgICAgfSk7XG4gICAgfVxuICB9KTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY2xvc3VyZSBmb3IgdGhlIHNlbGVjdGVkIGVsZW1lbnRzXG4gKlxuICogQHBhcmFtICB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICogQHJldHVybiB7TW92ZUNsb3N1cmV9IGNsb3N1cmVcbiAqL1xuTW92ZUhlbHBlci5wcm90b3R5cGUuZ2V0Q2xvc3VyZSA9IGZ1bmN0aW9uKGVsZW1lbnRzKSB7XG4gIHJldHVybiBuZXcgTW92ZUNsb3N1cmUoKS5hZGRBbGwoZWxlbWVudHMsIHRydWUpO1xufTsiLCJleHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb3VzZShldmVudEJ1cykge1xyXG4gIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgdGhpcy5fbGFzdE1vdmVFdmVudCA9IG51bGw7XHJcblxyXG4gIGZ1bmN0aW9uIHNldExhc3RNb3ZlRXZlbnQobW91c2Vtb3ZlRXZlbnQpIHtcclxuICAgIHNlbGYuX2xhc3RNb3ZlRXZlbnQgPSBtb3VzZW1vdmVFdmVudDtcclxuICB9XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuaW5pdCcsIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIHZhciBzdmcgPSBzZWxmLl9zdmcgPSBjb250ZXh0LnN2ZztcclxuXHJcbiAgICBzdmcuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgc2V0TGFzdE1vdmVFdmVudCk7XHJcbiAgfSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuZGVzdHJveScsIGZ1bmN0aW9uKCkge1xyXG4gICAgc2VsZi5fbGFzdE1vdXNlRXZlbnQgPSBudWxsO1xyXG5cclxuICAgIHNlbGYuX3N2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBzZXRMYXN0TW92ZUV2ZW50KTtcclxuICB9KTtcclxufVxyXG5cclxuTW91c2UuJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdO1xyXG5cclxuTW91c2UucHJvdG90eXBlLmdldExhc3RNb3ZlRXZlbnQgPSBmdW5jdGlvbigpIHtcclxuICByZXR1cm4gdGhpcy5fbGFzdE1vdmVFdmVudCB8fCBjcmVhdGVNb3ZlRXZlbnQoMCwgMCk7XHJcbn07XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNb3ZlRXZlbnQoeCwgeSkge1xyXG4gIHZhciBldmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50Jyk7XHJcblxyXG4gIHZhciBzY3JlZW5YID0geCxcclxuICAgICAgc2NyZWVuWSA9IHksXHJcbiAgICAgIGNsaWVudFggPSB4LFxyXG4gICAgICBjbGllbnRZID0geTtcclxuXHJcbiAgaWYgKGV2ZW50LmluaXRNb3VzZUV2ZW50KSB7XHJcbiAgICBldmVudC5pbml0TW91c2VFdmVudChcclxuICAgICAgJ21vdXNlbW92ZScsXHJcbiAgICAgIHRydWUsXHJcbiAgICAgIHRydWUsXHJcbiAgICAgIHdpbmRvdyxcclxuICAgICAgMCxcclxuICAgICAgc2NyZWVuWCxcclxuICAgICAgc2NyZWVuWSxcclxuICAgICAgY2xpZW50WCxcclxuICAgICAgY2xpZW50WSxcclxuICAgICAgZmFsc2UsXHJcbiAgICAgIGZhbHNlLFxyXG4gICAgICBmYWxzZSxcclxuICAgICAgZmFsc2UsXHJcbiAgICAgIDAsXHJcbiAgICAgIG51bGxcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZXZlbnQ7XHJcbn0iLCJpbXBvcnQgTW91c2UgZnJvbSAnLi9Nb3VzZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ21vdXNlJyBdLFxuICBtb3VzZTogWyAndHlwZScsIE1vdXNlIF1cbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZpbHRlcixcbiAgZ3JvdXBCeSxcbiAgaXNPYmplY3Rcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gNTAwLFxuICAgIE1FRElVTV9QUklPUklUWSA9IDEyNTAsXG4gICAgSElHSF9QUklPUklUWSA9IDE1MDA7XG5cbmltcG9ydCB7IGdldE9yaWdpbmFsIGFzIGdldE9yaWdpbmFsRXZlbnQgfSBmcm9tICcuLi8uLi91dGlsL0V2ZW50JztcblxudmFyIHJvdW5kID0gTWF0aC5yb3VuZDtcblxuZnVuY3Rpb24gbWlkKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBlbGVtZW50LnggKyByb3VuZChlbGVtZW50LndpZHRoIC8gMiksXG4gICAgeTogZWxlbWVudC55ICsgcm91bmQoZWxlbWVudC5oZWlnaHQgLyAyKVxuICB9O1xufVxuXG4vKipcbiAqIEEgcGx1Z2luIHRoYXQgbWFrZXMgc2hhcGVzIGRyYWdnYWJsZSAvIGRyb3BwYWJsZS5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtEcmFnZ2luZ30gZHJhZ2dpbmdcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKiBAcGFyYW0ge1NlbGVjdGlvbn0gc2VsZWN0aW9uXG4gKiBAcGFyYW0ge1J1bGVzfSBydWxlc1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBNb3ZlRXZlbnRzKFxuICAgIGV2ZW50QnVzLCBkcmFnZ2luZywgbW9kZWxpbmcsXG4gICAgc2VsZWN0aW9uLCBydWxlcykge1xuXG4gIC8vIHJ1bGVzXG5cbiAgZnVuY3Rpb24gY2FuTW92ZShzaGFwZXMsIGRlbHRhLCBwb3NpdGlvbiwgdGFyZ2V0KSB7XG5cbiAgICByZXR1cm4gcnVsZXMuYWxsb3dlZCgnZWxlbWVudHMubW92ZScsIHtcbiAgICAgIHNoYXBlczogc2hhcGVzLFxuICAgICAgZGVsdGE6IGRlbHRhLFxuICAgICAgcG9zaXRpb246IHBvc2l0aW9uLFxuICAgICAgdGFyZ2V0OiB0YXJnZXRcbiAgICB9KTtcbiAgfVxuXG5cbiAgLy8gbW92ZSBldmVudHNcblxuICAvLyBhc3NpZ24gYSBoaWdoIHByaW9yaXR5IHRvIHRoaXMgaGFuZGxlciB0byBzZXR1cCB0aGUgZW52aXJvbm1lbnRcbiAgLy8gb3RoZXJzIG1heSBob29rIHVwIGxhdGVyLCBlLmcuIGF0IGRlZmF1bHQgcHJpb3JpdHkgYW5kIG1vZGlmeVxuICAvLyB0aGUgbW92ZSBlbnZpcm9ubWVudC5cbiAgLy9cbiAgLy8gVGhpcyBzZXRzIHVwIHRoZSBjb250ZXh0IHdpdGhcbiAgLy9cbiAgLy8gKiBzaGFwZTogdGhlIHByaW1hcnkgc2hhcGUgYmVpbmcgbW92ZWRcbiAgLy8gKiBzaGFwZXM6IGEgbGlzdCBvZiBzaGFwZXMgdG8gYmUgbW92ZWRcbiAgLy8gKiB2YWxpZGF0ZWRTaGFwZXM6IGEgbGlzdCBvZiBzaGFwZXMgdGhhdCBhcmUgYmVpbmcgY2hlY2tlZFxuICAvLyAgICAgICAgICAgICAgICAgICAgYWdhaW5zdCB0aGUgcnVsZXMgYmVmb3JlIGFuZCBkdXJpbmcgbW92ZVxuICAvL1xuICBldmVudEJ1cy5vbignc2hhcGUubW92ZS5zdGFydCcsIEhJR0hfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHNoYXBlID0gZXZlbnQuc2hhcGUsXG4gICAgICAgIHNoYXBlcyA9IHNlbGVjdGlvbi5nZXQoKS5zbGljZSgpO1xuXG4gICAgLy8gbW92ZSBvbmx5IHNpbmdsZSBzaGFwZSBpZiB0aGUgZHJhZ2dlZCBlbGVtZW50XG4gICAgLy8gaXMgbm90IHBhcnQgb2YgdGhlIGN1cnJlbnQgc2VsZWN0aW9uXG4gICAgaWYgKHNoYXBlcy5pbmRleE9mKHNoYXBlKSA9PT0gLTEpIHtcbiAgICAgIHNoYXBlcyA9IFsgc2hhcGUgXTtcbiAgICB9XG5cbiAgICAvLyBlbnN1cmUgd2UgcmVtb3ZlIG5lc3RlZCBlbGVtZW50cyBpbiB0aGUgY29sbGVjdGlvblxuICAgIC8vIGFuZCBhZGQgYXR0YWNoZXJzIGZvciBhIHByb3BlciBkcmFnZ2VyXG4gICAgc2hhcGVzID0gcmVtb3ZlTmVzdGVkKHNoYXBlcyk7XG5cbiAgICAvLyBhdHRhY2ggc2hhcGVzIHRvIGRyYWcgY29udGV4dFxuICAgIGFzc2lnbihjb250ZXh0LCB7XG4gICAgICBzaGFwZXM6IHNoYXBlcyxcbiAgICAgIHZhbGlkYXRlZFNoYXBlczogc2hhcGVzLFxuICAgICAgc2hhcGU6IHNoYXBlXG4gICAgfSk7XG4gIH0pO1xuXG5cbiAgLy8gYXNzaWduIGEgaGlnaCBwcmlvcml0eSB0byB0aGlzIGhhbmRsZXIgdG8gc2V0dXAgdGhlIGVudmlyb25tZW50XG4gIC8vIG90aGVycyBtYXkgaG9vayB1cCBsYXRlciwgZS5nLiBhdCBkZWZhdWx0IHByaW9yaXR5IGFuZCBtb2RpZnlcbiAgLy8gdGhlIG1vdmUgZW52aXJvbm1lbnRcbiAgLy9cbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUuc3RhcnQnLCBNRURJVU1fUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHZhbGlkYXRlZFNoYXBlcyA9IGNvbnRleHQudmFsaWRhdGVkU2hhcGVzLFxuICAgICAgICBjYW5FeGVjdXRlO1xuXG4gICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSA9IGNhbk1vdmUodmFsaWRhdGVkU2hhcGVzKTtcblxuICAgIC8vIGNoZWNrIGlmIHdlIGNhbiBtb3ZlIHRoZSBlbGVtZW50c1xuICAgIGlmICghY2FuRXhlY3V0ZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYXNzaWduIGEgbG93IHByaW9yaXR5IHRvIHRoaXMgaGFuZGxlclxuICAvLyB0byBsZXQgb3RoZXJzIG1vZGlmeSB0aGUgbW92ZSBldmVudCBiZWZvcmUgd2UgdXBkYXRlXG4gIC8vIHRoZSBjb250ZXh0XG4gIC8vXG4gIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLm1vdmUnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIHZhbGlkYXRlZFNoYXBlcyA9IGNvbnRleHQudmFsaWRhdGVkU2hhcGVzLFxuICAgICAgICBob3ZlciA9IGV2ZW50LmhvdmVyLFxuICAgICAgICBkZWx0YSA9IHsgeDogZXZlbnQuZHgsIHk6IGV2ZW50LmR5IH0sXG4gICAgICAgIHBvc2l0aW9uID0geyB4OiBldmVudC54LCB5OiBldmVudC55IH0sXG4gICAgICAgIGNhbkV4ZWN1dGU7XG5cbiAgICAvLyBjaGVjayBpZiB3ZSBjYW4gbW92ZSB0aGUgZWxlbWVudHNcbiAgICBjYW5FeGVjdXRlID0gY2FuTW92ZSh2YWxpZGF0ZWRTaGFwZXMsIGRlbHRhLCBwb3NpdGlvbiwgaG92ZXIpO1xuXG4gICAgY29udGV4dC5kZWx0YSA9IGRlbHRhO1xuICAgIGNvbnRleHQuY2FuRXhlY3V0ZSA9IGNhbkV4ZWN1dGU7XG5cbiAgICAvLyBzaW1wbHkgaWdub3JlIG1vdmUgb3ZlclxuICAgIGlmIChjYW5FeGVjdXRlID09PSBudWxsKSB7XG4gICAgICBjb250ZXh0LnRhcmdldCA9IG51bGw7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb250ZXh0LnRhcmdldCA9IGhvdmVyO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignc2hhcGUubW92ZS5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0O1xuXG4gICAgdmFyIGRlbHRhID0gY29udGV4dC5kZWx0YSxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSxcbiAgICAgICAgaXNBdHRhY2ggPSBjYW5FeGVjdXRlID09PSAnYXR0YWNoJyxcbiAgICAgICAgc2hhcGVzID0gY29udGV4dC5zaGFwZXM7XG5cbiAgICBpZiAoY2FuRXhlY3V0ZSA9PT0gZmFsc2UpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBlbnN1cmUgd2UgaGF2ZSBhY3R1YWwgcGl4ZWwgdmFsdWVzIGRlbHRhc1xuICAgIC8vIChpbXBvcnRhbnQgd2hlbiB6b29tIGxldmVsIHdhcyA+IDEgZHVyaW5nIG1vdmUpXG4gICAgZGVsdGEueCA9IHJvdW5kKGRlbHRhLngpO1xuICAgIGRlbHRhLnkgPSByb3VuZChkZWx0YS55KTtcblxuICAgIGlmIChkZWx0YS54ID09PSAwICYmIGRlbHRhLnkgPT09IDApIHtcblxuICAgICAgLy8gZGlkbid0IG1vdmVcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBtb2RlbGluZy5tb3ZlRWxlbWVudHMoc2hhcGVzLCBkZWx0YSwgY29udGV4dC50YXJnZXQsIHtcbiAgICAgIHByaW1hcnlTaGFwZTogY29udGV4dC5zaGFwZSxcbiAgICAgIGF0dGFjaDogaXNBdHRhY2hcbiAgICB9KTtcbiAgfSk7XG5cblxuICAvLyBtb3ZlIGFjdGl2YXRpb25cblxuICBldmVudEJ1cy5vbignZWxlbWVudC5tb3VzZWRvd24nLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIG9yaWdpbmFsRXZlbnQgPSBnZXRPcmlnaW5hbEV2ZW50KGV2ZW50KTtcblxuICAgIGlmICghb3JpZ2luYWxFdmVudCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdtdXN0IHN1cHBseSBET00gbW91c2Vkb3duIGV2ZW50Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXJ0KG9yaWdpbmFsRXZlbnQsIGV2ZW50LmVsZW1lbnQpO1xuICB9KTtcblxuICAvKipcbiAgICogU3RhcnQgbW92ZS5cbiAgICpcbiAgICogQHBhcmFtIHtNb3VzZUV2ZW50fSBldmVudFxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAgICogQHBhcmFtIHtib29sZWFufSBbYWN0aXZhdGVdXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dF1cbiAgICovXG4gIGZ1bmN0aW9uIHN0YXJ0KGV2ZW50LCBlbGVtZW50LCBhY3RpdmF0ZSwgY29udGV4dCkge1xuICAgIGlmIChpc09iamVjdChhY3RpdmF0ZSkpIHtcbiAgICAgIGNvbnRleHQgPSBhY3RpdmF0ZTtcbiAgICAgIGFjdGl2YXRlID0gZmFsc2U7XG4gICAgfVxuXG4gICAgLy8gZG8gbm90IG1vdmUgY29ubmVjdGlvbnMgb3IgdGhlIHJvb3QgZWxlbWVudFxuICAgIGlmIChlbGVtZW50LndheXBvaW50cyB8fCAhZWxlbWVudC5wYXJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgcmVmZXJlbmNlUG9pbnQgPSBtaWQoZWxlbWVudCk7XG5cbiAgICBkcmFnZ2luZy5pbml0KGV2ZW50LCByZWZlcmVuY2VQb2ludCwgJ3NoYXBlLm1vdmUnLCB7XG4gICAgICBjdXJzb3I6ICdncmFiYmluZycsXG4gICAgICBhdXRvQWN0aXZhdGU6IGFjdGl2YXRlLFxuICAgICAgZGF0YToge1xuICAgICAgICBzaGFwZTogZWxlbWVudCxcbiAgICAgICAgY29udGV4dDogY29udGV4dCB8fCB7fVxuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gd2UndmUgaGFuZGxlZCB0aGUgZXZlbnRcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIEFQSVxuXG4gIHRoaXMuc3RhcnQgPSBzdGFydDtcbn1cblxuTW92ZUV2ZW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZHJhZ2dpbmcnLFxuICAnbW9kZWxpbmcnLFxuICAnc2VsZWN0aW9uJyxcbiAgJ3J1bGVzJ1xuXTtcblxuXG4vKipcbiAqIFJldHVybiBhIGZpbHRlcmVkIGxpc3Qgb2YgZWxlbWVudHMgdGhhdCBkbyBub3QgY29udGFpblxuICogdGhvc2UgbmVzdGVkIGludG8gb3RoZXJzLlxuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGZpbHRlcmVkXG4gKi9cbmZ1bmN0aW9uIHJlbW92ZU5lc3RlZChlbGVtZW50cykge1xuXG4gIHZhciBpZHMgPSBncm91cEJ5KGVsZW1lbnRzLCAnaWQnKTtcblxuICByZXR1cm4gZmlsdGVyKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgd2hpbGUgKChlbGVtZW50ID0gZWxlbWVudC5wYXJlbnQpKSB7XG5cbiAgICAgIC8vIHBhcmVudCBpbiBzZWxlY3Rpb25cbiAgICAgIGlmIChpZHNbZWxlbWVudC5pZF0pIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcbn1cbiIsImltcG9ydCB7XG4gIGZsYXR0ZW4sXG4gIGZvckVhY2gsXG4gIGZpbHRlcixcbiAgZmluZCxcbiAgZ3JvdXBCeSxcbiAgbWFwLFxuICBtYXRjaFBhdHRlcm4sXG4gIHNpemVcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBzZWxmQW5kQWxsQ2hpbGRyZW5cbn0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbmltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY3JlYXRlIGFzIHN2Z0NyZWF0ZSxcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbmltcG9ydCB7IHRyYW5zbGF0ZSB9IGZyb20gJy4uLy4uL3V0aWwvU3ZnVHJhbnNmb3JtVXRpbCc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSA0OTk7XG5cbnZhciBNQVJLRVJfRFJBR0dJTkcgPSAnZGpzLWRyYWdnaW5nJyxcbiAgICBNQVJLRVJfT0sgPSAnZHJvcC1vaycsXG4gICAgTUFSS0VSX05PVF9PSyA9ICdkcm9wLW5vdC1vaycsXG4gICAgTUFSS0VSX05FV19QQVJFTlQgPSAnbmV3LXBhcmVudCcsXG4gICAgTUFSS0VSX0FUVEFDSCA9ICdhdHRhY2gtb2snO1xuXG5cbi8qKlxuICogUHJvdmlkZXMgcHJldmlld3MgZm9yIG1vdmluZyBzaGFwZXMgd2hlbiBtb3ZpbmcuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqIEBwYXJhbSB7U3R5bGVzfSBzdHlsZXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW92ZVByZXZpZXcoXG4gICAgZXZlbnRCdXMsIGNhbnZhcywgc3R5bGVzLCBwcmV2aWV3U3VwcG9ydCkge1xuXG4gIGZ1bmN0aW9uIGdldFZpc3VhbERyYWdTaGFwZXMoc2hhcGVzKSB7XG4gICAgdmFyIGVsZW1lbnRzID0gZ2V0QWxsRHJhZ2dlZEVsZW1lbnRzKHNoYXBlcyk7XG5cbiAgICB2YXIgZmlsdGVyZWRFbGVtZW50cyA9IHJlbW92ZUVkZ2VzKGVsZW1lbnRzKTtcblxuICAgIHJldHVybiBmaWx0ZXJlZEVsZW1lbnRzO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0QWxsRHJhZ2dlZEVsZW1lbnRzKHNoYXBlcykge1xuICAgIHZhciBhbGxTaGFwZXMgPSBzZWxmQW5kQWxsQ2hpbGRyZW4oc2hhcGVzLCB0cnVlKTtcblxuICAgIHZhciBhbGxDb25uZWN0aW9ucyA9IG1hcChhbGxTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICByZXR1cm4gKHNoYXBlLmluY29taW5nIHx8IFtdKS5jb25jYXQoc2hhcGUub3V0Z29pbmcgfHwgW10pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGZsYXR0ZW4oYWxsU2hhcGVzLmNvbmNhdChhbGxDb25uZWN0aW9ucykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgZHJvcCBtYXJrZXIgb24gYW4gZWxlbWVudC5cbiAgICovXG4gIGZ1bmN0aW9uIHNldE1hcmtlcihlbGVtZW50LCBtYXJrZXIpIHtcblxuICAgIFsgTUFSS0VSX0FUVEFDSCwgTUFSS0VSX09LLCBNQVJLRVJfTk9UX09LLCBNQVJLRVJfTkVXX1BBUkVOVCBdLmZvckVhY2goZnVuY3Rpb24obSkge1xuXG4gICAgICBpZiAobSA9PT0gbWFya2VyKSB7XG4gICAgICAgIGNhbnZhcy5hZGRNYXJrZXIoZWxlbWVudCwgbSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYW52YXMucmVtb3ZlTWFya2VyKGVsZW1lbnQsIG0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ha2UgYW4gZWxlbWVudCBkcmFnZ2FibGUuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtib29sZWFufSBhZGRNYXJrZXJcbiAgICovXG4gIGZ1bmN0aW9uIG1ha2VEcmFnZ2FibGUoY29udGV4dCwgZWxlbWVudCwgYWRkTWFya2VyKSB7XG5cbiAgICBwcmV2aWV3U3VwcG9ydC5hZGREcmFnZ2VyKGVsZW1lbnQsIGNvbnRleHQuZHJhZ0dyb3VwKTtcblxuICAgIGlmIChhZGRNYXJrZXIpIHtcbiAgICAgIGNhbnZhcy5hZGRNYXJrZXIoZWxlbWVudCwgTUFSS0VSX0RSQUdHSU5HKTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dC5hbGxEcmFnZ2VkRWxlbWVudHMpIHtcbiAgICAgIGNvbnRleHQuYWxsRHJhZ2dlZEVsZW1lbnRzLnB1c2goZWxlbWVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnRleHQuYWxsRHJhZ2dlZEVsZW1lbnRzID0gWyBlbGVtZW50IF07XG4gICAgfVxuICB9XG5cbiAgLy8gYXNzaWduIGEgbG93IHByaW9yaXR5IHRvIHRoaXMgaGFuZGxlclxuICAvLyB0byBsZXQgb3RoZXJzIG1vZGlmeSB0aGUgbW92ZSBjb250ZXh0IGJlZm9yZVxuICAvLyB3ZSBkcmF3IHRoaW5nc1xuICBldmVudEJ1cy5vbignc2hhcGUubW92ZS5zdGFydCcsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXG4gICAgICAgIGRyYWdTaGFwZXMgPSBjb250ZXh0LnNoYXBlcyxcbiAgICAgICAgYWxsRHJhZ2dlZEVsZW1lbnRzID0gY29udGV4dC5hbGxEcmFnZ2VkRWxlbWVudHM7XG5cbiAgICB2YXIgdmlzdWFsbHlEcmFnZ2VkU2hhcGVzID0gZ2V0VmlzdWFsRHJhZ1NoYXBlcyhkcmFnU2hhcGVzKTtcblxuICAgIGlmICghY29udGV4dC5kcmFnR3JvdXApIHtcbiAgICAgIHZhciBkcmFnR3JvdXAgPSBzdmdDcmVhdGUoJ2cnKTtcblxuICAgICAgc3ZnQXR0cihkcmFnR3JvdXAsIHN0eWxlcy5jbHMoJ2Rqcy1kcmFnLWdyb3VwJywgWyAnbm8tZXZlbnRzJyBdKSk7XG5cbiAgICAgIHZhciBkZWZhdWx0TGF5ZXIgPSBjYW52YXMuZ2V0RGVmYXVsdExheWVyKCk7XG5cbiAgICAgIHN2Z0FwcGVuZChkZWZhdWx0TGF5ZXIsIGRyYWdHcm91cCk7XG5cbiAgICAgIGNvbnRleHQuZHJhZ0dyb3VwID0gZHJhZ0dyb3VwO1xuICAgIH1cblxuICAgIC8vIGFkZCBwcmV2aWV3c1xuICAgIHZpc3VhbGx5RHJhZ2dlZFNoYXBlcy5mb3JFYWNoKGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICBwcmV2aWV3U3VwcG9ydC5hZGREcmFnZ2VyKHNoYXBlLCBjb250ZXh0LmRyYWdHcm91cCk7XG4gICAgfSk7XG5cbiAgICAvLyBjYWNoZSBhbGwgZHJhZ2dlZCBlbGVtZW50cyAvIGdmeFxuICAgIC8vIHNvIHRoYXQgd2UgY2FuIHF1aWNrbHkgdW5kbyB0aGVpciBzdGF0ZSBjaGFuZ2VzIGxhdGVyXG4gICAgaWYgKCFhbGxEcmFnZ2VkRWxlbWVudHMpIHtcbiAgICAgIGFsbERyYWdnZWRFbGVtZW50cyA9IGdldEFsbERyYWdnZWRFbGVtZW50cyhkcmFnU2hhcGVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWxsRHJhZ2dlZEVsZW1lbnRzID0gZmxhdHRlbihbXG4gICAgICAgIGFsbERyYWdnZWRFbGVtZW50cyxcbiAgICAgICAgZ2V0QWxsRHJhZ2dlZEVsZW1lbnRzKGRyYWdTaGFwZXMpXG4gICAgICBdKTtcbiAgICB9XG5cbiAgICAvLyBhZGQgZHJhZ2dpbmcgbWFya2VyXG4gICAgZm9yRWFjaChhbGxEcmFnZ2VkRWxlbWVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGNhbnZhcy5hZGRNYXJrZXIoZSwgTUFSS0VSX0RSQUdHSU5HKTtcbiAgICB9KTtcblxuICAgIGNvbnRleHQuYWxsRHJhZ2dlZEVsZW1lbnRzID0gYWxsRHJhZ2dlZEVsZW1lbnRzO1xuXG4gICAgLy8gZGV0ZXJtaW5lLCBpZiBhbnkgb2YgdGhlIGRyYWdnZWQgZWxlbWVudHMgaGF2ZSBkaWZmZXJlbnQgcGFyZW50c1xuICAgIGNvbnRleHQuZGlmZmVyZW50UGFyZW50cyA9IGhhdmVEaWZmZXJlbnRQYXJlbnRzKGRyYWdTaGFwZXMpO1xuICB9KTtcblxuICAvLyB1cGRhdGUgcHJldmlld3NcbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUubW92ZScsIExPV19QUklPUklUWSwgZnVuY3Rpb24oZXZlbnQpIHtcblxuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgZHJhZ0dyb3VwID0gY29udGV4dC5kcmFnR3JvdXAsXG4gICAgICAgIHRhcmdldCA9IGNvbnRleHQudGFyZ2V0LFxuICAgICAgICBwYXJlbnQgPSBjb250ZXh0LnNoYXBlLnBhcmVudCxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZTtcblxuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgIGlmIChjYW5FeGVjdXRlID09PSAnYXR0YWNoJykge1xuICAgICAgICBzZXRNYXJrZXIodGFyZ2V0LCBNQVJLRVJfQVRUQUNIKTtcbiAgICAgIH0gZWxzZSBpZiAoY29udGV4dC5jYW5FeGVjdXRlICYmIHRhcmdldCAmJiB0YXJnZXQuaWQgIT09IHBhcmVudC5pZCkge1xuICAgICAgICBzZXRNYXJrZXIodGFyZ2V0LCBNQVJLRVJfTkVXX1BBUkVOVCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRNYXJrZXIodGFyZ2V0LCBjb250ZXh0LmNhbkV4ZWN1dGUgPyBNQVJLRVJfT0sgOiBNQVJLRVJfTk9UX09LKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0cmFuc2xhdGUoZHJhZ0dyb3VwLCBldmVudC5keCwgZXZlbnQuZHkpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdzaGFwZS5tb3ZlLm91dCcsICdzaGFwZS5tb3ZlLmNsZWFudXAnIF0sIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcblxuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgIHNldE1hcmtlcih0YXJnZXQsIG51bGwpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gcmVtb3ZlIHByZXZpZXdzXG4gIGV2ZW50QnVzLm9uKCdzaGFwZS5tb3ZlLmNsZWFudXAnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBhbGxEcmFnZ2VkRWxlbWVudHMgPSBjb250ZXh0LmFsbERyYWdnZWRFbGVtZW50cyxcbiAgICAgICAgZHJhZ0dyb3VwID0gY29udGV4dC5kcmFnR3JvdXA7XG5cblxuICAgIC8vIHJlbW92ZSBkcmFnZ2luZyBtYXJrZXJcbiAgICBmb3JFYWNoKGFsbERyYWdnZWRFbGVtZW50cywgZnVuY3Rpb24oZSkge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihlLCBNQVJLRVJfRFJBR0dJTkcpO1xuICAgIH0pO1xuXG4gICAgaWYgKGRyYWdHcm91cCkge1xuICAgICAgc3ZnUmVtb3ZlKGRyYWdHcm91cCk7XG4gICAgfVxuICB9KTtcblxuXG4gIC8vIEFQSSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbiAgLyoqXG4gICAqIE1ha2UgYW4gZWxlbWVudCBkcmFnZ2FibGUuXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAgICogQHBhcmFtIHtib29sZWFufSBhZGRNYXJrZXJcbiAgICovXG4gIHRoaXMubWFrZURyYWdnYWJsZSA9IG1ha2VEcmFnZ2FibGU7XG59XG5cbk1vdmVQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnLFxuICAnc3R5bGVzJyxcbiAgJ3ByZXZpZXdTdXBwb3J0J1xuXTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiByZXR1cm5zIGVsZW1lbnRzIG1pbnVzIGFsbCBjb25uZWN0aW9uc1xuICogd2hlcmUgc291cmNlIG9yIHRhcmdldCBpcyBub3QgZWxlbWVudHNcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlRWRnZXMoZWxlbWVudHMpIHtcblxuICB2YXIgZmlsdGVyZWRFbGVtZW50cyA9IGZpbHRlcihlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgaWYgKCFpc0Nvbm5lY3Rpb24oZWxlbWVudCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIHJldHVybiAoXG4gICAgICAgIGZpbmQoZWxlbWVudHMsIG1hdGNoUGF0dGVybih7IGlkOiBlbGVtZW50LnNvdXJjZS5pZCB9KSkgJiZcbiAgICAgICAgZmluZChlbGVtZW50cywgbWF0Y2hQYXR0ZXJuKHsgaWQ6IGVsZW1lbnQudGFyZ2V0LmlkIH0pKVxuICAgICAgKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBmaWx0ZXJlZEVsZW1lbnRzO1xufVxuXG5mdW5jdGlvbiBoYXZlRGlmZmVyZW50UGFyZW50cyhlbGVtZW50cykge1xuICByZXR1cm4gc2l6ZShncm91cEJ5KGVsZW1lbnRzLCBmdW5jdGlvbihlKSB7IHJldHVybiBlLnBhcmVudCAmJiBlLnBhcmVudC5pZDsgfSkpICE9PSAxO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhbiBlbGVtZW50IGlzIGEgY29ubmVjdGlvbi5cbiAqL1xuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQud2F5cG9pbnRzO1xufVxuIiwiaW1wb3J0IEludGVyYWN0aW9uRXZlbnRzTW9kdWxlIGZyb20gJy4uL2ludGVyYWN0aW9uLWV2ZW50cyc7XG5pbXBvcnQgU2VsZWN0aW9uTW9kdWxlIGZyb20gJy4uL3NlbGVjdGlvbic7XG5pbXBvcnQgT3V0bGluZU1vZHVsZSBmcm9tICcuLi9vdXRsaW5lJztcbmltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuaW1wb3J0IFByZXZpZXdTdXBwb3J0TW9kdWxlIGZyb20gJy4uL3ByZXZpZXctc3VwcG9ydCc7XG5cbmltcG9ydCBNb3ZlIGZyb20gJy4vTW92ZSc7XG5pbXBvcnQgTW92ZVByZXZpZXcgZnJvbSAnLi9Nb3ZlUHJldmlldyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSxcbiAgICBTZWxlY3Rpb25Nb2R1bGUsXG4gICAgT3V0bGluZU1vZHVsZSxcbiAgICBSdWxlc01vZHVsZSxcbiAgICBEcmFnZ2luZ01vZHVsZSxcbiAgICBQcmV2aWV3U3VwcG9ydE1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogW1xuICAgICdtb3ZlJyxcbiAgICAnbW92ZVByZXZpZXcnXG4gIF0sXG4gIG1vdmU6IFsgJ3R5cGUnLCBNb3ZlIF0sXG4gIG1vdmVQcmV2aWV3OiBbICd0eXBlJywgTW92ZVByZXZpZXcgXVxufTtcbiIsImltcG9ydCBpbmhlcml0cyBmcm9tICdpbmhlcml0cyc7XG5cbmltcG9ydCBDb21tYW5kSW50ZXJjZXB0b3IgZnJvbSAnLi4vLi4vY29tbWFuZC9Db21tYW5kSW50ZXJjZXB0b3InO1xuXG5cbi8qKlxuICogQW4gYWJzdHJhY3QgcHJvdmlkZXIgdGhhdCBhbGxvd3MgbW9kZWxlcnMgdG8gaW1wbGVtZW50IGEgY3VzdG9tXG4gKiBvcmRlcmluZyBvZiBkaWFncmFtIGVsZW1lbnRzIG9uIHRoZSBjYW52YXMuXG4gKlxuICogSXQgbWFrZXMgc3VyZSB0aGF0IHRoZSBvcmRlciBpcyBhbHdheXMgcHJlc2VydmVkIGR1cmluZyBlbGVtZW50XG4gKiBjcmVhdGlvbiBhbmQgbW92ZSBvcGVyYXRpb25zLlxuICpcbiAqIEluIG9yZGVyIHRvIHVzZSB0aGlzIGJlaGF2aW9yLCBpbmhlcml0IGZyb20gaXQgYW5kIG92ZXJyaWRlXG4gKiB0aGUgbWV0aG9kIHtAbGluayBPcmRlcmluZ1Byb3ZpZGVyI2dldE9yZGVyaW5nfS5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIGBgYGphdmFzY3JpcHRcbiAqIGZ1bmN0aW9uIEN1c3RvbU9yZGVyaW5nUHJvdmlkZXIoZXZlbnRCdXMpIHtcbiAqICAgT3JkZXJpbmdQcm92aWRlci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcbiAqXG4gKiAgIHRoaXMuZ2V0T3JkZXJpbmcgPSBmdW5jdGlvbihlbGVtZW50LCBuZXdQYXJlbnQpIHtcbiAqICAgICAvLyBhbHdheXMgaW5zZXJ0IGVsZW1lbnRzIGF0IHRoZSBmcm9udFxuICogICAgIC8vIHdoZW4gbW92aW5nXG4gKiAgICAgcmV0dXJuIHtcbiAqICAgICAgIGluZGV4OiAwLFxuICogICAgICAgcGFyZW50OiBuZXdQYXJlbnRcbiAqICAgICB9O1xuICogICB9O1xuICogfVxuICogYGBgXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gT3JkZXJpbmdQcm92aWRlcihldmVudEJ1cykge1xuXG4gIENvbW1hbmRJbnRlcmNlcHRvci5jYWxsKHRoaXMsIGV2ZW50QnVzKTtcblxuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLnByZUV4ZWN1dGUoWyAnc2hhcGUuY3JlYXRlJywgJ2Nvbm5lY3Rpb24uY3JlYXRlJyBdLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5zaGFwZSB8fCBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHBhcmVudCA9IGNvbnRleHQucGFyZW50O1xuXG4gICAgdmFyIG9yZGVyaW5nID0gc2VsZi5nZXRPcmRlcmluZyhlbGVtZW50LCBwYXJlbnQpO1xuXG4gICAgaWYgKG9yZGVyaW5nKSB7XG5cbiAgICAgIGlmIChvcmRlcmluZy5wYXJlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250ZXh0LnBhcmVudCA9IG9yZGVyaW5nLnBhcmVudDtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5wYXJlbnRJbmRleCA9IG9yZGVyaW5nLmluZGV4O1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy5wcmVFeGVjdXRlKFsgJ3NoYXBlLm1vdmUnLCAnY29ubmVjdGlvbi5tb3ZlJyBdLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBlbGVtZW50ID0gY29udGV4dC5zaGFwZSB8fCBjb250ZXh0LmNvbm5lY3Rpb24sXG4gICAgICAgIHBhcmVudCA9IGNvbnRleHQubmV3UGFyZW50IHx8IGVsZW1lbnQucGFyZW50O1xuXG4gICAgdmFyIG9yZGVyaW5nID0gc2VsZi5nZXRPcmRlcmluZyhlbGVtZW50LCBwYXJlbnQpO1xuXG4gICAgaWYgKG9yZGVyaW5nKSB7XG5cbiAgICAgIGlmIChvcmRlcmluZy5wYXJlbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBjb250ZXh0Lm5ld1BhcmVudCA9IG9yZGVyaW5nLnBhcmVudDtcbiAgICAgIH1cblxuICAgICAgY29udGV4dC5uZXdQYXJlbnRJbmRleCA9IG9yZGVyaW5nLmluZGV4O1xuICAgIH1cbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgY3VzdG9tIG9yZGVyaW5nIG9mIHRoZSBlbGVtZW50LCBib3RoIGluIHRlcm1zXG4gKiBvZiBwYXJlbnQgZWxlbWVudCBhbmQgaW5kZXggaW4gdGhlIG5ldyBwYXJlbnQuXG4gKlxuICogSW1wbGVtZW50b3JzIG9mIHRoaXMgbWV0aG9kIG11c3QgcmV0dXJuIGFuIG9iamVjdCB3aXRoXG4gKiBgcGFyZW50YCBfYW5kXyBgaW5kZXhgIGluIGl0LlxuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBuZXdQYXJlbnRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IG9yZGVyaW5nIGRlc2NyaXB0b3JcbiAqL1xuT3JkZXJpbmdQcm92aWRlci5wcm90b3R5cGUuZ2V0T3JkZXJpbmcgPSBmdW5jdGlvbihlbGVtZW50LCBuZXdQYXJlbnQpIHtcbiAgcmV0dXJuIG51bGw7XG59O1xuXG5pbmhlcml0cyhPcmRlcmluZ1Byb3ZpZGVyLCBDb21tYW5kSW50ZXJjZXB0b3IpOyIsImltcG9ydCB7IGdldEJCb3ggfSBmcm9tICcuLi8uLi91dGlsL0VsZW1lbnRzJztcblxudmFyIExPV19QUklPUklUWSA9IDUwMDtcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxuaW1wb3J0IHtcbiAgcXVlcnkgYXMgZG9tUXVlcnlcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cblxuLyoqXG4gKiBAY2xhc3NcbiAqXG4gKiBBIHBsdWdpbiB0aGF0IGFkZHMgYW4gb3V0bGluZSB0byBzaGFwZXMgYW5kIGNvbm5lY3Rpb25zIHRoYXQgbWF5IGJlIGFjdGl2YXRlZCBhbmQgc3R5bGVkXG4gKiB2aWEgQ1NTIGNsYXNzZXMuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7U3R5bGVzfSBzdHlsZXNcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gT3V0bGluZShldmVudEJ1cywgc3R5bGVzLCBlbGVtZW50UmVnaXN0cnkpIHtcblxuICB0aGlzLm9mZnNldCA9IDY7XG5cbiAgdmFyIE9VVExJTkVfU1RZTEUgPSBzdHlsZXMuY2xzKCdkanMtb3V0bGluZScsIFsgJ25vLWZpbGwnIF0pO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmdW5jdGlvbiBjcmVhdGVPdXRsaW5lKGdmeCwgYm91bmRzKSB7XG4gICAgdmFyIG91dGxpbmUgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcblxuICAgIHN2Z0F0dHIob3V0bGluZSwgYXNzaWduKHtcbiAgICAgIHg6IDEwLFxuICAgICAgeTogMTAsXG4gICAgICB3aWR0aDogMTAwLFxuICAgICAgaGVpZ2h0OiAxMDBcbiAgICB9LCBPVVRMSU5FX1NUWUxFKSk7XG5cbiAgICBzdmdBcHBlbmQoZ2Z4LCBvdXRsaW5lKTtcblxuICAgIHJldHVybiBvdXRsaW5lO1xuICB9XG5cbiAgLy8gQSBsb3cgcHJpb3J0aXR5IGlzIG5lY2Vzc2FyeSwgYmVjYXVzZSBvdXRsaW5lcyBvZiBsYWJlbHMgaGF2ZSB0byBiZSB1cGRhdGVkXG4gIC8vIGFmdGVyIHRoZSBsYWJlbCBib3VuZHMgaGF2ZSBiZWVuIHVwZGF0ZWQgaW4gdGhlIHJlbmRlcmVyLlxuICBldmVudEJ1cy5vbihbICdzaGFwZS5hZGRlZCcsICdzaGFwZS5jaGFuZ2VkJyBdLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICB2YXIgb3V0bGluZSA9IGRvbVF1ZXJ5KCcuZGpzLW91dGxpbmUnLCBnZngpO1xuXG4gICAgaWYgKCFvdXRsaW5lKSB7XG4gICAgICBvdXRsaW5lID0gY3JlYXRlT3V0bGluZShnZngsIGVsZW1lbnQpO1xuICAgIH1cblxuICAgIHNlbGYudXBkYXRlU2hhcGVPdXRsaW5lKG91dGxpbmUsIGVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdjb25uZWN0aW9uLmFkZGVkJywgJ2Nvbm5lY3Rpb24uY2hhbmdlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIHZhciBvdXRsaW5lID0gZG9tUXVlcnkoJy5kanMtb3V0bGluZScsIGdmeCk7XG5cbiAgICBpZiAoIW91dGxpbmUpIHtcbiAgICAgIG91dGxpbmUgPSBjcmVhdGVPdXRsaW5lKGdmeCwgZWxlbWVudCk7XG4gICAgfVxuXG4gICAgc2VsZi51cGRhdGVDb25uZWN0aW9uT3V0bGluZShvdXRsaW5lLCBlbGVtZW50KTtcbiAgfSk7XG59XG5cblxuLyoqXG4gKiBVcGRhdGVzIHRoZSBvdXRsaW5lIG9mIGEgc2hhcGUgcmVzcGVjdGluZyB0aGUgZGltZW5zaW9uIG9mIHRoZVxuICogZWxlbWVudCBhbmQgYW4gb3V0bGluZSBvZmZzZXQuXG4gKlxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gb3V0bGluZVxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqL1xuT3V0bGluZS5wcm90b3R5cGUudXBkYXRlU2hhcGVPdXRsaW5lID0gZnVuY3Rpb24ob3V0bGluZSwgZWxlbWVudCkge1xuXG4gIHN2Z0F0dHIob3V0bGluZSwge1xuICAgIHg6IC10aGlzLm9mZnNldCxcbiAgICB5OiAtdGhpcy5vZmZzZXQsXG4gICAgd2lkdGg6IGVsZW1lbnQud2lkdGggKyB0aGlzLm9mZnNldCAqIDIsXG4gICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodCArIHRoaXMub2Zmc2V0ICogMlxuICB9KTtcblxufTtcblxuXG4vKipcbiAqIFVwZGF0ZXMgdGhlIG91dGxpbmUgb2YgYSBjb25uZWN0aW9uIHJlc3BlY3RpbmcgdGhlIGJvdW5kaW5nIGJveCBvZlxuICogdGhlIGNvbm5lY3Rpb24gYW5kIGFuIG91dGxpbmUgb2Zmc2V0LlxuICpcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IG91dGxpbmVcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKi9cbk91dGxpbmUucHJvdG90eXBlLnVwZGF0ZUNvbm5lY3Rpb25PdXRsaW5lID0gZnVuY3Rpb24ob3V0bGluZSwgY29ubmVjdGlvbikge1xuXG4gIHZhciBiYm94ID0gZ2V0QkJveChjb25uZWN0aW9uKTtcblxuICBzdmdBdHRyKG91dGxpbmUsIHtcbiAgICB4OiBiYm94LnggLSB0aGlzLm9mZnNldCxcbiAgICB5OiBiYm94LnkgLSB0aGlzLm9mZnNldCxcbiAgICB3aWR0aDogYmJveC53aWR0aCArIHRoaXMub2Zmc2V0ICogMixcbiAgICBoZWlnaHQ6IGJib3guaGVpZ2h0ICsgdGhpcy5vZmZzZXQgKiAyXG4gIH0pO1xuXG59O1xuXG5cbk91dGxpbmUuJGluamVjdCA9IFsnZXZlbnRCdXMnLCAnc3R5bGVzJywgJ2VsZW1lbnRSZWdpc3RyeSddOyIsImltcG9ydCBPdXRsaW5lIGZyb20gJy4vT3V0bGluZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ291dGxpbmUnIF0sXG4gIG91dGxpbmU6IFsgJ3R5cGUnLCBPdXRsaW5lIF1cbn07IiwiaW1wb3J0IHtcbiAgaXNBcnJheSxcbiAgaXNTdHJpbmcsXG4gIGlzT2JqZWN0LFxuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIGZpbmQsXG4gIGZpbHRlcixcbiAgbWF0Y2hQYXR0ZXJuLFxuICBpc0RlZmluZWRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBkb21pZnksXG4gIGNsYXNzZXMgYXMgZG9tQ2xhc3NlcyxcbiAgYXR0ciBhcyBkb21BdHRyLFxuICByZW1vdmUgYXMgZG9tUmVtb3ZlLFxuICBjbGVhciBhcyBkb21DbGVhclxufSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IHtcbiAgZ2V0QkJveFxufSBmcm9tICcuLi8uLi91dGlsL0VsZW1lbnRzJztcblxuaW1wb3J0IElkcyBmcm9tICcuLi8uLi91dGlsL0lkR2VuZXJhdG9yJztcblxuLy8gZG9jdW1lbnQgd2lkZSB1bmlxdWUgb3ZlcmxheSBpZHNcbnZhciBpZHMgPSBuZXcgSWRzKCdvdicpO1xuXG52YXIgTE9XX1BSSU9SSVRZID0gNTAwO1xuXG5cbi8qKlxuICogQSBzZXJ2aWNlIHRoYXQgYWxsb3dzIHVzZXJzIHRvIGF0dGFjaCBvdmVybGF5cyB0byBkaWFncmFtIGVsZW1lbnRzLlxuICpcbiAqIFRoZSBvdmVybGF5IHNlcnZpY2Ugd2lsbCB0YWtlIGNhcmUgb2Ygb3ZlcmxheSBwb3NpdGlvbmluZyBkdXJpbmcgdXBkYXRlcy5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIGFkZCBhIHBpbmsgYmFkZ2Ugb24gdGhlIHRvcCBsZWZ0IG9mIHRoZSBzaGFwZVxuICogb3ZlcmxheXMuYWRkKHNvbWVTaGFwZSwge1xuICogICBwb3NpdGlvbjoge1xuICogICAgIHRvcDogLTUsXG4gKiAgICAgbGVmdDogLTVcbiAqICAgfSxcbiAqICAgaHRtbDogJzxkaXYgc3R5bGU9XCJ3aWR0aDogMTBweDsgYmFja2dyb3VuZDogZnVjaHNpYTsgY29sb3I6IHdoaXRlO1wiPjA8L2Rpdj4nXG4gKiB9KTtcbiAqXG4gKiAvLyBvciBhZGQgdmlhIHNoYXBlIGlkXG4gKlxuICogb3ZlcmxheXMuYWRkKCdzb21lLWVsZW1lbnQtaWQnLCB7XG4gKiAgIHBvc2l0aW9uOiB7XG4gKiAgICAgdG9wOiAtNSxcbiAqICAgICBsZWZ0OiAtNVxuICogICB9XG4gKiAgIGh0bWw6ICc8ZGl2IHN0eWxlPVwid2lkdGg6IDEwcHg7IGJhY2tncm91bmQ6IGZ1Y2hzaWE7IGNvbG9yOiB3aGl0ZTtcIj4wPC9kaXY+J1xuICogfSk7XG4gKlxuICogLy8gb3IgYWRkIHdpdGggb3B0aW9uYWwgdHlwZVxuICpcbiAqIG92ZXJsYXlzLmFkZChzb21lU2hhcGUsICdiYWRnZScsIHtcbiAqICAgcG9zaXRpb246IHtcbiAqICAgICB0b3A6IC01LFxuICogICAgIGxlZnQ6IC01XG4gKiAgIH1cbiAqICAgaHRtbDogJzxkaXYgc3R5bGU9XCJ3aWR0aDogMTBweDsgYmFja2dyb3VuZDogZnVjaHNpYTsgY29sb3I6IHdoaXRlO1wiPjA8L2Rpdj4nXG4gKiB9KTtcbiAqXG4gKlxuICogLy8gcmVtb3ZlIGFuIG92ZXJsYXlcbiAqXG4gKiB2YXIgaWQgPSBvdmVybGF5cy5hZGQoLi4uKTtcbiAqIG92ZXJsYXlzLnJlbW92ZShpZCk7XG4gKlxuICpcbiAqIFlvdSBtYXkgY29uZmlndXJlIG92ZXJsYXkgZGVmYXVsdHMgZHVyaW5nIHRvb2wgYnkgcHJvdmlkaW5nIGEgYGNvbmZpZ2AgbW9kdWxlXG4gKiB3aXRoIGBvdmVybGF5cy5kZWZhdWx0c2AgYXMgYW4gZW50cnk6XG4gKlxuICoge1xuICogICBvdmVybGF5czoge1xuICogICAgIGRlZmF1bHRzOiB7XG4gKiAgICAgICBzaG93OiB7XG4gKiAgICAgICAgIG1pblpvb206IDAuNyxcbiAqICAgICAgICAgbWF4Wm9vbTogNS4wXG4gKiAgICAgICB9LFxuICogICAgICAgc2NhbGU6IHtcbiAqICAgICAgICAgbWluOiAxXG4gKiAgICAgICB9XG4gKiAgICAgfVxuICogfVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWdcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIE92ZXJsYXlzKGNvbmZpZywgZXZlbnRCdXMsIGNhbnZhcywgZWxlbWVudFJlZ2lzdHJ5KSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xuICB0aGlzLl9lbGVtZW50UmVnaXN0cnkgPSBlbGVtZW50UmVnaXN0cnk7XG5cbiAgdGhpcy5faWRzID0gaWRzO1xuXG4gIHRoaXMuX292ZXJsYXlEZWZhdWx0cyA9IGFzc2lnbih7XG5cbiAgICAvLyBubyBzaG93IGNvbnN0cmFpbnRzXG4gICAgc2hvdzogbnVsbCxcblxuICAgIC8vIGFsd2F5cyBzY2FsZVxuICAgIHNjYWxlOiB0cnVlXG4gIH0sIGNvbmZpZyAmJiBjb25maWcuZGVmYXVsdHMpO1xuXG4gIC8qKlxuICAgKiBNYXBwaW5nIG92ZXJsYXlJZCAtPiBvdmVybGF5XG4gICAqL1xuICB0aGlzLl9vdmVybGF5cyA9IHt9O1xuXG4gIC8qKlxuICAgKiBNYXBwaW5nIGVsZW1lbnRJZCAtPiBvdmVybGF5IGNvbnRhaW5lclxuICAgKi9cbiAgdGhpcy5fb3ZlcmxheUNvbnRhaW5lcnMgPSBbXTtcblxuICAvLyByb290IGh0bWwgZWxlbWVudCBmb3IgYWxsIG92ZXJsYXlzXG4gIHRoaXMuX292ZXJsYXlSb290ID0gY3JlYXRlUm9vdChjYW52YXMuZ2V0Q29udGFpbmVyKCkpO1xuXG4gIHRoaXMuX2luaXQoKTtcbn1cblxuXG5PdmVybGF5cy4kaW5qZWN0ID0gW1xuICAnY29uZmlnLm92ZXJsYXlzJyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcycsXG4gICdlbGVtZW50UmVnaXN0cnknXG5dO1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgb3ZlcmxheSB3aXRoIHRoZSBzcGVjaWZpZWQgaWQgb3IgYSBsaXN0IG9mIG92ZXJsYXlzXG4gKiBmb3IgYW4gZWxlbWVudCB3aXRoIGEgZ2l2ZW4gdHlwZS5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIHJldHVybiB0aGUgc2luZ2xlIG92ZXJsYXkgd2l0aCB0aGUgZ2l2ZW4gaWRcbiAqIG92ZXJsYXlzLmdldCgnc29tZS1pZCcpO1xuICpcbiAqIC8vIHJldHVybiBhbGwgb3ZlcmxheXMgZm9yIHRoZSBzaGFwZVxuICogb3ZlcmxheXMuZ2V0KHsgZWxlbWVudDogc29tZVNoYXBlIH0pO1xuICpcbiAqIC8vIHJldHVybiBhbGwgb3ZlcmxheXMgb24gc2hhcGUgd2l0aCB0eXBlICdiYWRnZSdcbiAqIG92ZXJsYXlzLmdldCh7IGVsZW1lbnQ6IHNvbWVTaGFwZSwgdHlwZTogJ2JhZGdlJyB9KTtcbiAqXG4gKiAvLyBzaGFwZSBjYW4gYWxzbyBiZSBzcGVjaWZpZWQgYXMgaWRcbiAqIG92ZXJsYXlzLmdldCh7IGVsZW1lbnQ6ICdlbGVtZW50LWlkJywgdHlwZTogJ2JhZGdlJyB9KTtcbiAqXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHNlYXJjaFxuICogQHBhcmFtIHtzdHJpbmd9IFtzZWFyY2guaWRdXG4gKiBAcGFyYW0ge3N0cmluZ3xkanMubW9kZWwuQmFzZX0gW3NlYXJjaC5lbGVtZW50XVxuICogQHBhcmFtIHtzdHJpbmd9IFtzZWFyY2gudHlwZV1cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R8QXJyYXk8T2JqZWN0Pn0gdGhlIG92ZXJsYXkocylcbiAqL1xuT3ZlcmxheXMucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKHNlYXJjaCkge1xuXG4gIGlmIChpc1N0cmluZyhzZWFyY2gpKSB7XG4gICAgc2VhcmNoID0geyBpZDogc2VhcmNoIH07XG4gIH1cblxuICBpZiAoaXNTdHJpbmcoc2VhcmNoLmVsZW1lbnQpKSB7XG4gICAgc2VhcmNoLmVsZW1lbnQgPSB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0KHNlYXJjaC5lbGVtZW50KTtcbiAgfVxuXG4gIGlmIChzZWFyY2guZWxlbWVudCkge1xuICAgIHZhciBjb250YWluZXIgPSB0aGlzLl9nZXRPdmVybGF5Q29udGFpbmVyKHNlYXJjaC5lbGVtZW50LCB0cnVlKTtcblxuICAgIC8vIHJldHVybiBhIGxpc3Qgb2Ygb3ZlcmxheXMgd2hlbiBzZWFyY2hpbmcgYnkgZWxlbWVudCAoK3R5cGUpXG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgcmV0dXJuIHNlYXJjaC50eXBlID8gZmlsdGVyKGNvbnRhaW5lci5vdmVybGF5cywgbWF0Y2hQYXR0ZXJuKHsgdHlwZTogc2VhcmNoLnR5cGUgfSkpIDogY29udGFpbmVyLm92ZXJsYXlzLnNsaWNlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gIH0gZWxzZVxuICBpZiAoc2VhcmNoLnR5cGUpIHtcbiAgICByZXR1cm4gZmlsdGVyKHRoaXMuX292ZXJsYXlzLCBtYXRjaFBhdHRlcm4oeyB0eXBlOiBzZWFyY2gudHlwZSB9KSk7XG4gIH0gZWxzZSB7XG5cbiAgICAvLyByZXR1cm4gc2luZ2xlIGVsZW1lbnQgd2hlbiBzZWFyY2hpbmcgYnkgaWRcbiAgICByZXR1cm4gc2VhcmNoLmlkID8gdGhpcy5fb3ZlcmxheXNbc2VhcmNoLmlkXSA6IG51bGw7XG4gIH1cbn07XG5cbi8qKlxuICogQWRkcyBhIEhUTUwgb3ZlcmxheSB0byBhbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfGRqcy5tb2RlbC5CYXNlfSAgIGVsZW1lbnQgICBhdHRhY2ggb3ZlcmxheSB0byB0aGlzIHNoYXBlXG4gKiBAcGFyYW0ge3N0cmluZ30gICAgICAgICAgICAgICAgICBbdHlwZV0gICAgb3B0aW9uYWwgdHlwZSB0byBhc3NpZ24gdG8gdGhlIG92ZXJsYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSAgICAgICAgICAgICAgICAgIG92ZXJsYXkgICB0aGUgb3ZlcmxheSBjb25maWd1cmF0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd8RE9NRWxlbWVudH0gICAgICAgb3ZlcmxheS5odG1sICAgICAgICAgICAgICAgICBodG1sIGVsZW1lbnQgdG8gdXNlIGFzIGFuIG92ZXJsYXlcbiAqIEBwYXJhbSB7T2JqZWN0fSAgICAgICAgICAgICAgICAgIFtvdmVybGF5LnNob3ddICAgICAgICAgICAgICAgc2hvdyBjb25maWd1cmF0aW9uXG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICAgICBbb3ZlcmxheS5zaG93Lm1pblpvb21dICAgICAgIG1pbmltYWwgem9vbSBsZXZlbCB0byBzaG93IHRoZSBvdmVybGF5XG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICAgICBbb3ZlcmxheS5zaG93Lm1heFpvb21dICAgICAgIG1heGltdW0gem9vbSBsZXZlbCB0byBzaG93IHRoZSBvdmVybGF5XG4gKiBAcGFyYW0ge09iamVjdH0gICAgICAgICAgICAgICAgICBvdmVybGF5LnBvc2l0aW9uICAgICAgICAgICAgIHdoZXJlIHRvIGF0dGFjaCB0aGUgb3ZlcmxheVxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgICAgW292ZXJsYXkucG9zaXRpb24ubGVmdF0gICAgICByZWxhdGl2ZSB0byBlbGVtZW50IGJib3ggbGVmdCBhdHRhY2htZW50XG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICAgICBbb3ZlcmxheS5wb3NpdGlvbi50b3BdICAgICAgIHJlbGF0aXZlIHRvIGVsZW1lbnQgYmJveCB0b3AgYXR0YWNobWVudFxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgICAgW292ZXJsYXkucG9zaXRpb24uYm90dG9tXSAgICByZWxhdGl2ZSB0byBlbGVtZW50IGJib3ggYm90dG9tIGF0dGFjaG1lbnRcbiAqIEBwYXJhbSB7bnVtYmVyfSAgICAgICAgICAgICAgICAgIFtvdmVybGF5LnBvc2l0aW9uLnJpZ2h0XSAgICAgcmVsYXRpdmUgdG8gZWxlbWVudCBiYm94IHJpZ2h0IGF0dGFjaG1lbnRcbiAqIEBwYXJhbSB7Ym9vbGVhbnxPYmplY3R9ICAgICAgICAgIFtvdmVybGF5LnNjYWxlPXRydWVdICAgICAgICAgZmFsc2UgdG8gcHJlc2VydmUgdGhlIHNhbWUgc2l6ZSByZWdhcmRsZXNzIG9mXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWdyYW0gem9vbVxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgICAgW292ZXJsYXkuc2NhbGUubWluXVxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgICAgW292ZXJsYXkuc2NhbGUubWF4XVxuICpcbiAqIEByZXR1cm4ge3N0cmluZ30gICAgICAgICAgICAgICAgIGlkIHRoYXQgbWF5IGJlIHVzZWQgdG8gcmVmZXJlbmNlIHRoZSBvdmVybGF5IGZvciB1cGRhdGUgb3IgcmVtb3ZhbFxuICovXG5PdmVybGF5cy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24oZWxlbWVudCwgdHlwZSwgb3ZlcmxheSkge1xuXG4gIGlmIChpc09iamVjdCh0eXBlKSkge1xuICAgIG92ZXJsYXkgPSB0eXBlO1xuICAgIHR5cGUgPSBudWxsO1xuICB9XG5cbiAgaWYgKCFlbGVtZW50LmlkKSB7XG4gICAgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXQoZWxlbWVudCk7XG4gIH1cblxuICBpZiAoIW92ZXJsYXkucG9zaXRpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ211c3Qgc3BlY2lmaXkgb3ZlcmxheSBwb3NpdGlvbicpO1xuICB9XG5cbiAgaWYgKCFvdmVybGF5Lmh0bWwpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ211c3Qgc3BlY2lmaXkgb3ZlcmxheSBodG1sJyk7XG4gIH1cblxuICBpZiAoIWVsZW1lbnQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFsaWQgZWxlbWVudCBzcGVjaWZpZWQnKTtcbiAgfVxuXG4gIHZhciBpZCA9IHRoaXMuX2lkcy5uZXh0KCk7XG5cbiAgb3ZlcmxheSA9IGFzc2lnbih7fSwgdGhpcy5fb3ZlcmxheURlZmF1bHRzLCBvdmVybGF5LCB7XG4gICAgaWQ6IGlkLFxuICAgIHR5cGU6IHR5cGUsXG4gICAgZWxlbWVudDogZWxlbWVudCxcbiAgICBodG1sOiBvdmVybGF5Lmh0bWxcbiAgfSk7XG5cbiAgdGhpcy5fYWRkT3ZlcmxheShvdmVybGF5KTtcblxuICByZXR1cm4gaWQ7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlIGFuIG92ZXJsYXkgd2l0aCB0aGUgZ2l2ZW4gaWQgb3IgYWxsIG92ZXJsYXlzIG1hdGNoaW5nIHRoZSBnaXZlbiBmaWx0ZXIuXG4gKlxuICogQHNlZSBPdmVybGF5cyNnZXQgZm9yIGZpbHRlciBvcHRpb25zLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbaWRdXG4gKiBAcGFyYW0ge09iamVjdH0gW2ZpbHRlcl1cbiAqL1xuT3ZlcmxheXMucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKGZpbHRlcikge1xuXG4gIHZhciBvdmVybGF5cyA9IHRoaXMuZ2V0KGZpbHRlcikgfHwgW107XG5cbiAgaWYgKCFpc0FycmF5KG92ZXJsYXlzKSkge1xuICAgIG92ZXJsYXlzID0gWyBvdmVybGF5cyBdO1xuICB9XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGZvckVhY2gob3ZlcmxheXMsIGZ1bmN0aW9uKG92ZXJsYXkpIHtcblxuICAgIHZhciBjb250YWluZXIgPSBzZWxmLl9nZXRPdmVybGF5Q29udGFpbmVyKG92ZXJsYXkuZWxlbWVudCwgdHJ1ZSk7XG5cbiAgICBpZiAob3ZlcmxheSkge1xuICAgICAgZG9tUmVtb3ZlKG92ZXJsYXkuaHRtbCk7XG4gICAgICBkb21SZW1vdmUob3ZlcmxheS5odG1sQ29udGFpbmVyKTtcblxuICAgICAgZGVsZXRlIG92ZXJsYXkuaHRtbENvbnRhaW5lcjtcbiAgICAgIGRlbGV0ZSBvdmVybGF5LmVsZW1lbnQ7XG5cbiAgICAgIGRlbGV0ZSBzZWxmLl9vdmVybGF5c1tvdmVybGF5LmlkXTtcbiAgICB9XG5cbiAgICBpZiAoY29udGFpbmVyKSB7XG4gICAgICB2YXIgaWR4ID0gY29udGFpbmVyLm92ZXJsYXlzLmluZGV4T2Yob3ZlcmxheSk7XG4gICAgICBpZiAoaWR4ICE9PSAtMSkge1xuICAgICAgICBjb250YWluZXIub3ZlcmxheXMuc3BsaWNlKGlkeCwgMSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxufTtcblxuXG5PdmVybGF5cy5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uKCkge1xuICBzZXRWaXNpYmxlKHRoaXMuX292ZXJsYXlSb290KTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbigpIHtcbiAgc2V0VmlzaWJsZSh0aGlzLl9vdmVybGF5Um9vdCwgZmFsc2UpO1xufTtcblxuT3ZlcmxheXMucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX292ZXJsYXlzID0ge307XG5cbiAgdGhpcy5fb3ZlcmxheUNvbnRhaW5lcnMgPSBbXTtcblxuICBkb21DbGVhcih0aGlzLl9vdmVybGF5Um9vdCk7XG59O1xuXG5PdmVybGF5cy5wcm90b3R5cGUuX3VwZGF0ZU92ZXJsYXlDb250YWluZXIgPSBmdW5jdGlvbihjb250YWluZXIpIHtcbiAgdmFyIGVsZW1lbnQgPSBjb250YWluZXIuZWxlbWVudCxcbiAgICAgIGh0bWwgPSBjb250YWluZXIuaHRtbDtcblxuICAvLyB1cGRhdGUgY29udGFpbmVyIGxlZnQsdG9wIGFjY29yZGluZyB0byB0aGUgZWxlbWVudHMgeCx5IGNvb3JkaW5hdGVzXG4gIC8vIHRoaXMgZW5zdXJlcyB3ZSBjYW4gYXR0YWNoIGNoaWxkIGVsZW1lbnRzIHJlbGF0aXZlIHRvIHRoaXMgY29udGFpbmVyXG5cbiAgdmFyIHggPSBlbGVtZW50LngsXG4gICAgICB5ID0gZWxlbWVudC55O1xuXG4gIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgIHZhciBiYm94ID0gZ2V0QkJveChlbGVtZW50KTtcbiAgICB4ID0gYmJveC54O1xuICAgIHkgPSBiYm94Lnk7XG4gIH1cblxuICBzZXRQb3NpdGlvbihodG1sLCB4LCB5KTtcblxuICBkb21BdHRyKGNvbnRhaW5lci5odG1sLCAnZGF0YS1jb250YWluZXItaWQnLCBlbGVtZW50LmlkKTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl91cGRhdGVPdmVybGF5ID0gZnVuY3Rpb24ob3ZlcmxheSkge1xuXG4gIHZhciBwb3NpdGlvbiA9IG92ZXJsYXkucG9zaXRpb24sXG4gICAgICBodG1sQ29udGFpbmVyID0gb3ZlcmxheS5odG1sQ29udGFpbmVyLFxuICAgICAgZWxlbWVudCA9IG92ZXJsYXkuZWxlbWVudDtcblxuICAvLyB1cGRhdGUgb3ZlcmxheSBodG1sIHJlbGF0aXZlIHRvIHNoYXBlIGJlY2F1c2VcbiAgLy8gaXQgaXMgYWxyZWFkeSBwb3NpdGlvbmVkIG9uIHRoZSBlbGVtZW50XG5cbiAgLy8gdXBkYXRlIHJlbGF0aXZlXG4gIHZhciBsZWZ0ID0gcG9zaXRpb24ubGVmdCxcbiAgICAgIHRvcCA9IHBvc2l0aW9uLnRvcDtcblxuICBpZiAocG9zaXRpb24ucmlnaHQgIT09IHVuZGVmaW5lZCkge1xuXG4gICAgdmFyIHdpZHRoO1xuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICB3aWR0aCA9IGdldEJCb3goZWxlbWVudCkud2lkdGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpZHRoID0gZWxlbWVudC53aWR0aDtcbiAgICB9XG5cbiAgICBsZWZ0ID0gcG9zaXRpb24ucmlnaHQgKiAtMSArIHdpZHRoO1xuICB9XG5cbiAgaWYgKHBvc2l0aW9uLmJvdHRvbSAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICB2YXIgaGVpZ2h0O1xuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICBoZWlnaHQgPSBnZXRCQm94KGVsZW1lbnQpLmhlaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgaGVpZ2h0ID0gZWxlbWVudC5oZWlnaHQ7XG4gICAgfVxuXG4gICAgdG9wID0gcG9zaXRpb24uYm90dG9tICogLTEgKyBoZWlnaHQ7XG4gIH1cblxuICBzZXRQb3NpdGlvbihodG1sQ29udGFpbmVyLCBsZWZ0IHx8IDAsIHRvcCB8fCAwKTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl9jcmVhdGVPdmVybGF5Q29udGFpbmVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xuICB2YXIgaHRtbCA9IGRvbWlmeSgnPGRpdiBjbGFzcz1cImRqcy1vdmVybGF5c1wiIHN0eWxlPVwicG9zaXRpb246IGFic29sdXRlXCIgLz4nKTtcblxuICB0aGlzLl9vdmVybGF5Um9vdC5hcHBlbmRDaGlsZChodG1sKTtcblxuICB2YXIgY29udGFpbmVyID0ge1xuICAgIGh0bWw6IGh0bWwsXG4gICAgZWxlbWVudDogZWxlbWVudCxcbiAgICBvdmVybGF5czogW11cbiAgfTtcblxuICB0aGlzLl91cGRhdGVPdmVybGF5Q29udGFpbmVyKGNvbnRhaW5lcik7XG5cbiAgdGhpcy5fb3ZlcmxheUNvbnRhaW5lcnMucHVzaChjb250YWluZXIpO1xuXG4gIHJldHVybiBjb250YWluZXI7XG59O1xuXG5cbk92ZXJsYXlzLnByb3RvdHlwZS5fdXBkYXRlUm9vdCA9IGZ1bmN0aW9uKHZpZXdib3gpIHtcbiAgdmFyIHNjYWxlID0gdmlld2JveC5zY2FsZSB8fCAxO1xuXG4gIHZhciBtYXRyaXggPSAnbWF0cml4KCcgK1xuICBbXG4gICAgc2NhbGUsXG4gICAgMCxcbiAgICAwLFxuICAgIHNjYWxlLFxuICAgIC0xICogdmlld2JveC54ICogc2NhbGUsXG4gICAgLTEgKiB2aWV3Ym94LnkgKiBzY2FsZVxuICBdLmpvaW4oJywnKSArXG4gICcpJztcblxuICBzZXRUcmFuc2Zvcm0odGhpcy5fb3ZlcmxheVJvb3QsIG1hdHJpeCk7XG59O1xuXG5cbk92ZXJsYXlzLnByb3RvdHlwZS5fZ2V0T3ZlcmxheUNvbnRhaW5lciA9IGZ1bmN0aW9uKGVsZW1lbnQsIHJhdykge1xuICB2YXIgY29udGFpbmVyID0gZmluZCh0aGlzLl9vdmVybGF5Q29udGFpbmVycywgZnVuY3Rpb24oYykge1xuICAgIHJldHVybiBjLmVsZW1lbnQgPT09IGVsZW1lbnQ7XG4gIH0pO1xuXG5cbiAgaWYgKCFjb250YWluZXIgJiYgIXJhdykge1xuICAgIHJldHVybiB0aGlzLl9jcmVhdGVPdmVybGF5Q29udGFpbmVyKGVsZW1lbnQpO1xuICB9XG5cbiAgcmV0dXJuIGNvbnRhaW5lcjtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl9hZGRPdmVybGF5ID0gZnVuY3Rpb24ob3ZlcmxheSkge1xuXG4gIHZhciBpZCA9IG92ZXJsYXkuaWQsXG4gICAgICBlbGVtZW50ID0gb3ZlcmxheS5lbGVtZW50LFxuICAgICAgaHRtbCA9IG92ZXJsYXkuaHRtbCxcbiAgICAgIGh0bWxDb250YWluZXIsXG4gICAgICBvdmVybGF5Q29udGFpbmVyO1xuXG4gIC8vIHVud3JhcCBqcXVlcnkgKGZvciB0aG9zZSB3aG8gbmVlZCBpdClcbiAgaWYgKGh0bWwuZ2V0ICYmIGh0bWwuY29uc3RydWN0b3IucHJvdG90eXBlLmpxdWVyeSkge1xuICAgIGh0bWwgPSBodG1sLmdldCgwKTtcbiAgfVxuXG4gIC8vIGNyZWF0ZSBwcm9wZXIgaHRtbCBlbGVtZW50cyBmcm9tXG4gIC8vIG92ZXJsYXkgSFRNTCBzdHJpbmdzXG4gIGlmIChpc1N0cmluZyhodG1sKSkge1xuICAgIGh0bWwgPSBkb21pZnkoaHRtbCk7XG4gIH1cblxuICBvdmVybGF5Q29udGFpbmVyID0gdGhpcy5fZ2V0T3ZlcmxheUNvbnRhaW5lcihlbGVtZW50KTtcblxuICBodG1sQ29udGFpbmVyID0gZG9taWZ5KCc8ZGl2IGNsYXNzPVwiZGpzLW92ZXJsYXlcIiBkYXRhLW92ZXJsYXktaWQ9XCInICsgaWQgKyAnXCIgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGVcIj4nKTtcblxuICBodG1sQ29udGFpbmVyLmFwcGVuZENoaWxkKGh0bWwpO1xuXG4gIGlmIChvdmVybGF5LnR5cGUpIHtcbiAgICBkb21DbGFzc2VzKGh0bWxDb250YWluZXIpLmFkZCgnZGpzLW92ZXJsYXktJyArIG92ZXJsYXkudHlwZSk7XG4gIH1cblxuICBvdmVybGF5Lmh0bWxDb250YWluZXIgPSBodG1sQ29udGFpbmVyO1xuXG4gIG92ZXJsYXlDb250YWluZXIub3ZlcmxheXMucHVzaChvdmVybGF5KTtcbiAgb3ZlcmxheUNvbnRhaW5lci5odG1sLmFwcGVuZENoaWxkKGh0bWxDb250YWluZXIpO1xuXG4gIHRoaXMuX292ZXJsYXlzW2lkXSA9IG92ZXJsYXk7XG5cbiAgdGhpcy5fdXBkYXRlT3ZlcmxheShvdmVybGF5KTtcbiAgdGhpcy5fdXBkYXRlT3ZlcmxheVZpc2liaWx0eShvdmVybGF5LCB0aGlzLl9jYW52YXMudmlld2JveCgpKTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl91cGRhdGVPdmVybGF5VmlzaWJpbHR5ID0gZnVuY3Rpb24ob3ZlcmxheSwgdmlld2JveCkge1xuICB2YXIgc2hvdyA9IG92ZXJsYXkuc2hvdyxcbiAgICAgIG1pblpvb20gPSBzaG93ICYmIHNob3cubWluWm9vbSxcbiAgICAgIG1heFpvb20gPSBzaG93ICYmIHNob3cubWF4Wm9vbSxcbiAgICAgIGh0bWxDb250YWluZXIgPSBvdmVybGF5Lmh0bWxDb250YWluZXIsXG4gICAgICB2aXNpYmxlID0gdHJ1ZTtcblxuICBpZiAoc2hvdykge1xuICAgIGlmIChcbiAgICAgIChpc0RlZmluZWQobWluWm9vbSkgJiYgbWluWm9vbSA+IHZpZXdib3guc2NhbGUpIHx8XG4gICAgICAoaXNEZWZpbmVkKG1heFpvb20pICYmIG1heFpvb20gPCB2aWV3Ym94LnNjYWxlKVxuICAgICkge1xuICAgICAgdmlzaWJsZSA9IGZhbHNlO1xuICAgIH1cblxuICAgIHNldFZpc2libGUoaHRtbENvbnRhaW5lciwgdmlzaWJsZSk7XG4gIH1cblxuICB0aGlzLl91cGRhdGVPdmVybGF5U2NhbGUob3ZlcmxheSwgdmlld2JveCk7XG59O1xuXG5cbk92ZXJsYXlzLnByb3RvdHlwZS5fdXBkYXRlT3ZlcmxheVNjYWxlID0gZnVuY3Rpb24ob3ZlcmxheSwgdmlld2JveCkge1xuICB2YXIgc2hvdWxkU2NhbGUgPSBvdmVybGF5LnNjYWxlLFxuICAgICAgbWluU2NhbGUsXG4gICAgICBtYXhTY2FsZSxcbiAgICAgIGh0bWxDb250YWluZXIgPSBvdmVybGF5Lmh0bWxDb250YWluZXI7XG5cbiAgdmFyIHNjYWxlLCB0cmFuc2Zvcm0gPSAnJztcblxuICBpZiAoc2hvdWxkU2NhbGUgIT09IHRydWUpIHtcblxuICAgIGlmIChzaG91bGRTY2FsZSA9PT0gZmFsc2UpIHtcbiAgICAgIG1pblNjYWxlID0gMTtcbiAgICAgIG1heFNjYWxlID0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWluU2NhbGUgPSBzaG91bGRTY2FsZS5taW47XG4gICAgICBtYXhTY2FsZSA9IHNob3VsZFNjYWxlLm1heDtcbiAgICB9XG5cbiAgICBpZiAoaXNEZWZpbmVkKG1pblNjYWxlKSAmJiB2aWV3Ym94LnNjYWxlIDwgbWluU2NhbGUpIHtcbiAgICAgIHNjYWxlID0gKDEgLyB2aWV3Ym94LnNjYWxlIHx8IDEpICogbWluU2NhbGU7XG4gICAgfVxuXG4gICAgaWYgKGlzRGVmaW5lZChtYXhTY2FsZSkgJiYgdmlld2JveC5zY2FsZSA+IG1heFNjYWxlKSB7XG4gICAgICBzY2FsZSA9ICgxIC8gdmlld2JveC5zY2FsZSB8fCAxKSAqIG1heFNjYWxlO1xuICAgIH1cbiAgfVxuXG4gIGlmIChpc0RlZmluZWQoc2NhbGUpKSB7XG4gICAgdHJhbnNmb3JtID0gJ3NjYWxlKCcgKyBzY2FsZSArICcsJyArIHNjYWxlICsgJyknO1xuICB9XG5cbiAgc2V0VHJhbnNmb3JtKGh0bWxDb250YWluZXIsIHRyYW5zZm9ybSk7XG59O1xuXG5cbk92ZXJsYXlzLnByb3RvdHlwZS5fdXBkYXRlT3ZlcmxheXNWaXNpYmlsdHkgPSBmdW5jdGlvbih2aWV3Ym94KSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGZvckVhY2godGhpcy5fb3ZlcmxheXMsIGZ1bmN0aW9uKG92ZXJsYXkpIHtcbiAgICBzZWxmLl91cGRhdGVPdmVybGF5VmlzaWJpbHR5KG92ZXJsYXksIHZpZXdib3gpO1xuICB9KTtcbn07XG5cblxuT3ZlcmxheXMucHJvdG90eXBlLl9pbml0ID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG5cbiAgLy8gc2Nyb2xsL3pvb20gaW50ZWdyYXRpb25cblxuICBmdW5jdGlvbiB1cGRhdGVWaWV3Ym94KHZpZXdib3gpIHtcbiAgICBzZWxmLl91cGRhdGVSb290KHZpZXdib3gpO1xuICAgIHNlbGYuX3VwZGF0ZU92ZXJsYXlzVmlzaWJpbHR5KHZpZXdib3gpO1xuXG4gICAgc2VsZi5zaG93KCk7XG4gIH1cblxuICBldmVudEJ1cy5vbignY2FudmFzLnZpZXdib3guY2hhbmdpbmcnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHNlbGYuaGlkZSgpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY2FudmFzLnZpZXdib3guY2hhbmdlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdXBkYXRlVmlld2JveChldmVudC52aWV3Ym94KTtcbiAgfSk7XG5cblxuICAvLyByZW1vdmUgaW50ZWdyYXRpb25cblxuICBldmVudEJ1cy5vbihbICdzaGFwZS5yZW1vdmUnLCAnY29ubmVjdGlvbi5yZW1vdmUnIF0sIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbWVudCA9IGUuZWxlbWVudDtcbiAgICB2YXIgb3ZlcmxheXMgPSBzZWxmLmdldCh7IGVsZW1lbnQ6IGVsZW1lbnQgfSk7XG5cbiAgICBmb3JFYWNoKG92ZXJsYXlzLCBmdW5jdGlvbihvKSB7XG4gICAgICBzZWxmLnJlbW92ZShvLmlkKTtcbiAgICB9KTtcblxuICAgIHZhciBjb250YWluZXIgPSBzZWxmLl9nZXRPdmVybGF5Q29udGFpbmVyKGVsZW1lbnQpO1xuXG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgZG9tUmVtb3ZlKGNvbnRhaW5lci5odG1sKTtcbiAgICAgIHZhciBpID0gc2VsZi5fb3ZlcmxheUNvbnRhaW5lcnMuaW5kZXhPZihjb250YWluZXIpO1xuICAgICAgaWYgKGkgIT09IC0xKSB7XG4gICAgICAgIHNlbGYuX292ZXJsYXlDb250YWluZXJzLnNwbGljZShpLCAxKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG5cbiAgLy8gbW92ZSBpbnRlZ3JhdGlvblxuXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LmNoYW5nZWQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbWVudCA9IGUuZWxlbWVudDtcblxuICAgIHZhciBjb250YWluZXIgPSBzZWxmLl9nZXRPdmVybGF5Q29udGFpbmVyKGVsZW1lbnQsIHRydWUpO1xuXG4gICAgaWYgKGNvbnRhaW5lcikge1xuICAgICAgZm9yRWFjaChjb250YWluZXIub3ZlcmxheXMsIGZ1bmN0aW9uKG92ZXJsYXkpIHtcbiAgICAgICAgc2VsZi5fdXBkYXRlT3ZlcmxheShvdmVybGF5KTtcbiAgICAgIH0pO1xuXG4gICAgICBzZWxmLl91cGRhdGVPdmVybGF5Q29udGFpbmVyKGNvbnRhaW5lcik7XG4gICAgfVxuICB9KTtcblxuXG4gIC8vIG1hcmtlciBpbnRlZ3JhdGlvbiwgc2ltcGx5IGFkZCB0aGVtIG9uIHRoZSBvdmVybGF5cyBhcyBjbGFzc2VzLCB0b28uXG5cbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQubWFya2VyLnVwZGF0ZScsIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgY29udGFpbmVyID0gc2VsZi5fZ2V0T3ZlcmxheUNvbnRhaW5lcihlLmVsZW1lbnQsIHRydWUpO1xuICAgIGlmIChjb250YWluZXIpIHtcbiAgICAgIGRvbUNsYXNzZXMoY29udGFpbmVyLmh0bWwpW2UuYWRkID8gJ2FkZCcgOiAncmVtb3ZlJ10oZS5tYXJrZXIpO1xuICAgIH1cbiAgfSk7XG5cblxuICAvLyBjbGVhciBvdmVybGF5cyB3aXRoIGRpYWdyYW1cblxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5jbGVhcicsIHRoaXMuY2xlYXIsIHRoaXMpO1xufTtcblxuXG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gY3JlYXRlUm9vdChwYXJlbnROb2RlKSB7XG4gIHZhciByb290ID0gZG9taWZ5KFxuICAgICc8ZGl2IGNsYXNzPVwiZGpzLW92ZXJsYXktY29udGFpbmVyXCIgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGU7IHdpZHRoOiAwOyBoZWlnaHQ6IDA7XCIgLz4nXG4gICk7XG5cbiAgcGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUocm9vdCwgcGFyZW50Tm9kZS5maXJzdENoaWxkKTtcblxuICByZXR1cm4gcm9vdDtcbn1cblxuZnVuY3Rpb24gc2V0UG9zaXRpb24oZWwsIHgsIHkpIHtcbiAgYXNzaWduKGVsLnN0eWxlLCB7IGxlZnQ6IHggKyAncHgnLCB0b3A6IHkgKyAncHgnIH0pO1xufVxuXG5mdW5jdGlvbiBzZXRWaXNpYmxlKGVsLCB2aXNpYmxlKSB7XG4gIGVsLnN0eWxlLmRpc3BsYXkgPSB2aXNpYmxlID09PSBmYWxzZSA/ICdub25lJyA6ICcnO1xufVxuXG5mdW5jdGlvbiBzZXRUcmFuc2Zvcm0oZWwsIHRyYW5zZm9ybSkge1xuXG4gIGVsLnN0eWxlWyd0cmFuc2Zvcm0tb3JpZ2luJ10gPSAndG9wIGxlZnQnO1xuXG4gIFsgJycsICctbXMtJywgJy13ZWJraXQtJyBdLmZvckVhY2goZnVuY3Rpb24ocHJlZml4KSB7XG4gICAgZWwuc3R5bGVbcHJlZml4ICsgJ3RyYW5zZm9ybSddID0gdHJhbnNmb3JtO1xuICB9KTtcbn0iLCJpbXBvcnQgT3ZlcmxheXMgZnJvbSAnLi9PdmVybGF5cyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ292ZXJsYXlzJyBdLFxuICBvdmVybGF5czogWyAndHlwZScsIE92ZXJsYXlzIF1cbn07IiwiaW1wb3J0IHtcbiAgaXNBcnJheSxcbiAgaXNGdW5jdGlvbixcbiAgZm9yRWFjaFxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRvbWlmeSxcbiAgcXVlcnkgYXMgZG9tUXVlcnksXG4gIGF0dHIgYXMgZG9tQXR0cixcbiAgY2xlYXIgYXMgZG9tQ2xlYXIsXG4gIGNsYXNzZXMgYXMgZG9tQ2xhc3NlcyxcbiAgbWF0Y2hlcyBhcyBkb21NYXRjaGVzLFxuICBkZWxlZ2F0ZSBhcyBkb21EZWxlZ2F0ZSxcbiAgZXZlbnQgYXMgZG9tRXZlbnRcbn0gZnJvbSAnbWluLWRvbSc7XG5cblxudmFyIFRPR0dMRV9TRUxFQ1RPUiA9ICcuZGpzLXBhbGV0dGUtdG9nZ2xlJyxcbiAgICBFTlRSWV9TRUxFQ1RPUiA9ICcuZW50cnknLFxuICAgIEVMRU1FTlRfU0VMRUNUT1IgPSBUT0dHTEVfU0VMRUNUT1IgKyAnLCAnICsgRU5UUllfU0VMRUNUT1I7XG5cbnZhciBQQUxFVFRFX09QRU5fQ0xTID0gJ29wZW4nLFxuICAgIFBBTEVUVEVfVFdPX0NPTFVNTl9DTFMgPSAndHdvLWNvbHVtbic7XG5cbnZhciBERUZBVUxUX1BSSU9SSVRZID0gMTAwMDtcblxuXG4vKipcbiAqIEEgcGFsZXR0ZSBjb250YWluaW5nIG1vZGVsaW5nIGVsZW1lbnRzLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBQYWxldHRlKGV2ZW50QnVzLCBjYW52YXMpIHtcblxuICB0aGlzLl9ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGV2ZW50QnVzLm9uKCd0b29sLW1hbmFnZXIudXBkYXRlJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgdG9vbCA9IGV2ZW50LnRvb2w7XG5cbiAgICBzZWxmLnVwZGF0ZVRvb2xIaWdobGlnaHQodG9vbCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdpMThuLmNoYW5nZWQnLCBmdW5jdGlvbigpIHtcbiAgICBzZWxmLl91cGRhdGUoKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2RpYWdyYW0uaW5pdCcsIGZ1bmN0aW9uKCkge1xuXG4gICAgc2VsZi5fZGlhZ3JhbUluaXRpYWxpemVkID0gdHJ1ZTtcblxuICAgIHNlbGYuX3JlYnVpbGQoKTtcbiAgfSk7XG59XG5cblBhbGV0dGUuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2NhbnZhcycgXTtcblxuXG4vKipcbiAqIFJlZ2lzdGVyIGEgcHJvdmlkZXIgd2l0aCB0aGUgcGFsZXR0ZVxuICpcbiAqIEBwYXJhbSAge251bWJlcn0gW3ByaW9yaXR5PTEwMDBdXG4gKiBAcGFyYW0gIHtQYWxldHRlUHJvdmlkZXJ9IHByb3ZpZGVyXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbnN0IHBhbGV0dGVQcm92aWRlciA9IHtcbiAqICAgZ2V0UGFsZXR0ZUVudHJpZXM6IGZ1bmN0aW9uKCkge1xuICogICAgIHJldHVybiBmdW5jdGlvbihlbnRyaWVzKSB7XG4gKiAgICAgICByZXR1cm4ge1xuICogICAgICAgICAuLi5lbnRyaWVzLFxuICogICAgICAgICAnZW50cnktMSc6IHtcbiAqICAgICAgICAgICBsYWJlbDogJ015IEVudHJ5JyxcbiAqICAgICAgICAgICBhY3Rpb246IGZ1bmN0aW9uKCkgeyBhbGVydChcIkkgaGF2ZSBiZWVuIGNsaWNrZWQhXCIpOyB9XG4gKiAgICAgICAgIH1cbiAqICAgICAgIH07XG4gKiAgICAgfVxuICogICB9XG4gKiB9O1xuICpcbiAqIHBhbGV0dGUucmVnaXN0ZXJQcm92aWRlcig4MDAsIHBhbGV0dGVQcm92aWRlcik7XG4gKi9cblBhbGV0dGUucHJvdG90eXBlLnJlZ2lzdGVyUHJvdmlkZXIgPSBmdW5jdGlvbihwcmlvcml0eSwgcHJvdmlkZXIpIHtcbiAgaWYgKCFwcm92aWRlcikge1xuICAgIHByb3ZpZGVyID0gcHJpb3JpdHk7XG4gICAgcHJpb3JpdHkgPSBERUZBVUxUX1BSSU9SSVRZO1xuICB9XG5cbiAgdGhpcy5fZXZlbnRCdXMub24oJ3BhbGV0dGUuZ2V0UHJvdmlkZXJzJywgcHJpb3JpdHksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZXZlbnQucHJvdmlkZXJzLnB1c2gocHJvdmlkZXIpO1xuICB9KTtcblxuICB0aGlzLl9yZWJ1aWxkKCk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgcGFsZXR0ZSBlbnRyaWVzXG4gKlxuICogQHJldHVybiB7T2JqZWN0PHN0cmluZywgUGFsZXR0ZUVudHJ5RGVzY3JpcHRvcj59IG1hcCBvZiBlbnRyaWVzXG4gKi9cblBhbGV0dGUucHJvdG90eXBlLmdldEVudHJpZXMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHByb3ZpZGVycyA9IHRoaXMuX2dldFByb3ZpZGVycygpO1xuXG4gIHJldHVybiBwcm92aWRlcnMucmVkdWNlKGFkZFBhbGV0dGVFbnRyaWVzLCB7fSk7XG59O1xuXG5QYWxldHRlLnByb3RvdHlwZS5fcmVidWlsZCA9IGZ1bmN0aW9uKCkge1xuXG4gIGlmICghdGhpcy5fZGlhZ3JhbUluaXRpYWxpemVkKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHByb3ZpZGVycyA9IHRoaXMuX2dldFByb3ZpZGVycygpO1xuXG4gIGlmICghcHJvdmlkZXJzLmxlbmd0aCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICghdGhpcy5fY29udGFpbmVyKSB7XG4gICAgdGhpcy5faW5pdCgpO1xuICB9XG5cbiAgdGhpcy5fdXBkYXRlKCk7XG59O1xuXG4vKipcbiAqIEluaXRpYWxpemVcbiAqL1xuUGFsZXR0ZS5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbigpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdmFyIGV2ZW50QnVzID0gdGhpcy5fZXZlbnRCdXM7XG5cbiAgdmFyIHBhcmVudENvbnRhaW5lciA9IHRoaXMuX2dldFBhcmVudENvbnRhaW5lcigpO1xuXG4gIHZhciBjb250YWluZXIgPSB0aGlzLl9jb250YWluZXIgPSBkb21pZnkoUGFsZXR0ZS5IVE1MX01BUktVUCk7XG5cbiAgcGFyZW50Q29udGFpbmVyLmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG5cbiAgZG9tRGVsZWdhdGUuYmluZChjb250YWluZXIsIEVMRU1FTlRfU0VMRUNUT1IsICdjbGljaycsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgdGFyZ2V0ID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQ7XG5cbiAgICBpZiAoZG9tTWF0Y2hlcyh0YXJnZXQsIFRPR0dMRV9TRUxFQ1RPUikpIHtcbiAgICAgIHJldHVybiBzZWxmLnRvZ2dsZSgpO1xuICAgIH1cblxuICAgIHNlbGYudHJpZ2dlcignY2xpY2snLCBldmVudCk7XG4gIH0pO1xuXG4gIC8vIHByZXZlbnQgZHJhZyBwcm9wYWdhdGlvblxuICBkb21FdmVudC5iaW5kKGNvbnRhaW5lciwgJ21vdXNlZG93bicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH0pO1xuXG4gIC8vIHByZXZlbnQgZHJhZyBwcm9wYWdhdGlvblxuICBkb21EZWxlZ2F0ZS5iaW5kKGNvbnRhaW5lciwgRU5UUllfU0VMRUNUT1IsICdkcmFnc3RhcnQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHNlbGYudHJpZ2dlcignZHJhZ3N0YXJ0JywgZXZlbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY2FudmFzLnJlc2l6ZWQnLCB0aGlzLl9sYXlvdXRDaGFuZ2VkLCB0aGlzKTtcblxuICBldmVudEJ1cy5maXJlKCdwYWxldHRlLmNyZWF0ZScsIHtcbiAgICBjb250YWluZXI6IGNvbnRhaW5lclxuICB9KTtcbn07XG5cblBhbGV0dGUucHJvdG90eXBlLl9nZXRQcm92aWRlcnMgPSBmdW5jdGlvbihpZCkge1xuXG4gIHZhciBldmVudCA9IHRoaXMuX2V2ZW50QnVzLmNyZWF0ZUV2ZW50KHtcbiAgICB0eXBlOiAncGFsZXR0ZS5nZXRQcm92aWRlcnMnLFxuICAgIHByb3ZpZGVyczogW11cbiAgfSk7XG5cbiAgdGhpcy5fZXZlbnRCdXMuZmlyZShldmVudCk7XG5cbiAgcmV0dXJuIGV2ZW50LnByb3ZpZGVycztcbn07XG5cbi8qKlxuICogVXBkYXRlIHBhbGV0dGUgc3RhdGUuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBbc3RhdGVdIHsgb3BlbiwgdHdvQ29sdW1uIH1cbiAqL1xuUGFsZXR0ZS5wcm90b3R5cGUuX3RvZ2dsZVN0YXRlID0gZnVuY3Rpb24oc3RhdGUpIHtcblxuICBzdGF0ZSA9IHN0YXRlIHx8IHt9O1xuXG4gIHZhciBwYXJlbnQgPSB0aGlzLl9nZXRQYXJlbnRDb250YWluZXIoKSxcbiAgICAgIGNvbnRhaW5lciA9IHRoaXMuX2NvbnRhaW5lcjtcblxuICB2YXIgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICB2YXIgdHdvQ29sdW1uO1xuXG4gIHZhciBjbHMgPSBkb21DbGFzc2VzKGNvbnRhaW5lcik7XG5cbiAgaWYgKCd0d29Db2x1bW4nIGluIHN0YXRlKSB7XG4gICAgdHdvQ29sdW1uID0gc3RhdGUudHdvQ29sdW1uO1xuICB9IGVsc2Uge1xuICAgIHR3b0NvbHVtbiA9IHRoaXMuX25lZWRzQ29sbGFwc2UocGFyZW50LmNsaWVudEhlaWdodCwgdGhpcy5fZW50cmllcyB8fCB7fSk7XG4gIH1cblxuICAvLyBhbHdheXMgdXBkYXRlIHR3byBjb2x1bW5cbiAgY2xzLnRvZ2dsZShQQUxFVFRFX1RXT19DT0xVTU5fQ0xTLCB0d29Db2x1bW4pO1xuXG4gIGlmICgnb3BlbicgaW4gc3RhdGUpIHtcbiAgICBjbHMudG9nZ2xlKFBBTEVUVEVfT1BFTl9DTFMsIHN0YXRlLm9wZW4pO1xuICB9XG5cbiAgZXZlbnRCdXMuZmlyZSgncGFsZXR0ZS5jaGFuZ2VkJywge1xuICAgIHR3b0NvbHVtbjogdHdvQ29sdW1uLFxuICAgIG9wZW46IHRoaXMuaXNPcGVuKClcbiAgfSk7XG59O1xuXG5QYWxldHRlLnByb3RvdHlwZS5fdXBkYXRlID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIGVudHJpZXNDb250YWluZXIgPSBkb21RdWVyeSgnLmRqcy1wYWxldHRlLWVudHJpZXMnLCB0aGlzLl9jb250YWluZXIpLFxuICAgICAgZW50cmllcyA9IHRoaXMuX2VudHJpZXMgPSB0aGlzLmdldEVudHJpZXMoKTtcblxuICBkb21DbGVhcihlbnRyaWVzQ29udGFpbmVyKTtcblxuICBmb3JFYWNoKGVudHJpZXMsIGZ1bmN0aW9uKGVudHJ5LCBpZCkge1xuXG4gICAgdmFyIGdyb3VwaW5nID0gZW50cnkuZ3JvdXAgfHwgJ2RlZmF1bHQnO1xuXG4gICAgdmFyIGNvbnRhaW5lciA9IGRvbVF1ZXJ5KCdbZGF0YS1ncm91cD0nICsgZ3JvdXBpbmcgKyAnXScsIGVudHJpZXNDb250YWluZXIpO1xuICAgIGlmICghY29udGFpbmVyKSB7XG4gICAgICBjb250YWluZXIgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJncm91cFwiIGRhdGEtZ3JvdXA9XCInICsgZ3JvdXBpbmcgKyAnXCI+PC9kaXY+Jyk7XG4gICAgICBlbnRyaWVzQ29udGFpbmVyLmFwcGVuZENoaWxkKGNvbnRhaW5lcik7XG4gICAgfVxuXG4gICAgdmFyIGh0bWwgPSBlbnRyeS5odG1sIHx8IChcbiAgICAgIGVudHJ5LnNlcGFyYXRvciA/XG4gICAgICAgICc8aHIgY2xhc3M9XCJzZXBhcmF0b3JcIiAvPicgOlxuICAgICAgICAnPGRpdiBjbGFzcz1cImVudHJ5XCIgZHJhZ2dhYmxlPVwidHJ1ZVwiPjwvZGl2PicpO1xuXG5cbiAgICB2YXIgY29udHJvbCA9IGRvbWlmeShodG1sKTtcbiAgICBjb250YWluZXIuYXBwZW5kQ2hpbGQoY29udHJvbCk7XG5cbiAgICBpZiAoIWVudHJ5LnNlcGFyYXRvcikge1xuICAgICAgZG9tQXR0cihjb250cm9sLCAnZGF0YS1hY3Rpb24nLCBpZCk7XG5cbiAgICAgIGlmIChlbnRyeS50aXRsZSkge1xuICAgICAgICBkb21BdHRyKGNvbnRyb2wsICd0aXRsZScsIGVudHJ5LnRpdGxlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGVudHJ5LmNsYXNzTmFtZSkge1xuICAgICAgICBhZGRDbGFzc2VzKGNvbnRyb2wsIGVudHJ5LmNsYXNzTmFtZSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChlbnRyeS5pbWFnZVVybCkge1xuICAgICAgICBjb250cm9sLmFwcGVuZENoaWxkKGRvbWlmeSgnPGltZyBzcmM9XCInICsgZW50cnkuaW1hZ2VVcmwgKyAnXCI+JykpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgLy8gb3BlbiBhZnRlciB1cGRhdGVcbiAgdGhpcy5vcGVuKCk7XG59O1xuXG5cbi8qKlxuICogVHJpZ2dlciBhbiBhY3Rpb24gYXZhaWxhYmxlIG9uIHRoZSBwYWxldHRlXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBhY3Rpb25cbiAqIEBwYXJhbSAge0V2ZW50fSBldmVudFxuICovXG5QYWxldHRlLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oYWN0aW9uLCBldmVudCwgYXV0b0FjdGl2YXRlKSB7XG4gIHZhciBlbnRyaWVzID0gdGhpcy5fZW50cmllcyxcbiAgICAgIGVudHJ5LFxuICAgICAgaGFuZGxlcixcbiAgICAgIG9yaWdpbmFsRXZlbnQsXG4gICAgICBidXR0b24gPSBldmVudC5kZWxlZ2F0ZVRhcmdldCB8fCBldmVudC50YXJnZXQ7XG5cbiAgaWYgKCFidXR0b24pIHtcbiAgICByZXR1cm4gZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIGVudHJ5ID0gZW50cmllc1tkb21BdHRyKGJ1dHRvbiwgJ2RhdGEtYWN0aW9uJyldO1xuXG4gIC8vIHdoZW4gdXNlciBjbGlja3Mgb24gdGhlIHBhbGV0dGUgYW5kIG5vdCBvbiBhbiBhY3Rpb25cbiAgaWYgKCFlbnRyeSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGhhbmRsZXIgPSBlbnRyeS5hY3Rpb247XG5cbiAgb3JpZ2luYWxFdmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQgfHwgZXZlbnQ7XG5cbiAgLy8gc2ltcGxlIGFjdGlvbiAodmlhIGNhbGxiYWNrIGZ1bmN0aW9uKVxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIGlmIChhY3Rpb24gPT09ICdjbGljaycpIHtcbiAgICAgIGhhbmRsZXIob3JpZ2luYWxFdmVudCwgYXV0b0FjdGl2YXRlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGhhbmRsZXJbYWN0aW9uXSkge1xuICAgICAgaGFuZGxlclthY3Rpb25dKG9yaWdpbmFsRXZlbnQsIGF1dG9BY3RpdmF0ZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gc2lsZW5jZSBvdGhlciBhY3Rpb25zXG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG59O1xuXG5QYWxldHRlLnByb3RvdHlwZS5fbGF5b3V0Q2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl90b2dnbGVTdGF0ZSh7fSk7XG59O1xuXG4vKipcbiAqIERvIHdlIG5lZWQgdG8gY29sbGFwc2UgdG8gdHdvIGNvbHVtbnM/XG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGF2YWlsYWJsZUhlaWdodFxuICogQHBhcmFtIHtPYmplY3R9IGVudHJpZXNcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5QYWxldHRlLnByb3RvdHlwZS5fbmVlZHNDb2xsYXBzZSA9IGZ1bmN0aW9uKGF2YWlsYWJsZUhlaWdodCwgZW50cmllcykge1xuXG4gIC8vIHRvcCBtYXJnaW4gKyBib3R0b20gdG9nZ2xlICsgYm90dG9tIG1hcmdpblxuICAvLyBpbXBsZW1lbnRvcnMgbXVzdCBvdmVycmlkZSB0aGlzIG1ldGhvZCBpZiB0aGV5XG4gIC8vIGNoYW5nZSB0aGUgcGFsZXR0ZSBzdHlsZXNcbiAgdmFyIG1hcmdpbiA9IDIwICsgMTAgKyAyMDtcblxuICB2YXIgZW50cmllc0hlaWdodCA9IE9iamVjdC5rZXlzKGVudHJpZXMpLmxlbmd0aCAqIDQ2O1xuXG4gIHJldHVybiBhdmFpbGFibGVIZWlnaHQgPCBlbnRyaWVzSGVpZ2h0ICsgbWFyZ2luO1xufTtcblxuLyoqXG4gKiBDbG9zZSB0aGUgcGFsZXR0ZVxuICovXG5QYWxldHRlLnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuXG4gIHRoaXMuX3RvZ2dsZVN0YXRlKHtcbiAgICBvcGVuOiBmYWxzZSxcbiAgICB0d29Db2x1bW46IGZhbHNlXG4gIH0pO1xufTtcblxuXG4vKipcbiAqIE9wZW4gdGhlIHBhbGV0dGVcbiAqL1xuUGFsZXR0ZS5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl90b2dnbGVTdGF0ZSh7IG9wZW46IHRydWUgfSk7XG59O1xuXG5cblBhbGV0dGUucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uKG9wZW4pIHtcbiAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICB0aGlzLmNsb3NlKCk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy5vcGVuKCk7XG4gIH1cbn07XG5cblBhbGV0dGUucHJvdG90eXBlLmlzQWN0aXZlVG9vbCA9IGZ1bmN0aW9uKHRvb2wpIHtcbiAgcmV0dXJuIHRvb2wgJiYgdGhpcy5fYWN0aXZlVG9vbCA9PT0gdG9vbDtcbn07XG5cblBhbGV0dGUucHJvdG90eXBlLnVwZGF0ZVRvb2xIaWdobGlnaHQgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHZhciBlbnRyaWVzQ29udGFpbmVyLFxuICAgICAgdG9vbHNDb250YWluZXI7XG5cbiAgaWYgKCF0aGlzLl90b29sc0NvbnRhaW5lcikge1xuICAgIGVudHJpZXNDb250YWluZXIgPSBkb21RdWVyeSgnLmRqcy1wYWxldHRlLWVudHJpZXMnLCB0aGlzLl9jb250YWluZXIpO1xuXG4gICAgdGhpcy5fdG9vbHNDb250YWluZXIgPSBkb21RdWVyeSgnW2RhdGEtZ3JvdXA9dG9vbHNdJywgZW50cmllc0NvbnRhaW5lcik7XG4gIH1cblxuICB0b29sc0NvbnRhaW5lciA9IHRoaXMuX3Rvb2xzQ29udGFpbmVyO1xuXG4gIGZvckVhY2godG9vbHNDb250YWluZXIuY2hpbGRyZW4sIGZ1bmN0aW9uKHRvb2wpIHtcbiAgICB2YXIgYWN0aW9uTmFtZSA9IHRvb2wuZ2V0QXR0cmlidXRlKCdkYXRhLWFjdGlvbicpO1xuXG4gICAgaWYgKCFhY3Rpb25OYW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRvb2xDbGFzc2VzID0gZG9tQ2xhc3Nlcyh0b29sKTtcblxuICAgIGFjdGlvbk5hbWUgPSBhY3Rpb25OYW1lLnJlcGxhY2UoJy10b29sJywgJycpO1xuXG4gICAgaWYgKHRvb2xDbGFzc2VzLmNvbnRhaW5zKCdlbnRyeScpICYmIGFjdGlvbk5hbWUgPT09IG5hbWUpIHtcbiAgICAgIHRvb2xDbGFzc2VzLmFkZCgnaGlnaGxpZ2h0ZWQtZW50cnknKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdG9vbENsYXNzZXMucmVtb3ZlKCdoaWdobGlnaHRlZC1lbnRyeScpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJuIHRydWUgaWYgdGhlIHBhbGV0dGUgaXMgb3BlbmVkLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogcGFsZXR0ZS5vcGVuKCk7XG4gKlxuICogaWYgKHBhbGV0dGUuaXNPcGVuKCkpIHtcbiAqICAgLy8geWVzLCB3ZSBhcmUgb3BlblxuICogfVxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgcGFsZXR0ZSBpcyBvcGVuZWRcbiAqL1xuUGFsZXR0ZS5wcm90b3R5cGUuaXNPcGVuID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBkb21DbGFzc2VzKHRoaXMuX2NvbnRhaW5lcikuaGFzKFBBTEVUVEVfT1BFTl9DTFMpO1xufTtcblxuLyoqXG4gKiBHZXQgY29udGFpbmVyIHRoZSBwYWxldHRlIGxpdmVzIGluLlxuICpcbiAqIEByZXR1cm4ge0VsZW1lbnR9XG4gKi9cblBhbGV0dGUucHJvdG90eXBlLl9nZXRQYXJlbnRDb250YWluZXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX2NhbnZhcy5nZXRDb250YWluZXIoKTtcbn07XG5cblxuLyogbWFya3VwIGRlZmluaXRpb24gKi9cblxuUGFsZXR0ZS5IVE1MX01BUktVUCA9XG4gICc8ZGl2IGNsYXNzPVwiZGpzLXBhbGV0dGVcIj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImRqcy1wYWxldHRlLWVudHJpZXNcIj48L2Rpdj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImRqcy1wYWxldHRlLXRvZ2dsZVwiPjwvZGl2PicgK1xuICAnPC9kaXY+JztcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gYWRkQ2xhc3NlcyhlbGVtZW50LCBjbGFzc05hbWVzKSB7XG5cbiAgdmFyIGNsYXNzZXMgPSBkb21DbGFzc2VzKGVsZW1lbnQpO1xuXG4gIHZhciBhY3R1YWxDbGFzc05hbWVzID0gaXNBcnJheShjbGFzc05hbWVzKSA/IGNsYXNzTmFtZXMgOiBjbGFzc05hbWVzLnNwbGl0KC9cXHMrL2cpO1xuICBhY3R1YWxDbGFzc05hbWVzLmZvckVhY2goZnVuY3Rpb24oY2xzKSB7XG4gICAgY2xhc3Nlcy5hZGQoY2xzKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGFkZFBhbGV0dGVFbnRyaWVzKGVudHJpZXMsIHByb3ZpZGVyKSB7XG5cbiAgdmFyIGVudHJpZXNPclVwZGF0ZXIgPSBwcm92aWRlci5nZXRQYWxldHRlRW50cmllcygpO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGVudHJpZXNPclVwZGF0ZXIpKSB7XG4gICAgcmV0dXJuIGVudHJpZXNPclVwZGF0ZXIoZW50cmllcyk7XG4gIH1cblxuICBmb3JFYWNoKGVudHJpZXNPclVwZGF0ZXIsIGZ1bmN0aW9uKGVudHJ5LCBpZCkge1xuICAgIGVudHJpZXNbaWRdID0gZW50cnk7XG4gIH0pO1xuXG4gIHJldHVybiBlbnRyaWVzO1xufSIsImltcG9ydCBQYWxldHRlIGZyb20gJy4vUGFsZXR0ZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsgJ3BhbGV0dGUnIF0sXG4gIHBhbGV0dGU6IFsgJ3R5cGUnLCBQYWxldHRlIF1cbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGZvckVhY2gsXG4gIGlzRnVuY3Rpb24sXG4gIGlzRGVmaW5lZCxcbiAgb21pdCxcbiAgc2l6ZVxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBkb21pZnkgYXMgZG9taWZ5LFxuICBjbGFzc2VzIGFzIGRvbUNsYXNzZXMsXG4gIGF0dHIgYXMgZG9tQXR0cixcbiAgcmVtb3ZlIGFzIGRvbVJlbW92ZVxufSBmcm9tICdtaW4tZG9tJztcblxudmFyIERBVEFfUkVGID0gJ2RhdGEtaWQnO1xuXG52YXIgQ0xPU0VfRVZFTlRTID0gW1xuICAnY29udGV4dFBhZC5jbG9zZScsXG4gICdjYW52YXMudmlld2JveC5jaGFuZ2luZycsXG4gICdjb21tYW5kU3RhY2suY2hhbmdlZCdcbl07XG5cbnZhciBERUZBVUxUX1BSSU9SSVRZID0gMTAwMDtcblxuXG4vKipcbiAqIEEgcG9wdXAgbWVudSB0aGF0IGNhbiBiZSB1c2VkIHRvIGRpc3BsYXkgYSBsaXN0IG9mIGFjdGlvbnMgYW55d2hlcmUgaW4gdGhlIGNhbnZhcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29uZmlnXG4gKiBAcGFyYW0ge2Jvb2xlYW58T2JqZWN0fSBbY29uZmlnLnNjYWxlPXsgbWluOiAxLjAsIG1heDogMS41IH1dXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmZpZy5zY2FsZS5taW5dXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmZpZy5zY2FsZS5tYXhdXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFBvcHVwTWVudShjb25maWcsIGV2ZW50QnVzLCBjYW52YXMpIHtcblxuICB2YXIgc2NhbGUgPSBpc0RlZmluZWQoY29uZmlnICYmIGNvbmZpZy5zY2FsZSkgPyBjb25maWcuc2NhbGUgOiB7XG4gICAgbWluOiAxLFxuICAgIG1heDogMS41XG4gIH07XG5cbiAgdGhpcy5fY29uZmlnID0ge1xuICAgIHNjYWxlOiBzY2FsZVxuICB9O1xuXG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fcHJvdmlkZXJzID0ge307XG4gIHRoaXMuX2N1cnJlbnQgPSB7fTtcbn1cblxuUG9wdXBNZW51LiRpbmplY3QgPSBbXG4gICdjb25maWcucG9wdXBNZW51JyxcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcydcbl07XG5cbi8qKlxuICogUmVnaXN0ZXJzIGEgcG9wdXAgbWVudSBwcm92aWRlclxuICpcbiAqIEBwYXJhbSAge3N0cmluZ30gaWRcbiAqIEBwYXJhbSB7bnVtYmVyfSBbcHJpb3JpdHk9MTAwMF1cbiAqIEBwYXJhbSAge09iamVjdH0gcHJvdmlkZXJcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcG9wdXBNZW51UHJvdmlkZXIgPSB7XG4gKiAgIGdldFBvcHVwTWVudUVudHJpZXM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAqICAgICByZXR1cm4ge1xuICogICAgICAgJ2VudHJ5LTEnOiB7XG4gKiAgICAgICAgIGxhYmVsOiAnTXkgRW50cnknLFxuICogICAgICAgICBhY3Rpb246IGZ1bmN0aW9uKCkgeyBhbGVydChcIkkgaGF2ZSBiZWVuIGNsaWNrZWQhXCIpOyB9XG4gKiAgICAgICB9XG4gKiAgICAgfVxuICogICB9XG4gKiB9O1xuICpcbiAqIHBvcHVwTWVudS5yZWdpc3RlclByb3ZpZGVyKCdteU1lbnVJRCcsIHBvcHVwTWVudVByb3ZpZGVyKTtcbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5yZWdpc3RlclByb3ZpZGVyID0gZnVuY3Rpb24oaWQsIHByaW9yaXR5LCBwcm92aWRlcikge1xuICBpZiAoIXByb3ZpZGVyKSB7XG4gICAgcHJvdmlkZXIgPSBwcmlvcml0eTtcbiAgICBwcmlvcml0eSA9IERFRkFVTFRfUFJJT1JJVFk7XG4gIH1cblxuICB0aGlzLl9ldmVudEJ1cy5vbigncG9wdXBNZW51LmdldFByb3ZpZGVycy4nICsgaWQsIHByaW9yaXR5LCBmdW5jdGlvbihldmVudCkge1xuICAgIGV2ZW50LnByb3ZpZGVycy5wdXNoKHByb3ZpZGVyKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIERldGVybWluZSBpZiB0aGUgcG9wdXAgbWVudSBoYXMgZW50cmllcy5cbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufSB0cnVlIGlmIGVtcHR5XG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHByb3ZpZGVySWQpIHtcbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdlbGVtZW50IHBhcmFtZXRlciBpcyBtaXNzaW5nJyk7XG4gIH1cblxuICBpZiAoIXByb3ZpZGVySWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb3ZpZGVySWQgcGFyYW1ldGVyIGlzIG1pc3NpbmcnKTtcbiAgfVxuXG4gIHZhciBwcm92aWRlcnMgPSB0aGlzLl9nZXRQcm92aWRlcnMocHJvdmlkZXJJZCk7XG5cbiAgaWYgKCFwcm92aWRlcnMpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHZhciBlbnRyaWVzID0gdGhpcy5fZ2V0RW50cmllcyhlbGVtZW50LCBwcm92aWRlcnMpLFxuICAgICAgaGVhZGVyRW50cmllcyA9IHRoaXMuX2dldEhlYWRlckVudHJpZXMoZWxlbWVudCwgcHJvdmlkZXJzKTtcblxuICB2YXIgaGFzRW50cmllcyA9IHNpemUoZW50cmllcykgPiAwLFxuICAgICAgaGFzSGVhZGVyRW50cmllcyA9IGhlYWRlckVudHJpZXMgJiYgc2l6ZShoZWFkZXJFbnRyaWVzKSA+IDA7XG5cbiAgcmV0dXJuICFoYXNFbnRyaWVzICYmICFoYXNIZWFkZXJFbnRyaWVzO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZSBlbnRyaWVzIGFuZCBvcGVuIHBvcHVwIG1lbnUgYXQgZ2l2ZW4gcG9zaXRpb25cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGVsZW1lbnRcbiAqIEBwYXJhbSAge3N0cmluZ30gaWQgcHJvdmlkZXIgaWRcbiAqIEBwYXJhbSAge09iamVjdH0gcG9zaXRpb25cbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHBvcHVwIG1lbnUgaW5zdGFuY2VcbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5vcGVuID0gZnVuY3Rpb24oZWxlbWVudCwgaWQsIHBvc2l0aW9uKSB7XG5cbiAgdmFyIHByb3ZpZGVycyA9IHRoaXMuX2dldFByb3ZpZGVycyhpZCk7XG5cbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdFbGVtZW50IGlzIG1pc3NpbmcnKTtcbiAgfVxuXG4gIGlmICghcHJvdmlkZXJzIHx8ICFwcm92aWRlcnMubGVuZ3RoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyByZWdpc3RlcmVkIHByb3ZpZGVycyBmb3I6ICcgKyBpZCk7XG4gIH1cblxuICBpZiAoIXBvc2l0aW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd0aGUgcG9zaXRpb24gYXJndW1lbnQgaXMgbWlzc2luZycpO1xuICB9XG5cbiAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICB0aGlzLmNsb3NlKCk7XG4gIH1cblxuICB0aGlzLl9lbWl0KCdvcGVuJyk7XG5cbiAgdmFyIGN1cnJlbnQgPSB0aGlzLl9jdXJyZW50ID0ge1xuICAgIGNsYXNzTmFtZTogaWQsXG4gICAgZWxlbWVudDogZWxlbWVudCxcbiAgICBwb3NpdGlvbjogcG9zaXRpb25cbiAgfTtcblxuICB2YXIgZW50cmllcyA9IHRoaXMuX2dldEVudHJpZXMoZWxlbWVudCwgcHJvdmlkZXJzKSxcbiAgICAgIGhlYWRlckVudHJpZXMgPSB0aGlzLl9nZXRIZWFkZXJFbnRyaWVzKGVsZW1lbnQsIHByb3ZpZGVycyk7XG5cbiAgY3VycmVudC5lbnRyaWVzID0gYXNzaWduKHt9LCBlbnRyaWVzLCBoZWFkZXJFbnRyaWVzKTtcblxuICBjdXJyZW50LmNvbnRhaW5lciA9IHRoaXMuX2NyZWF0ZUNvbnRhaW5lcigpO1xuXG4gIGlmIChzaXplKGhlYWRlckVudHJpZXMpKSB7XG4gICAgY3VycmVudC5jb250YWluZXIuYXBwZW5kQ2hpbGQoXG4gICAgICB0aGlzLl9jcmVhdGVFbnRyaWVzKGhlYWRlckVudHJpZXMsICdkanMtcG9wdXAtaGVhZGVyJylcbiAgICApO1xuICB9XG5cbiAgaWYgKHNpemUoZW50cmllcykpIHtcbiAgICBjdXJyZW50LmNvbnRhaW5lci5hcHBlbmRDaGlsZChcbiAgICAgIHRoaXMuX2NyZWF0ZUVudHJpZXMoZW50cmllcywgJ2Rqcy1wb3B1cC1ib2R5JylcbiAgICApO1xuICB9XG5cbiAgdmFyIGNhbnZhcyA9IHRoaXMuX2NhbnZhcyxcbiAgICAgIHBhcmVudCA9IGNhbnZhcy5nZXRDb250YWluZXIoKTtcblxuICB0aGlzLl9hdHRhY2hDb250YWluZXIoY3VycmVudC5jb250YWluZXIsIHBhcmVudCwgcG9zaXRpb24uY3Vyc29yKTtcbiAgdGhpcy5fYmluZEF1dG9DbG9zZSgpO1xufTtcblxuXG4vKipcbiAqIFJlbW92ZXMgdGhlIHBvcHVwIG1lbnUgYW5kIHVuYmluZHMgdGhlIGV2ZW50IGhhbmRsZXJzLlxuICovXG5Qb3B1cE1lbnUucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG5cbiAgaWYgKCF0aGlzLmlzT3BlbigpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fZW1pdCgnY2xvc2UnKTtcblxuICB0aGlzLl91bmJpbmRBdXRvQ2xvc2UoKTtcbiAgZG9tUmVtb3ZlKHRoaXMuX2N1cnJlbnQuY29udGFpbmVyKTtcbiAgdGhpcy5fY3VycmVudC5jb250YWluZXIgPSBudWxsO1xufTtcblxuXG4vKipcbiAqIERldGVybWluZSBpZiBhbiBvcGVuIHBvcHVwIG1lbnUgZXhpc3QuXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn0gdHJ1ZSBpZiBvcGVuXG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuaXNPcGVuID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAhIXRoaXMuX2N1cnJlbnQuY29udGFpbmVyO1xufTtcblxuXG4vKipcbiAqIFRyaWdnZXIgYW4gYWN0aW9uIGFzc29jaWF0ZWQgd2l0aCBhbiBlbnRyeS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gZXZlbnRcbiAqXG4gKiBAcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGFjdGlvbiBjYWxsYmFjaywgaWYgYW55XG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUudHJpZ2dlciA9IGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgLy8gc2lsZW5jZSBvdGhlciBhY3Rpb25zXG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgdmFyIGVsZW1lbnQgPSBldmVudC5kZWxlZ2F0ZVRhcmdldCB8fCBldmVudC50YXJnZXQsXG4gICAgICBlbnRyeUlkID0gZG9tQXR0cihlbGVtZW50LCBEQVRBX1JFRik7XG5cbiAgdmFyIGVudHJ5ID0gdGhpcy5fZ2V0RW50cnkoZW50cnlJZCk7XG5cbiAgaWYgKGVudHJ5LmFjdGlvbikge1xuICAgIHJldHVybiBlbnRyeS5hY3Rpb24uY2FsbChudWxsLCBldmVudCwgZW50cnkpO1xuICB9XG59O1xuXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9nZXRQcm92aWRlcnMgPSBmdW5jdGlvbihpZCkge1xuXG4gIHZhciBldmVudCA9IHRoaXMuX2V2ZW50QnVzLmNyZWF0ZUV2ZW50KHtcbiAgICB0eXBlOiAncG9wdXBNZW51LmdldFByb3ZpZGVycy4nICsgaWQsXG4gICAgcHJvdmlkZXJzOiBbXVxuICB9KTtcblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKGV2ZW50KTtcblxuICByZXR1cm4gZXZlbnQucHJvdmlkZXJzO1xufTtcblxuUG9wdXBNZW51LnByb3RvdHlwZS5fZ2V0RW50cmllcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIHByb3ZpZGVycykge1xuXG4gIHZhciBlbnRyaWVzID0ge307XG5cbiAgZm9yRWFjaChwcm92aWRlcnMsIGZ1bmN0aW9uKHByb3ZpZGVyKSB7XG5cbiAgICAvLyBoYW5kbGUgbGVnYWN5IG1ldGhvZFxuICAgIGlmICghcHJvdmlkZXIuZ2V0UG9wdXBNZW51RW50cmllcykge1xuICAgICAgZm9yRWFjaChwcm92aWRlci5nZXRFbnRyaWVzKGVsZW1lbnQpLCBmdW5jdGlvbihlbnRyeSkge1xuICAgICAgICB2YXIgaWQgPSBlbnRyeS5pZDtcblxuICAgICAgICBpZiAoIWlkKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdldmVyeSBlbnRyeSBtdXN0IGhhdmUgdGhlIGlkIHByb3BlcnR5IHNldCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgZW50cmllc1tpZF0gPSBvbWl0KGVudHJ5LCBbICdpZCcgXSk7XG4gICAgICB9KTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBlbnRyaWVzT3JVcGRhdGVyID0gcHJvdmlkZXIuZ2V0UG9wdXBNZW51RW50cmllcyhlbGVtZW50KTtcblxuICAgIGlmIChpc0Z1bmN0aW9uKGVudHJpZXNPclVwZGF0ZXIpKSB7XG4gICAgICBlbnRyaWVzID0gZW50cmllc09yVXBkYXRlcihlbnRyaWVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yRWFjaChlbnRyaWVzT3JVcGRhdGVyLCBmdW5jdGlvbihlbnRyeSwgaWQpIHtcbiAgICAgICAgZW50cmllc1tpZF0gPSBlbnRyeTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGVudHJpZXM7XG59O1xuXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9nZXRIZWFkZXJFbnRyaWVzID0gZnVuY3Rpb24oZWxlbWVudCwgcHJvdmlkZXJzKSB7XG5cbiAgdmFyIGVudHJpZXMgPSB7fTtcblxuICBmb3JFYWNoKHByb3ZpZGVycywgZnVuY3Rpb24ocHJvdmlkZXIpIHtcblxuICAgIC8vIGhhbmRsZSBsZWdhY3kgbWV0aG9kXG4gICAgaWYgKCFwcm92aWRlci5nZXRQb3B1cE1lbnVIZWFkZXJFbnRyaWVzKSB7XG4gICAgICBpZiAoIXByb3ZpZGVyLmdldEhlYWRlckVudHJpZXMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBmb3JFYWNoKHByb3ZpZGVyLmdldEhlYWRlckVudHJpZXMoZWxlbWVudCksIGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgICAgIHZhciBpZCA9IGVudHJ5LmlkO1xuXG4gICAgICAgIGlmICghaWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2V2ZXJ5IGVudHJ5IG11c3QgaGF2ZSB0aGUgaWQgcHJvcGVydHkgc2V0Jyk7XG4gICAgICAgIH1cblxuICAgICAgICBlbnRyaWVzW2lkXSA9IG9taXQoZW50cnksIFsgJ2lkJyBdKTtcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIGVudHJpZXNPclVwZGF0ZXIgPSBwcm92aWRlci5nZXRQb3B1cE1lbnVIZWFkZXJFbnRyaWVzKGVsZW1lbnQpO1xuXG4gICAgaWYgKGlzRnVuY3Rpb24oZW50cmllc09yVXBkYXRlcikpIHtcbiAgICAgIGVudHJpZXMgPSBlbnRyaWVzT3JVcGRhdGVyKGVudHJpZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmb3JFYWNoKGVudHJpZXNPclVwZGF0ZXIsIGZ1bmN0aW9uKGVudHJ5LCBpZCkge1xuICAgICAgICBlbnRyaWVzW2lkXSA9IGVudHJ5O1xuICAgICAgfSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gZW50cmllcztcblxuXG59O1xuXG4vKipcbiAqIEdldHMgYW4gZW50cnkgaW5zdGFuY2UgKGVpdGhlciBlbnRyeSBvciBoZWFkZXJFbnRyeSkgYnkgaWQuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBlbnRyeUlkXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBlbnRyeSBpbnN0YW5jZVxuICovXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9nZXRFbnRyeSA9IGZ1bmN0aW9uKGVudHJ5SWQpIHtcblxuICB2YXIgZW50cnkgPSB0aGlzLl9jdXJyZW50LmVudHJpZXNbZW50cnlJZF07XG5cbiAgaWYgKCFlbnRyeSkge1xuICAgIHRocm93IG5ldyBFcnJvcignZW50cnkgbm90IGZvdW5kJyk7XG4gIH1cblxuICByZXR1cm4gZW50cnk7XG59O1xuXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9lbWl0ID0gZnVuY3Rpb24oZXZlbnROYW1lKSB7XG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3BvcHVwTWVudS4nICsgZXZlbnROYW1lKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgcG9wdXAgbWVudSBjb250YWluZXIuXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBhIERPTSBjb250YWluZXJcbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5fY3JlYXRlQ29udGFpbmVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBjb250YWluZXIgPSBkb21pZnkoJzxkaXYgY2xhc3M9XCJkanMtcG9wdXBcIj4nKSxcbiAgICAgIHBvc2l0aW9uID0gdGhpcy5fY3VycmVudC5wb3NpdGlvbixcbiAgICAgIGNsYXNzTmFtZSA9IHRoaXMuX2N1cnJlbnQuY2xhc3NOYW1lO1xuXG4gIGFzc2lnbihjb250YWluZXIuc3R5bGUsIHtcbiAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICBsZWZ0OiBwb3NpdGlvbi54ICsgJ3B4JyxcbiAgICB0b3A6IHBvc2l0aW9uLnkgKyAncHgnLFxuICAgIHZpc2liaWxpdHk6ICdoaWRkZW4nXG4gIH0pO1xuXG4gIGRvbUNsYXNzZXMoY29udGFpbmVyKS5hZGQoY2xhc3NOYW1lKTtcblxuICByZXR1cm4gY29udGFpbmVyO1xufTtcblxuXG4vKipcbiAqIEF0dGFjaGVzIHRoZSBjb250YWluZXIgdG8gdGhlIERPTS5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY29udGFpbmVyXG4gKiBAcGFyYW0ge09iamVjdH0gcGFyZW50XG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuX2F0dGFjaENvbnRhaW5lciA9IGZ1bmN0aW9uKGNvbnRhaW5lciwgcGFyZW50LCBjdXJzb3IpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8vIEV2ZW50IGhhbmRsZXJcbiAgZG9tRGVsZWdhdGUuYmluZChjb250YWluZXIsICcuZW50cnknICwnY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuICAgIHNlbGYudHJpZ2dlcihldmVudCk7XG4gIH0pO1xuXG4gIHRoaXMuX3VwZGF0ZVNjYWxlKGNvbnRhaW5lcik7XG5cbiAgLy8gQXR0YWNoIHRvIERPTVxuICBwYXJlbnQuYXBwZW5kQ2hpbGQoY29udGFpbmVyKTtcblxuICBpZiAoY3Vyc29yKSB7XG4gICAgdGhpcy5fYXNzdXJlSXNJbmJvdW5kcyhjb250YWluZXIsIGN1cnNvcik7XG4gIH1cbn07XG5cblxuLyoqXG4gKiBVcGRhdGVzIHBvcHVwIHN0eWxlLnRyYW5zZm9ybSB3aXRoIHJlc3BlY3QgdG8gdGhlIGNvbmZpZyBhbmQgem9vbSBsZXZlbC5cbiAqXG4gKiBAbWV0aG9kIF91cGRhdGVTY2FsZVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250YWluZXJcbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5fdXBkYXRlU2NhbGUgPSBmdW5jdGlvbihjb250YWluZXIpIHtcbiAgdmFyIHpvb20gPSB0aGlzLl9jYW52YXMuem9vbSgpO1xuXG4gIHZhciBzY2FsZUNvbmZpZyA9IHRoaXMuX2NvbmZpZy5zY2FsZSxcbiAgICAgIG1pblNjYWxlLFxuICAgICAgbWF4U2NhbGUsXG4gICAgICBzY2FsZSA9IHpvb207XG5cbiAgaWYgKHNjYWxlQ29uZmlnICE9PSB0cnVlKSB7XG5cbiAgICBpZiAoc2NhbGVDb25maWcgPT09IGZhbHNlKSB7XG4gICAgICBtaW5TY2FsZSA9IDE7XG4gICAgICBtYXhTY2FsZSA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1pblNjYWxlID0gc2NhbGVDb25maWcubWluO1xuICAgICAgbWF4U2NhbGUgPSBzY2FsZUNvbmZpZy5tYXg7XG4gICAgfVxuXG4gICAgaWYgKGlzRGVmaW5lZChtaW5TY2FsZSkgJiYgem9vbSA8IG1pblNjYWxlKSB7XG4gICAgICBzY2FsZSA9IG1pblNjYWxlO1xuICAgIH1cblxuICAgIGlmIChpc0RlZmluZWQobWF4U2NhbGUpICYmIHpvb20gPiBtYXhTY2FsZSkge1xuICAgICAgc2NhbGUgPSBtYXhTY2FsZTtcbiAgICB9XG5cbiAgfVxuXG4gIHNldFRyYW5zZm9ybShjb250YWluZXIsICdzY2FsZSgnICsgc2NhbGUgKyAnKScpO1xufTtcblxuXG4vKipcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoZSBtZW51IGlzIGFsd2F5cyBmdWxseSBzaG93blxuICpcbiAqIEBtZXRob2QgZnVuY3Rpb25cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGNvbnRhaW5lclxuICogQHBhcmFtICB7UG9zaXRpb259IGN1cnNvciB7eCwgeX1cbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5fYXNzdXJlSXNJbmJvdW5kcyA9IGZ1bmN0aW9uKGNvbnRhaW5lciwgY3Vyc29yKSB7XG4gIHZhciBjYW52YXMgPSB0aGlzLl9jYW52YXMsXG4gICAgICBjbGllbnRSZWN0ID0gY2FudmFzLl9jb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgdmFyIGNvbnRhaW5lclggPSBjb250YWluZXIub2Zmc2V0TGVmdCxcbiAgICAgIGNvbnRhaW5lclkgPSBjb250YWluZXIub2Zmc2V0VG9wLFxuICAgICAgY29udGFpbmVyV2lkdGggPSBjb250YWluZXIuc2Nyb2xsV2lkdGgsXG4gICAgICBjb250YWluZXJIZWlnaHQgPSBjb250YWluZXIuc2Nyb2xsSGVpZ2h0LFxuICAgICAgb3ZlckF4aXMgPSB7fSxcbiAgICAgIGxlZnQsIHRvcDtcblxuICB2YXIgY3Vyc29yUG9zaXRpb24gPSB7XG4gICAgeDogY3Vyc29yLnggLSBjbGllbnRSZWN0LmxlZnQsXG4gICAgeTogY3Vyc29yLnkgLSBjbGllbnRSZWN0LnRvcFxuICB9O1xuXG4gIGlmIChjb250YWluZXJYICsgY29udGFpbmVyV2lkdGggPiBjbGllbnRSZWN0LndpZHRoKSB7XG4gICAgb3ZlckF4aXMueCA9IHRydWU7XG4gIH1cblxuICBpZiAoY29udGFpbmVyWSArIGNvbnRhaW5lckhlaWdodCA+IGNsaWVudFJlY3QuaGVpZ2h0KSB7XG4gICAgb3ZlckF4aXMueSA9IHRydWU7XG4gIH1cblxuICBpZiAob3ZlckF4aXMueCAmJiBvdmVyQXhpcy55KSB7XG4gICAgbGVmdCA9IGN1cnNvclBvc2l0aW9uLnggLSBjb250YWluZXJXaWR0aCArICdweCc7XG4gICAgdG9wID0gY3Vyc29yUG9zaXRpb24ueSAtIGNvbnRhaW5lckhlaWdodCArICdweCc7XG4gIH0gZWxzZSBpZiAob3ZlckF4aXMueCkge1xuICAgIGxlZnQgPSBjdXJzb3JQb3NpdGlvbi54IC0gY29udGFpbmVyV2lkdGggKyAncHgnO1xuICAgIHRvcCA9IGN1cnNvclBvc2l0aW9uLnkgKyAncHgnO1xuICB9IGVsc2UgaWYgKG92ZXJBeGlzLnkgJiYgY3Vyc29yUG9zaXRpb24ueSA8IGNvbnRhaW5lckhlaWdodCkge1xuICAgIGxlZnQgPSBjdXJzb3JQb3NpdGlvbi54ICsgJ3B4JztcbiAgICB0b3AgPSAxMCArICdweCc7XG4gIH0gZWxzZSBpZiAob3ZlckF4aXMueSkge1xuICAgIGxlZnQgPSBjdXJzb3JQb3NpdGlvbi54ICsgJ3B4JztcbiAgICB0b3AgPSBjdXJzb3JQb3NpdGlvbi55IC0gY29udGFpbmVySGVpZ2h0ICsgJ3B4JztcbiAgfVxuXG4gIGFzc2lnbihjb250YWluZXIuc3R5bGUsIHsgbGVmdDogbGVmdCwgdG9wOiB0b3AgfSwgeyB2aXNpYmlsaXR5OiAndmlzaWJsZScsICd6LWluZGV4JzogMTAwMCB9KTtcbn07XG5cblxuLyoqXG4gKiBDcmVhdGVzIGEgbGlzdCBvZiBlbnRyaWVzIGFuZCByZXR1cm5zIHRoZW0gYXMgYSBET00gY29udGFpbmVyLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gZW50cmllcyBhbiBhcnJheSBvZiBlbnRyeSBvYmplY3RzXG4gKiBAcGFyYW0ge3N0cmluZ30gY2xhc3NOYW1lIHRoZSBjbGFzcyBuYW1lIG9mIHRoZSBlbnRyeSBjb250YWluZXJcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IGEgRE9NIGNvbnRhaW5lclxuICovXG5Qb3B1cE1lbnUucHJvdG90eXBlLl9jcmVhdGVFbnRyaWVzID0gZnVuY3Rpb24oZW50cmllcywgY2xhc3NOYW1lKSB7XG5cbiAgdmFyIGVudHJpZXNDb250YWluZXIgPSBkb21pZnkoJzxkaXY+JyksXG4gICAgICBzZWxmID0gdGhpcztcblxuICBkb21DbGFzc2VzKGVudHJpZXNDb250YWluZXIpLmFkZChjbGFzc05hbWUpO1xuXG4gIGZvckVhY2goZW50cmllcywgZnVuY3Rpb24oZW50cnksIGlkKSB7XG4gICAgdmFyIGVudHJ5Q29udGFpbmVyID0gc2VsZi5fY3JlYXRlRW50cnkoZW50cnksIGlkKTtcbiAgICBlbnRyaWVzQ29udGFpbmVyLmFwcGVuZENoaWxkKGVudHJ5Q29udGFpbmVyKTtcbiAgfSk7XG5cbiAgcmV0dXJuIGVudHJpZXNDb250YWluZXI7XG59O1xuXG5cbi8qKlxuICogQ3JlYXRlcyBhIHNpbmdsZSBlbnRyeSBhbmQgcmV0dXJucyBpdCBhcyBhIERPTSBjb250YWluZXIuXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSBlbnRyeVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gYSBET00gY29udGFpbmVyXG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuX2NyZWF0ZUVudHJ5ID0gZnVuY3Rpb24oZW50cnksIGlkKSB7XG5cbiAgdmFyIGVudHJ5Q29udGFpbmVyID0gZG9taWZ5KCc8ZGl2PicpLFxuICAgICAgZW50cnlDbGFzc2VzID0gZG9tQ2xhc3NlcyhlbnRyeUNvbnRhaW5lcik7XG5cbiAgZW50cnlDbGFzc2VzLmFkZCgnZW50cnknKTtcblxuICBpZiAoZW50cnkuY2xhc3NOYW1lKSB7XG4gICAgZW50cnkuY2xhc3NOYW1lLnNwbGl0KCcgJykuZm9yRWFjaChmdW5jdGlvbihjbGFzc05hbWUpIHtcbiAgICAgIGVudHJ5Q2xhc3Nlcy5hZGQoY2xhc3NOYW1lKTtcbiAgICB9KTtcbiAgfVxuXG4gIGRvbUF0dHIoZW50cnlDb250YWluZXIsIERBVEFfUkVGLCBpZCk7XG5cbiAgaWYgKGVudHJ5LmxhYmVsKSB7XG4gICAgdmFyIGxhYmVsID0gZG9taWZ5KCc8c3Bhbj4nKTtcbiAgICBsYWJlbC50ZXh0Q29udGVudCA9IGVudHJ5LmxhYmVsO1xuICAgIGVudHJ5Q29udGFpbmVyLmFwcGVuZENoaWxkKGxhYmVsKTtcbiAgfVxuXG4gIGlmIChlbnRyeS5pbWFnZVVybCkge1xuICAgIGVudHJ5Q29udGFpbmVyLmFwcGVuZENoaWxkKGRvbWlmeSgnPGltZyBzcmM9XCInICsgZW50cnkuaW1hZ2VVcmwgKyAnXCIgLz4nKSk7XG4gIH1cblxuICBpZiAoZW50cnkuYWN0aXZlID09PSB0cnVlKSB7XG4gICAgZW50cnlDbGFzc2VzLmFkZCgnYWN0aXZlJyk7XG4gIH1cblxuICBpZiAoZW50cnkuZGlzYWJsZWQgPT09IHRydWUpIHtcbiAgICBlbnRyeUNsYXNzZXMuYWRkKCdkaXNhYmxlZCcpO1xuICB9XG5cbiAgaWYgKGVudHJ5LnRpdGxlKSB7XG4gICAgZW50cnlDb250YWluZXIudGl0bGUgPSBlbnRyeS50aXRsZTtcbiAgfVxuXG4gIHJldHVybiBlbnRyeUNvbnRhaW5lcjtcbn07XG5cblxuLyoqXG4gKiBTZXQgdXAgbGlzdGVuZXIgdG8gY2xvc2UgcG9wdXAgYXV0b21hdGljYWxseSBvbiBjZXJ0YWluIGV2ZW50cy5cbiAqL1xuUG9wdXBNZW51LnByb3RvdHlwZS5fYmluZEF1dG9DbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9ldmVudEJ1cy5vbmNlKENMT1NFX0VWRU5UUywgdGhpcy5jbG9zZSwgdGhpcyk7XG59O1xuXG5cbi8qKlxuICogUmVtb3ZlIHRoZSBhdXRvLWNsb3NpbmcgbGlzdGVuZXIuXG4gKi9cblBvcHVwTWVudS5wcm90b3R5cGUuX3VuYmluZEF1dG9DbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9ldmVudEJ1cy5vZmYoQ0xPU0VfRVZFTlRTLCB0aGlzLmNsb3NlLCB0aGlzKTtcbn07XG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIHNldFRyYW5zZm9ybShlbGVtZW50LCB0cmFuc2Zvcm0pIHtcbiAgZWxlbWVudC5zdHlsZVsndHJhbnNmb3JtLW9yaWdpbiddID0gJ3RvcCBsZWZ0JztcblxuICBbICcnLCAnLW1zLScsICctd2Via2l0LScgXS5mb3JFYWNoKGZ1bmN0aW9uKHByZWZpeCkge1xuICAgIGVsZW1lbnQuc3R5bGVbcHJlZml4ICsgJ3RyYW5zZm9ybSddID0gdHJhbnNmb3JtO1xuICB9KTtcbn0iLCJpbXBvcnQgUG9wdXBNZW51IGZyb20gJy4vUG9wdXBNZW51JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAncG9wdXBNZW51JyBdLFxuICBwb3B1cE1lbnU6IFsgJ3R5cGUnLCBQb3B1cE1lbnUgXVxufTtcbiIsImltcG9ydCB7XHJcbiAgZm9yRWFjaFxyXG59IGZyb20gJ21pbi1kYXNoJztcclxuXHJcbmltcG9ydCB7XHJcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcclxuICBhdHRyIGFzIHN2Z0F0dHIsXHJcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzLFxyXG4gIGNsb25lIGFzIHN2Z0Nsb25lLFxyXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXHJcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZVxyXG59IGZyb20gJ3Rpbnktc3ZnJztcclxuXHJcbmltcG9ydCB7IHF1ZXJ5IGFzIGRvbVF1ZXJ5IH0gZnJvbSAnbWluLWRvbSc7XHJcblxyXG5pbXBvcnQgeyBnZXRWaXN1YWwgfSBmcm9tICcuLi8uLi91dGlsL0dyYXBoaWNzVXRpbCc7XHJcblxyXG52YXIgTUFSS0VSX1RZUEVTID0gW1xyXG4gICdtYXJrZXItc3RhcnQnLFxyXG4gICdtYXJrZXItbWlkJyxcclxuICAnbWFya2VyLWVuZCdcclxuXTtcclxuXHJcbnZhciBOT0RFU19DQU5fSEFWRV9NQVJLRVIgPSBbXHJcbiAgJ2NpcmNsZScsXHJcbiAgJ2VsbGlwc2UnLFxyXG4gICdsaW5lJyxcclxuICAncGF0aCcsXHJcbiAgJ3BvbHlnb24nLFxyXG4gICdwb2x5bGluZScsXHJcbiAgJ3JlY3QnXHJcbl07XHJcblxyXG5cclxuLyoqXHJcbiAqIEFkZHMgc3VwcG9ydCBmb3IgcHJldmlld3Mgb2YgbW92aW5nL3Jlc2l6aW5nIGVsZW1lbnRzLlxyXG4gKi9cclxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUHJldmlld1N1cHBvcnQoZWxlbWVudFJlZ2lzdHJ5LCBldmVudEJ1cywgY2FudmFzLCBzdHlsZXMpIHtcclxuICB0aGlzLl9lbGVtZW50UmVnaXN0cnkgPSBlbGVtZW50UmVnaXN0cnk7XHJcbiAgdGhpcy5fY2FudmFzID0gY2FudmFzO1xyXG4gIHRoaXMuX3N0eWxlcyA9IHN0eWxlcztcclxuXHJcbiAgdGhpcy5fY2xvbmVkTWFya2VycyA9IHt9O1xyXG5cclxuICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdkcmFnLmNsZWFudXAnLCBmdW5jdGlvbigpIHtcclxuICAgIGZvckVhY2goc2VsZi5fY2xvbmVkTWFya2VycywgZnVuY3Rpb24oY2xvbmVkTWFya2VyKSB7XHJcbiAgICAgIHN2Z1JlbW92ZShjbG9uZWRNYXJrZXIpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgc2VsZi5fY2xvbmVkTWFya2VycyA9IHt9O1xyXG4gIH0pO1xyXG59XHJcblxyXG5QcmV2aWV3U3VwcG9ydC4kaW5qZWN0ID0gW1xyXG4gICdlbGVtZW50UmVnaXN0cnknLFxyXG4gICdldmVudEJ1cycsXHJcbiAgJ2NhbnZhcycsXHJcbiAgJ3N0eWxlcydcclxuXTtcclxuXHJcblxyXG4vKipcclxuICogUmV0dXJucyBncmFwaGljcyBvZiBhbiBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge1NWR0VsZW1lbnR9XHJcbiAqL1xyXG5QcmV2aWV3U3VwcG9ydC5wcm90b3R5cGUuZ2V0R2Z4ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLl9lbGVtZW50UmVnaXN0cnkuZ2V0R3JhcGhpY3MoZWxlbWVudCk7XHJcbn07XHJcblxyXG4vKipcclxuICogQWRkcyBhIG1vdmUgcHJldmlldyBvZiBhIGdpdmVuIHNoYXBlIHRvIGEgZ2l2ZW4gc3ZnIGdyb3VwLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ3JvdXBcclxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBbZ2Z4XVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtTVkdFbGVtZW50fSBkcmFnZ2VyXHJcbiAqL1xyXG5QcmV2aWV3U3VwcG9ydC5wcm90b3R5cGUuYWRkRHJhZ2dlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIGdyb3VwLCBnZngpIHtcclxuICBnZnggPSBnZnggfHwgdGhpcy5nZXRHZngoZWxlbWVudCk7XHJcblxyXG4gIHZhciBkcmFnZ2VyID0gc3ZnQ2xvbmUoZ2Z4KTtcclxuICB2YXIgYmJveCA9IGdmeC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuXHJcbiAgdGhpcy5fY2xvbmVNYXJrZXJzKGdldFZpc3VhbChkcmFnZ2VyKSk7XHJcblxyXG4gIHN2Z0F0dHIoZHJhZ2dlciwgdGhpcy5fc3R5bGVzLmNscygnZGpzLWRyYWdnZXInLCBbXSwge1xyXG4gICAgeDogYmJveC50b3AsXHJcbiAgICB5OiBiYm94LmxlZnRcclxuICB9KSk7XHJcblxyXG4gIHN2Z0FwcGVuZChncm91cCwgZHJhZ2dlcik7XHJcblxyXG4gIHJldHVybiBkcmFnZ2VyO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEFkZHMgYSByZXNpemUgcHJldmlldyBvZiBhIGdpdmVuIHNoYXBlIHRvIGEgZ2l2ZW4gc3ZnIGdyb3VwLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ3JvdXBcclxuICpcclxuICogQHJldHVybiB7U1ZHRWxlbWVudH0gZnJhbWVcclxuICovXHJcblByZXZpZXdTdXBwb3J0LnByb3RvdHlwZS5hZGRGcmFtZSA9IGZ1bmN0aW9uKHNoYXBlLCBncm91cCkge1xyXG5cclxuICB2YXIgZnJhbWUgPSBzdmdDcmVhdGUoJ3JlY3QnLCB7XHJcbiAgICBjbGFzczogJ2Rqcy1yZXNpemUtb3ZlcmxheScsXHJcbiAgICB3aWR0aDogIHNoYXBlLndpZHRoLFxyXG4gICAgaGVpZ2h0OiBzaGFwZS5oZWlnaHQsXHJcbiAgICB4OiBzaGFwZS54LFxyXG4gICAgeTogc2hhcGUueVxyXG4gIH0pO1xyXG5cclxuICBzdmdBcHBlbmQoZ3JvdXAsIGZyYW1lKTtcclxuXHJcbiAgcmV0dXJuIGZyYW1lO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIENsb25lIGFsbCBtYXJrZXJzIHJlZmVyZW5jZWQgYnkgYSBub2RlIGFuZCBpdHMgY2hpbGQgbm9kZXMuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ2Z4XHJcbiAqL1xyXG5QcmV2aWV3U3VwcG9ydC5wcm90b3R5cGUuX2Nsb25lTWFya2VycyA9IGZ1bmN0aW9uKGdmeCkge1xyXG4gIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgaWYgKGdmeC5jaGlsZE5vZGVzKSB7XHJcblxyXG4gICAgLy8gVE9ETzogdXNlIGZvckVhY2ggb25jZSB3ZSBkcm9wIFBoYW50b21KU1xyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBnZnguY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xyXG5cclxuICAgICAgLy8gcmVjdXJzaXZlbHkgY2xvbmUgbWFya2VycyBvZiBjaGlsZCBub2Rlc1xyXG4gICAgICBzZWxmLl9jbG9uZU1hcmtlcnMoZ2Z4LmNoaWxkTm9kZXNbIGkgXSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZiAoIWNhbkhhdmVNYXJrZXIoZ2Z4KSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgTUFSS0VSX1RZUEVTLmZvckVhY2goZnVuY3Rpb24obWFya2VyVHlwZSkge1xyXG4gICAgaWYgKHN2Z0F0dHIoZ2Z4LCBtYXJrZXJUeXBlKSkge1xyXG4gICAgICB2YXIgbWFya2VyID0gZ2V0TWFya2VyKGdmeCwgbWFya2VyVHlwZSwgc2VsZi5fY2FudmFzLmdldENvbnRhaW5lcigpKTtcclxuXHJcbiAgICAgIHNlbGYuX2Nsb25lTWFya2VyKGdmeCwgbWFya2VyLCBtYXJrZXJUeXBlKTtcclxuICAgIH1cclxuICB9KTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDbG9uZSBtYXJrZXIgcmVmZXJlbmNlZCBieSBhbiBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGdmeFxyXG4gKiBAcGFyYW0ge1NWR0VsZW1lbnR9IG1hcmtlclxyXG4gKiBAcGFyYW0ge3N0cmluZ30gbWFya2VyVHlwZVxyXG4gKi9cclxuUHJldmlld1N1cHBvcnQucHJvdG90eXBlLl9jbG9uZU1hcmtlciA9IGZ1bmN0aW9uKGdmeCwgbWFya2VyLCBtYXJrZXJUeXBlKSB7XHJcbiAgdmFyIG1hcmtlcklkID0gbWFya2VyLmlkO1xyXG5cclxuICB2YXIgY2xvbmVkTWFya2VyID0gdGhpcy5fY2xvbmVkTWFya2Vyc1sgbWFya2VySWQgXTtcclxuXHJcbiAgaWYgKCFjbG9uZWRNYXJrZXIpIHtcclxuICAgIGNsb25lZE1hcmtlciA9IHN2Z0Nsb25lKG1hcmtlcik7XHJcblxyXG4gICAgdmFyIGNsb25lZE1hcmtlcklkID0gbWFya2VySWQgKyAnLWNsb25lJztcclxuXHJcbiAgICBjbG9uZWRNYXJrZXIuaWQgPSBjbG9uZWRNYXJrZXJJZDtcclxuXHJcbiAgICBzdmdDbGFzc2VzKGNsb25lZE1hcmtlcilcclxuICAgICAgLmFkZCgnZGpzLWRyYWdnZXInKVxyXG4gICAgICAuYWRkKCdkanMtZHJhZ2dlci1tYXJrZXInKTtcclxuXHJcbiAgICB0aGlzLl9jbG9uZWRNYXJrZXJzWyBtYXJrZXJJZCBdID0gY2xvbmVkTWFya2VyO1xyXG5cclxuICAgIHZhciBkZWZzID0gZG9tUXVlcnkoJ2RlZnMnLCB0aGlzLl9jYW52YXMuX3N2Zyk7XHJcblxyXG4gICAgaWYgKCFkZWZzKSB7XHJcbiAgICAgIGRlZnMgPSBzdmdDcmVhdGUoJ2RlZnMnKTtcclxuXHJcbiAgICAgIHN2Z0FwcGVuZCh0aGlzLl9jYW52YXMuX3N2ZywgZGVmcyk7XHJcbiAgICB9XHJcblxyXG4gICAgc3ZnQXBwZW5kKGRlZnMsIGNsb25lZE1hcmtlcik7XHJcbiAgfVxyXG5cclxuICB2YXIgcmVmZXJlbmNlID0gaWRUb1JlZmVyZW5jZSh0aGlzLl9jbG9uZWRNYXJrZXJzWyBtYXJrZXJJZCBdLmlkKTtcclxuXHJcbiAgc3ZnQXR0cihnZngsIG1hcmtlclR5cGUsIHJlZmVyZW5jZSk7XHJcbn07XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbi8qKlxyXG4gKiBHZXQgbWFya2VyIG9mIGdpdmVuIHR5cGUgcmVmZXJlbmNlZCBieSBub2RlLlxyXG4gKlxyXG4gKiBAcGFyYW0ge05vZGV9IG5vZGVcclxuICogQHBhcmFtIHtzdHJpbmd9IG1hcmtlclR5cGVcclxuICogQHBhcmFtIHtOb2RlfSBbcGFyZW50Tm9kZV1cclxuICpcclxuICogQHBhcmFtIHtOb2RlfVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0TWFya2VyKG5vZGUsIG1hcmtlclR5cGUsIHBhcmVudE5vZGUpIHtcclxuICB2YXIgaWQgPSByZWZlcmVuY2VUb0lkKHN2Z0F0dHIobm9kZSwgbWFya2VyVHlwZSkpO1xyXG5cclxuICByZXR1cm4gZG9tUXVlcnkoJ21hcmtlciMnICsgaWQsIHBhcmVudE5vZGUgfHwgZG9jdW1lbnQpO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IElEIG9mIGZyYWdtZW50IHdpdGhpbiBjdXJyZW50IGRvY3VtZW50IGZyb20gaXRzIGZ1bmN0aW9uYWwgSVJJIHJlZmVyZW5jZS5cclxuICogUmVmZXJlbmNlcyBtYXkgdXNlIHNpbmdsZSBvciBkb3VibGUgcXVvdGVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gcmVmZXJlbmNlXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtzdHJpbmd9XHJcbiAqL1xyXG5mdW5jdGlvbiByZWZlcmVuY2VUb0lkKHJlZmVyZW5jZSkge1xyXG4gIHJldHVybiByZWZlcmVuY2UubWF0Y2goL3VybFxcKFsnXCJdPyMoW14nXCJdKilbJ1wiXT9cXCkvKVsxXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBmdW5jdGlvbmFsIElSSSByZWZlcmVuY2UgZm9yIGdpdmVuIElEIG9mIGZyYWdtZW50IHdpdGhpbiBjdXJyZW50IGRvY3VtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRcclxuICpcclxuICogQHJldHVybnMge3N0cmluZ31cclxuICovXHJcbmZ1bmN0aW9uIGlkVG9SZWZlcmVuY2UoaWQpIHtcclxuICByZXR1cm4gJ3VybCgjJyArIGlkICsgJyknO1xyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2sgd2V0aGVyIG5vZGUgdHlwZSBjYW4gaGF2ZSBtYXJrZXIgYXR0cmlidXRlcy5cclxuICpcclxuICogQHBhcmFtIHtOb2RlfSBub2RlXHJcbiAqXHJcbiAqIEByZXR1cm5zIHtib29sZWFufVxyXG4gKi9cclxuZnVuY3Rpb24gY2FuSGF2ZU1hcmtlcihub2RlKSB7XHJcbiAgcmV0dXJuIE5PREVTX0NBTl9IQVZFX01BUktFUi5pbmRleE9mKG5vZGUubm9kZU5hbWUpICE9PSAtMTtcclxufSIsImltcG9ydCBQcmV2aWV3U3VwcG9ydCBmcm9tICcuL1ByZXZpZXdTdXBwb3J0JztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAncHJldmlld1N1cHBvcnQnIF0sXG4gIHByZXZpZXdTdXBwb3J0OiBbICd0eXBlJywgUHJldmlld1N1cHBvcnQgXVxufTtcbiIsImltcG9ydCB7XG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbnZhciByb3VuZCA9IE1hdGgucm91bmQ7XG5cbi8qKlxuICogU2VydmljZSB0aGF0IGFsbG93IHJlcGxhY2luZyBvZiBlbGVtZW50cy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVwbGFjZShtb2RlbGluZykge1xuXG4gIHRoaXMuX21vZGVsaW5nID0gbW9kZWxpbmc7XG59XG5cblJlcGxhY2UuJGluamVjdCA9IFsgJ21vZGVsaW5nJyBdO1xuXG4vKipcbiAqIEBwYXJhbSB7RWxlbWVudH0gb2xkRWxlbWVudCAtIEVsZW1lbnQgdG8gYmUgcmVwbGFjZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSAgbmV3RWxlbWVudERhdGEgLSBDb250YWluaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBuZXcgZWxlbWVudCxcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgZXhhbXBsZSB0aGUgbmV3IGJvdW5kcyBhbmQgdHlwZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSAgb3B0aW9ucyAtIEN1c3RvbSBvcHRpb25zIHRoYXQgd2lsbCBiZSBhdHRhY2hlZCB0byB0aGUgY29udGV4dC4gSXQgY2FuIGJlIHVzZWQgdG8gaW5qZWN0IGRhdGFcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoYXQgaXMgbmVlZGVkIGluIHRoZSBjb21tYW5kIGNoYWluLiBGb3IgZXhhbXBsZSBpdCBjb3VsZCBiZSB1c2VkIGluXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICBldmVudGJ1cy5vbignY29tbWFuZFN0YWNrLnNoYXBlLnJlcGxhY2UucG9zdEV4ZWN1dGUnKSB0byBjaGFuZ2Ugc2hhcGUgYXR0cmlidXRlcyBhZnRlclxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2hhcGUgY3JlYXRpb24uXG4gKi9cblJlcGxhY2UucHJvdG90eXBlLnJlcGxhY2VFbGVtZW50ID0gZnVuY3Rpb24ob2xkRWxlbWVudCwgbmV3RWxlbWVudERhdGEsIG9wdGlvbnMpIHtcblxuICBpZiAob2xkRWxlbWVudC53YXlwb2ludHMpIHtcblxuICAgIC8vIFRPRE8obmlra3UpOiB3ZSBkbyBub3QgcmVwbGFjZSBjb25uZWN0aW9ucywgeWV0XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgbW9kZWxpbmcgPSB0aGlzLl9tb2RlbGluZztcblxuICB2YXIgd2lkdGggPSBuZXdFbGVtZW50RGF0YS53aWR0aCB8fCBvbGRFbGVtZW50LndpZHRoLFxuICAgICAgaGVpZ2h0ID0gbmV3RWxlbWVudERhdGEuaGVpZ2h0IHx8IG9sZEVsZW1lbnQuaGVpZ2h0LFxuICAgICAgeCA9IG5ld0VsZW1lbnREYXRhLnggfHwgb2xkRWxlbWVudC54LFxuICAgICAgeSA9IG5ld0VsZW1lbnREYXRhLnkgfHwgb2xkRWxlbWVudC55LFxuICAgICAgY2VudGVyWCA9IHJvdW5kKHggKyB3aWR0aCAvIDIpLFxuICAgICAgY2VudGVyWSA9IHJvdW5kKHkgKyBoZWlnaHQgLyAyKTtcblxuICAvLyBtb2RlbGluZyBBUEkgcmVxdWlyZXMgY2VudGVyIGNvb3JkaW5hdGVzLFxuICAvLyBhY2NvdW50IGZvciB0aGF0IHdoZW4gaGFuZGxpbmcgc2hhcGUgYm91bmRzXG5cbiAgcmV0dXJuIG1vZGVsaW5nLnJlcGxhY2VTaGFwZShcbiAgICBvbGRFbGVtZW50LFxuICAgIGFzc2lnbihcbiAgICAgIHt9LFxuICAgICAgbmV3RWxlbWVudERhdGEsXG4gICAgICB7XG4gICAgICAgIHg6IGNlbnRlclgsXG4gICAgICAgIHk6IGNlbnRlclksXG4gICAgICAgIHdpZHRoOiB3aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBoZWlnaHRcbiAgICAgIH1cbiAgICApLFxuICAgIG9wdGlvbnNcbiAgKTtcbn07XG4iLCJpbXBvcnQgUmVwbGFjZSBmcm9tICcuL1JlcGxhY2UnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdyZXBsYWNlJyBdLFxuICByZXBsYWNlOiBbICd0eXBlJywgUmVwbGFjZSBdXG59OyIsImltcG9ydCB7XG4gIHBpY2ssXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIHJlc2l6ZUJvdW5kcyxcbiAgZW5zdXJlQ29uc3RyYWludHMsXG4gIGNvbXB1dGVDaGlsZHJlbkJCb3gsXG4gIGdldE1pblJlc2l6ZUJvdW5kc1xufSBmcm9tICcuL1Jlc2l6ZVV0aWwnO1xuXG5pbXBvcnQge1xuICBhc1RSQkwsXG4gIGdldE1pZCxcbiAgcm91bmRCb3VuZHNcbn0gZnJvbSAnLi4vLi4vbGF5b3V0L0xheW91dFV0aWwnO1xuXG52YXIgREVGQVVMVF9NSU5fV0lEVEggPSAxMDtcblxuXG4vKipcbiAqIEEgY29tcG9uZW50IHRoYXQgcHJvdmlkZXMgcmVzaXppbmcgb2Ygc2hhcGVzIG9uIHRoZSBjYW52YXMuXG4gKlxuICogVGhlIGZvbGxvd2luZyBjb21wb25lbnRzIGFyZSBwYXJ0IG9mIHNoYXBlIHJlc2l6ZTpcbiAqXG4gKiAgKiBhZGRpbmcgcmVzaXplIGhhbmRsZXMsXG4gKiAgKiBjcmVhdGluZyBhIHZpc3VhbCBkdXJpbmcgcmVzaXplXG4gKiAgKiBjaGVja2luZyByZXNpemUgcnVsZXNcbiAqICAqIGNvbW1pdHRpbmcgYSBjaGFuZ2Ugb25jZSBmaW5pc2hlZFxuICpcbiAqXG4gKiAjIyBDdXN0b21pemluZ1xuICpcbiAqIEl0J3MgcG9zc2libGUgdG8gY3VzdG9taXplIHRoZSByZXNpemluZyBiZWhhdmlvdXIgYnkgaW50ZXJjZXB0aW5nICdyZXNpemUuc3RhcnQnXG4gKiBhbmQgcHJvdmlkaW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVycyB0aHJvdWdoIHRoZSAnY29udGV4dCc6XG4gKlxuICogICAqIG1pbkRpbWVuc2lvbnMgKHsgd2lkdGgsIGhlaWdodCB9KTogbWluaW11bSBzaGFwZSBkaW1lbnNpb25zXG4gKlxuICogICAqIGNoaWxkcmVuQm94UGFkZGluZyAoeyBsZWZ0LCB0b3AsIGJvdHRvbSwgcmlnaHQgfSB8fCBudW1iZXIpOlxuICogICAgIGdhcCBiZXR3ZWVuIHRoZSBtaW5pbXVtIGJvdW5kaW5nIGJveCBhbmQgdGhlIGNvbnRhaW5lclxuICpcbiAqIGYuZXg6XG4gKlxuICogYGBgamF2YXNjcmlwdFxuICogZXZlbnRCdXMub24oJ3Jlc2l6ZS5zdGFydCcsIDE1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gKiAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAqXG4gKiAgY29udGV4dC5taW5EaW1lbnNpb25zID0geyB3aWR0aDogMTQwLCBoZWlnaHQ6IDEyMCB9O1xuICpcbiAqICAvLyBQYXNzaW5nIGdlbmVyYWwgcGFkZGluZ1xuICogIGNvbnRleHQuY2hpbGRyZW5Cb3hQYWRkaW5nID0gMzA7XG4gKlxuICogIC8vIFBhc3NpbmcgcGFkZGluZyB0byBhIHNwZWNpZmljIHNpZGVcbiAqICBjb250ZXh0LmNoaWxkcmVuQm94UGFkZGluZy5sZWZ0ID0gMjA7XG4gKiB9KTtcbiAqIGBgYFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSZXNpemUoZXZlbnRCdXMsIHJ1bGVzLCBtb2RlbGluZywgZHJhZ2dpbmcpIHtcblxuICB0aGlzLl9kcmFnZ2luZyA9IGRyYWdnaW5nO1xuICB0aGlzLl9ydWxlcyA9IHJ1bGVzO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuXG4gIC8qKlxuICAgKiBIYW5kbGUgcmVzaXplIG1vdmUgYnkgc3BlY2lmaWVkIGRlbHRhLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dFxuICAgKiBAcGFyYW0ge1BvaW50fSBkZWx0YVxuICAgKi9cbiAgZnVuY3Rpb24gaGFuZGxlTW92ZShjb250ZXh0LCBkZWx0YSkge1xuXG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXG4gICAgICAgIHJlc2l6ZUNvbnN0cmFpbnRzID0gY29udGV4dC5yZXNpemVDb25zdHJhaW50cyxcbiAgICAgICAgbmV3Qm91bmRzO1xuXG4gICAgY29udGV4dC5kZWx0YSA9IGRlbHRhO1xuXG4gICAgbmV3Qm91bmRzID0gcmVzaXplQm91bmRzKHNoYXBlLCBkaXJlY3Rpb24sIGRlbHRhKTtcblxuICAgIC8vIGVuc3VyZSBjb25zdHJhaW50cyBkdXJpbmcgcmVzaXplXG4gICAgY29udGV4dC5uZXdCb3VuZHMgPSBlbnN1cmVDb25zdHJhaW50cyhuZXdCb3VuZHMsIHJlc2l6ZUNvbnN0cmFpbnRzKTtcblxuICAgIC8vIHVwZGF0ZSArIGNhY2hlIGV4ZWN1dGFibGUgc3RhdGVcbiAgICBjb250ZXh0LmNhbkV4ZWN1dGUgPSBzZWxmLmNhblJlc2l6ZShjb250ZXh0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgcmVzaXplIHN0YXJ0LlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IGNvbnRleHRcbiAgICovXG4gIGZ1bmN0aW9uIGhhbmRsZVN0YXJ0KGNvbnRleHQpIHtcblxuICAgIHZhciByZXNpemVDb25zdHJhaW50cyA9IGNvbnRleHQucmVzaXplQ29uc3RyYWludHMsXG5cbiAgICAgICAgLy8gZXZhbHVhdGUgbWluQm91bmRzIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eVxuICAgICAgICBtaW5Cb3VuZHMgPSBjb250ZXh0Lm1pbkJvdW5kcztcblxuICAgIGlmIChyZXNpemVDb25zdHJhaW50cyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKG1pbkJvdW5kcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBtaW5Cb3VuZHMgPSBzZWxmLmNvbXB1dGVNaW5SZXNpemVCb3goY29udGV4dCk7XG4gICAgfVxuXG4gICAgY29udGV4dC5yZXNpemVDb25zdHJhaW50cyA9IHtcbiAgICAgIG1pbjogYXNUUkJMKG1pbkJvdW5kcylcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEhhbmRsZSByZXNpemUgZW5kLlxuICAgKlxuICAgKiBAcGFyYW0gIHtPYmplY3R9IGNvbnRleHRcbiAgICovXG4gIGZ1bmN0aW9uIGhhbmRsZUVuZChjb250ZXh0KSB7XG4gICAgdmFyIHNoYXBlID0gY29udGV4dC5zaGFwZSxcbiAgICAgICAgY2FuRXhlY3V0ZSA9IGNvbnRleHQuY2FuRXhlY3V0ZSxcbiAgICAgICAgbmV3Qm91bmRzID0gY29udGV4dC5uZXdCb3VuZHM7XG5cbiAgICBpZiAoY2FuRXhlY3V0ZSkge1xuXG4gICAgICAvLyBlbnN1cmUgd2UgaGF2ZSBhY3R1YWwgcGl4ZWwgdmFsdWVzIGZvciBuZXcgYm91bmRzXG4gICAgICAvLyAoaW1wb3J0YW50IHdoZW4gem9vbSBsZXZlbCB3YXMgPiAxIGR1cmluZyBtb3ZlKVxuICAgICAgbmV3Qm91bmRzID0gcm91bmRCb3VuZHMobmV3Qm91bmRzKTtcblxuICAgICAgaWYgKCFib3VuZHNDaGFuZ2VkKHNoYXBlLCBuZXdCb3VuZHMpKSB7XG5cbiAgICAgICAgLy8gbm8gcmVzaXplIG5lY2Vzc2FyeVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIHBlcmZvcm0gdGhlIGFjdHVhbCByZXNpemVcbiAgICAgIG1vZGVsaW5nLnJlc2l6ZVNoYXBlKHNoYXBlLCBuZXdCb3VuZHMpO1xuICAgIH1cbiAgfVxuXG5cbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5zdGFydCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaGFuZGxlU3RhcnQoZXZlbnQuY29udGV4dCk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdyZXNpemUubW92ZScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGRlbHRhID0ge1xuICAgICAgeDogZXZlbnQuZHgsXG4gICAgICB5OiBldmVudC5keVxuICAgIH07XG5cbiAgICBoYW5kbGVNb3ZlKGV2ZW50LmNvbnRleHQsIGRlbHRhKTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIGhhbmRsZUVuZChldmVudC5jb250ZXh0KTtcbiAgfSk7XG5cbn1cblxuXG5SZXNpemUucHJvdG90eXBlLmNhblJlc2l6ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgdmFyIHJ1bGVzID0gdGhpcy5fcnVsZXM7XG5cbiAgdmFyIGN0eCA9IHBpY2soY29udGV4dCwgWyAnbmV3Qm91bmRzJywgJ3NoYXBlJywgJ2RlbHRhJywgJ2RpcmVjdGlvbicgXSk7XG5cbiAgcmV0dXJuIHJ1bGVzLmFsbG93ZWQoJ3NoYXBlLnJlc2l6ZScsIGN0eCk7XG59O1xuXG4vKipcbiAqIEFjdGl2YXRlIGEgcmVzaXplIG9wZXJhdGlvbi5cbiAqXG4gKiBZb3UgbWF5IHNwZWNpZnkgYWRkaXRpb25hbCBjb250ZXh0dWFsIGluZm9ybWF0aW9uIGFuZCBtdXN0IHNwZWNpZnkgYVxuICogcmVzaXplIGRpcmVjdGlvbiBkdXJpbmcgYWN0aXZhdGlvbiBvZiB0aGUgcmVzaXplIGV2ZW50LlxuICpcbiAqIEBwYXJhbSB7TW91c2VFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBzaGFwZVxuICogQHBhcmFtIHtPYmplY3R8c3RyaW5nfSBjb250ZXh0T3JEaXJlY3Rpb25cbiAqL1xuUmVzaXplLnByb3RvdHlwZS5hY3RpdmF0ZSA9IGZ1bmN0aW9uKGV2ZW50LCBzaGFwZSwgY29udGV4dE9yRGlyZWN0aW9uKSB7XG4gIHZhciBkcmFnZ2luZyA9IHRoaXMuX2RyYWdnaW5nLFxuICAgICAgY29udGV4dCxcbiAgICAgIGRpcmVjdGlvbjtcblxuICBpZiAodHlwZW9mIGNvbnRleHRPckRpcmVjdGlvbiA9PT0gJ3N0cmluZycpIHtcbiAgICBjb250ZXh0T3JEaXJlY3Rpb24gPSB7XG4gICAgICBkaXJlY3Rpb246IGNvbnRleHRPckRpcmVjdGlvblxuICAgIH07XG4gIH1cblxuICBjb250ZXh0ID0gYXNzaWduKHsgc2hhcGU6IHNoYXBlIH0sIGNvbnRleHRPckRpcmVjdGlvbik7XG5cbiAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb247XG5cbiAgaWYgKCFkaXJlY3Rpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ211c3QgcHJvdmlkZSBhIGRpcmVjdGlvbiAobnx3fHN8ZXxud3xzZXxuZXxzdyknKTtcbiAgfVxuXG4gIGRyYWdnaW5nLmluaXQoZXZlbnQsIGdldFJlZmVyZW5jZVBvaW50KHNoYXBlLCBkaXJlY3Rpb24pLCAncmVzaXplJywge1xuICAgIGF1dG9BY3RpdmF0ZTogdHJ1ZSxcbiAgICBjdXJzb3I6IGdldEN1cnNvcihkaXJlY3Rpb24pLFxuICAgIGRhdGE6IHtcbiAgICAgIHNoYXBlOiBzaGFwZSxcbiAgICAgIGNvbnRleHQ6IGNvbnRleHRcbiAgICB9XG4gIH0pO1xufTtcblxuUmVzaXplLnByb3RvdHlwZS5jb21wdXRlTWluUmVzaXplQm94ID0gZnVuY3Rpb24oY29udGV4dCkge1xuICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXG4gICAgICBtaW5EaW1lbnNpb25zLFxuICAgICAgY2hpbGRyZW5Cb3VuZHM7XG5cbiAgbWluRGltZW5zaW9ucyA9IGNvbnRleHQubWluRGltZW5zaW9ucyB8fCB7XG4gICAgd2lkdGg6IERFRkFVTFRfTUlOX1dJRFRILFxuICAgIGhlaWdodDogREVGQVVMVF9NSU5fV0lEVEhcbiAgfTtcblxuICAvLyBnZXQgY2hpbGRyZW4gYm91bmRzXG4gIGNoaWxkcmVuQm91bmRzID0gY29tcHV0ZUNoaWxkcmVuQkJveChzaGFwZSwgY29udGV4dC5jaGlsZHJlbkJveFBhZGRpbmcpO1xuXG4gIC8vIGdldCBjb3JyZWN0IG1pbmltdW0gYm91bmRzIGZyb20gZ2l2ZW4gcmVzaXplIGRpcmVjdGlvblxuICAvLyBiYXNpY2FsbHkgZW5zdXJlcyB0aGF0IHRoZSBtaW5Cb3VuZHMgaXMgbWF4KGNoaWxkcmVuQm91bmRzLCBtaW5EaW1lbnNpb25zKVxuICByZXR1cm4gZ2V0TWluUmVzaXplQm91bmRzKGRpcmVjdGlvbiwgc2hhcGUsIG1pbkRpbWVuc2lvbnMsIGNoaWxkcmVuQm91bmRzKTtcbn07XG5cblxuUmVzaXplLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdydWxlcycsXG4gICdtb2RlbGluZycsXG4gICdkcmFnZ2luZydcbl07XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBib3VuZHNDaGFuZ2VkKHNoYXBlLCBuZXdCb3VuZHMpIHtcbiAgcmV0dXJuIHNoYXBlLnggIT09IG5ld0JvdW5kcy54IHx8XG4gICAgc2hhcGUueSAhPT0gbmV3Qm91bmRzLnkgfHxcbiAgICBzaGFwZS53aWR0aCAhPT0gbmV3Qm91bmRzLndpZHRoIHx8XG4gICAgc2hhcGUuaGVpZ2h0ICE9PSBuZXdCb3VuZHMuaGVpZ2h0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlUG9pbnQoc2hhcGUsIGRpcmVjdGlvbikge1xuICB2YXIgbWlkID0gZ2V0TWlkKHNoYXBlKSxcbiAgICAgIHRyYmwgPSBhc1RSQkwoc2hhcGUpO1xuXG4gIHZhciByZWZlcmVuY2VQb2ludCA9IHtcbiAgICB4OiBtaWQueCxcbiAgICB5OiBtaWQueVxuICB9O1xuXG4gIGlmIChkaXJlY3Rpb24uaW5kZXhPZignbicpICE9PSAtMSkge1xuICAgIHJlZmVyZW5jZVBvaW50LnkgPSB0cmJsLnRvcDtcbiAgfSBlbHNlIGlmIChkaXJlY3Rpb24uaW5kZXhPZigncycpICE9PSAtMSkge1xuICAgIHJlZmVyZW5jZVBvaW50LnkgPSB0cmJsLmJvdHRvbTtcbiAgfVxuXG4gIGlmIChkaXJlY3Rpb24uaW5kZXhPZignZScpICE9PSAtMSkge1xuICAgIHJlZmVyZW5jZVBvaW50LnggPSB0cmJsLnJpZ2h0O1xuICB9IGVsc2UgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCd3JykgIT09IC0xKSB7XG4gICAgcmVmZXJlbmNlUG9pbnQueCA9IHRyYmwubGVmdDtcbiAgfVxuXG4gIHJldHVybiByZWZlcmVuY2VQb2ludDtcbn1cblxuZnVuY3Rpb24gZ2V0Q3Vyc29yKGRpcmVjdGlvbikge1xuICB2YXIgcHJlZml4ID0gJ3Jlc2l6ZS0nO1xuXG4gIGlmIChkaXJlY3Rpb24gPT09ICduJyB8fCBkaXJlY3Rpb24gPT09ICdzJykge1xuICAgIHJldHVybiBwcmVmaXggKyAnbnMnO1xuICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ2UnIHx8IGRpcmVjdGlvbiA9PT0gJ3cnKSB7XG4gICAgcmV0dXJuIHByZWZpeCArICdldyc7XG4gIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAnbncnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgIHJldHVybiBwcmVmaXggKyAnbndzZSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHByZWZpeCArICduZXN3JztcbiAgfVxufSIsImltcG9ydCB7XG4gIGJpbmQsXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNsYXNzZXMgYXMgc3ZnQ2xhc3NlcyxcbiAgY2xlYXIgYXMgc3ZnQ2xlYXIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICBldmVudCBhcyBkb21FdmVudFxufSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IHtcbiAgaXNQcmltYXJ5QnV0dG9uXG59IGZyb20gJy4uLy4uL3V0aWwvTW91c2UnO1xuXG5pbXBvcnQge1xuICB0cmFuc2Zvcm1cbn0gZnJvbSAnLi4vLi4vdXRpbC9TdmdUcmFuc2Zvcm1VdGlsJztcblxuaW1wb3J0IHsgZ2V0UmVmZXJlbmNlUG9pbnQgfSBmcm9tICcuL1Jlc2l6ZSc7XG5cbnZhciBIQU5ETEVfT0ZGU0VUID0gLTYsXG4gICAgSEFORExFX1NJWkUgPSA0LFxuICAgIEhBTkRMRV9ISVRfU0laRSA9IDIwO1xuXG52YXIgQ0xTX1JFU0laRVIgPSAnZGpzLXJlc2l6ZXInO1xuXG52YXIgZGlyZWN0aW9ucyA9IFsgJ24nLCAndycsICdzJywgJ2UnLCAnbncnLCAnbmUnLCAnc2UnLCAnc3cnIF07XG5cblxuLyoqXG4gKiBUaGlzIGNvbXBvbmVudCBpcyByZXNwb25zaWJsZSBmb3IgYWRkaW5nIHJlc2l6ZSBoYW5kbGVzLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge1NlbGVjdGlvbn0gc2VsZWN0aW9uXG4gKiBAcGFyYW0ge1Jlc2l6ZX0gcmVzaXplXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlc2l6ZUhhbmRsZXMoZXZlbnRCdXMsIGNhbnZhcywgc2VsZWN0aW9uLCByZXNpemUpIHtcblxuICB0aGlzLl9yZXNpemUgPSByZXNpemU7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZXZlbnRCdXMub24oJ3NlbGVjdGlvbi5jaGFuZ2VkJywgZnVuY3Rpb24oZSkge1xuICAgIHZhciBuZXdTZWxlY3Rpb24gPSBlLm5ld1NlbGVjdGlvbjtcblxuICAgIC8vIHJlbW92ZSBvbGQgc2VsZWN0aW9uIG1hcmtlcnNcbiAgICBzZWxmLnJlbW92ZVJlc2l6ZXJzKCk7XG5cbiAgICAvLyBhZGQgbmV3IHNlbGVjdGlvbiBtYXJrZXJzIE9OTFkgaWYgc2luZ2xlIHNlbGVjdGlvblxuICAgIGlmIChuZXdTZWxlY3Rpb24ubGVuZ3RoID09PSAxKSB7XG4gICAgICBmb3JFYWNoKG5ld1NlbGVjdGlvbiwgYmluZChzZWxmLmFkZFJlc2l6ZXIsIHNlbGYpKTtcbiAgICB9XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdzaGFwZS5jaGFuZ2VkJywgZnVuY3Rpb24oZSkge1xuICAgIHZhciBzaGFwZSA9IGUuZWxlbWVudDtcblxuICAgIGlmIChzZWxlY3Rpb24uaXNTZWxlY3RlZChzaGFwZSkpIHtcbiAgICAgIHNlbGYucmVtb3ZlUmVzaXplcnMoKTtcblxuICAgICAgc2VsZi5hZGRSZXNpemVyKHNoYXBlKTtcbiAgICB9XG4gIH0pO1xufVxuXG5cblJlc2l6ZUhhbmRsZXMucHJvdG90eXBlLm1ha2VEcmFnZ2FibGUgPSBmdW5jdGlvbihlbGVtZW50LCBnZngsIGRpcmVjdGlvbikge1xuICB2YXIgcmVzaXplID0gdGhpcy5fcmVzaXplO1xuXG4gIGZ1bmN0aW9uIHN0YXJ0UmVzaXplKGV2ZW50KSB7XG5cbiAgICAvLyBvbmx5IHRyaWdnZXIgb24gbGVmdCBtb3VzZSBidXR0b25cbiAgICBpZiAoaXNQcmltYXJ5QnV0dG9uKGV2ZW50KSkge1xuICAgICAgcmVzaXplLmFjdGl2YXRlKGV2ZW50LCBlbGVtZW50LCBkaXJlY3Rpb24pO1xuICAgIH1cbiAgfVxuXG4gIGRvbUV2ZW50LmJpbmQoZ2Z4LCAnbW91c2Vkb3duJywgc3RhcnRSZXNpemUpO1xuICBkb21FdmVudC5iaW5kKGdmeCwgJ3RvdWNoc3RhcnQnLCBzdGFydFJlc2l6ZSk7XG59O1xuXG5cblJlc2l6ZUhhbmRsZXMucHJvdG90eXBlLl9jcmVhdGVSZXNpemVyID0gZnVuY3Rpb24oZWxlbWVudCwgeCwgeSwgZGlyZWN0aW9uKSB7XG4gIHZhciByZXNpemVyc1BhcmVudCA9IHRoaXMuX2dldFJlc2l6ZXJzUGFyZW50KCk7XG5cbiAgdmFyIG9mZnNldCA9IGdldEhhbmRsZU9mZnNldChkaXJlY3Rpb24pO1xuXG4gIHZhciBncm91cCA9IHN2Z0NyZWF0ZSgnZycpO1xuXG4gIHN2Z0NsYXNzZXMoZ3JvdXApLmFkZChDTFNfUkVTSVpFUik7XG4gIHN2Z0NsYXNzZXMoZ3JvdXApLmFkZChDTFNfUkVTSVpFUiArICctJyArIGVsZW1lbnQuaWQpO1xuICBzdmdDbGFzc2VzKGdyb3VwKS5hZGQoQ0xTX1JFU0laRVIgKyAnLScgKyBkaXJlY3Rpb24pO1xuXG4gIHN2Z0FwcGVuZChyZXNpemVyc1BhcmVudCwgZ3JvdXApO1xuXG4gIHZhciB2aXN1YWwgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcblxuICBzdmdBdHRyKHZpc3VhbCwge1xuICAgIHg6IC1IQU5ETEVfU0laRSAvIDIgKyBvZmZzZXQueCxcbiAgICB5OiAtSEFORExFX1NJWkUgLyAyICsgb2Zmc2V0LnksXG4gICAgd2lkdGg6IEhBTkRMRV9TSVpFLFxuICAgIGhlaWdodDogSEFORExFX1NJWkVcbiAgfSk7XG5cbiAgc3ZnQ2xhc3Nlcyh2aXN1YWwpLmFkZChDTFNfUkVTSVpFUiArICctdmlzdWFsJyk7XG5cbiAgc3ZnQXBwZW5kKGdyb3VwLCB2aXN1YWwpO1xuXG4gIHZhciBoaXQgPSBzdmdDcmVhdGUoJ3JlY3QnKTtcblxuICBzdmdBdHRyKGhpdCwge1xuICAgIHg6IC1IQU5ETEVfSElUX1NJWkUgLyAyICsgb2Zmc2V0LngsXG4gICAgeTogLUhBTkRMRV9ISVRfU0laRSAvIDIgKyBvZmZzZXQueSxcbiAgICB3aWR0aDogSEFORExFX0hJVF9TSVpFLFxuICAgIGhlaWdodDogSEFORExFX0hJVF9TSVpFXG4gIH0pO1xuXG4gIHN2Z0NsYXNzZXMoaGl0KS5hZGQoQ0xTX1JFU0laRVIgKyAnLWhpdCcpO1xuXG4gIHN2Z0FwcGVuZChncm91cCwgaGl0KTtcblxuICB0cmFuc2Zvcm0oZ3JvdXAsIHgsIHkpO1xuXG4gIHJldHVybiBncm91cDtcbn07XG5cblJlc2l6ZUhhbmRsZXMucHJvdG90eXBlLmNyZWF0ZVJlc2l6ZXIgPSBmdW5jdGlvbihlbGVtZW50LCBkaXJlY3Rpb24pIHtcbiAgdmFyIHBvaW50ID0gZ2V0UmVmZXJlbmNlUG9pbnQoZWxlbWVudCwgZGlyZWN0aW9uKTtcblxuICB2YXIgcmVzaXplciA9IHRoaXMuX2NyZWF0ZVJlc2l6ZXIoZWxlbWVudCwgcG9pbnQueCwgcG9pbnQueSwgZGlyZWN0aW9uKTtcblxuICB0aGlzLm1ha2VEcmFnZ2FibGUoZWxlbWVudCwgcmVzaXplciwgZGlyZWN0aW9uKTtcbn07XG5cbi8vIHJlc2l6ZSBoYW5kbGVzIGltcGxlbWVudGF0aW9uIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBBZGQgcmVzaXplcnMgZm9yIGEgZ2l2ZW4gZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gc2hhcGVcbiAqL1xuUmVzaXplSGFuZGxlcy5wcm90b3R5cGUuYWRkUmVzaXplciA9IGZ1bmN0aW9uKHNoYXBlKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICB2YXIgcmVzaXplID0gdGhpcy5fcmVzaXplO1xuXG4gIGlmICghcmVzaXplLmNhblJlc2l6ZSh7IHNoYXBlOiBzaGFwZSB9KSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGZvckVhY2goZGlyZWN0aW9ucywgZnVuY3Rpb24oZGlyZWN0aW9uKSB7XG4gICAgc2VsZi5jcmVhdGVSZXNpemVyKHNoYXBlLCBkaXJlY3Rpb24pO1xuICB9KTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFsbCByZXNpemVyc1xuICovXG5SZXNpemVIYW5kbGVzLnByb3RvdHlwZS5yZW1vdmVSZXNpemVycyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmVzaXplcnNQYXJlbnQgPSB0aGlzLl9nZXRSZXNpemVyc1BhcmVudCgpO1xuXG4gIHN2Z0NsZWFyKHJlc2l6ZXJzUGFyZW50KTtcbn07XG5cblJlc2l6ZUhhbmRsZXMucHJvdG90eXBlLl9nZXRSZXNpemVyc1BhcmVudCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fY2FudmFzLmdldExheWVyKCdyZXNpemVycycpO1xufTtcblxuUmVzaXplSGFuZGxlcy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3NlbGVjdGlvbicsXG4gICdyZXNpemUnXG5dO1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZ2V0SGFuZGxlT2Zmc2V0KGRpcmVjdGlvbikge1xuICB2YXIgb2Zmc2V0ID0ge1xuICAgIHg6IDAsXG4gICAgeTogMFxuICB9O1xuXG4gIGlmIChkaXJlY3Rpb24uaW5kZXhPZignZScpICE9PSAtMSkge1xuICAgIG9mZnNldC54ID0gLUhBTkRMRV9PRkZTRVQ7XG4gIH0gZWxzZSBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ3cnKSAhPT0gLTEpIHtcbiAgICBvZmZzZXQueCA9IEhBTkRMRV9PRkZTRVQ7XG4gIH1cblxuICBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ3MnKSAhPT0gLTEpIHtcbiAgICBvZmZzZXQueSA9IC1IQU5ETEVfT0ZGU0VUO1xuICB9IGVsc2UgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCduJykgIT09IC0xKSB7XG4gICAgb2Zmc2V0LnkgPSBIQU5ETEVfT0ZGU0VUO1xuICB9XG5cbiAgcmV0dXJuIG9mZnNldDtcbn0iLCJ2YXIgTUFSS0VSX1JFU0laSU5HID0gJ2Rqcy1yZXNpemluZycsXG4gICAgTUFSS0VSX1JFU0laRV9OT1RfT0sgPSAncmVzaXplLW5vdC1vayc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSA1MDA7XG5cbmltcG9ydCB7XG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgcmVtb3ZlIGFzIHN2Z1JlbW92ZSxcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzXG59IGZyb20gJ3Rpbnktc3ZnJztcblxuXG4vKipcbiAqIFByb3ZpZGVzIHByZXZpZXdzIGZvciByZXNpemluZyBzaGFwZXMgd2hlbiByZXNpemluZy5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICogQHBhcmFtIHtDYW52YXN9IGNhbnZhc1xuICogQHBhcmFtIHtQcmV2aWV3U3VwcG9ydH0gcHJldmlld1N1cHBvcnRcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gUmVzaXplUHJldmlldyhldmVudEJ1cywgY2FudmFzLCBwcmV2aWV3U3VwcG9ydCkge1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgcmVzaXplciBmcmFtZS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAgICovXG4gIGZ1bmN0aW9uIHVwZGF0ZUZyYW1lKGNvbnRleHQpIHtcblxuICAgIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXG4gICAgICAgIGJvdW5kcyA9IGNvbnRleHQubmV3Qm91bmRzLFxuICAgICAgICBmcmFtZSA9IGNvbnRleHQuZnJhbWU7XG5cbiAgICBpZiAoIWZyYW1lKSB7XG4gICAgICBmcmFtZSA9IGNvbnRleHQuZnJhbWUgPSBwcmV2aWV3U3VwcG9ydC5hZGRGcmFtZShzaGFwZSwgY2FudmFzLmdldERlZmF1bHRMYXllcigpKTtcblxuICAgICAgY2FudmFzLmFkZE1hcmtlcihzaGFwZSwgTUFSS0VSX1JFU0laSU5HKTtcbiAgICB9XG5cbiAgICBpZiAoYm91bmRzLndpZHRoID4gNSkge1xuICAgICAgc3ZnQXR0cihmcmFtZSwgeyB4OiBib3VuZHMueCwgd2lkdGg6IGJvdW5kcy53aWR0aCB9KTtcbiAgICB9XG5cbiAgICBpZiAoYm91bmRzLmhlaWdodCA+IDUpIHtcbiAgICAgIHN2Z0F0dHIoZnJhbWUsIHsgeTogYm91bmRzLnksIGhlaWdodDogYm91bmRzLmhlaWdodCB9KTtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dC5jYW5FeGVjdXRlKSB7XG4gICAgICBzdmdDbGFzc2VzKGZyYW1lKS5yZW1vdmUoTUFSS0VSX1JFU0laRV9OT1RfT0spO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdmdDbGFzc2VzKGZyYW1lKS5hZGQoTUFSS0VSX1JFU0laRV9OT1RfT0spO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgcmVzaXplciBmcmFtZS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAgICovXG4gIGZ1bmN0aW9uIHJlbW92ZUZyYW1lKGNvbnRleHQpIHtcbiAgICB2YXIgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxuICAgICAgICBmcmFtZSA9IGNvbnRleHQuZnJhbWU7XG5cbiAgICBpZiAoZnJhbWUpIHtcbiAgICAgIHN2Z1JlbW92ZShjb250ZXh0LmZyYW1lKTtcbiAgICB9XG5cbiAgICBjYW52YXMucmVtb3ZlTWFya2VyKHNoYXBlLCBNQVJLRVJfUkVTSVpJTkcpO1xuICB9XG5cbiAgLy8gYWRkIGFuZCB1cGRhdGUgcHJldmlld3NcbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5tb3ZlJywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuICAgIHVwZGF0ZUZyYW1lKGV2ZW50LmNvbnRleHQpO1xuICB9KTtcblxuICAvLyByZW1vdmUgcHJldmlld3NcbiAgZXZlbnRCdXMub24oJ3Jlc2l6ZS5jbGVhbnVwJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICByZW1vdmVGcmFtZShldmVudC5jb250ZXh0KTtcbiAgfSk7XG5cbn1cblxuUmVzaXplUHJldmlldy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3ByZXZpZXdTdXBwb3J0J1xuXTsiLCJpbXBvcnQge1xuICBmaWx0ZXIsXG4gIGlzTnVtYmVyXG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIG1heCA9IE1hdGgubWF4LFxuICAgIG1pbiA9IE1hdGgubWluO1xuXG52YXIgREVGQVVMVF9DSElMRF9CT1hfUEFERElORyA9IDIwO1xuXG5pbXBvcnQge1xuICBnZXRCQm94XG59IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG5pbXBvcnQge1xuICBhc1RSQkwsXG4gIGFzQm91bmRzXG59IGZyb20gJy4uLy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxuXG4vKipcbiAqIFN1YnN0cmFjdCBhIFRSQkwgZnJvbSBhbm90aGVyXG4gKlxuICogQHBhcmFtICB7VFJCTH0gdHJibEFcbiAqIEBwYXJhbSAge1RSQkx9IHRyYmxCXG4gKlxuICogQHJldHVybiB7VFJCTH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN1YnN0cmFjdFRSQkwodHJibEEsIHRyYmxCKSB7XG4gIHJldHVybiB7XG4gICAgdG9wOiB0cmJsQS50b3AgLSB0cmJsQi50b3AsXG4gICAgcmlnaHQ6IHRyYmxBLnJpZ2h0IC0gdHJibEIucmlnaHQsXG4gICAgYm90dG9tOiB0cmJsQS5ib3R0b20gLSB0cmJsQi5ib3R0b20sXG4gICAgbGVmdDogdHJibEEubGVmdCAtIHRyYmxCLmxlZnRcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNpemUgdGhlIGdpdmVuIGJvdW5kcyBieSB0aGUgc3BlY2lmaWVkIGRlbHRhIGZyb20gYSBnaXZlbiBhbmNob3IgcG9pbnQuXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IGJvdW5kcyB0aGUgYm91bmRpbmcgYm94IHRoYXQgc2hvdWxkIGJlIHJlc2l6ZWRcbiAqIEBwYXJhbSB7c3RyaW5nfSBkaXJlY3Rpb24gaW4gd2hpY2ggdGhlIGVsZW1lbnQgaXMgcmVzaXplZCAobncsIG5lLCBzZSwgc3cpXG4gKiBAcGFyYW0ge1BvaW50fSBkZWx0YSBvZiB0aGUgcmVzaXplIG9wZXJhdGlvblxuICpcbiAqIEByZXR1cm4ge0JvdW5kc30gcmVzaXplZCBib3VuZGluZyBib3hcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc2l6ZUJvdW5kcyhib3VuZHMsIGRpcmVjdGlvbiwgZGVsdGEpIHtcbiAgdmFyIGR4ID0gZGVsdGEueCxcbiAgICAgIGR5ID0gZGVsdGEueTtcblxuICB2YXIgbmV3Qm91bmRzID0ge1xuICAgIHg6IGJvdW5kcy54LFxuICAgIHk6IGJvdW5kcy55LFxuICAgIHdpZHRoOiBib3VuZHMud2lkdGgsXG4gICAgaGVpZ2h0OiBib3VuZHMuaGVpZ2h0XG4gIH07XG5cbiAgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCduJykgIT09IC0xKSB7XG4gICAgbmV3Qm91bmRzLnkgPSBib3VuZHMueSArIGR5O1xuICAgIG5ld0JvdW5kcy5oZWlnaHQgPSBib3VuZHMuaGVpZ2h0IC0gZHk7XG4gIH0gZWxzZSBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ3MnKSAhPT0gLTEpIHtcbiAgICBuZXdCb3VuZHMuaGVpZ2h0ID0gYm91bmRzLmhlaWdodCArIGR5O1xuICB9XG5cbiAgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCdlJykgIT09IC0xKSB7XG4gICAgbmV3Qm91bmRzLndpZHRoID0gYm91bmRzLndpZHRoICsgZHg7XG4gIH0gZWxzZSBpZiAoZGlyZWN0aW9uLmluZGV4T2YoJ3cnKSAhPT0gLTEpIHtcbiAgICBuZXdCb3VuZHMueCA9IGJvdW5kcy54ICsgZHg7XG4gICAgbmV3Qm91bmRzLndpZHRoID0gYm91bmRzLndpZHRoIC0gZHg7XG4gIH1cblxuICByZXR1cm4gbmV3Qm91bmRzO1xufVxuXG5cbi8qKlxuICogUmVzaXplIHRoZSBnaXZlbiBib3VuZHMgYnkgYXBwbHlpbmcgdGhlIHBhc3NlZFxuICogeyB0b3AsIHJpZ2h0LCBib3R0b20sIGxlZnQgfSBkZWx0YS5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc30gYm91bmRzXG4gKiBAcGFyYW0ge1RSQkx9IHRyYmxSZXNpemVcbiAqXG4gKiBAcmV0dXJuIHtCb3VuZHN9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNpemVUUkJMKGJvdW5kcywgcmVzaXplKSB7XG4gIHJldHVybiB7XG4gICAgeDogYm91bmRzLnggKyAocmVzaXplLmxlZnQgfHwgMCksXG4gICAgeTogYm91bmRzLnkgKyAocmVzaXplLnRvcCB8fCAwKSxcbiAgICB3aWR0aDogYm91bmRzLndpZHRoIC0gKHJlc2l6ZS5sZWZ0IHx8IDApICsgKHJlc2l6ZS5yaWdodCB8fCAwKSxcbiAgICBoZWlnaHQ6IGJvdW5kcy5oZWlnaHQgLSAocmVzaXplLnRvcCB8fCAwKSArIChyZXNpemUuYm90dG9tIHx8IDApXG4gIH07XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHJlYXR0YWNoUG9pbnQoYm91bmRzLCBuZXdCb3VuZHMsIHBvaW50KSB7XG5cbiAgdmFyIHN4ID0gYm91bmRzLndpZHRoIC8gbmV3Qm91bmRzLndpZHRoLFxuICAgICAgc3kgPSBib3VuZHMuaGVpZ2h0IC8gbmV3Qm91bmRzLmhlaWdodDtcblxuICByZXR1cm4ge1xuICAgIHg6IE1hdGgucm91bmQoKG5ld0JvdW5kcy54ICsgbmV3Qm91bmRzLndpZHRoIC8gMikpIC0gTWF0aC5mbG9vcigoKGJvdW5kcy54ICsgYm91bmRzLndpZHRoIC8gMikgLSBwb2ludC54KSAvIHN4KSxcbiAgICB5OiBNYXRoLnJvdW5kKChuZXdCb3VuZHMueSArIG5ld0JvdW5kcy5oZWlnaHQgLyAyKSkgLSBNYXRoLmZsb29yKCgoYm91bmRzLnkgKyBib3VuZHMuaGVpZ2h0IC8gMikgLSBwb2ludC55KSAvIHN5KVxuICB9O1xufVxuXG5cbmZ1bmN0aW9uIGFwcGx5Q29uc3RyYWludHMoYXR0ciwgdHJibCwgcmVzaXplQ29uc3RyYWludHMpIHtcblxuICB2YXIgdmFsdWUgPSB0cmJsW2F0dHJdLFxuICAgICAgbWluVmFsdWUgPSByZXNpemVDb25zdHJhaW50cy5taW4gJiYgcmVzaXplQ29uc3RyYWludHMubWluW2F0dHJdLFxuICAgICAgbWF4VmFsdWUgPSByZXNpemVDb25zdHJhaW50cy5tYXggJiYgcmVzaXplQ29uc3RyYWludHMubWF4W2F0dHJdO1xuXG4gIGlmIChpc051bWJlcihtaW5WYWx1ZSkpIHtcbiAgICB2YWx1ZSA9ICgvdG9wfGxlZnQvLnRlc3QoYXR0cikgPyBtaW4gOiBtYXgpKHZhbHVlLCBtaW5WYWx1ZSk7XG4gIH1cblxuICBpZiAoaXNOdW1iZXIobWF4VmFsdWUpKSB7XG4gICAgdmFsdWUgPSAoL3RvcHxsZWZ0Ly50ZXN0KGF0dHIpID8gbWF4IDogbWluKSh2YWx1ZSwgbWF4VmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gZW5zdXJlQ29uc3RyYWludHMoY3VycmVudEJvdW5kcywgcmVzaXplQ29uc3RyYWludHMpIHtcblxuICBpZiAoIXJlc2l6ZUNvbnN0cmFpbnRzKSB7XG4gICAgcmV0dXJuIGN1cnJlbnRCb3VuZHM7XG4gIH1cblxuICB2YXIgY3VycmVudFRyYmwgPSBhc1RSQkwoY3VycmVudEJvdW5kcyk7XG5cbiAgcmV0dXJuIGFzQm91bmRzKHtcbiAgICB0b3A6IGFwcGx5Q29uc3RyYWludHMoJ3RvcCcsIGN1cnJlbnRUcmJsLCByZXNpemVDb25zdHJhaW50cyksXG4gICAgcmlnaHQ6IGFwcGx5Q29uc3RyYWludHMoJ3JpZ2h0JywgY3VycmVudFRyYmwsIHJlc2l6ZUNvbnN0cmFpbnRzKSxcbiAgICBib3R0b206IGFwcGx5Q29uc3RyYWludHMoJ2JvdHRvbScsIGN1cnJlbnRUcmJsLCByZXNpemVDb25zdHJhaW50cyksXG4gICAgbGVmdDogYXBwbHlDb25zdHJhaW50cygnbGVmdCcsIGN1cnJlbnRUcmJsLCByZXNpemVDb25zdHJhaW50cylcbiAgfSk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE1pblJlc2l6ZUJvdW5kcyhkaXJlY3Rpb24sIGN1cnJlbnRCb3VuZHMsIG1pbkRpbWVuc2lvbnMsIGNoaWxkcmVuQm91bmRzKSB7XG5cbiAgdmFyIGN1cnJlbnRCb3ggPSBhc1RSQkwoY3VycmVudEJvdW5kcyk7XG5cbiAgdmFyIG1pbkJveCA9IHtcbiAgICB0b3A6IC9uLy50ZXN0KGRpcmVjdGlvbikgPyBjdXJyZW50Qm94LmJvdHRvbSAtIG1pbkRpbWVuc2lvbnMuaGVpZ2h0IDogY3VycmVudEJveC50b3AsXG4gICAgbGVmdDogL3cvLnRlc3QoZGlyZWN0aW9uKSA/IGN1cnJlbnRCb3gucmlnaHQgLSBtaW5EaW1lbnNpb25zLndpZHRoIDogY3VycmVudEJveC5sZWZ0LFxuICAgIGJvdHRvbTogL3MvLnRlc3QoZGlyZWN0aW9uKSA/IGN1cnJlbnRCb3gudG9wICsgbWluRGltZW5zaW9ucy5oZWlnaHQgOiBjdXJyZW50Qm94LmJvdHRvbSxcbiAgICByaWdodDogL2UvLnRlc3QoZGlyZWN0aW9uKSA/IGN1cnJlbnRCb3gubGVmdCArIG1pbkRpbWVuc2lvbnMud2lkdGggOiBjdXJyZW50Qm94LnJpZ2h0XG4gIH07XG5cbiAgdmFyIGNoaWxkcmVuQm94ID0gY2hpbGRyZW5Cb3VuZHMgPyBhc1RSQkwoY2hpbGRyZW5Cb3VuZHMpIDogbWluQm94O1xuXG4gIHZhciBjb21iaW5lZEJveCA9IHtcbiAgICB0b3A6IG1pbihtaW5Cb3gudG9wLCBjaGlsZHJlbkJveC50b3ApLFxuICAgIGxlZnQ6IG1pbihtaW5Cb3gubGVmdCwgY2hpbGRyZW5Cb3gubGVmdCksXG4gICAgYm90dG9tOiBtYXgobWluQm94LmJvdHRvbSwgY2hpbGRyZW5Cb3guYm90dG9tKSxcbiAgICByaWdodDogbWF4KG1pbkJveC5yaWdodCwgY2hpbGRyZW5Cb3gucmlnaHQpXG4gIH07XG5cbiAgcmV0dXJuIGFzQm91bmRzKGNvbWJpbmVkQm94KTtcbn1cblxuZnVuY3Rpb24gYXNQYWRkaW5nKG1heUJlUGFkZGluZywgZGVmYXVsdFZhbHVlKSB7XG4gIGlmICh0eXBlb2YgbWF5QmVQYWRkaW5nICE9PSAndW5kZWZpbmVkJykge1xuICAgIHJldHVybiBtYXlCZVBhZGRpbmc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIERFRkFVTFRfQ0hJTERfQk9YX1BBRERJTkc7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFkZFBhZGRpbmcoYmJveCwgcGFkZGluZykge1xuICB2YXIgbGVmdCwgcmlnaHQsIHRvcCwgYm90dG9tO1xuXG4gIGlmICh0eXBlb2YgcGFkZGluZyA9PT0gJ29iamVjdCcpIHtcbiAgICBsZWZ0ID0gYXNQYWRkaW5nKHBhZGRpbmcubGVmdCk7XG4gICAgcmlnaHQgPSBhc1BhZGRpbmcocGFkZGluZy5yaWdodCk7XG4gICAgdG9wID0gYXNQYWRkaW5nKHBhZGRpbmcudG9wKTtcbiAgICBib3R0b20gPSBhc1BhZGRpbmcocGFkZGluZy5ib3R0b20pO1xuICB9IGVsc2Uge1xuICAgIGxlZnQgPSByaWdodCA9IHRvcCA9IGJvdHRvbSA9IGFzUGFkZGluZyhwYWRkaW5nKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgeDogYmJveC54IC0gbGVmdCxcbiAgICB5OiBiYm94LnkgLSB0b3AsXG4gICAgd2lkdGg6IGJib3gud2lkdGggKyBsZWZ0ICsgcmlnaHQsXG4gICAgaGVpZ2h0OiBiYm94LmhlaWdodCArIHRvcCArIGJvdHRvbVxuICB9O1xufVxuXG5cbi8qKlxuICogSXMgdGhlIGdpdmVuIGVsZW1lbnQgcGFydCBvZiB0aGUgcmVzaXplXG4gKiB0YXJnZXRzIG1pbiBib3VuZGFyeSBib3g/XG4gKlxuICogVGhpcyBpcyB0aGUgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiB3aGljaCBleGNsdWRlc1xuICogY29ubmVjdGlvbnMgYW5kIGxhYmVscy5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGlzQkJveENoaWxkKGVsZW1lbnQpIHtcblxuICAvLyBleGNsdWRlIGNvbm5lY3Rpb25zXG4gIGlmIChlbGVtZW50LndheXBvaW50cykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIGV4Y2x1ZGUgbGFiZWxzXG4gIGlmIChlbGVtZW50LnR5cGUgPT09ICdsYWJlbCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gY2hpbGRyZW4gYm91bmRpbmcgY29tcHV0ZWQgZnJvbSBhIHNoYXBlcyBjaGlsZHJlblxuICogb3IgYSBsaXN0IG9mIHByZWZpbHRlcmVkIGNoaWxkcmVuLlxuICpcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5TaGFwZXxBcnJheTxkanMubW9kZWwuU2hhcGU+fSBzaGFwZU9yQ2hpbGRyZW5cbiAqIEBwYXJhbSAge251bWJlcnxPYmplY3R9IHBhZGRpbmdcbiAqXG4gKiBAcmV0dXJuIHtCb3VuZHN9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlQ2hpbGRyZW5CQm94KHNoYXBlT3JDaGlsZHJlbiwgcGFkZGluZykge1xuXG4gIHZhciBlbGVtZW50cztcblxuICAvLyBjb21wdXRlIGJhc2VkIG9uIHNoYXBlXG4gIGlmIChzaGFwZU9yQ2hpbGRyZW4ubGVuZ3RoID09PSB1bmRlZmluZWQpIHtcblxuICAgIC8vIGdyYWIgYWxsIHRoZSBjaGlsZHJlbiB0aGF0IGFyZSBwYXJ0IG9mIHRoZVxuICAgIC8vIHBhcmVudHMgY2hpbGRyZW4gYm94XG4gICAgZWxlbWVudHMgPSBmaWx0ZXIoc2hhcGVPckNoaWxkcmVuLmNoaWxkcmVuLCBpc0JCb3hDaGlsZCk7XG5cbiAgfSBlbHNlIHtcbiAgICBlbGVtZW50cyA9IHNoYXBlT3JDaGlsZHJlbjtcbiAgfVxuXG4gIGlmIChlbGVtZW50cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gYWRkUGFkZGluZyhnZXRCQm94KGVsZW1lbnRzKSwgcGFkZGluZyk7XG4gIH1cbn1cbiIsImltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgRHJhZ2dpbmdNb2R1bGUgZnJvbSAnLi4vZHJhZ2dpbmcnO1xuaW1wb3J0IFByZXZpZXdTdXBwb3J0TW9kdWxlIGZyb20gJy4uL3ByZXZpZXctc3VwcG9ydCc7XG5cbmltcG9ydCBSZXNpemUgZnJvbSAnLi9SZXNpemUnO1xuaW1wb3J0IFJlc2l6ZVByZXZpZXcgZnJvbSAnLi9SZXNpemVQcmV2aWV3JztcbmltcG9ydCBSZXNpemVIYW5kbGVzIGZyb20gJy4vUmVzaXplSGFuZGxlcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBSdWxlc01vZHVsZSxcbiAgICBEcmFnZ2luZ01vZHVsZSxcbiAgICBQcmV2aWV3U3VwcG9ydE1vZHVsZVxuICBdLFxuICBfX2luaXRfXzogW1xuICAgICdyZXNpemUnLFxuICAgICdyZXNpemVQcmV2aWV3JyxcbiAgICAncmVzaXplSGFuZGxlcydcbiAgXSxcbiAgcmVzaXplOiBbICd0eXBlJywgUmVzaXplIF0sXG4gIHJlc2l6ZVByZXZpZXc6IFsgJ3R5cGUnLCBSZXNpemVQcmV2aWV3IF0sXG4gIHJlc2l6ZUhhbmRsZXM6IFsgJ3R5cGUnLCBSZXNpemVIYW5kbGVzIF1cbn07XG4iLCJpbXBvcnQgaW5oZXJpdHMgZnJvbSAnaW5oZXJpdHMnO1xuXG5pbXBvcnQgQ29tbWFuZEludGVyY2VwdG9yIGZyb20gJy4uLy4uL2NvbW1hbmQvQ29tbWFuZEludGVyY2VwdG9yJztcblxuLyoqXG4gKiBBIGJhc2ljIHByb3ZpZGVyIHRoYXQgbWF5IGJlIGV4dGVuZGVkIHRvIGltcGxlbWVudCBtb2RlbGluZyBydWxlcy5cbiAqXG4gKiBFeHRlbnNpb25zIHNob3VsZCBpbXBsZW1lbnQgdGhlIGluaXQgbWV0aG9kIHRvIGFjdHVhbGx5IGFkZCB0aGVpciBjdXN0b21cbiAqIG1vZGVsaW5nIGNoZWNrcy4gQ2hlY2tzIG1heSBiZSBhZGRlZCB2aWEgdGhlICNhZGRSdWxlKGFjdGlvbiwgZm4pIG1ldGhvZC5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSdWxlUHJvdmlkZXIoZXZlbnRCdXMpIHtcbiAgQ29tbWFuZEludGVyY2VwdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xuXG4gIHRoaXMuaW5pdCgpO1xufVxuXG5SdWxlUHJvdmlkZXIuJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdO1xuXG5pbmhlcml0cyhSdWxlUHJvdmlkZXIsIENvbW1hbmRJbnRlcmNlcHRvcik7XG5cblxuLyoqXG4gKiBBZGRzIGEgbW9kZWxpbmcgcnVsZSBmb3IgdGhlIGdpdmVuIGFjdGlvbiwgaW1wbGVtZW50ZWQgdGhyb3VnaFxuICogYSBjYWxsYmFjayBmdW5jdGlvbi5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gd2lsbCByZWNlaXZlIHRoZSBtb2RlbGluZyBzcGVjaWZpYyBhY3Rpb24gY29udGV4dFxuICogdG8gcGVyZm9ybSBpdHMgY2hlY2suIEl0IG11c3QgcmV0dXJuIGBmYWxzZWAgdG8gZGlzYWxsb3cgdGhlXG4gKiBhY3Rpb24gZnJvbSBoYXBwZW5pbmcgb3IgYHRydWVgIHRvIGFsbG93IHRoZSBhY3Rpb24uXG4gKlxuICogQSBydWxlIHByb3ZpZGVyIG1heSBwYXNzIG92ZXIgdGhlIGV2YWx1YXRpb24gdG8gbG93ZXIgcHJpb3JpdHlcbiAqIHJ1bGVzIGJ5IHJldHVybmluZyByZXR1cm4gbm90aGluZyAob3IgPGNvZGU+dW5kZWZpbmVkPC9jb2RlPikuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBSZXNpemFibGVSdWxlcy5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge1xuICpcbiAqICAgXFwvKipcbiAqICAgICogUmV0dXJuIGB0cnVlYCwgYGZhbHNlYCBvciBub3RoaW5nIHRvIGRlbm90ZVxuICogICAgKiBfYWxsb3dlZF8sIF9ub3QgYWxsb3dlZF8gYW5kIF9jb250aW51ZSBldmFsdWF0aW5nXy5cbiAqICAgICpcXC9cbiAqICAgdGhpcy5hZGRSdWxlKCdzaGFwZS5yZXNpemUnLCBmdW5jdGlvbihjb250ZXh0KSB7XG4gKlxuICogICAgIHZhciBzaGFwZSA9IGNvbnRleHQuc2hhcGU7XG4gKlxuICogICAgIGlmICghY29udGV4dC5uZXdCb3VuZHMpIHtcbiAqICAgICAgIC8vIGNoZWNrIGdlbmVyYWwgcmVzaXphYmlsaXR5XG4gKiAgICAgICBpZiAoIXNoYXBlLnJlc2l6YWJsZSkge1xuICogICAgICAgICByZXR1cm4gZmFsc2U7XG4gKiAgICAgICB9XG4gKlxuICogICAgICAgLy8gbm90IHJldHVybmluZyBhbnl0aGluZyAocmVhZDogdW5kZWZpbmVkKVxuICogICAgICAgLy8gd2lsbCBjb250aW51ZSB0aGUgZXZhbHVhdGlvbiBvZiBvdGhlciBydWxlc1xuICogICAgICAgLy8gKHdpdGggbG93ZXIgcHJpb3JpdHkpXG4gKiAgICAgICByZXR1cm47XG4gKiAgICAgfSBlbHNlIHtcbiAqICAgICAgIC8vIGVsZW1lbnQgbXVzdCBoYXZlIG1pbmltdW0gc2l6ZSBvZiAxMCoxMCBwb2ludHNcbiAqICAgICAgIHJldHVybiBjb250ZXh0Lm5ld0JvdW5kcy53aWR0aCA+IDEwICYmIGNvbnRleHQubmV3Qm91bmRzLmhlaWdodCA+IDEwO1xuICogICAgIH1cbiAqICAgfSk7XG4gKiB9O1xuICpcbiAqIEBwYXJhbSB7c3RyaW5nfEFycmF5PHN0cmluZz59IGFjdGlvbnMgdGhlIGlkZW50aWZpZXIgZm9yIHRoZSBtb2RlbGluZyBhY3Rpb24gdG8gY2hlY2tcbiAqIEBwYXJhbSB7bnVtYmVyfSBbcHJpb3JpdHldIHRoZSBwcmlvcml0eSBhdCB3aGljaCB0aGlzIHJ1bGUgaXMgYmVpbmcgYXBwbGllZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gdGhlIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgcGVyZm9ybXMgdGhlIGFjdHVhbCBjaGVja1xuICovXG5SdWxlUHJvdmlkZXIucHJvdG90eXBlLmFkZFJ1bGUgPSBmdW5jdGlvbihhY3Rpb25zLCBwcmlvcml0eSwgZm4pIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgaWYgKHR5cGVvZiBhY3Rpb25zID09PSAnc3RyaW5nJykge1xuICAgIGFjdGlvbnMgPSBbIGFjdGlvbnMgXTtcbiAgfVxuXG4gIGFjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihhY3Rpb24pIHtcblxuICAgIHNlbGYuY2FuRXhlY3V0ZShhY3Rpb24sIHByaW9yaXR5LCBmdW5jdGlvbihjb250ZXh0LCBhY3Rpb24sIGV2ZW50KSB7XG4gICAgICByZXR1cm4gZm4oY29udGV4dCk7XG4gICAgfSwgdHJ1ZSk7XG4gIH0pO1xufTtcblxuLyoqXG4gKiBJbXBsZW1lbnQgdGhpcyBtZXRob2QgdG8gYWRkIG5ldyBydWxlcyBkdXJpbmcgcHJvdmlkZXIgaW5pdGlhbGl6YXRpb24uXG4gKi9cblJ1bGVQcm92aWRlci5wcm90b3R5cGUuaW5pdCA9IGZ1bmN0aW9uKCkge307IiwiLyoqXG4gKiBBIHNlcnZpY2UgdGhhdCBwcm92aWRlcyBydWxlcyBmb3IgY2VydGFpbiBkaWFncmFtIGFjdGlvbnMuXG4gKlxuICogVGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gd2lsbCBob29rIGludG8gdGhlIHtAbGluayBDb21tYW5kU3RhY2t9XG4gKiB0byBwZXJmb3JtIHRoZSBhY3R1YWwgcnVsZSBldmFsdWF0aW9uLiBNYWtlIHN1cmUgdG8gcHJvdmlkZSB0aGVcbiAqIGBjb21tYW5kU3RhY2tgIHNlcnZpY2Ugd2l0aCB0aGlzIG1vZHVsZSBpZiB5b3UgcGxhbiB0byB1c2UgaXQuXG4gKlxuICogVG9nZXRoZXIgd2l0aCB0aGlzIGltcGxlbWVudGF0aW9uIHlvdSBtYXkgdXNlIHRoZSB7QGxpbmsgUnVsZVByb3ZpZGVyfVxuICogdG8gaW1wbGVtZW50IHlvdXIgb3duIHJ1bGUgY2hlY2tlcnMuXG4gKlxuICogVGhpcyBtb2R1bGUgaXMgbWVudCB0byBiZSBlYXNpbHkgcmVwbGFjZWQsIHRodXMgdGhlIHRpbnkgZm9vdCBwcmludC5cbiAqXG4gKiBAcGFyYW0ge0luamVjdG9yfSBpbmplY3RvclxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBSdWxlcyhpbmplY3Rvcikge1xuICB0aGlzLl9jb21tYW5kU3RhY2sgPSBpbmplY3Rvci5nZXQoJ2NvbW1hbmRTdGFjaycsIGZhbHNlKTtcbn1cblxuUnVsZXMuJGluamVjdCA9IFsgJ2luamVjdG9yJyBdO1xuXG5cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCBhIGdpdmVuIG1vZGVsaW5nIGFjdGlvbiBjYW4gYmUgZXhlY3V0ZWRcbiAqIGluIHRoZSBzcGVjaWZpZWQgY29udGV4dC5cbiAqXG4gKiBUaGlzIGltcGxlbWVudGF0aW9uIHdpbGwgcmVzcG9uZCB3aXRoIGFsbG93IHVubGVzcyBhbnlvbmVcbiAqIG9iamVjdHMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGFjdGlvbiB0aGUgYWN0aW9uIHRvIGJlIGNoZWNrZWRcbiAqIEBwYXJhbSB7T2JqZWN0fSBbY29udGV4dF0gdGhlIGNvbnRleHQgdG8gY2hlY2sgdGhlIGFjdGlvbiBpblxuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHJldHVybnMgdHJ1ZSwgZmFsc2Ugb3IgbnVsbCBkZXBlbmRpbmcgb24gd2hldGhlciB0aGVcbiAqICAgICAgICAgICAgICAgICAgIG9wZXJhdGlvbiBpcyBhbGxvd2VkLCBub3QgYWxsb3dlZCBvciBzaG91bGQgYmUgaWdub3JlZC5cbiAqL1xuUnVsZXMucHJvdG90eXBlLmFsbG93ZWQgPSBmdW5jdGlvbihhY3Rpb24sIGNvbnRleHQpIHtcbiAgdmFyIGFsbG93ZWQgPSB0cnVlO1xuXG4gIHZhciBjb21tYW5kU3RhY2sgPSB0aGlzLl9jb21tYW5kU3RhY2s7XG5cbiAgaWYgKGNvbW1hbmRTdGFjaykge1xuICAgIGFsbG93ZWQgPSBjb21tYW5kU3RhY2suY2FuRXhlY3V0ZShhY3Rpb24sIGNvbnRleHQpO1xuICB9XG5cbiAgLy8gbWFwIHVuZGVmaW5lZCB0byB0cnVlLCBpLmUuIG5vIHJ1bGVzXG4gIHJldHVybiBhbGxvd2VkID09PSB1bmRlZmluZWQgPyB0cnVlIDogYWxsb3dlZDtcbn07IiwiaW1wb3J0IFJ1bGVzIGZyb20gJy4vUnVsZXMnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdydWxlcycgXSxcbiAgcnVsZXM6IFsgJ3R5cGUnLCBSdWxlcyBdXG59O1xuIiwiaW1wb3J0IHtcbiAgY2xlYXIgYXMgZG9tQ2xlYXIsXG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgY2xhc3NlcyBhcyBkb21DbGFzc2VzLFxuICBhdHRyIGFzIGRvbUF0dHIsXG4gIGRvbWlmeSBhcyBkb21pZnlcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIGdldEJCb3ggYXMgZ2V0Qm91bmRpbmdCb3hcbn0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbmltcG9ydCB7XG4gIGVzY2FwZUhUTUxcbn0gZnJvbSAnLi4vLi4vdXRpbC9Fc2NhcGVVdGlsJztcblxuLyoqXG4gKiBQcm92aWRlcyBzZWFyY2hpbmcgaW5mcmFzdHJ1Y3R1cmVcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gU2VhcmNoUGFkKGNhbnZhcywgZXZlbnRCdXMsIG92ZXJsYXlzLCBzZWxlY3Rpb24pIHtcbiAgdGhpcy5fb3BlbiA9IGZhbHNlO1xuICB0aGlzLl9yZXN1bHRzID0gW107XG4gIHRoaXMuX2V2ZW50TWFwcyA9IFtdO1xuXG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fb3ZlcmxheXMgPSBvdmVybGF5cztcbiAgdGhpcy5fc2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuXG4gIC8vIHNldHVwIGVsZW1lbnRzXG4gIHRoaXMuX2NvbnRhaW5lciA9IGRvbWlmeShTZWFyY2hQYWQuQk9YX0hUTUwpO1xuICB0aGlzLl9zZWFyY2hJbnB1dCA9IGRvbVF1ZXJ5KFNlYXJjaFBhZC5JTlBVVF9TRUxFQ1RPUiwgdGhpcy5fY29udGFpbmVyKTtcbiAgdGhpcy5fcmVzdWx0c0NvbnRhaW5lciA9IGRvbVF1ZXJ5KFNlYXJjaFBhZC5SRVNVTFRTX0NPTlRBSU5FUl9TRUxFQ1RPUiwgdGhpcy5fY29udGFpbmVyKTtcblxuICAvLyBhdHRhY2ggc2VhcmNoIHBhZFxuICB0aGlzLl9jYW52YXMuZ2V0Q29udGFpbmVyKCkuYXBwZW5kQ2hpbGQodGhpcy5fY29udGFpbmVyKTtcblxuICAvLyBjbGVhbnVwIG9uIGRlc3Ryb3lcbiAgZXZlbnRCdXMub24oWyAnY2FudmFzLmRlc3Ryb3knLCAnZGlhZ3JhbS5kZXN0cm95JyBdLCB0aGlzLmNsb3NlLCB0aGlzKTtcbn1cblxuXG5TZWFyY2hQYWQuJGluamVjdCA9IFtcbiAgJ2NhbnZhcycsXG4gICdldmVudEJ1cycsXG4gICdvdmVybGF5cycsXG4gICdzZWxlY3Rpb24nXG5dO1xuXG5cbi8qKlxuICogQmluZHMgYW5kIGtlZXBzIHRyYWNrIG9mIGFsbCBldmVudCBsaXN0ZXJlbmVyc1xuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLl9iaW5kRXZlbnRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBmdW5jdGlvbiBsaXN0ZW4oZWwsIHNlbGVjdG9yLCB0eXBlLCBmbikge1xuICAgIHNlbGYuX2V2ZW50TWFwcy5wdXNoKHtcbiAgICAgIGVsOiBlbCxcbiAgICAgIHR5cGU6IHR5cGUsXG4gICAgICBsaXN0ZW5lcjogZG9tRGVsZWdhdGUuYmluZChlbCwgc2VsZWN0b3IsIHR5cGUsIGZuKVxuICAgIH0pO1xuICB9XG5cbiAgLy8gY2xvc2Ugc2VhcmNoIG9uIGNsaWNraW5nIGFueXdoZXJlIG91dHNpZGVcbiAgbGlzdGVuKGRvY3VtZW50LCAnaHRtbCcsICdjbGljaycsIGZ1bmN0aW9uKGUpIHtcbiAgICBzZWxmLmNsb3NlKCk7XG4gIH0pO1xuXG4gIC8vIHN0b3AgZXZlbnQgZnJvbSBwcm9wYWdhdGluZyBhbmQgY2xvc2luZyBzZWFyY2hcbiAgLy8gZm9jdXMgb24gaW5wdXRcbiAgbGlzdGVuKHRoaXMuX2NvbnRhaW5lciwgU2VhcmNoUGFkLklOUFVUX1NFTEVDVE9SLCAnY2xpY2snLCBmdW5jdGlvbihlKSB7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBlLmRlbGVnYXRlVGFyZ2V0LmZvY3VzKCk7XG4gIH0pO1xuXG4gIC8vIHByZXNlbGVjdCByZXN1bHQgb24gaG92ZXJcbiAgbGlzdGVuKHRoaXMuX2NvbnRhaW5lciwgU2VhcmNoUGFkLlJFU1VMVF9TRUxFQ1RPUiwgJ21vdXNlb3ZlcicsIGZ1bmN0aW9uKGUpIHtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHNlbGYuX3Njcm9sbFRvTm9kZShlLmRlbGVnYXRlVGFyZ2V0KTtcbiAgICBzZWxmLl9wcmVzZWxlY3QoZS5kZWxlZ2F0ZVRhcmdldCk7XG4gIH0pO1xuXG4gIC8vIHNlbGVjdHMgZGVzaXJlZCByZXN1bHQgb24gbW91c2UgY2xpY2tcbiAgbGlzdGVuKHRoaXMuX2NvbnRhaW5lciwgU2VhcmNoUGFkLlJFU1VMVF9TRUxFQ1RPUiwgJ2NsaWNrJywgZnVuY3Rpb24oZSkge1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgc2VsZi5fc2VsZWN0KGUuZGVsZWdhdGVUYXJnZXQpO1xuICB9KTtcblxuICAvLyBwcmV2ZW50IGN1cnNvciBpbiBpbnB1dCBmcm9tIGdvaW5nIGxlZnQgYW5kIHJpZ2h0IHdoZW4gdXNpbmcgdXAvZG93biB0b1xuICAvLyBuYXZpZ2F0ZSByZXN1bHRzXG4gIGxpc3Rlbih0aGlzLl9jb250YWluZXIsIFNlYXJjaFBhZC5JTlBVVF9TRUxFQ1RPUiwgJ2tleWRvd24nLCBmdW5jdGlvbihlKSB7XG5cbiAgICAvLyB1cFxuICAgIGlmIChlLmtleUNvZGUgPT09IDM4KSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgLy8gZG93blxuICAgIGlmIChlLmtleUNvZGUgPT09IDQwKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9KTtcblxuICAvLyBoYW5kbGUga2V5Ym9hcmQgaW5wdXRcbiAgbGlzdGVuKHRoaXMuX2NvbnRhaW5lciwgU2VhcmNoUGFkLklOUFVUX1NFTEVDVE9SLCAna2V5dXAnLCBmdW5jdGlvbihlKSB7XG5cbiAgICAvLyBlc2NhcGVcbiAgICBpZiAoZS5rZXlDb2RlID09PSAyNykge1xuICAgICAgcmV0dXJuIHNlbGYuY2xvc2UoKTtcbiAgICB9XG5cbiAgICAvLyBlbnRlclxuICAgIGlmIChlLmtleUNvZGUgPT09IDEzKSB7XG4gICAgICB2YXIgc2VsZWN0ZWQgPSBzZWxmLl9nZXRDdXJyZW50UmVzdWx0KCk7XG5cbiAgICAgIHJldHVybiBzZWxlY3RlZCA/IHNlbGYuX3NlbGVjdChzZWxlY3RlZCkgOiBzZWxmLmNsb3NlKCk7XG4gICAgfVxuXG4gICAgLy8gdXBcbiAgICBpZiAoZS5rZXlDb2RlID09PSAzOCkge1xuICAgICAgcmV0dXJuIHNlbGYuX3Njcm9sbFRvRGlyZWN0aW9uKHRydWUpO1xuICAgIH1cblxuICAgIC8vIGRvd25cbiAgICBpZiAoZS5rZXlDb2RlID09PSA0MCkge1xuICAgICAgcmV0dXJuIHNlbGYuX3Njcm9sbFRvRGlyZWN0aW9uKCk7XG4gICAgfVxuXG4gICAgLy8gbGVmdCAmJiByaWdodFxuICAgIC8vIGRvIG5vdCBzZWFyY2ggd2hpbGUgbmF2aWdhdGluZyB0ZXh0IGlucHV0XG4gICAgaWYgKGUua2V5Q29kZSA9PT0gMzcgfHwgZS5rZXlDb2RlID09PSAzOSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGFueXRoaW5nIGVsc2VcbiAgICBzZWxmLl9zZWFyY2goZS5kZWxlZ2F0ZVRhcmdldC52YWx1ZSk7XG4gIH0pO1xufTtcblxuXG4vKipcbiAqIFVuYmluZHMgYWxsIHByZXZpb3VzbHkgZXN0YWJsaXNoZWQgbGlzdGVuZXJzXG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuX3VuYmluZEV2ZW50cyA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9ldmVudE1hcHMuZm9yRWFjaChmdW5jdGlvbihtKSB7XG4gICAgZG9tRGVsZWdhdGUudW5iaW5kKG0uZWwsIG0udHlwZSwgbS5saXN0ZW5lcik7XG4gIH0pO1xufTtcblxuXG4vKipcbiAqIFBlcmZvcm1zIGEgc2VhcmNoIGZvciB0aGUgZ2l2ZW4gcGF0dGVybi5cbiAqXG4gKiBAcGFyYW0gIHtzdHJpbmd9IHBhdHRlcm5cbiAqL1xuU2VhcmNoUGFkLnByb3RvdHlwZS5fc2VhcmNoID0gZnVuY3Rpb24ocGF0dGVybikge1xuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdGhpcy5fY2xlYXJSZXN1bHRzKCk7XG5cbiAgLy8gZG8gbm90IHNlYXJjaCBvbiBlbXB0eSBxdWVyeVxuICBpZiAoIXBhdHRlcm4gfHwgcGF0dGVybiA9PT0gJycpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgc2VhcmNoUmVzdWx0cyA9IHRoaXMuX3NlYXJjaFByb3ZpZGVyLmZpbmQocGF0dGVybik7XG5cbiAgaWYgKCFzZWFyY2hSZXN1bHRzLmxlbmd0aCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIC8vIGFwcGVuZCBuZXcgcmVzdWx0c1xuICBzZWFyY2hSZXN1bHRzLmZvckVhY2goZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgdmFyIGlkID0gcmVzdWx0LmVsZW1lbnQuaWQ7XG4gICAgdmFyIG5vZGUgPSBzZWxmLl9jcmVhdGVSZXN1bHROb2RlKHJlc3VsdCwgaWQpO1xuICAgIHNlbGYuX3Jlc3VsdHNbaWRdID0ge1xuICAgICAgZWxlbWVudDogcmVzdWx0LmVsZW1lbnQsXG4gICAgICBub2RlOiBub2RlXG4gICAgfTtcbiAgfSk7XG5cbiAgLy8gcHJlc2VsZWN0IGZpcnN0IHJlc3VsdFxuICB2YXIgbm9kZSA9IGRvbVF1ZXJ5KFNlYXJjaFBhZC5SRVNVTFRfU0VMRUNUT1IsIHRoaXMuX3Jlc3VsdHNDb250YWluZXIpO1xuICB0aGlzLl9zY3JvbGxUb05vZGUobm9kZSk7XG4gIHRoaXMuX3ByZXNlbGVjdChub2RlKTtcbn07XG5cblxuLyoqXG4gKiBOYXZpZ2F0ZSB0byB0aGUgcHJldmlvdXMvbmV4dCByZXN1bHQuIERlZmF1bHRzIHRvIG5leHQgcmVzdWx0LlxuICogQHBhcmFtICB7Ym9vbGVhbn0gcHJldmlvdXNcbiAqL1xuU2VhcmNoUGFkLnByb3RvdHlwZS5fc2Nyb2xsVG9EaXJlY3Rpb24gPSBmdW5jdGlvbihwcmV2aW91cykge1xuICB2YXIgc2VsZWN0ZWQgPSB0aGlzLl9nZXRDdXJyZW50UmVzdWx0KCk7XG4gIGlmICghc2VsZWN0ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgbm9kZSA9IHByZXZpb3VzID8gc2VsZWN0ZWQucHJldmlvdXNFbGVtZW50U2libGluZyA6IHNlbGVjdGVkLm5leHRFbGVtZW50U2libGluZztcbiAgaWYgKG5vZGUpIHtcbiAgICB0aGlzLl9zY3JvbGxUb05vZGUobm9kZSk7XG4gICAgdGhpcy5fcHJlc2VsZWN0KG5vZGUpO1xuICB9XG59O1xuXG5cbi8qKlxuICogU2Nyb2xsIHRvIHRoZSBub2RlIGlmIGl0IGlzIG5vdCB2aXNpYmxlLlxuICpcbiAqIEBwYXJhbSAge0VsZW1lbnR9IG5vZGVcbiAqL1xuU2VhcmNoUGFkLnByb3RvdHlwZS5fc2Nyb2xsVG9Ob2RlID0gZnVuY3Rpb24obm9kZSkge1xuICBpZiAoIW5vZGUgfHwgbm9kZSA9PT0gdGhpcy5fZ2V0Q3VycmVudFJlc3VsdCgpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG5vZGVPZmZzZXQgPSBub2RlLm9mZnNldFRvcDtcbiAgdmFyIGNvbnRhaW5lclNjcm9sbCA9IHRoaXMuX3Jlc3VsdHNDb250YWluZXIuc2Nyb2xsVG9wO1xuXG4gIHZhciBib3R0b21TY3JvbGwgPSBub2RlT2Zmc2V0IC0gdGhpcy5fcmVzdWx0c0NvbnRhaW5lci5jbGllbnRIZWlnaHQgKyBub2RlLmNsaWVudEhlaWdodDtcblxuICBpZiAobm9kZU9mZnNldCA8IGNvbnRhaW5lclNjcm9sbCkge1xuICAgIHRoaXMuX3Jlc3VsdHNDb250YWluZXIuc2Nyb2xsVG9wID0gbm9kZU9mZnNldDtcbiAgfSBlbHNlIGlmIChjb250YWluZXJTY3JvbGwgPCBib3R0b21TY3JvbGwpIHtcbiAgICB0aGlzLl9yZXN1bHRzQ29udGFpbmVyLnNjcm9sbFRvcCA9IGJvdHRvbVNjcm9sbDtcbiAgfVxufTtcblxuXG4vKipcbiAqIENsZWFycyBhbGwgcmVzdWx0cyBkYXRhLlxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLl9jbGVhclJlc3VsdHMgPSBmdW5jdGlvbigpIHtcbiAgZG9tQ2xlYXIodGhpcy5fcmVzdWx0c0NvbnRhaW5lcik7XG5cbiAgdGhpcy5fcmVzdWx0cyA9IFtdO1xuXG4gIHRoaXMuX3Jlc2V0T3ZlcmxheSgpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5jbGVhcmVkJyk7XG59O1xuXG5cbi8qKlxuICogR2V0IGN1cnJlbnRseSBzZWxlY3RlZCByZXN1bHQuXG4gKlxuICogQHJldHVybiB7RWxlbWVudH1cbiAqL1xuU2VhcmNoUGFkLnByb3RvdHlwZS5fZ2V0Q3VycmVudFJlc3VsdCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gZG9tUXVlcnkoU2VhcmNoUGFkLlJFU1VMVF9TRUxFQ1RFRF9TRUxFQ1RPUiwgdGhpcy5fcmVzdWx0c0NvbnRhaW5lcik7XG59O1xuXG5cbi8qKlxuICogQ3JlYXRlIHJlc3VsdCBET00gZWxlbWVudCB3aXRoaW4gcmVzdWx0cyBjb250YWluZXJcbiAqIHRoYXQgY29ycmVzcG9uZHMgdG8gYSBzZWFyY2ggcmVzdWx0LlxuICpcbiAqICdyZXN1bHQnIDogb25lIG9mIHRoZSBlbGVtZW50cyByZXR1cm5lZCBieSBTZWFyY2hQcm92aWRlclxuICogJ2lkJyA6IGlkIGF0dHJpYnV0ZSB2YWx1ZSB0byBhc3NpZ24gdG8gdGhlIG5ldyBET00gbm9kZVxuICogcmV0dXJuIDogY3JlYXRlZCBET00gZWxlbWVudFxuICpcbiAqIEBwYXJhbSAge1NlYXJjaFJlc3VsdH0gcmVzdWx0XG4gKiBAcGFyYW0gIHtzdHJpbmd9IGlkXG4gKiBAcmV0dXJuIHtFbGVtZW50fVxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLl9jcmVhdGVSZXN1bHROb2RlID0gZnVuY3Rpb24ocmVzdWx0LCBpZCkge1xuICB2YXIgbm9kZSA9IGRvbWlmeShTZWFyY2hQYWQuUkVTVUxUX0hUTUwpO1xuXG4gIC8vIGNyZWF0ZSBvbmx5IGlmIGF2YWlsYWJsZVxuICBpZiAocmVzdWx0LnByaW1hcnlUb2tlbnMubGVuZ3RoID4gMCkge1xuICAgIGNyZWF0ZUlubmVyVGV4dE5vZGUobm9kZSwgcmVzdWx0LnByaW1hcnlUb2tlbnMsIFNlYXJjaFBhZC5SRVNVTFRfUFJJTUFSWV9IVE1MKTtcbiAgfVxuXG4gIC8vIHNlY29uZGFyeSB0b2tlbnMgKHJlcHJlc2VudCBlbGVtZW50IElEKSBhcmUgYWxsd2F5cyBhdmFpbGFibGVcbiAgY3JlYXRlSW5uZXJUZXh0Tm9kZShub2RlLCByZXN1bHQuc2Vjb25kYXJ5VG9rZW5zLCBTZWFyY2hQYWQuUkVTVUxUX1NFQ09OREFSWV9IVE1MKTtcblxuICBkb21BdHRyKG5vZGUsIFNlYXJjaFBhZC5SRVNVTFRfSURfQVRUUklCVVRFLCBpZCk7XG5cbiAgdGhpcy5fcmVzdWx0c0NvbnRhaW5lci5hcHBlbmRDaGlsZChub2RlKTtcblxuICByZXR1cm4gbm9kZTtcbn07XG5cblxuLyoqXG4gKiBSZWdpc3RlciBzZWFyY2ggZWxlbWVudCBwcm92aWRlci5cbiAqXG4gKiBTZWFyY2hQcm92aWRlci5maW5kIC0gcHJvdmlkZXMgc2VhcmNoIGZ1bmN0aW9uIG92ZXIgb3duIGVsZW1lbnRzXG4gKiAgKHBhdHRlcm4pID0+IFt7IHRleHQ6IDxTdHJpbmc+LCBlbGVtZW50OiA8RWxlbWVudD59LCAuLi5dXG4gKlxuICogQHBhcmFtICB7U2VhcmNoUHJvdmlkZXJ9IHByb3ZpZGVyXG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUucmVnaXN0ZXJQcm92aWRlciA9IGZ1bmN0aW9uKHByb3ZpZGVyKSB7XG4gIHRoaXMuX3NlYXJjaFByb3ZpZGVyID0gcHJvdmlkZXI7XG59O1xuXG5cbi8qKlxuICogT3BlbiBzZWFyY2ggcGFkLlxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgaWYgKCF0aGlzLl9zZWFyY2hQcm92aWRlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignbm8gc2VhcmNoIHByb3ZpZGVyIHJlZ2lzdGVyZWQnKTtcbiAgfVxuXG4gIGlmICh0aGlzLmlzT3BlbigpKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fYmluZEV2ZW50cygpO1xuXG4gIHRoaXMuX29wZW4gPSB0cnVlO1xuXG4gIGRvbUNsYXNzZXModGhpcy5fY29udGFpbmVyKS5hZGQoJ29wZW4nKTtcblxuICB0aGlzLl9zZWFyY2hJbnB1dC5mb2N1cygpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5vcGVuZWQnKTtcbn07XG5cblxuLyoqXG4gKiBDbG9zZSBzZWFyY2ggcGFkLlxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5pc09wZW4oKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRoaXMuX3VuYmluZEV2ZW50cygpO1xuXG4gIHRoaXMuX29wZW4gPSBmYWxzZTtcblxuICBkb21DbGFzc2VzKHRoaXMuX2NvbnRhaW5lcikucmVtb3ZlKCdvcGVuJyk7XG5cbiAgdGhpcy5fY2xlYXJSZXN1bHRzKCk7XG5cbiAgdGhpcy5fc2VhcmNoSW5wdXQudmFsdWUgPSAnJztcbiAgdGhpcy5fc2VhcmNoSW5wdXQuYmx1cigpO1xuXG4gIHRoaXMuX3Jlc2V0T3ZlcmxheSgpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5jbG9zZWQnKTtcbn07XG5cblxuLyoqXG4gKiBUb2dnbGVzIHNlYXJjaCBwYWQgb24vb2ZmLlxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmlzT3BlbigpID8gdGhpcy5jbG9zZSgpIDogdGhpcy5vcGVuKCk7XG59O1xuXG5cbi8qKlxuICogUmVwb3J0IHN0YXRlIG9mIHNlYXJjaCBwYWQuXG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuaXNPcGVuID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9vcGVuO1xufTtcblxuXG4vKipcbiAqIFByZXNlbGVjdCByZXN1bHQgZW50cnkuXG4gKlxuICogQHBhcmFtICB7RWxlbWVudH0gZWxlbWVudFxuICovXG5TZWFyY2hQYWQucHJvdG90eXBlLl9wcmVzZWxlY3QgPSBmdW5jdGlvbihub2RlKSB7XG4gIHZhciBzZWxlY3RlZE5vZGUgPSB0aGlzLl9nZXRDdXJyZW50UmVzdWx0KCk7XG5cbiAgLy8gYWxyZWFkeSBzZWxlY3RlZFxuICBpZiAobm9kZSA9PT0gc2VsZWN0ZWROb2RlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gcmVtb3ZpbmcgcHJlc2VsZWN0aW9uIGZyb20gY3VycmVudCBub2RlXG4gIGlmIChzZWxlY3RlZE5vZGUpIHtcbiAgICBkb21DbGFzc2VzKHNlbGVjdGVkTm9kZSkucmVtb3ZlKFNlYXJjaFBhZC5SRVNVTFRfU0VMRUNURURfQ0xBU1MpO1xuICB9XG5cbiAgdmFyIGlkID0gZG9tQXR0cihub2RlLCBTZWFyY2hQYWQuUkVTVUxUX0lEX0FUVFJJQlVURSk7XG4gIHZhciBlbGVtZW50ID0gdGhpcy5fcmVzdWx0c1tpZF0uZWxlbWVudDtcblxuICBkb21DbGFzc2VzKG5vZGUpLmFkZChTZWFyY2hQYWQuUkVTVUxUX1NFTEVDVEVEX0NMQVNTKTtcblxuICB0aGlzLl9yZXNldE92ZXJsYXkoZWxlbWVudCk7XG5cbiAgdGhpcy5fY2VudGVyVmlld2JveChlbGVtZW50KTtcblxuICB0aGlzLl9zZWxlY3Rpb24uc2VsZWN0KGVsZW1lbnQpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5wcmVzZWxlY3RlZCcsIGVsZW1lbnQpO1xufTtcblxuXG4vKipcbiAqIFNlbGVjdCByZXN1bHQgbm9kZS5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBlbGVtZW50XG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuX3NlbGVjdCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgdmFyIGlkID0gZG9tQXR0cihub2RlLCBTZWFyY2hQYWQuUkVTVUxUX0lEX0FUVFJJQlVURSk7XG4gIHZhciBlbGVtZW50ID0gdGhpcy5fcmVzdWx0c1tpZF0uZWxlbWVudDtcblxuICB0aGlzLmNsb3NlKCk7XG5cbiAgdGhpcy5fcmVzZXRPdmVybGF5KCk7XG5cbiAgdGhpcy5fY2VudGVyVmlld2JveChlbGVtZW50KTtcblxuICB0aGlzLl9zZWxlY3Rpb24uc2VsZWN0KGVsZW1lbnQpO1xuXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ3NlYXJjaFBhZC5zZWxlY3RlZCcsIGVsZW1lbnQpO1xufTtcblxuXG4vKipcbiAqIENlbnRlciB2aWV3Ym94IG9uIHRoZSBlbGVtZW50IG1pZGRsZSBwb2ludC5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBlbGVtZW50XG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuX2NlbnRlclZpZXdib3ggPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciB2aWV3Ym94ID0gdGhpcy5fY2FudmFzLnZpZXdib3goKTtcblxuICB2YXIgYm94ID0gZ2V0Qm91bmRpbmdCb3goZWxlbWVudCk7XG5cbiAgdmFyIG5ld1ZpZXdib3ggPSB7XG4gICAgeDogKGJveC54ICsgYm94LndpZHRoLzIpIC0gdmlld2JveC5vdXRlci53aWR0aC8yLFxuICAgIHk6IChib3gueSArIGJveC5oZWlnaHQvMikgLSB2aWV3Ym94Lm91dGVyLmhlaWdodC8yLFxuICAgIHdpZHRoOiB2aWV3Ym94Lm91dGVyLndpZHRoLFxuICAgIGhlaWdodDogdmlld2JveC5vdXRlci5oZWlnaHRcbiAgfTtcblxuICB0aGlzLl9jYW52YXMudmlld2JveChuZXdWaWV3Ym94KTtcblxuICB0aGlzLl9jYW52YXMuem9vbSh2aWV3Ym94LnNjYWxlKTtcbn07XG5cblxuLyoqXG4gKiBSZXNldCBvdmVybGF5IHJlbW92ZXMgYW5kLCBvcHRpb25hbGx5LCBzZXRcbiAqIG92ZXJsYXkgdG8gYSBuZXcgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBlbGVtZW50XG4gKi9cblNlYXJjaFBhZC5wcm90b3R5cGUuX3Jlc2V0T3ZlcmxheSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgaWYgKHRoaXMuX292ZXJsYXlJZCkge1xuICAgIHRoaXMuX292ZXJsYXlzLnJlbW92ZSh0aGlzLl9vdmVybGF5SWQpO1xuICB9XG5cbiAgaWYgKGVsZW1lbnQpIHtcbiAgICB2YXIgYm94ID0gZ2V0Qm91bmRpbmdCb3goZWxlbWVudCk7XG4gICAgdmFyIG92ZXJsYXkgPSBjb25zdHJ1Y3RPdmVybGF5KGJveCk7XG4gICAgdGhpcy5fb3ZlcmxheUlkID0gdGhpcy5fb3ZlcmxheXMuYWRkKGVsZW1lbnQsIG92ZXJsYXkpO1xuICB9XG59O1xuXG5cbi8qKlxuICogQ29uc3RydWN0IG92ZXJsYXkgb2JqZWN0IGZvciB0aGUgZ2l2ZW4gYm91bmRpbmcgYm94LlxuICpcbiAqIEBwYXJhbSAge0JvdW5kaW5nQm94fSBib3hcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuZnVuY3Rpb24gY29uc3RydWN0T3ZlcmxheShib3gpIHtcblxuICB2YXIgb2Zmc2V0ID0gNjtcbiAgdmFyIHcgPSBib3gud2lkdGggKyBvZmZzZXQgKiAyO1xuICB2YXIgaCA9IGJveC5oZWlnaHQgKyBvZmZzZXQgKiAyO1xuXG4gIHZhciBzdHlsZXMgPSBbXG4gICAgJ3dpZHRoOiAnKyB3ICsncHgnLFxuICAgICdoZWlnaHQ6ICcrIGggKyAncHgnXG4gIF0uam9pbignOyAnKTtcblxuICByZXR1cm4ge1xuICAgIHBvc2l0aW9uOiB7XG4gICAgICBib3R0b206IGggLSBvZmZzZXQsXG4gICAgICByaWdodDogdyAtIG9mZnNldFxuICAgIH0sXG4gICAgc2hvdzogdHJ1ZSxcbiAgICBodG1sOiAnPGRpdiBzdHlsZT1cIicgKyBzdHlsZXMgKyAnXCIgY2xhc3M9XCInICsgU2VhcmNoUGFkLk9WRVJMQVlfQ0xBU1MgKyAnXCI+PC9kaXY+J1xuICB9O1xufVxuXG5cbi8qKlxuICogQ3JlYXRlcyBhbmQgYXBwZW5kcyBjaGlsZCBub2RlIGZyb20gcmVzdWx0IHRva2VucyBhbmQgSFRNTCB0ZW1wbGF0ZS5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBub2RlXG4gKiBAcGFyYW0gIHtBcnJheTxPYmplY3Q+fSB0b2tlbnNcbiAqIEBwYXJhbSAge3N0cmluZ30gdGVtcGxhdGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5uZXJUZXh0Tm9kZShwYXJlbnROb2RlLCB0b2tlbnMsIHRlbXBsYXRlKSB7XG4gIHZhciB0ZXh0ID0gY3JlYXRlSHRtbFRleHQodG9rZW5zKTtcbiAgdmFyIGNoaWxkTm9kZSA9IGRvbWlmeSh0ZW1wbGF0ZSk7XG4gIGNoaWxkTm9kZS5pbm5lckhUTUwgPSB0ZXh0O1xuICBwYXJlbnROb2RlLmFwcGVuZENoaWxkKGNoaWxkTm9kZSk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGludGVybmFsIEhUTUwgbWFya3VwIGZyb20gcmVzdWx0IHRva2Vucy5cbiAqIENhdGVycyBmb3IgaGlnaGxpZ2h0aW5nIHBhdHRlcm4gbWF0Y2hlZCB0b2tlbnMuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8T2JqZWN0Pn0gdG9rZW5zXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUh0bWxUZXh0KHRva2Vucykge1xuICB2YXIgaHRtbFRleHQgPSAnJztcblxuICB0b2tlbnMuZm9yRWFjaChmdW5jdGlvbih0KSB7XG4gICAgaWYgKHQubWF0Y2hlZCkge1xuICAgICAgaHRtbFRleHQgKz0gJzxzdHJvbmcgY2xhc3M9XCInICsgU2VhcmNoUGFkLlJFU1VMVF9ISUdITElHSFRfQ0xBU1MgKyAnXCI+JyArIGVzY2FwZUhUTUwodC5tYXRjaGVkKSArICc8L3N0cm9uZz4nO1xuICAgIH0gZWxzZSB7XG4gICAgICBodG1sVGV4dCArPSBlc2NhcGVIVE1MKHQubm9ybWFsKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBodG1sVGV4dCAhPT0gJycgPyBodG1sVGV4dCA6IG51bGw7XG59XG5cblxuLyoqXG4gKiBDT05TVEFOVFNcbiAqL1xuU2VhcmNoUGFkLkNPTlRBSU5FUl9TRUxFQ1RPUiA9ICcuZGpzLXNlYXJjaC1jb250YWluZXInO1xuU2VhcmNoUGFkLklOUFVUX1NFTEVDVE9SID0gJy5kanMtc2VhcmNoLWlucHV0IGlucHV0JztcblNlYXJjaFBhZC5SRVNVTFRTX0NPTlRBSU5FUl9TRUxFQ1RPUiA9ICcuZGpzLXNlYXJjaC1yZXN1bHRzJztcblNlYXJjaFBhZC5SRVNVTFRfU0VMRUNUT1IgPSAnLmRqcy1zZWFyY2gtcmVzdWx0JztcblNlYXJjaFBhZC5SRVNVTFRfU0VMRUNURURfQ0xBU1MgPSAnZGpzLXNlYXJjaC1yZXN1bHQtc2VsZWN0ZWQnO1xuU2VhcmNoUGFkLlJFU1VMVF9TRUxFQ1RFRF9TRUxFQ1RPUiA9ICcuJyArIFNlYXJjaFBhZC5SRVNVTFRfU0VMRUNURURfQ0xBU1M7XG5TZWFyY2hQYWQuUkVTVUxUX0lEX0FUVFJJQlVURSA9ICdkYXRhLXJlc3VsdC1pZCc7XG5TZWFyY2hQYWQuUkVTVUxUX0hJR0hMSUdIVF9DTEFTUyA9ICdkanMtc2VhcmNoLWhpZ2hsaWdodCc7XG5TZWFyY2hQYWQuT1ZFUkxBWV9DTEFTUyA9ICdkanMtc2VhcmNoLW92ZXJsYXknO1xuXG5TZWFyY2hQYWQuQk9YX0hUTUwgPVxuICAnPGRpdiBjbGFzcz1cImRqcy1zZWFyY2gtY29udGFpbmVyIGRqcy1kcmFnZ2FibGUgZGpzLXNjcm9sbGFibGVcIj4nICtcbiAgICAnPGRpdiBjbGFzcz1cImRqcy1zZWFyY2gtaW5wdXRcIj4nICtcbiAgICAgICc8aW5wdXQgdHlwZT1cInRleHRcIi8+JyArXG4gICAgJzwvZGl2PicgK1xuICAgICc8ZGl2IGNsYXNzPVwiZGpzLXNlYXJjaC1yZXN1bHRzXCI+PC9kaXY+JyArXG4gICc8L2Rpdj4nO1xuXG5TZWFyY2hQYWQuUkVTVUxUX0hUTUwgPVxuICAnPGRpdiBjbGFzcz1cImRqcy1zZWFyY2gtcmVzdWx0XCI+PC9kaXY+JztcblxuU2VhcmNoUGFkLlJFU1VMVF9QUklNQVJZX0hUTUwgPVxuICAnPGRpdiBjbGFzcz1cImRqcy1zZWFyY2gtcmVzdWx0LXByaW1hcnlcIj48L2Rpdj4nO1xuXG5TZWFyY2hQYWQuUkVTVUxUX1NFQ09OREFSWV9IVE1MID1cbiAgJzxwIGNsYXNzPVwiZGpzLXNlYXJjaC1yZXN1bHQtc2Vjb25kYXJ5XCI+PC9wPic7XG4iLCJpbXBvcnQgT3ZlcmxheXNNb2R1bGUgZnJvbSAnLi4vb3ZlcmxheXMnO1xuaW1wb3J0IFNlbGVjdGlvbk1vZHVsZSBmcm9tICcuLi9zZWxlY3Rpb24nO1xuXG5pbXBvcnQgU2VhcmNoUGFkIGZyb20gJy4vU2VhcmNoUGFkJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIE92ZXJsYXlzTW9kdWxlLFxuICAgIFNlbGVjdGlvbk1vZHVsZVxuICBdLFxuICBzZWFyY2hQYWQ6IFsgJ3R5cGUnLCBTZWFyY2hQYWQgXVxufTtcbiIsImltcG9ydCB7XG4gIGlzQXJyYXksXG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5cbi8qKlxuICogQSBzZXJ2aWNlIHRoYXQgb2ZmZXJzIHRoZSBjdXJyZW50IHNlbGVjdGlvbiBpbiBhIGRpYWdyYW0uXG4gKiBPZmZlcnMgdGhlIGFwaSB0byBjb250cm9sIHRoZSBzZWxlY3Rpb24sIHRvby5cbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1cyB0aGUgZXZlbnQgYnVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNlbGVjdGlvbihldmVudEJ1cykge1xuXG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG5cbiAgdGhpcy5fc2VsZWN0ZWRFbGVtZW50cyA9IFtdO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICBldmVudEJ1cy5vbihbICdzaGFwZS5yZW1vdmUnLCAnY29ubmVjdGlvbi5yZW1vdmUnIF0sIGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZWxlbWVudCA9IGUuZWxlbWVudDtcbiAgICBzZWxmLmRlc2VsZWN0KGVsZW1lbnQpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihbICdkaWFncmFtLmNsZWFyJyBdLCBmdW5jdGlvbihlKSB7XG4gICAgc2VsZi5zZWxlY3QobnVsbCk7XG4gIH0pO1xufVxuXG5TZWxlY3Rpb24uJGluamVjdCA9IFsgJ2V2ZW50QnVzJyBdO1xuXG5cblNlbGVjdGlvbi5wcm90b3R5cGUuZGVzZWxlY3QgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHZhciBzZWxlY3RlZEVsZW1lbnRzID0gdGhpcy5fc2VsZWN0ZWRFbGVtZW50cztcblxuICB2YXIgaWR4ID0gc2VsZWN0ZWRFbGVtZW50cy5pbmRleE9mKGVsZW1lbnQpO1xuXG4gIGlmIChpZHggIT09IC0xKSB7XG4gICAgdmFyIG9sZFNlbGVjdGlvbiA9IHNlbGVjdGVkRWxlbWVudHMuc2xpY2UoKTtcblxuICAgIHNlbGVjdGVkRWxlbWVudHMuc3BsaWNlKGlkeCwgMSk7XG5cbiAgICB0aGlzLl9ldmVudEJ1cy5maXJlKCdzZWxlY3Rpb24uY2hhbmdlZCcsIHsgb2xkU2VsZWN0aW9uOiBvbGRTZWxlY3Rpb24sIG5ld1NlbGVjdGlvbjogc2VsZWN0ZWRFbGVtZW50cyB9KTtcbiAgfVxufTtcblxuXG5TZWxlY3Rpb24ucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fc2VsZWN0ZWRFbGVtZW50cztcbn07XG5cblNlbGVjdGlvbi5wcm90b3R5cGUuaXNTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkRWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTE7XG59O1xuXG5cbi8qKlxuICogVGhpcyBtZXRob2Qgc2VsZWN0cyBvbmUgb3IgbW9yZSBlbGVtZW50cyBvbiB0aGUgZGlhZ3JhbS5cbiAqXG4gKiBCeSBwYXNzaW5nIGFuIGFkZGl0aW9uYWwgYWRkIHBhcmFtZXRlciB5b3UgY2FuIGRlY2lkZSB3aGV0aGVyIG9yIG5vdCB0aGUgZWxlbWVudChzKVxuICogc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSBhbHJlYWR5IGV4aXN0aW5nIHNlbGVjdGlvbiBvciBub3QuXG4gKlxuICogQG1ldGhvZCBTZWxlY3Rpb24jc2VsZWN0XG4gKlxuICogQHBhcmFtICB7T2JqZWN0fE9iamVjdFtdfSBlbGVtZW50cyBlbGVtZW50IG9yIGFycmF5IG9mIGVsZW1lbnRzIHRvIGJlIHNlbGVjdGVkXG4gKiBAcGFyYW0gIHtib29sZWFufSBbYWRkXSB3aGV0aGVyIHRoZSBlbGVtZW50KHMpIHNob3VsZCBiZSBhcHBlbmRlZCB0byB0aGUgY3VycmVudCBzZWxlY3Rpb24sIGRlZmF1bHRzIHRvIGZhbHNlXG4gKi9cblNlbGVjdGlvbi5wcm90b3R5cGUuc2VsZWN0ID0gZnVuY3Rpb24oZWxlbWVudHMsIGFkZCkge1xuICB2YXIgc2VsZWN0ZWRFbGVtZW50cyA9IHRoaXMuX3NlbGVjdGVkRWxlbWVudHMsXG4gICAgICBvbGRTZWxlY3Rpb24gPSBzZWxlY3RlZEVsZW1lbnRzLnNsaWNlKCk7XG5cbiAgaWYgKCFpc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gZWxlbWVudHMgPyBbIGVsZW1lbnRzIF0gOiBbXTtcbiAgfVxuXG4gIC8vIHNlbGVjdGlvbiBtYXkgYmUgY2xlYXJlZCBieSBwYXNzaW5nIGFuIGVtcHR5IGFycmF5IG9yIG51bGxcbiAgLy8gdG8gdGhlIG1ldGhvZFxuICBpZiAoYWRkKSB7XG4gICAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgaWYgKHNlbGVjdGVkRWxlbWVudHMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTEpIHtcblxuICAgICAgICAvLyBhbHJlYWR5IHNlbGVjdGVkXG4gICAgICAgIHJldHVybjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNlbGVjdGVkRWxlbWVudHMucHVzaChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLl9zZWxlY3RlZEVsZW1lbnRzID0gc2VsZWN0ZWRFbGVtZW50cyA9IGVsZW1lbnRzLnNsaWNlKCk7XG4gIH1cblxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdzZWxlY3Rpb24uY2hhbmdlZCcsIHsgb2xkU2VsZWN0aW9uOiBvbGRTZWxlY3Rpb24sIG5ld1NlbGVjdGlvbjogc2VsZWN0ZWRFbGVtZW50cyB9KTtcbn07XG4iLCJpbXBvcnQge1xuICBoYXNQcmltYXJ5TW9kaWZpZXIsXG4gIGhhc1NlY29uZGFyeU1vZGlmaWVyXG59IGZyb20gJy4uLy4uL3V0aWwvTW91c2UnO1xuXG5pbXBvcnQge1xuICBmaW5kLFxuICBpc0FycmF5XG59IGZyb20gJ21pbi1kYXNoJztcblxuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBTZWxlY3Rpb25CZWhhdmlvcihldmVudEJ1cywgc2VsZWN0aW9uLCBjYW52YXMsIGVsZW1lbnRSZWdpc3RyeSkge1xuXG4gIC8vIFNlbGVjdCBlbGVtZW50cyBvbiBjcmVhdGVcbiAgZXZlbnRCdXMub24oJ2NyZWF0ZS5lbmQnLCA1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBlbGVtZW50cyA9IGNvbnRleHQuZWxlbWVudHMsXG4gICAgICAgIGhpbnRzID0gY29udGV4dC5oaW50cyB8fCB7fSxcbiAgICAgICAgYXV0b1NlbGVjdCA9IGhpbnRzLmF1dG9TZWxlY3Q7XG5cbiAgICBpZiAoY2FuRXhlY3V0ZSkge1xuICAgICAgaWYgKGF1dG9TZWxlY3QgPT09IGZhbHNlKSB7XG5cbiAgICAgICAgLy8gU2VsZWN0IG5vIGVsZW1lbnRzXG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKGlzQXJyYXkoYXV0b1NlbGVjdCkpIHtcbiAgICAgICAgc2VsZWN0aW9uLnNlbGVjdChhdXRvU2VsZWN0KTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gU2VsZWN0IGFsbCBlbGVtZW50cyBieSBkZWZhdWx0XG4gICAgICAgIHNlbGVjdGlvbi5zZWxlY3QoZWxlbWVudHMuZmlsdGVyKGlzU2hvd24pKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIFNlbGVjdCBjb25uZWN0aW9uIHRhcmdldHMgb24gY29ubmVjdFxuICBldmVudEJ1cy5vbignY29ubmVjdC5lbmQnLCA1MDAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBjYW5FeGVjdXRlID0gY29udGV4dC5jYW5FeGVjdXRlLFxuICAgICAgICBob3ZlciA9IGNvbnRleHQuaG92ZXI7XG5cbiAgICBpZiAoY2FuRXhlY3V0ZSAmJiBob3Zlcikge1xuICAgICAgc2VsZWN0aW9uLnNlbGVjdChob3Zlcik7XG4gICAgfVxuICB9KTtcblxuICAvLyBTZWxlY3Qgc2hhcGVzIG9uIG1vdmVcbiAgZXZlbnRCdXMub24oJ3NoYXBlLm1vdmUuZW5kJywgNTAwLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBwcmV2aW91c1NlbGVjdGlvbiA9IGV2ZW50LnByZXZpb3VzU2VsZWN0aW9uIHx8IFtdO1xuXG4gICAgdmFyIHNoYXBlID0gZWxlbWVudFJlZ2lzdHJ5LmdldChldmVudC5jb250ZXh0LnNoYXBlLmlkKTtcblxuICAgIC8vIEFsd2F5cyBzZWxlY3QgbWFpbiBzaGFwZSBvbiBtb3ZlXG4gICAgdmFyIGlzU2VsZWN0ZWQgPSBmaW5kKHByZXZpb3VzU2VsZWN0aW9uLCBmdW5jdGlvbihzZWxlY3RlZFNoYXBlKSB7XG4gICAgICByZXR1cm4gc2hhcGUuaWQgPT09IHNlbGVjdGVkU2hhcGUuaWQ7XG4gICAgfSk7XG5cbiAgICBpZiAoIWlzU2VsZWN0ZWQpIHtcbiAgICAgIHNlbGVjdGlvbi5zZWxlY3Qoc2hhcGUpO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gU2VsZWN0IGVsZW1lbnRzIG9uIGNsaWNrXG4gIGV2ZW50QnVzLm9uKCdlbGVtZW50LmNsaWNrJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQ7XG5cbiAgICBpZiAoZWxlbWVudCA9PT0gY2FudmFzLmdldFJvb3RFbGVtZW50KCkpIHtcbiAgICAgIGVsZW1lbnQgPSBudWxsO1xuICAgIH1cblxuICAgIHZhciBpc1NlbGVjdGVkID0gc2VsZWN0aW9uLmlzU2VsZWN0ZWQoZWxlbWVudCksXG4gICAgICAgIGlzTXVsdGlTZWxlY3QgPSBzZWxlY3Rpb24uZ2V0KCkubGVuZ3RoID4gMTtcblxuICAgIC8vIEFkZCB0byBzZWxlY3Rpb24gaWYgQ1RSTCBvciBTSElGVCBwcmVzc2VkXG4gICAgdmFyIGFkZCA9IGhhc1ByaW1hcnlNb2RpZmllcihldmVudCkgfHwgaGFzU2Vjb25kYXJ5TW9kaWZpZXIoZXZlbnQpO1xuXG4gICAgaWYgKGlzU2VsZWN0ZWQgJiYgaXNNdWx0aVNlbGVjdCkge1xuICAgICAgaWYgKGFkZCkge1xuXG4gICAgICAgIC8vIERlc2VsZWN0IGVsZW1lbnRcbiAgICAgICAgcmV0dXJuIHNlbGVjdGlvbi5kZXNlbGVjdChlbGVtZW50KTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gU2VsZWN0IGVsZW1lbnQgb25seVxuICAgICAgICByZXR1cm4gc2VsZWN0aW9uLnNlbGVjdChlbGVtZW50KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFpc1NlbGVjdGVkKSB7XG5cbiAgICAgIC8vIFNlbGVjdCBlbGVtZW50XG4gICAgICBzZWxlY3Rpb24uc2VsZWN0KGVsZW1lbnQsIGFkZCk7XG4gICAgfSBlbHNlIHtcblxuICAgICAgLy8gRGVzZWxlY3QgZWxlbWVudFxuICAgICAgc2VsZWN0aW9uLmRlc2VsZWN0KGVsZW1lbnQpO1xuICAgIH1cbiAgfSk7XG59XG5cblNlbGVjdGlvbkJlaGF2aW9yLiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdzZWxlY3Rpb24nLFxuICAnY2FudmFzJyxcbiAgJ2VsZW1lbnRSZWdpc3RyeSdcbl07XG5cblxuZnVuY3Rpb24gaXNTaG93bihlbGVtZW50KSB7XG4gIHJldHVybiAhZWxlbWVudC5oaWRkZW47XG59XG4iLCJpbXBvcnQge1xuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxudmFyIE1BUktFUl9IT1ZFUiA9ICdob3ZlcicsXG4gICAgTUFSS0VSX1NFTEVDVEVEID0gJ3NlbGVjdGVkJztcblxuXG4vKipcbiAqIEEgcGx1Z2luIHRoYXQgYWRkcyBhIHZpc2libGUgc2VsZWN0aW9uIFVJIHRvIHNoYXBlcyBhbmQgY29ubmVjdGlvbnNcbiAqIGJ5IGFwcGVuZGluZyB0aGUgPGNvZGU+aG92ZXI8L2NvZGU+IGFuZCA8Y29kZT5zZWxlY3RlZDwvY29kZT4gY2xhc3NlcyB0byB0aGVtLlxuICpcbiAqIEBjbGFzc1xuICpcbiAqIE1ha2VzIGVsZW1lbnRzIHNlbGVjdGFibGUsIHRvby5cbiAqXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudHNcbiAqIEBwYXJhbSB7U2VsZWN0aW9uU2VydmljZX0gc2VsZWN0aW9uXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNlbGVjdGlvblZpc3VhbHMoZXZlbnRzLCBjYW52YXMsIHNlbGVjdGlvbiwgc3R5bGVzKSB7XG5cbiAgdGhpcy5fbXVsdGlTZWxlY3Rpb25Cb3ggPSBudWxsO1xuXG4gIGZ1bmN0aW9uIGFkZE1hcmtlcihlLCBjbHMpIHtcbiAgICBjYW52YXMuYWRkTWFya2VyKGUsIGNscyk7XG4gIH1cblxuICBmdW5jdGlvbiByZW1vdmVNYXJrZXIoZSwgY2xzKSB7XG4gICAgY2FudmFzLnJlbW92ZU1hcmtlcihlLCBjbHMpO1xuICB9XG5cbiAgZXZlbnRzLm9uKCdlbGVtZW50LmhvdmVyJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBhZGRNYXJrZXIoZXZlbnQuZWxlbWVudCwgTUFSS0VSX0hPVkVSKTtcbiAgfSk7XG5cbiAgZXZlbnRzLm9uKCdlbGVtZW50Lm91dCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgcmVtb3ZlTWFya2VyKGV2ZW50LmVsZW1lbnQsIE1BUktFUl9IT1ZFUik7XG4gIH0pO1xuXG4gIGV2ZW50cy5vbignc2VsZWN0aW9uLmNoYW5nZWQnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgZnVuY3Rpb24gZGVzZWxlY3Qocykge1xuICAgICAgcmVtb3ZlTWFya2VyKHMsIE1BUktFUl9TRUxFQ1RFRCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2VsZWN0KHMpIHtcbiAgICAgIGFkZE1hcmtlcihzLCBNQVJLRVJfU0VMRUNURUQpO1xuICAgIH1cblxuICAgIHZhciBvbGRTZWxlY3Rpb24gPSBldmVudC5vbGRTZWxlY3Rpb24sXG4gICAgICAgIG5ld1NlbGVjdGlvbiA9IGV2ZW50Lm5ld1NlbGVjdGlvbjtcblxuICAgIGZvckVhY2gob2xkU2VsZWN0aW9uLCBmdW5jdGlvbihlKSB7XG4gICAgICBpZiAobmV3U2VsZWN0aW9uLmluZGV4T2YoZSkgPT09IC0xKSB7XG4gICAgICAgIGRlc2VsZWN0KGUpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgZm9yRWFjaChuZXdTZWxlY3Rpb24sIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGlmIChvbGRTZWxlY3Rpb24uaW5kZXhPZihlKSA9PT0gLTEpIHtcbiAgICAgICAgc2VsZWN0KGUpO1xuICAgICAgfVxuICAgIH0pO1xuICB9KTtcbn1cblxuU2VsZWN0aW9uVmlzdWFscy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnY2FudmFzJyxcbiAgJ3NlbGVjdGlvbicsXG4gICdzdHlsZXMnXG5dOyIsImltcG9ydCBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSBmcm9tICcuLi9pbnRlcmFjdGlvbi1ldmVudHMnO1xuaW1wb3J0IE91dGxpbmVNb2R1bGUgZnJvbSAnLi4vb3V0bGluZSc7XG5cbmltcG9ydCBTZWxlY3Rpb24gZnJvbSAnLi9TZWxlY3Rpb24nO1xuaW1wb3J0IFNlbGVjdGlvblZpc3VhbHMgZnJvbSAnLi9TZWxlY3Rpb25WaXN1YWxzJztcbmltcG9ydCBTZWxlY3Rpb25CZWhhdmlvciBmcm9tICcuL1NlbGVjdGlvbkJlaGF2aW9yJztcblxuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdzZWxlY3Rpb25WaXN1YWxzJywgJ3NlbGVjdGlvbkJlaGF2aW9yJyBdLFxuICBfX2RlcGVuZHNfXzogW1xuICAgIEludGVyYWN0aW9uRXZlbnRzTW9kdWxlLFxuICAgIE91dGxpbmVNb2R1bGVcbiAgXSxcbiAgc2VsZWN0aW9uOiBbICd0eXBlJywgU2VsZWN0aW9uIF0sXG4gIHNlbGVjdGlvblZpc3VhbHM6IFsgJ3R5cGUnLCBTZWxlY3Rpb25WaXN1YWxzIF0sXG4gIHNlbGVjdGlvbkJlaGF2aW9yOiBbICd0eXBlJywgU2VsZWN0aW9uQmVoYXZpb3IgXVxufTtcbiIsImltcG9ydCBTbmFwQ29udGV4dCBmcm9tICcuL1NuYXBDb250ZXh0JztcclxuXHJcbmltcG9ydCB7XHJcbiAgZ2V0Q2hpbGRyZW4sXHJcbiAgaXNTbmFwcGVkLFxyXG4gIG1pZFxyXG59IGZyb20gJy4vU25hcFV0aWwnO1xyXG5cclxuaW1wb3J0IHsgaXNDbWQgfSBmcm9tICcuLi9rZXlib2FyZC9LZXlib2FyZFV0aWwnO1xyXG5cclxuaW1wb3J0IHtcclxuICBmb3JFYWNoLFxyXG4gIGlzTnVtYmVyXHJcbn0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxudmFyIEhJR0hFUl9QUklPUklUWSA9IDEyNTA7XHJcblxyXG5cclxuLyoqXHJcbiAqIFNuYXAgZHVyaW5nIGNyZWF0ZSBhbmQgbW92ZS5cclxuICpcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZWxlbWVudFJlZ2lzdHJ5XHJcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXHJcbiAqIEBwYXJhbSB7U25hcHBpbmd9IHNuYXBwaW5nXHJcbiAqL1xyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcmVhdGVNb3ZlU25hcHBpbmcoZWxlbWVudFJlZ2lzdHJ5LCBldmVudEJ1cywgc25hcHBpbmcpIHtcclxuICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcclxuXHJcbiAgZXZlbnRCdXMub24oW1xyXG4gICAgJ2NyZWF0ZS5zdGFydCcsXHJcbiAgICAnc2hhcGUubW92ZS5zdGFydCdcclxuICBdLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgc2VsZi5pbml0U25hcChldmVudCk7XHJcbiAgfSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKFtcclxuICAgICdjcmVhdGUubW92ZScsXHJcbiAgICAnY3JlYXRlLmVuZCcsXHJcbiAgICAnc2hhcGUubW92ZS5tb3ZlJyxcclxuICAgICdzaGFwZS5tb3ZlLmVuZCdcclxuICBdLCBISUdIRVJfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgICAgc2hhcGUgPSBjb250ZXh0LnNoYXBlLFxyXG4gICAgICAgIHNuYXBDb250ZXh0ID0gY29udGV4dC5zbmFwQ29udGV4dCxcclxuICAgICAgICB0YXJnZXQgPSBjb250ZXh0LnRhcmdldDtcclxuXHJcbiAgICBpZiAoZXZlbnQub3JpZ2luYWxFdmVudCAmJiBpc0NtZChldmVudC5vcmlnaW5hbEV2ZW50KSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzU25hcHBlZChldmVudCkgfHwgIXRhcmdldCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHNuYXBQb2ludHMgPSBzbmFwQ29udGV4dC5wb2ludHNGb3JUYXJnZXQodGFyZ2V0KTtcclxuXHJcbiAgICBpZiAoIXNuYXBQb2ludHMuaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgc25hcFBvaW50cyA9IHNlbGYuYWRkU25hcFRhcmdldFBvaW50cyhzbmFwUG9pbnRzLCBzaGFwZSwgdGFyZ2V0KTtcclxuXHJcbiAgICAgIHNuYXBQb2ludHMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIHNuYXBwaW5nLnNuYXAoZXZlbnQsIHNuYXBQb2ludHMpO1xyXG4gIH0pO1xyXG5cclxuICBldmVudEJ1cy5vbihbXHJcbiAgICAnY3JlYXRlLmNsZWFudXAnLFxyXG4gICAgJ3NoYXBlLm1vdmUuY2xlYW51cCdcclxuICBdLCBmdW5jdGlvbigpIHtcclxuICAgIHNuYXBwaW5nLmhpZGUoKTtcclxuICB9KTtcclxufVxyXG5cclxuQ3JlYXRlTW92ZVNuYXBwaW5nLiRpbmplY3QgPSBbXHJcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXHJcbiAgJ2V2ZW50QnVzJyxcclxuICAnc25hcHBpbmcnXHJcbl07XHJcblxyXG5DcmVhdGVNb3ZlU25hcHBpbmcucHJvdG90eXBlLmluaXRTbmFwID0gZnVuY3Rpb24oZXZlbnQpIHtcclxuICB2YXIgZWxlbWVudFJlZ2lzdHJ5ID0gdGhpcy5fZWxlbWVudFJlZ2lzdHJ5O1xyXG5cclxuICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQsXHJcbiAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcclxuICAgICAgc25hcENvbnRleHQgPSBjb250ZXh0LnNuYXBDb250ZXh0O1xyXG5cclxuICBpZiAoIXNuYXBDb250ZXh0KSB7XHJcbiAgICBzbmFwQ29udGV4dCA9IGNvbnRleHQuc25hcENvbnRleHQgPSBuZXcgU25hcENvbnRleHQoKTtcclxuICB9XHJcblxyXG4gIHZhciBzaGFwZU1pZDtcclxuXHJcbiAgaWYgKGVsZW1lbnRSZWdpc3RyeS5nZXQoc2hhcGUuaWQpKSB7XHJcblxyXG4gICAgLy8gbW92ZVxyXG4gICAgc2hhcGVNaWQgPSBtaWQoc2hhcGUsIGV2ZW50KTtcclxuICB9IGVsc2Uge1xyXG5cclxuICAgIC8vIGNyZWF0ZVxyXG4gICAgc2hhcGVNaWQgPSB7XHJcbiAgICAgIHg6IGV2ZW50LnggKyBtaWQoc2hhcGUpLngsXHJcbiAgICAgIHk6IGV2ZW50LnkgKyBtaWQoc2hhcGUpLnlcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICB2YXIgc2hhcGVUb3BMZWZ0ID0ge1xyXG4gICAgICAgIHg6IHNoYXBlTWlkLnggLSBzaGFwZS53aWR0aCAvIDIsXHJcbiAgICAgICAgeTogc2hhcGVNaWQueSAtIHNoYXBlLmhlaWdodCAvIDJcclxuICAgICAgfSxcclxuICAgICAgc2hhcGVCb3R0b21SaWdodCA9IHtcclxuICAgICAgICB4OiBzaGFwZU1pZC54ICsgc2hhcGUud2lkdGggLyAyLFxyXG4gICAgICAgIHk6IHNoYXBlTWlkLnkgKyBzaGFwZS5oZWlnaHQgLyAyXHJcbiAgICAgIH07XHJcblxyXG4gIHNuYXBDb250ZXh0LnNldFNuYXBPcmlnaW4oJ21pZCcsIHtcclxuICAgIHg6IHNoYXBlTWlkLnggLSBldmVudC54LFxyXG4gICAgeTogc2hhcGVNaWQueSAtIGV2ZW50LnlcclxuICB9KTtcclxuXHJcbiAgLy8gc25hcCBsYWJlbHMgdG8gbWlkIG9ubHlcclxuICBpZiAoaXNMYWJlbChzaGFwZSkpIHtcclxuICAgIHJldHVybiBzbmFwQ29udGV4dDtcclxuICB9XHJcblxyXG4gIHNuYXBDb250ZXh0LnNldFNuYXBPcmlnaW4oJ3RvcC1sZWZ0Jywge1xyXG4gICAgeDogc2hhcGVUb3BMZWZ0LnggLSBldmVudC54LFxyXG4gICAgeTogc2hhcGVUb3BMZWZ0LnkgLSBldmVudC55XHJcbiAgfSk7XHJcblxyXG4gIHNuYXBDb250ZXh0LnNldFNuYXBPcmlnaW4oJ2JvdHRvbS1yaWdodCcsIHtcclxuICAgIHg6IHNoYXBlQm90dG9tUmlnaHQueCAtIGV2ZW50LngsXHJcbiAgICB5OiBzaGFwZUJvdHRvbVJpZ2h0LnkgLSBldmVudC55XHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBzbmFwQ29udGV4dDtcclxufTtcclxuXHJcbkNyZWF0ZU1vdmVTbmFwcGluZy5wcm90b3R5cGUuYWRkU25hcFRhcmdldFBvaW50cyA9IGZ1bmN0aW9uKHNuYXBQb2ludHMsIHNoYXBlLCB0YXJnZXQpIHtcclxuICB2YXIgc25hcFRhcmdldHMgPSB0aGlzLmdldFNuYXBUYXJnZXRzKHNoYXBlLCB0YXJnZXQpO1xyXG5cclxuICBmb3JFYWNoKHNuYXBUYXJnZXRzLCBmdW5jdGlvbihzbmFwVGFyZ2V0KSB7XHJcblxyXG4gICAgLy8gaGFuZGxlIGxhYmVsc1xyXG4gICAgaWYgKGlzTGFiZWwoc25hcFRhcmdldCkpIHtcclxuXHJcbiAgICAgIGlmIChpc0xhYmVsKHNoYXBlKSkge1xyXG4gICAgICAgIHNuYXBQb2ludHMuYWRkKCdtaWQnLCBtaWQoc25hcFRhcmdldCkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaGFuZGxlIGNvbm5lY3Rpb25zXHJcbiAgICBpZiAoaXNDb25uZWN0aW9uKHNuYXBUYXJnZXQpKSB7XHJcblxyXG4gICAgICAvLyBpZ25vcmUgc2luZ2xlIHNlZ21lbnQgY29ubmVjdGlvbnNcclxuICAgICAgaWYgKHNuYXBUYXJnZXQud2F5cG9pbnRzLmxlbmd0aCA8IDMpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIGlnbm9yZSBmaXJzdCBhbmQgbGFzdCB3YXlwb2ludFxyXG4gICAgICB2YXIgd2F5cG9pbnRzID0gc25hcFRhcmdldC53YXlwb2ludHMuc2xpY2UoMSwgLTEpO1xyXG5cclxuICAgICAgZm9yRWFjaCh3YXlwb2ludHMsIGZ1bmN0aW9uKHdheXBvaW50KSB7XHJcbiAgICAgICAgc25hcFBvaW50cy5hZGQoJ21pZCcsIHdheXBvaW50KTtcclxuICAgICAgfSk7XHJcblxyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgLy8gaGFuZGxlIHNoYXBlc1xyXG4gICAgc25hcFBvaW50cy5hZGQoJ21pZCcsIG1pZChzbmFwVGFyZ2V0KSk7XHJcbiAgfSk7XHJcblxyXG4gIGlmICghaXNOdW1iZXIoc2hhcGUueCkgfHwgIWlzTnVtYmVyKHNoYXBlLnkpKSB7XHJcbiAgICByZXR1cm4gc25hcFBvaW50cztcclxuICB9XHJcblxyXG4gIC8vIHNuYXAgdG8gb3JpZ2luYWwgcG9zaXRpb24gd2hlbiBtb3ZpbmdcclxuICBpZiAodGhpcy5fZWxlbWVudFJlZ2lzdHJ5LmdldChzaGFwZS5pZCkpIHtcclxuICAgIHNuYXBQb2ludHMuYWRkKCdtaWQnLCBtaWQoc2hhcGUpKTtcclxuICB9XHJcblxyXG4gIHJldHVybiBzbmFwUG9pbnRzO1xyXG59O1xyXG5cclxuQ3JlYXRlTW92ZVNuYXBwaW5nLnByb3RvdHlwZS5nZXRTbmFwVGFyZ2V0cyA9IGZ1bmN0aW9uKHNoYXBlLCB0YXJnZXQpIHtcclxuICByZXR1cm4gZ2V0Q2hpbGRyZW4odGFyZ2V0KS5maWx0ZXIoZnVuY3Rpb24oY2hpbGQpIHtcclxuICAgIHJldHVybiAhaXNIaWRkZW4oY2hpbGQpO1xyXG4gIH0pO1xyXG59O1xyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBpc0Nvbm5lY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiAhIWVsZW1lbnQud2F5cG9pbnRzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0hpZGRlbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuICEhZWxlbWVudC5oaWRkZW47XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xyXG4gIHJldHVybiAhIWVsZW1lbnQubGFiZWxUYXJnZXQ7XHJcbn0iLCJpbXBvcnQgU25hcENvbnRleHQgZnJvbSAnLi9TbmFwQ29udGV4dCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIGJvdHRvbVJpZ2h0LFxyXG4gIGdldENoaWxkcmVuLFxyXG4gIGlzU25hcHBlZCxcclxuICBzZXRTbmFwcGVkLFxyXG4gIHRvcExlZnQsXHJcbn0gZnJvbSAnLi9TbmFwVXRpbCc7XHJcblxyXG5pbXBvcnQgeyBpc0NtZCB9IGZyb20gJy4uL2tleWJvYXJkL0tleWJvYXJkVXRpbCc7XHJcblxyXG5pbXBvcnQge1xyXG4gIGFzVFJCTCxcclxuICBnZXRNaWRcclxufSBmcm9tICcuLi8uLi9sYXlvdXQvTGF5b3V0VXRpbCc7XHJcblxyXG5pbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xyXG5cclxudmFyIEhJR0hFUl9QUklPUklUWSA9IDEyNTA7XHJcblxyXG5cclxuLyoqXHJcbiAqIFNuYXAgZHVyaW5nIHJlc2l6ZS5cclxuICpcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcclxuICogQHBhcmFtIHtTbmFwcGluZ30gc25hcHBpbmdcclxuICovXHJcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFJlc2l6ZVNuYXBwaW5nKGV2ZW50QnVzLCBzbmFwcGluZykge1xyXG4gIHZhciBzZWxmID0gdGhpcztcclxuXHJcbiAgZXZlbnRCdXMub24oWyAncmVzaXplLnN0YXJ0JyBdLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgc2VsZi5pbml0U25hcChldmVudCk7XHJcbiAgfSk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKFtcclxuICAgICdyZXNpemUubW92ZScsXHJcbiAgICAncmVzaXplLmVuZCcsXHJcbiAgXSwgSElHSEVSX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICAgIHNoYXBlID0gY29udGV4dC5zaGFwZSxcclxuICAgICAgICBwYXJlbnQgPSBzaGFwZS5wYXJlbnQsXHJcbiAgICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXHJcbiAgICAgICAgc25hcENvbnRleHQgPSBjb250ZXh0LnNuYXBDb250ZXh0O1xyXG5cclxuICAgIGlmIChldmVudC5vcmlnaW5hbEV2ZW50ICYmIGlzQ21kKGV2ZW50Lm9yaWdpbmFsRXZlbnQpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaXNTbmFwcGVkKGV2ZW50KSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHNuYXBQb2ludHMgPSBzbmFwQ29udGV4dC5wb2ludHNGb3JUYXJnZXQocGFyZW50KTtcclxuXHJcbiAgICBpZiAoIXNuYXBQb2ludHMuaW5pdGlhbGl6ZWQpIHtcclxuICAgICAgc25hcFBvaW50cyA9IHNlbGYuYWRkU25hcFRhcmdldFBvaW50cyhzbmFwUG9pbnRzLCBzaGFwZSwgcGFyZW50LCBkaXJlY3Rpb24pO1xyXG5cclxuICAgICAgc25hcFBvaW50cy5pbml0aWFsaXplZCA9IHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzSG9yaXpvbnRhbChkaXJlY3Rpb24pKSB7XHJcbiAgICAgIHNldFNuYXBwZWQoZXZlbnQsICd4JywgZXZlbnQueCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzVmVydGljYWwoZGlyZWN0aW9uKSkge1xyXG4gICAgICBzZXRTbmFwcGVkKGV2ZW50LCAneScsIGV2ZW50LnkpO1xyXG4gICAgfVxyXG5cclxuICAgIHNuYXBwaW5nLnNuYXAoZXZlbnQsIHNuYXBQb2ludHMpO1xyXG4gIH0pO1xyXG5cclxuICBldmVudEJ1cy5vbihbICdyZXNpemUuY2xlYW51cCcgXSwgZnVuY3Rpb24oKSB7XHJcbiAgICBzbmFwcGluZy5oaWRlKCk7XHJcbiAgfSk7XHJcbn1cclxuXHJcblJlc2l6ZVNuYXBwaW5nLnByb3RvdHlwZS5pbml0U25hcCA9IGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxyXG4gICAgICBzaGFwZSA9IGNvbnRleHQuc2hhcGUsXHJcbiAgICAgIGRpcmVjdGlvbiA9IGNvbnRleHQuZGlyZWN0aW9uLFxyXG4gICAgICBzbmFwQ29udGV4dCA9IGNvbnRleHQuc25hcENvbnRleHQ7XHJcblxyXG4gIGlmICghc25hcENvbnRleHQpIHtcclxuICAgIHNuYXBDb250ZXh0ID0gY29udGV4dC5zbmFwQ29udGV4dCA9IG5ldyBTbmFwQ29udGV4dCgpO1xyXG4gIH1cclxuXHJcbiAgdmFyIHNuYXBPcmlnaW4gPSBnZXRTbmFwT3JpZ2luKHNoYXBlLCBkaXJlY3Rpb24pO1xyXG5cclxuICBzbmFwQ29udGV4dC5zZXRTbmFwT3JpZ2luKCdjb3JuZXInLCB7XHJcbiAgICB4OiBzbmFwT3JpZ2luLnggLSBldmVudC54LFxyXG4gICAgeTogc25hcE9yaWdpbi55IC0gZXZlbnQueVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gc25hcENvbnRleHQ7XHJcbn07XHJcblxyXG5SZXNpemVTbmFwcGluZy5wcm90b3R5cGUuYWRkU25hcFRhcmdldFBvaW50cyA9IGZ1bmN0aW9uKHNuYXBQb2ludHMsIHNoYXBlLCB0YXJnZXQsIGRpcmVjdGlvbikge1xyXG4gIHZhciBzbmFwVGFyZ2V0cyA9IHRoaXMuZ2V0U25hcFRhcmdldHMoc2hhcGUsIHRhcmdldCk7XHJcblxyXG4gIGZvckVhY2goc25hcFRhcmdldHMsIGZ1bmN0aW9uKHNuYXBUYXJnZXQpIHtcclxuICAgIHNuYXBQb2ludHMuYWRkKCdjb3JuZXInLCBib3R0b21SaWdodChzbmFwVGFyZ2V0KSk7XHJcbiAgICBzbmFwUG9pbnRzLmFkZCgnY29ybmVyJywgdG9wTGVmdChzbmFwVGFyZ2V0KSk7XHJcbiAgfSk7XHJcblxyXG4gIHNuYXBQb2ludHMuYWRkKCdjb3JuZXInLCBnZXRTbmFwT3JpZ2luKHNoYXBlLCBkaXJlY3Rpb24pKTtcclxuXHJcbiAgcmV0dXJuIHNuYXBQb2ludHM7XHJcbn07XHJcblxyXG5SZXNpemVTbmFwcGluZy4kaW5qZWN0ID0gW1xyXG4gICdldmVudEJ1cycsXHJcbiAgJ3NuYXBwaW5nJ1xyXG5dO1xyXG5cclxuUmVzaXplU25hcHBpbmcucHJvdG90eXBlLmdldFNuYXBUYXJnZXRzID0gZnVuY3Rpb24oc2hhcGUsIHRhcmdldCkge1xyXG4gIHJldHVybiBnZXRDaGlsZHJlbih0YXJnZXQpLmZpbHRlcihmdW5jdGlvbihjaGlsZCkge1xyXG4gICAgcmV0dXJuICFpc0F0dGFjaGVkKGNoaWxkLCBzaGFwZSlcclxuICAgICAgJiYgIWlzQ29ubmVjdGlvbihjaGlsZClcclxuICAgICAgJiYgIWlzSGlkZGVuKGNoaWxkKVxyXG4gICAgICAmJiAhaXNMYWJlbChjaGlsZCk7XHJcbiAgfSk7XHJcbn07XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIGdldFNuYXBPcmlnaW4oc2hhcGUsIGRpcmVjdGlvbikge1xyXG4gIHZhciBtaWQgPSBnZXRNaWQoc2hhcGUpLFxyXG4gICAgICB0cmJsID0gYXNUUkJMKHNoYXBlKTtcclxuXHJcbiAgdmFyIHNuYXBPcmlnaW4gPSB7XHJcbiAgICB4OiBtaWQueCxcclxuICAgIHk6IG1pZC55XHJcbiAgfTtcclxuXHJcbiAgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCduJykgIT09IC0xKSB7XHJcbiAgICBzbmFwT3JpZ2luLnkgPSB0cmJsLnRvcDtcclxuICB9IGVsc2UgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCdzJykgIT09IC0xKSB7XHJcbiAgICBzbmFwT3JpZ2luLnkgPSB0cmJsLmJvdHRvbTtcclxuICB9XHJcblxyXG4gIGlmIChkaXJlY3Rpb24uaW5kZXhPZignZScpICE9PSAtMSkge1xyXG4gICAgc25hcE9yaWdpbi54ID0gdHJibC5yaWdodDtcclxuICB9IGVsc2UgaWYgKGRpcmVjdGlvbi5pbmRleE9mKCd3JykgIT09IC0xKSB7XHJcbiAgICBzbmFwT3JpZ2luLnggPSB0cmJsLmxlZnQ7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gc25hcE9yaWdpbjtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNBdHRhY2hlZChlbGVtZW50LCBob3N0KSB7XHJcbiAgcmV0dXJuIGVsZW1lbnQuaG9zdCA9PT0gaG9zdDtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gISFlbGVtZW50LndheXBvaW50cztcclxufVxyXG5cclxuZnVuY3Rpb24gaXNIaWRkZW4oZWxlbWVudCkge1xyXG4gIHJldHVybiAhIWVsZW1lbnQuaGlkZGVuO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0xhYmVsKGVsZW1lbnQpIHtcclxuICByZXR1cm4gISFlbGVtZW50LmxhYmVsVGFyZ2V0O1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0hvcml6b250YWwoZGlyZWN0aW9uKSB7XHJcbiAgcmV0dXJuIGRpcmVjdGlvbiA9PT0gJ24nIHx8IGRpcmVjdGlvbiA9PT0gJ3MnO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc1ZlcnRpY2FsKGRpcmVjdGlvbikge1xyXG4gIHJldHVybiBkaXJlY3Rpb24gPT09ICdlJyB8fCBkaXJlY3Rpb24gPT09ICd3JztcclxufSIsImltcG9ydCB7XG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBzbmFwVG9cbn0gZnJvbSAnLi9TbmFwVXRpbCc7XG5cblxuLyoqXG4gKiBBIHNuYXAgY29udGV4dCwgY29udGFpbmluZyB0aGUgKHBvc3NpYmx5IGluY29tcGxldGUpXG4gKiBtYXBwaW5ncyBvZiBkcm9wIHRhcmdldHMgKHRvIGlkZW50aWZ5IHRoZSBzbmFwcGluZylcbiAqIHRvIGNvbXB1dGVkIHNuYXAgcG9pbnRzLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBTbmFwQ29udGV4dCgpIHtcblxuICAvKipcbiAgICogTWFwPFN0cmluZywgU25hcFBvaW50cz4gbWFwcGluZyBkcm9wIHRhcmdldHMgdG9cbiAgICogYSBsaXN0IG9mIHBvc3NpYmxlIHNuYXBwaW5ncy5cbiAgICpcbiAgICogQHR5cGUge09iamVjdH1cbiAgICovXG4gIHRoaXMuX3RhcmdldHMgPSB7fTtcblxuICAvKipcbiAgICogTWFwPFN0cmluZywgUG9pbnQ+IGluaXRpYWwgcG9zaXRpb25pbmcgb2YgZWxlbWVudFxuICAgKiByZWdhcmRpbmcgdmFyaW91cyBzbmFwIGRpcmVjdGlvbnMuXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLl9zbmFwT3JpZ2lucyA9IHt9O1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIHNuYXAgbG9jYXRpb25zXG4gICAqXG4gICAqIEB0eXBlIHtBcnJheTxzdHJpbmc+fVxuICAgKi9cbiAgdGhpcy5fc25hcExvY2F0aW9ucyA9IFtdO1xuXG4gIC8qKlxuICAgKiBNYXA8U3RyaW5nLCBBcnJheTxQb2ludD4+IG9mIGRlZmF1bHQgc25hcHBpbmcgbG9jYXRpb25zXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLl9kZWZhdWx0U25hcHMgPSB7fTtcbn1cblxuXG5TbmFwQ29udGV4dC5wcm90b3R5cGUuZ2V0U25hcE9yaWdpbiA9IGZ1bmN0aW9uKHNuYXBMb2NhdGlvbikge1xuICByZXR1cm4gdGhpcy5fc25hcE9yaWdpbnNbc25hcExvY2F0aW9uXTtcbn07XG5cblxuU25hcENvbnRleHQucHJvdG90eXBlLnNldFNuYXBPcmlnaW4gPSBmdW5jdGlvbihzbmFwTG9jYXRpb24sIGluaXRpYWxWYWx1ZSkge1xuICB0aGlzLl9zbmFwT3JpZ2luc1tzbmFwTG9jYXRpb25dID0gaW5pdGlhbFZhbHVlO1xuXG4gIGlmICh0aGlzLl9zbmFwTG9jYXRpb25zLmluZGV4T2Yoc25hcExvY2F0aW9uKSA9PT0gLTEpIHtcbiAgICB0aGlzLl9zbmFwTG9jYXRpb25zLnB1c2goc25hcExvY2F0aW9uKTtcbiAgfVxufTtcblxuXG5TbmFwQ29udGV4dC5wcm90b3R5cGUuYWRkRGVmYXVsdFNuYXAgPSBmdW5jdGlvbih0eXBlLCBwb2ludCkge1xuXG4gIHZhciBzbmFwVmFsdWVzID0gdGhpcy5fZGVmYXVsdFNuYXBzW3R5cGVdO1xuXG4gIGlmICghc25hcFZhbHVlcykge1xuICAgIHNuYXBWYWx1ZXMgPSB0aGlzLl9kZWZhdWx0U25hcHNbdHlwZV0gPSBbXTtcbiAgfVxuXG4gIHNuYXBWYWx1ZXMucHVzaChwb2ludCk7XG59O1xuXG4vKipcbiAqIFJldHVybiBhIG51bWJlciBvZiBpbml0aWFsaXplZCBzbmFwcywgaS5lLiBzbmFwIGxvY2F0aW9ucyBzdWNoIGFzXG4gKiB0b3AtbGVmdCwgbWlkLCBib3R0b20tcmlnaHQgYW5kIHNvIGZvcnRoLlxuICpcbiAqIEByZXR1cm4ge0FycmF5PHN0cmluZz59IHNuYXBMb2NhdGlvbnNcbiAqL1xuU25hcENvbnRleHQucHJvdG90eXBlLmdldFNuYXBMb2NhdGlvbnMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX3NuYXBMb2NhdGlvbnM7XG59O1xuXG4vKipcbiAqIFNldCB0aGUgc25hcCBsb2NhdGlvbnMgZm9yIHRoaXMgY29udGV4dC5cbiAqXG4gKiBUaGUgb3JkZXIgb2YgbG9jYXRpb25zIGRldGVybWluZXMgcHJlY2VkZW5jZS5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IHNuYXBMb2NhdGlvbnNcbiAqL1xuU25hcENvbnRleHQucHJvdG90eXBlLnNldFNuYXBMb2NhdGlvbnMgPSBmdW5jdGlvbihzbmFwTG9jYXRpb25zKSB7XG4gIHRoaXMuX3NuYXBMb2NhdGlvbnMgPSBzbmFwTG9jYXRpb25zO1xufTtcblxuLyoqXG4gKiBHZXQgc25hcCBwb2ludHMgZm9yIGEgZ2l2ZW4gdGFyZ2V0XG4gKlxuICogQHBhcmFtIHtFbGVtZW50fHN0cmluZ30gdGFyZ2V0XG4gKi9cblNuYXBDb250ZXh0LnByb3RvdHlwZS5wb2ludHNGb3JUYXJnZXQgPSBmdW5jdGlvbih0YXJnZXQpIHtcblxuICB2YXIgdGFyZ2V0SWQgPSB0YXJnZXQuaWQgfHwgdGFyZ2V0O1xuXG4gIHZhciBzbmFwUG9pbnRzID0gdGhpcy5fdGFyZ2V0c1t0YXJnZXRJZF07XG5cbiAgaWYgKCFzbmFwUG9pbnRzKSB7XG4gICAgc25hcFBvaW50cyA9IHRoaXMuX3RhcmdldHNbdGFyZ2V0SWRdID0gbmV3IFNuYXBQb2ludHMoKTtcbiAgICBzbmFwUG9pbnRzLmluaXREZWZhdWx0cyh0aGlzLl9kZWZhdWx0U25hcHMpO1xuICB9XG5cbiAgcmV0dXJuIHNuYXBQb2ludHM7XG59O1xuXG5cbi8qKlxuICogQ3JlYXRlcyB0aGUgc25hcCBwb2ludHMgYW5kIGluaXRpYWxpemVzIHRoZW0gd2l0aCB0aGVcbiAqIGdpdmVuIGRlZmF1bHQgdmFsdWVzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0PHN0cmluZywgQXJyYXk8UG9pbnQ+Pn0gW2RlZmF1bHRQb2ludHNdXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBTbmFwUG9pbnRzKGRlZmF1bHRTbmFwcykge1xuXG4gIC8qKlxuICAgKiBNYXA8U3RyaW5nLCBNYXA8KHh8eSksIEFycmF5PG51bWJlcj4+PiBtYXBwaW5nIHNuYXAgbG9jYXRpb25zLFxuICAgKiBpLmUuIHRvcC1sZWZ0LCBib3R0b20tcmlnaHQsIGNlbnRlciB0byBhY3R1YWwgc25hcCB2YWx1ZXMuXG4gICAqXG4gICAqIEB0eXBlIHtPYmplY3R9XG4gICAqL1xuICB0aGlzLl9zbmFwVmFsdWVzID0ge307XG59XG5cblNuYXBQb2ludHMucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKHNuYXBMb2NhdGlvbiwgcG9pbnQpIHtcblxuICB2YXIgc25hcFZhbHVlcyA9IHRoaXMuX3NuYXBWYWx1ZXNbc25hcExvY2F0aW9uXTtcblxuICBpZiAoIXNuYXBWYWx1ZXMpIHtcbiAgICBzbmFwVmFsdWVzID0gdGhpcy5fc25hcFZhbHVlc1tzbmFwTG9jYXRpb25dID0geyB4OiBbXSwgeTogW10gfTtcbiAgfVxuXG4gIGlmIChzbmFwVmFsdWVzLnguaW5kZXhPZihwb2ludC54KSA9PT0gLTEpIHtcbiAgICBzbmFwVmFsdWVzLngucHVzaChwb2ludC54KTtcbiAgfVxuXG4gIGlmIChzbmFwVmFsdWVzLnkuaW5kZXhPZihwb2ludC55KSA9PT0gLTEpIHtcbiAgICBzbmFwVmFsdWVzLnkucHVzaChwb2ludC55KTtcbiAgfVxufTtcblxuXG5TbmFwUG9pbnRzLnByb3RvdHlwZS5zbmFwID0gZnVuY3Rpb24ocG9pbnQsIHNuYXBMb2NhdGlvbiwgYXhpcywgdG9sZXJhbmNlKSB7XG4gIHZhciBzbmFwcGluZ1ZhbHVlcyA9IHRoaXMuX3NuYXBWYWx1ZXNbc25hcExvY2F0aW9uXTtcblxuICByZXR1cm4gc25hcHBpbmdWYWx1ZXMgJiYgc25hcFRvKHBvaW50W2F4aXNdLCBzbmFwcGluZ1ZhbHVlc1theGlzXSwgdG9sZXJhbmNlKTtcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG51bWJlciBvZiBkZWZhdWx0IHNuYXBwaW5nIHBvaW50cy5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IGRlZmF1bHRTbmFwc1xuICovXG5TbmFwUG9pbnRzLnByb3RvdHlwZS5pbml0RGVmYXVsdHMgPSBmdW5jdGlvbihkZWZhdWx0U25hcHMpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZm9yRWFjaChkZWZhdWx0U25hcHMgfHwge30sIGZ1bmN0aW9uKHNuYXBQb2ludHMsIHNuYXBMb2NhdGlvbikge1xuICAgIGZvckVhY2goc25hcFBvaW50cywgZnVuY3Rpb24ocG9pbnQpIHtcbiAgICAgIHNlbGYuYWRkKHNuYXBMb2NhdGlvbiwgcG9pbnQpO1xuICAgIH0pO1xuICB9KTtcbn07IiwidmFyIGFicyA9IE1hdGguYWJzLFxuICAgIHJvdW5kID0gTWF0aC5yb3VuZDtcblxuXG4vKipcbiAqIFNuYXAgdmFsdWUgdG8gYSBjb2xsZWN0aW9uIG9mIHJlZmVyZW5jZSB2YWx1ZXMuXG4gKlxuICogQHBhcmFtICB7bnVtYmVyfSB2YWx1ZVxuICogQHBhcmFtICB7QXJyYXk8bnVtYmVyPn0gdmFsdWVzXG4gKiBAcGFyYW0gIHtudW1iZXJ9IFt0b2xlcmFuY2U9MTBdXG4gKlxuICogQHJldHVybiB7bnVtYmVyfSB0aGUgdmFsdWUgd2Ugc25hcHBlZCB0byBvciBudWxsLCBpZiBub25lIHNuYXBwZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNuYXBUbyh2YWx1ZSwgdmFsdWVzLCB0b2xlcmFuY2UpIHtcbiAgdG9sZXJhbmNlID0gdG9sZXJhbmNlID09PSB1bmRlZmluZWQgPyAxMCA6IHRvbGVyYW5jZTtcblxuICB2YXIgaWR4LCBzbmFwVmFsdWU7XG5cbiAgZm9yIChpZHggPSAwOyBpZHggPCB2YWx1ZXMubGVuZ3RoOyBpZHgrKykge1xuICAgIHNuYXBWYWx1ZSA9IHZhbHVlc1tpZHhdO1xuXG4gICAgaWYgKGFicyhzbmFwVmFsdWUgLSB2YWx1ZSkgPD0gdG9sZXJhbmNlKSB7XG4gICAgICByZXR1cm4gc25hcFZhbHVlO1xuICAgIH1cbiAgfVxufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiB0b3BMZWZ0KGJvdW5kcykge1xuICByZXR1cm4ge1xuICAgIHg6IGJvdW5kcy54LFxuICAgIHk6IGJvdW5kcy55XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b3BSaWdodChib3VuZHMpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBib3VuZHMueCArIGJvdW5kcy53aWR0aCxcbiAgICB5OiBib3VuZHMueVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gYm90dG9tTGVmdChib3VuZHMpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBib3VuZHMueCxcbiAgICB5OiBib3VuZHMueSArIGJvdW5kcy5oZWlnaHRcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJvdHRvbVJpZ2h0KGJvdW5kcykge1xuICByZXR1cm4ge1xuICAgIHg6IGJvdW5kcy54ICsgYm91bmRzLndpZHRoLFxuICAgIHk6IGJvdW5kcy55ICsgYm91bmRzLmhlaWdodFxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWlkKGJvdW5kcywgZGVmYXVsdFZhbHVlKSB7XG5cbiAgaWYgKCFib3VuZHMgfHwgaXNOYU4oYm91bmRzLngpIHx8IGlzTmFOKGJvdW5kcy55KSkge1xuICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHg6IHJvdW5kKGJvdW5kcy54ICsgYm91bmRzLndpZHRoIC8gMiksXG4gICAgeTogcm91bmQoYm91bmRzLnkgKyBib3VuZHMuaGVpZ2h0IC8gMilcbiAgfTtcbn1cblxuXG4vKipcbiAqIFJldHJpZXZlIHRoZSBzbmFwIHN0YXRlIG9mIHRoZSBnaXZlbiBldmVudC5cbiAqXG4gKiBAcGFyYW0gIHtFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSAge3N0cmluZ30gYXhpc1xuICpcbiAqIEByZXR1cm4ge2Jvb2xlYW59IHRoZSBzbmFwcGVkIHN0YXRlXG4gKlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTbmFwcGVkKGV2ZW50LCBheGlzKSB7XG4gIHZhciBzbmFwcGVkID0gZXZlbnQuc25hcHBlZDtcblxuICBpZiAoIXNuYXBwZWQpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBpZiAodHlwZW9mIGF4aXMgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHNuYXBwZWRbYXhpc107XG4gIH1cblxuICByZXR1cm4gc25hcHBlZC54ICYmIHNuYXBwZWQueTtcbn1cblxuXG4vKipcbiAqIFNldCB0aGUgZ2l2ZW4gZXZlbnQgYXMgc25hcHBlZC5cbiAqXG4gKiBUaGlzIG1ldGhvZCBtYXkgY2hhbmdlIHRoZSB4IGFuZC9vciB5IHBvc2l0aW9uIG9mIHRoZSBzaGFwZVxuICogZnJvbSB0aGUgZ2l2ZW4gZXZlbnQhXG4gKlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7c3RyaW5nfSBheGlzXG4gKiBAcGFyYW0ge251bWJlcnxib29sZWFufSB2YWx1ZVxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gb2xkIHZhbHVlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRTbmFwcGVkKGV2ZW50LCBheGlzLCB2YWx1ZSkge1xuICBpZiAodHlwZW9mIGF4aXMgIT09ICdzdHJpbmcnKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdheGlzIG11c3QgYmUgaW4gW3gsIHldJyk7XG4gIH1cblxuICBpZiAodHlwZW9mIHZhbHVlICE9PSAnbnVtYmVyJyAmJiB2YWx1ZSAhPT0gZmFsc2UpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3ZhbHVlIG11c3QgYmUgTnVtYmVyIG9yIGZhbHNlJyk7XG4gIH1cblxuICB2YXIgZGVsdGEsXG4gICAgICBwcmV2aW91c1ZhbHVlID0gZXZlbnRbYXhpc107XG5cbiAgdmFyIHNuYXBwZWQgPSBldmVudC5zbmFwcGVkID0gKGV2ZW50LnNuYXBwZWQgfHwge30pO1xuXG5cbiAgaWYgKHZhbHVlID09PSBmYWxzZSkge1xuICAgIHNuYXBwZWRbYXhpc10gPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICBzbmFwcGVkW2F4aXNdID0gdHJ1ZTtcblxuICAgIGRlbHRhID0gdmFsdWUgLSBwcmV2aW91c1ZhbHVlO1xuXG4gICAgZXZlbnRbYXhpc10gKz0gZGVsdGE7XG4gICAgZXZlbnRbJ2QnICsgYXhpc10gKz0gZGVsdGE7XG4gIH1cblxuICByZXR1cm4gcHJldmlvdXNWYWx1ZTtcbn1cblxuLyoqXG4gKiBHZXQgY2hpbGRyZW4gb2YgYSBzaGFwZS5cbiAqXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5TaGFwZX0gcGFyZW50XG4gKlxuICogQHJldHVybnMge0FycmF5PGRqcy5tb2RlbC5TaGFwZXxkanMubW9kZWwuQ29ubmVjdGlvbj59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDaGlsZHJlbihwYXJlbnQpIHtcbiAgcmV0dXJuIHBhcmVudC5jaGlsZHJlbiB8fCBbXTtcbn0iLCJpbXBvcnQge1xuICBiaW5kLFxuICBkZWJvdW5jZSxcbiAgZm9yRWFjaCxcbiAgaXNOdW1iZXIsXG4gIGlzT2JqZWN0XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgaXNTbmFwcGVkLFxuICBzZXRTbmFwcGVkXG59IGZyb20gJy4vU25hcFV0aWwnO1xuXG5pbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNsYXNzZXMgYXMgc3ZnQ2xhc3NlcyxcbiAgY3JlYXRlIGFzIHN2Z0NyZWF0ZVxufSBmcm9tICd0aW55LXN2Zyc7XG5cbnZhciBTTkFQX1RPTEVSQU5DRSA9IDc7XG5cbmV4cG9ydCB2YXIgU05BUF9MSU5FX0hJREVfREVMQVkgPSAxMDAwO1xuXG5cbi8qKlxuICogR2VuZXJpYyBzbmFwcGluZyBmZWF0dXJlLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNuYXBwaW5nKGNhbnZhcykge1xuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG5cbiAgLy8gZGVsYXkgaGlkZSBieSAxMDAwIHNlY29uZHMgc2luY2UgbGFzdCBzbmFwXG4gIHRoaXMuX2FzeW5jSGlkZSA9IGRlYm91bmNlKGJpbmQodGhpcy5oaWRlLCB0aGlzKSwgU05BUF9MSU5FX0hJREVfREVMQVkpO1xufVxuXG5TbmFwcGluZy4kaW5qZWN0ID0gWyAnY2FudmFzJyBdO1xuXG4vKipcbiAqIFNuYXAgYW4gZXZlbnQgdG8gZ2l2ZW4gc25hcCBwb2ludHMuXG4gKlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnRcbiAqIEBwYXJhbSB7U25hcFBvaW50c30gc25hcFBvaW50c1xuICovXG5TbmFwcGluZy5wcm90b3R5cGUuc25hcCA9IGZ1bmN0aW9uKGV2ZW50LCBzbmFwUG9pbnRzKSB7XG4gIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgIHNuYXBDb250ZXh0ID0gY29udGV4dC5zbmFwQ29udGV4dCxcbiAgICAgIHNuYXBMb2NhdGlvbnMgPSBzbmFwQ29udGV4dC5nZXRTbmFwTG9jYXRpb25zKCk7XG5cbiAgdmFyIHNuYXBwaW5nID0ge1xuICAgIHg6IGlzU25hcHBlZChldmVudCwgJ3gnKSxcbiAgICB5OiBpc1NuYXBwZWQoZXZlbnQsICd5JylcbiAgfTtcblxuICBmb3JFYWNoKHNuYXBMb2NhdGlvbnMsIGZ1bmN0aW9uKGxvY2F0aW9uKSB7XG4gICAgdmFyIHNuYXBPcmlnaW4gPSBzbmFwQ29udGV4dC5nZXRTbmFwT3JpZ2luKGxvY2F0aW9uKTtcblxuICAgIHZhciBzbmFwQ3VycmVudCA9IHtcbiAgICAgIHg6IGV2ZW50LnggKyBzbmFwT3JpZ2luLngsXG4gICAgICB5OiBldmVudC55ICsgc25hcE9yaWdpbi55XG4gICAgfTtcblxuICAgIC8vIHNuYXAgYm90aCBheGlzIGlmIG5vdCBzbmFwcGVkIGFscmVhZHlcbiAgICBmb3JFYWNoKFsgJ3gnLCAneScgXSwgZnVuY3Rpb24oYXhpcykge1xuICAgICAgdmFyIGxvY2F0aW9uU25hcHBpbmc7XG5cbiAgICAgIGlmICghc25hcHBpbmdbYXhpc10pIHtcbiAgICAgICAgbG9jYXRpb25TbmFwcGluZyA9IHNuYXBQb2ludHMuc25hcChzbmFwQ3VycmVudCwgbG9jYXRpb24sIGF4aXMsIFNOQVBfVE9MRVJBTkNFKTtcblxuICAgICAgICBpZiAobG9jYXRpb25TbmFwcGluZyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgc25hcHBpbmdbYXhpc10gPSB7XG4gICAgICAgICAgICB2YWx1ZTogbG9jYXRpb25TbmFwcGluZyxcbiAgICAgICAgICAgIG9yaWdpblZhbHVlOiBsb2NhdGlvblNuYXBwaW5nIC0gc25hcE9yaWdpbltheGlzXVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIG5vIG5lZWQgdG8gY29udGludWUgc25hcHBpbmdcbiAgICBpZiAoc25hcHBpbmcueCAmJiBzbmFwcGluZy55KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9KTtcblxuICAvLyBzaG93IHNuYXAgbGluZXNcbiAgdGhpcy5zaG93U25hcExpbmUoJ3ZlcnRpY2FsJywgc25hcHBpbmcueCAmJiBzbmFwcGluZy54LnZhbHVlKTtcbiAgdGhpcy5zaG93U25hcExpbmUoJ2hvcml6b250YWwnLCBzbmFwcGluZy55ICYmIHNuYXBwaW5nLnkudmFsdWUpO1xuXG4gIC8vIHNuYXAgZXZlbnRcbiAgZm9yRWFjaChbICd4JywgJ3knIF0sIGZ1bmN0aW9uKGF4aXMpIHtcbiAgICB2YXIgYXhpc1NuYXBwaW5nID0gc25hcHBpbmdbYXhpc107XG5cbiAgICBpZiAoaXNPYmplY3QoYXhpc1NuYXBwaW5nKSkge1xuICAgICAgc2V0U25hcHBlZChldmVudCwgYXhpcywgYXhpc1NuYXBwaW5nLm9yaWdpblZhbHVlKTtcbiAgICB9XG4gIH0pO1xufTtcblxuU25hcHBpbmcucHJvdG90eXBlLl9jcmVhdGVMaW5lID0gZnVuY3Rpb24ob3JpZW50YXRpb24pIHtcbiAgdmFyIHJvb3QgPSB0aGlzLl9jYW52YXMuZ2V0TGF5ZXIoJ3NuYXAnKTtcblxuICB2YXIgbGluZSA9IHN2Z0NyZWF0ZSgncGF0aCcpO1xuXG4gIHN2Z0F0dHIobGluZSwgeyBkOiAnTTAsMCBMMCwwJyB9KTtcblxuICBzdmdDbGFzc2VzKGxpbmUpLmFkZCgnZGpzLXNuYXAtbGluZScpO1xuXG4gIHN2Z0FwcGVuZChyb290LCBsaW5lKTtcblxuICByZXR1cm4ge1xuICAgIHVwZGF0ZTogZnVuY3Rpb24ocG9zaXRpb24pIHtcblxuICAgICAgaWYgKCFpc051bWJlcihwb3NpdGlvbikpIHtcbiAgICAgICAgc3ZnQXR0cihsaW5lLCB7IGRpc3BsYXk6ICdub25lJyB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChvcmllbnRhdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICAgICAgc3ZnQXR0cihsaW5lLCB7XG4gICAgICAgICAgICBkOiAnTS0xMDAwMDAsJyArIHBvc2l0aW9uICsgJyBMKzEwMDAwMCwnICsgcG9zaXRpb24sXG4gICAgICAgICAgICBkaXNwbGF5OiAnJ1xuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHN2Z0F0dHIobGluZSwge1xuICAgICAgICAgICAgZDogJ00gJyArIHBvc2l0aW9uICsgJywtMTAwMDAwIEwgJyArIHBvc2l0aW9uICsgJywgKzEwMDAwMCcsXG4gICAgICAgICAgICBkaXNwbGF5OiAnJ1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9O1xufTtcblxuU25hcHBpbmcucHJvdG90eXBlLl9jcmVhdGVTbmFwTGluZXMgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fc25hcExpbmVzID0ge1xuICAgIGhvcml6b250YWw6IHRoaXMuX2NyZWF0ZUxpbmUoJ2hvcml6b250YWwnKSxcbiAgICB2ZXJ0aWNhbDogdGhpcy5fY3JlYXRlTGluZSgndmVydGljYWwnKVxuICB9O1xufTtcblxuU25hcHBpbmcucHJvdG90eXBlLnNob3dTbmFwTGluZSA9IGZ1bmN0aW9uKG9yaWVudGF0aW9uLCBwb3NpdGlvbikge1xuXG4gIHZhciBsaW5lID0gdGhpcy5nZXRTbmFwTGluZShvcmllbnRhdGlvbik7XG5cbiAgaWYgKGxpbmUpIHtcbiAgICBsaW5lLnVwZGF0ZShwb3NpdGlvbik7XG4gIH1cblxuICB0aGlzLl9hc3luY0hpZGUoKTtcbn07XG5cblNuYXBwaW5nLnByb3RvdHlwZS5nZXRTbmFwTGluZSA9IGZ1bmN0aW9uKG9yaWVudGF0aW9uKSB7XG4gIGlmICghdGhpcy5fc25hcExpbmVzKSB7XG4gICAgdGhpcy5fY3JlYXRlU25hcExpbmVzKCk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fc25hcExpbmVzW29yaWVudGF0aW9uXTtcbn07XG5cblNuYXBwaW5nLnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24oKSB7XG4gIGZvckVhY2godGhpcy5fc25hcExpbmVzLCBmdW5jdGlvbihzbmFwTGluZSkge1xuICAgIHNuYXBMaW5lLnVwZGF0ZSgpO1xuICB9KTtcbn07XG4iLCJpbXBvcnQgQ3JlYXRlTW92ZVNuYXBwaW5nIGZyb20gJy4vQ3JlYXRlTW92ZVNuYXBwaW5nJztcbmltcG9ydCBSZXNpemVTbmFwcGluZyBmcm9tICcuL1Jlc2l6ZVNuYXBwaW5nJztcbmltcG9ydCBTbmFwcGluZyBmcm9tICcuL1NuYXBwaW5nJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogW1xuICAgICdjcmVhdGVNb3ZlU25hcHBpbmcnLFxuICAgICdyZXNpemVTbmFwcGluZycsXG4gICAgJ3NuYXBwaW5nJ1xuICBdLFxuICBjcmVhdGVNb3ZlU25hcHBpbmc6IFsgJ3R5cGUnLCBDcmVhdGVNb3ZlU25hcHBpbmcgXSxcbiAgcmVzaXplU25hcHBpbmc6IFsgJ3R5cGUnLCBSZXNpemVTbmFwcGluZyBdLFxuICBzbmFwcGluZzogWyAndHlwZScsIFNuYXBwaW5nIF1cbn07IiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaWx0ZXIsXG4gIGZvckVhY2gsXG4gIGlzTnVtYmVyXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHsgYXNUUkJMIH0gZnJvbSAnLi4vLi4vbGF5b3V0L0xheW91dFV0aWwnO1xuXG5pbXBvcnQgeyBnZXRCQm94IH0gZnJvbSAnLi4vLi4vdXRpbC9FbGVtZW50cyc7XG5cbmltcG9ydCB7IGdldERpcmVjdGlvbiB9IGZyb20gJy4vU3BhY2VVdGlsJztcblxuaW1wb3J0IHsgaGFzUHJpbWFyeU1vZGlmaWVyIH0gZnJvbSAnLi4vLi4vdXRpbC9Nb3VzZSc7XG5cbmltcG9ydCB7IHNldCBhcyBzZXRDdXJzb3IgfSBmcm9tICcuLi8uLi91dGlsL0N1cnNvcic7XG5cbmltcG9ydCB7IHNlbGZBbmRBbGxDaGlsZHJlbiB9IGZyb20gJy4uLy4uL3V0aWwvRWxlbWVudHMnO1xuXG52YXIgYWJzID0gTWF0aC5hYnMsXG4gICAgcm91bmQgPSBNYXRoLnJvdW5kO1xuXG52YXIgQVhJU19UT19ESU1FTlNJT04gPSB7XG4gIHg6ICd3aWR0aCcsXG4gIHk6ICdoZWlnaHQnXG59O1xuXG52YXIgQ1VSU09SX0NST1NTSEFJUiA9ICdjcm9zc2hhaXInO1xuXG52YXIgRElSRUNUSU9OX1RPX1RSQkwgPSB7XG4gIG46ICd0b3AnLFxuICB3OiAnbGVmdCcsXG4gIHM6ICdib3R0b20nLFxuICBlOiAncmlnaHQnXG59O1xuXG52YXIgSElHSF9QUklPUklUWSA9IDE1MDA7XG5cbnZhciBESVJFQ1RJT05fVE9fT1BQT1NJVEUgPSB7XG4gIG46ICdzJyxcbiAgdzogJ2UnLFxuICBzOiAnbicsXG4gIGU6ICd3J1xufTtcblxudmFyIFBBRERJTkcgPSAyMDtcblxuXG4vKipcbiAqIEFkZCBvciByZW1vdmUgc3BhY2UgYnkgbW92aW5nIGFuZCByZXNpemluZyBlbGVtZW50cy5cbiAqXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge0RyYWdnaW5nfSBkcmFnZ2luZ1xuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7TW9kZWxpbmd9IG1vZGVsaW5nXG4gKiBAcGFyYW0ge1J1bGVzfSBydWxlc1xuICogQHBhcmFtIHt0b29sTWFuYWdlcn0gdG9vbE1hbmFnZXJcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gU3BhY2VUb29sKGNhbnZhcywgZHJhZ2dpbmcsIGV2ZW50QnVzLCBtb2RlbGluZywgcnVsZXMsIHRvb2xNYW5hZ2VyKSB7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcbiAgdGhpcy5fZHJhZ2dpbmcgPSBkcmFnZ2luZztcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcbiAgdGhpcy5fbW9kZWxpbmcgPSBtb2RlbGluZztcbiAgdGhpcy5fcnVsZXMgPSBydWxlcztcbiAgdGhpcy5fdG9vbE1hbmFnZXIgPSB0b29sTWFuYWdlcjtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgdG9vbE1hbmFnZXIucmVnaXN0ZXJUb29sKCdzcGFjZScsIHtcbiAgICB0b29sOiAnc3BhY2VUb29sLnNlbGVjdGlvbicsXG4gICAgZHJhZ2dpbmc6ICdzcGFjZVRvb2wnXG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdzcGFjZVRvb2wuc2VsZWN0aW9uLmVuZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZXZlbnRCdXMub25jZSgnc3BhY2VUb29sLnNlbGVjdGlvbi5lbmRlZCcsIGZ1bmN0aW9uKCkge1xuICAgICAgc2VsZi5hY3RpdmF0ZU1ha2VTcGFjZShldmVudC5vcmlnaW5hbEV2ZW50KTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ3NwYWNlVG9vbC5tb3ZlJywgSElHSF9QUklPUklUWSAsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBpbml0aWFsaXplZCA9IGNvbnRleHQuaW5pdGlhbGl6ZWQ7XG5cbiAgICBpZiAoIWluaXRpYWxpemVkKSB7XG4gICAgICBpbml0aWFsaXplZCA9IGNvbnRleHQuaW5pdGlhbGl6ZWQgPSBzZWxmLmluaXQoZXZlbnQsIGNvbnRleHQpO1xuICAgIH1cblxuICAgIGlmIChpbml0aWFsaXplZCkge1xuICAgICAgZW5zdXJlQ29uc3RyYWludHMoZXZlbnQpO1xuICAgIH1cbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ3NwYWNlVG9vbC5lbmQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgYXhpcyA9IGNvbnRleHQuYXhpcyxcbiAgICAgICAgZGlyZWN0aW9uID0gY29udGV4dC5kaXJlY3Rpb24sXG4gICAgICAgIG1vdmluZ1NoYXBlcyA9IGNvbnRleHQubW92aW5nU2hhcGVzLFxuICAgICAgICByZXNpemluZ1NoYXBlcyA9IGNvbnRleHQucmVzaXppbmdTaGFwZXMsXG4gICAgICAgIHN0YXJ0ID0gY29udGV4dC5zdGFydDtcblxuICAgIGlmICghY29udGV4dC5pbml0aWFsaXplZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGVuc3VyZUNvbnN0cmFpbnRzKGV2ZW50KTtcblxuICAgIHZhciBkZWx0YSA9IHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwXG4gICAgfTtcblxuICAgIGRlbHRhWyBheGlzIF0gPSByb3VuZChldmVudFsgJ2QnICsgYXhpcyBdKTtcblxuICAgIHNlbGYubWFrZVNwYWNlKG1vdmluZ1NoYXBlcywgcmVzaXppbmdTaGFwZXMsIGRlbHRhLCBkaXJlY3Rpb24sIHN0YXJ0KTtcblxuICAgIGV2ZW50QnVzLm9uY2UoJ3NwYWNlVG9vbC5lbmRlZCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICAgIC8vIGFjdGl2YXRlIHNwYWNlIHRvb2wgc2VsZWN0aW9uIGFmdGVyIG1ha2Ugc3BhY2VcbiAgICAgIHNlbGYuYWN0aXZhdGVTZWxlY3Rpb24oZXZlbnQub3JpZ2luYWxFdmVudCwgdHJ1ZSwgdHJ1ZSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG5TcGFjZVRvb2wuJGluamVjdCA9IFtcbiAgJ2NhbnZhcycsXG4gICdkcmFnZ2luZycsXG4gICdldmVudEJ1cycsXG4gICdtb2RlbGluZycsXG4gICdydWxlcycsXG4gICd0b29sTWFuYWdlcidcbl07XG5cbi8qKlxuICogQWN0aXZhdGUgc3BhY2UgdG9vbCBzZWxlY3Rpb24uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGV2ZW50XG4gKiBAcGFyYW0ge2Jvb2xlYW59IGF1dG9BY3RpdmF0ZVxuICovXG5TcGFjZVRvb2wucHJvdG90eXBlLmFjdGl2YXRlU2VsZWN0aW9uID0gZnVuY3Rpb24oZXZlbnQsIGF1dG9BY3RpdmF0ZSwgcmVhY3RpdmF0ZSkge1xuICB0aGlzLl9kcmFnZ2luZy5pbml0KGV2ZW50LCAnc3BhY2VUb29sLnNlbGVjdGlvbicsIHtcbiAgICBhdXRvQWN0aXZhdGU6IGF1dG9BY3RpdmF0ZSxcbiAgICBjdXJzb3I6IENVUlNPUl9DUk9TU0hBSVIsXG4gICAgZGF0YToge1xuICAgICAgY29udGV4dDoge1xuICAgICAgICByZWFjdGl2YXRlOiByZWFjdGl2YXRlXG4gICAgICB9XG4gICAgfSxcbiAgICB0cmFwQ2xpY2s6IGZhbHNlXG4gIH0pO1xufTtcblxuLyoqXG4gKiBBY3RpdmF0ZSBzcGFjZSB0b29sIG1ha2Ugc3BhY2UuXG4gKlxuICogQHBhcmFtICB7TW91c2VFdmVudH0gZXZlbnRcbiAqL1xuU3BhY2VUb29sLnByb3RvdHlwZS5hY3RpdmF0ZU1ha2VTcGFjZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2RyYWdnaW5nLmluaXQoZXZlbnQsICdzcGFjZVRvb2wnLCB7XG4gICAgYXV0b0FjdGl2YXRlOiB0cnVlLFxuICAgIGN1cnNvcjogQ1VSU09SX0NST1NTSEFJUixcbiAgICBkYXRhOiB7XG4gICAgICBjb250ZXh0OiB7fVxuICAgIH1cbiAgfSk7XG59O1xuXG4vKipcbiAqIE1ha2Ugc3BhY2UuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8ZGpzLm1vZGVsLlNoYXBlPn0gbW92aW5nU2hhcGVzXG4gKiBAcGFyYW0gIHtBcnJheTxkanMubW9kZWwuU2hhcGU+fSByZXNpemluZ1NoYXBlc1xuICogQHBhcmFtICB7T2JqZWN0fSBkZWx0YVxuICogQHBhcmFtICB7bnVtYmVyfSBkZWx0YS54XG4gKiBAcGFyYW0gIHtudW1iZXJ9IGRlbHRhLnlcbiAqIEBwYXJhbSAge3N0cmluZ30gZGlyZWN0aW9uXG4gKiBAcGFyYW0gIHtudW1iZXJ9IHN0YXJ0XG4gKi9cblNwYWNlVG9vbC5wcm90b3R5cGUubWFrZVNwYWNlID0gZnVuY3Rpb24obW92aW5nU2hhcGVzLCByZXNpemluZ1NoYXBlcywgZGVsdGEsIGRpcmVjdGlvbiwgc3RhcnQpIHtcbiAgcmV0dXJuIHRoaXMuX21vZGVsaW5nLmNyZWF0ZVNwYWNlKG1vdmluZ1NoYXBlcywgcmVzaXppbmdTaGFwZXMsIGRlbHRhLCBkaXJlY3Rpb24sIHN0YXJ0KTtcbn07XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBtYWtlIHNwYWNlIGFuZCByZXR1cm4gdHJ1ZSBpZiB0aGF0IHdhcyBzdWNjZXNzZnVsLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBldmVudFxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqXG4gKiBAcmV0dXJuIHtib29sZWFufVxuICovXG5TcGFjZVRvb2wucHJvdG90eXBlLmluaXQgPSBmdW5jdGlvbihldmVudCwgY29udGV4dCkge1xuICB2YXIgYXhpcyA9IGFicyhldmVudC5keCkgPiBhYnMoZXZlbnQuZHkpID8gJ3gnIDogJ3knLFxuICAgICAgZGVsdGEgPSBldmVudFsgJ2QnICsgYXhpcyBdLFxuICAgICAgc3RhcnQgPSBldmVudFsgYXhpcyBdIC0gZGVsdGE7XG5cbiAgaWYgKGFicyhkZWx0YSkgPCA1KSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLy8gaW52ZXJ0IGRlbHRhIHRvIHJlbW92ZSBzcGFjZSB3aGVuIG1vdmluZyBsZWZ0XG4gIGlmIChkZWx0YSA8IDApIHtcbiAgICBkZWx0YSAqPSAtMTtcbiAgfVxuXG4gIC8vIGludmVydCBkZWx0YSB0byBhZGQvcmVtb3ZlIHNwYWNlIHdoZW4gcmVtb3ZpbmcvYWRkaW5nIHNwYWNlIGlmIG1vZGlmaWVyIGtleSBpcyBwcmVzc2VkXG4gIGlmIChoYXNQcmltYXJ5TW9kaWZpZXIoZXZlbnQpKSB7XG4gICAgZGVsdGEgKj0gLTE7XG4gIH1cblxuICB2YXIgZGlyZWN0aW9uID0gZ2V0RGlyZWN0aW9uKGF4aXMsIGRlbHRhKTtcblxuICB2YXIgcm9vdCA9IHRoaXMuX2NhbnZhcy5nZXRSb290RWxlbWVudCgpO1xuXG4gIHZhciBjaGlsZHJlbiA9IHNlbGZBbmRBbGxDaGlsZHJlbihyb290LCB0cnVlKTtcblxuICB2YXIgZWxlbWVudHMgPSB0aGlzLmNhbGN1bGF0ZUFkanVzdG1lbnRzKGNoaWxkcmVuLCBheGlzLCBkZWx0YSwgc3RhcnQpO1xuXG4gIHZhciBtaW5EaW1lbnNpb25zID0gdGhpcy5fZXZlbnRCdXMuZmlyZSgnc3BhY2VUb29sLmdldE1pbkRpbWVuc2lvbnMnLCB7XG4gICAgYXhpczogYXhpcyxcbiAgICBkaXJlY3Rpb246IGRpcmVjdGlvbixcbiAgICBzaGFwZXM6IGVsZW1lbnRzLnJlc2l6aW5nU2hhcGVzLFxuICAgIHN0YXJ0OiBzdGFydFxuICB9KTtcblxuICB2YXIgc3BhY2VUb29sQ29uc3RyYWludHMgPSBnZXRTcGFjZVRvb2xDb25zdHJhaW50cyhlbGVtZW50cywgYXhpcywgZGlyZWN0aW9uLCBzdGFydCwgbWluRGltZW5zaW9ucyk7XG5cbiAgYXNzaWduKFxuICAgIGNvbnRleHQsXG4gICAgZWxlbWVudHMsXG4gICAge1xuICAgICAgYXhpczogYXhpcyxcbiAgICAgIGRpcmVjdGlvbjogZGlyZWN0aW9uLFxuICAgICAgc3BhY2VUb29sQ29uc3RyYWludHM6IHNwYWNlVG9vbENvbnN0cmFpbnRzLFxuICAgICAgc3RhcnQ6IHN0YXJ0XG4gICAgfVxuICApO1xuXG4gIHNldEN1cnNvcigncmVzaXplLScgKyAoYXhpcyA9PT0gJ3gnID8gJ2V3JyA6ICducycpKTtcblxuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKlxuICogR2V0IGVsZW1lbnRzIHRvIGJlIG1vdmVkIGFuZCByZXNpemVkLlxuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGF4aXNcbiAqIEBwYXJhbSAge251bWJlcn0gZGVsdGFcbiAqIEBwYXJhbSAge251bWJlcn0gc3RhcnRcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cblNwYWNlVG9vbC5wcm90b3R5cGUuY2FsY3VsYXRlQWRqdXN0bWVudHMgPSBmdW5jdGlvbihlbGVtZW50cywgYXhpcywgZGVsdGEsIHN0YXJ0KSB7XG4gIHZhciBydWxlcyA9IHRoaXMuX3J1bGVzO1xuXG4gIHZhciBtb3ZpbmdTaGFwZXMgPSBbXSxcbiAgICAgIHJlc2l6aW5nU2hhcGVzID0gW107XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIGlmICghZWxlbWVudC5wYXJlbnQgfHwgaXNDb25uZWN0aW9uKGVsZW1lbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHNoYXBlU3RhcnQgPSBlbGVtZW50WyBheGlzIF0sXG4gICAgICAgIHNoYXBlRW5kID0gc2hhcGVTdGFydCArIGVsZW1lbnRbIEFYSVNfVE9fRElNRU5TSU9OWyBheGlzIF0gXTtcblxuICAgIC8vIHNoYXBlIHRvIGJlIG1vdmVkXG4gICAgaWYgKChkZWx0YSA+IDAgJiYgc2hhcGVTdGFydCA+IHN0YXJ0KSB8fCAoZGVsdGEgPCAwICYmIHNoYXBlRW5kIDwgc3RhcnQpKSB7XG4gICAgICByZXR1cm4gbW92aW5nU2hhcGVzLnB1c2goZWxlbWVudCk7XG4gICAgfVxuXG4gICAgLy8gc2hhcGUgdG8gYmUgcmVzaXplZFxuICAgIGlmIChzaGFwZVN0YXJ0IDwgc3RhcnQgJiZcbiAgICAgIHNoYXBlRW5kID4gc3RhcnQgJiZcbiAgICAgIHJ1bGVzLmFsbG93ZWQoJ3NoYXBlLnJlc2l6ZScsIHsgc2hhcGU6IGVsZW1lbnQgfSlcbiAgICApIHtcblxuICAgICAgcmV0dXJuIHJlc2l6aW5nU2hhcGVzLnB1c2goZWxlbWVudCk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4ge1xuICAgIG1vdmluZ1NoYXBlczogbW92aW5nU2hhcGVzLFxuICAgIHJlc2l6aW5nU2hhcGVzOiByZXNpemluZ1NoYXBlc1xuICB9O1xufTtcblxuU3BhY2VUb29sLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuaXNBY3RpdmUoKSkge1xuICAgIHRoaXMuX2RyYWdnaW5nLmNhbmNlbCgpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMuYWN0aXZhdGVTZWxlY3Rpb24oKTtcbiAgfVxufTtcblxuU3BhY2VUb29sLnByb3RvdHlwZS5pc0FjdGl2ZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgY29udGV4dCA9IHRoaXMuX2RyYWdnaW5nLmNvbnRleHQoKTtcblxuICByZXR1cm4gY29udGV4dCAmJiAvXnNwYWNlVG9vbC8udGVzdChjb250ZXh0LnByZWZpeCk7XG59O1xuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy9cblxuZnVuY3Rpb24gYWRkUGFkZGluZyh0cmJsKSB7XG4gIHJldHVybiB7XG4gICAgdG9wOiB0cmJsLnRvcCAtIFBBRERJTkcsXG4gICAgcmlnaHQ6IHRyYmwucmlnaHQgKyBQQURESU5HLFxuICAgIGJvdHRvbTogdHJibC5ib3R0b20gKyBQQURESU5HLFxuICAgIGxlZnQ6IHRyYmwubGVmdCAtIFBBRERJTkdcbiAgfTtcbn1cblxuZnVuY3Rpb24gZW5zdXJlQ29uc3RyYWludHMoZXZlbnQpIHtcbiAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMgPSBjb250ZXh0LnNwYWNlVG9vbENvbnN0cmFpbnRzO1xuXG4gIGlmICghc3BhY2VUb29sQ29uc3RyYWludHMpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgeCwgeTtcblxuICBpZiAoaXNOdW1iZXIoc3BhY2VUb29sQ29uc3RyYWludHMubGVmdCkpIHtcbiAgICB4ID0gTWF0aC5tYXgoZXZlbnQueCwgc3BhY2VUb29sQ29uc3RyYWludHMubGVmdCk7XG5cbiAgICBldmVudC5keCA9IGV2ZW50LmR4ICsgeCAtIGV2ZW50Lng7XG4gICAgZXZlbnQueCA9IHg7XG4gIH1cblxuICBpZiAoaXNOdW1iZXIoc3BhY2VUb29sQ29uc3RyYWludHMucmlnaHQpKSB7XG4gICAgeCA9IE1hdGgubWluKGV2ZW50LngsIHNwYWNlVG9vbENvbnN0cmFpbnRzLnJpZ2h0KTtcblxuICAgIGV2ZW50LmR4ID0gZXZlbnQuZHggKyB4IC0gZXZlbnQueDtcbiAgICBldmVudC54ID0geDtcbiAgfVxuXG4gIGlmIChpc051bWJlcihzcGFjZVRvb2xDb25zdHJhaW50cy50b3ApKSB7XG4gICAgeSA9IE1hdGgubWF4KGV2ZW50LnksIHNwYWNlVG9vbENvbnN0cmFpbnRzLnRvcCk7XG5cbiAgICBldmVudC5keSA9IGV2ZW50LmR5ICsgeSAtIGV2ZW50Lnk7XG4gICAgZXZlbnQueSA9IHk7XG4gIH1cblxuICBpZiAoaXNOdW1iZXIoc3BhY2VUb29sQ29uc3RyYWludHMuYm90dG9tKSkge1xuICAgIHkgPSBNYXRoLm1pbihldmVudC55LCBzcGFjZVRvb2xDb25zdHJhaW50cy5ib3R0b20pO1xuXG4gICAgZXZlbnQuZHkgPSBldmVudC5keSArIHkgLSBldmVudC55O1xuICAgIGV2ZW50LnkgPSB5O1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFNwYWNlVG9vbENvbnN0cmFpbnRzKGVsZW1lbnRzLCBheGlzLCBkaXJlY3Rpb24sIHN0YXJ0LCBtaW5EaW1lbnNpb25zKSB7XG4gIHZhciBtb3ZpbmdTaGFwZXMgPSBlbGVtZW50cy5tb3ZpbmdTaGFwZXMsXG4gICAgICByZXNpemluZ1NoYXBlcyA9IGVsZW1lbnRzLnJlc2l6aW5nU2hhcGVzO1xuXG4gIGlmICghcmVzaXppbmdTaGFwZXMubGVuZ3RoKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHNwYWNlVG9vbENvbnN0cmFpbnRzID0ge30sXG4gICAgICBtaW4sXG4gICAgICBtYXg7XG5cbiAgZm9yRWFjaChyZXNpemluZ1NoYXBlcywgZnVuY3Rpb24ocmVzaXppbmdTaGFwZSkge1xuICAgIHZhciByZXNpemluZ1NoYXBlQkJveCA9IGFzVFJCTChyZXNpemluZ1NoYXBlKTtcblxuICAgIC8vIGZpbmQgY2hpbGRyZW4gdGhhdCBhcmUgbm90IG1vdmluZyBvciByZXNpemluZ1xuICAgIHZhciBub25Nb3ZpbmdSZXNpemluZ0NoaWxkcmVuID0gZmlsdGVyKHJlc2l6aW5nU2hhcGUuY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICByZXR1cm4gIWlzQ29ubmVjdGlvbihjaGlsZCkgJiZcbiAgICAgICAgIWlzTGFiZWwoY2hpbGQpICYmXG4gICAgICAgICFpbmNsdWRlcyhtb3ZpbmdTaGFwZXMsIGNoaWxkKSAmJlxuICAgICAgICAhaW5jbHVkZXMocmVzaXppbmdTaGFwZXMsIGNoaWxkKTtcbiAgICB9KTtcblxuICAgIC8vIGZpbmQgY2hpbGRyZW4gdGhhdCBhcmUgbW92aW5nXG4gICAgdmFyIG1vdmluZ0NoaWxkcmVuID0gZmlsdGVyKHJlc2l6aW5nU2hhcGUuY2hpbGRyZW4sIGZ1bmN0aW9uKGNoaWxkKSB7XG4gICAgICByZXR1cm4gIWlzQ29ubmVjdGlvbihjaGlsZCkgJiYgIWlzTGFiZWwoY2hpbGQpICYmIGluY2x1ZGVzKG1vdmluZ1NoYXBlcywgY2hpbGQpO1xuICAgIH0pO1xuXG4gICAgdmFyIG1pbk9yTWF4LFxuICAgICAgICBub25Nb3ZpbmdSZXNpemluZ0NoaWxkcmVuQkJveCxcbiAgICAgICAgbW92aW5nQ2hpbGRyZW5CQm94O1xuXG4gICAgaWYgKG5vbk1vdmluZ1Jlc2l6aW5nQ2hpbGRyZW4ubGVuZ3RoKSB7XG4gICAgICBub25Nb3ZpbmdSZXNpemluZ0NoaWxkcmVuQkJveCA9IGFkZFBhZGRpbmcoYXNUUkJMKGdldEJCb3gobm9uTW92aW5nUmVzaXppbmdDaGlsZHJlbikpKTtcblxuICAgICAgbWluT3JNYXggPSBzdGFydCAtXG4gICAgICAgIHJlc2l6aW5nU2hhcGVCQm94WyBESVJFQ1RJT05fVE9fVFJCTFsgZGlyZWN0aW9uIF0gXSArXG4gICAgICAgIG5vbk1vdmluZ1Jlc2l6aW5nQ2hpbGRyZW5CQm94WyBESVJFQ1RJT05fVE9fVFJCTFsgZGlyZWN0aW9uIF0gXTtcblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ24nKSB7XG4gICAgICAgIHNwYWNlVG9vbENvbnN0cmFpbnRzLmJvdHRvbSA9IG1heCA9IGlzTnVtYmVyKG1heCkgPyBNYXRoLm1pbihtYXgsIG1pbk9yTWF4KSA6IG1pbk9yTWF4O1xuICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT09ICd3Jykge1xuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy5yaWdodCA9IG1heCA9IGlzTnVtYmVyKG1heCkgPyBNYXRoLm1pbihtYXgsIG1pbk9yTWF4KSA6IG1pbk9yTWF4O1xuICAgICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT09ICdzJykge1xuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy50b3AgPSBtaW4gPSBpc051bWJlcihtaW4pID8gTWF0aC5tYXgobWluLCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAnZScpIHtcbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMubGVmdCA9IG1pbiA9IGlzTnVtYmVyKG1pbikgPyBNYXRoLm1heChtaW4sIG1pbk9yTWF4KSA6IG1pbk9yTWF4O1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtb3ZpbmdDaGlsZHJlbi5sZW5ndGgpIHtcbiAgICAgIG1vdmluZ0NoaWxkcmVuQkJveCA9IGFkZFBhZGRpbmcoYXNUUkJMKGdldEJCb3gobW92aW5nQ2hpbGRyZW4pKSk7XG5cbiAgICAgIG1pbk9yTWF4ID0gc3RhcnQgLVxuICAgICAgICBtb3ZpbmdDaGlsZHJlbkJCb3hbIERJUkVDVElPTl9UT19UUkJMWyBESVJFQ1RJT05fVE9fT1BQT1NJVEVbIGRpcmVjdGlvbiBdIF0gXSArXG4gICAgICAgIHJlc2l6aW5nU2hhcGVCQm94WyBESVJFQ1RJT05fVE9fVFJCTFsgRElSRUNUSU9OX1RPX09QUE9TSVRFWyBkaXJlY3Rpb24gXSBdIF07XG5cbiAgICAgIGlmIChkaXJlY3Rpb24gPT09ICduJykge1xuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy5ib3R0b20gPSBtYXggPSBpc051bWJlcihtYXgpID8gTWF0aC5taW4obWF4LCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAndycpIHtcbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMucmlnaHQgPSBtYXggPSBpc051bWJlcihtYXgpID8gTWF0aC5taW4obWF4LCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAncycpIHtcbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMudG9wID0gbWluID0gaXNOdW1iZXIobWluKSA/IE1hdGgubWF4KG1pbiwgbWluT3JNYXgpIDogbWluT3JNYXg7XG4gICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ2UnKSB7XG4gICAgICAgIHNwYWNlVG9vbENvbnN0cmFpbnRzLmxlZnQgPSBtaW4gPSBpc051bWJlcihtaW4pID8gTWF0aC5tYXgobWluLCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVzaXppbmdTaGFwZU1pbkRpbWVuc2lvbnMgPSBtaW5EaW1lbnNpb25zICYmIG1pbkRpbWVuc2lvbnNbIHJlc2l6aW5nU2hhcGUuaWQgXTtcblxuICAgIGlmIChyZXNpemluZ1NoYXBlTWluRGltZW5zaW9ucykge1xuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ24nKSB7XG4gICAgICAgIG1pbk9yTWF4ID0gc3RhcnQgK1xuICAgICAgICAgIHJlc2l6aW5nU2hhcGVbIEFYSVNfVE9fRElNRU5TSU9OIFsgYXhpcyBdIF0gLVxuICAgICAgICAgIHJlc2l6aW5nU2hhcGVNaW5EaW1lbnNpb25zWyBBWElTX1RPX0RJTUVOU0lPTlsgYXhpcyBdIF07XG5cbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMuYm90dG9tID0gbWF4ID0gaXNOdW1iZXIobWF4KSA/IE1hdGgubWluKG1heCwgbWluT3JNYXgpIDogbWluT3JNYXg7XG4gICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiA9PT0gJ3cnKSB7XG4gICAgICAgIG1pbk9yTWF4ID0gc3RhcnQgK1xuICAgICAgICAgIHJlc2l6aW5nU2hhcGVbIEFYSVNfVE9fRElNRU5TSU9OIFsgYXhpcyBdIF0gLVxuICAgICAgICAgIHJlc2l6aW5nU2hhcGVNaW5EaW1lbnNpb25zWyBBWElTX1RPX0RJTUVOU0lPTlsgYXhpcyBdIF07XG5cbiAgICAgICAgc3BhY2VUb29sQ29uc3RyYWludHMucmlnaHQgPSBtYXggPSBpc051bWJlcihtYXgpID8gTWF0aC5taW4obWF4LCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAncycpIHtcbiAgICAgICAgbWluT3JNYXggPSBzdGFydCAtXG4gICAgICAgICAgcmVzaXppbmdTaGFwZVsgQVhJU19UT19ESU1FTlNJT04gWyBheGlzIF0gXSArXG4gICAgICAgICAgcmVzaXppbmdTaGFwZU1pbkRpbWVuc2lvbnNbIEFYSVNfVE9fRElNRU5TSU9OWyBheGlzIF0gXTtcblxuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy50b3AgPSBtaW4gPSBpc051bWJlcihtaW4pID8gTWF0aC5tYXgobWluLCBtaW5Pck1heCkgOiBtaW5Pck1heDtcbiAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09PSAnZScpIHtcbiAgICAgICAgbWluT3JNYXggPSBzdGFydCAtXG4gICAgICAgICAgcmVzaXppbmdTaGFwZVsgQVhJU19UT19ESU1FTlNJT04gWyBheGlzIF0gXSArXG4gICAgICAgICAgcmVzaXppbmdTaGFwZU1pbkRpbWVuc2lvbnNbIEFYSVNfVE9fRElNRU5TSU9OWyBheGlzIF0gXTtcblxuICAgICAgICBzcGFjZVRvb2xDb25zdHJhaW50cy5sZWZ0ID0gbWluID0gaXNOdW1iZXIobWluKSA/IE1hdGgubWF4KG1pbiwgbWluT3JNYXgpIDogbWluT3JNYXg7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gc3BhY2VUb29sQ29uc3RyYWludHM7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVzKGFycmF5LCBpdGVtKSB7XG4gIHJldHVybiBhcnJheS5pbmRleE9mKGl0ZW0pICE9PSAtMTtcbn1cblxuZnVuY3Rpb24gaXNDb25uZWN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuICEhZWxlbWVudC53YXlwb2ludHM7XG59XG5cbmZ1bmN0aW9uIGlzTGFiZWwoZWxlbWVudCkge1xuICByZXR1cm4gISFlbGVtZW50LmxhYmVsVGFyZ2V0O1xufSIsImltcG9ydCB7XG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgTUFSS0VSX0RSQUdHSU5HID0gJ2Rqcy1kcmFnZ2luZycsXG4gICAgTUFSS0VSX1JFU0laSU5HID0gJ2Rqcy1yZXNpemluZyc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSAyNTA7XG5cbmltcG9ydCB7XG4gIGFwcGVuZCBhcyBzdmdBcHBlbmQsXG4gIGF0dHIgYXMgc3ZnQXR0cixcbiAgY2xhc3NlcyBhcyBzdmdDbGFzc2VzLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICByZW1vdmUgYXMgc3ZnUmVtb3ZlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxuaW1wb3J0IHtcbiAgdHJhbnNsYXRlXG59IGZyb20gJy4uLy4uL3V0aWwvU3ZnVHJhbnNmb3JtVXRpbCc7XG5cbnZhciBtYXggPSBNYXRoLm1heDtcblxuXG4vKipcbiAqIFByb3ZpZGVzIHByZXZpZXdzIGZvciBzZWxlY3RpbmcvbW92aW5nL3Jlc2l6aW5nIHNoYXBlcyB3aGVuIGNyZWF0aW5nL3JlbW92aW5nIHNwYWNlLlxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0VsZW1lbnRSZWdpc3RyeX0gZWxlbWVudFJlZ2lzdHJ5XG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKiBAcGFyYW0ge1N0eWxlc30gc3R5bGVzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFNwYWNlVG9vbFByZXZpZXcoXG4gICAgZXZlbnRCdXMsIGVsZW1lbnRSZWdpc3RyeSwgY2FudmFzLFxuICAgIHN0eWxlcywgcHJldmlld1N1cHBvcnQpIHtcblxuICBmdW5jdGlvbiBhZGRQcmV2aWV3R2Z4KGNvbGxlY3Rpb24sIGRyYWdHcm91cCkge1xuICAgIGZvckVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcHJldmlld1N1cHBvcnQuYWRkRHJhZ2dlcihlbGVtZW50LCBkcmFnR3JvdXApO1xuXG4gICAgICBjYW52YXMuYWRkTWFya2VyKGVsZW1lbnQsIE1BUktFUl9EUkFHR0lORyk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBhZGQgY3Jvc3NoYWlyXG4gIGV2ZW50QnVzLm9uKCdzcGFjZVRvb2wuc2VsZWN0aW9uLnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgc3BhY2UgPSBjYW52YXMuZ2V0TGF5ZXIoJ3NwYWNlJyksXG4gICAgICAgIGNvbnRleHQgPSBldmVudC5jb250ZXh0O1xuXG4gICAgdmFyIG9yaWVudGF0aW9uID0ge1xuICAgICAgeDogJ00gMCwtMTAwMDAgTCAwLDEwMDAwJyxcbiAgICAgIHk6ICdNIC0xMDAwMCwwIEwgMTAwMDAsMCdcbiAgICB9O1xuXG4gICAgdmFyIGNyb3NzaGFpckdyb3VwID0gc3ZnQ3JlYXRlKCdnJyk7XG4gICAgc3ZnQXR0cihjcm9zc2hhaXJHcm91cCwgc3R5bGVzLmNscygnZGpzLWNyb3NzaGFpci1ncm91cCcsIFsgJ25vLWV2ZW50cycgXSkpO1xuXG4gICAgc3ZnQXBwZW5kKHNwYWNlLCBjcm9zc2hhaXJHcm91cCk7XG5cbiAgICAvLyBob3Jpem9udGFsIHBhdGhcbiAgICB2YXIgcGF0aFggPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICBzdmdBdHRyKHBhdGhYLCAnZCcsIG9yaWVudGF0aW9uLngpO1xuICAgIHN2Z0NsYXNzZXMocGF0aFgpLmFkZCgnZGpzLWNyb3NzaGFpcicpO1xuXG4gICAgc3ZnQXBwZW5kKGNyb3NzaGFpckdyb3VwLCBwYXRoWCk7XG5cbiAgICAvLyB2ZXJ0aWNhbCBwYXRoXG4gICAgdmFyIHBhdGhZID0gc3ZnQ3JlYXRlKCdwYXRoJyk7XG4gICAgc3ZnQXR0cihwYXRoWSwgJ2QnLCBvcmllbnRhdGlvbi55KTtcbiAgICBzdmdDbGFzc2VzKHBhdGhZKS5hZGQoJ2Rqcy1jcm9zc2hhaXInKTtcblxuICAgIHN2Z0FwcGVuZChjcm9zc2hhaXJHcm91cCwgcGF0aFkpO1xuXG4gICAgY29udGV4dC5jcm9zc2hhaXJHcm91cCA9IGNyb3NzaGFpckdyb3VwO1xuICB9KTtcblxuICAvLyB1cGRhdGUgY3Jvc3NoYWlyXG4gIGV2ZW50QnVzLm9uKCdzcGFjZVRvb2wuc2VsZWN0aW9uLm1vdmUnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjcm9zc2hhaXJHcm91cCA9IGV2ZW50LmNvbnRleHQuY3Jvc3NoYWlyR3JvdXA7XG5cbiAgICB0cmFuc2xhdGUoY3Jvc3NoYWlyR3JvdXAsIGV2ZW50LngsIGV2ZW50LnkpO1xuICB9KTtcblxuICAvLyByZW1vdmUgY3Jvc3NoYWlyXG4gIGV2ZW50QnVzLm9uKCdzcGFjZVRvb2wuc2VsZWN0aW9uLmNsZWFudXAnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHZhciBjb250ZXh0ID0gZXZlbnQuY29udGV4dCxcbiAgICAgICAgY3Jvc3NoYWlyR3JvdXAgPSBjb250ZXh0LmNyb3NzaGFpckdyb3VwO1xuXG4gICAgaWYgKGNyb3NzaGFpckdyb3VwKSB7XG4gICAgICBzdmdSZW1vdmUoY3Jvc3NoYWlyR3JvdXApO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gYWRkIGFuZCB1cGRhdGUgbW92ZS9yZXNpemUgcHJldmlld3NcbiAgZXZlbnRCdXMub24oJ3NwYWNlVG9vbC5tb3ZlJywgTE9XX1BSSU9SSVRZLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBsaW5lID0gY29udGV4dC5saW5lLFxuICAgICAgICBheGlzID0gY29udGV4dC5heGlzLFxuICAgICAgICBtb3ZpbmdTaGFwZXMgPSBjb250ZXh0Lm1vdmluZ1NoYXBlcyxcbiAgICAgICAgcmVzaXppbmdTaGFwZXMgPSBjb250ZXh0LnJlc2l6aW5nU2hhcGVzO1xuXG4gICAgaWYgKCFjb250ZXh0LmluaXRpYWxpemVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCFjb250ZXh0LmRyYWdHcm91cCkge1xuICAgICAgdmFyIHNwYWNlTGF5ZXIgPSBjYW52YXMuZ2V0TGF5ZXIoJ3NwYWNlJyk7XG5cbiAgICAgIGxpbmUgPSBzdmdDcmVhdGUoJ3BhdGgnKTtcbiAgICAgIHN2Z0F0dHIobGluZSwgJ2QnLCAnTTAsMCBMMCwwJyk7XG4gICAgICBzdmdDbGFzc2VzKGxpbmUpLmFkZCgnZGpzLWNyb3NzaGFpcicpO1xuXG4gICAgICBzdmdBcHBlbmQoc3BhY2VMYXllciwgbGluZSk7XG5cbiAgICAgIGNvbnRleHQubGluZSA9IGxpbmU7XG5cbiAgICAgIHZhciBkcmFnR3JvdXAgPSBzdmdDcmVhdGUoJ2cnKTtcbiAgICAgIHN2Z0F0dHIoZHJhZ0dyb3VwLCBzdHlsZXMuY2xzKCdkanMtZHJhZy1ncm91cCcsIFsgJ25vLWV2ZW50cycgXSkpO1xuXG4gICAgICBzdmdBcHBlbmQoY2FudmFzLmdldERlZmF1bHRMYXllcigpLCBkcmFnR3JvdXApO1xuXG4gICAgICAvLyBzaGFwZXNcbiAgICAgIGFkZFByZXZpZXdHZngobW92aW5nU2hhcGVzLCBkcmFnR3JvdXApO1xuXG4gICAgICAvLyBjb25uZWN0aW9uc1xuICAgICAgdmFyIG1vdmluZ0Nvbm5lY3Rpb25zID0gY29udGV4dC5tb3ZpbmdDb25uZWN0aW9ucyA9IGVsZW1lbnRSZWdpc3RyeS5maWx0ZXIoZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgICB2YXIgc291cmNlSXNNb3ZpbmcgPSBmYWxzZTtcblxuICAgICAgICBmb3JFYWNoKG1vdmluZ1NoYXBlcywgZnVuY3Rpb24oc2hhcGUpIHtcbiAgICAgICAgICBmb3JFYWNoKHNoYXBlLm91dGdvaW5nLCBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICBpZiAoZWxlbWVudCA9PT0gY29ubmVjdGlvbikge1xuICAgICAgICAgICAgICBzb3VyY2VJc01vdmluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHZhciB0YXJnZXRJc01vdmluZyA9IGZhbHNlO1xuXG4gICAgICAgIGZvckVhY2gobW92aW5nU2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgICAgICAgIGZvckVhY2goc2hhcGUuaW5jb21pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50ID09PSBjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgIHRhcmdldElzTW92aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdmFyIHNvdXJjZUlzUmVzaXppbmcgPSBmYWxzZTtcblxuICAgICAgICBmb3JFYWNoKHJlc2l6aW5nU2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgICAgICAgIGZvckVhY2goc2hhcGUub3V0Z29pbmcsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGlmIChlbGVtZW50ID09PSBjb25uZWN0aW9uKSB7XG4gICAgICAgICAgICAgIHNvdXJjZUlzUmVzaXppbmcgPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9KTtcblxuICAgICAgICB2YXIgdGFyZ2V0SXNSZXNpemluZyA9IGZhbHNlO1xuXG4gICAgICAgIGZvckVhY2gocmVzaXppbmdTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICAgICAgZm9yRWFjaChzaGFwZS5pbmNvbWluZywgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT09IGNvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgICAgdGFyZ2V0SXNSZXNpemluZyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBpc0Nvbm5lY3Rpb24oZWxlbWVudClcbiAgICAgICAgICAmJiAoc291cmNlSXNNb3ZpbmcgfHwgc291cmNlSXNSZXNpemluZylcbiAgICAgICAgICAmJiAodGFyZ2V0SXNNb3ZpbmcgfHwgdGFyZ2V0SXNSZXNpemluZyk7XG4gICAgICB9KTtcblxuXG4gICAgICBhZGRQcmV2aWV3R2Z4KG1vdmluZ0Nvbm5lY3Rpb25zLCBkcmFnR3JvdXApO1xuXG4gICAgICBjb250ZXh0LmRyYWdHcm91cCA9IGRyYWdHcm91cDtcbiAgICB9XG5cbiAgICBpZiAoIWNvbnRleHQuZnJhbWVHcm91cCkge1xuICAgICAgdmFyIGZyYW1lR3JvdXAgPSBzdmdDcmVhdGUoJ2cnKTtcbiAgICAgIHN2Z0F0dHIoZnJhbWVHcm91cCwgc3R5bGVzLmNscygnZGpzLWZyYW1lLWdyb3VwJywgWyAnbm8tZXZlbnRzJyBdKSk7XG5cbiAgICAgIHN2Z0FwcGVuZChjYW52YXMuZ2V0RGVmYXVsdExheWVyKCksIGZyYW1lR3JvdXApO1xuXG4gICAgICB2YXIgZnJhbWVzID0gW107XG5cbiAgICAgIGZvckVhY2gocmVzaXppbmdTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICAgIHZhciBmcmFtZSA9IHByZXZpZXdTdXBwb3J0LmFkZEZyYW1lKHNoYXBlLCBmcmFtZUdyb3VwKTtcblxuICAgICAgICB2YXIgaW5pdGlhbEJvdW5kcyA9IGZyYW1lLmdldEJCb3goKTtcblxuICAgICAgICBmcmFtZXMucHVzaCh7XG4gICAgICAgICAgZWxlbWVudDogZnJhbWUsXG4gICAgICAgICAgaW5pdGlhbEJvdW5kczogaW5pdGlhbEJvdW5kc1xuICAgICAgICB9KTtcblxuICAgICAgICBjYW52YXMuYWRkTWFya2VyKHNoYXBlLCBNQVJLRVJfUkVTSVpJTkcpO1xuICAgICAgfSk7XG5cbiAgICAgIGNvbnRleHQuZnJhbWVHcm91cCA9IGZyYW1lR3JvdXA7XG4gICAgICBjb250ZXh0LmZyYW1lcyA9IGZyYW1lcztcbiAgICB9XG5cbiAgICB2YXIgb3JpZW50YXRpb24gPSB7XG4gICAgICB4OiAnTScgKyBldmVudC54ICsgJywgLTEwMDAwIEwnICsgZXZlbnQueCArICcsIDEwMDAwJyxcbiAgICAgIHk6ICdNIC0xMDAwMCwgJyArIGV2ZW50LnkgKyAnIEwgMTAwMDAsICcgKyBldmVudC55XG4gICAgfTtcblxuICAgIHN2Z0F0dHIobGluZSwgeyBkOiBvcmllbnRhdGlvblsgYXhpcyBdIH0pO1xuXG4gICAgdmFyIG9wcG9zaXRlID0geyB4OiAneScsIHk6ICd4JyB9O1xuICAgIHZhciBkZWx0YSA9IHsgeDogZXZlbnQuZHgsIHk6IGV2ZW50LmR5IH07XG4gICAgZGVsdGFbIG9wcG9zaXRlWyBjb250ZXh0LmF4aXMgXSBdID0gMDtcblxuICAgIC8vIHVwZGF0ZSBtb3ZlIHByZXZpZXdzXG4gICAgdHJhbnNsYXRlKGNvbnRleHQuZHJhZ0dyb3VwLCBkZWx0YS54LCBkZWx0YS55KTtcblxuICAgIC8vIHVwZGF0ZSByZXNpemUgcHJldmlld3NcbiAgICBmb3JFYWNoKGNvbnRleHQuZnJhbWVzLCBmdW5jdGlvbihmcmFtZSkge1xuICAgICAgdmFyIGVsZW1lbnQgPSBmcmFtZS5lbGVtZW50LFxuICAgICAgICAgIGluaXRpYWxCb3VuZHMgPSBmcmFtZS5pbml0aWFsQm91bmRzLFxuICAgICAgICAgIHdpZHRoLFxuICAgICAgICAgIGhlaWdodDtcblxuICAgICAgaWYgKGNvbnRleHQuZGlyZWN0aW9uID09PSAnZScpIHtcbiAgICAgICAgc3ZnQXR0cihlbGVtZW50LCB7XG4gICAgICAgICAgd2lkdGg6IG1heChpbml0aWFsQm91bmRzLndpZHRoICsgZGVsdGEueCwgNSlcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB3aWR0aCA9IG1heChpbml0aWFsQm91bmRzLndpZHRoIC0gZGVsdGEueCwgNSk7XG5cbiAgICAgICAgc3ZnQXR0cihlbGVtZW50LCB7XG4gICAgICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgICAgIHg6IGluaXRpYWxCb3VuZHMueCArIGluaXRpYWxCb3VuZHMud2lkdGggLSB3aWR0aFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbnRleHQuZGlyZWN0aW9uID09PSAncycpIHtcbiAgICAgICAgc3ZnQXR0cihlbGVtZW50LCB7XG4gICAgICAgICAgaGVpZ2h0OiBtYXgoaW5pdGlhbEJvdW5kcy5oZWlnaHQgKyBkZWx0YS55LCA1KVxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhlaWdodCA9IG1heChpbml0aWFsQm91bmRzLmhlaWdodCAtIGRlbHRhLnksIDUpO1xuXG4gICAgICAgIHN2Z0F0dHIoZWxlbWVudCwge1xuICAgICAgICAgIGhlaWdodDogaGVpZ2h0LFxuICAgICAgICAgIHk6IGluaXRpYWxCb3VuZHMueSArIGluaXRpYWxCb3VuZHMuaGVpZ2h0IC0gaGVpZ2h0XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gIH0pO1xuXG4gIC8vIHJlbW92ZSBtb3ZlL3Jlc2l6ZSBwcmV2aWV3c1xuICBldmVudEJ1cy5vbignc3BhY2VUb29sLmNsZWFudXAnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIGNvbnRleHQgPSBldmVudC5jb250ZXh0LFxuICAgICAgICBtb3ZpbmdTaGFwZXMgPSBjb250ZXh0Lm1vdmluZ1NoYXBlcyxcbiAgICAgICAgbW92aW5nQ29ubmVjdGlvbnMgPSBjb250ZXh0Lm1vdmluZ0Nvbm5lY3Rpb25zLFxuICAgICAgICByZXNpemluZ1NoYXBlcyA9IGNvbnRleHQucmVzaXppbmdTaGFwZXMsXG4gICAgICAgIGxpbmUgPSBjb250ZXh0LmxpbmUsXG4gICAgICAgIGRyYWdHcm91cCA9IGNvbnRleHQuZHJhZ0dyb3VwLFxuICAgICAgICBmcmFtZUdyb3VwID0gY29udGV4dC5mcmFtZUdyb3VwO1xuXG4gICAgLy8gbW92aW5nIHNoYXBlc1xuICAgIGZvckVhY2gobW92aW5nU2hhcGVzLCBmdW5jdGlvbihzaGFwZSkge1xuICAgICAgY2FudmFzLnJlbW92ZU1hcmtlcihzaGFwZSwgTUFSS0VSX0RSQUdHSU5HKTtcbiAgICB9KTtcblxuICAgIC8vIG1vdmluZyBjb25uZWN0aW9uc1xuICAgIGZvckVhY2gobW92aW5nQ29ubmVjdGlvbnMsIGZ1bmN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAgIGNhbnZhcy5yZW1vdmVNYXJrZXIoY29ubmVjdGlvbiwgTUFSS0VSX0RSQUdHSU5HKTtcbiAgICB9KTtcblxuICAgIGlmIChkcmFnR3JvdXApIHtcbiAgICAgIHN2Z1JlbW92ZShsaW5lKTtcbiAgICAgIHN2Z1JlbW92ZShkcmFnR3JvdXApO1xuICAgIH1cblxuICAgIGZvckVhY2gocmVzaXppbmdTaGFwZXMsIGZ1bmN0aW9uKHNoYXBlKSB7XG4gICAgICBjYW52YXMucmVtb3ZlTWFya2VyKHNoYXBlLCBNQVJLRVJfUkVTSVpJTkcpO1xuICAgIH0pO1xuXG4gICAgaWYgKGZyYW1lR3JvdXApIHtcbiAgICAgIHN2Z1JlbW92ZShmcmFtZUdyb3VwKTtcbiAgICB9XG4gIH0pO1xufVxuXG5TcGFjZVRvb2xQcmV2aWV3LiRpbmplY3QgPSBbXG4gICdldmVudEJ1cycsXG4gICdlbGVtZW50UmVnaXN0cnknLFxuICAnY2FudmFzJyxcbiAgJ3N0eWxlcycsXG4gICdwcmV2aWV3U3VwcG9ydCdcbl07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogQ2hlY2tzIGlmIGFuIGVsZW1lbnQgaXMgYSBjb25uZWN0aW9uLlxuICovXG5mdW5jdGlvbiBpc0Nvbm5lY3Rpb24oZWxlbWVudCkge1xuICByZXR1cm4gZWxlbWVudC53YXlwb2ludHM7XG59XG4iLCJpbXBvcnQgeyBmb3JFYWNoIH0gZnJvbSAnbWluLWRhc2gnO1xuXG4vKipcbiAqIFJldHVybiBkaXJlY3Rpb24gZ2l2ZW4gYXhpcyBhbmQgZGVsdGEuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IGF4aXNcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YVxuICpcbiAqIEByZXR1cm4ge3N0cmluZ31cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERpcmVjdGlvbihheGlzLCBkZWx0YSkge1xuXG4gIGlmIChheGlzID09PSAneCcpIHtcbiAgICBpZiAoZGVsdGEgPiAwKSB7XG4gICAgICByZXR1cm4gJ2UnO1xuICAgIH1cblxuICAgIGlmIChkZWx0YSA8IDApIHtcbiAgICAgIHJldHVybiAndyc7XG4gICAgfVxuICB9XG5cbiAgaWYgKGF4aXMgPT09ICd5Jykge1xuICAgIGlmIChkZWx0YSA+IDApIHtcbiAgICAgIHJldHVybiAncyc7XG4gICAgfVxuXG4gICAgaWYgKGRlbHRhIDwgMCkge1xuICAgICAgcmV0dXJuICduJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGNvbm5lY3Rpb25zIHdob3NlIHdheXBvaW50cyBhcmUgdG8gYmUgdXBkYXRlZC4gV2F5cG9pbnRzIGFyZSB0byBiZSB1cGRhdGVkIGlmIHN0YXJ0XG4gKiBvciBlbmQgaXMgdG8gYmUgbW92ZWQgb3IgcmVzaXplZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZX0gbW92aW5nU2hhcGVzXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZX0gcmVzaXppbmdTaGFwZXNcbiAqXG4gKiBAcmV0dXJucyB7QXJyYXk8ZGpzLm1vZGVsLkNvbm5lY3Rpb24+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0V2F5cG9pbnRzVXBkYXRpbmdDb25uZWN0aW9ucyhtb3ZpbmdTaGFwZXMsIHJlc2l6aW5nU2hhcGVzKSB7XG4gIHZhciB3YXlwb2ludHNVcGRhdGluZ0Nvbm5lY3Rpb25zID0gW107XG5cbiAgZm9yRWFjaChtb3ZpbmdTaGFwZXMuY29uY2F0KHJlc2l6aW5nU2hhcGVzKSwgZnVuY3Rpb24oc2hhcGUpIHtcbiAgICB2YXIgaW5jb21pbmcgPSBzaGFwZS5pbmNvbWluZyxcbiAgICAgICAgb3V0Z29pbmcgPSBzaGFwZS5vdXRnb2luZztcblxuICAgIGZvckVhY2goaW5jb21pbmcuY29uY2F0KG91dGdvaW5nKSwgZnVuY3Rpb24oY29ubmVjdGlvbikge1xuICAgICAgdmFyIHNvdXJjZSA9IGNvbm5lY3Rpb24uc291cmNlLFxuICAgICAgICAgIHRhcmdldCA9IGNvbm5lY3Rpb24udGFyZ2V0O1xuXG4gICAgICBpZiAoaW5jbHVkZXMobW92aW5nU2hhcGVzLCBzb3VyY2UpIHx8XG4gICAgICAgIGluY2x1ZGVzKG1vdmluZ1NoYXBlcywgdGFyZ2V0KSB8fFxuICAgICAgICBpbmNsdWRlcyhyZXNpemluZ1NoYXBlcywgc291cmNlKSB8fFxuICAgICAgICBpbmNsdWRlcyhyZXNpemluZ1NoYXBlcywgdGFyZ2V0KSkge1xuXG4gICAgICAgIGlmICghaW5jbHVkZXMod2F5cG9pbnRzVXBkYXRpbmdDb25uZWN0aW9ucywgY29ubmVjdGlvbikpIHtcbiAgICAgICAgICB3YXlwb2ludHNVcGRhdGluZ0Nvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfSk7XG5cbiAgcmV0dXJuIHdheXBvaW50c1VwZGF0aW5nQ29ubmVjdGlvbnM7XG59XG5cbmZ1bmN0aW9uIGluY2x1ZGVzKGFycmF5LCBpdGVtKSB7XG4gIHJldHVybiBhcnJheS5pbmRleE9mKGl0ZW0pICE9PSAtMTtcbn1cblxuLyoqXG4gKiBSZXNpemUgYm91bmRzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBib3VuZHNcbiAqIEBwYXJhbSB7bnVtYmVyfSBib3VuZHMueFxuICogQHBhcmFtIHtudW1iZXJ9IGJvdW5kcy55XG4gKiBAcGFyYW0ge251bWJlcn0gYm91bmRzLndpZHRoXG4gKiBAcGFyYW0ge251bWJlcn0gYm91bmRzLmhlaWdodFxuICogQHBhcmFtIHtzdHJpbmd9IGRpcmVjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IGRlbHRhXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsdGEueFxuICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhLnlcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNpemVCb3VuZHMoYm91bmRzLCBkaXJlY3Rpb24sIGRlbHRhKSB7XG4gIHZhciB4ID0gYm91bmRzLngsXG4gICAgICB5ID0gYm91bmRzLnksXG4gICAgICB3aWR0aCA9IGJvdW5kcy53aWR0aCxcbiAgICAgIGhlaWdodCA9IGJvdW5kcy5oZWlnaHQsXG4gICAgICBkeCA9IGRlbHRhLngsXG4gICAgICBkeSA9IGRlbHRhLnk7XG5cbiAgc3dpdGNoIChkaXJlY3Rpb24pIHtcbiAgY2FzZSAnbic6XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5ICsgZHksXG4gICAgICB3aWR0aDogd2lkdGgsXG4gICAgICBoZWlnaHQ6IGhlaWdodCAtIGR5XG4gICAgfTtcbiAgY2FzZSAncyc6XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5LFxuICAgICAgd2lkdGg6IHdpZHRoLFxuICAgICAgaGVpZ2h0OiBoZWlnaHQgKyBkeVxuICAgIH07XG4gIGNhc2UgJ3cnOlxuICAgIHJldHVybiB7XG4gICAgICB4OiB4ICsgZHgsXG4gICAgICB5OiB5LFxuICAgICAgd2lkdGg6IHdpZHRoIC0gZHgsXG4gICAgICBoZWlnaHQ6IGhlaWdodFxuICAgIH07XG4gIGNhc2UgJ2UnOlxuICAgIHJldHVybiB7XG4gICAgICB4OiB4LFxuICAgICAgeTogeSxcbiAgICAgIHdpZHRoOiB3aWR0aCArIGR4LFxuICAgICAgaGVpZ2h0OiBoZWlnaHRcbiAgICB9O1xuICBkZWZhdWx0OlxuICAgIHRocm93IG5ldyBFcnJvcigndW5rbm93biBkaXJlY3Rpb246ICcgKyBkaXJlY3Rpb24pO1xuICB9XG59IiwiaW1wb3J0IERyYWdnaW5nTW9kdWxlIGZyb20gJy4uL2RyYWdnaW5nJztcbmltcG9ydCBSdWxlc01vZHVsZSBmcm9tICcuLi9ydWxlcyc7XG5pbXBvcnQgVG9vbE1hbmFnZXJNb2R1bGUgZnJvbSAnLi4vdG9vbC1tYW5hZ2VyJztcbmltcG9ydCBQcmV2aWV3U3VwcG9ydE1vZHVsZSBmcm9tICcuLi9wcmV2aWV3LXN1cHBvcnQnO1xuXG5pbXBvcnQgU3BhY2VUb29sIGZyb20gJy4vU3BhY2VUb29sJztcbmltcG9ydCBTcGFjZVRvb2xQcmV2aWV3IGZyb20gJy4vU3BhY2VUb29sUHJldmlldyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19pbml0X186IFsnc3BhY2VUb29sUHJldmlldyddLFxuICBfX2RlcGVuZHNfXzogW1xuICAgIERyYWdnaW5nTW9kdWxlLFxuICAgIFJ1bGVzTW9kdWxlLFxuICAgIFRvb2xNYW5hZ2VyTW9kdWxlLFxuICAgIFByZXZpZXdTdXBwb3J0TW9kdWxlXG4gIF0sXG4gIHNwYWNlVG9vbDogWyd0eXBlJywgU3BhY2VUb29sIF0sXG4gIHNwYWNlVG9vbFByZXZpZXc6IFsndHlwZScsIFNwYWNlVG9vbFByZXZpZXcgXVxufTtcbiIsImltcG9ydCB7XG4gIGZvckVhY2hcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBjbG9zZXN0IGFzIGRvbUNsb3Nlc3Rcbn0gZnJvbSAnbWluLWRvbSc7XG5cbnZhciBMT1dfUFJJT1JJVFkgPSAyNTA7XG5cbi8qKlxuICogVGhlIHRvb2wgbWFuYWdlciBhY3RzIGFzIG1pZGRsZS1tYW4gYmV0d2VlbiB0aGUgYXZhaWxhYmxlIHRvb2wncyBhbmQgdGhlIFBhbGV0dGUsXG4gKiBpdCB0YWtlcyBjYXJlIG9mIG1ha2luZyBzdXJlIHRoYXQgdGhlIGNvcnJlY3QgYWN0aXZlIHN0YXRlIGlzIHNldC5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgIGV2ZW50QnVzXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgIGRyYWdnaW5nXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRvb2xNYW5hZ2VyKGV2ZW50QnVzLCBkcmFnZ2luZykge1xuICB0aGlzLl9ldmVudEJ1cyA9IGV2ZW50QnVzO1xuICB0aGlzLl9kcmFnZ2luZyA9IGRyYWdnaW5nO1xuXG4gIHRoaXMuX3Rvb2xzID0gW107XG4gIHRoaXMuX2FjdGl2ZSA9IG51bGw7XG59XG5cblRvb2xNYW5hZ2VyLiRpbmplY3QgPSBbICdldmVudEJ1cycsICdkcmFnZ2luZycgXTtcblxuVG9vbE1hbmFnZXIucHJvdG90eXBlLnJlZ2lzdGVyVG9vbCA9IGZ1bmN0aW9uKG5hbWUsIGV2ZW50cykge1xuICB2YXIgdG9vbHMgPSB0aGlzLl90b29scztcblxuICBpZiAoIWV2ZW50cykge1xuICAgIHRocm93IG5ldyBFcnJvcignQSB0b29sIGhhcyB0byBiZSByZWdpc3RlcmVkIHdpdGggaXRcXCdzIFwiZXZlbnRzXCInKTtcbiAgfVxuXG4gIHRvb2xzLnB1c2gobmFtZSk7XG5cbiAgdGhpcy5iaW5kRXZlbnRzKG5hbWUsIGV2ZW50cyk7XG59O1xuXG5Ub29sTWFuYWdlci5wcm90b3R5cGUuaXNBY3RpdmUgPSBmdW5jdGlvbih0b29sKSB7XG4gIHJldHVybiB0b29sICYmIHRoaXMuX2FjdGl2ZSA9PT0gdG9vbDtcbn07XG5cblRvb2xNYW5hZ2VyLnByb3RvdHlwZS5sZW5ndGggPSBmdW5jdGlvbih0b29sKSB7XG4gIHJldHVybiB0aGlzLl90b29scy5sZW5ndGg7XG59O1xuXG5Ub29sTWFuYWdlci5wcm90b3R5cGUuc2V0QWN0aXZlID0gZnVuY3Rpb24odG9vbCkge1xuICB2YXIgZXZlbnRCdXMgPSB0aGlzLl9ldmVudEJ1cztcblxuICBpZiAodGhpcy5fYWN0aXZlICE9PSB0b29sKSB7XG4gICAgdGhpcy5fYWN0aXZlID0gdG9vbDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ3Rvb2wtbWFuYWdlci51cGRhdGUnLCB7IHRvb2w6IHRvb2wgfSk7XG4gIH1cbn07XG5cblRvb2xNYW5hZ2VyLnByb3RvdHlwZS5iaW5kRXZlbnRzID0gZnVuY3Rpb24obmFtZSwgZXZlbnRzKSB7XG4gIHZhciBldmVudEJ1cyA9IHRoaXMuX2V2ZW50QnVzLFxuICAgICAgZHJhZ2dpbmcgPSB0aGlzLl9kcmFnZ2luZztcblxuICB2YXIgZXZlbnRzVG9SZWdpc3RlciA9IFtdO1xuXG4gIGV2ZW50QnVzLm9uKGV2ZW50cy50b29sICsgJy5pbml0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgY29udGV4dCA9IGV2ZW50LmNvbnRleHQ7XG5cbiAgICAvLyBBY3RpdmUgdG9vbHMgdGhhdCB3YW50IHRvIHJlYWN0aXZhdGUgdGhlbXNlbHZlcyBtdXN0IGRvIHRoaXMgZXhwbGljaXRseVxuICAgIGlmICghY29udGV4dC5yZWFjdGl2YXRlICYmIHRoaXMuaXNBY3RpdmUobmFtZSkpIHtcbiAgICAgIHRoaXMuc2V0QWN0aXZlKG51bGwpO1xuXG4gICAgICBkcmFnZ2luZy5jYW5jZWwoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldEFjdGl2ZShuYW1lKTtcblxuICB9LCB0aGlzKTtcblxuICAvLyBUb2RvW3JpY2FyZG9dOiBhZGQgdGVzdCBjYXNlc1xuICBmb3JFYWNoKGV2ZW50cywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBldmVudHNUb1JlZ2lzdGVyLnB1c2goZXZlbnQgKyAnLmVuZGVkJyk7XG4gICAgZXZlbnRzVG9SZWdpc3Rlci5wdXNoKGV2ZW50ICsgJy5jYW5jZWxlZCcpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbihldmVudHNUb1JlZ2lzdGVyLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIG9yaWdpbmFsRXZlbnQgPSBldmVudC5vcmlnaW5hbEV2ZW50O1xuXG4gICAgLy8gV2UgZGVmZXIgdGhlIGRlLWFjdGl2YXRpb24gb2YgdGhlIHRvb2wgdG8gdGhlIC5hY3RpdmF0ZSBwaGFzZSxcbiAgICAvLyBzbyB3ZSdyZSBhYmxlIHRvIGNoZWNrIGlmIHdlIHdhbnQgdG8gdG9nZ2xlIG9mZiB0aGUgY3VycmVudFxuICAgIC8vIGFjdGl2ZSB0b29sIG9yIHN3aXRjaCB0byBhIG5ldyBvbmVcbiAgICBpZiAoIXRoaXMuX2FjdGl2ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChvcmlnaW5hbEV2ZW50ICYmIGRvbUNsb3Nlc3Qob3JpZ2luYWxFdmVudC50YXJnZXQsICcuZ3JvdXBbZGF0YS1ncm91cD1cInRvb2xzXCJdJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNldEFjdGl2ZShudWxsKTtcbiAgfSwgdGhpcyk7XG59O1xuIiwiaW1wb3J0IERyYWdnaW5nTW9kdWxlIGZyb20gJy4uL2RyYWdnaW5nJztcblxuaW1wb3J0IFRvb2xNYW5hZ2VyIGZyb20gJy4vVG9vbE1hbmFnZXInO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbXG4gICAgRHJhZ2dpbmdNb2R1bGVcbiAgXSxcbiAgX19pbml0X186IFsgJ3Rvb2xNYW5hZ2VyJyBdLFxuICB0b29sTWFuYWdlcjogWyAndHlwZScsIFRvb2xNYW5hZ2VyIF1cbn07XG4iLCJpbXBvcnQge1xuICBpc1N0cmluZyxcbiAgYXNzaWduLFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZG9taWZ5LFxuICBhdHRyIGFzIGRvbUF0dHIsXG4gIGNsYXNzZXMgYXMgZG9tQ2xhc3NlcyxcbiAgcmVtb3ZlIGFzIGRvbVJlbW92ZSxcbiAgZGVsZWdhdGUgYXMgZG9tRGVsZWdhdGVcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCBJZHMgZnJvbSAnLi4vLi4vdXRpbC9JZEdlbmVyYXRvcic7XG5cbi8vIGRvY3VtZW50IHdpZGUgdW5pcXVlIHRvb2x0aXAgaWRzXG52YXIgaWRzID0gbmV3IElkcygndHQnKTtcblxuXG5mdW5jdGlvbiBjcmVhdGVSb290KHBhcmVudE5vZGUpIHtcbiAgdmFyIHJvb3QgPSBkb21pZnkoXG4gICAgJzxkaXYgY2xhc3M9XCJkanMtdG9vbHRpcC1jb250YWluZXJcIiBzdHlsZT1cInBvc2l0aW9uOiBhYnNvbHV0ZTsgd2lkdGg6IDA7IGhlaWdodDogMDtcIiAvPidcbiAgKTtcblxuICBwYXJlbnROb2RlLmluc2VydEJlZm9yZShyb290LCBwYXJlbnROb2RlLmZpcnN0Q2hpbGQpO1xuXG4gIHJldHVybiByb290O1xufVxuXG5cbmZ1bmN0aW9uIHNldFBvc2l0aW9uKGVsLCB4LCB5KSB7XG4gIGFzc2lnbihlbC5zdHlsZSwgeyBsZWZ0OiB4ICsgJ3B4JywgdG9wOiB5ICsgJ3B4JyB9KTtcbn1cblxuZnVuY3Rpb24gc2V0VmlzaWJsZShlbCwgdmlzaWJsZSkge1xuICBlbC5zdHlsZS5kaXNwbGF5ID0gdmlzaWJsZSA9PT0gZmFsc2UgPyAnbm9uZScgOiAnJztcbn1cblxuXG52YXIgdG9vbHRpcENsYXNzID0gJ2Rqcy10b29sdGlwJyxcbiAgICB0b29sdGlwU2VsZWN0b3IgPSAnLicgKyB0b29sdGlwQ2xhc3M7XG5cbi8qKlxuICogQSBzZXJ2aWNlIHRoYXQgYWxsb3dzIHVzZXJzIHRvIHJlbmRlciB0b29sIHRpcHMgb24gdGhlIGRpYWdyYW0uXG4gKlxuICogVGhlIHRvb2x0aXAgc2VydmljZSB3aWxsIHRha2UgY2FyZSBvZiB1cGRhdGluZyB0aGUgdG9vbHRpcCBwb3NpdGlvbmluZ1xuICogZHVyaW5nIG5hdmlnYXRpb24gKyB6b29taW5nLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogYGBgamF2YXNjcmlwdFxuICpcbiAqIC8vIGFkZCBhIHBpbmsgYmFkZ2Ugb24gdGhlIHRvcCBsZWZ0IG9mIHRoZSBzaGFwZVxuICogdG9vbHRpcHMuYWRkKHtcbiAqICAgcG9zaXRpb246IHtcbiAqICAgICB4OiA1MCxcbiAqICAgICB5OiAxMDBcbiAqICAgfSxcbiAqICAgaHRtbDogJzxkaXYgc3R5bGU9XCJ3aWR0aDogMTBweDsgYmFja2dyb3VuZDogZnVjaHNpYTsgY29sb3I6IHdoaXRlO1wiPjA8L2Rpdj4nXG4gKiB9KTtcbiAqXG4gKiAvLyBvciB3aXRoIG9wdGlvbmFsIGxpZmUgc3BhblxuICogdG9vbHRpcHMuYWRkKHtcbiAqICAgcG9zaXRpb246IHtcbiAqICAgICB0b3A6IC01LFxuICogICAgIGxlZnQ6IC01XG4gKiAgIH0sXG4gKiAgIGh0bWw6ICc8ZGl2IHN0eWxlPVwid2lkdGg6IDEwcHg7IGJhY2tncm91bmQ6IGZ1Y2hzaWE7IGNvbG9yOiB3aGl0ZTtcIj4wPC9kaXY+JyxcbiAqICAgdHRsOiAyMDAwXG4gKiB9KTtcbiAqXG4gKiAvLyByZW1vdmUgYSB0b29sIHRpcFxuICogdmFyIGlkID0gdG9vbHRpcHMuYWRkKC4uLik7XG4gKiB0b29sdGlwcy5yZW1vdmUoaWQpO1xuICogYGBgXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gVG9vbHRpcHMoZXZlbnRCdXMsIGNhbnZhcykge1xuXG4gIHRoaXMuX2V2ZW50QnVzID0gZXZlbnRCdXM7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcztcblxuICB0aGlzLl9pZHMgPSBpZHM7XG5cbiAgdGhpcy5fdG9vbHRpcERlZmF1bHRzID0ge1xuICAgIHNob3c6IHtcbiAgICAgIG1pblpvb206IDAuNyxcbiAgICAgIG1heFpvb206IDUuMFxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogTWFwcGluZyB0b29sdGlwSWQgLT4gdG9vbHRpcFxuICAgKi9cbiAgdGhpcy5fdG9vbHRpcHMgPSB7fTtcblxuICAvLyByb290IGh0bWwgZWxlbWVudCBmb3IgYWxsIHRvb2x0aXBzXG4gIHRoaXMuX3Rvb2x0aXBSb290ID0gY3JlYXRlUm9vdChjYW52YXMuZ2V0Q29udGFpbmVyKCkpO1xuXG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQodGhpcy5fdG9vbHRpcFJvb3QsIHRvb2x0aXBTZWxlY3RvciwgJ21vdXNlZG93bicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH0pO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQodGhpcy5fdG9vbHRpcFJvb3QsIHRvb2x0aXBTZWxlY3RvciwgJ21vdXNlb3ZlcicsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgc2VsZi50cmlnZ2VyKCdtb3VzZW92ZXInLCBldmVudCk7XG4gIH0pO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQodGhpcy5fdG9vbHRpcFJvb3QsIHRvb2x0aXBTZWxlY3RvciwgJ21vdXNlb3V0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBzZWxmLnRyaWdnZXIoJ21vdXNlb3V0JywgZXZlbnQpO1xuICB9KTtcblxuICB0aGlzLl9pbml0KCk7XG59XG5cblxuVG9vbHRpcHMuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2NhbnZhcycgXTtcblxuXG4vKipcbiAqIEFkZHMgYSBIVE1MIHRvb2x0aXAgdG8gdGhlIGRpYWdyYW1cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gICAgICAgICAgICAgICB0b29sdGlwICAgdGhlIHRvb2x0aXAgY29uZmlndXJhdGlvblxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfERPTUVsZW1lbnR9ICAgIHRvb2x0aXAuaHRtbCAgICAgICAgICAgICAgICAgaHRtbCBlbGVtZW50IHRvIHVzZSBhcyBhbiB0b29sdGlwXG4gKiBAcGFyYW0ge09iamVjdH0gICAgICAgICAgICAgICBbdG9vbHRpcC5zaG93XSAgICAgICAgICAgICAgIHNob3cgY29uZmlndXJhdGlvblxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgW3Rvb2x0aXAuc2hvdy5taW5ab29tXSAgICAgICBtaW5pbWFsIHpvb20gbGV2ZWwgdG8gc2hvdyB0aGUgdG9vbHRpcFxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgW3Rvb2x0aXAuc2hvdy5tYXhab29tXSAgICAgICBtYXhpbXVtIHpvb20gbGV2ZWwgdG8gc2hvdyB0aGUgdG9vbHRpcFxuICogQHBhcmFtIHtPYmplY3R9ICAgICAgICAgICAgICAgdG9vbHRpcC5wb3NpdGlvbiAgICAgICAgICAgICB3aGVyZSB0byBhdHRhY2ggdGhlIHRvb2x0aXBcbiAqIEBwYXJhbSB7bnVtYmVyfSAgICAgICAgICAgICAgIFt0b29sdGlwLnBvc2l0aW9uLmxlZnRdICAgICAgcmVsYXRpdmUgdG8gZWxlbWVudCBiYm94IGxlZnQgYXR0YWNobWVudFxuICogQHBhcmFtIHtudW1iZXJ9ICAgICAgICAgICAgICAgW3Rvb2x0aXAucG9zaXRpb24udG9wXSAgICAgICByZWxhdGl2ZSB0byBlbGVtZW50IGJib3ggdG9wIGF0dGFjaG1lbnRcbiAqIEBwYXJhbSB7bnVtYmVyfSAgICAgICAgICAgICAgIFt0b29sdGlwLnBvc2l0aW9uLmJvdHRvbV0gICAgcmVsYXRpdmUgdG8gZWxlbWVudCBiYm94IGJvdHRvbSBhdHRhY2htZW50XG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICBbdG9vbHRpcC5wb3NpdGlvbi5yaWdodF0gICAgIHJlbGF0aXZlIHRvIGVsZW1lbnQgYmJveCByaWdodCBhdHRhY2htZW50XG4gKiBAcGFyYW0ge251bWJlcn0gICAgICAgICAgICAgICBbdG9vbHRpcC50aW1lb3V0PS0xXVxuICpcbiAqIEByZXR1cm4ge3N0cmluZ30gICAgICAgICAgICAgIGlkIHRoYXQgbWF5IGJlIHVzZWQgdG8gcmVmZXJlbmNlIHRoZSB0b29sdGlwIGZvciB1cGRhdGUgb3IgcmVtb3ZhbFxuICovXG5Ub29sdGlwcy5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24odG9vbHRpcCkge1xuXG4gIGlmICghdG9vbHRpcC5wb3NpdGlvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignbXVzdCBzcGVjaWZpeSB0b29sdGlwIHBvc2l0aW9uJyk7XG4gIH1cblxuICBpZiAoIXRvb2x0aXAuaHRtbCkge1xuICAgIHRocm93IG5ldyBFcnJvcignbXVzdCBzcGVjaWZpeSB0b29sdGlwIGh0bWwnKTtcbiAgfVxuXG4gIHZhciBpZCA9IHRoaXMuX2lkcy5uZXh0KCk7XG5cbiAgdG9vbHRpcCA9IGFzc2lnbih7fSwgdGhpcy5fdG9vbHRpcERlZmF1bHRzLCB0b29sdGlwLCB7XG4gICAgaWQ6IGlkXG4gIH0pO1xuXG4gIHRoaXMuX2FkZFRvb2x0aXAodG9vbHRpcCk7XG5cbiAgaWYgKHRvb2x0aXAudGltZW91dCkge1xuICAgIHRoaXMuc2V0VGltZW91dCh0b29sdGlwKTtcbiAgfVxuXG4gIHJldHVybiBpZDtcbn07XG5cblRvb2x0aXBzLnByb3RvdHlwZS50cmlnZ2VyID0gZnVuY3Rpb24oYWN0aW9uLCBldmVudCkge1xuXG4gIHZhciBub2RlID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQgfHwgZXZlbnQudGFyZ2V0O1xuXG4gIHZhciB0b29sdGlwID0gdGhpcy5nZXQoZG9tQXR0cihub2RlLCAnZGF0YS10b29sdGlwLWlkJykpO1xuXG4gIGlmICghdG9vbHRpcCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmIChhY3Rpb24gPT09ICdtb3VzZW92ZXInICYmIHRvb2x0aXAudGltZW91dCkge1xuICAgIHRoaXMuY2xlYXJUaW1lb3V0KHRvb2x0aXApO1xuICB9XG5cbiAgaWYgKGFjdGlvbiA9PT0gJ21vdXNlb3V0JyAmJiB0b29sdGlwLnRpbWVvdXQpIHtcblxuICAgIC8vIGN1dCB0aW1lb3V0IGFmdGVyIG1vdXNlIG91dFxuICAgIHRvb2x0aXAudGltZW91dCA9IDEwMDA7XG5cbiAgICB0aGlzLnNldFRpbWVvdXQodG9vbHRpcCk7XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGEgdG9vbHRpcCB3aXRoIHRoZSBnaXZlbiBpZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuICovXG5Ub29sdGlwcy5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24oaWQpIHtcblxuICBpZiAodHlwZW9mIGlkICE9PSAnc3RyaW5nJykge1xuICAgIGlkID0gaWQuaWQ7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fdG9vbHRpcHNbaWRdO1xufTtcblxuVG9vbHRpcHMucHJvdG90eXBlLmNsZWFyVGltZW91dCA9IGZ1bmN0aW9uKHRvb2x0aXApIHtcblxuICB0b29sdGlwID0gdGhpcy5nZXQodG9vbHRpcCk7XG5cbiAgaWYgKCF0b29sdGlwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIHJlbW92ZVRpbWVyID0gdG9vbHRpcC5yZW1vdmVUaW1lcjtcblxuICBpZiAocmVtb3ZlVGltZXIpIHtcbiAgICBjbGVhclRpbWVvdXQocmVtb3ZlVGltZXIpO1xuICAgIHRvb2x0aXAucmVtb3ZlVGltZXIgPSBudWxsO1xuICB9XG59O1xuXG5Ub29sdGlwcy5wcm90b3R5cGUuc2V0VGltZW91dCA9IGZ1bmN0aW9uKHRvb2x0aXApIHtcblxuICB0b29sdGlwID0gdGhpcy5nZXQodG9vbHRpcCk7XG5cbiAgaWYgKCF0b29sdGlwKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5jbGVhclRpbWVvdXQodG9vbHRpcCk7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHRvb2x0aXAucmVtb3ZlVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIHNlbGYucmVtb3ZlKHRvb2x0aXApO1xuICB9LCB0b29sdGlwLnRpbWVvdXQpO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgYW4gdG9vbHRpcCB3aXRoIHRoZSBnaXZlbiBpZFxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBpZFxuICovXG5Ub29sdGlwcy5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24oaWQpIHtcblxuICB2YXIgdG9vbHRpcCA9IHRoaXMuZ2V0KGlkKTtcblxuICBpZiAodG9vbHRpcCkge1xuICAgIGRvbVJlbW92ZSh0b29sdGlwLmh0bWwpO1xuICAgIGRvbVJlbW92ZSh0b29sdGlwLmh0bWxDb250YWluZXIpO1xuXG4gICAgZGVsZXRlIHRvb2x0aXAuaHRtbENvbnRhaW5lcjtcblxuICAgIGRlbGV0ZSB0aGlzLl90b29sdGlwc1t0b29sdGlwLmlkXTtcbiAgfVxufTtcblxuXG5Ub29sdGlwcy5wcm90b3R5cGUuc2hvdyA9IGZ1bmN0aW9uKCkge1xuICBzZXRWaXNpYmxlKHRoaXMuX3Rvb2x0aXBSb290KTtcbn07XG5cblxuVG9vbHRpcHMucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbigpIHtcbiAgc2V0VmlzaWJsZSh0aGlzLl90b29sdGlwUm9vdCwgZmFsc2UpO1xufTtcblxuXG5Ub29sdGlwcy5wcm90b3R5cGUuX3VwZGF0ZVJvb3QgPSBmdW5jdGlvbih2aWV3Ym94KSB7XG4gIHZhciBhID0gdmlld2JveC5zY2FsZSB8fCAxO1xuICB2YXIgZCA9IHZpZXdib3guc2NhbGUgfHwgMTtcblxuICB2YXIgbWF0cml4ID0gJ21hdHJpeCgnICsgYSArICcsMCwwLCcgKyBkICsgJywnICsgKC0xICogdmlld2JveC54ICogYSkgKyAnLCcgKyAoLTEgKiB2aWV3Ym94LnkgKiBkKSArICcpJztcblxuICB0aGlzLl90b29sdGlwUm9vdC5zdHlsZS50cmFuc2Zvcm0gPSBtYXRyaXg7XG4gIHRoaXMuX3Rvb2x0aXBSb290LnN0eWxlWyctbXMtdHJhbnNmb3JtJ10gPSBtYXRyaXg7XG59O1xuXG5cblRvb2x0aXBzLnByb3RvdHlwZS5fYWRkVG9vbHRpcCA9IGZ1bmN0aW9uKHRvb2x0aXApIHtcblxuICB2YXIgaWQgPSB0b29sdGlwLmlkLFxuICAgICAgaHRtbCA9IHRvb2x0aXAuaHRtbCxcbiAgICAgIGh0bWxDb250YWluZXIsXG4gICAgICB0b29sdGlwUm9vdCA9IHRoaXMuX3Rvb2x0aXBSb290O1xuXG4gIC8vIHVud3JhcCBqcXVlcnkgKGZvciB0aG9zZSB3aG8gbmVlZCBpdClcbiAgaWYgKGh0bWwuZ2V0ICYmIGh0bWwuY29uc3RydWN0b3IucHJvdG90eXBlLmpxdWVyeSkge1xuICAgIGh0bWwgPSBodG1sLmdldCgwKTtcbiAgfVxuXG4gIC8vIGNyZWF0ZSBwcm9wZXIgaHRtbCBlbGVtZW50cyBmcm9tXG4gIC8vIHRvb2x0aXAgSFRNTCBzdHJpbmdzXG4gIGlmIChpc1N0cmluZyhodG1sKSkge1xuICAgIGh0bWwgPSBkb21pZnkoaHRtbCk7XG4gIH1cblxuICBodG1sQ29udGFpbmVyID0gZG9taWZ5KCc8ZGl2IGRhdGEtdG9vbHRpcC1pZD1cIicgKyBpZCArICdcIiBjbGFzcz1cIicgKyB0b29sdGlwQ2xhc3MgKyAnXCIgc3R5bGU9XCJwb3NpdGlvbjogYWJzb2x1dGVcIj4nKTtcblxuICBodG1sQ29udGFpbmVyLmFwcGVuZENoaWxkKGh0bWwpO1xuXG4gIGlmICh0b29sdGlwLnR5cGUpIHtcbiAgICBkb21DbGFzc2VzKGh0bWxDb250YWluZXIpLmFkZCgnZGpzLXRvb2x0aXAtJyArIHRvb2x0aXAudHlwZSk7XG4gIH1cblxuICBpZiAodG9vbHRpcC5jbGFzc05hbWUpIHtcbiAgICBkb21DbGFzc2VzKGh0bWxDb250YWluZXIpLmFkZCh0b29sdGlwLmNsYXNzTmFtZSk7XG4gIH1cblxuICB0b29sdGlwLmh0bWxDb250YWluZXIgPSBodG1sQ29udGFpbmVyO1xuXG4gIHRvb2x0aXBSb290LmFwcGVuZENoaWxkKGh0bWxDb250YWluZXIpO1xuXG4gIHRoaXMuX3Rvb2x0aXBzW2lkXSA9IHRvb2x0aXA7XG5cbiAgdGhpcy5fdXBkYXRlVG9vbHRpcCh0b29sdGlwKTtcbn07XG5cblxuVG9vbHRpcHMucHJvdG90eXBlLl91cGRhdGVUb29sdGlwID0gZnVuY3Rpb24odG9vbHRpcCkge1xuXG4gIHZhciBwb3NpdGlvbiA9IHRvb2x0aXAucG9zaXRpb24sXG4gICAgICBodG1sQ29udGFpbmVyID0gdG9vbHRpcC5odG1sQ29udGFpbmVyO1xuXG4gIC8vIHVwZGF0ZSBvdmVybGF5IGh0bWwgYmFzZWQgb24gdG9vbHRpcCB4LCB5XG5cbiAgc2V0UG9zaXRpb24oaHRtbENvbnRhaW5lciwgcG9zaXRpb24ueCwgcG9zaXRpb24ueSk7XG59O1xuXG5cblRvb2x0aXBzLnByb3RvdHlwZS5fdXBkYXRlVG9vbHRpcFZpc2liaWx0eSA9IGZ1bmN0aW9uKHZpZXdib3gpIHtcblxuICBmb3JFYWNoKHRoaXMuX3Rvb2x0aXBzLCBmdW5jdGlvbih0b29sdGlwKSB7XG4gICAgdmFyIHNob3cgPSB0b29sdGlwLnNob3csXG4gICAgICAgIGh0bWxDb250YWluZXIgPSB0b29sdGlwLmh0bWxDb250YWluZXIsXG4gICAgICAgIHZpc2libGUgPSB0cnVlO1xuXG4gICAgaWYgKHNob3cpIHtcbiAgICAgIGlmIChzaG93Lm1pblpvb20gPiB2aWV3Ym94LnNjYWxlIHx8XG4gICAgICAgICAgc2hvdy5tYXhab29tIDwgdmlld2JveC5zY2FsZSkge1xuICAgICAgICB2aXNpYmxlID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIHNldFZpc2libGUoaHRtbENvbnRhaW5lciwgdmlzaWJsZSk7XG4gICAgfVxuICB9KTtcbn07XG5cblRvb2x0aXBzLnByb3RvdHlwZS5faW5pdCA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvLyBzY3JvbGwvem9vbSBpbnRlZ3JhdGlvblxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVZpZXdib3godmlld2JveCkge1xuICAgIHNlbGYuX3VwZGF0ZVJvb3Qodmlld2JveCk7XG4gICAgc2VsZi5fdXBkYXRlVG9vbHRpcFZpc2liaWx0eSh2aWV3Ym94KTtcblxuICAgIHNlbGYuc2hvdygpO1xuICB9XG5cbiAgdGhpcy5fZXZlbnRCdXMub24oJ2NhbnZhcy52aWV3Ym94LmNoYW5naW5nJywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICBzZWxmLmhpZGUoKTtcbiAgfSk7XG5cbiAgdGhpcy5fZXZlbnRCdXMub24oJ2NhbnZhcy52aWV3Ym94LmNoYW5nZWQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHVwZGF0ZVZpZXdib3goZXZlbnQudmlld2JveCk7XG4gIH0pO1xufTtcbiIsImltcG9ydCBUb29sdGlwcyBmcm9tICcuL1Rvb2x0aXBzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAndG9vbHRpcHMnIF0sXG4gIHRvb2x0aXBzOiBbICd0eXBlJywgVG9vbHRpcHMgXVxufTsiLCJpbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRvdWNoRml4KGNhbnZhcywgZXZlbnRCdXMpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZXZlbnRCdXMub24oJ2NhbnZhcy5pbml0JywgZnVuY3Rpb24oZSkge1xuICAgIHNlbGYuYWRkQkJveE1hcmtlcihlLnN2Zyk7XG4gIH0pO1xufVxuXG5Ub3VjaEZpeC4kaW5qZWN0ID0gWyAnY2FudmFzJywgJ2V2ZW50QnVzJyBdO1xuXG5cbi8qKlxuICogU2FmYXJpIG1vYmlsZSAoaU9TIDcpIGRvZXMgbm90IGZpcmUgdG91Y2hzdGFydCBldmVudCBpbiA8U1ZHPiBlbGVtZW50XG4gKiBpZiB0aGVyZSBpcyBubyBzaGFwZSBiZXR3ZWVuIDAsMCBhbmQgdmlld3BvcnQgZWxlbWVudHMgb3JpZ2luLlxuICpcbiAqIFNvIHRvdWNoc3RhcnQgZXZlbnQgaXMgb25seSBmaXJlZCB3aGVuIHRoZSA8ZyBjbGFzcz1cInZpZXdwb3J0XCI+IGVsZW1lbnQgd2FzIGhpdC5cbiAqIFB1dHRpbmcgYW4gZWxlbWVudCBvdmVyIGFuZCBiZWxvdyB0aGUgJ3ZpZXdwb3J0JyBmaXhlcyB0aGF0IGJlaGF2aW9yLlxuICovXG5Ub3VjaEZpeC5wcm90b3R5cGUuYWRkQkJveE1hcmtlciA9IGZ1bmN0aW9uKHN2Zykge1xuXG4gIHZhciBtYXJrZXJTdHlsZSA9IHtcbiAgICBmaWxsOiAnbm9uZScsXG4gICAgY2xhc3M6ICdvdXRlci1ib3VuZC1tYXJrZXInXG4gIH07XG5cbiAgdmFyIHJlY3QxID0gc3ZnQ3JlYXRlKCdyZWN0Jyk7XG4gIHN2Z0F0dHIocmVjdDEsIHtcbiAgICB4OiAtMTAwMDAsXG4gICAgeTogMTAwMDAsXG4gICAgd2lkdGg6IDEwLFxuICAgIGhlaWdodDogMTBcbiAgfSk7XG4gIHN2Z0F0dHIocmVjdDEsIG1hcmtlclN0eWxlKTtcblxuICBzdmdBcHBlbmQoc3ZnLCByZWN0MSk7XG5cbiAgdmFyIHJlY3QyID0gc3ZnQ3JlYXRlKCdyZWN0Jyk7XG4gIHN2Z0F0dHIocmVjdDIsIHtcbiAgICB4OiAxMDAwMCxcbiAgICB5OiAxMDAwMCxcbiAgICB3aWR0aDogMTAsXG4gICAgaGVpZ2h0OiAxMFxuICB9KTtcbiAgc3ZnQXR0cihyZWN0MiwgbWFya2VyU3R5bGUpO1xuXG4gIHN2Z0FwcGVuZChzdmcsIHJlY3QyKTtcbn07XG4iLCJpbXBvcnQge1xuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZXZlbnQgYXMgZG9tRXZlbnQsXG4gIGNsb3Nlc3QgYXMgZG9tQ2xvc2VzdFxufSBmcm9tICdtaW4tZG9tJztcblxuaW1wb3J0IEhhbW1lciBmcm9tICdoYW1tZXJqcyc7XG5cbmltcG9ydCB7XG4gIHRvUG9pbnRcbn0gZnJvbSAnLi4vLi4vdXRpbC9FdmVudCc7XG5cbnZhciBNSU5fWk9PTSA9IDAuMixcbiAgICBNQVhfWk9PTSA9IDQ7XG5cbnZhciBtb3VzZUV2ZW50cyA9IFtcbiAgJ21vdXNlZG93bicsXG4gICdtb3VzZXVwJyxcbiAgJ21vdXNlb3ZlcicsXG4gICdtb3VzZW91dCcsXG4gICdjbGljaycsXG4gICdkYmxjbGljaydcbl07XG5cbmZ1bmN0aW9uIGxvZygpIHtcblxuICAvLyBjb25zb2xlLmxvZy5hcHBseShjb25zb2xlLCBhcmd1bWVudHMpO1xufVxuXG5mdW5jdGlvbiBnZXQoc2VydmljZSwgaW5qZWN0b3IpIHtcbiAgcmV0dXJuIGluamVjdG9yLmdldChzZXJ2aWNlLCBmYWxzZSk7XG59XG5cbmZ1bmN0aW9uIHN0b3BFdmVudChldmVudCkge1xuXG4gIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cbiAgaWYgKHR5cGVvZiBldmVudC5zdG9wUHJvcGFnYXRpb24gPT09ICdmdW5jdGlvbicpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfSBlbHNlIGlmIChldmVudC5zcmNFdmVudCAmJiB0eXBlb2YgZXZlbnQuc3JjRXZlbnQuc3RvcFByb3BhZ2F0aW9uID09PSAnZnVuY3Rpb24nKSB7XG5cbiAgICAvLyBpUGhvbmUgJiBpUGFkXG4gICAgZXZlbnQuc3JjRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBpZiAodHlwZW9mIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICB9XG59XG5cblxuZnVuY3Rpb24gY3JlYXRlVG91Y2hSZWNvZ25pemVyKG5vZGUpIHtcblxuICBmdW5jdGlvbiBzdG9wTW91c2UoZXZlbnQpIHtcblxuICAgIGZvckVhY2gobW91c2VFdmVudHMsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGRvbUV2ZW50LmJpbmQobm9kZSwgZSwgc3RvcEV2ZW50LCB0cnVlKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFsbG93TW91c2UoZXZlbnQpIHtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgZm9yRWFjaChtb3VzZUV2ZW50cywgZnVuY3Rpb24oZSkge1xuICAgICAgICBkb21FdmVudC51bmJpbmQobm9kZSwgZSwgc3RvcEV2ZW50LCB0cnVlKTtcbiAgICAgIH0pO1xuICAgIH0sIDUwMCk7XG4gIH1cblxuICBkb21FdmVudC5iaW5kKG5vZGUsICd0b3VjaHN0YXJ0Jywgc3RvcE1vdXNlLCB0cnVlKTtcbiAgZG9tRXZlbnQuYmluZChub2RlLCAndG91Y2hlbmQnLCBhbGxvd01vdXNlLCB0cnVlKTtcbiAgZG9tRXZlbnQuYmluZChub2RlLCAndG91Y2hjYW5jZWwnLCBhbGxvd01vdXNlLCB0cnVlKTtcblxuICAvLyBBIHRvdWNoIGV2ZW50IHJlY29nbml6ZXIgdGhhdCBoYW5kbGVzXG4gIC8vIHRvdWNoIGV2ZW50cyBvbmx5ICh3ZSBrbm93LCB3ZSBjYW4gYWxyZWFkeSBoYW5kbGVcbiAgLy8gbW91c2UgZXZlbnRzIG91dCBvZiB0aGUgYm94KVxuXG4gIHZhciByZWNvZ25pemVyID0gbmV3IEhhbW1lci5NYW5hZ2VyKG5vZGUsIHtcbiAgICBpbnB1dENsYXNzOiBIYW1tZXIuVG91Y2hJbnB1dCxcbiAgICByZWNvZ25pemVyczogW10sXG4gICAgZG9tRXZlbnRzOiB0cnVlXG4gIH0pO1xuXG5cbiAgdmFyIHRhcCA9IG5ldyBIYW1tZXIuVGFwKCk7XG4gIHZhciBwYW4gPSBuZXcgSGFtbWVyLlBhbih7IHRocmVzaG9sZDogMTAgfSk7XG4gIHZhciBwcmVzcyA9IG5ldyBIYW1tZXIuUHJlc3MoKTtcbiAgdmFyIHBpbmNoID0gbmV3IEhhbW1lci5QaW5jaCgpO1xuXG4gIHZhciBkb3VibGVUYXAgPSBuZXcgSGFtbWVyLlRhcCh7IGV2ZW50OiAnZG91YmxldGFwJywgdGFwczogMiB9KTtcblxuICBwaW5jaC5yZXF1aXJlRmFpbHVyZShwYW4pO1xuICBwaW5jaC5yZXF1aXJlRmFpbHVyZShwcmVzcyk7XG5cbiAgcmVjb2duaXplci5hZGQoWyBwYW4sIHByZXNzLCBwaW5jaCwgZG91YmxlVGFwLCB0YXAgXSk7XG5cbiAgcmVjb2duaXplci5yZXNldCA9IGZ1bmN0aW9uKGZvcmNlKSB7XG4gICAgdmFyIHJlY29nbml6ZXJzID0gdGhpcy5yZWNvZ25pemVycyxcbiAgICAgICAgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvbjtcblxuICAgIGlmIChzZXNzaW9uLnN0b3BwZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsb2coJ3JlY29nbml6ZXInLCAnc3RvcCcpO1xuXG4gICAgcmVjb2duaXplci5zdG9wKGZvcmNlKTtcblxuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgaSwgcjtcblxuICAgICAgbG9nKCdyZWNvZ25pemVyJywgJ3Jlc2V0Jyk7XG4gICAgICBmb3IgKGkgPSAwOyAociA9IHJlY29nbml6ZXJzW2ldKTsgaSsrKSB7XG4gICAgICAgIHIucmVzZXQoKTtcbiAgICAgICAgci5zdGF0ZSA9IDg7IC8vIEZBSUxFRCBTVEFURVxuICAgICAgfVxuXG4gICAgICBzZXNzaW9uLmN1clJlY29nbml6ZXIgPSBudWxsO1xuICAgIH0sIDApO1xuICB9O1xuXG4gIHJlY29nbml6ZXIub24oJ2hhbW1lci5pbnB1dCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnNyY0V2ZW50LmRlZmF1bHRQcmV2ZW50ZWQpIHtcbiAgICAgIHJlY29nbml6ZXIucmVzZXQodHJ1ZSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmVjb2duaXplcjtcbn1cblxuLyoqXG4gKiBBIHBsdWdpbiB0aGF0IHByb3ZpZGVzIHRvdWNoIGV2ZW50cyBmb3IgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7SW50ZXJhY3Rpb25FdmVudHN9IGludGVyYWN0aW9uRXZlbnRzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFRvdWNoSW50ZXJhY3Rpb25FdmVudHMoXG4gICAgaW5qZWN0b3IsIGNhbnZhcywgZXZlbnRCdXMsXG4gICAgZWxlbWVudFJlZ2lzdHJ5LCBpbnRlcmFjdGlvbkV2ZW50cykge1xuXG4gIC8vIG9wdGlvbmFsIGludGVncmF0aW9uc1xuICB2YXIgZHJhZ2dpbmcgPSBnZXQoJ2RyYWdnaW5nJywgaW5qZWN0b3IpLFxuICAgICAgbW92ZSA9IGdldCgnbW92ZScsIGluamVjdG9yKSxcbiAgICAgIGNvbnRleHRQYWQgPSBnZXQoJ2NvbnRleHRQYWQnLCBpbmplY3RvciksXG4gICAgICBwYWxldHRlID0gZ2V0KCdwYWxldHRlJywgaW5qZWN0b3IpO1xuXG4gIC8vIHRoZSB0b3VjaCByZWNvZ25pemVyXG4gIHZhciByZWNvZ25pemVyO1xuXG4gIGZ1bmN0aW9uIGhhbmRsZXIodHlwZSkge1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICBsb2coJ2VsZW1lbnQnLCB0eXBlLCBldmVudCk7XG5cbiAgICAgIGludGVyYWN0aW9uRXZlbnRzLmZpcmUodHlwZSwgZXZlbnQpO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBnZXRHZngodGFyZ2V0KSB7XG4gICAgdmFyIG5vZGUgPSBkb21DbG9zZXN0KHRhcmdldCwgJ3N2ZywgLmRqcy1lbGVtZW50JywgdHJ1ZSk7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBmdW5jdGlvbiBpbml0RXZlbnRzKHN2Zykge1xuXG4gICAgLy8gdG91Y2ggcmVjb2duaXplclxuICAgIHJlY29nbml6ZXIgPSBjcmVhdGVUb3VjaFJlY29nbml6ZXIoc3ZnKTtcblxuICAgIHJlY29nbml6ZXIub24oJ2RvdWJsZXRhcCcsIGhhbmRsZXIoJ2VsZW1lbnQuZGJsY2xpY2snKSk7XG5cbiAgICByZWNvZ25pemVyLm9uKCd0YXAnLCBoYW5kbGVyKCdlbGVtZW50LmNsaWNrJykpO1xuXG4gICAgZnVuY3Rpb24gc3RhcnRHcmFiQ2FudmFzKGV2ZW50KSB7XG5cbiAgICAgIGxvZygnY2FudmFzJywgJ2dyYWIgc3RhcnQnKTtcblxuICAgICAgdmFyIGx4ID0gMCwgbHkgPSAwO1xuXG4gICAgICBmdW5jdGlvbiB1cGRhdGUoZSkge1xuXG4gICAgICAgIHZhciBkeCA9IGUuZGVsdGFYIC0gbHgsXG4gICAgICAgICAgICBkeSA9IGUuZGVsdGFZIC0gbHk7XG5cbiAgICAgICAgY2FudmFzLnNjcm9sbCh7IGR4OiBkeCwgZHk6IGR5IH0pO1xuXG4gICAgICAgIGx4ID0gZS5kZWx0YVg7XG4gICAgICAgIGx5ID0gZS5kZWx0YVk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGVuZChlKSB7XG4gICAgICAgIHJlY29nbml6ZXIub2ZmKCdwYW5tb3ZlJywgdXBkYXRlKTtcbiAgICAgICAgcmVjb2duaXplci5vZmYoJ3BhbmVuZCcsIGVuZCk7XG4gICAgICAgIHJlY29nbml6ZXIub2ZmKCdwYW5jYW5jZWwnLCBlbmQpO1xuXG4gICAgICAgIGxvZygnY2FudmFzJywgJ2dyYWIgZW5kJyk7XG4gICAgICB9XG5cbiAgICAgIHJlY29nbml6ZXIub24oJ3Bhbm1vdmUnLCB1cGRhdGUpO1xuICAgICAgcmVjb2duaXplci5vbigncGFuZW5kJywgZW5kKTtcbiAgICAgIHJlY29nbml6ZXIub24oJ3BhbmNhbmNlbCcsIGVuZCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RhcnRHcmFiKGV2ZW50KSB7XG5cbiAgICAgIHZhciBnZnggPSBnZXRHZngoZXZlbnQudGFyZ2V0KSxcbiAgICAgICAgICBlbGVtZW50ID0gZ2Z4ICYmIGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcblxuICAgICAgLy8gcmVjb2duaXplclxuICAgICAgaWYgKG1vdmUgJiYgY2FudmFzLmdldFJvb3RFbGVtZW50KCkgIT09IGVsZW1lbnQpIHtcbiAgICAgICAgbG9nKCdlbGVtZW50JywgJ21vdmUgc3RhcnQnLCBlbGVtZW50LCBldmVudCwgdHJ1ZSk7XG4gICAgICAgIHJldHVybiBtb3ZlLnN0YXJ0KGV2ZW50LCBlbGVtZW50LCB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0YXJ0R3JhYkNhbnZhcyhldmVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc3RhcnRab29tKGUpIHtcblxuICAgICAgbG9nKCdjYW52YXMnLCAnem9vbSBzdGFydCcpO1xuXG4gICAgICB2YXIgem9vbSA9IGNhbnZhcy56b29tKCksXG4gICAgICAgICAgbWlkID0gZS5jZW50ZXI7XG5cbiAgICAgIGZ1bmN0aW9uIHVwZGF0ZShlKSB7XG5cbiAgICAgICAgdmFyIHJhdGlvID0gMSAtICgxIC0gZS5zY2FsZSkgLyAxLjUwLFxuICAgICAgICAgICAgbmV3Wm9vbSA9IE1hdGgubWF4KE1JTl9aT09NLCBNYXRoLm1pbihNQVhfWk9PTSwgcmF0aW8gKiB6b29tKSk7XG5cbiAgICAgICAgY2FudmFzLnpvb20obmV3Wm9vbSwgbWlkKTtcblxuICAgICAgICBzdG9wRXZlbnQoZSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGVuZChlKSB7XG4gICAgICAgIHJlY29nbml6ZXIub2ZmKCdwaW5jaG1vdmUnLCB1cGRhdGUpO1xuICAgICAgICByZWNvZ25pemVyLm9mZigncGluY2hlbmQnLCBlbmQpO1xuICAgICAgICByZWNvZ25pemVyLm9mZigncGluY2hjYW5jZWwnLCBlbmQpO1xuXG4gICAgICAgIHJlY29nbml6ZXIucmVzZXQodHJ1ZSk7XG5cbiAgICAgICAgbG9nKCdjYW52YXMnLCAnem9vbSBlbmQnKTtcbiAgICAgIH1cblxuICAgICAgcmVjb2duaXplci5vbigncGluY2htb3ZlJywgdXBkYXRlKTtcbiAgICAgIHJlY29nbml6ZXIub24oJ3BpbmNoZW5kJywgZW5kKTtcbiAgICAgIHJlY29nbml6ZXIub24oJ3BpbmNoY2FuY2VsJywgZW5kKTtcbiAgICB9XG5cbiAgICByZWNvZ25pemVyLm9uKCdwYW5zdGFydCcsIHN0YXJ0R3JhYik7XG4gICAgcmVjb2duaXplci5vbigncHJlc3MnLCBzdGFydEdyYWIpO1xuXG4gICAgcmVjb2duaXplci5vbigncGluY2hzdGFydCcsIHN0YXJ0Wm9vbSk7XG4gIH1cblxuICBpZiAoZHJhZ2dpbmcpIHtcblxuICAgIC8vIHNpbXVsYXRlIGhvdmVyIGR1cmluZyBkcmFnZ2luZ1xuICAgIGV2ZW50QnVzLm9uKCdkcmFnLm1vdmUnLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgICB2YXIgb3JpZ2luYWxFdmVudCA9IGV2ZW50Lm9yaWdpbmFsRXZlbnQ7XG5cbiAgICAgIGlmICghb3JpZ2luYWxFdmVudCB8fCBvcmlnaW5hbEV2ZW50IGluc3RhbmNlb2YgTW91c2VFdmVudCkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciBwb3NpdGlvbiA9IHRvUG9pbnQob3JpZ2luYWxFdmVudCk7XG5cbiAgICAgIC8vIHRoaXMgZ2V0cyByZWFsbHkgZXhwZW5zaXZlIC4uLlxuICAgICAgdmFyIG5vZGUgPSBkb2N1bWVudC5lbGVtZW50RnJvbVBvaW50KHBvc2l0aW9uLngsIHBvc2l0aW9uLnkpLFxuICAgICAgICAgIGdmeCA9IGdldEdmeChub2RlKSxcbiAgICAgICAgICBlbGVtZW50ID0gZ2Z4ICYmIGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcblxuICAgICAgaWYgKGVsZW1lbnQgIT09IGV2ZW50LmhvdmVyKSB7XG4gICAgICAgIGlmIChldmVudC5ob3Zlcikge1xuICAgICAgICAgIGRyYWdnaW5nLm91dChldmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZWxlbWVudCkge1xuICAgICAgICAgIGRyYWdnaW5nLmhvdmVyKHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG5cbiAgICAgICAgICBldmVudC5ob3ZlciA9IGVsZW1lbnQ7XG4gICAgICAgICAgZXZlbnQuaG92ZXJHZnggPSBnZng7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChjb250ZXh0UGFkKSB7XG5cbiAgICBldmVudEJ1cy5vbignY29udGV4dFBhZC5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIG5vZGUgPSBldmVudC5wYWQuaHRtbDtcblxuICAgICAgLy8gdG91Y2ggcmVjb2duaXplclxuICAgICAgdmFyIHBhZFJlY29nbml6ZXIgPSBjcmVhdGVUb3VjaFJlY29nbml6ZXIobm9kZSk7XG5cbiAgICAgIHBhZFJlY29nbml6ZXIub24oJ3BhbnN0YXJ0JywgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgbG9nKCdjb250ZXh0LXBhZCcsICdwYW5zdGFydCcsIGV2ZW50KTtcbiAgICAgICAgY29udGV4dFBhZC50cmlnZ2VyKCdkcmFnc3RhcnQnLCBldmVudCwgdHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgcGFkUmVjb2duaXplci5vbigncHJlc3MnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICBsb2coJ2NvbnRleHQtcGFkJywgJ3ByZXNzJywgZXZlbnQpO1xuICAgICAgICBjb250ZXh0UGFkLnRyaWdnZXIoJ2RyYWdzdGFydCcsIGV2ZW50LCB0cnVlKTtcbiAgICAgIH0pO1xuXG4gICAgICBwYWRSZWNvZ25pemVyLm9uKCd0YXAnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICBsb2coJ2NvbnRleHQtcGFkJywgJ3RhcCcsIGV2ZW50KTtcbiAgICAgICAgY29udGV4dFBhZC50cmlnZ2VyKCdjbGljaycsIGV2ZW50KTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHBhbGV0dGUpIHtcbiAgICBldmVudEJ1cy5vbigncGFsZXR0ZS5jcmVhdGUnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgdmFyIG5vZGUgPSBldmVudC5jb250YWluZXI7XG5cbiAgICAgIC8vIHRvdWNoIHJlY29nbml6ZXJcbiAgICAgIHZhciBwYWRSZWNvZ25pemVyID0gY3JlYXRlVG91Y2hSZWNvZ25pemVyKG5vZGUpO1xuXG4gICAgICBwYWRSZWNvZ25pemVyLm9uKCdwYW5zdGFydCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIGxvZygncGFsZXR0ZScsICdwYW5zdGFydCcsIGV2ZW50KTtcbiAgICAgICAgcGFsZXR0ZS50cmlnZ2VyKCdkcmFnc3RhcnQnLCBldmVudCwgdHJ1ZSk7XG4gICAgICB9KTtcblxuICAgICAgcGFkUmVjb2duaXplci5vbigncHJlc3MnLCBmdW5jdGlvbihldmVudCkge1xuICAgICAgICBsb2coJ3BhbGV0dGUnLCAncHJlc3MnLCBldmVudCk7XG4gICAgICAgIHBhbGV0dGUudHJpZ2dlcignZHJhZ3N0YXJ0JywgZXZlbnQsIHRydWUpO1xuICAgICAgfSk7XG5cbiAgICAgIHBhZFJlY29nbml6ZXIub24oJ3RhcCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgICAgIGxvZygncGFsZXR0ZScsICd0YXAnLCBldmVudCk7XG4gICAgICAgIHBhbGV0dGUudHJpZ2dlcignY2xpY2snLCBldmVudCk7XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuaW5pdCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgaW5pdEV2ZW50cyhldmVudC5zdmcpO1xuICB9KTtcbn1cblxuXG5Ub3VjaEludGVyYWN0aW9uRXZlbnRzLiRpbmplY3QgPSBbXG4gICdpbmplY3RvcicsXG4gICdjYW52YXMnLFxuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ2ludGVyYWN0aW9uRXZlbnRzJyxcbiAgJ3RvdWNoRml4J1xuXTtcbiIsImltcG9ydCBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSBmcm9tICcuLi9pbnRlcmFjdGlvbi1ldmVudHMnO1xuXG5pbXBvcnQgVG91Y2hJbnRlcmFjdGlvbkV2ZW50cyBmcm9tICcuL1RvdWNoSW50ZXJhY3Rpb25FdmVudHMnO1xuaW1wb3J0IFRvdWNoRml4IGZyb20gJy4vVG91Y2hGaXgnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9fZGVwZW5kc19fOiBbIEludGVyYWN0aW9uRXZlbnRzTW9kdWxlIF0sXG4gIF9faW5pdF9fOiBbICd0b3VjaEludGVyYWN0aW9uRXZlbnRzJyBdLFxuICB0b3VjaEludGVyYWN0aW9uRXZlbnRzOiBbICd0eXBlJywgVG91Y2hJbnRlcmFjdGlvbkV2ZW50cyBdLFxuICB0b3VjaEZpeDogWyAndHlwZScsIFRvdWNoRml4IF1cbn07IiwiaW1wb3J0IHRyYW5zbGF0ZSBmcm9tICcuL3RyYW5zbGF0ZSc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgdHJhbnNsYXRlOiBbICd2YWx1ZScsIHRyYW5zbGF0ZSBdXG59OyIsIi8qKlxuICogQSBzaW1wbGUgdHJhbnNsYXRpb24gc3R1YiB0byBiZSB1c2VkIGZvciBtdWx0aS1sYW5ndWFnZSBzdXBwb3J0XG4gKiBpbiBkaWFncmFtcy4gQ2FuIGJlIGVhc2lseSByZXBsYWNlZCB3aXRoIGEgbW9yZSBzb3BoaXN0aWNhdGVkXG4gKiBzb2x1dGlvbi5cbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIHVzZSBpdCBpbnNpZGUgYW55IGRpYWdyYW0gY29tcG9uZW50IGJ5IGluamVjdGluZyBgdHJhbnNsYXRlYC5cbiAqXG4gKiBmdW5jdGlvbiBNeVNlcnZpY2UodHJhbnNsYXRlKSB7XG4gKiAgIGFsZXJ0KHRyYW5zbGF0ZSgnSEVMTE8ge3lvdX0nLCB7IHlvdTogJ1lvdSEnIH0pKTtcbiAqIH1cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGVtcGxhdGUgdG8gaW50ZXJwb2xhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbcmVwbGFjZW1lbnRzXSBhIG1hcCB3aXRoIHN1YnN0aXR1dGVzXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgdHJhbnNsYXRlZCBzdHJpbmdcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gdHJhbnNsYXRlKHRlbXBsYXRlLCByZXBsYWNlbWVudHMpIHtcblxuICByZXBsYWNlbWVudHMgPSByZXBsYWNlbWVudHMgfHwge307XG5cbiAgcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoL3soW159XSspfS9nLCBmdW5jdGlvbihfLCBrZXkpIHtcbiAgICByZXR1cm4gcmVwbGFjZW1lbnRzW2tleV0gfHwgJ3snICsga2V5ICsgJ30nO1xuICB9KTtcbn0iLCJpbXBvcnQge1xuICBnZXRNaWRcbn0gZnJvbSAnLi9MYXlvdXRVdGlsJztcblxuXG4vKipcbiAqIEEgYmFzZSBjb25uZWN0aW9uIGxheW91dGVyIGltcGxlbWVudGF0aW9uXG4gKiB0aGF0IGxheW91dHMgdGhlIGNvbm5lY3Rpb24gYnkgZGlyZWN0bHkgY29ubmVjdGluZ1xuICogbWlkKHNvdXJjZSkgKyBtaWQodGFyZ2V0KS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gQmFzZUxheW91dGVyKCkge31cblxuXG4vKipcbiAqIFJldHVybiB0aGUgbmV3IGxheW91dGVkIHdheXBvaW50cyBmb3IgdGhlIGdpdmVuIGNvbm5lY3Rpb24uXG4gKlxuICogVGhlIGNvbm5lY3Rpb24gcGFzc2VkIGlzIHN0aWxsIHVuY2hhbmdlZDsgeW91IG1heSBmaWd1cmUgb3V0IGFib3V0XG4gKiB0aGUgbmV3IGNvbm5lY3Rpb24gc3RhcnQgLyBlbmQgdmlhIHRoZSBsYXlvdXQgaGludHMgcHJvdmlkZWQuXG4gKlxuICogQHBhcmFtIHtkanMubW9kZWwuQ29ubmVjdGlvbn0gY29ubmVjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7UG9pbnR9IFtoaW50cy5jb25uZWN0aW9uU3RhcnRdXG4gKiBAcGFyYW0ge1BvaW50fSBbaGludHMuY29ubmVjdGlvbkVuZF1cbiAqIEBwYXJhbSB7UG9pbnR9IFtoaW50cy5zb3VyY2VdXG4gKiBAcGFyYW0ge1BvaW50fSBbaGludHMudGFyZ2V0XVxuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gdGhlIGxheW91dGVkIGNvbm5lY3Rpb24gd2F5cG9pbnRzXG4gKi9cbkJhc2VMYXlvdXRlci5wcm90b3R5cGUubGF5b3V0Q29ubmVjdGlvbiA9IGZ1bmN0aW9uKGNvbm5lY3Rpb24sIGhpbnRzKSB7XG5cbiAgaGludHMgPSBoaW50cyB8fCB7fTtcblxuICByZXR1cm4gW1xuICAgIGhpbnRzLmNvbm5lY3Rpb25TdGFydCB8fCBnZXRNaWQoaGludHMuc291cmNlIHx8IGNvbm5lY3Rpb24uc291cmNlKSxcbiAgICBoaW50cy5jb25uZWN0aW9uRW5kIHx8IGdldE1pZChoaW50cy50YXJnZXQgfHwgY29ubmVjdGlvbi50YXJnZXQpXG4gIF07XG59O1xuIiwiaW1wb3J0IHtcbiAgYXNzaWduXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0RWxlbWVudExpbmVJbnRlcnNlY3Rpb25cbn0gZnJvbSAnLi9MYXlvdXRVdGlsJztcblxuXG5mdW5jdGlvbiBkb2NraW5nVG9Qb2ludChkb2NraW5nKSB7XG5cbiAgLy8gdXNlIHRoZSBkb2NraW5ncyBhY3R1YWwgcG9pbnQgYW5kXG4gIC8vIHJldGFpbiB0aGUgb3JpZ2luYWwgZG9ja2luZ1xuICByZXR1cm4gYXNzaWduKHsgb3JpZ2luYWw6IGRvY2tpbmcucG9pbnQub3JpZ2luYWwgfHwgZG9ja2luZy5wb2ludCB9LCBkb2NraW5nLmFjdHVhbCk7XG59XG5cblxuLyoqXG4gKiBBIHtAbGluayBDb25uZWN0aW9uRG9ja2luZ30gdGhhdCBjcm9wcyBjb25uZWN0aW9uIHdheXBvaW50cyBiYXNlZCBvblxuICogdGhlIHBhdGgocykgb2YgdGhlIGNvbm5lY3Rpb24gc291cmNlIGFuZCB0YXJnZXQuXG4gKlxuICogQHBhcmFtIHtkanMuY29yZS5FbGVtZW50UmVnaXN0cnl9IGVsZW1lbnRSZWdpc3RyeVxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBDcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nKGVsZW1lbnRSZWdpc3RyeSwgZ3JhcGhpY3NGYWN0b3J5KSB7XG4gIHRoaXMuX2VsZW1lbnRSZWdpc3RyeSA9IGVsZW1lbnRSZWdpc3RyeTtcbiAgdGhpcy5fZ3JhcGhpY3NGYWN0b3J5ID0gZ3JhcGhpY3NGYWN0b3J5O1xufVxuXG5Dcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nLiRpbmplY3QgPSBbICdlbGVtZW50UmVnaXN0cnknLCAnZ3JhcGhpY3NGYWN0b3J5JyBdO1xuXG5cbi8qKlxuICogQGluaGVyaXREb2MgQ29ubmVjdGlvbkRvY2tpbmcjZ2V0Q3JvcHBlZFdheXBvaW50c1xuICovXG5Dcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nLnByb3RvdHlwZS5nZXRDcm9wcGVkV2F5cG9pbnRzID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgc291cmNlLCB0YXJnZXQpIHtcblxuICBzb3VyY2UgPSBzb3VyY2UgfHwgY29ubmVjdGlvbi5zb3VyY2U7XG4gIHRhcmdldCA9IHRhcmdldCB8fCBjb25uZWN0aW9uLnRhcmdldDtcblxuICB2YXIgc291cmNlRG9ja2luZyA9IHRoaXMuZ2V0RG9ja2luZ1BvaW50KGNvbm5lY3Rpb24sIHNvdXJjZSwgdHJ1ZSksXG4gICAgICB0YXJnZXREb2NraW5nID0gdGhpcy5nZXREb2NraW5nUG9pbnQoY29ubmVjdGlvbiwgdGFyZ2V0KTtcblxuICB2YXIgY3JvcHBlZFdheXBvaW50cyA9IGNvbm5lY3Rpb24ud2F5cG9pbnRzLnNsaWNlKHNvdXJjZURvY2tpbmcuaWR4ICsgMSwgdGFyZ2V0RG9ja2luZy5pZHgpO1xuXG4gIGNyb3BwZWRXYXlwb2ludHMudW5zaGlmdChkb2NraW5nVG9Qb2ludChzb3VyY2VEb2NraW5nKSk7XG4gIGNyb3BwZWRXYXlwb2ludHMucHVzaChkb2NraW5nVG9Qb2ludCh0YXJnZXREb2NraW5nKSk7XG5cbiAgcmV0dXJuIGNyb3BwZWRXYXlwb2ludHM7XG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgY29ubmVjdGlvbiBkb2NraW5nIHBvaW50IG9uIHRoZSBzcGVjaWZpZWQgc2hhcGVcbiAqXG4gKiBAaW5oZXJpdERvYyBDb25uZWN0aW9uRG9ja2luZyNnZXREb2NraW5nUG9pbnRcbiAqL1xuQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZy5wcm90b3R5cGUuZ2V0RG9ja2luZ1BvaW50ID0gZnVuY3Rpb24oY29ubmVjdGlvbiwgc2hhcGUsIGRvY2tTdGFydCkge1xuXG4gIHZhciB3YXlwb2ludHMgPSBjb25uZWN0aW9uLndheXBvaW50cyxcbiAgICAgIGRvY2tpbmdJZHgsXG4gICAgICBkb2NraW5nUG9pbnQsXG4gICAgICBjcm9wcGVkUG9pbnQ7XG5cbiAgZG9ja2luZ0lkeCA9IGRvY2tTdGFydCA/IDAgOiB3YXlwb2ludHMubGVuZ3RoIC0gMTtcbiAgZG9ja2luZ1BvaW50ID0gd2F5cG9pbnRzW2RvY2tpbmdJZHhdO1xuXG4gIGNyb3BwZWRQb2ludCA9IHRoaXMuX2dldEludGVyc2VjdGlvbihzaGFwZSwgY29ubmVjdGlvbiwgZG9ja1N0YXJ0KTtcblxuICByZXR1cm4ge1xuICAgIHBvaW50OiBkb2NraW5nUG9pbnQsXG4gICAgYWN0dWFsOiBjcm9wcGVkUG9pbnQgfHwgZG9ja2luZ1BvaW50LFxuICAgIGlkeDogZG9ja2luZ0lkeFxuICB9O1xufTtcblxuXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZy5wcm90b3R5cGUuX2dldEludGVyc2VjdGlvbiA9IGZ1bmN0aW9uKHNoYXBlLCBjb25uZWN0aW9uLCB0YWtlRmlyc3QpIHtcblxuICB2YXIgc2hhcGVQYXRoID0gdGhpcy5fZ2V0U2hhcGVQYXRoKHNoYXBlKSxcbiAgICAgIGNvbm5lY3Rpb25QYXRoID0gdGhpcy5fZ2V0Q29ubmVjdGlvblBhdGgoY29ubmVjdGlvbik7XG5cbiAgcmV0dXJuIGdldEVsZW1lbnRMaW5lSW50ZXJzZWN0aW9uKHNoYXBlUGF0aCwgY29ubmVjdGlvblBhdGgsIHRha2VGaXJzdCk7XG59O1xuXG5Dcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nLnByb3RvdHlwZS5fZ2V0Q29ubmVjdGlvblBhdGggPSBmdW5jdGlvbihjb25uZWN0aW9uKSB7XG4gIHJldHVybiB0aGlzLl9ncmFwaGljc0ZhY3RvcnkuZ2V0Q29ubmVjdGlvblBhdGgoY29ubmVjdGlvbik7XG59O1xuXG5Dcm9wcGluZ0Nvbm5lY3Rpb25Eb2NraW5nLnByb3RvdHlwZS5fZ2V0U2hhcGVQYXRoID0gZnVuY3Rpb24oc2hhcGUpIHtcbiAgcmV0dXJuIHRoaXMuX2dyYXBoaWNzRmFjdG9yeS5nZXRTaGFwZVBhdGgoc2hhcGUpO1xufTtcblxuQ3JvcHBpbmdDb25uZWN0aW9uRG9ja2luZy5wcm90b3R5cGUuX2dldEdmeCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHRoaXMuX2VsZW1lbnRSZWdpc3RyeS5nZXRHcmFwaGljcyhlbGVtZW50KTtcbn07XG4iLCJpbXBvcnQge1xuICBpc09iamVjdCxcbiAgc29ydEJ5XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgcG9pbnREaXN0YW5jZSxcbiAgcG9pbnRzT25MaW5lXG59IGZyb20gJy4uL3V0aWwvR2VvbWV0cnknO1xuXG5pbXBvcnQgaW50ZXJzZWN0UGF0aHMgZnJvbSAncGF0aC1pbnRlcnNlY3Rpb24nO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiByb3VuZEJvdW5kcyhib3VuZHMpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBNYXRoLnJvdW5kKGJvdW5kcy54KSxcbiAgICB5OiBNYXRoLnJvdW5kKGJvdW5kcy55KSxcbiAgICB3aWR0aDogTWF0aC5yb3VuZChib3VuZHMud2lkdGgpLFxuICAgIGhlaWdodDogTWF0aC5yb3VuZChib3VuZHMuaGVpZ2h0KVxuICB9O1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiByb3VuZFBvaW50KHBvaW50KSB7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBNYXRoLnJvdW5kKHBvaW50LngpLFxuICAgIHk6IE1hdGgucm91bmQocG9pbnQueSlcbiAgfTtcbn1cblxuXG4vKipcbiAqIENvbnZlcnQgdGhlIGdpdmVuIGJvdW5kcyB0byBhIHsgdG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0IH0gZGVzY3JpcHRvci5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc3xQb2ludH0gYm91bmRzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNUUkJMKGJvdW5kcykge1xuICByZXR1cm4ge1xuICAgIHRvcDogYm91bmRzLnksXG4gICAgcmlnaHQ6IGJvdW5kcy54ICsgKGJvdW5kcy53aWR0aCB8fCAwKSxcbiAgICBib3R0b206IGJvdW5kcy55ICsgKGJvdW5kcy5oZWlnaHQgfHwgMCksXG4gICAgbGVmdDogYm91bmRzLnhcbiAgfTtcbn1cblxuXG4vKipcbiAqIENvbnZlcnQgYSB7IHRvcCwgbGVmdCwgYm90dG9tLCByaWdodCB9IHRvIGFuIG9iamVjdHMgYm91bmRzLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0cmJsXG4gKlxuICogQHJldHVybiB7Qm91bmRzfVxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNCb3VuZHModHJibCkge1xuICByZXR1cm4ge1xuICAgIHg6IHRyYmwubGVmdCxcbiAgICB5OiB0cmJsLnRvcCxcbiAgICB3aWR0aDogdHJibC5yaWdodCAtIHRyYmwubGVmdCxcbiAgICBoZWlnaHQ6IHRyYmwuYm90dG9tIC0gdHJibC50b3BcbiAgfTtcbn1cblxuXG4vKipcbiAqIEdldCB0aGUgbWlkIG9mIHRoZSBnaXZlbiBib3VuZHMgb3IgcG9pbnQuXG4gKlxuICogQHBhcmFtIHtCb3VuZHN8UG9pbnR9IGJvdW5kc1xuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWlkKGJvdW5kcykge1xuICByZXR1cm4gcm91bmRQb2ludCh7XG4gICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIHx8IDApIC8gMixcbiAgICB5OiBib3VuZHMueSArIChib3VuZHMuaGVpZ2h0IHx8IDApIC8gMlxuICB9KTtcbn1cblxuXG4vLyBvcmllbnRhdGlvbiB1dGlscyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbi8qKlxuICogR2V0IG9yaWVudGF0aW9uIG9mIHRoZSBnaXZlbiByZWN0YW5nbGUgd2l0aCByZXNwZWN0IHRvXG4gKiB0aGUgcmVmZXJlbmNlIHJlY3RhbmdsZS5cbiAqXG4gKiBBIHBhZGRpbmcgKHBvc2l0aXZlIG9yIG5lZ2F0aXZlKSBtYXkgYmUgcGFzc2VkIHRvIGluZmx1ZW5jZVxuICogaG9yaXpvbnRhbCAvIHZlcnRpY2FsIG9yaWVudGF0aW9uIGFuZCBpbnRlcnNlY3Rpb24uXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IHJlY3RcbiAqIEBwYXJhbSB7Qm91bmRzfSByZWZlcmVuY2VcbiAqIEBwYXJhbSB7UG9pbnR8bnVtYmVyfSBwYWRkaW5nXG4gKlxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgb3JpZW50YXRpb247IG9uZSBvZiB0b3AsIHRvcC1sZWZ0LCBsZWZ0LCAuLi4sIGJvdHRvbSwgcmlnaHQgb3IgaW50ZXJzZWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0T3JpZW50YXRpb24ocmVjdCwgcmVmZXJlbmNlLCBwYWRkaW5nKSB7XG5cbiAgcGFkZGluZyA9IHBhZGRpbmcgfHwgMDtcblxuICAvLyBtYWtlIHN1cmUgd2UgY2FuIHVzZSBhbiBvYmplY3QsIHRvb1xuICAvLyBmb3IgaW5kaXZpZHVhbCB7IHgsIHkgfSBwYWRkaW5nXG4gIGlmICghaXNPYmplY3QocGFkZGluZykpIHtcbiAgICBwYWRkaW5nID0geyB4OiBwYWRkaW5nLCB5OiBwYWRkaW5nIH07XG4gIH1cblxuXG4gIHZhciByZWN0T3JpZW50YXRpb24gPSBhc1RSQkwocmVjdCksXG4gICAgICByZWZlcmVuY2VPcmllbnRhdGlvbiA9IGFzVFJCTChyZWZlcmVuY2UpO1xuXG4gIHZhciB0b3AgPSByZWN0T3JpZW50YXRpb24uYm90dG9tICsgcGFkZGluZy55IDw9IHJlZmVyZW5jZU9yaWVudGF0aW9uLnRvcCxcbiAgICAgIHJpZ2h0ID0gcmVjdE9yaWVudGF0aW9uLmxlZnQgLSBwYWRkaW5nLnggPj0gcmVmZXJlbmNlT3JpZW50YXRpb24ucmlnaHQsXG4gICAgICBib3R0b20gPSByZWN0T3JpZW50YXRpb24udG9wIC0gcGFkZGluZy55ID49IHJlZmVyZW5jZU9yaWVudGF0aW9uLmJvdHRvbSxcbiAgICAgIGxlZnQgPSByZWN0T3JpZW50YXRpb24ucmlnaHQgKyBwYWRkaW5nLnggPD0gcmVmZXJlbmNlT3JpZW50YXRpb24ubGVmdDtcblxuICB2YXIgdmVydGljYWwgPSB0b3AgPyAndG9wJyA6IChib3R0b20gPyAnYm90dG9tJyA6IG51bGwpLFxuICAgICAgaG9yaXpvbnRhbCA9IGxlZnQgPyAnbGVmdCcgOiAocmlnaHQgPyAncmlnaHQnIDogbnVsbCk7XG5cbiAgaWYgKGhvcml6b250YWwgJiYgdmVydGljYWwpIHtcbiAgICByZXR1cm4gdmVydGljYWwgKyAnLScgKyBob3Jpem9udGFsO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBob3Jpem9udGFsIHx8IHZlcnRpY2FsIHx8ICdpbnRlcnNlY3QnO1xuICB9XG59XG5cblxuLy8gaW50ZXJzZWN0aW9uIHV0aWxzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBHZXQgaW50ZXJzZWN0aW9uIGJldHdlZW4gYW4gZWxlbWVudCBhbmQgYSBsaW5lIHBhdGguXG4gKlxuICogQHBhcmFtIHtQYXRoRGVmfSBlbGVtZW50UGF0aFxuICogQHBhcmFtIHtQYXRoRGVmfSBsaW5lUGF0aFxuICogQHBhcmFtIHtib29sZWFufSBjcm9wU3RhcnQgY3JvcCBmcm9tIHN0YXJ0IG9yIGVuZFxuICpcbiAqIEByZXR1cm4ge1BvaW50fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RWxlbWVudExpbmVJbnRlcnNlY3Rpb24oZWxlbWVudFBhdGgsIGxpbmVQYXRoLCBjcm9wU3RhcnQpIHtcblxuICB2YXIgaW50ZXJzZWN0aW9ucyA9IGdldEludGVyc2VjdGlvbnMoZWxlbWVudFBhdGgsIGxpbmVQYXRoKTtcblxuICAvLyByZWNvZ25pemUgaW50ZXJzZWN0aW9uc1xuICAvLyBvbmx5IG9uZSAtPiBjaG9vc2VcbiAgLy8gdHdvIGNsb3NlIHRvZ2V0aGVyIC0+IGNob29zZSBmaXJzdFxuICAvLyB0d28gb3IgbW9yZSBkaXN0aW5jdCAtPiBwdWxsIG91dCBhcHByb3ByaWF0ZSBvbmVcbiAgLy8gbm9uZSAtPiBvayAoZmFsbGJhY2sgdG8gcG9pbnQgaXRzZWxmKVxuICBpZiAoaW50ZXJzZWN0aW9ucy5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gcm91bmRQb2ludChpbnRlcnNlY3Rpb25zWzBdKTtcbiAgfSBlbHNlIGlmIChpbnRlcnNlY3Rpb25zLmxlbmd0aCA9PT0gMiAmJiBwb2ludERpc3RhbmNlKGludGVyc2VjdGlvbnNbMF0sIGludGVyc2VjdGlvbnNbMV0pIDwgMSkge1xuICAgIHJldHVybiByb3VuZFBvaW50KGludGVyc2VjdGlvbnNbMF0pO1xuICB9IGVsc2UgaWYgKGludGVyc2VjdGlvbnMubGVuZ3RoID4gMSkge1xuXG4gICAgLy8gc29ydCBieSBpbnRlcnNlY3Rpb25zIGJhc2VkIG9uIGNvbm5lY3Rpb24gc2VnbWVudCArXG4gICAgLy8gZGlzdGFuY2UgZnJvbSBzdGFydFxuICAgIGludGVyc2VjdGlvbnMgPSBzb3J0QnkoaW50ZXJzZWN0aW9ucywgZnVuY3Rpb24oaSkge1xuICAgICAgdmFyIGRpc3RhbmNlID0gTWF0aC5mbG9vcihpLnQyICogMTAwKSB8fCAxO1xuXG4gICAgICBkaXN0YW5jZSA9IDEwMCAtIGRpc3RhbmNlO1xuXG4gICAgICBkaXN0YW5jZSA9IChkaXN0YW5jZSA8IDEwID8gJzAnIDogJycpICsgZGlzdGFuY2U7XG5cbiAgICAgIC8vIGNyZWF0ZSBhIHNvcnQgc3RyaW5nIHRoYXQgbWFrZXMgc3VyZSB3ZSBzb3J0XG4gICAgICAvLyBsaW5lIHNlZ21lbnQgQVNDICsgbGluZSBzZWdtZW50IHBvc2l0aW9uIERFU0MgKGZvciBjcm9wU3RhcnQpXG4gICAgICAvLyBsaW5lIHNlZ21lbnQgQVNDICsgbGluZSBzZWdtZW50IHBvc2l0aW9uIEFTQyAoZm9yIGNyb3BFbmQpXG4gICAgICByZXR1cm4gaS5zZWdtZW50MiArICcjJyArIGRpc3RhbmNlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJvdW5kUG9pbnQoaW50ZXJzZWN0aW9uc1tjcm9wU3RhcnQgPyAwIDogaW50ZXJzZWN0aW9ucy5sZW5ndGggLSAxXSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW50ZXJzZWN0aW9ucyhhLCBiKSB7XG4gIHJldHVybiBpbnRlcnNlY3RQYXRocyhhLCBiKTtcbn1cblxuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyUmVkdW5kYW50V2F5cG9pbnRzKHdheXBvaW50cykge1xuXG4gIC8vIGFsdGVyIGNvcHkgb2Ygd2F5cG9pbnRzLCBub3Qgb3JpZ2luYWxcbiAgd2F5cG9pbnRzID0gd2F5cG9pbnRzLnNsaWNlKCk7XG5cbiAgdmFyIGlkeCA9IDAsXG4gICAgICBwb2ludCxcbiAgICAgIHByZXZpb3VzUG9pbnQsXG4gICAgICBuZXh0UG9pbnQ7XG5cbiAgd2hpbGUgKHdheXBvaW50c1tpZHhdKSB7XG4gICAgcG9pbnQgPSB3YXlwb2ludHNbaWR4XTtcbiAgICBwcmV2aW91c1BvaW50ID0gd2F5cG9pbnRzW2lkeCAtIDFdO1xuICAgIG5leHRQb2ludCA9IHdheXBvaW50c1tpZHggKyAxXTtcblxuICAgIGlmIChwb2ludERpc3RhbmNlKHBvaW50LCBuZXh0UG9pbnQpID09PSAwIHx8XG4gICAgICAgIHBvaW50c09uTGluZShwcmV2aW91c1BvaW50LCBuZXh0UG9pbnQsIHBvaW50KSkge1xuXG4gICAgICAvLyByZW1vdmUgcG9pbnQsIGlmIG92ZXJsYXBwaW5nIHdpdGgge25leHRQb2ludH1cbiAgICAgIC8vIG9yIG9uIGxpbmUgd2l0aCB7cHJldmlvdXNQb2ludH0gLT4ge3BvaW50fSAtPiB7bmV4dFBvaW50fVxuICAgICAgd2F5cG9pbnRzLnNwbGljZShpZHgsIDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZHgrKztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gd2F5cG9pbnRzO1xufVxuIiwiaW1wb3J0IHtcbiAgYXNzaWduLFxuICBmaW5kLFxuICBpc0FycmF5LFxuICB3aXRob3V0XG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgZ2V0T3JpZW50YXRpb24sXG4gIGdldE1pZFxufSBmcm9tICcuL0xheW91dFV0aWwnO1xuXG5pbXBvcnQge1xuICBwb2ludEluUmVjdCxcbiAgcG9pbnREaXN0YW5jZSxcbiAgcG9pbnRzQWxpZ25lZCxcbiAgcG9pbnRzT25MaW5lXG59IGZyb20gJy4uL3V0aWwvR2VvbWV0cnknO1xuXG52YXIgTUlOX1NFR01FTlRfTEVOR1RIID0gMjAsXG4gICAgUE9JTlRfT1JJRU5UQVRJT05fUEFERElORyA9IDU7XG5cbnZhciByb3VuZCA9IE1hdGgucm91bmQ7XG5cbnZhciBJTlRFUlNFQ1RJT05fVEhSRVNIT0xEID0gMjAsXG4gICAgT1JJRU5UQVRJT05fVEhSRVNIT0xEID0ge1xuICAgICAgJ2g6aCc6IDIwLFxuICAgICAgJ3Y6dic6IDIwLFxuICAgICAgJ2g6dic6IC0xMCxcbiAgICAgICd2OmgnOiAtMTBcbiAgICB9O1xuXG5mdW5jdGlvbiBuZWVkc1R1cm4ob3JpZW50YXRpb24sIHN0YXJ0RGlyZWN0aW9uKSB7XG4gIHJldHVybiAhe1xuICAgIHQ6IC90b3AvLFxuICAgIHI6IC9yaWdodC8sXG4gICAgYjogL2JvdHRvbS8sXG4gICAgbDogL2xlZnQvLFxuICAgIGg6IC8uLyxcbiAgICB2OiAvLi9cbiAgfVtzdGFydERpcmVjdGlvbl0udGVzdChvcmllbnRhdGlvbik7XG59XG5cbmZ1bmN0aW9uIGNhbkxheW91dFN0cmFpZ2h0KGRpcmVjdGlvbiwgdGFyZ2V0T3JpZW50YXRpb24pIHtcbiAgcmV0dXJuIHtcbiAgICB0OiAvdG9wLyxcbiAgICByOiAvcmlnaHQvLFxuICAgIGI6IC9ib3R0b20vLFxuICAgIGw6IC9sZWZ0LyxcbiAgICBoOiAvbGVmdHxyaWdodC8sXG4gICAgdjogL3RvcHxib3R0b20vXG4gIH1bZGlyZWN0aW9uXS50ZXN0KHRhcmdldE9yaWVudGF0aW9uKTtcbn1cblxuZnVuY3Rpb24gZ2V0U2VnbWVudEJlbmRwb2ludHMoYSwgYiwgZGlyZWN0aW9ucykge1xuICB2YXIgb3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihiLCBhLCBQT0lOVF9PUklFTlRBVElPTl9QQURESU5HKTtcblxuICB2YXIgc3RhcnREaXJlY3Rpb24gPSBkaXJlY3Rpb25zLnNwbGl0KCc6JylbMF07XG5cbiAgdmFyIHhtaWQgPSByb3VuZCgoYi54IC0gYS54KSAvIDIgKyBhLngpLFxuICAgICAgeW1pZCA9IHJvdW5kKChiLnkgLSBhLnkpIC8gMiArIGEueSk7XG5cbiAgdmFyIHNlZ21lbnRFbmQsIHNlZ21lbnREaXJlY3Rpb25zO1xuXG4gIHZhciBsYXlvdXRTdHJhaWdodCA9IGNhbkxheW91dFN0cmFpZ2h0KHN0YXJ0RGlyZWN0aW9uLCBvcmllbnRhdGlvbiksXG4gICAgICBsYXlvdXRIb3Jpem9udGFsID0gL2h8cnxsLy50ZXN0KHN0YXJ0RGlyZWN0aW9uKSxcbiAgICAgIGxheW91dFR1cm4gPSBmYWxzZTtcblxuICB2YXIgdHVybk5leHREaXJlY3Rpb25zID0gZmFsc2U7XG5cbiAgaWYgKGxheW91dFN0cmFpZ2h0KSB7XG4gICAgc2VnbWVudEVuZCA9IGxheW91dEhvcml6b250YWwgPyB7IHg6IHhtaWQsIHk6IGEueSB9IDogeyB4OiBhLngsIHk6IHltaWQgfTtcblxuICAgIHNlZ21lbnREaXJlY3Rpb25zID0gbGF5b3V0SG9yaXpvbnRhbCA/ICdoOmgnIDogJ3Y6dic7XG4gIH0gZWxzZSB7XG4gICAgbGF5b3V0VHVybiA9IG5lZWRzVHVybihvcmllbnRhdGlvbiwgc3RhcnREaXJlY3Rpb24pO1xuXG4gICAgc2VnbWVudERpcmVjdGlvbnMgPSBsYXlvdXRIb3Jpem9udGFsID8gJ2g6dicgOiAndjpoJztcblxuICAgIGlmIChsYXlvdXRUdXJuKSB7XG5cbiAgICAgIGlmIChsYXlvdXRIb3Jpem9udGFsKSB7XG4gICAgICAgIHR1cm5OZXh0RGlyZWN0aW9ucyA9IHltaWQgPT09IGEueTtcblxuICAgICAgICBzZWdtZW50RW5kID0ge1xuICAgICAgICAgIHg6IGEueCArIE1JTl9TRUdNRU5UX0xFTkdUSCAqICgvbC8udGVzdChzdGFydERpcmVjdGlvbikgPyAtMSA6IDEpLFxuICAgICAgICAgIHk6IHR1cm5OZXh0RGlyZWN0aW9ucyA/IHltaWQgKyBNSU5fU0VHTUVOVF9MRU5HVEggOiB5bWlkXG4gICAgICAgIH07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0dXJuTmV4dERpcmVjdGlvbnMgPSB4bWlkID09PSBhLng7XG5cbiAgICAgICAgc2VnbWVudEVuZCA9IHtcbiAgICAgICAgICB4OiB0dXJuTmV4dERpcmVjdGlvbnMgPyB4bWlkICsgTUlOX1NFR01FTlRfTEVOR1RIIDogeG1pZCxcbiAgICAgICAgICB5OiBhLnkgKyBNSU5fU0VHTUVOVF9MRU5HVEggKiAoL3QvLnRlc3Qoc3RhcnREaXJlY3Rpb24pID8gLTEgOiAxKVxuICAgICAgICB9O1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIHNlZ21lbnRFbmQgPSB7XG4gICAgICAgIHg6IHhtaWQsXG4gICAgICAgIHk6IHltaWRcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3YXlwb2ludHM6IGdldEJlbmRwb2ludHMoYSwgc2VnbWVudEVuZCwgc2VnbWVudERpcmVjdGlvbnMpLmNvbmNhdChzZWdtZW50RW5kKSxcbiAgICBkaXJlY3Rpb25zOiAgc2VnbWVudERpcmVjdGlvbnMsXG4gICAgdHVybk5leHREaXJlY3Rpb25zOiB0dXJuTmV4dERpcmVjdGlvbnNcbiAgfTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RhcnRTZWdtZW50KGEsIGIsIGRpcmVjdGlvbnMpIHtcbiAgcmV0dXJuIGdldFNlZ21lbnRCZW5kcG9pbnRzKGEsIGIsIGRpcmVjdGlvbnMpO1xufVxuXG5mdW5jdGlvbiBnZXRFbmRTZWdtZW50KGEsIGIsIGRpcmVjdGlvbnMpIHtcbiAgdmFyIGludmVydGVkU2VnbWVudCA9IGdldFNlZ21lbnRCZW5kcG9pbnRzKGIsIGEsIGludmVydERpcmVjdGlvbnMoZGlyZWN0aW9ucykpO1xuXG4gIHJldHVybiB7XG4gICAgd2F5cG9pbnRzOiBpbnZlcnRlZFNlZ21lbnQud2F5cG9pbnRzLnNsaWNlKCkucmV2ZXJzZSgpLFxuICAgIGRpcmVjdGlvbnM6IGludmVydERpcmVjdGlvbnMoaW52ZXJ0ZWRTZWdtZW50LmRpcmVjdGlvbnMpLFxuICAgIHR1cm5OZXh0RGlyZWN0aW9uczogaW52ZXJ0ZWRTZWdtZW50LnR1cm5OZXh0RGlyZWN0aW9uc1xuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRNaWRTZWdtZW50KHN0YXJ0U2VnbWVudCwgZW5kU2VnbWVudCkge1xuXG4gIHZhciBzdGFydERpcmVjdGlvbiA9IHN0YXJ0U2VnbWVudC5kaXJlY3Rpb25zLnNwbGl0KCc6JylbMV0sXG4gICAgICBlbmREaXJlY3Rpb24gPSBlbmRTZWdtZW50LmRpcmVjdGlvbnMuc3BsaXQoJzonKVswXTtcblxuICBpZiAoc3RhcnRTZWdtZW50LnR1cm5OZXh0RGlyZWN0aW9ucykge1xuICAgIHN0YXJ0RGlyZWN0aW9uID0gc3RhcnREaXJlY3Rpb24gPT0gJ2gnID8gJ3YnIDogJ2gnO1xuICB9XG5cbiAgaWYgKGVuZFNlZ21lbnQudHVybk5leHREaXJlY3Rpb25zKSB7XG4gICAgZW5kRGlyZWN0aW9uID0gZW5kRGlyZWN0aW9uID09ICdoJyA/ICd2JyA6ICdoJztcbiAgfVxuXG4gIHZhciBkaXJlY3Rpb25zID0gc3RhcnREaXJlY3Rpb24gKyAnOicgKyBlbmREaXJlY3Rpb247XG5cbiAgdmFyIGJlbmRwb2ludHMgPSBnZXRCZW5kcG9pbnRzKFxuICAgIHN0YXJ0U2VnbWVudC53YXlwb2ludHNbc3RhcnRTZWdtZW50LndheXBvaW50cy5sZW5ndGggLSAxXSxcbiAgICBlbmRTZWdtZW50LndheXBvaW50c1swXSxcbiAgICBkaXJlY3Rpb25zXG4gICk7XG5cbiAgcmV0dXJuIHtcbiAgICB3YXlwb2ludHM6IGJlbmRwb2ludHMsXG4gICAgZGlyZWN0aW9uczogZGlyZWN0aW9uc1xuICB9O1xufVxuXG5mdW5jdGlvbiBpbnZlcnREaXJlY3Rpb25zKGRpcmVjdGlvbnMpIHtcbiAgcmV0dXJuIGRpcmVjdGlvbnMuc3BsaXQoJzonKS5yZXZlcnNlKCkuam9pbignOicpO1xufVxuXG4vKipcbiAqIEhhbmRsZSBzaW1wbGUgbGF5b3V0cyB3aXRoIG1heGltdW0gdHdvIGJlbmRwb2ludHMuXG4gKi9cbmZ1bmN0aW9uIGdldFNpbXBsZUJlbmRwb2ludHMoYSwgYiwgZGlyZWN0aW9ucykge1xuXG4gIHZhciB4bWlkID0gcm91bmQoKGIueCAtIGEueCkgLyAyICsgYS54KSxcbiAgICAgIHltaWQgPSByb3VuZCgoYi55IC0gYS55KSAvIDIgKyBhLnkpO1xuXG4gIC8vIG9uZSBwb2ludCwgcmlnaHQgb3IgbGVmdCBmcm9tIGFcbiAgaWYgKGRpcmVjdGlvbnMgPT09ICdoOnYnKSB7XG4gICAgcmV0dXJuIFsgeyB4OiBiLngsIHk6IGEueSB9IF07XG4gIH1cblxuICAvLyBvbmUgcG9pbnQsIGFib3ZlIG9yIGJlbG93IGFcbiAgaWYgKGRpcmVjdGlvbnMgPT09ICd2OmgnKSB7XG4gICAgcmV0dXJuIFsgeyB4OiBhLngsIHk6IGIueSB9IF07XG4gIH1cblxuICAvLyB2ZXJ0aWNhbCBzZWdtZW50IGJldHdlZW4gYSBhbmQgYlxuICBpZiAoZGlyZWN0aW9ucyA9PT0gJ2g6aCcpIHtcbiAgICByZXR1cm4gW1xuICAgICAgeyB4OiB4bWlkLCB5OiBhLnkgfSxcbiAgICAgIHsgeDogeG1pZCwgeTogYi55IH1cbiAgICBdO1xuICB9XG5cbiAgLy8gaG9yaXpvbnRhbCBzZWdtZW50IGJldHdlZW4gYSBhbmQgYlxuICBpZiAoZGlyZWN0aW9ucyA9PT0gJ3Y6dicpIHtcbiAgICByZXR1cm4gW1xuICAgICAgeyB4OiBhLngsIHk6IHltaWQgfSxcbiAgICAgIHsgeDogYi54LCB5OiB5bWlkIH1cbiAgICBdO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGRpcmVjdGlvbnM6IGNhbiBvbmx5IGhhbmRsZSB2YXJpYW5zIG9mIFtodl06W2h2XScpO1xufVxuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgbWlkIHBvaW50cyBmb3IgYSBtYW5oYXR0YW4gY29ubmVjdGlvbiBiZXR3ZWVuIHR3byBwb2ludHMuXG4gKlxuICogQGV4YW1wbGUgaDpoIChob3Jpem9udGFsOmhvcml6b250YWwpXG4gKlxuICogW2FdLS0tLVt4XVxuICogICAgICAgICB8XG4gKiAgICAgICAgW3hdLS0tLVtiXVxuICpcbiAqIEBleGFtcGxlIGg6diAoaG9yaXpvbnRhbDp2ZXJ0aWNhbClcbiAqXG4gKiBbYV0tLS0tW3hdXG4gKiAgICAgICAgIHxcbiAqICAgICAgICBbYl1cbiAqXG4gKiBAZXhhbXBsZSBoOnIgKGhvcml6b250YWw6cmlnaHQpXG4gKlxuICogW2FdLS0tLVt4XVxuICogICAgICAgICB8XG4gKiAgICBbYl0tW3hdXG4gKlxuICogQHBhcmFtICB7UG9pbnR9IGFcbiAqIEBwYXJhbSAge1BvaW50fSBiXG4gKiBAcGFyYW0gIHtzdHJpbmd9IGRpcmVjdGlvbnNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxQb2ludD59XG4gKi9cbmZ1bmN0aW9uIGdldEJlbmRwb2ludHMoYSwgYiwgZGlyZWN0aW9ucykge1xuICBkaXJlY3Rpb25zID0gZGlyZWN0aW9ucyB8fCAnaDpoJztcblxuICBpZiAoIWlzVmFsaWREaXJlY3Rpb25zKGRpcmVjdGlvbnMpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ3Vua25vd24gZGlyZWN0aW9uczogPCcgKyBkaXJlY3Rpb25zICsgJz46ICcgK1xuICAgICAgJ211c3QgYmUgc3BlY2lmaWVkIGFzIDxzdGFydD46PGVuZD4gJyArXG4gICAgICAnd2l0aCBzdGFydC9lbmQgaW4geyBoLHYsdCxyLGIsbCB9J1xuICAgICk7XG4gIH1cblxuICAvLyBjb21wdXRlIGV4cGxpY2l0IGRpcmVjdGlvbnMsIGludm9sdmluZyB0cmJsIGRvY2tpbmdzXG4gIC8vIHVzaW5nIGEgdGhyZWUgc2VnbWVudGVkIGxheW91dGluZyBhbGdvcml0aG1cbiAgaWYgKGlzRXhwbGljaXREaXJlY3Rpb25zKGRpcmVjdGlvbnMpKSB7XG4gICAgdmFyIHN0YXJ0U2VnbWVudCA9IGdldFN0YXJ0U2VnbWVudChhLCBiLCBkaXJlY3Rpb25zKSxcbiAgICAgICAgZW5kU2VnbWVudCA9IGdldEVuZFNlZ21lbnQoYSwgYiwgZGlyZWN0aW9ucyksXG4gICAgICAgIG1pZFNlZ21lbnQgPSBnZXRNaWRTZWdtZW50KHN0YXJ0U2VnbWVudCwgZW5kU2VnbWVudCk7XG5cbiAgICByZXR1cm4gW10uY29uY2F0KFxuICAgICAgc3RhcnRTZWdtZW50LndheXBvaW50cyxcbiAgICAgIG1pZFNlZ21lbnQud2F5cG9pbnRzLFxuICAgICAgZW5kU2VnbWVudC53YXlwb2ludHNcbiAgICApO1xuICB9XG5cbiAgLy8gaGFuZGxlIHNpbXBsZSBbaHZdOltodl0gY2FzZXMgdGhhdCBjYW4gYmUgZWFzaWx5IGNvbXB1dGVkXG4gIHJldHVybiBnZXRTaW1wbGVCZW5kcG9pbnRzKGEsIGIsIGRpcmVjdGlvbnMpO1xufVxuXG4vKipcbiAqIENyZWF0ZSBhIGNvbm5lY3Rpb24gYmV0d2VlbiB0aGUgdHdvIHBvaW50cyBhY2NvcmRpbmdcbiAqIHRvIHRoZSBtYW5oYXR0YW4gbGF5b3V0IChvbmx5IGhvcml6b250YWwgYW5kIHZlcnRpY2FsKSBlZGdlcy5cbiAqXG4gKiBAcGFyYW0ge1BvaW50fSBhXG4gKiBAcGFyYW0ge1BvaW50fSBiXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IFtkaXJlY3Rpb25zPSdoOmgnXSBzcGVjaWZpZXMgbWFuaGF0dGFuIGRpcmVjdGlvbnMgZm9yIGVhY2ggcG9pbnQgYXMge2FkaXJlY3Rpb259OntiZGlyZWN0aW9ufS5cbiAgICAgICAgICAgICAgICAgICBBIGRpcmVjdGlvbmZvciBhIHBvaW50IGlzIGVpdGhlciBgaGAgKGhvcml6b250YWwpIG9yIGB2YCAodmVydGljYWwpXG4gKlxuICogQHJldHVybiB7QXJyYXk8UG9pbnQ+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gY29ubmVjdFBvaW50cyhhLCBiLCBkaXJlY3Rpb25zKSB7XG5cbiAgdmFyIHBvaW50cyA9IGdldEJlbmRwb2ludHMoYSwgYiwgZGlyZWN0aW9ucyk7XG5cbiAgcG9pbnRzLnVuc2hpZnQoYSk7XG4gIHBvaW50cy5wdXNoKGIpO1xuXG4gIHJldHVybiB3aXRob3V0UmVkdW5kYW50UG9pbnRzKHBvaW50cyk7XG59XG5cblxuLyoqXG4gKiBDb25uZWN0IHR3byByZWN0YW5nbGVzIHVzaW5nIGEgbWFuaGF0dGFuIGxheW91dGVkIGNvbm5lY3Rpb24uXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IHNvdXJjZSBzb3VyY2UgcmVjdGFuZ2xlXG4gKiBAcGFyYW0ge0JvdW5kc30gdGFyZ2V0IHRhcmdldCByZWN0YW5nbGVcbiAqIEBwYXJhbSB7UG9pbnR9IFtzdGFydF0gc291cmNlIGRvY2tpbmdcbiAqIEBwYXJhbSB7UG9pbnR9IFtlbmRdIHRhcmdldCBkb2NraW5nXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqIEBwYXJhbSB7c3RyaW5nfSBbaGludHMucHJlc2VydmVEb2NraW5nPXNvdXJjZV0gcHJlc2VydmUgZG9ja2luZyBvbiBzZWxlY3RlZCBzaWRlXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtoaW50cy5wcmVmZXJyZWRMYXlvdXRzXVxuICogQHBhcmFtIHtQb2ludHxib29sZWFufSBbaGludHMuY29ubmVjdGlvblN0YXJ0XSB3aGV0aGVyIHRoZSBzdGFydCBjaGFuZ2VkXG4gKiBAcGFyYW0ge1BvaW50fGJvb2xlYW59IFtoaW50cy5jb25uZWN0aW9uRW5kXSB3aGV0aGVyIHRoZSBlbmQgY2hhbmdlZFxuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gY29ubmVjdGlvbiBwb2ludHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbm5lY3RSZWN0YW5nbGVzKHNvdXJjZSwgdGFyZ2V0LCBzdGFydCwgZW5kLCBoaW50cykge1xuXG4gIHZhciBwcmVmZXJyZWRMYXlvdXRzID0gaGludHMgJiYgaGludHMucHJlZmVycmVkTGF5b3V0cyB8fCBbXTtcblxuICB2YXIgcHJlZmVycmVkTGF5b3V0ID0gd2l0aG91dChwcmVmZXJyZWRMYXlvdXRzLCAnc3RyYWlnaHQnKVswXSB8fCAnaDpoJztcblxuICB2YXIgdGhyZXNob2xkID0gT1JJRU5UQVRJT05fVEhSRVNIT0xEW3ByZWZlcnJlZExheW91dF0gfHwgMDtcblxuICB2YXIgb3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihzb3VyY2UsIHRhcmdldCwgdGhyZXNob2xkKTtcblxuICB2YXIgZGlyZWN0aW9ucyA9IGdldERpcmVjdGlvbnMob3JpZW50YXRpb24sIHByZWZlcnJlZExheW91dCk7XG5cbiAgc3RhcnQgPSBzdGFydCB8fCBnZXRNaWQoc291cmNlKTtcbiAgZW5kID0gZW5kIHx8IGdldE1pZCh0YXJnZXQpO1xuXG4gIHZhciBkaXJlY3Rpb25TcGxpdCA9IGRpcmVjdGlvbnMuc3BsaXQoJzonKTtcblxuICAvLyBjb21wdXRlIGFjdHVhbCBkb2NraW5nIHBvaW50cyBmb3Igc3RhcnQgLyBlbmRcbiAgLy8gdGhpcyBlbnN1cmVzIHdlIHByb3Blcmx5IGxheW91dCBvbmx5IHBhcnRzIG9mIHRoZVxuICAvLyBjb25uZWN0aW9uIHRoYXQgbGllcyBpbiBiZXR3ZWVuIHRoZSB0d28gcmVjdGFuZ2xlc1xuICB2YXIgc3RhcnREb2NraW5nID0gZ2V0RG9ja2luZ1BvaW50KHN0YXJ0LCBzb3VyY2UsIGRpcmVjdGlvblNwbGl0WzBdLCBpbnZlcnRPcmllbnRhdGlvbihvcmllbnRhdGlvbikpLFxuICAgICAgZW5kRG9ja2luZyA9IGdldERvY2tpbmdQb2ludChlbmQsIHRhcmdldCwgZGlyZWN0aW9uU3BsaXRbMV0sIG9yaWVudGF0aW9uKTtcblxuICByZXR1cm4gY29ubmVjdFBvaW50cyhzdGFydERvY2tpbmcsIGVuZERvY2tpbmcsIGRpcmVjdGlvbnMpO1xufVxuXG5cbi8qKlxuICogUmVwYWlyIHRoZSBjb25uZWN0aW9uIGJldHdlZW4gdHdvIHJlY3RhbmdsZXMsIG9mIHdoaWNoIG9uZSBoYXMgYmVlbiB1cGRhdGVkLlxuICpcbiAqIEBwYXJhbSB7Qm91bmRzfSBzb3VyY2VcbiAqIEBwYXJhbSB7Qm91bmRzfSB0YXJnZXRcbiAqIEBwYXJhbSB7UG9pbnR9IFtzdGFydF1cbiAqIEBwYXJhbSB7UG9pbnR9IFtlbmRdXG4gKiBAcGFyYW0ge0FycmF5PFBvaW50Pn0gW3dheXBvaW50c11cbiAqIEBwYXJhbSB7T2JqZWN0fSBbaGludHNdXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtoaW50cy5wcmVmZXJyZWRMYXlvdXRzXSBsaXN0IG9mIHByZWZlcnJlZCBsYXlvdXRzXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtoaW50cy5jb25uZWN0aW9uU3RhcnRdXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtoaW50cy5jb25uZWN0aW9uRW5kXVxuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50Pn0gcmVwYWlyZWQgd2F5cG9pbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBhaXJDb25uZWN0aW9uKHNvdXJjZSwgdGFyZ2V0LCBzdGFydCwgZW5kLCB3YXlwb2ludHMsIGhpbnRzKSB7XG5cbiAgaWYgKGlzQXJyYXkoc3RhcnQpKSB7XG4gICAgd2F5cG9pbnRzID0gc3RhcnQ7XG4gICAgaGludHMgPSBlbmQ7XG5cbiAgICBzdGFydCA9IGdldE1pZChzb3VyY2UpO1xuICAgIGVuZCA9IGdldE1pZCh0YXJnZXQpO1xuICB9XG5cbiAgaGludHMgPSBhc3NpZ24oeyBwcmVmZXJyZWRMYXlvdXRzOiBbXSB9LCBoaW50cyk7XG4gIHdheXBvaW50cyA9IHdheXBvaW50cyB8fCBbXTtcblxuICB2YXIgcHJlZmVycmVkTGF5b3V0cyA9IGhpbnRzLnByZWZlcnJlZExheW91dHMsXG4gICAgICBwcmVmZXJTdHJhaWdodCA9IHByZWZlcnJlZExheW91dHMuaW5kZXhPZignc3RyYWlnaHQnKSAhPT0gLTEsXG4gICAgICByZXBhaXJlZFdheXBvaW50cztcblxuICAvLyBqdXN0IGxheW91dCBub24tZXhpc3Rpbmcgb3Igc2ltcGxlIGNvbm5lY3Rpb25zXG4gIC8vIGF0dGVtcHQgdG8gcmVuZGVyIHN0cmFpZ2h0IGxpbmVzLCBpZiByZXF1aXJlZFxuXG4gIC8vIGF0dGVtcHQgdG8gbGF5b3V0IGEgc3RyYWlnaHQgbGluZVxuICByZXBhaXJlZFdheXBvaW50cyA9IHByZWZlclN0cmFpZ2h0ICYmIHRyeUxheW91dFN0cmFpZ2h0KHNvdXJjZSwgdGFyZ2V0LCBzdGFydCwgZW5kLCBoaW50cyk7XG5cbiAgaWYgKHJlcGFpcmVkV2F5cG9pbnRzKSB7XG4gICAgcmV0dXJuIHJlcGFpcmVkV2F5cG9pbnRzO1xuICB9XG5cbiAgLy8gdHJ5IHRvIGxheW91dCBmcm9tIGVuZFxuICByZXBhaXJlZFdheXBvaW50cyA9IGhpbnRzLmNvbm5lY3Rpb25FbmQgJiYgdHJ5UmVwYWlyQ29ubmVjdGlvbkVuZCh0YXJnZXQsIHNvdXJjZSwgZW5kLCB3YXlwb2ludHMpO1xuXG4gIGlmIChyZXBhaXJlZFdheXBvaW50cykge1xuICAgIHJldHVybiByZXBhaXJlZFdheXBvaW50cztcbiAgfVxuXG4gIC8vIHRyeSB0byBsYXlvdXQgZnJvbSBzdGFydFxuICByZXBhaXJlZFdheXBvaW50cyA9IGhpbnRzLmNvbm5lY3Rpb25TdGFydCAmJiB0cnlSZXBhaXJDb25uZWN0aW9uU3RhcnQoc291cmNlLCB0YXJnZXQsIHN0YXJ0LCB3YXlwb2ludHMpO1xuXG4gIGlmIChyZXBhaXJlZFdheXBvaW50cykge1xuICAgIHJldHVybiByZXBhaXJlZFdheXBvaW50cztcbiAgfVxuXG4gIC8vIG9yIHdoZXRoZXIgbm90aGluZyBzZWVtcyB0byBoYXZlIGNoYW5nZWRcbiAgaWYgKCFoaW50cy5jb25uZWN0aW9uU3RhcnQgJiYgIWhpbnRzLmNvbm5lY3Rpb25FbmQgJiYgd2F5cG9pbnRzICYmIHdheXBvaW50cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gd2F5cG9pbnRzO1xuICB9XG5cbiAgLy8gc2ltcGx5IHJlY29ubmVjdCBpZiBub3RoaW5nIGVsc2Ugd29ya2VkXG4gIHJldHVybiBjb25uZWN0UmVjdGFuZ2xlcyhzb3VyY2UsIHRhcmdldCwgc3RhcnQsIGVuZCwgaGludHMpO1xufVxuXG5cbmZ1bmN0aW9uIGluUmFuZ2UoYSwgc3RhcnQsIGVuZCkge1xuICByZXR1cm4gYSA+PSBzdGFydCAmJiBhIDw9IGVuZDtcbn1cblxuZnVuY3Rpb24gaXNJblJhbmdlKGF4aXMsIGEsIGIpIHtcbiAgdmFyIHNpemUgPSB7XG4gICAgeDogJ3dpZHRoJyxcbiAgICB5OiAnaGVpZ2h0J1xuICB9O1xuXG4gIHJldHVybiBpblJhbmdlKGFbYXhpc10sIGJbYXhpc10sIGJbYXhpc10gKyBiW3NpemVbYXhpc11dKTtcbn1cblxuLyoqXG4gKiBMYXlvdXQgYSBzdHJhaWdodCBjb25uZWN0aW9uXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IHNvdXJjZVxuICogQHBhcmFtIHtCb3VuZHN9IHRhcmdldFxuICogQHBhcmFtIHtQb2ludH0gc3RhcnRcbiAqIEBwYXJhbSB7UG9pbnR9IGVuZFxuICogQHBhcmFtIHtPYmplY3R9IFtoaW50c11cbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxQb2ludD58bnVsbH0gd2F5cG9pbnRzIGlmIHN0cmFpZ2h0IGxheW91dCB3b3JrZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyeUxheW91dFN0cmFpZ2h0KHNvdXJjZSwgdGFyZ2V0LCBzdGFydCwgZW5kLCBoaW50cykge1xuICB2YXIgYXhpcyA9IHt9LFxuICAgICAgcHJpbWFyeUF4aXMsXG4gICAgICBvcmllbnRhdGlvbjtcblxuICBvcmllbnRhdGlvbiA9IGdldE9yaWVudGF0aW9uKHNvdXJjZSwgdGFyZ2V0KTtcblxuICAvLyBvbmx5IGxheW91dCBhIHN0cmFpZ2h0IGNvbm5lY3Rpb24gaWYgc2hhcGVzIGFyZVxuICAvLyBob3Jpem9udGFsbHkgb3IgdmVydGljYWxseSBhbGlnbmVkXG4gIGlmICghL14odG9wfGJvdHRvbXxsZWZ0fHJpZ2h0KSQvLnRlc3Qob3JpZW50YXRpb24pKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoL3RvcHxib3R0b20vLnRlc3Qob3JpZW50YXRpb24pKSB7XG4gICAgcHJpbWFyeUF4aXMgPSAneCc7XG4gIH1cblxuICBpZiAoL2xlZnR8cmlnaHQvLnRlc3Qob3JpZW50YXRpb24pKSB7XG4gICAgcHJpbWFyeUF4aXMgPSAneSc7XG4gIH1cblxuICBpZiAoaGludHMucHJlc2VydmVEb2NraW5nID09PSAndGFyZ2V0Jykge1xuXG4gICAgaWYgKCFpc0luUmFuZ2UocHJpbWFyeUF4aXMsIGVuZCwgc291cmNlKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgYXhpc1twcmltYXJ5QXhpc10gPSBlbmRbcHJpbWFyeUF4aXNdO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgeDogYXhpcy54ICE9PSB1bmRlZmluZWQgPyBheGlzLnggOiBzdGFydC54LFxuICAgICAgICB5OiBheGlzLnkgIT09IHVuZGVmaW5lZCA/IGF4aXMueSA6IHN0YXJ0LnksXG4gICAgICAgIG9yaWdpbmFsOiB7XG4gICAgICAgICAgeDogYXhpcy54ICE9PSB1bmRlZmluZWQgPyBheGlzLnggOiBzdGFydC54LFxuICAgICAgICAgIHk6IGF4aXMueSAhPT0gdW5kZWZpbmVkID8gYXhpcy55IDogc3RhcnQueVxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB4OiBlbmQueCxcbiAgICAgICAgeTogZW5kLnlcbiAgICAgIH1cbiAgICBdO1xuXG4gIH0gZWxzZSB7XG5cbiAgICBpZiAoIWlzSW5SYW5nZShwcmltYXJ5QXhpcywgc3RhcnQsIHRhcmdldCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGF4aXNbcHJpbWFyeUF4aXNdID0gc3RhcnRbcHJpbWFyeUF4aXNdO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIHtcbiAgICAgICAgeDogc3RhcnQueCxcbiAgICAgICAgeTogc3RhcnQueVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgeDogYXhpcy54ICE9PSB1bmRlZmluZWQgPyBheGlzLnggOiBlbmQueCxcbiAgICAgICAgeTogYXhpcy55ICE9PSB1bmRlZmluZWQgPyBheGlzLnkgOiBlbmQueSxcbiAgICAgICAgb3JpZ2luYWw6IHtcbiAgICAgICAgICB4OiBheGlzLnggIT09IHVuZGVmaW5lZCA/IGF4aXMueCA6IGVuZC54LFxuICAgICAgICAgIHk6IGF4aXMueSAhPT0gdW5kZWZpbmVkID8gYXhpcy55IDogZW5kLnlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIF07XG4gIH1cblxufVxuXG4vKipcbiAqIFJlcGFpciBhIGNvbm5lY3Rpb24gZnJvbSBzdGFydC5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc30gbW92ZWRcbiAqIEBwYXJhbSB7Qm91bmRzfSBvdGhlclxuICogQHBhcmFtIHtQb2ludH0gbmV3RG9ja2luZ1xuICogQHBhcmFtIHtBcnJheTxQb2ludD59IHBvaW50cyBvcmlnaW5hbFBvaW50cyBmcm9tIG1vdmVkIHRvIG90aGVyXG4gKlxuICogQHJldHVybiB7QXJyYXk8UG9pbnQ+fG51bGx9IHRoZSByZXBhaXJlZCBwb2ludHMgYmV0d2VlbiB0aGUgdHdvIHJlY3RhbmdsZXNcbiAqL1xuZnVuY3Rpb24gdHJ5UmVwYWlyQ29ubmVjdGlvblN0YXJ0KG1vdmVkLCBvdGhlciwgbmV3RG9ja2luZywgcG9pbnRzKSB7XG4gIHJldHVybiBfdHJ5UmVwYWlyQ29ubmVjdGlvblNpZGUobW92ZWQsIG90aGVyLCBuZXdEb2NraW5nLCBwb2ludHMpO1xufVxuXG4vKipcbiAqIFJlcGFpciBhIGNvbm5lY3Rpb24gZnJvbSBlbmQuXG4gKlxuICogQHBhcmFtIHtCb3VuZHN9IG1vdmVkXG4gKiBAcGFyYW0ge0JvdW5kc30gb3RoZXJcbiAqIEBwYXJhbSB7UG9pbnR9IG5ld0RvY2tpbmdcbiAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSBwb2ludHMgb3JpZ2luYWxQb2ludHMgZnJvbSBtb3ZlZCB0byBvdGhlclxuICpcbiAqIEByZXR1cm4ge0FycmF5PFBvaW50PnxudWxsfSB0aGUgcmVwYWlyZWQgcG9pbnRzIGJldHdlZW4gdGhlIHR3byByZWN0YW5nbGVzXG4gKi9cbmZ1bmN0aW9uIHRyeVJlcGFpckNvbm5lY3Rpb25FbmQobW92ZWQsIG90aGVyLCBuZXdEb2NraW5nLCBwb2ludHMpIHtcbiAgdmFyIHdheXBvaW50cyA9IHBvaW50cy5zbGljZSgpLnJldmVyc2UoKTtcblxuICB3YXlwb2ludHMgPSBfdHJ5UmVwYWlyQ29ubmVjdGlvblNpZGUobW92ZWQsIG90aGVyLCBuZXdEb2NraW5nLCB3YXlwb2ludHMpO1xuXG4gIHJldHVybiB3YXlwb2ludHMgPyB3YXlwb2ludHMucmV2ZXJzZSgpIDogbnVsbDtcbn1cblxuLyoqXG4gKiBSZXBhaXIgYSBjb25uZWN0aW9uIGZyb20gb25lIHNpZGUgdGhhdCBtb3ZlZC5cbiAqXG4gKiBAcGFyYW0ge0JvdW5kc30gbW92ZWRcbiAqIEBwYXJhbSB7Qm91bmRzfSBvdGhlclxuICogQHBhcmFtIHtQb2ludH0gbmV3RG9ja2luZ1xuICogQHBhcmFtIHtBcnJheTxQb2ludD59IHBvaW50cyBvcmlnaW5hbFBvaW50cyBmcm9tIG1vdmVkIHRvIG90aGVyXG4gKlxuICogQHJldHVybiB7QXJyYXk8UG9pbnQ+fSB0aGUgcmVwYWlyZWQgcG9pbnRzIGJldHdlZW4gdGhlIHR3byByZWN0YW5nbGVzXG4gKi9cbmZ1bmN0aW9uIF90cnlSZXBhaXJDb25uZWN0aW9uU2lkZShtb3ZlZCwgb3RoZXIsIG5ld0RvY2tpbmcsIHBvaW50cykge1xuXG4gIGZ1bmN0aW9uIG5lZWRzUmVsYXlvdXQocG9pbnRzKSB7XG4gICAgaWYgKHBvaW50cy5sZW5ndGggPCAzKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAocG9pbnRzLmxlbmd0aCA+IDQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyByZWxheW91dCBpZiB0d28gcG9pbnRzIG92ZXJsYXBcbiAgICAvLyB0aGlzIGlzIG1vc3QgbGlrZWx5IGR1ZSB0b1xuICAgIHJldHVybiAhIWZpbmQocG9pbnRzLCBmdW5jdGlvbihwLCBpZHgpIHtcbiAgICAgIHZhciBxID0gcG9pbnRzW2lkeCAtIDFdO1xuXG4gICAgICByZXR1cm4gcSAmJiBwb2ludERpc3RhbmNlKHAsIHEpIDwgMztcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlcGFpckJlbmRwb2ludChjYW5kaWRhdGUsIG9sZFBlZXIsIG5ld1BlZXIpIHtcblxuICAgIHZhciBhbGlnbm1lbnQgPSBwb2ludHNBbGlnbmVkKG9sZFBlZXIsIGNhbmRpZGF0ZSk7XG5cbiAgICBzd2l0Y2ggKGFsaWdubWVudCkge1xuICAgIGNhc2UgJ3YnOlxuXG4gICAgICAvLyByZXBhaXIgaG9yaXpvbnRhbCBhbGlnbm1lbnRcbiAgICAgIHJldHVybiB7IHg6IG5ld1BlZXIueCwgeTogY2FuZGlkYXRlLnkgfTtcbiAgICBjYXNlICdoJzpcblxuICAgICAgLy8gcmVwYWlyIHZlcnRpY2FsIGFsaWdubWVudFxuICAgICAgcmV0dXJuIHsgeDogY2FuZGlkYXRlLngsIHk6IG5ld1BlZXIueSB9O1xuICAgIH1cblxuICAgIHJldHVybiB7IHg6IGNhbmRpZGF0ZS54LCB5OiBjYW5kaWRhdGUuIHkgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZU92ZXJsYXBwaW5nKHBvaW50cywgYSwgYikge1xuICAgIHZhciBpO1xuXG4gICAgZm9yIChpID0gcG9pbnRzLmxlbmd0aCAtIDI7IGkgIT09IDA7IGktLSkge1xuXG4gICAgICAvLyBpbnRlcnNlY3RzICg/KSBicmVhaywgcmVtb3ZlIGFsbCBiZW5kcG9pbnRzIHVwIHRvIHRoaXMgb25lIGFuZCByZWxheW91dFxuICAgICAgaWYgKHBvaW50SW5SZWN0KHBvaW50c1tpXSwgYSwgSU5URVJTRUNUSU9OX1RIUkVTSE9MRCkgfHxcbiAgICAgICAgICBwb2ludEluUmVjdChwb2ludHNbaV0sIGIsIElOVEVSU0VDVElPTl9USFJFU0hPTEQpKSB7XG5cbiAgICAgICAgLy8gcmV0dXJuIHNsaWNlZCBvbGQgY29ubmVjdGlvblxuICAgICAgICByZXR1cm4gcG9pbnRzLnNsaWNlKGkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBwb2ludHM7XG4gIH1cblxuICAvLyAoMCkgb25seSByZXBhaXIgd2hhdCBoYXMgbGF5b3V0YWJsZSBiZW5kcG9pbnRzXG5cbiAgLy8gKDEpIGlmIG9ubHkgb25lIGJlbmRwb2ludCBhbmQgb24gc2hhcGUgbW92ZWQgb250byBvdGhlciBzaGFwZXMgYXhpc1xuICAvLyAgICAgKGhvcml6b250YWxseSAvIHZlcnRpY2FsbHkpLCByZWxheW91dFxuXG4gIGlmIChuZWVkc1JlbGF5b3V0KHBvaW50cykpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHZhciBvbGREb2NraW5nID0gcG9pbnRzWzBdLFxuICAgICAgbmV3UG9pbnRzID0gcG9pbnRzLnNsaWNlKCksXG4gICAgICBzbGljZWRQb2ludHM7XG5cbiAgLy8gKDIpIHJlcGFpciBvbmx5IGxhc3QgbGluZSBzZWdtZW50IGFuZCBvbmx5IGlmIGl0IHdhcyBsYXlvdXRlZCBiZWZvcmVcblxuICBuZXdQb2ludHNbMF0gPSBuZXdEb2NraW5nO1xuICBuZXdQb2ludHNbMV0gPSByZXBhaXJCZW5kcG9pbnQobmV3UG9pbnRzWzFdLCBvbGREb2NraW5nLCBuZXdEb2NraW5nKTtcblxuXG4gIC8vICgzKSBpZiBzaGFwZSBpbnRlcnNlY3RzIHdpdGggYW55IGJlbmRwb2ludCBhZnRlciByZXBhaXIsXG4gIC8vICAgICByZW1vdmUgYWxsIHNlZ21lbnRzIHVwIHRvIHRoaXMgYmVuZHBvaW50IGFuZCByZXBhaXIgZnJvbSB0aGVyZVxuICBzbGljZWRQb2ludHMgPSByZW1vdmVPdmVybGFwcGluZyhuZXdQb2ludHMsIG1vdmVkLCBvdGhlcik7XG5cbiAgaWYgKHNsaWNlZFBvaW50cyAhPT0gbmV3UG9pbnRzKSB7XG4gICAgbmV3UG9pbnRzID0gX3RyeVJlcGFpckNvbm5lY3Rpb25TaWRlKG1vdmVkLCBvdGhlciwgbmV3RG9ja2luZywgc2xpY2VkUG9pbnRzKTtcbiAgfVxuXG4gIC8vICg0KSBkbyBOT1QgcmVwYWlyIGlmIHJlcGFpcmVkIGJlbmRwb2ludHMgYXJlIGFsaWduZWRcbiAgaWYgKG5ld1BvaW50cyAmJiBwb2ludHNBbGlnbmVkKG5ld1BvaW50cykpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBuZXdQb2ludHM7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBtYW5oYXR0YW4gZGlyZWN0aW9ucyBjb25uZWN0aW5nIHR3byByZWN0YW5nbGVzXG4gKiB3aXRoIHRoZSBnaXZlbiBvcmllbnRhdGlvbi5cbiAqXG4gKiBXaWxsIGFsd2F5cyByZXR1cm4gdGhlIGRlZmF1bHQgbGF5b3V0LCBpZiBpdCBpcyBzcGVjaWZpY1xuICogcmVnYXJkaW5nIHNpZGVzIGFscmVhZHkgKHRyYmwpLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogZ2V0RGlyZWN0aW9ucygndG9wJyk7IC8vIC0+ICd2OnYnXG4gKiBnZXREaXJlY3Rpb25zKCdpbnRlcnNlY3QnKTsgLy8gLT4gJ3Q6dCdcbiAqXG4gKiBnZXREaXJlY3Rpb25zKCd0b3AtcmlnaHQnLCAndjpoJyk7IC8vIC0+ICd2OmgnXG4gKiBnZXREaXJlY3Rpb25zKCd0b3AtcmlnaHQnLCAnaDpoJyk7IC8vIC0+ICdoOmgnXG4gKlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBvcmllbnRhdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IGRlZmF1bHRMYXlvdXRcbiAqXG4gKiBAcmV0dXJuIHtzdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGdldERpcmVjdGlvbnMob3JpZW50YXRpb24sIGRlZmF1bHRMYXlvdXQpIHtcblxuICAvLyBkb24ndCBvdmVycmlkZSBzcGVjaWZpYyB0cmJsIGRpcmVjdGlvbnNcbiAgaWYgKGlzRXhwbGljaXREaXJlY3Rpb25zKGRlZmF1bHRMYXlvdXQpKSB7XG4gICAgcmV0dXJuIGRlZmF1bHRMYXlvdXQ7XG4gIH1cblxuICBzd2l0Y2ggKG9yaWVudGF0aW9uKSB7XG4gIGNhc2UgJ2ludGVyc2VjdCc6XG4gICAgcmV0dXJuICd0OnQnO1xuXG4gIGNhc2UgJ3RvcCc6XG4gIGNhc2UgJ2JvdHRvbSc6XG4gICAgcmV0dXJuICd2OnYnO1xuXG4gIGNhc2UgJ2xlZnQnOlxuICBjYXNlICdyaWdodCc6XG4gICAgcmV0dXJuICdoOmgnO1xuXG4gIC8vICd0b3AtbGVmdCdcbiAgLy8gJ3RvcC1yaWdodCdcbiAgLy8gJ2JvdHRvbS1sZWZ0J1xuICAvLyAnYm90dG9tLXJpZ2h0J1xuICBkZWZhdWx0OlxuICAgIHJldHVybiBkZWZhdWx0TGF5b3V0O1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzVmFsaWREaXJlY3Rpb25zKGRpcmVjdGlvbnMpIHtcbiAgcmV0dXJuIGRpcmVjdGlvbnMgJiYgL15ofHZ8dHxyfGJ8bDpofHZ8dHxyfGJ8bCQvLnRlc3QoZGlyZWN0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGlzRXhwbGljaXREaXJlY3Rpb25zKGRpcmVjdGlvbnMpIHtcbiAgcmV0dXJuIGRpcmVjdGlvbnMgJiYgL3R8cnxifGwvLnRlc3QoZGlyZWN0aW9ucyk7XG59XG5cbmZ1bmN0aW9uIGludmVydE9yaWVudGF0aW9uKG9yaWVudGF0aW9uKSB7XG4gIHJldHVybiB7XG4gICAgJ3RvcCc6ICdib3R0b20nLFxuICAgICdib3R0b20nOiAndG9wJyxcbiAgICAnbGVmdCc6ICdyaWdodCcsXG4gICAgJ3JpZ2h0JzogJ2xlZnQnLFxuICAgICd0b3AtbGVmdCc6ICdib3R0b20tcmlnaHQnLFxuICAgICdib3R0b20tcmlnaHQnOiAndG9wLWxlZnQnLFxuICAgICd0b3AtcmlnaHQnOiAnYm90dG9tLWxlZnQnLFxuICAgICdib3R0b20tbGVmdCc6ICd0b3AtcmlnaHQnLFxuICB9W29yaWVudGF0aW9uXTtcbn1cblxuZnVuY3Rpb24gZ2V0RG9ja2luZ1BvaW50KHBvaW50LCByZWN0YW5nbGUsIGRvY2tpbmdEaXJlY3Rpb24sIHRhcmdldE9yaWVudGF0aW9uKSB7XG5cbiAgLy8gZW5zdXJlIHdlIGVuZCB1cCB3aXRoIGEgc3BlY2lmaWMgZG9ja2luZyBkaXJlY3Rpb25cbiAgLy8gYmFzZWQgb24gdGhlIHRhcmdldE9yaWVudGF0aW9uLCBpZiA8aHx2PiBpcyBiZWluZyBwYXNzZWRcblxuICBpZiAoZG9ja2luZ0RpcmVjdGlvbiA9PT0gJ2gnKSB7XG4gICAgZG9ja2luZ0RpcmVjdGlvbiA9IC9sZWZ0Ly50ZXN0KHRhcmdldE9yaWVudGF0aW9uKSA/ICdsJyA6ICdyJztcbiAgfVxuXG4gIGlmIChkb2NraW5nRGlyZWN0aW9uID09PSAndicpIHtcbiAgICBkb2NraW5nRGlyZWN0aW9uID0gL3RvcC8udGVzdCh0YXJnZXRPcmllbnRhdGlvbikgPyAndCcgOiAnYic7XG4gIH1cblxuICBpZiAoZG9ja2luZ0RpcmVjdGlvbiA9PT0gJ3QnKSB7XG4gICAgcmV0dXJuIHsgb3JpZ2luYWw6IHBvaW50LCB4OiBwb2ludC54LCB5OiByZWN0YW5nbGUueSB9O1xuICB9XG5cbiAgaWYgKGRvY2tpbmdEaXJlY3Rpb24gPT09ICdyJykge1xuICAgIHJldHVybiB7IG9yaWdpbmFsOiBwb2ludCwgeDogcmVjdGFuZ2xlLnggKyByZWN0YW5nbGUud2lkdGgsIHk6IHBvaW50LnkgfTtcbiAgfVxuXG4gIGlmIChkb2NraW5nRGlyZWN0aW9uID09PSAnYicpIHtcbiAgICByZXR1cm4geyBvcmlnaW5hbDogcG9pbnQsIHg6IHBvaW50LngsIHk6IHJlY3RhbmdsZS55ICsgcmVjdGFuZ2xlLmhlaWdodCB9O1xuICB9XG5cbiAgaWYgKGRvY2tpbmdEaXJlY3Rpb24gPT09ICdsJykge1xuICAgIHJldHVybiB7IG9yaWdpbmFsOiBwb2ludCwgeDogcmVjdGFuZ2xlLngsIHk6IHBvaW50LnkgfTtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcigndW5leHBlY3RlZCBkb2NraW5nRGlyZWN0aW9uOiA8JyArIGRvY2tpbmdEaXJlY3Rpb24gKyAnPicpO1xufVxuXG5cbi8qKlxuICogUmV0dXJuIGxpc3Qgb2Ygd2F5cG9pbnRzIHdpdGggcmVkdW5kYW50IG9uZXMgZmlsdGVyZWQgb3V0LlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogT3JpZ2luYWwgcG9pbnRzOlxuICpcbiAqICAgW3hdIC0tLS0tIFt4XSAtLS0tLS0gW3hdXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgIFt4XSAtLS0tLSBbeF0gLSBbeF1cbiAqXG4gKiBGaWx0ZXJlZDpcbiAqXG4gKiAgIFt4XSAtLS0tLS0tLS0tLS0tLS0tIFt4XVxuICogICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICBbeF0gLS0tLS0tLS0tLS0gW3hdXG4gKlxuICogQHBhcmFtICB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxQb2ludD59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRob3V0UmVkdW5kYW50UG9pbnRzKHdheXBvaW50cykge1xuICByZXR1cm4gd2F5cG9pbnRzLnJlZHVjZShmdW5jdGlvbihwb2ludHMsIHAsIGlkeCkge1xuXG4gICAgdmFyIHByZXZpb3VzID0gcG9pbnRzW3BvaW50cy5sZW5ndGggLSAxXSxcbiAgICAgICAgbmV4dCA9IHdheXBvaW50c1tpZHggKyAxXTtcblxuICAgIGlmICghcG9pbnRzT25MaW5lKHByZXZpb3VzLCBuZXh0LCBwLCAwKSkge1xuICAgICAgcG9pbnRzLnB1c2gocCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBvaW50cztcbiAgfSwgW10pO1xufVxuIiwiaW1wb3J0IHsgYXNzaWduIH0gZnJvbSAnbWluLWRhc2gnO1xuaW1wb3J0IGluaGVyaXRzIGZyb20gJ2luaGVyaXRzJztcblxuaW1wb3J0IFJlZnMgZnJvbSAnb2JqZWN0LXJlZnMnO1xuXG52YXIgcGFyZW50UmVmcyA9IG5ldyBSZWZzKHsgbmFtZTogJ2NoaWxkcmVuJywgZW51bWVyYWJsZTogdHJ1ZSwgY29sbGVjdGlvbjogdHJ1ZSB9LCB7IG5hbWU6ICdwYXJlbnQnIH0pLFxuICAgIGxhYmVsUmVmcyA9IG5ldyBSZWZzKHsgbmFtZTogJ2xhYmVscycsIGVudW1lcmFibGU6IHRydWUsIGNvbGxlY3Rpb246IHRydWUgfSwgeyBuYW1lOiAnbGFiZWxUYXJnZXQnIH0pLFxuICAgIGF0dGFjaGVyUmVmcyA9IG5ldyBSZWZzKHsgbmFtZTogJ2F0dGFjaGVycycsIGNvbGxlY3Rpb246IHRydWUgfSwgeyBuYW1lOiAnaG9zdCcgfSksXG4gICAgb3V0Z29pbmdSZWZzID0gbmV3IFJlZnMoeyBuYW1lOiAnb3V0Z29pbmcnLCBjb2xsZWN0aW9uOiB0cnVlIH0sIHsgbmFtZTogJ3NvdXJjZScgfSksXG4gICAgaW5jb21pbmdSZWZzID0gbmV3IFJlZnMoeyBuYW1lOiAnaW5jb21pbmcnLCBjb2xsZWN0aW9uOiB0cnVlIH0sIHsgbmFtZTogJ3RhcmdldCcgfSk7XG5cbi8qKlxuICogQG5hbWVzcGFjZSBkanMubW9kZWxcbiAqL1xuXG4vKipcbiAqIEBtZW1iZXJPZiBkanMubW9kZWxcbiAqL1xuXG4vKipcbiAqIFRoZSBiYXNpYyBncmFwaGljYWwgcmVwcmVzZW50YXRpb25cbiAqXG4gKiBAY2xhc3NcbiAqXG4gKiBAYWJzdHJhY3RcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIEJhc2UoKSB7XG5cbiAgLyoqXG4gICAqIFRoZSBvYmplY3QgdGhhdCBiYWNrcyB1cCB0aGUgc2hhcGVcbiAgICpcbiAgICogQG5hbWUgQmFzZSNidXNpbmVzc09iamVjdFxuICAgKiBAdHlwZSBPYmplY3RcbiAgICovXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCAnYnVzaW5lc3NPYmplY3QnLCB7XG4gICAgd3JpdGFibGU6IHRydWVcbiAgfSk7XG5cblxuICAvKipcbiAgICogU2luZ2xlIGxhYmVsIHN1cHBvcnQsIHdpbGwgbWFwcGVkIHRvIG11bHRpIGxhYmVsIGFycmF5XG4gICAqXG4gICAqIEBuYW1lIEJhc2UjbGFiZWxcbiAgICogQHR5cGUgT2JqZWN0XG4gICAqL1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgJ2xhYmVsJywge1xuICAgIGdldDogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpcy5sYWJlbHNbMF07XG4gICAgfSxcbiAgICBzZXQ6IGZ1bmN0aW9uKG5ld0xhYmVsKSB7XG5cbiAgICAgIHZhciBsYWJlbCA9IHRoaXMubGFiZWwsXG4gICAgICAgICAgbGFiZWxzID0gdGhpcy5sYWJlbHM7XG5cbiAgICAgIGlmICghbmV3TGFiZWwgJiYgbGFiZWwpIHtcbiAgICAgICAgbGFiZWxzLnJlbW92ZShsYWJlbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsYWJlbHMuYWRkKG5ld0xhYmVsLCAwKTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8qKlxuICAgKiBUaGUgcGFyZW50IHNoYXBlXG4gICAqXG4gICAqIEBuYW1lIEJhc2UjcGFyZW50XG4gICAqIEB0eXBlIFNoYXBlXG4gICAqL1xuICBwYXJlbnRSZWZzLmJpbmQodGhpcywgJ3BhcmVudCcpO1xuXG4gIC8qKlxuICAgKiBUaGUgbGlzdCBvZiBsYWJlbHNcbiAgICpcbiAgICogQG5hbWUgQmFzZSNsYWJlbHNcbiAgICogQHR5cGUgTGFiZWxcbiAgICovXG4gIGxhYmVsUmVmcy5iaW5kKHRoaXMsICdsYWJlbHMnKTtcblxuICAvKipcbiAgICogVGhlIGxpc3Qgb2Ygb3V0Z29pbmcgY29ubmVjdGlvbnNcbiAgICpcbiAgICogQG5hbWUgQmFzZSNvdXRnb2luZ1xuICAgKiBAdHlwZSBBcnJheTxDb25uZWN0aW9uPlxuICAgKi9cbiAgb3V0Z29pbmdSZWZzLmJpbmQodGhpcywgJ291dGdvaW5nJyk7XG5cbiAgLyoqXG4gICAqIFRoZSBsaXN0IG9mIGluY29taW5nIGNvbm5lY3Rpb25zXG4gICAqXG4gICAqIEBuYW1lIEJhc2UjaW5jb21pbmdcbiAgICogQHR5cGUgQXJyYXk8Q29ubmVjdGlvbj5cbiAgICovXG4gIGluY29taW5nUmVmcy5iaW5kKHRoaXMsICdpbmNvbWluZycpO1xufVxuXG5cbi8qKlxuICogQSBncmFwaGljYWwgb2JqZWN0XG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBTaGFwZSgpIHtcbiAgQmFzZS5jYWxsKHRoaXMpO1xuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgZnJhbWUgc2hhcGVzXG4gICAqXG4gICAqIEBuYW1lIFNoYXBlI2lzRnJhbWVcbiAgICogQHR5cGUgYm9vbGVhblxuICAgKi9cblxuICAvKipcbiAgICogVGhlIGxpc3Qgb2YgY2hpbGRyZW5cbiAgICpcbiAgICogQG5hbWUgU2hhcGUjY2hpbGRyZW5cbiAgICogQHR5cGUgQXJyYXk8QmFzZT5cbiAgICovXG4gIHBhcmVudFJlZnMuYmluZCh0aGlzLCAnY2hpbGRyZW4nKTtcblxuICAvKipcbiAgICogQG5hbWUgU2hhcGUjaG9zdFxuICAgKiBAdHlwZSBTaGFwZVxuICAgKi9cbiAgYXR0YWNoZXJSZWZzLmJpbmQodGhpcywgJ2hvc3QnKTtcblxuICAvKipcbiAgICogQG5hbWUgU2hhcGUjYXR0YWNoZXJzXG4gICAqIEB0eXBlIFNoYXBlXG4gICAqL1xuICBhdHRhY2hlclJlZnMuYmluZCh0aGlzLCAnYXR0YWNoZXJzJyk7XG59XG5cbmluaGVyaXRzKFNoYXBlLCBCYXNlKTtcblxuXG4vKipcbiAqIEEgcm9vdCBncmFwaGljYWwgb2JqZWN0XG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAZXh0ZW5kcyBTaGFwZVxuICovXG5leHBvcnQgZnVuY3Rpb24gUm9vdCgpIHtcbiAgU2hhcGUuY2FsbCh0aGlzKTtcbn1cblxuaW5oZXJpdHMoUm9vdCwgU2hhcGUpO1xuXG5cbi8qKlxuICogQSBsYWJlbCBmb3IgYW4gZWxlbWVudFxuICpcbiAqIEBjbGFzc1xuICogQGNvbnN0cnVjdG9yXG4gKlxuICogQGV4dGVuZHMgU2hhcGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIExhYmVsKCkge1xuICBTaGFwZS5jYWxsKHRoaXMpO1xuXG4gIC8qKlxuICAgKiBUaGUgbGFiZWxlZCBlbGVtZW50XG4gICAqXG4gICAqIEBuYW1lIExhYmVsI2xhYmVsVGFyZ2V0XG4gICAqIEB0eXBlIEJhc2VcbiAgICovXG4gIGxhYmVsUmVmcy5iaW5kKHRoaXMsICdsYWJlbFRhcmdldCcpO1xufVxuXG5pbmhlcml0cyhMYWJlbCwgU2hhcGUpO1xuXG5cbi8qKlxuICogQSBjb25uZWN0aW9uIGJldHdlZW4gdHdvIGVsZW1lbnRzXG4gKlxuICogQGNsYXNzXG4gKiBAY29uc3RydWN0b3JcbiAqXG4gKiBAZXh0ZW5kcyBCYXNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDb25uZWN0aW9uKCkge1xuICBCYXNlLmNhbGwodGhpcyk7XG5cbiAgLyoqXG4gICAqIFRoZSBlbGVtZW50IHRoaXMgY29ubmVjdGlvbiBvcmlnaW5hdGVzIGZyb21cbiAgICpcbiAgICogQG5hbWUgQ29ubmVjdGlvbiNzb3VyY2VcbiAgICogQHR5cGUgQmFzZVxuICAgKi9cbiAgb3V0Z29pbmdSZWZzLmJpbmQodGhpcywgJ3NvdXJjZScpO1xuXG4gIC8qKlxuICAgKiBUaGUgZWxlbWVudCB0aGlzIGNvbm5lY3Rpb24gcG9pbnRzIHRvXG4gICAqXG4gICAqIEBuYW1lIENvbm5lY3Rpb24jdGFyZ2V0XG4gICAqIEB0eXBlIEJhc2VcbiAgICovXG4gIGluY29taW5nUmVmcy5iaW5kKHRoaXMsICd0YXJnZXQnKTtcbn1cblxuaW5oZXJpdHMoQ29ubmVjdGlvbiwgQmFzZSk7XG5cblxudmFyIHR5cGVzID0ge1xuICBjb25uZWN0aW9uOiBDb25uZWN0aW9uLFxuICBzaGFwZTogU2hhcGUsXG4gIGxhYmVsOiBMYWJlbCxcbiAgcm9vdDogUm9vdFxufTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IG1vZGVsIGVsZW1lbnQgb2YgdGhlIHNwZWNpZmllZCB0eXBlXG4gKlxuICogQG1ldGhvZCBjcmVhdGVcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBzaGFwZTEgPSBNb2RlbC5jcmVhdGUoJ3NoYXBlJywgeyB4OiAxMCwgeTogMTAsIHdpZHRoOiAxMDAsIGhlaWdodDogMTAwIH0pO1xuICogdmFyIHNoYXBlMiA9IE1vZGVsLmNyZWF0ZSgnc2hhcGUnLCB7IHg6IDIxMCwgeTogMjEwLCB3aWR0aDogMTAwLCBoZWlnaHQ6IDEwMCB9KTtcbiAqXG4gKiB2YXIgY29ubmVjdGlvbiA9IE1vZGVsLmNyZWF0ZSgnY29ubmVjdGlvbicsIHsgd2F5cG9pbnRzOiBbIHsgeDogMTEwLCB5OiA1NSB9LCB7eDogMjEwLCB5OiA1NSB9IF0gfSk7XG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSB0eXBlIGxvd2VyLWNhc2VkIG1vZGVsIG5hbWVcbiAqIEBwYXJhbSAge09iamVjdH0gYXR0cnMgYXR0cmlidXRlcyB0byBpbml0aWFsaXplIHRoZSBuZXcgbW9kZWwgaW5zdGFuY2Ugd2l0aFxuICpcbiAqIEByZXR1cm4ge0Jhc2V9IHRoZSBuZXcgbW9kZWwgaW5zdGFuY2VcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZSh0eXBlLCBhdHRycykge1xuICB2YXIgVHlwZSA9IHR5cGVzW3R5cGVdO1xuICBpZiAoIVR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ3Vua25vd24gdHlwZTogPCcgKyB0eXBlICsgJz4nKTtcbiAgfVxuICByZXR1cm4gYXNzaWduKG5ldyBUeXBlKCksIGF0dHJzKTtcbn0iLCJpbXBvcnQgeyBhc3NpZ24gfSBmcm9tICdtaW4tZGFzaCc7XG5cblxudmFyIERFRkFVTFRfQ09ORklHID0ge1xuICBtb3ZlU3BlZWQ6IDUwLFxuICBtb3ZlU3BlZWRBY2NlbGVyYXRlZDogMjAwXG59O1xuXG5cbi8qKlxuICogQSBmZWF0dXJlIHRoYXQgYWxsb3dzIHVzZXJzIHRvIG1vdmUgdGhlIGNhbnZhcyB1c2luZyB0aGUga2V5Ym9hcmQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZ1xuICogQHBhcmFtIHtudW1iZXJ9IFtjb25maWcubW92ZVNwZWVkPTUwXVxuICogQHBhcmFtIHtudW1iZXJ9IFtjb25maWcubW92ZVNwZWVkQWNjZWxlcmF0ZWQ9MjAwXVxuICogQHBhcmFtIHtLZXlib2FyZH0ga2V5Ym9hcmRcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gS2V5Ym9hcmRNb3ZlKFxuICAgIGNvbmZpZyxcbiAgICBrZXlib2FyZCxcbiAgICBjYW52YXNcbikge1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICB0aGlzLl9jb25maWcgPSBhc3NpZ24oe30sIERFRkFVTFRfQ09ORklHLCBjb25maWcgfHwge30pO1xuXG4gIGtleWJvYXJkLmFkZExpc3RlbmVyKGFycm93c0xpc3RlbmVyKTtcblxuXG4gIGZ1bmN0aW9uIGFycm93c0xpc3RlbmVyKGNvbnRleHQpIHtcblxuICAgIHZhciBldmVudCA9IGNvbnRleHQua2V5RXZlbnQsXG4gICAgICAgIGNvbmZpZyA9IHNlbGYuX2NvbmZpZztcblxuICAgIGlmICgha2V5Ym9hcmQuaXNDbWQoZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGtleWJvYXJkLmlzS2V5KFtcbiAgICAgICdBcnJvd0xlZnQnLCAnTGVmdCcsXG4gICAgICAnQXJyb3dVcCcsICdVcCcsXG4gICAgICAnQXJyb3dEb3duJywgJ0Rvd24nLFxuICAgICAgJ0Fycm93UmlnaHQnLCAnUmlnaHQnXG4gICAgXSwgZXZlbnQpKSB7XG5cbiAgICAgIHZhciBzcGVlZCA9IChcbiAgICAgICAga2V5Ym9hcmQuaXNTaGlmdChldmVudCkgP1xuICAgICAgICAgIGNvbmZpZy5tb3ZlU3BlZWRBY2NlbGVyYXRlZCA6XG4gICAgICAgICAgY29uZmlnLm1vdmVTcGVlZFxuICAgICAgKTtcblxuICAgICAgdmFyIGRpcmVjdGlvbjtcblxuICAgICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0Fycm93TGVmdCc6XG4gICAgICBjYXNlICdMZWZ0JzpcbiAgICAgICAgZGlyZWN0aW9uID0gJ2xlZnQnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93VXAnOlxuICAgICAgY2FzZSAnVXAnOlxuICAgICAgICBkaXJlY3Rpb24gPSAndXAnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93UmlnaHQnOlxuICAgICAgY2FzZSAnUmlnaHQnOlxuICAgICAgICBkaXJlY3Rpb24gPSAncmlnaHQnO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6XG4gICAgICBjYXNlICdEb3duJzpcbiAgICAgICAgZGlyZWN0aW9uID0gJ2Rvd24nO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgc2VsZi5tb3ZlQ2FudmFzKHtcbiAgICAgICAgc3BlZWQ6IHNwZWVkLFxuICAgICAgICBkaXJlY3Rpb246IGRpcmVjdGlvblxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIHRoaXMubW92ZUNhbnZhcyA9IGZ1bmN0aW9uKG9wdHMpIHtcblxuICAgIHZhciBkeCA9IDAsXG4gICAgICAgIGR5ID0gMCxcbiAgICAgICAgc3BlZWQgPSBvcHRzLnNwZWVkO1xuXG4gICAgdmFyIGFjdHVhbFNwZWVkID0gc3BlZWQgLyBNYXRoLm1pbihNYXRoLnNxcnQoY2FudmFzLnZpZXdib3goKS5zY2FsZSksIDEpO1xuXG4gICAgc3dpdGNoIChvcHRzLmRpcmVjdGlvbikge1xuICAgIGNhc2UgJ2xlZnQnOiAvLyBMZWZ0XG4gICAgICBkeCA9IGFjdHVhbFNwZWVkO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAndXAnOiAvLyBVcFxuICAgICAgZHkgPSBhY3R1YWxTcGVlZDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3JpZ2h0JzogLy8gUmlnaHRcbiAgICAgIGR4ID0gLWFjdHVhbFNwZWVkO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZG93bic6IC8vIERvd25cbiAgICAgIGR5ID0gLWFjdHVhbFNwZWVkO1xuICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgY2FudmFzLnNjcm9sbCh7XG4gICAgICBkeDogZHgsXG4gICAgICBkeTogZHlcbiAgICB9KTtcbiAgfTtcblxufVxuXG5cbktleWJvYXJkTW92ZS4kaW5qZWN0ID0gW1xuICAnY29uZmlnLmtleWJvYXJkTW92ZScsXG4gICdrZXlib2FyZCcsXG4gICdjYW52YXMnXG5dO1xuIiwiaW1wb3J0IEtleWJvYXJkTW9kdWxlIGZyb20gJy4uLy4uL2ZlYXR1cmVzL2tleWJvYXJkJztcblxuaW1wb3J0IEtleWJvYXJkTW92ZSBmcm9tICcuL0tleWJvYXJkTW92ZSc7XG5cblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIEtleWJvYXJkTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdrZXlib2FyZE1vdmUnIF0sXG4gIGtleWJvYXJkTW92ZTogWyAndHlwZScsIEtleWJvYXJkTW92ZSBdXG59OyIsImltcG9ydCB7XG4gIHNldCBhcyBjdXJzb3JTZXQsXG4gIHVuc2V0IGFzIGN1cnNvclVuc2V0XG59IGZyb20gJy4uLy4uL3V0aWwvQ3Vyc29yJztcblxuaW1wb3J0IHtcbiAgaW5zdGFsbCBhcyBpbnN0YWxsQ2xpY2tUcmFwXG59IGZyb20gJy4uLy4uL3V0aWwvQ2xpY2tUcmFwJztcblxuaW1wb3J0IHtcbiAgZGVsdGEgYXMgZGVsdGFQb3Ncbn0gZnJvbSAnLi4vLi4vdXRpbC9Qb3NpdGlvblV0aWwnO1xuXG5pbXBvcnQge1xuICBldmVudCBhcyBkb21FdmVudCxcbiAgY2xvc2VzdCBhcyBkb21DbG9zZXN0XG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICB0b1BvaW50XG59IGZyb20gJy4uLy4uL3V0aWwvRXZlbnQnO1xuXG5cbnZhciBUSFJFU0hPTEQgPSAxNTtcblxuXG4vKipcbiAqIE1vdmUgdGhlIGNhbnZhcyB2aWEgbW91c2UuXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqIEBwYXJhbSB7Q2FudmFzfSBjYW52YXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gTW92ZUNhbnZhcyhldmVudEJ1cywgY2FudmFzKSB7XG5cbiAgdmFyIGNvbnRleHQ7XG5cblxuICAvLyBsaXN0ZW4gZm9yIG1vdmUgb24gZWxlbWVudCBtb3VzZSBkb3duO1xuICAvLyBhbGxvdyBvdGhlcnMgdG8gaG9vayBpbnRvIHRoZSBldmVudCBiZWZvcmUgdXMgdGhvdWdoXG4gIC8vIChkcmFnZ2luZyAvIGVsZW1lbnQgbW92aW5nIHdpbGwgZG8gdGhpcylcbiAgZXZlbnRCdXMub24oJ2VsZW1lbnQubW91c2Vkb3duJywgNTAwLCBmdW5jdGlvbihlKSB7XG4gICAgcmV0dXJuIGhhbmRsZVN0YXJ0KGUub3JpZ2luYWxFdmVudCk7XG4gIH0pO1xuXG5cbiAgZnVuY3Rpb24gaGFuZGxlTW92ZShldmVudCkge1xuXG4gICAgdmFyIHN0YXJ0ID0gY29udGV4dC5zdGFydCxcbiAgICAgICAgcG9zaXRpb24gPSB0b1BvaW50KGV2ZW50KSxcbiAgICAgICAgZGVsdGEgPSBkZWx0YVBvcyhwb3NpdGlvbiwgc3RhcnQpO1xuXG4gICAgaWYgKCFjb250ZXh0LmRyYWdnaW5nICYmIGxlbmd0aChkZWx0YSkgPiBUSFJFU0hPTEQpIHtcbiAgICAgIGNvbnRleHQuZHJhZ2dpbmcgPSB0cnVlO1xuXG4gICAgICBpbnN0YWxsQ2xpY2tUcmFwKGV2ZW50QnVzKTtcblxuICAgICAgY3Vyc29yU2V0KCdncmFiJyk7XG4gICAgfVxuXG4gICAgaWYgKGNvbnRleHQuZHJhZ2dpbmcpIHtcblxuICAgICAgdmFyIGxhc3RQb3NpdGlvbiA9IGNvbnRleHQubGFzdCB8fCBjb250ZXh0LnN0YXJ0O1xuXG4gICAgICBkZWx0YSA9IGRlbHRhUG9zKHBvc2l0aW9uLCBsYXN0UG9zaXRpb24pO1xuXG4gICAgICBjYW52YXMuc2Nyb2xsKHtcbiAgICAgICAgZHg6IGRlbHRhLngsXG4gICAgICAgIGR5OiBkZWx0YS55XG4gICAgICB9KTtcblxuICAgICAgY29udGV4dC5sYXN0ID0gcG9zaXRpb247XG4gICAgfVxuXG4gICAgLy8gcHJldmVudCBzZWxlY3RcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICB9XG5cblxuICBmdW5jdGlvbiBoYW5kbGVFbmQoZXZlbnQpIHtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdtb3VzZW1vdmUnLCBoYW5kbGVNb3ZlKTtcbiAgICBkb21FdmVudC51bmJpbmQoZG9jdW1lbnQsICdtb3VzZXVwJywgaGFuZGxlRW5kKTtcblxuICAgIGNvbnRleHQgPSBudWxsO1xuXG4gICAgY3Vyc29yVW5zZXQoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVN0YXJ0KGV2ZW50KSB7XG5cbiAgICAvLyBldmVudCBpcyBhbHJlYWR5IGhhbmRsZWQgYnkgJy5kanMtZHJhZ2dhYmxlJ1xuICAgIGlmIChkb21DbG9zZXN0KGV2ZW50LnRhcmdldCwgJy5kanMtZHJhZ2dhYmxlJykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cblxuICAgIC8vIHJlamVjdCBub24tbGVmdCBsZWZ0IG1vdXNlIGJ1dHRvbiBvciBtb2RpZmllciBrZXlcbiAgICBpZiAoZXZlbnQuYnV0dG9uIHx8IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQuc2hpZnRLZXkgfHwgZXZlbnQuYWx0S2V5KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29udGV4dCA9IHtcbiAgICAgIHN0YXJ0OiB0b1BvaW50KGV2ZW50KVxuICAgIH07XG5cbiAgICBkb21FdmVudC5iaW5kKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgaGFuZGxlTW92ZSk7XG4gICAgZG9tRXZlbnQuYmluZChkb2N1bWVudCwgJ21vdXNldXAnLCBoYW5kbGVFbmQpO1xuXG4gICAgLy8gd2UndmUgaGFuZGxlZCB0aGUgZXZlbnRcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG5cbk1vdmVDYW52YXMuJGluamVjdCA9IFtcbiAgJ2V2ZW50QnVzJyxcbiAgJ2NhbnZhcydcbl07XG5cblxuXG4vLyBoZWxwZXJzIC8vLy8vLy9cblxuZnVuY3Rpb24gbGVuZ3RoKHBvaW50KSB7XG4gIHJldHVybiBNYXRoLnNxcnQoTWF0aC5wb3cocG9pbnQueCwgMikgKyBNYXRoLnBvdyhwb2ludC55LCAyKSk7XG59XG4iLCJpbXBvcnQgTW92ZUNhbnZhcyBmcm9tICcuL01vdmVDYW52YXMnO1xuXG5leHBvcnQgZGVmYXVsdCB7XG4gIF9faW5pdF9fOiBbICdtb3ZlQ2FudmFzJyBdLFxuICBtb3ZlQ2FudmFzOiBbICd0eXBlJywgTW92ZUNhbnZhcyBdXG59OyIsImltcG9ydCBUb3VjaE1vZHVsZSBmcm9tICcuLi8uLi9mZWF0dXJlcy90b3VjaCc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgX19kZXBlbmRzX186IFtcbiAgICBUb3VjaE1vZHVsZVxuICBdXG59OyIsImltcG9ydCB7XG4gIGV2ZW50IGFzIGRvbUV2ZW50LFxuICBjbG9zZXN0IGFzIGRvbUNsb3Nlc3Rcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7XG4gIGdldFN0ZXBTaXplLFxuICBjYXBcbn0gZnJvbSAnLi9ab29tVXRpbCc7XG5cbmltcG9ydCB7XG4gIGxvZzEwXG59IGZyb20gJy4uLy4uL3V0aWwvTWF0aCc7XG5cbmltcG9ydCB7XG4gIGJpbmRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG52YXIgc2lnbiA9IE1hdGguc2lnbiB8fCBmdW5jdGlvbihuKSB7XG4gIHJldHVybiBuID49IDAgPyAxIDogLTE7XG59O1xuXG52YXIgUkFOR0UgPSB7IG1pbjogMC4yLCBtYXg6IDQgfSxcbiAgICBOVU1fU1RFUFMgPSAxMDtcblxudmFyIERFTFRBX1RIUkVTSE9MRCA9IDAuMTtcblxudmFyIERFRkFVTFRfU0NBTEUgPSAwLjc1O1xuXG4vKipcbiAqIEFuIGltcGxlbWVudGF0aW9uIG9mIHpvb21pbmcgYW5kIHNjcm9sbGluZyB3aXRoaW4gdGhlXG4gKiB7QGxpbmsgQ2FudmFzfSB2aWEgdGhlIG1vdXNlIHdoZWVsLlxuICpcbiAqIE1vdXNlIHdoZWVsIHpvb21pbmcgLyBzY3JvbGxpbmcgbWF5IGJlIGRpc2FibGVkIHVzaW5nXG4gKiB0aGUge0BsaW5rIHRvZ2dsZShlbmFibGVkKX0gbWV0aG9kLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBbY29uZmlnXVxuICogQHBhcmFtIHtib29sZWFufSBbY29uZmlnLmVuYWJsZWQ9dHJ1ZV0gZGVmYXVsdCBlbmFibGVkIHN0YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmZpZy5zY2FsZT0uNzVdIHNjcm9sbCBzZW5zaXZpdHlcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIFpvb21TY3JvbGwoY29uZmlnLCBldmVudEJ1cywgY2FudmFzKSB7XG5cbiAgY29uZmlnID0gY29uZmlnIHx8IHt9O1xuXG4gIHRoaXMuX2VuYWJsZWQgPSBmYWxzZTtcblxuICB0aGlzLl9jYW52YXMgPSBjYW52YXM7XG4gIHRoaXMuX2NvbnRhaW5lciA9IGNhbnZhcy5fY29udGFpbmVyO1xuXG4gIHRoaXMuX2hhbmRsZVdoZWVsID0gYmluZCh0aGlzLl9oYW5kbGVXaGVlbCwgdGhpcyk7XG5cbiAgdGhpcy5fdG90YWxEZWx0YSA9IDA7XG4gIHRoaXMuX3NjYWxlID0gY29uZmlnLnNjYWxlIHx8IERFRkFVTFRfU0NBTEU7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuaW5pdCcsIGZ1bmN0aW9uKGUpIHtcbiAgICBzZWxmLl9pbml0KGNvbmZpZy5lbmFibGVkICE9PSBmYWxzZSk7XG4gIH0pO1xufVxuXG5ab29tU2Nyb2xsLiRpbmplY3QgPSBbXG4gICdjb25maWcuem9vbVNjcm9sbCcsXG4gICdldmVudEJ1cycsXG4gICdjYW52YXMnXG5dO1xuXG5ab29tU2Nyb2xsLnByb3RvdHlwZS5zY3JvbGwgPSBmdW5jdGlvbiBzY3JvbGwoZGVsdGEpIHtcbiAgdGhpcy5fY2FudmFzLnNjcm9sbChkZWx0YSk7XG59O1xuXG5cblpvb21TY3JvbGwucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gcmVzZXQoKSB7XG4gIHRoaXMuX2NhbnZhcy56b29tKCdmaXQtdmlld3BvcnQnKTtcbn07XG5cbi8qKlxuICogWm9vbSBkZXBlbmRpbmcgb24gZGVsdGEuXG4gKlxuICogQHBhcmFtIHtudW1iZXJ9IGRlbHRhXG4gKiBAcGFyYW0ge09iamVjdH0gcG9zaXRpb25cbiAqL1xuWm9vbVNjcm9sbC5wcm90b3R5cGUuem9vbSA9IGZ1bmN0aW9uIHpvb20oZGVsdGEsIHBvc2l0aW9uKSB7XG5cbiAgLy8gem9vbSB3aXRoIGhhbGYgdGhlIHN0ZXAgc2l6ZSBvZiBzdGVwWm9vbVxuICB2YXIgc3RlcFNpemUgPSBnZXRTdGVwU2l6ZShSQU5HRSwgTlVNX1NURVBTICogMik7XG5cbiAgLy8gYWRkIHVudGlsIHRocmVzaG9sZCByZWFjaGVkXG4gIHRoaXMuX3RvdGFsRGVsdGEgKz0gZGVsdGE7XG5cbiAgaWYgKE1hdGguYWJzKHRoaXMuX3RvdGFsRGVsdGEpID4gREVMVEFfVEhSRVNIT0xEKSB7XG4gICAgdGhpcy5fem9vbShkZWx0YSwgcG9zaXRpb24sIHN0ZXBTaXplKTtcblxuICAgIC8vIHJlc2V0XG4gICAgdGhpcy5fdG90YWxEZWx0YSA9IDA7XG4gIH1cbn07XG5cblxuWm9vbVNjcm9sbC5wcm90b3R5cGUuX2hhbmRsZVdoZWVsID0gZnVuY3Rpb24gaGFuZGxlV2hlZWwoZXZlbnQpIHtcblxuICAvLyBldmVudCBpcyBhbHJlYWR5IGhhbmRsZWQgYnkgJy5kanMtc2Nyb2xsYWJsZSdcbiAgaWYgKGRvbUNsb3Nlc3QoZXZlbnQudGFyZ2V0LCAnLmRqcy1zY3JvbGxhYmxlJywgdHJ1ZSkpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZWxlbWVudCA9IHRoaXMuX2NvbnRhaW5lcjtcblxuICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gIC8vIHBpbmNoIHRvIHpvb20gaXMgbWFwcGVkIHRvIHdoZWVsICsgY3RybEtleSA9IHRydWVcbiAgLy8gaW4gbW9kZXJuIGJyb3dzZXJzICghKVxuXG4gIHZhciBpc1pvb20gPSBldmVudC5jdHJsS2V5O1xuXG4gIHZhciBpc0hvcml6b250YWxTY3JvbGwgPSBldmVudC5zaGlmdEtleTtcblxuICB2YXIgZmFjdG9yID0gLTEgKiB0aGlzLl9zY2FsZSxcbiAgICAgIGRlbHRhO1xuXG4gIGlmIChpc1pvb20pIHtcbiAgICBmYWN0b3IgKj0gZXZlbnQuZGVsdGFNb2RlID09PSAwID8gMC4wMjAgOiAwLjMyO1xuICB9IGVsc2Uge1xuICAgIGZhY3RvciAqPSBldmVudC5kZWx0YU1vZGUgPT09IDAgPyAxLjAgOiAxNi4wO1xuICB9XG5cbiAgaWYgKGlzWm9vbSkge1xuICAgIHZhciBlbGVtZW50UmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICB2YXIgb2Zmc2V0ID0ge1xuICAgICAgeDogZXZlbnQuY2xpZW50WCAtIGVsZW1lbnRSZWN0LmxlZnQsXG4gICAgICB5OiBldmVudC5jbGllbnRZIC0gZWxlbWVudFJlY3QudG9wXG4gICAgfTtcblxuICAgIGRlbHRhID0gKFxuICAgICAgTWF0aC5zcXJ0KFxuICAgICAgICBNYXRoLnBvdyhldmVudC5kZWx0YVksIDIpICtcbiAgICAgICAgTWF0aC5wb3coZXZlbnQuZGVsdGFYLCAyKVxuICAgICAgKSAqIHNpZ24oZXZlbnQuZGVsdGFZKSAqIGZhY3RvclxuICAgICk7XG5cbiAgICAvLyB6b29tIGluIHJlbGF0aXZlIHRvIGRpYWdyYW0ge3gseX0gY29vcmRpbmF0ZXNcbiAgICB0aGlzLnpvb20oZGVsdGEsIG9mZnNldCk7XG4gIH0gZWxzZSB7XG5cbiAgICBpZiAoaXNIb3Jpem9udGFsU2Nyb2xsKSB7XG4gICAgICBkZWx0YSA9IHtcbiAgICAgICAgZHg6IGZhY3RvciAqIGV2ZW50LmRlbHRhWSxcbiAgICAgICAgZHk6IDBcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbHRhID0ge1xuICAgICAgICBkeDogZmFjdG9yICogZXZlbnQuZGVsdGFYLFxuICAgICAgICBkeTogZmFjdG9yICogZXZlbnQuZGVsdGFZXG4gICAgICB9O1xuICAgIH1cblxuICAgIHRoaXMuc2Nyb2xsKGRlbHRhKTtcbiAgfVxufTtcblxuLyoqXG4gKiBab29tIHdpdGggZml4ZWQgc3RlcCBzaXplLlxuICpcbiAqIEBwYXJhbSB7bnVtYmVyfSBkZWx0YSAtIFpvb20gZGVsdGEgKDEgZm9yIHpvb21pbmcgaW4sIC0xIGZvciBvdXQpLlxuICogQHBhcmFtIHtPYmplY3R9IHBvc2l0aW9uXG4gKi9cblpvb21TY3JvbGwucHJvdG90eXBlLnN0ZXBab29tID0gZnVuY3Rpb24gc3RlcFpvb20oZGVsdGEsIHBvc2l0aW9uKSB7XG5cbiAgdmFyIHN0ZXBTaXplID0gZ2V0U3RlcFNpemUoUkFOR0UsIE5VTV9TVEVQUyk7XG5cbiAgdGhpcy5fem9vbShkZWx0YSwgcG9zaXRpb24sIHN0ZXBTaXplKTtcbn07XG5cblxuLyoqXG4gKiBab29tIGluL291dCBnaXZlbiBhIHN0ZXAgc2l6ZS5cbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gZGVsdGFcbiAqIEBwYXJhbSB7T2JqZWN0fSBwb3NpdGlvblxuICogQHBhcmFtIHtudW1iZXJ9IHN0ZXBTaXplXG4gKi9cblpvb21TY3JvbGwucHJvdG90eXBlLl96b29tID0gZnVuY3Rpb24oZGVsdGEsIHBvc2l0aW9uLCBzdGVwU2l6ZSkge1xuICB2YXIgY2FudmFzID0gdGhpcy5fY2FudmFzO1xuXG4gIHZhciBkaXJlY3Rpb24gPSBkZWx0YSA+IDAgPyAxIDogLTE7XG5cbiAgdmFyIGN1cnJlbnRMaW5lYXJab29tTGV2ZWwgPSBsb2cxMChjYW52YXMuem9vbSgpKTtcblxuICAvLyBzbmFwIHRvIGEgcHJveGltYXRlIHpvb20gc3RlcFxuICB2YXIgbmV3TGluZWFyWm9vbUxldmVsID0gTWF0aC5yb3VuZChjdXJyZW50TGluZWFyWm9vbUxldmVsIC8gc3RlcFNpemUpICogc3RlcFNpemU7XG5cbiAgLy8gaW5jcmVhc2Ugb3IgZGVjcmVhc2Ugb25lIHpvb20gc3RlcCBpbiB0aGUgZ2l2ZW4gZGlyZWN0aW9uXG4gIG5ld0xpbmVhclpvb21MZXZlbCArPSBzdGVwU2l6ZSAqIGRpcmVjdGlvbjtcblxuICAvLyBjYWxjdWxhdGUgdGhlIGFic29sdXRlIGxvZ2FyaXRobWljIHpvb20gbGV2ZWwgYmFzZWQgb24gdGhlIGxpbmVhciB6b29tIGxldmVsXG4gIC8vIChlLmcuIDIgZm9yIGFuIGFic29sdXRlIHgyIHpvb20pXG4gIHZhciBuZXdMb2dab29tTGV2ZWwgPSBNYXRoLnBvdygxMCwgbmV3TGluZWFyWm9vbUxldmVsKTtcblxuICBjYW52YXMuem9vbShjYXAoUkFOR0UsIG5ld0xvZ1pvb21MZXZlbCksIHBvc2l0aW9uKTtcbn07XG5cblxuLyoqXG4gKiBUb2dnbGUgdGhlIHpvb20gc2Nyb2xsIGFiaWxpdHkgdmlhIG1vdXNlIHdoZWVsLlxuICpcbiAqIEBwYXJhbSAge2Jvb2xlYW59IFtuZXdFbmFibGVkXSBuZXcgZW5hYmxlZCBzdGF0ZVxuICovXG5ab29tU2Nyb2xsLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiB0b2dnbGUobmV3RW5hYmxlZCkge1xuXG4gIHZhciBlbGVtZW50ID0gdGhpcy5fY29udGFpbmVyO1xuICB2YXIgaGFuZGxlV2hlZWwgPSB0aGlzLl9oYW5kbGVXaGVlbDtcblxuICB2YXIgb2xkRW5hYmxlZCA9IHRoaXMuX2VuYWJsZWQ7XG5cbiAgaWYgKHR5cGVvZiBuZXdFbmFibGVkID09PSAndW5kZWZpbmVkJykge1xuICAgIG5ld0VuYWJsZWQgPSAhb2xkRW5hYmxlZDtcbiAgfVxuXG4gIC8vIG9ubHkgcmVhY3Qgb24gYWN0dWFsIGNoYW5nZXNcbiAgaWYgKG9sZEVuYWJsZWQgIT09IG5ld0VuYWJsZWQpIHtcblxuICAgIC8vIGFkZCBvciByZW1vdmUgd2hlZWwgbGlzdGVuZXIgYmFzZWQgb25cbiAgICAvLyBjaGFuZ2VkIGVuYWJsZWQgc3RhdGVcbiAgICBkb21FdmVudFtuZXdFbmFibGVkID8gJ2JpbmQnIDogJ3VuYmluZCddKGVsZW1lbnQsICd3aGVlbCcsIGhhbmRsZVdoZWVsLCBmYWxzZSk7XG4gIH1cblxuICB0aGlzLl9lbmFibGVkID0gbmV3RW5hYmxlZDtcblxuICByZXR1cm4gbmV3RW5hYmxlZDtcbn07XG5cblxuWm9vbVNjcm9sbC5wcm90b3R5cGUuX2luaXQgPSBmdW5jdGlvbihuZXdFbmFibGVkKSB7XG4gIHRoaXMudG9nZ2xlKG5ld0VuYWJsZWQpO1xufTtcbiIsImltcG9ydCB7XG4gIGxvZzEwXG59IGZyb20gJy4uLy4uL3V0aWwvTWF0aCc7XG5cbi8qKlxuICogR2V0IHN0ZXAgc2l6ZSBmb3IgZ2l2ZW4gcmFuZ2UgYW5kIG51bWJlciBvZiBzdGVwcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcmFuZ2VcbiAqIEBwYXJhbSB7bnVtYmVyfSByYW5nZS5taW5cbiAqIEBwYXJhbSB7bnVtYmVyfSByYW5nZS5tYXhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFN0ZXBTaXplKHJhbmdlLCBzdGVwcykge1xuXG4gIHZhciBtaW5MaW5lYXJSYW5nZSA9IGxvZzEwKHJhbmdlLm1pbiksXG4gICAgICBtYXhMaW5lYXJSYW5nZSA9IGxvZzEwKHJhbmdlLm1heCk7XG5cbiAgdmFyIGFic29sdXRlTGluZWFyUmFuZ2UgPSBNYXRoLmFicyhtaW5MaW5lYXJSYW5nZSkgKyBNYXRoLmFicyhtYXhMaW5lYXJSYW5nZSk7XG5cbiAgcmV0dXJuIGFic29sdXRlTGluZWFyUmFuZ2UgLyBzdGVwcztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNhcChyYW5nZSwgc2NhbGUpIHtcbiAgcmV0dXJuIE1hdGgubWF4KHJhbmdlLm1pbiwgTWF0aC5taW4ocmFuZ2UubWF4LCBzY2FsZSkpO1xufVxuIiwiaW1wb3J0IFpvb21TY3JvbGwgZnJvbSAnLi9ab29tU2Nyb2xsJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2luaXRfXzogWyAnem9vbVNjcm9sbCcgXSxcbiAgem9vbVNjcm9sbDogWyAndHlwZScsIFpvb21TY3JvbGwgXVxufTsiLCJpbXBvcnQge1xuICBhc1RSQkwsXG4gIGdldE9yaWVudGF0aW9uLFxuICByb3VuZFBvaW50XG59IGZyb20gJy4uL2xheW91dC9MYXlvdXRVdGlsJztcblxuaW1wb3J0IHtcbiAgY2VudGVyLFxuICBkZWx0YVxufSBmcm9tICcuL1Bvc2l0aW9uVXRpbCc7XG5cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBhYnNvbHV0ZSBwb2ludCByZWxhdGl2ZSB0byB0aGUgbmV3IGVsZW1lbnQncyBwb3NpdGlvblxuICpcbiAqIEBwYXJhbSB7cG9pbnR9IHBvaW50IFthYnNvbHV0ZV1cbiAqIEBwYXJhbSB7Ym91bmRzfSBvbGRCb3VuZHNcbiAqIEBwYXJhbSB7Ym91bmRzfSBuZXdCb3VuZHNcbiAqXG4gKiBAcmV0dXJuIHtwb2ludH0gcG9pbnQgW2Fic29sdXRlXVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmV3QXR0YWNoUG9pbnQocG9pbnQsIG9sZEJvdW5kcywgbmV3Qm91bmRzKSB7XG4gIHZhciBvbGRDZW50ZXIgPSBjZW50ZXIob2xkQm91bmRzKSxcbiAgICAgIG5ld0NlbnRlciA9IGNlbnRlcihuZXdCb3VuZHMpLFxuICAgICAgb2xkRGVsdGEgPSBkZWx0YShwb2ludCwgb2xkQ2VudGVyKTtcblxuICB2YXIgbmV3RGVsdGEgPSB7XG4gICAgeDogb2xkRGVsdGEueCAqIChuZXdCb3VuZHMud2lkdGggLyBvbGRCb3VuZHMud2lkdGgpLFxuICAgIHk6IG9sZERlbHRhLnkgKiAobmV3Qm91bmRzLmhlaWdodCAvIG9sZEJvdW5kcy5oZWlnaHQpXG4gIH07XG5cbiAgcmV0dXJuIHJvdW5kUG9pbnQoe1xuICAgIHg6IG5ld0NlbnRlci54ICsgbmV3RGVsdGEueCxcbiAgICB5OiBuZXdDZW50ZXIueSArIG5ld0RlbHRhLnlcbiAgfSk7XG59XG5cblxuLyoqXG4gKiBDYWxjdWxhdGVzIHRoZSBzaGFwZSdzIGRlbHRhIHJlbGF0aXZlIHRvIGEgbmV3IHBvc2l0aW9uXG4gKiBvZiBhIGNlcnRhaW4gZWxlbWVudCdzIGJvdW5kc1xuICpcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBwb2ludCBbYWJzb2x1dGVdXG4gKiBAcGFyYW0ge2JvdW5kc30gb2xkQm91bmRzXG4gKiBAcGFyYW0ge2JvdW5kc30gbmV3Qm91bmRzXG4gKlxuICogQHJldHVybiB7ZGVsdGF9IGRlbHRhXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXROZXdBdHRhY2hTaGFwZURlbHRhKHNoYXBlLCBvbGRCb3VuZHMsIG5ld0JvdW5kcykge1xuICB2YXIgc2hhcGVDZW50ZXIgPSBjZW50ZXIoc2hhcGUpLFxuICAgICAgb2xkQ2VudGVyID0gY2VudGVyKG9sZEJvdW5kcyksXG4gICAgICBuZXdDZW50ZXIgPSBjZW50ZXIobmV3Qm91bmRzKSxcbiAgICAgIHNoYXBlRGVsdGEgPSBkZWx0YShzaGFwZSwgc2hhcGVDZW50ZXIpLFxuICAgICAgb2xkQ2VudGVyRGVsdGEgPSBkZWx0YShzaGFwZUNlbnRlciwgb2xkQ2VudGVyKSxcbiAgICAgIHN0aWNreVBvc2l0aW9uRGVsdGEgPSBnZXRTdGlja3lQb3NpdGlvbkRlbHRhKHNoYXBlQ2VudGVyLCBvbGRCb3VuZHMsIG5ld0JvdW5kcyk7XG5cbiAgaWYgKHN0aWNreVBvc2l0aW9uRGVsdGEpIHtcbiAgICByZXR1cm4gc3RpY2t5UG9zaXRpb25EZWx0YTtcbiAgfVxuXG4gIHZhciBuZXdDZW50ZXJEZWx0YSA9IHtcbiAgICB4OiBvbGRDZW50ZXJEZWx0YS54ICogKG5ld0JvdW5kcy53aWR0aCAvIG9sZEJvdW5kcy53aWR0aCksXG4gICAgeTogb2xkQ2VudGVyRGVsdGEueSAqIChuZXdCb3VuZHMuaGVpZ2h0IC8gb2xkQm91bmRzLmhlaWdodClcbiAgfTtcblxuICB2YXIgbmV3U2hhcGVDZW50ZXIgPSB7XG4gICAgeDogbmV3Q2VudGVyLnggKyBuZXdDZW50ZXJEZWx0YS54LFxuICAgIHk6IG5ld0NlbnRlci55ICsgbmV3Q2VudGVyRGVsdGEueVxuICB9O1xuXG4gIHJldHVybiByb3VuZFBvaW50KHtcbiAgICB4OiBuZXdTaGFwZUNlbnRlci54ICsgc2hhcGVEZWx0YS54IC0gc2hhcGUueCxcbiAgICB5OiBuZXdTaGFwZUNlbnRlci55ICsgc2hhcGVEZWx0YS55IC0gc2hhcGUueVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RpY2t5UG9zaXRpb25EZWx0YShvbGRTaGFwZUNlbnRlciwgb2xkQm91bmRzLCBuZXdCb3VuZHMpIHtcbiAgdmFyIG9sZFRSQkwgPSBhc1RSQkwob2xkQm91bmRzKSxcbiAgICAgIG5ld1RSQkwgPSBhc1RSQkwobmV3Qm91bmRzKTtcblxuICBpZiAoaXNNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIG9sZE9yaWVudGF0aW9uID0gZ2V0T3JpZW50YXRpb24ob2xkQm91bmRzLCBvbGRTaGFwZUNlbnRlciksXG4gICAgICBzdGlja3lQb3NpdGlvbkRlbHRhLFxuICAgICAgbmV3U2hhcGVDZW50ZXIsXG4gICAgICBuZXdPcmllbnRhdGlvbjtcblxuICBpZiAob2xkT3JpZW50YXRpb24gPT09ICd0b3AnKSB7XG4gICAgc3RpY2t5UG9zaXRpb25EZWx0YSA9IHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiBuZXdUUkJMLmJvdHRvbSAtIG9sZFRSQkwuYm90dG9tXG4gICAgfTtcbiAgfSBlbHNlIGlmIChvbGRPcmllbnRhdGlvbiA9PT0gJ2JvdHRvbScpIHtcbiAgICBzdGlja3lQb3NpdGlvbkRlbHRhID0ge1xuICAgICAgeDogMCxcbiAgICAgIHk6IG5ld1RSQkwudG9wIC0gb2xkVFJCTC50b3BcbiAgICB9O1xuICB9IGVsc2UgaWYgKG9sZE9yaWVudGF0aW9uID09PSAncmlnaHQnKSB7XG4gICAgc3RpY2t5UG9zaXRpb25EZWx0YSA9IHtcbiAgICAgIHg6IG5ld1RSQkwubGVmdCAtIG9sZFRSQkwubGVmdCxcbiAgICAgIHk6IDBcbiAgICB9O1xuICB9IGVsc2UgaWYgKG9sZE9yaWVudGF0aW9uID09PSAnbGVmdCcpIHtcbiAgICBzdGlja3lQb3NpdGlvbkRlbHRhID0ge1xuICAgICAgeDogbmV3VFJCTC5yaWdodCAtIG9sZFRSQkwucmlnaHQsXG4gICAgICB5OiAwXG4gICAgfTtcbiAgfSBlbHNlIHtcblxuICAgIC8vIGZhbGxiYWNrIHRvIHByb3BvcnRpb25hbCBtb3ZlbWVudCBmb3IgY29ybmVyLXBsYWNlZCBhdHRhY2htZW50c1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgbmV3U2hhcGVDZW50ZXIgPSB7XG4gICAgeDogb2xkU2hhcGVDZW50ZXIueCArIHN0aWNreVBvc2l0aW9uRGVsdGEueCxcbiAgICB5OiBvbGRTaGFwZUNlbnRlci55ICsgc3RpY2t5UG9zaXRpb25EZWx0YS55XG4gIH07XG5cbiAgbmV3T3JpZW50YXRpb24gPSBnZXRPcmllbnRhdGlvbihuZXdCb3VuZHMsIG5ld1NoYXBlQ2VudGVyKTtcblxuICBpZiAobmV3T3JpZW50YXRpb24gIT09IG9sZE9yaWVudGF0aW9uKSB7XG5cbiAgICAvLyBmYWxsYmFjayB0byBwcm9wb3J0aW9uYWwgbW92ZW1lbnQgaWYgb3JpZW50YXRpb24gd291bGQgb3RoZXJ3aXNlIGNoYW5nZVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHN0aWNreVBvc2l0aW9uRGVsdGE7XG59XG5cbmZ1bmN0aW9uIGlzTW92ZWQob2xkVFJCTCwgbmV3VFJCTCkge1xuICByZXR1cm4gaXNIb3Jpem9udGFsbHlNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKSB8fCBpc1ZlcnRpY2FsbHlNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKTtcbn1cblxuZnVuY3Rpb24gaXNIb3Jpem9udGFsbHlNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKSB7XG4gIHJldHVybiBvbGRUUkJMLnJpZ2h0ICE9PSBuZXdUUkJMLnJpZ2h0ICYmIG9sZFRSQkwubGVmdCAhPT0gbmV3VFJCTC5sZWZ0O1xufVxuXG5mdW5jdGlvbiBpc1ZlcnRpY2FsbHlNb3ZlZChvbGRUUkJMLCBuZXdUUkJMKSB7XG4gIHJldHVybiBvbGRUUkJMLnRvcCAhPT0gbmV3VFJCTC50b3AgJiYgb2xkVFJCTC5ib3R0b20gIT09IG5ld1RSQkwuYm90dG9tO1xufVxuIiwidmFyIFRSQVBfUFJJT1JJVFkgPSA1MDAwO1xuXG4vKipcbiAqIEluc3RhbGxzIGEgY2xpY2sgdHJhcCB0aGF0IHByZXZlbnRzIGEgZ2hvc3QgY2xpY2sgZm9sbG93aW5nIGEgZHJhZ2dpbmcgb3BlcmF0aW9uLlxuICpcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBhIGZ1bmN0aW9uIHRvIGltbWVkaWF0ZWx5IHJlbW92ZSB0aGUgaW5zdGFsbGVkIHRyYXAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YWxsKGV2ZW50QnVzLCBldmVudE5hbWUpIHtcblxuICBldmVudE5hbWUgPSBldmVudE5hbWUgfHwgJ2VsZW1lbnQuY2xpY2snO1xuXG4gIGZ1bmN0aW9uIHRyYXAoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZXZlbnRCdXMub25jZShldmVudE5hbWUsIFRSQVBfUFJJT1JJVFksIHRyYXApO1xuXG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICBldmVudEJ1cy5vZmYoZXZlbnROYW1lLCB0cmFwKTtcbiAgfTtcbn0iLCIvKipcbiAqIEZhaWxzYWZlIHJlbW92ZSBhbiBlbGVtZW50IGZyb20gYSBjb2xsZWN0aW9uXG4gKlxuICogQHBhcmFtICB7QXJyYXk8T2JqZWN0Pn0gW2NvbGxlY3Rpb25dXG4gKiBAcGFyYW0gIHtPYmplY3R9IFtlbGVtZW50XVxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gdGhlIHByZXZpb3VzIGluZGV4IG9mIHRoZSBlbGVtZW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW1vdmUoY29sbGVjdGlvbiwgZWxlbWVudCkge1xuXG4gIGlmICghY29sbGVjdGlvbiB8fCAhZWxlbWVudCkge1xuICAgIHJldHVybiAtMTtcbiAgfVxuXG4gIHZhciBpZHggPSBjb2xsZWN0aW9uLmluZGV4T2YoZWxlbWVudCk7XG5cbiAgaWYgKGlkeCAhPT0gLTEpIHtcbiAgICBjb2xsZWN0aW9uLnNwbGljZShpZHgsIDEpO1xuICB9XG5cbiAgcmV0dXJuIGlkeDtcbn1cblxuLyoqXG4gKiBGYWlsIHNhdmUgYWRkIGFuIGVsZW1lbnQgdG8gdGhlIGdpdmVuIGNvbm5lY3Rpb24sIGVuc3VyaW5nXG4gKiBpdCBkb2VzIG5vdCB5ZXQgZXhpc3QuXG4gKlxuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBjb2xsZWN0aW9uXG4gKiBAcGFyYW0ge09iamVjdH0gZWxlbWVudFxuICogQHBhcmFtIHtudW1iZXJ9IGlkeFxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkKGNvbGxlY3Rpb24sIGVsZW1lbnQsIGlkeCkge1xuXG4gIGlmICghY29sbGVjdGlvbiB8fCAhZWxlbWVudCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGlmICh0eXBlb2YgaWR4ICE9PSAnbnVtYmVyJykge1xuICAgIGlkeCA9IC0xO1xuICB9XG5cbiAgdmFyIGN1cnJlbnRJZHggPSBjb2xsZWN0aW9uLmluZGV4T2YoZWxlbWVudCk7XG5cbiAgaWYgKGN1cnJlbnRJZHggIT09IC0xKSB7XG5cbiAgICBpZiAoY3VycmVudElkeCA9PT0gaWR4KSB7XG5cbiAgICAgIC8vIG5vdGhpbmcgdG8gZG8sIHBvc2l0aW9uIGhhcyBub3QgY2hhbmdlZFxuICAgICAgcmV0dXJuO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIGlmIChpZHggIT09IC0xKSB7XG5cbiAgICAgICAgLy8gcmVtb3ZlIGZyb20gY3VycmVudCBwb3NpdGlvblxuICAgICAgICBjb2xsZWN0aW9uLnNwbGljZShjdXJyZW50SWR4LCAxKTtcbiAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgLy8gYWxyZWFkeSBleGlzdHMgaW4gY29sbGVjdGlvblxuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGlkeCAhPT0gLTEpIHtcblxuICAgIC8vIGluc2VydCBhdCBzcGVjaWZpZWQgcG9zaXRpb25cbiAgICBjb2xsZWN0aW9uLnNwbGljZShpZHgsIDAsIGVsZW1lbnQpO1xuICB9IGVsc2Uge1xuXG4gICAgLy8gcHVzaCB0byBlbmRcbiAgICBjb2xsZWN0aW9uLnB1c2goZWxlbWVudCk7XG4gIH1cbn1cblxuXG4vKipcbiAqIEZhaWwgc2F2ZSBnZXQgdGhlIGluZGV4IG9mIGFuIGVsZW1lbnQgaW4gYSBjb2xsZWN0aW9uLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gY29sbGVjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnRcbiAqXG4gKiBAcmV0dXJuIHtudW1iZXJ9IHRoZSBpbmRleCBvciAtMSBpZiBjb2xsZWN0aW9uIG9yIGVsZW1lbnQgZG9cbiAqICAgICAgICAgICAgICAgICAgbm90IGV4aXN0IG9yIHRoZSBlbGVtZW50IGlzIG5vdCBjb250YWluZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbmRleE9mKGNvbGxlY3Rpb24sIGVsZW1lbnQpIHtcblxuICBpZiAoIWNvbGxlY3Rpb24gfHwgIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICByZXR1cm4gY29sbGVjdGlvbi5pbmRleE9mKGVsZW1lbnQpO1xufVxuIiwiaW1wb3J0IHtcbiAgY2xhc3NlcyBhcyBkb21DbGFzc2VzXG59IGZyb20gJ21pbi1kb20nO1xuXG52YXIgQ1VSU09SX0NMU19QQVRURVJOID0gL15kanMtY3Vyc29yLS4qJC87XG5cblxuZXhwb3J0IGZ1bmN0aW9uIHNldChtb2RlKSB7XG4gIHZhciBjbGFzc2VzID0gZG9tQ2xhc3Nlcyhkb2N1bWVudC5ib2R5KTtcblxuICBjbGFzc2VzLnJlbW92ZU1hdGNoaW5nKENVUlNPUl9DTFNfUEFUVEVSTik7XG5cbiAgaWYgKG1vZGUpIHtcbiAgICBjbGFzc2VzLmFkZCgnZGpzLWN1cnNvci0nICsgbW9kZSk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVuc2V0KCkge1xuICBzZXQobnVsbCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBoYXMobW9kZSkge1xuICB2YXIgY2xhc3NlcyA9IGRvbUNsYXNzZXMoZG9jdW1lbnQuYm9keSk7XG5cbiAgcmV0dXJuIGNsYXNzZXMuaGFzKCdkanMtY3Vyc29yLScgKyBtb2RlKTtcbn1cbiIsImltcG9ydCB7XG4gIGFzc2lnbixcbiAgZmlsdGVyLFxuICBmaW5kLFxuICBpc0FycmF5LFxuICBpc051bWJlcixcbiAgaXNPYmplY3QsXG4gIGlzVW5kZWZpbmVkLFxuICBncm91cEJ5LFxuICBmb3JFYWNoXG59IGZyb20gJ21pbi1kYXNoJztcblxuXG4vKipcbiAqIEdldCBwYXJlbnQgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuYmFzZT59IGVsZW1lbnRzXG4gKlxuICogQHJldHVybnMge0FycmF5PGRqcy5tb2RlbC5CYXNlPn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFBhcmVudHMoZWxlbWVudHMpIHtcblxuICAvLyBmaW5kIGVsZW1lbnRzIHRoYXQgYXJlIG5vdCBjaGlsZHJlbiBvZiBhbnkgb3RoZXIgZWxlbWVudHNcbiAgcmV0dXJuIGZpbHRlcihlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuICAgIHJldHVybiAhZmluZChlbGVtZW50cywgZnVuY3Rpb24oZSkge1xuICAgICAgcmV0dXJuIGUgIT09IGVsZW1lbnQgJiYgZ2V0UGFyZW50KGVsZW1lbnQsIGUpO1xuICAgIH0pO1xuICB9KTtcbn1cblxuXG5mdW5jdGlvbiBnZXRQYXJlbnQoZWxlbWVudCwgcGFyZW50KSB7XG4gIGlmICghcGFyZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKGVsZW1lbnQgPT09IHBhcmVudCkge1xuICAgIHJldHVybiBwYXJlbnQ7XG4gIH1cblxuICBpZiAoIWVsZW1lbnQucGFyZW50KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgcmV0dXJuIGdldFBhcmVudChlbGVtZW50LnBhcmVudCwgcGFyZW50KTtcbn1cblxuXG4vKipcbiAqIEFkZHMgYW4gZWxlbWVudCB0byBhIGNvbGxlY3Rpb24gYW5kIHJldHVybnMgdHJ1ZSBpZiB0aGVcbiAqIGVsZW1lbnQgd2FzIGFkZGVkLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gZWxlbWVudHNcbiAqIEBwYXJhbSB7T2JqZWN0fSBlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHVuaXF1ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gYWRkKGVsZW1lbnRzLCBlLCB1bmlxdWUpIHtcbiAgdmFyIGNhbkFkZCA9ICF1bmlxdWUgfHwgZWxlbWVudHMuaW5kZXhPZihlKSA9PT0gLTE7XG5cbiAgaWYgKGNhbkFkZCkge1xuICAgIGVsZW1lbnRzLnB1c2goZSk7XG4gIH1cblxuICByZXR1cm4gY2FuQWRkO1xufVxuXG5cbi8qKlxuICogSXRlcmF0ZSBvdmVyIGVhY2ggZWxlbWVudCBpbiBhIGNvbGxlY3Rpb24sIGNhbGxpbmcgdGhlIGl0ZXJhdG9yIGZ1bmN0aW9uIGBmbmBcbiAqIHdpdGggKGVsZW1lbnQsIGluZGV4LCByZWN1cnNpb25EZXB0aCkuXG4gKlxuICogUmVjdXJzZSBpbnRvIGFsbCBlbGVtZW50cyB0aGF0IGFyZSByZXR1cm5lZCBieSBgZm5gLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheTxPYmplY3Q+fSBlbGVtZW50c1xuICogQHBhcmFtICB7RnVuY3Rpb259IGZuIGl0ZXJhdG9yIGZ1bmN0aW9uIGNhbGxlZCB3aXRoIChlbGVtZW50LCBpbmRleCwgcmVjdXJzaW9uRGVwdGgpXG4gKiBAcGFyYW0gIHtudW1iZXJ9IFtkZXB0aF0gbWF4aW11bSByZWN1cnNpb24gZGVwdGhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVhY2hFbGVtZW50KGVsZW1lbnRzLCBmbiwgZGVwdGgpIHtcblxuICBkZXB0aCA9IGRlcHRoIHx8IDA7XG5cbiAgaWYgKCFpc0FycmF5KGVsZW1lbnRzKSkge1xuICAgIGVsZW1lbnRzID0gWyBlbGVtZW50cyBdO1xuICB9XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24ocywgaSkge1xuICAgIHZhciBmaWx0ZXIgPSBmbihzLCBpLCBkZXB0aCk7XG5cbiAgICBpZiAoaXNBcnJheShmaWx0ZXIpICYmIGZpbHRlci5sZW5ndGgpIHtcbiAgICAgIGVhY2hFbGVtZW50KGZpbHRlciwgZm4sIGRlcHRoICsgMSk7XG4gICAgfVxuICB9KTtcbn1cblxuXG4vKipcbiAqIENvbGxlY3RzIHNlbGYgKyBjaGlsZCBlbGVtZW50cyB1cCB0byBhIGdpdmVuIGRlcHRoIGZyb20gYSBsaXN0IG9mIGVsZW1lbnRzLlxuICpcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfEFycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHMgdGhlIGVsZW1lbnRzIHRvIHNlbGVjdCB0aGUgY2hpbGRyZW4gZnJvbVxuICogQHBhcmFtICB7Ym9vbGVhbn0gdW5pcXVlIHdoZXRoZXIgdG8gcmV0dXJuIGEgdW5pcXVlIHJlc3VsdCBzZXQgKG5vIGR1cGxpY2F0ZXMpXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1heERlcHRoIHRoZSBkZXB0aCB0byBzZWFyY2ggdGhyb3VnaCBvciAtMSBmb3IgaW5maW5pdGVcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuQmFzZT59IGZvdW5kIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWxmQW5kQ2hpbGRyZW4oZWxlbWVudHMsIHVuaXF1ZSwgbWF4RGVwdGgpIHtcbiAgdmFyIHJlc3VsdCA9IFtdLFxuICAgICAgcHJvY2Vzc2VkQ2hpbGRyZW4gPSBbXTtcblxuICBlYWNoRWxlbWVudChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCwgaSwgZGVwdGgpIHtcbiAgICBhZGQocmVzdWx0LCBlbGVtZW50LCB1bmlxdWUpO1xuXG4gICAgdmFyIGNoaWxkcmVuID0gZWxlbWVudC5jaGlsZHJlbjtcblxuICAgIC8vIG1heCB0cmF2ZXJzYWwgZGVwdGggbm90IHJlYWNoZWQgeWV0XG4gICAgaWYgKG1heERlcHRoID09PSAtMSB8fCBkZXB0aCA8IG1heERlcHRoKSB7XG5cbiAgICAgIC8vIGNoaWxkcmVuIGV4aXN0ICYmIGNoaWxkcmVuIG5vdCB5ZXQgcHJvY2Vzc2VkXG4gICAgICBpZiAoY2hpbGRyZW4gJiYgYWRkKHByb2Nlc3NlZENoaWxkcmVuLCBjaGlsZHJlbiwgdW5pcXVlKSkge1xuICAgICAgICByZXR1cm4gY2hpbGRyZW47XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFJldHVybiBzZWxmICsgZGlyZWN0IGNoaWxkcmVuIGZvciBhIG51bWJlciBvZiBlbGVtZW50c1xuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHMgdG8gcXVlcnlcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGFsbG93RHVwbGljYXRlcyB0byBhbGxvdyBkdXBsaWNhdGVzIGluIHRoZSByZXN1bHQgc2V0XG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSB0aGUgY29sbGVjdGVkIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWxmQW5kRGlyZWN0Q2hpbGRyZW4oZWxlbWVudHMsIGFsbG93RHVwbGljYXRlcykge1xuICByZXR1cm4gc2VsZkFuZENoaWxkcmVuKGVsZW1lbnRzLCAhYWxsb3dEdXBsaWNhdGVzLCAxKTtcbn1cblxuXG4vKipcbiAqIFJldHVybiBzZWxmICsgQUxMIGNoaWxkcmVuIGZvciBhIG51bWJlciBvZiBlbGVtZW50c1xuICpcbiAqIEBwYXJhbSAge0FycmF5PGRqcy5tb2RlbC5CYXNlPn0gZWxlbWVudHMgdG8gcXVlcnlcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGFsbG93RHVwbGljYXRlcyB0byBhbGxvdyBkdXBsaWNhdGVzIGluIHRoZSByZXN1bHQgc2V0XG4gKlxuICogQHJldHVybiB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSB0aGUgY29sbGVjdGVkIGVsZW1lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWxmQW5kQWxsQ2hpbGRyZW4oZWxlbWVudHMsIGFsbG93RHVwbGljYXRlcykge1xuICByZXR1cm4gc2VsZkFuZENoaWxkcmVuKGVsZW1lbnRzLCAhYWxsb3dEdXBsaWNhdGVzLCAtMSk7XG59XG5cblxuLyoqXG4gKiBHZXRzIHRoZSB0aGUgY2xvc3VyZSBmb3IgYWxsIHNlbGVjdGVkIGVsZW1lbnRzLFxuICogdGhlaXIgZW5jbG9zZWQgY2hpbGRyZW4gYW5kIGNvbm5lY3Rpb25zLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8ZGpzLm1vZGVsLkJhc2U+fSBlbGVtZW50c1xuICogQHBhcmFtIHtib29sZWFufSBbaXNUb3BMZXZlbD10cnVlXVxuICogQHBhcmFtIHtPYmplY3R9IFtleGlzdGluZ0Nsb3N1cmVdXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSBuZXdDbG9zdXJlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbG9zdXJlKGVsZW1lbnRzLCBpc1RvcExldmVsLCBjbG9zdXJlKSB7XG5cbiAgaWYgKGlzVW5kZWZpbmVkKGlzVG9wTGV2ZWwpKSB7XG4gICAgaXNUb3BMZXZlbCA9IHRydWU7XG4gIH1cblxuICBpZiAoaXNPYmplY3QoaXNUb3BMZXZlbCkpIHtcbiAgICBjbG9zdXJlID0gaXNUb3BMZXZlbDtcbiAgICBpc1RvcExldmVsID0gdHJ1ZTtcbiAgfVxuXG5cbiAgY2xvc3VyZSA9IGNsb3N1cmUgfHwge307XG5cbiAgdmFyIGFsbFNoYXBlcyA9IGNvcHlPYmplY3QoY2xvc3VyZS5hbGxTaGFwZXMpLFxuICAgICAgYWxsQ29ubmVjdGlvbnMgPSBjb3B5T2JqZWN0KGNsb3N1cmUuYWxsQ29ubmVjdGlvbnMpLFxuICAgICAgZW5jbG9zZWRFbGVtZW50cyA9IGNvcHlPYmplY3QoY2xvc3VyZS5lbmNsb3NlZEVsZW1lbnRzKSxcbiAgICAgIGVuY2xvc2VkQ29ubmVjdGlvbnMgPSBjb3B5T2JqZWN0KGNsb3N1cmUuZW5jbG9zZWRDb25uZWN0aW9ucyk7XG5cbiAgdmFyIHRvcExldmVsID0gY29weU9iamVjdChcbiAgICBjbG9zdXJlLnRvcExldmVsLFxuICAgIGlzVG9wTGV2ZWwgJiYgZ3JvdXBCeShlbGVtZW50cywgZnVuY3Rpb24oZSkgeyByZXR1cm4gZS5pZDsgfSlcbiAgKTtcblxuXG4gIGZ1bmN0aW9uIGhhbmRsZUNvbm5lY3Rpb24oYykge1xuICAgIGlmICh0b3BMZXZlbFtjLnNvdXJjZS5pZF0gJiYgdG9wTGV2ZWxbYy50YXJnZXQuaWRdKSB7XG4gICAgICB0b3BMZXZlbFtjLmlkXSA9IFsgYyBdO1xuICAgIH1cblxuICAgIC8vIG5vdCBlbmNsb3NlZCBhcyBhIGNoaWxkLCBidXQgbWF5YmUgbG9naWNhbGx5XG4gICAgLy8gKGNvbm5lY3RpbmcgdHdvIG1vdmVkIGVsZW1lbnRzPylcbiAgICBpZiAoYWxsU2hhcGVzW2Muc291cmNlLmlkXSAmJiBhbGxTaGFwZXNbYy50YXJnZXQuaWRdKSB7XG4gICAgICBlbmNsb3NlZENvbm5lY3Rpb25zW2MuaWRdID0gZW5jbG9zZWRFbGVtZW50c1tjLmlkXSA9IGM7XG4gICAgfVxuXG4gICAgYWxsQ29ubmVjdGlvbnNbYy5pZF0gPSBjO1xuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlRWxlbWVudChlbGVtZW50KSB7XG5cbiAgICBlbmNsb3NlZEVsZW1lbnRzW2VsZW1lbnQuaWRdID0gZWxlbWVudDtcblxuICAgIGlmIChlbGVtZW50LndheXBvaW50cykge1xuXG4gICAgICAvLyByZW1lbWJlciBjb25uZWN0aW9uXG4gICAgICBlbmNsb3NlZENvbm5lY3Rpb25zW2VsZW1lbnQuaWRdID0gYWxsQ29ubmVjdGlvbnNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIC8vIHJlbWVtYmVyIHNoYXBlXG4gICAgICBhbGxTaGFwZXNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuXG4gICAgICAvLyByZW1lbWJlciBhbGwgY29ubmVjdGlvbnNcbiAgICAgIGZvckVhY2goZWxlbWVudC5pbmNvbWluZywgaGFuZGxlQ29ubmVjdGlvbik7XG5cbiAgICAgIGZvckVhY2goZWxlbWVudC5vdXRnb2luZywgaGFuZGxlQ29ubmVjdGlvbik7XG5cbiAgICAgIC8vIHJlY3Vyc2UgaW50byBjaGlsZHJlblxuICAgICAgcmV0dXJuIGVsZW1lbnQuY2hpbGRyZW47XG4gICAgfVxuICB9XG5cbiAgZWFjaEVsZW1lbnQoZWxlbWVudHMsIGhhbmRsZUVsZW1lbnQpO1xuXG4gIHJldHVybiB7XG4gICAgYWxsU2hhcGVzOiBhbGxTaGFwZXMsXG4gICAgYWxsQ29ubmVjdGlvbnM6IGFsbENvbm5lY3Rpb25zLFxuICAgIHRvcExldmVsOiB0b3BMZXZlbCxcbiAgICBlbmNsb3NlZENvbm5lY3Rpb25zOiBlbmNsb3NlZENvbm5lY3Rpb25zLFxuICAgIGVuY2xvc2VkRWxlbWVudHM6IGVuY2xvc2VkRWxlbWVudHNcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBzdXJyb3VuZGluZyBiYm94IGZvciBhbGwgZWxlbWVudHMgaW5cbiAqIHRoZSBhcnJheSBvciB0aGUgZWxlbWVudCBwcmltaXRpdmUuXG4gKlxuICogQHBhcmFtIHtBcnJheTxkanMubW9kZWwuU2hhcGU+fGRqcy5tb2RlbC5TaGFwZX0gZWxlbWVudHNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gc3RvcFJlY3Vyc2lvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QkJveChlbGVtZW50cywgc3RvcFJlY3Vyc2lvbikge1xuXG4gIHN0b3BSZWN1cnNpb24gPSAhIXN0b3BSZWN1cnNpb247XG4gIGlmICghaXNBcnJheShlbGVtZW50cykpIHtcbiAgICBlbGVtZW50cyA9IFtlbGVtZW50c107XG4gIH1cblxuICB2YXIgbWluWCxcbiAgICAgIG1pblksXG4gICAgICBtYXhYLFxuICAgICAgbWF4WTtcblxuICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgICAvLyBJZiBlbGVtZW50IGlzIGEgY29ubmVjdGlvbiB0aGUgYmJveCBtdXN0IGJlIGNvbXB1dGVkIGZpcnN0XG4gICAgdmFyIGJib3ggPSBlbGVtZW50O1xuICAgIGlmIChlbGVtZW50LndheXBvaW50cyAmJiAhc3RvcFJlY3Vyc2lvbikge1xuICAgICAgYmJveCA9IGdldEJCb3goZWxlbWVudC53YXlwb2ludHMsIHRydWUpO1xuICAgIH1cblxuICAgIHZhciB4ID0gYmJveC54LFxuICAgICAgICB5ID0gYmJveC55LFxuICAgICAgICBoZWlnaHQgPSBiYm94LmhlaWdodCB8fCAwLFxuICAgICAgICB3aWR0aCA9IGJib3gud2lkdGggfHwgMDtcblxuICAgIGlmICh4IDwgbWluWCB8fCBtaW5YID09PSB1bmRlZmluZWQpIHtcbiAgICAgIG1pblggPSB4O1xuICAgIH1cbiAgICBpZiAoeSA8IG1pblkgfHwgbWluWSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBtaW5ZID0geTtcbiAgICB9XG5cbiAgICBpZiAoKHggKyB3aWR0aCkgPiBtYXhYIHx8IG1heFggPT09IHVuZGVmaW5lZCkge1xuICAgICAgbWF4WCA9IHggKyB3aWR0aDtcbiAgICB9XG4gICAgaWYgKCh5ICsgaGVpZ2h0KSA+IG1heFkgfHwgbWF4WSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBtYXhZID0geSArIGhlaWdodDtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiB7XG4gICAgeDogbWluWCxcbiAgICB5OiBtaW5ZLFxuICAgIGhlaWdodDogbWF4WSAtIG1pblksXG4gICAgd2lkdGg6IG1heFggLSBtaW5YXG4gIH07XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIGFsbCBlbGVtZW50cyB0aGF0IGFyZSBlbmNsb3NlZCBmcm9tIHRoZSBib3VuZGluZyBib3guXG4gKlxuICogICAqIElmIGJib3guKHdpZHRofGhlaWdodCkgaXMgbm90IHNwZWNpZmllZCB0aGUgbWV0aG9kIHJldHVybnNcbiAqICAgICBhbGwgZWxlbWVudHMgd2l0aCBlbGVtZW50LngveSA+IGJib3gueC95XG4gKiAgICogSWYgb25seSBiYm94Lnggb3IgYmJveC55IGlzIHNwZWNpZmllZCwgbWV0aG9kIHJldHVybiBhbGwgZWxlbWVudHMgd2l0aFxuICogICAgIGUueCA+IGJib3gueCBvciBlLnkgPiBiYm94LnlcbiAqXG4gKiBAcGFyYW0ge0FycmF5PGRqcy5tb2RlbC5TaGFwZT59IGVsZW1lbnRzIExpc3Qgb2YgRWxlbWVudHMgdG8gc2VhcmNoIHRocm91Z2hcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLlNoYXBlfSBiYm94IHRoZSBlbmNsb3NpbmcgYmJveC5cbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxkanMubW9kZWwuU2hhcGU+fSBlbmNsb3NlZCBlbGVtZW50c1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RW5jbG9zZWRFbGVtZW50cyhlbGVtZW50cywgYmJveCkge1xuXG4gIHZhciBmaWx0ZXJlZEVsZW1lbnRzID0ge307XG5cbiAgZm9yRWFjaChlbGVtZW50cywgZnVuY3Rpb24oZWxlbWVudCkge1xuXG4gICAgdmFyIGUgPSBlbGVtZW50O1xuXG4gICAgaWYgKGUud2F5cG9pbnRzKSB7XG4gICAgICBlID0gZ2V0QkJveChlKTtcbiAgICB9XG5cbiAgICBpZiAoIWlzTnVtYmVyKGJib3gueSkgJiYgKGUueCA+IGJib3gueCkpIHtcbiAgICAgIGZpbHRlcmVkRWxlbWVudHNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuICAgIH1cbiAgICBpZiAoIWlzTnVtYmVyKGJib3gueCkgJiYgKGUueSA+IGJib3gueSkpIHtcbiAgICAgIGZpbHRlcmVkRWxlbWVudHNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuICAgIH1cbiAgICBpZiAoZS54ID4gYmJveC54ICYmIGUueSA+IGJib3gueSkge1xuICAgICAgaWYgKGlzTnVtYmVyKGJib3gud2lkdGgpICYmIGlzTnVtYmVyKGJib3guaGVpZ2h0KSAmJlxuICAgICAgICAgIGUud2lkdGggKyBlLnggPCBiYm94LndpZHRoICsgYmJveC54ICYmXG4gICAgICAgICAgZS5oZWlnaHQgKyBlLnkgPCBiYm94LmhlaWdodCArIGJib3gueSkge1xuXG4gICAgICAgIGZpbHRlcmVkRWxlbWVudHNbZWxlbWVudC5pZF0gPSBlbGVtZW50O1xuICAgICAgfSBlbHNlIGlmICghaXNOdW1iZXIoYmJveC53aWR0aCkgfHwgIWlzTnVtYmVyKGJib3guaGVpZ2h0KSkge1xuICAgICAgICBmaWx0ZXJlZEVsZW1lbnRzW2VsZW1lbnQuaWRdID0gZWxlbWVudDtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBmaWx0ZXJlZEVsZW1lbnRzO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUeXBlKGVsZW1lbnQpIHtcblxuICBpZiAoJ3dheXBvaW50cycgaW4gZWxlbWVudCkge1xuICAgIHJldHVybiAnY29ubmVjdGlvbic7XG4gIH1cblxuICBpZiAoJ3gnIGluIGVsZW1lbnQpIHtcbiAgICByZXR1cm4gJ3NoYXBlJztcbiAgfVxuXG4gIHJldHVybiAncm9vdCc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc0ZyYW1lRWxlbWVudChlbGVtZW50KSB7XG5cbiAgcmV0dXJuICEhKGVsZW1lbnQgJiYgZWxlbWVudC5pc0ZyYW1lKTtcbn1cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNvcHlPYmplY3Qoc3JjMSwgc3JjMikge1xuICByZXR1cm4gYXNzaWduKHt9LCBzcmMxIHx8IHt9LCBzcmMyIHx8IHt9KTtcbn0iLCJleHBvcnQge1xuICBkZWZhdWx0IGFzIGVzY2FwZUNTU1xufSBmcm9tICdjc3MuZXNjYXBlJztcblxudmFyIEhUTUxfRVNDQVBFX01BUCA9IHtcbiAgJyYnOiAnJmFtcDsnLFxuICAnPCc6ICcmbHQ7JyxcbiAgJz4nOiAnJmd0OycsXG4gICdcIic6ICcmcXVvdDsnLFxuICAnXFwnJzogJyYjMzk7J1xufTtcblxuZXhwb3J0IGZ1bmN0aW9uIGVzY2FwZUhUTUwoc3RyKSB7XG4gIHN0ciA9ICcnICsgc3RyO1xuXG4gIHJldHVybiBzdHIgJiYgc3RyLnJlcGxhY2UoL1smPD5cIiddL2csIGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgcmV0dXJuIEhUTUxfRVNDQVBFX01BUFttYXRjaF07XG4gIH0pO1xufVxuIiwiZnVuY3Rpb24gX19zdG9wUHJvcGFnYXRpb24oZXZlbnQpIHtcbiAgaWYgKCFldmVudCB8fCB0eXBlb2YgZXZlbnQuc3RvcFByb3BhZ2F0aW9uICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9yaWdpbmFsKGV2ZW50KSB7XG4gIHJldHVybiBldmVudC5vcmlnaW5hbEV2ZW50IHx8IGV2ZW50LnNyY0V2ZW50O1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBzdG9wUHJvcGFnYXRpb24oZXZlbnQsIGltbWVkaWF0ZSkge1xuICBfX3N0b3BQcm9wYWdhdGlvbihldmVudCwgaW1tZWRpYXRlKTtcbiAgX19zdG9wUHJvcGFnYXRpb24oZ2V0T3JpZ2luYWwoZXZlbnQpLCBpbW1lZGlhdGUpO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiB0b1BvaW50KGV2ZW50KSB7XG5cbiAgaWYgKGV2ZW50LnBvaW50ZXJzICYmIGV2ZW50LnBvaW50ZXJzLmxlbmd0aCkge1xuICAgIGV2ZW50ID0gZXZlbnQucG9pbnRlcnNbMF07XG4gIH1cblxuICBpZiAoZXZlbnQudG91Y2hlcyAmJiBldmVudC50b3VjaGVzLmxlbmd0aCkge1xuICAgIGV2ZW50ID0gZXZlbnQudG91Y2hlc1swXTtcbiAgfVxuXG4gIHJldHVybiBldmVudCA/IHtcbiAgICB4OiBldmVudC5jbGllbnRYLFxuICAgIHk6IGV2ZW50LmNsaWVudFlcbiAgfSA6IG51bGw7XG59IiwiaW1wb3J0IHtcbiAgZXZlcnksXG4gIGlzQXJyYXlcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG4vKipcbiAqIENvbXB1dGVzIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIHR3byBwb2ludHNcbiAqXG4gKiBAcGFyYW0gIHtQb2ludH0gIHBcbiAqIEBwYXJhbSAge1BvaW50fSAgcVxuICpcbiAqIEByZXR1cm4ge251bWJlcn0gIGRpc3RhbmNlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb2ludERpc3RhbmNlKGEsIGIpIHtcbiAgaWYgKCFhIHx8ICFiKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgcmV0dXJuIE1hdGguc3FydChcbiAgICBNYXRoLnBvdyhhLnggLSBiLngsIDIpICtcbiAgICBNYXRoLnBvdyhhLnkgLSBiLnksIDIpXG4gICk7XG59XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHBvaW50IHIgaXMgb24gdGhlIGxpbmUgYmV0d2VlbiBwIGFuZCBxXG4gKlxuICogQHBhcmFtICB7UG9pbnR9ICBwXG4gKiBAcGFyYW0gIHtQb2ludH0gIHFcbiAqIEBwYXJhbSAge1BvaW50fSAgclxuICogQHBhcmFtICB7bnVtYmVyfSBbYWNjdXJhY3k9NV0gYWNjdXJhY3kgZm9yIHBvaW50cyBvbiBsaW5lIGNoZWNrIChsb3dlciBpcyBiZXR0ZXIpXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvaW50c09uTGluZShwLCBxLCByLCBhY2N1cmFjeSkge1xuXG4gIGlmICh0eXBlb2YgYWNjdXJhY3kgPT09ICd1bmRlZmluZWQnKSB7XG4gICAgYWNjdXJhY3kgPSA1O1xuICB9XG5cbiAgaWYgKCFwIHx8ICFxIHx8ICFyKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdmFyIHZhbCA9IChxLnggLSBwLngpICogKHIueSAtIHAueSkgLSAocS55IC0gcC55KSAqIChyLnggLSBwLngpLFxuICAgICAgZGlzdCA9IHBvaW50RGlzdGFuY2UocCwgcSk7XG5cbiAgLy8gQHNlZSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS85MDc0OTEvNDEyMTkwXG4gIHJldHVybiBNYXRoLmFicyh2YWwgLyBkaXN0KSA8PSBhY2N1cmFjeTtcbn1cblxuXG52YXIgQUxJR05FRF9USFJFU0hPTEQgPSAyO1xuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdHdvIHBvaW50cyBhcmUgaG9yaXpvbnRhbGx5IG9yIHZlcnRpY2FsbHkgYWxpZ25lZC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PFBvaW50PnxQb2ludH1cbiAqIEBwYXJhbSB7UG9pbnR9XG4gKlxuICogQHJldHVybiB7c3RyaW5nfGJvb2xlYW59XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb2ludHNBbGlnbmVkKGEsIGIpIHtcbiAgdmFyIHBvaW50cztcblxuICBpZiAoaXNBcnJheShhKSkge1xuICAgIHBvaW50cyA9IGE7XG4gIH0gZWxzZSB7XG4gICAgcG9pbnRzID0gWyBhLCBiIF07XG4gIH1cblxuICBpZiAocG9pbnRzQWxpZ25lZEhvcml6b250YWxseShwb2ludHMpKSB7XG4gICAgcmV0dXJuICdoJztcbiAgfVxuXG4gIGlmIChwb2ludHNBbGlnbmVkVmVydGljYWxseShwb2ludHMpKSB7XG4gICAgcmV0dXJuICd2JztcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBvaW50c0FsaWduZWRIb3Jpem9udGFsbHkoYSwgYikge1xuICB2YXIgcG9pbnRzO1xuXG4gIGlmIChpc0FycmF5KGEpKSB7XG4gICAgcG9pbnRzID0gYTtcbiAgfSBlbHNlIHtcbiAgICBwb2ludHMgPSBbIGEsIGIgXTtcbiAgfVxuXG4gIHZhciBmaXJzdFBvaW50ID0gcG9pbnRzLnNsaWNlKCkuc2hpZnQoKTtcblxuICByZXR1cm4gZXZlcnkocG9pbnRzLCBmdW5jdGlvbihwb2ludCkge1xuICAgIHJldHVybiBNYXRoLmFicyhmaXJzdFBvaW50LnkgLSBwb2ludC55KSA8PSBBTElHTkVEX1RIUkVTSE9MRDtcbiAgfSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwb2ludHNBbGlnbmVkVmVydGljYWxseShhLCBiKSB7XG4gIHZhciBwb2ludHM7XG5cbiAgaWYgKGlzQXJyYXkoYSkpIHtcbiAgICBwb2ludHMgPSBhO1xuICB9IGVsc2Uge1xuICAgIHBvaW50cyA9IFsgYSwgYiBdO1xuICB9XG5cbiAgdmFyIGZpcnN0UG9pbnQgPSBwb2ludHMuc2xpY2UoKS5zaGlmdCgpO1xuXG4gIHJldHVybiBldmVyeShwb2ludHMsIGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgcmV0dXJuIE1hdGguYWJzKGZpcnN0UG9pbnQueCAtIHBvaW50LngpIDw9IEFMSUdORURfVEhSRVNIT0xEO1xuICB9KTtcbn1cblxuXG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBwb2ludCBwIGlzIGluc2lkZSB0aGUgcmVjdGFuZ2xlIHJlY3RcbiAqXG4gKiBAcGFyYW0gIHtQb2ludH0gIHBcbiAqIEBwYXJhbSAge1JlY3R9IHJlY3RcbiAqIEBwYXJhbSAge251bWJlcn0gdG9sZXJhbmNlXG4gKlxuICogQHJldHVybiB7Ym9vbGVhbn1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvaW50SW5SZWN0KHAsIHJlY3QsIHRvbGVyYW5jZSkge1xuICB0b2xlcmFuY2UgPSB0b2xlcmFuY2UgfHwgMDtcblxuICByZXR1cm4gcC54ID4gcmVjdC54IC0gdG9sZXJhbmNlICYmXG4gICAgICAgICBwLnkgPiByZWN0LnkgLSB0b2xlcmFuY2UgJiZcbiAgICAgICAgIHAueCA8IHJlY3QueCArIHJlY3Qud2lkdGggKyB0b2xlcmFuY2UgJiZcbiAgICAgICAgIHAueSA8IHJlY3QueSArIHJlY3QuaGVpZ2h0ICsgdG9sZXJhbmNlO1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBwb2ludCBpbiB0aGUgbWlkZGxlIG9mIHBvaW50cyBwIGFuZCBxXG4gKlxuICogQHBhcmFtICB7UG9pbnR9ICBwXG4gKiBAcGFyYW0gIHtQb2ludH0gIHFcbiAqXG4gKiBAcmV0dXJuIHtQb2ludH0gbWlkZGxlIHBvaW50XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRNaWRQb2ludChwLCBxKSB7XG4gIHJldHVybiB7XG4gICAgeDogTWF0aC5yb3VuZChwLnggKyAoKHEueCAtIHAueCkgLyAyLjApKSxcbiAgICB5OiBNYXRoLnJvdW5kKHAueSArICgocS55IC0gcC55KSAvIDIuMCkpXG4gIH07XG59XG4iLCIvKipcbiAqIFNWR3MgZm9yIGVsZW1lbnRzIGFyZSBnZW5lcmF0ZWQgYnkgdGhlIHtAbGluayBHcmFwaGljc0ZhY3Rvcnl9LlxuICpcbiAqIFRoaXMgdXRpbGl0eSBnaXZlcyBxdWljayBhY2Nlc3MgdG8gdGhlIGltcG9ydGFudCBzZW1hbnRpY1xuICogcGFydHMgb2YgYW4gZWxlbWVudC5cbiAqL1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHZpc3VhbCBwYXJ0IG9mIGEgZGlhZ3JhbSBlbGVtZW50XG4gKlxuICogQHBhcmFtIHtTbmFwPFNWR0VsZW1lbnQ+fSBnZnhcbiAqXG4gKiBAcmV0dXJuIHtTbmFwPFNWR0VsZW1lbnQ+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmlzdWFsKGdmeCkge1xuICByZXR1cm4gZ2Z4LmNoaWxkTm9kZXNbMF07XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY2hpbGRyZW4gZm9yIGEgZ2l2ZW4gZGlhZ3JhbSBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7U25hcDxTVkdFbGVtZW50Pn0gZ2Z4XG4gKiBAcmV0dXJuIHtTbmFwPFNWR0VsZW1lbnQ+fVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Q2hpbGRyZW4oZ2Z4KSB7XG4gIHJldHVybiBnZngucGFyZW50Tm9kZS5jaGlsZE5vZGVzWzFdO1xufSIsIi8qKlxuICogVXRpbCB0aGF0IHByb3ZpZGVzIHVuaXF1ZSBJRHMuXG4gKlxuICogQGNsYXNzIGRqcy51dGlsLklkR2VuZXJhdG9yXG4gKiBAY29uc3RydWN0b3JcbiAqIEBtZW1iZXJPZiBkanMudXRpbFxuICpcbiAqIFRoZSBpZHMgY2FuIGJlIGN1c3RvbWl6ZWQgdmlhIGEgZ2l2ZW4gcHJlZml4IGFuZCBjb250YWluIGEgcmFuZG9tIHZhbHVlIHRvIGF2b2lkIGNvbGxpc2lvbnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHByZWZpeCBhIHByZWZpeCB0byBwcmVwZW5kIHRvIGdlbmVyYXRlZCBpZHMgKGZvciBiZXR0ZXIgcmVhZGFiaWxpdHkpXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIElkR2VuZXJhdG9yKHByZWZpeCkge1xuXG4gIHRoaXMuX2NvdW50ZXIgPSAwO1xuICB0aGlzLl9wcmVmaXggPSAocHJlZml4ID8gcHJlZml4ICsgJy0nIDogJycpICsgTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogMTAwMDAwMDAwMCkgKyAnLSc7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIG5leHQgdW5pcXVlIElELlxuICpcbiAqIEBtZXRob2QgZGpzLnV0aWwuSWRHZW5lcmF0b3IjbmV4dFxuICpcbiAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSBpZFxuICovXG5JZEdlbmVyYXRvci5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fcHJlZml4ICsgKCsrdGhpcy5fY291bnRlcik7XG59O1xuIiwiaW1wb3J0IHtcbiAgcG9pbnREaXN0YW5jZVxufSBmcm9tICcuL0dlb21ldHJ5JztcblxuaW1wb3J0IGludGVyc2VjdFBhdGhzIGZyb20gJ3BhdGgtaW50ZXJzZWN0aW9uJztcblxudmFyIHJvdW5kID0gTWF0aC5yb3VuZCxcbiAgICBtYXggPSBNYXRoLm1heDtcblxuXG5mdW5jdGlvbiBjaXJjbGVQYXRoKGNlbnRlciwgcikge1xuICB2YXIgeCA9IGNlbnRlci54LFxuICAgICAgeSA9IGNlbnRlci55O1xuXG4gIHJldHVybiBbXG4gICAgWydNJywgeCwgeV0sXG4gICAgWydtJywgMCwgLXJdLFxuICAgIFsnYScsIHIsIHIsIDAsIDEsIDEsIDAsIDIgKiByXSxcbiAgICBbJ2EnLCByLCByLCAwLCAxLCAxLCAwLCAtMiAqIHJdLFxuICAgIFsneiddXG4gIF07XG59XG5cbmZ1bmN0aW9uIGxpbmVQYXRoKHBvaW50cykge1xuICB2YXIgc2VnbWVudHMgPSBbXTtcblxuICBwb2ludHMuZm9yRWFjaChmdW5jdGlvbihwLCBpZHgpIHtcbiAgICBzZWdtZW50cy5wdXNoKFsgaWR4ID09PSAwID8gJ00nIDogJ0wnLCBwLngsIHAueSBdKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHNlZ21lbnRzO1xufVxuXG5cbnZhciBJTlRFUlNFQ1RJT05fVEhSRVNIT0xEID0gMTA7XG5cbmZ1bmN0aW9uIGdldEJlbmRwb2ludEludGVyc2VjdGlvbih3YXlwb2ludHMsIHJlZmVyZW5jZSkge1xuXG4gIHZhciBpLCB3O1xuXG4gIGZvciAoaSA9IDA7ICh3ID0gd2F5cG9pbnRzW2ldKTsgaSsrKSB7XG5cbiAgICBpZiAocG9pbnREaXN0YW5jZSh3LCByZWZlcmVuY2UpIDw9IElOVEVSU0VDVElPTl9USFJFU0hPTEQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBvaW50OiB3YXlwb2ludHNbaV0sXG4gICAgICAgIGJlbmRwb2ludDogdHJ1ZSxcbiAgICAgICAgaW5kZXg6IGlcbiAgICAgIH07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGdldFBhdGhJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCByZWZlcmVuY2UpIHtcblxuICB2YXIgaW50ZXJzZWN0aW9ucyA9IGludGVyc2VjdFBhdGhzKGNpcmNsZVBhdGgocmVmZXJlbmNlLCBJTlRFUlNFQ1RJT05fVEhSRVNIT0xEKSwgbGluZVBhdGgod2F5cG9pbnRzKSk7XG5cbiAgdmFyIGEgPSBpbnRlcnNlY3Rpb25zWzBdLFxuICAgICAgYiA9IGludGVyc2VjdGlvbnNbaW50ZXJzZWN0aW9ucy5sZW5ndGggLSAxXSxcbiAgICAgIGlkeDtcblxuICBpZiAoIWEpIHtcblxuICAgIC8vIG5vIGludGVyc2VjdGlvblxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGEgIT09IGIpIHtcblxuICAgIGlmIChhLnNlZ21lbnQyICE9PSBiLnNlZ21lbnQyKSB7XG5cbiAgICAgIC8vIHdlIHVzZSB0aGUgYmVuZHBvaW50IGluIGJldHdlZW4gYm90aCBzZWdtZW50c1xuICAgICAgLy8gYXMgdGhlIGludGVyc2VjdGlvbiBwb2ludFxuXG4gICAgICBpZHggPSBtYXgoYS5zZWdtZW50MiwgYi5zZWdtZW50MikgLSAxO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBwb2ludDogd2F5cG9pbnRzW2lkeF0sXG4gICAgICAgIGJlbmRwb2ludDogdHJ1ZSxcbiAgICAgICAgaW5kZXg6IGlkeFxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgcG9pbnQ6IHtcbiAgICAgICAgeDogKHJvdW5kKGEueCArIGIueCkgLyAyKSxcbiAgICAgICAgeTogKHJvdW5kKGEueSArIGIueSkgLyAyKVxuICAgICAgfSxcbiAgICAgIGluZGV4OiBhLnNlZ21lbnQyXG4gICAgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgcG9pbnQ6IHtcbiAgICAgIHg6IHJvdW5kKGEueCksXG4gICAgICB5OiByb3VuZChhLnkpXG4gICAgfSxcbiAgICBpbmRleDogYS5zZWdtZW50MlxuICB9O1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGNsb3Nlc3QgcG9pbnQgb24gdGhlIGNvbm5lY3Rpb24gdG93YXJkcyBhIGdpdmVuIHJlZmVyZW5jZSBwb2ludC5cbiAqXG4gKiBAcGFyYW0gIHtBcnJheTxQb2ludD59IHdheXBvaW50c1xuICogQHBhcmFtICB7UG9pbnR9IHJlZmVyZW5jZVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gaW50ZXJzZWN0aW9uIGRhdGEgKHNlZ21lbnQsIHBvaW50KVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0QXBwcm94SW50ZXJzZWN0aW9uKHdheXBvaW50cywgcmVmZXJlbmNlKSB7XG4gIHJldHVybiBnZXRCZW5kcG9pbnRJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCByZWZlcmVuY2UpIHx8IGdldFBhdGhJbnRlcnNlY3Rpb24od2F5cG9pbnRzLCByZWZlcmVuY2UpO1xufVxuIiwiLyoqXG4gKiBHZXQgdGhlIGxvZ2FyaXRobSBvZiB4IHdpdGggYmFzZSAxMFxuICogQHBhcmFtICB7SW50ZWdlcn0gdmFsdWVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxvZzEwKHgpIHtcbiAgcmV0dXJuIE1hdGgubG9nKHgpIC8gTWF0aC5sb2coMTApO1xufVxuXG5leHBvcnQgeyBkZWx0YSBhcyBzdWJzdHJhY3QgfSBmcm9tICcuL1Bvc2l0aW9uVXRpbCc7XG4iLCJpbXBvcnQge1xuICBnZXRPcmlnaW5hbCBhcyBnZXRPcmlnaW5hbEV2ZW50XG59IGZyb20gJy4vRXZlbnQnO1xuXG5pbXBvcnQge1xuICBpc01hY1xufSBmcm9tICcuL1BsYXRmb3JtJztcblxuZXhwb3J0IHtcbiAgaXNNYWNcbn0gZnJvbSAnLi9QbGF0Zm9ybSc7XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGlzUHJpbWFyeUJ1dHRvbihldmVudCkge1xuXG4gIC8vIGJ1dHRvbiA9PT0gMCAtPiBsZWZ0IMOha2EgcHJpbWFyeSBtb3VzZSBidXR0b25cbiAgcmV0dXJuICEoZ2V0T3JpZ2luYWxFdmVudChldmVudCkgfHwgZXZlbnQpLmJ1dHRvbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGhhc1ByaW1hcnlNb2RpZmllcihldmVudCkge1xuICB2YXIgb3JpZ2luYWxFdmVudCA9IGdldE9yaWdpbmFsRXZlbnQoZXZlbnQpIHx8IGV2ZW50O1xuXG4gIGlmICghaXNQcmltYXJ5QnV0dG9uKGV2ZW50KSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIC8vIFVzZSBhbHQgYXMgcHJpbWFyeSBtb2RpZmllciBrZXkgZm9yIG1hYyBPU1xuICBpZiAoaXNNYWMoKSkge1xuICAgIHJldHVybiBvcmlnaW5hbEV2ZW50Lm1ldGFLZXk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG9yaWdpbmFsRXZlbnQuY3RybEtleTtcbiAgfVxufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBoYXNTZWNvbmRhcnlNb2RpZmllcihldmVudCkge1xuICB2YXIgb3JpZ2luYWxFdmVudCA9IGdldE9yaWdpbmFsRXZlbnQoZXZlbnQpIHx8IGV2ZW50O1xuXG4gIHJldHVybiBpc1ByaW1hcnlCdXR0b24oZXZlbnQpICYmIG9yaWdpbmFsRXZlbnQuc2hpZnRLZXk7XG59IiwiZXhwb3J0IGZ1bmN0aW9uIGlzTWFjKCkge1xuICByZXR1cm4gKC9tYWMvaSkudGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pO1xufSIsImV4cG9ydCBmdW5jdGlvbiBjZW50ZXIoYm91bmRzKSB7XG4gIHJldHVybiB7XG4gICAgeDogYm91bmRzLnggKyAoYm91bmRzLndpZHRoIC8gMiksXG4gICAgeTogYm91bmRzLnkgKyAoYm91bmRzLmhlaWdodCAvIDIpXG4gIH07XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGRlbHRhKGEsIGIpIHtcbiAgcmV0dXJuIHtcbiAgICB4OiBhLnggLSBiLngsXG4gICAgeTogYS55IC0gYi55XG4gIH07XG59IiwiLyoqXG4gKiBSZW1vdmUgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIGEgY29sbGVjdGlvbiB1bnRpbCBpdCBpcyBlbXB0eS5cbiAqXG4gKiBUaGlzIGlzIGEgbnVsbC1zYWZlIG9wZXJhdGlvbiB0aGF0IGVuc3VyZXMgZWxlbWVudHNcbiAqIGFyZSBiZWluZyByZW1vdmVkIGZyb20gdGhlIGdpdmVuIGNvbGxlY3Rpb24gdW50aWwgdGhlXG4gKiBjb2xsZWN0aW9uIGlzIGVtcHR5LlxuICpcbiAqIFRoZSBpbXBsZW1lbnRhdGlvbiBkZWFscyB3aXRoIHRoZSBmYWN0IHRoYXQgYSByZW1vdmUgb3BlcmF0aW9uXG4gKiBtYXkgdG91Y2gsIGkuZS4gcmVtb3ZlIG11bHRpcGxlIGVsZW1lbnRzIGluIHRoZSBjb2xsZWN0aW9uXG4gKiBhdCBhIHRpbWUuXG4gKlxuICogQHBhcmFtIHtBcnJheTxPYmplY3Q+fSBbY29sbGVjdGlvbl1cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHJlbW92ZUZuXG4gKlxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn0gdGhlIGNsZWFyZWQgY29sbGVjdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gc2F2ZUNsZWFyKGNvbGxlY3Rpb24sIHJlbW92ZUZuKSB7XG5cbiAgaWYgKHR5cGVvZiByZW1vdmVGbiAhPT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBFcnJvcigncmVtb3ZlRm4gaXRlcmF0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG4gIH1cblxuICBpZiAoIWNvbGxlY3Rpb24pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgZTtcblxuICB3aGlsZSAoKGUgPSBjb2xsZWN0aW9uWzBdKSkge1xuICAgIHJlbW92ZUZuKGUpO1xuICB9XG5cbiAgcmV0dXJuIGNvbGxlY3Rpb247XG59XG4iLCJpbXBvcnQge1xuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wb25lbnRzVG9QYXRoKGVsZW1lbnRzKSB7XG4gIHJldHVybiBlbGVtZW50cy5qb2luKCcsJykucmVwbGFjZSgvLD8oW0Etel0pLD8vZywgJyQxJyk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0b1NWR1BvaW50cyhwb2ludHMpIHtcbiAgdmFyIHJlc3VsdCA9ICcnO1xuXG4gIGZvciAodmFyIGkgPSAwLCBwOyAocCA9IHBvaW50c1tpXSk7IGkrKykge1xuICAgIHJlc3VsdCArPSBwLnggKyAnLCcgKyBwLnkgKyAnICc7XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTGluZShwb2ludHMsIGF0dHJzKSB7XG5cbiAgdmFyIGxpbmUgPSBzdmdDcmVhdGUoJ3BvbHlsaW5lJyk7XG4gIHN2Z0F0dHIobGluZSwgeyBwb2ludHM6IHRvU1ZHUG9pbnRzKHBvaW50cykgfSk7XG5cbiAgaWYgKGF0dHJzKSB7XG4gICAgc3ZnQXR0cihsaW5lLCBhdHRycyk7XG4gIH1cblxuICByZXR1cm4gbGluZTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHVwZGF0ZUxpbmUoZ2Z4LCBwb2ludHMpIHtcbiAgc3ZnQXR0cihnZngsIHsgcG9pbnRzOiB0b1NWR1BvaW50cyhwb2ludHMpIH0pO1xuXG4gIHJldHVybiBnZng7XG59XG4iLCJpbXBvcnQge1xyXG4gIHRyYW5zZm9ybSBhcyBzdmdUcmFuc2Zvcm0sXHJcbiAgY3JlYXRlVHJhbnNmb3JtXHJcbn0gZnJvbSAndGlueS1zdmcnO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0gezxTVkdFbGVtZW50Pn0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge251bWJlcn0geFxyXG4gKiBAcGFyYW0ge251bWJlcn0geVxyXG4gKiBAcGFyYW0ge251bWJlcn0gYW5nbGVcclxuICogQHBhcmFtIHtudW1iZXJ9IGFtb3VudFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybShnZngsIHgsIHksIGFuZ2xlLCBhbW91bnQpIHtcclxuICB2YXIgdHJhbnNsYXRlID0gY3JlYXRlVHJhbnNmb3JtKCk7XHJcbiAgdHJhbnNsYXRlLnNldFRyYW5zbGF0ZSh4LCB5KTtcclxuXHJcbiAgdmFyIHJvdGF0ZSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xyXG4gIHJvdGF0ZS5zZXRSb3RhdGUoYW5nbGUgfHwgMCwgMCwgMCk7XHJcblxyXG4gIHZhciBzY2FsZSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xyXG4gIHNjYWxlLnNldFNjYWxlKGFtb3VudCB8fCAxLCBhbW91bnQgfHwgMSk7XHJcblxyXG4gIHN2Z1RyYW5zZm9ybShnZngsIFsgdHJhbnNsYXRlLCByb3RhdGUsIHNjYWxlIF0pO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge251bWJlcn0geFxyXG4gKiBAcGFyYW0ge251bWJlcn0geVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zbGF0ZShnZngsIHgsIHkpIHtcclxuICB2YXIgdHJhbnNsYXRlID0gY3JlYXRlVHJhbnNmb3JtKCk7XHJcbiAgdHJhbnNsYXRlLnNldFRyYW5zbGF0ZSh4LCB5KTtcclxuXHJcbiAgc3ZnVHJhbnNmb3JtKGdmeCwgdHJhbnNsYXRlKTtcclxufVxyXG5cclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGVsZW1lbnRcclxuICogQHBhcmFtIHtudW1iZXJ9IGFuZ2xlXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gcm90YXRlKGdmeCwgYW5nbGUpIHtcclxuICB2YXIgcm90YXRlID0gY3JlYXRlVHJhbnNmb3JtKCk7XHJcbiAgcm90YXRlLnNldFJvdGF0ZShhbmdsZSwgMCwgMCk7XHJcblxyXG4gIHN2Z1RyYW5zZm9ybShnZngsIHJvdGF0ZSk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogQHBhcmFtIHtTVkdFbGVtZW50fSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzY2FsZShnZngsIGFtb3VudCkge1xyXG4gIHZhciBzY2FsZSA9IGNyZWF0ZVRyYW5zZm9ybSgpO1xyXG4gIHNjYWxlLnNldFNjYWxlKGFtb3VudCwgYW1vdW50KTtcclxuXHJcbiAgc3ZnVHJhbnNmb3JtKGdmeCwgc2NhbGUpO1xyXG59IiwiaW1wb3J0IHtcbiAgaXNPYmplY3QsXG4gIGFzc2lnbixcbiAgZm9yRWFjaCxcbiAgcmVkdWNlXG59IGZyb20gJ21pbi1kYXNoJztcblxuaW1wb3J0IHtcbiAgYXBwZW5kIGFzIHN2Z0FwcGVuZCxcbiAgYXR0ciBhcyBzdmdBdHRyLFxuICBjcmVhdGUgYXMgc3ZnQ3JlYXRlLFxuICByZW1vdmUgYXMgc3ZnUmVtb3ZlXG59IGZyb20gJ3Rpbnktc3ZnJztcblxudmFyIERFRkFVTFRfQk9YX1BBRERJTkcgPSAwO1xuXG52YXIgREVGQVVMVF9MQUJFTF9TSVpFID0ge1xuICB3aWR0aDogMTUwLFxuICBoZWlnaHQ6IDUwXG59O1xuXG5cbmZ1bmN0aW9uIHBhcnNlQWxpZ24oYWxpZ24pIHtcblxuICB2YXIgcGFydHMgPSBhbGlnbi5zcGxpdCgnLScpO1xuXG4gIHJldHVybiB7XG4gICAgaG9yaXpvbnRhbDogcGFydHNbMF0gfHwgJ2NlbnRlcicsXG4gICAgdmVydGljYWw6IHBhcnRzWzFdIHx8ICd0b3AnXG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhcnNlUGFkZGluZyhwYWRkaW5nKSB7XG5cbiAgaWYgKGlzT2JqZWN0KHBhZGRpbmcpKSB7XG4gICAgcmV0dXJuIGFzc2lnbih7IHRvcDogMCwgbGVmdDogMCwgcmlnaHQ6IDAsIGJvdHRvbTogMCB9LCBwYWRkaW5nKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4ge1xuICAgICAgdG9wOiBwYWRkaW5nLFxuICAgICAgbGVmdDogcGFkZGluZyxcbiAgICAgIHJpZ2h0OiBwYWRkaW5nLFxuICAgICAgYm90dG9tOiBwYWRkaW5nXG4gICAgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRUZXh0QkJveCh0ZXh0LCBmYWtlVGV4dCkge1xuXG4gIGZha2VUZXh0LnRleHRDb250ZW50ID0gdGV4dDtcblxuICB2YXIgdGV4dEJCb3g7XG5cbiAgdHJ5IHtcbiAgICB2YXIgYmJveCxcbiAgICAgICAgZW1wdHlMaW5lID0gdGV4dCA9PT0gJyc7XG5cbiAgICAvLyBhZGQgZHVtbXkgdGV4dCwgd2hlbiBsaW5lIGlzIGVtcHR5IHRvXG4gICAgLy8gZGV0ZXJtaW5lIGNvcnJlY3QgaGVpZ2h0XG4gICAgZmFrZVRleHQudGV4dENvbnRlbnQgPSBlbXB0eUxpbmUgPyAnZHVtbXknIDogdGV4dDtcblxuICAgIHRleHRCQm94ID0gZmFrZVRleHQuZ2V0QkJveCgpO1xuXG4gICAgLy8gdGFrZSB0ZXh0IHJlbmRlcmluZyByZWxhdGVkIGhvcml6b250YWxcbiAgICAvLyBwYWRkaW5nIGludG8gYWNjb3VudFxuICAgIGJib3ggPSB7XG4gICAgICB3aWR0aDogdGV4dEJCb3gud2lkdGggKyB0ZXh0QkJveC54ICogMixcbiAgICAgIGhlaWdodDogdGV4dEJCb3guaGVpZ2h0XG4gICAgfTtcblxuICAgIGlmIChlbXB0eUxpbmUpIHtcblxuICAgICAgLy8gY29ycmVjdCB3aWR0aFxuICAgICAgYmJveC53aWR0aCA9IDA7XG4gICAgfVxuXG4gICAgcmV0dXJuIGJib3g7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4geyB3aWR0aDogMCwgaGVpZ2h0OiAwIH07XG4gIH1cbn1cblxuXG4vKipcbiAqIExheW91dCB0aGUgbmV4dCBsaW5lIGFuZCByZXR1cm4gdGhlIGxheW91dGVkIGVsZW1lbnQuXG4gKlxuICogQWx0ZXJzIHRoZSBsaW5lcyBwYXNzZWQuXG4gKlxuICogQHBhcmFtICB7QXJyYXk8c3RyaW5nPn0gbGluZXNcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIGxpbmUgZGVzY3JpcHRvciwgYW4gb2JqZWN0IHsgd2lkdGgsIGhlaWdodCwgdGV4dCB9XG4gKi9cbmZ1bmN0aW9uIGxheW91dE5leHQobGluZXMsIG1heFdpZHRoLCBmYWtlVGV4dCkge1xuXG4gIHZhciBvcmlnaW5hbExpbmUgPSBsaW5lcy5zaGlmdCgpLFxuICAgICAgZml0TGluZSA9IG9yaWdpbmFsTGluZTtcblxuICB2YXIgdGV4dEJCb3g7XG5cbiAgZm9yICg7Oykge1xuICAgIHRleHRCQm94ID0gZ2V0VGV4dEJCb3goZml0TGluZSwgZmFrZVRleHQpO1xuXG4gICAgdGV4dEJCb3gud2lkdGggPSBmaXRMaW5lID8gdGV4dEJCb3gud2lkdGggOiAwO1xuXG4gICAgLy8gdHJ5IHRvIGZpdFxuICAgIGlmIChmaXRMaW5lID09PSAnICcgfHwgZml0TGluZSA9PT0gJycgfHwgdGV4dEJCb3gud2lkdGggPCBNYXRoLnJvdW5kKG1heFdpZHRoKSB8fCBmaXRMaW5lLmxlbmd0aCA8IDIpIHtcbiAgICAgIHJldHVybiBmaXQobGluZXMsIGZpdExpbmUsIG9yaWdpbmFsTGluZSwgdGV4dEJCb3gpO1xuICAgIH1cblxuICAgIGZpdExpbmUgPSBzaG9ydGVuTGluZShmaXRMaW5lLCB0ZXh0QkJveC53aWR0aCwgbWF4V2lkdGgpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGZpdChsaW5lcywgZml0TGluZSwgb3JpZ2luYWxMaW5lLCB0ZXh0QkJveCkge1xuICBpZiAoZml0TGluZS5sZW5ndGggPCBvcmlnaW5hbExpbmUubGVuZ3RoKSB7XG4gICAgdmFyIHJlbWFpbmRlciA9IG9yaWdpbmFsTGluZS5zbGljZShmaXRMaW5lLmxlbmd0aCkudHJpbSgpO1xuXG4gICAgbGluZXMudW5zaGlmdChyZW1haW5kZXIpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB3aWR0aDogdGV4dEJCb3gud2lkdGgsXG4gICAgaGVpZ2h0OiB0ZXh0QkJveC5oZWlnaHQsXG4gICAgdGV4dDogZml0TGluZVxuICB9O1xufVxuXG5cbi8qKlxuICogU2hvcnRlbnMgYSBsaW5lIGJhc2VkIG9uIHNwYWNpbmcgYW5kIGh5cGhlbnMuXG4gKiBSZXR1cm5zIHRoZSBzaG9ydGVuZWQgcmVzdWx0IG9uIHN1Y2Nlc3MuXG4gKlxuICogQHBhcmFtICB7c3RyaW5nfSBsaW5lXG4gKiBAcGFyYW0gIHtudW1iZXJ9IG1heExlbmd0aCB0aGUgbWF4aW11bSBjaGFyYWN0ZXJzIG9mIHRoZSBzdHJpbmdcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIHNob3J0ZW5lZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gc2VtYW50aWNTaG9ydGVuKGxpbmUsIG1heExlbmd0aCkge1xuICB2YXIgcGFydHMgPSBsaW5lLnNwbGl0KC8oXFxzfC0pL2cpLFxuICAgICAgcGFydCxcbiAgICAgIHNob3J0ZW5lZFBhcnRzID0gW10sXG4gICAgICBsZW5ndGggPSAwO1xuXG4gIC8vIHRyeSB0byBzaG9ydGVuIHZpYSBzcGFjZXMgKyBoeXBoZW5zXG4gIGlmIChwYXJ0cy5sZW5ndGggPiAxKSB7XG4gICAgd2hpbGUgKChwYXJ0ID0gcGFydHMuc2hpZnQoKSkpIHtcbiAgICAgIGlmIChwYXJ0Lmxlbmd0aCArIGxlbmd0aCA8IG1heExlbmd0aCkge1xuICAgICAgICBzaG9ydGVuZWRQYXJ0cy5wdXNoKHBhcnQpO1xuICAgICAgICBsZW5ndGggKz0gcGFydC5sZW5ndGg7XG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIC8vIHJlbW92ZSBwcmV2aW91cyBwYXJ0LCB0b28gaWYgaHlwaGVuIGRvZXMgbm90IGZpdCBhbnltb3JlXG4gICAgICAgIGlmIChwYXJ0ID09PSAnLScpIHtcbiAgICAgICAgICBzaG9ydGVuZWRQYXJ0cy5wb3AoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzaG9ydGVuZWRQYXJ0cy5qb2luKCcnKTtcbn1cblxuXG5mdW5jdGlvbiBzaG9ydGVuTGluZShsaW5lLCB3aWR0aCwgbWF4V2lkdGgpIHtcbiAgdmFyIGxlbmd0aCA9IE1hdGgubWF4KGxpbmUubGVuZ3RoICogKG1heFdpZHRoIC8gd2lkdGgpLCAxKTtcblxuICAvLyB0cnkgdG8gc2hvcnRlbiBzZW1hbnRpY2FsbHkgKGkuZS4gYmFzZWQgb24gc3BhY2VzIGFuZCBoeXBoZW5zKVxuICB2YXIgc2hvcnRlbmVkTGluZSA9IHNlbWFudGljU2hvcnRlbihsaW5lLCBsZW5ndGgpO1xuXG4gIGlmICghc2hvcnRlbmVkTGluZSkge1xuXG4gICAgLy8gZm9yY2Ugc2hvcnRlbiBieSBjdXR0aW5nIHRoZSBsb25nIHdvcmRcbiAgICBzaG9ydGVuZWRMaW5lID0gbGluZS5zbGljZSgwLCBNYXRoLm1heChNYXRoLnJvdW5kKGxlbmd0aCAtIDEpLCAxKSk7XG4gIH1cblxuICByZXR1cm4gc2hvcnRlbmVkTGluZTtcbn1cblxuXG5mdW5jdGlvbiBnZXRIZWxwZXJTdmcoKSB7XG4gIHZhciBoZWxwZXJTdmcgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnaGVscGVyLXN2ZycpO1xuXG4gIGlmICghaGVscGVyU3ZnKSB7XG4gICAgaGVscGVyU3ZnID0gc3ZnQ3JlYXRlKCdzdmcnKTtcblxuICAgIHN2Z0F0dHIoaGVscGVyU3ZnLCB7XG4gICAgICBpZDogJ2hlbHBlci1zdmcnLFxuICAgICAgd2lkdGg6IDAsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICBzdHlsZTogJ3Zpc2liaWxpdHk6IGhpZGRlbjsgcG9zaXRpb246IGZpeGVkJ1xuICAgIH0pO1xuXG4gICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChoZWxwZXJTdmcpO1xuICB9XG5cbiAgcmV0dXJuIGhlbHBlclN2Zztcbn1cblxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgbGFiZWwgdXRpbGl0eVxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb25maWdcbiAqIEBwYXJhbSB7RGltZW5zaW9uc30gY29uZmlnLnNpemVcbiAqIEBwYXJhbSB7bnVtYmVyfSBjb25maWcucGFkZGluZ1xuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZy5zdHlsZVxuICogQHBhcmFtIHtzdHJpbmd9IGNvbmZpZy5hbGlnblxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBUZXh0KGNvbmZpZykge1xuXG4gIHRoaXMuX2NvbmZpZyA9IGFzc2lnbih7fSwge1xuICAgIHNpemU6IERFRkFVTFRfTEFCRUxfU0laRSxcbiAgICBwYWRkaW5nOiBERUZBVUxUX0JPWF9QQURESU5HLFxuICAgIHN0eWxlOiB7fSxcbiAgICBhbGlnbjogJ2NlbnRlci10b3AnXG4gIH0sIGNvbmZpZyB8fCB7fSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgbGF5b3V0ZWQgdGV4dCBhcyBhbiBTVkcgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dFxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqXG4gKiBAcmV0dXJuIHtTVkdFbGVtZW50fVxuICovXG5UZXh0LnByb3RvdHlwZS5jcmVhdGVUZXh0ID0gZnVuY3Rpb24odGV4dCwgb3B0aW9ucykge1xuICByZXR1cm4gdGhpcy5sYXlvdXRUZXh0KHRleHQsIG9wdGlvbnMpLmVsZW1lbnQ7XG59O1xuXG4vKipcbiAqIFJldHVybnMgYSBsYWJlbHMgbGF5b3V0ZWQgZGltZW5zaW9ucy5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCB0byBsYXlvdXRcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKlxuICogQHJldHVybiB7RGltZW5zaW9uc31cbiAqL1xuVGV4dC5wcm90b3R5cGUuZ2V0RGltZW5zaW9ucyA9IGZ1bmN0aW9uKHRleHQsIG9wdGlvbnMpIHtcbiAgcmV0dXJuIHRoaXMubGF5b3V0VGV4dCh0ZXh0LCBvcHRpb25zKS5kaW1lbnNpb25zO1xufTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuZCByZXR1cm5zIGEgbGFiZWwgYW5kIGl0cyBib3VuZGluZyBib3guXG4gKlxuICogQG1ldGhvZCBUZXh0I2NyZWF0ZVRleHRcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gdGV4dCB0aGUgdGV4dCB0byByZW5kZXIgb24gdGhlIGxhYmVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMuYWxpZ24gaG93IHRvIGFsaWduIGluIHRoZSBib3VuZGluZyBib3guXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBbnkgb2YgeyAnY2VudGVyLW1pZGRsZScsICdjZW50ZXItdG9wJyB9LFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdHMgdG8gJ2NlbnRlci10b3AnLlxuICogQHBhcmFtIHtzdHJpbmd9IG9wdGlvbnMuc3R5bGUgc3R5bGUgdG8gYmUgYXBwbGllZCB0byB0aGUgdGV4dFxuICogQHBhcmFtIHtib29sZWFufSBvcHRpb25zLmZpdEJveCBpbmRpY2F0ZXMgaWYgYm94IHdpbGwgYmUgcmVjYWxjdWxhdGVkIHRvXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpdCB0ZXh0XG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB7IGVsZW1lbnQsIGRpbWVuc2lvbnMgfVxuICovXG5UZXh0LnByb3RvdHlwZS5sYXlvdXRUZXh0ID0gZnVuY3Rpb24odGV4dCwgb3B0aW9ucykge1xuICB2YXIgYm94ID0gYXNzaWduKHt9LCB0aGlzLl9jb25maWcuc2l6ZSwgb3B0aW9ucy5ib3gpLFxuICAgICAgc3R5bGUgPSBhc3NpZ24oe30sIHRoaXMuX2NvbmZpZy5zdHlsZSwgb3B0aW9ucy5zdHlsZSksXG4gICAgICBhbGlnbiA9IHBhcnNlQWxpZ24ob3B0aW9ucy5hbGlnbiB8fCB0aGlzLl9jb25maWcuYWxpZ24pLFxuICAgICAgcGFkZGluZyA9IHBhcnNlUGFkZGluZyhvcHRpb25zLnBhZGRpbmcgIT09IHVuZGVmaW5lZCA/IG9wdGlvbnMucGFkZGluZyA6IHRoaXMuX2NvbmZpZy5wYWRkaW5nKSxcbiAgICAgIGZpdEJveCA9IG9wdGlvbnMuZml0Qm94IHx8IGZhbHNlO1xuXG4gIHZhciBsaW5lSGVpZ2h0ID0gZ2V0TGluZUhlaWdodChzdHlsZSk7XG5cbiAgdmFyIGxpbmVzID0gdGV4dC5zcGxpdCgvXFxyP1xcbi9nKSxcbiAgICAgIGxheW91dGVkID0gW107XG5cbiAgdmFyIG1heFdpZHRoID0gYm94LndpZHRoIC0gcGFkZGluZy5sZWZ0IC0gcGFkZGluZy5yaWdodDtcblxuICAvLyBlbnN1cmUgY29ycmVjdCByZW5kZXJpbmcgYnkgYXR0YWNoaW5nIGhlbHBlciB0ZXh0IG5vZGUgdG8gaW52aXNpYmxlIFNWR1xuICB2YXIgaGVscGVyVGV4dCA9IHN2Z0NyZWF0ZSgndGV4dCcpO1xuICBzdmdBdHRyKGhlbHBlclRleHQsIHsgeDogMCwgeTogMCB9KTtcbiAgc3ZnQXR0cihoZWxwZXJUZXh0LCBzdHlsZSk7XG5cbiAgdmFyIGhlbHBlclN2ZyA9IGdldEhlbHBlclN2ZygpO1xuXG4gIHN2Z0FwcGVuZChoZWxwZXJTdmcsIGhlbHBlclRleHQpO1xuXG4gIHdoaWxlIChsaW5lcy5sZW5ndGgpIHtcbiAgICBsYXlvdXRlZC5wdXNoKGxheW91dE5leHQobGluZXMsIG1heFdpZHRoLCBoZWxwZXJUZXh0KSk7XG4gIH1cblxuICBpZiAoYWxpZ24udmVydGljYWwgPT09ICdtaWRkbGUnKSB7XG4gICAgcGFkZGluZy50b3AgPSBwYWRkaW5nLmJvdHRvbSA9IDA7XG4gIH1cblxuICB2YXIgdG90YWxIZWlnaHQgPSByZWR1Y2UobGF5b3V0ZWQsIGZ1bmN0aW9uKHN1bSwgbGluZSwgaWR4KSB7XG4gICAgcmV0dXJuIHN1bSArIChsaW5lSGVpZ2h0IHx8IGxpbmUuaGVpZ2h0KTtcbiAgfSwgMCkgKyBwYWRkaW5nLnRvcCArIHBhZGRpbmcuYm90dG9tO1xuXG4gIHZhciBtYXhMaW5lV2lkdGggPSByZWR1Y2UobGF5b3V0ZWQsIGZ1bmN0aW9uKHN1bSwgbGluZSwgaWR4KSB7XG4gICAgcmV0dXJuIGxpbmUud2lkdGggPiBzdW0gPyBsaW5lLndpZHRoIDogc3VtO1xuICB9LCAwKTtcblxuICAvLyB0aGUgeSBwb3NpdGlvbiBvZiB0aGUgbmV4dCBsaW5lXG4gIHZhciB5ID0gcGFkZGluZy50b3A7XG5cbiAgaWYgKGFsaWduLnZlcnRpY2FsID09PSAnbWlkZGxlJykge1xuICAgIHkgKz0gKGJveC5oZWlnaHQgLSB0b3RhbEhlaWdodCkgLyAyO1xuICB9XG5cbiAgLy8gbWFnaWMgbnVtYmVyIGluaXRpYWwgb2Zmc2V0XG4gIHkgLT0gKGxpbmVIZWlnaHQgfHwgbGF5b3V0ZWRbMF0uaGVpZ2h0KSAvIDQ7XG5cblxuICB2YXIgdGV4dEVsZW1lbnQgPSBzdmdDcmVhdGUoJ3RleHQnKTtcblxuICBzdmdBdHRyKHRleHRFbGVtZW50LCBzdHlsZSk7XG5cbiAgLy8gbGF5b3V0IGVhY2ggbGluZSB0YWtpbmcgaW50byBhY2NvdW50IHRoYXQgcGFyZW50XG4gIC8vIHNoYXBlIG1pZ2h0IHJlc2l6ZSB0byBmaXQgdGV4dCBzaXplXG4gIGZvckVhY2gobGF5b3V0ZWQsIGZ1bmN0aW9uKGxpbmUpIHtcblxuICAgIHZhciB4O1xuXG4gICAgeSArPSAobGluZUhlaWdodCB8fCBsaW5lLmhlaWdodCk7XG5cbiAgICBzd2l0Y2ggKGFsaWduLmhvcml6b250YWwpIHtcbiAgICBjYXNlICdsZWZ0JzpcbiAgICAgIHggPSBwYWRkaW5nLmxlZnQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgIHggPSAoKGZpdEJveCA/IG1heExpbmVXaWR0aCA6IG1heFdpZHRoKVxuICAgICAgICAtIHBhZGRpbmcucmlnaHQgLSBsaW5lLndpZHRoKTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcblxuICAgICAgLy8gYWthIGNlbnRlclxuICAgICAgeCA9IE1hdGgubWF4KCgoKGZpdEJveCA/IG1heExpbmVXaWR0aCA6IG1heFdpZHRoKVxuICAgICAgICAtIGxpbmUud2lkdGgpIC8gMiArIHBhZGRpbmcubGVmdCksIDApO1xuICAgIH1cblxuICAgIHZhciB0c3BhbiA9IHN2Z0NyZWF0ZSgndHNwYW4nKTtcbiAgICBzdmdBdHRyKHRzcGFuLCB7IHg6IHgsIHk6IHkgfSk7XG5cbiAgICB0c3Bhbi50ZXh0Q29udGVudCA9IGxpbmUudGV4dDtcblxuICAgIHN2Z0FwcGVuZCh0ZXh0RWxlbWVudCwgdHNwYW4pO1xuICB9KTtcblxuICBzdmdSZW1vdmUoaGVscGVyVGV4dCk7XG5cbiAgdmFyIGRpbWVuc2lvbnMgPSB7XG4gICAgd2lkdGg6IG1heExpbmVXaWR0aCxcbiAgICBoZWlnaHQ6IHRvdGFsSGVpZ2h0XG4gIH07XG5cbiAgcmV0dXJuIHtcbiAgICBkaW1lbnNpb25zOiBkaW1lbnNpb25zLFxuICAgIGVsZW1lbnQ6IHRleHRFbGVtZW50XG4gIH07XG59O1xuXG5cbmZ1bmN0aW9uIGdldExpbmVIZWlnaHQoc3R5bGUpIHtcbiAgaWYgKCdmb250U2l6ZScgaW4gc3R5bGUgJiYgJ2xpbmVIZWlnaHQnIGluIHN0eWxlKSB7XG4gICAgcmV0dXJuIHN0eWxlLmxpbmVIZWlnaHQgKiBwYXJzZUludChzdHlsZS5mb250U2l6ZSwgMTApO1xuICB9XG59IiwiaW1wb3J0IHsgaXNTdHJpbmcsIGFzc2lnbiB9IGZyb20gJ21pbi1kYXNoJztcbmltcG9ydCB7IE1vZGRsZSB9IGZyb20gJ21vZGRsZSc7XG5pbXBvcnQgeyBSZWFkZXIsIFdyaXRlciB9IGZyb20gJ21vZGRsZS14bWwnO1xuXG4vKipcbiAqIEEgc3ViIGNsYXNzIG9mIHtAbGluayBNb2RkbGV9IHdpdGggc3VwcG9ydCBmb3IgaW1wb3J0IGFuZCBleHBvcnQgb2YgQlBNTiAyLjAgeG1sIGZpbGVzLlxuICpcbiAqIEBjbGFzcyBCcG1uTW9kZGxlXG4gKiBAZXh0ZW5kcyBNb2RkbGVcbiAqXG4gKiBAcGFyYW0ge09iamVjdHxBcnJheX0gcGFja2FnZXMgdG8gdXNlIGZvciBpbnN0YW50aWF0aW5nIHRoZSBtb2RlbFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSBhZGRpdGlvbmFsIG9wdGlvbnMgdG8gcGFzcyBvdmVyXG4gKi9cbmZ1bmN0aW9uIEJwbW5Nb2RkbGUocGFja2FnZXMsIG9wdGlvbnMpIHtcbiAgTW9kZGxlLmNhbGwodGhpcywgcGFja2FnZXMsIG9wdGlvbnMpO1xufVxuXG5CcG1uTW9kZGxlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoTW9kZGxlLnByb3RvdHlwZSk7XG5cbi8qKlxuICogVGhlIGZyb21YTUwgcmVzdWx0LlxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFBhcnNlUmVzdWx0XG4gKlxuICogQHByb3BlcnR5IHtNb2RkbGVFbGVtZW50fSByb290RWxlbWVudFxuICogQHByb3BlcnR5IHtBcnJheTxPYmplY3Q+fSByZWZlcmVuY2VzXG4gKiBAcHJvcGVydHkge0FycmF5PEVycm9yPn0gd2FybmluZ3NcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBlbGVtZW50c0J5SWQgLSBhIG1hcHBpbmcgY29udGFpbmluZyBlYWNoIElEIC0+IE1vZGRsZUVsZW1lbnRcbiAqL1xuXG4vKipcbiAqIFRoZSBmcm9tWE1MIGVycm9yLlxuICpcbiAqIEB0eXBlZGVmIHtFcnJvcn0gUGFyc2VFcnJvclxuICpcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8RXJyb3I+fSB3YXJuaW5nc1xuICovXG5cbi8qKlxuICogSW5zdGFudGlhdGVzIGEgQlBNTiBtb2RlbCB0cmVlIGZyb20gYSBnaXZlbiB4bWwgc3RyaW5nLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSAgIHhtbFN0clxuICogQHBhcmFtIHtTdHJpbmd9ICAgW3R5cGVOYW1lPSdicG1uOkRlZmluaXRpb25zJ10gbmFtZSBvZiB0aGUgcm9vdCBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gICBbb3B0aW9uc10gIG9wdGlvbnMgdG8gcGFzcyB0byB0aGUgdW5kZXJseWluZyByZWFkZXJcbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxQYXJzZVJlc3VsdCwgUGFyc2VFcnJvcj59XG4gKi9cbkJwbW5Nb2RkbGUucHJvdG90eXBlLmZyb21YTUwgPSBmdW5jdGlvbih4bWxTdHIsIHR5cGVOYW1lLCBvcHRpb25zKSB7XG5cbiAgaWYgKCFpc1N0cmluZyh0eXBlTmFtZSkpIHtcbiAgICBvcHRpb25zID0gdHlwZU5hbWU7XG4gICAgdHlwZU5hbWUgPSAnYnBtbjpEZWZpbml0aW9ucyc7XG4gIH1cblxuICB2YXIgcmVhZGVyID0gbmV3IFJlYWRlcihhc3NpZ24oeyBtb2RlbDogdGhpcywgbGF4OiB0cnVlIH0sIG9wdGlvbnMpKTtcbiAgdmFyIHJvb3RIYW5kbGVyID0gcmVhZGVyLmhhbmRsZXIodHlwZU5hbWUpO1xuXG4gIHJldHVybiByZWFkZXIuZnJvbVhNTCh4bWxTdHIsIHJvb3RIYW5kbGVyKTtcbn07XG5cblxuLyoqXG4gKiBUaGUgdG9YTUwgcmVzdWx0LlxuICpcbiAqIEB0eXBlZGVmIHtPYmplY3R9IFNlcmlhbGl6YXRpb25SZXN1bHRcbiAqXG4gKiBAcHJvcGVydHkge1N0cmluZ30geG1sXG4gKi9cblxuLyoqXG4gKiBTZXJpYWxpemVzIGEgQlBNTiAyLjAgb2JqZWN0IHRyZWUgdG8gWE1MLlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSAgIGVsZW1lbnQgICAgdGhlIHJvb3QgZWxlbWVudCwgdHlwaWNhbGx5IGFuIGluc3RhbmNlIG9mIGBicG1uOkRlZmluaXRpb25zYFxuICogQHBhcmFtIHtPYmplY3R9ICAgW29wdGlvbnNdICB0byBwYXNzIHRvIHRoZSB1bmRlcmx5aW5nIHdyaXRlclxuICpcbiAqIEByZXR1cm5zIHtQcm9taXNlPFNlcmlhbGl6YXRpb25SZXN1bHQsIEVycm9yPn1cbiAqL1xuQnBtbk1vZGRsZS5wcm90b3R5cGUudG9YTUwgPSBmdW5jdGlvbihlbGVtZW50LCBvcHRpb25zKSB7XG5cbiAgdmFyIHdyaXRlciA9IG5ldyBXcml0ZXIob3B0aW9ucyk7XG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHJlc29sdmUsIHJlamVjdCkge1xuICAgIHRyeSB7XG4gICAgICB2YXIgcmVzdWx0ID0gd3JpdGVyLnRvWE1MKGVsZW1lbnQpO1xuXG4gICAgICByZXR1cm4gcmVzb2x2ZSh7XG4gICAgICAgIHhtbDogcmVzdWx0XG4gICAgICB9KTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHJldHVybiByZWplY3QoZXJyKTtcbiAgICB9XG4gIH0pO1xufTtcblxudmFyIG5hbWUgPSBcIkJQTU4yMFwiO1xudmFyIHVyaSA9IFwiaHR0cDovL3d3dy5vbWcub3JnL3NwZWMvQlBNTi8yMDEwMDUyNC9NT0RFTFwiO1xudmFyIHByZWZpeCA9IFwiYnBtblwiO1xudmFyIGFzc29jaWF0aW9ucyA9IFtcbl07XG52YXIgdHlwZXMgPSBbXG5cdHtcblx0XHRuYW1lOiBcIkludGVyZmFjZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm9wZXJhdGlvbnNcIixcblx0XHRcdFx0dHlwZTogXCJPcGVyYXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImltcGxlbWVudGF0aW9uUmVmXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiT3BlcmF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW5NZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvdXRNZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJlcnJvclJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkVycm9yXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25SZWZcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFbmRQb2ludFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQXVkaXRpbmdcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdsb2JhbFRhc2tcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkNhbGxhYmxlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVzb3VyY2VzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVzb3VyY2VSb2xlXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTW9uaXRvcmluZ1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUGVyZm9ybWVyXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSZXNvdXJjZVJvbGVcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUHJvY2Vzc1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRmxvd0VsZW1lbnRzQ29udGFpbmVyXCIsXG5cdFx0XHRcIkNhbGxhYmxlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicHJvY2Vzc1R5cGVcIixcblx0XHRcdFx0dHlwZTogXCJQcm9jZXNzVHlwZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNDbG9zZWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhdWRpdGluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIkF1ZGl0aW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibW9uaXRvcmluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIk1vbml0b3JpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwcm9wZXJ0aWVzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUHJvcGVydHlcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxhbmVTZXRzXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0cmVwbGFjZXM6IFwiRmxvd0VsZW1lbnRzQ29udGFpbmVyI2xhbmVTZXRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiTGFuZVNldFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZsb3dFbGVtZW50c1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdHJlcGxhY2VzOiBcIkZsb3dFbGVtZW50c0NvbnRhaW5lciNmbG93RWxlbWVudHNcIixcblx0XHRcdFx0dHlwZTogXCJGbG93RWxlbWVudFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImFydGlmYWN0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkFydGlmYWN0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJyZXNvdXJjZXNcIixcblx0XHRcdFx0dHlwZTogXCJSZXNvdXJjZVJvbGVcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvcnJlbGF0aW9uU3Vic2NyaXB0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkNvcnJlbGF0aW9uU3Vic2NyaXB0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzdXBwb3J0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIlByb2Nlc3NcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkZWZpbml0aW9uYWxDb2xsYWJvcmF0aW9uUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29sbGFib3JhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzRXhlY3V0YWJsZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJMYW5lU2V0XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibGFuZXNcIixcblx0XHRcdFx0dHlwZTogXCJMYW5lXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTGFuZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpdGlvbkVsZW1lbnRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJCYXNlRWxlbWVudFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpdGlvbkVsZW1lbnRcIixcblx0XHRcdFx0dHlwZTogXCJCYXNlRWxlbWVudFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZsb3dOb2RlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRmxvd05vZGVcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjaGlsZExhbmVTZXRcIixcblx0XHRcdFx0dHlwZTogXCJMYW5lU2V0XCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdsb2JhbE1hbnVhbFRhc2tcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkdsb2JhbFRhc2tcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTWFudWFsVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiVGFza1wiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJVc2VyVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiVGFza1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVuZGVyaW5nc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlJlbmRlcmluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZW5kZXJpbmdcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkh1bWFuUGVyZm9ybWVyXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJQZXJmb3JtZXJcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUG90ZW50aWFsT3duZXJcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkh1bWFuUGVyZm9ybWVyXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdsb2JhbFVzZXJUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJHbG9iYWxUYXNrXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbXBsZW1lbnRhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVuZGVyaW5nc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlJlbmRlcmluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdhdGV3YXlcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRmxvd05vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImdhdGV3YXlEaXJlY3Rpb25cIixcblx0XHRcdFx0dHlwZTogXCJHYXRld2F5RGlyZWN0aW9uXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBcIlVuc3BlY2lmaWVkXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXZlbnRCYXNlZEdhdGV3YXlcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkdhdGV3YXlcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImluc3RhbnRpYXRlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJldmVudEdhdGV3YXlUeXBlXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXZlbnRCYXNlZEdhdGV3YXlUeXBlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0XCJkZWZhdWx0XCI6IFwiRXhjbHVzaXZlXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNvbXBsZXhHYXRld2F5XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJHYXRld2F5XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhY3RpdmF0aW9uQ29uZGl0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXhwcmVzc2lvblwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwieHNpOnR5cGVcIlxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRlZmF1bHRcIixcblx0XHRcdFx0dHlwZTogXCJTZXF1ZW5jZUZsb3dcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXhjbHVzaXZlR2F0ZXdheVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiR2F0ZXdheVwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGVmYXVsdFwiLFxuXHRcdFx0XHR0eXBlOiBcIlNlcXVlbmNlRmxvd1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJbmNsdXNpdmVHYXRld2F5XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJHYXRld2F5XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkZWZhdWx0XCIsXG5cdFx0XHRcdHR5cGU6IFwiU2VxdWVuY2VGbG93XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlBhcmFsbGVsR2F0ZXdheVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiR2F0ZXdheVwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSb290RWxlbWVudFwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZWxhdGlvbnNoaXBcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0eXBlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkaXJlY3Rpb25cIixcblx0XHRcdFx0dHlwZTogXCJSZWxhdGlvbnNoaXBEaXJlY3Rpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNvdXJjZVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkVsZW1lbnRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0YXJnZXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJFbGVtZW50XCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJhc2VFbGVtZW50XCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiLFxuXHRcdFx0XHRpc0lkOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRvY3VtZW50YXRpb25cIixcblx0XHRcdFx0dHlwZTogXCJEb2N1bWVudGF0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25EZWZpbml0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvbkRlZmluaXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25FbGVtZW50c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvbkVsZW1lbnRzXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkV4dGVuc2lvblwiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtdXN0VW5kZXJzdGFuZFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogZmFsc2UsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGVmaW5pdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvbkRlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXh0ZW5zaW9uRGVmaW5pdGlvblwiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25BdHRyaWJ1dGVEZWZpbml0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvbkF0dHJpYnV0ZURlZmluaXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFeHRlbnNpb25BdHRyaWJ1dGVEZWZpbml0aW9uXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInR5cGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzUmVmZXJlbmNlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25EZWZpbml0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXh0ZW5zaW9uRGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFeHRlbnNpb25FbGVtZW50c1wiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ2YWx1ZVJlZlwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkVsZW1lbnRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ2YWx1ZXNcIixcblx0XHRcdFx0dHlwZTogXCJFbGVtZW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHRlbnNpb25BdHRyaWJ1dGVEZWZpbml0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXh0ZW5zaW9uQXR0cmlidXRlRGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJEb2N1bWVudGF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGV4dFwiLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiLFxuXHRcdFx0XHRpc0JvZHk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGV4dEZvcm1hdFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCJ0ZXh0L3BsYWluXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXZlbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRmxvd05vZGVcIixcblx0XHRcdFwiSW50ZXJhY3Rpb25Ob2RlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwcm9wZXJ0aWVzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUHJvcGVydHlcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJbnRlcm1lZGlhdGVDYXRjaEV2ZW50XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJDYXRjaEV2ZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkludGVybWVkaWF0ZVRocm93RXZlbnRcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlRocm93RXZlbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRW5kRXZlbnRcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlRocm93RXZlbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiU3RhcnRFdmVudFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ2F0Y2hFdmVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNJbnRlcnJ1cHRpbmdcIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IHRydWUsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlRocm93RXZlbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFJbnB1dHNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhSW5wdXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFJbnB1dEFzc29jaWF0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFJbnB1dEFzc29jaWF0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldFwiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0U2V0XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXZlbnREZWZpbml0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXZlbnREZWZpbml0aW9uUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNhdGNoRXZlbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcmFsbGVsTXVsdGlwbGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IGZhbHNlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFPdXRwdXRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRGF0YU91dHB1dFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU91dHB1dEFzc29jaWF0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFPdXRwdXRBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0cHV0U2V0XCIsXG5cdFx0XHRcdHR5cGU6IFwiT3V0cHV0U2V0XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXZlbnREZWZpbml0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXZlbnREZWZpbml0aW9uUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJvdW5kYXJ5RXZlbnRcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkNhdGNoRXZlbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbmNlbEFjdGl2aXR5XCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiB0cnVlLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImF0dGFjaGVkVG9SZWZcIixcblx0XHRcdFx0dHlwZTogXCJBY3Rpdml0eVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFdmVudERlZmluaXRpb25cIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ2FuY2VsRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJFdmVudERlZmluaXRpb25cIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXJyb3JFdmVudERlZmluaXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkV2ZW50RGVmaW5pdGlvblwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXJyb3JSZWZcIixcblx0XHRcdFx0dHlwZTogXCJFcnJvclwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJUZXJtaW5hdGVFdmVudERlZmluaXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkV2ZW50RGVmaW5pdGlvblwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJFc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJFdmVudERlZmluaXRpb25cIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImVzY2FsYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJFc2NhbGF0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkVzY2FsYXRpb25cIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3RydWN0dXJlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJlc2NhbGF0aW9uQ29kZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnREZWZpbml0aW9uXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ3YWl0Rm9yQ29tcGxldGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhY3Rpdml0eVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkFjdGl2aXR5XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlRpbWVyRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJFdmVudERlZmluaXRpb25cIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRpbWVEYXRlXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXhwcmVzc2lvblwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwieHNpOnR5cGVcIlxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRpbWVDeWNsZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkV4cHJlc3Npb25cIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInhzaTp0eXBlXCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0aW1lRHVyYXRpb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkxpbmtFdmVudERlZmluaXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkV2ZW50RGVmaW5pdGlvblwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0XCIsXG5cdFx0XHRcdHR5cGU6IFwiTGlua0V2ZW50RGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNvdXJjZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkxpbmtFdmVudERlZmluaXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTWVzc2FnZUV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnREZWZpbml0aW9uXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm9wZXJhdGlvblJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIk9wZXJhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnREZWZpbml0aW9uXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb25kaXRpb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlNpZ25hbEV2ZW50RGVmaW5pdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXZlbnREZWZpbml0aW9uXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzaWduYWxSZWZcIixcblx0XHRcdFx0dHlwZTogXCJTaWduYWxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiU2lnbmFsXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3RydWN0dXJlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSW1wbGljaXRUaHJvd0V2ZW50XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJUaHJvd0V2ZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFTdGF0ZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJdGVtQXdhcmVFbGVtZW50XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXRlbVN1YmplY3RSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJdGVtRGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFTdGF0ZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFTdGF0ZVwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJEYXRhQXNzb2NpYXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzb3VyY2VSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJdGVtQXdhcmVFbGVtZW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbUF3YXJlRWxlbWVudFwiLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0cmFuc2Zvcm1hdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIkZvcm1hbEV4cHJlc3Npb25cIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInByb3BlcnR5XCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhc3NpZ25tZW50XCIsXG5cdFx0XHRcdHR5cGU6IFwiQXNzaWdubWVudFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFJbnB1dFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNDb2xsZWN0aW9uXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0U2V0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldFdpdGhPcHRpb25hbFwiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0U2V0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldFdpdGhXaGlsZUV4ZWN1dGluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0U2V0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRGF0YU91dHB1dFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNDb2xsZWN0aW9uXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvdXRwdXRTZXRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJPdXRwdXRTZXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dHB1dFNldFdpdGhPcHRpb25hbFwiLFxuXHRcdFx0XHR0eXBlOiBcIk91dHB1dFNldFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzVmlydHVhbDogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0cHV0U2V0V2l0aFdoaWxlRXhlY3V0aW5nXCIsXG5cdFx0XHRcdHR5cGU6IFwiT3V0cHV0U2V0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSW5wdXRTZXRcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkYXRhSW5wdXRSZWZzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRGF0YUlucHV0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3B0aW9uYWxJbnB1dFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhSW5wdXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ3aGlsZUV4ZWN1dGluZ0lucHV0UmVmc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFJbnB1dFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dHB1dFNldFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJPdXRwdXRTZXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiT3V0cHV0U2V0XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU91dHB1dFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhT3V0cHV0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW5wdXRTZXRSZWZzXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW5wdXRTZXRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcHRpb25hbE91dHB1dFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhT3V0cHV0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwid2hpbGVFeGVjdXRpbmdPdXRwdXRSZWZzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRGF0YU91dHB1dFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJQcm9wZXJ0eVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFJbnB1dEFzc29jaWF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJEYXRhQXNzb2NpYXRpb25cIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRGF0YU91dHB1dEFzc29jaWF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJEYXRhQXNzb2NpYXRpb25cIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSW5wdXRPdXRwdXRTcGVjaWZpY2F0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YUlucHV0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFJbnB1dFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU91dHB1dHNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhT3V0cHV0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dFNldHNcIixcblx0XHRcdFx0dHlwZTogXCJJbnB1dFNldFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0cHV0U2V0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIk91dHB1dFNldFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFPYmplY3RcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkZsb3dFbGVtZW50XCIsXG5cdFx0XHRcIkl0ZW1Bd2FyZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzQ29sbGVjdGlvblwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogZmFsc2UsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIklucHV0T3V0cHV0QmluZGluZ1wiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnB1dERhdGFSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJbnB1dFNldFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dHB1dERhdGFSZWZcIixcblx0XHRcdFx0dHlwZTogXCJPdXRwdXRTZXRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcGVyYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJPcGVyYXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQXNzaWdubWVudFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZyb21cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidG9cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkRhdGFTdG9yZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIixcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY2FwYWNpdHlcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkludGVnZXJcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpc1VubGltaXRlZFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogdHJ1ZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRGF0YVN0b3JlUmVmZXJlbmNlXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJJdGVtQXdhcmVFbGVtZW50XCIsXG5cdFx0XHRcIkZsb3dFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkYXRhU3RvcmVSZWZcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhU3RvcmVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRGF0YU9iamVjdFJlZmVyZW5jZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSXRlbUF3YXJlRWxlbWVudFwiLFxuXHRcdFx0XCJGbG93RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU9iamVjdFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFPYmplY3RcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29udmVyc2F0aW9uTGlua1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNvdXJjZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkludGVyYWN0aW9uTm9kZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRhcmdldFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkludGVyYWN0aW9uTm9kZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb252ZXJzYXRpb25Bc3NvY2lhdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlubmVyQ29udmVyc2F0aW9uTm9kZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkNvbnZlcnNhdGlvbk5vZGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvdXRlckNvbnZlcnNhdGlvbk5vZGVSZWZcIixcblx0XHRcdFx0dHlwZTogXCJDb252ZXJzYXRpb25Ob2RlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNhbGxDb252ZXJzYXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkNvbnZlcnNhdGlvbk5vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbGxlZENvbGxhYm9yYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJDb2xsYWJvcmF0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicGFydGljaXBhbnRBc3NvY2lhdGlvbnNcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudEFzc29jaWF0aW9uXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29udmVyc2F0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJDb252ZXJzYXRpb25Ob2RlXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlN1YkNvbnZlcnNhdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ29udmVyc2F0aW9uTm9kZVwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29udmVyc2F0aW9uTm9kZXNcIixcblx0XHRcdFx0dHlwZTogXCJDb252ZXJzYXRpb25Ob2RlXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29udmVyc2F0aW9uTm9kZVwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJJbnRlcmFjdGlvbk5vZGVcIixcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpY2lwYW50UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUGFydGljaXBhbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlRmxvd1JlZnNcIixcblx0XHRcdFx0dHlwZTogXCJNZXNzYWdlRmxvd1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvcnJlbGF0aW9uS2V5c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkNvcnJlbGF0aW9uS2V5XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiR2xvYmFsQ29udmVyc2F0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJDb2xsYWJvcmF0aW9uXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlBhcnRuZXJFbnRpdHlcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlJvb3RFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlBhcnRuZXJSb2xlXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicGFydGljaXBhbnRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb3JyZWxhdGlvblByb3BlcnR5XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29ycmVsYXRpb25Qcm9wZXJ0eVJldHJpZXZhbEV4cHJlc3Npb25cIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvblByb3BlcnR5UmV0cmlldmFsRXhwcmVzc2lvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidHlwZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkl0ZW1EZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkVycm9yXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3RydWN0dXJlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJlcnJvckNvZGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb3JyZWxhdGlvbktleVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvcnJlbGF0aW9uUHJvcGVydHlSZWZcIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvblByb3BlcnR5XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkV4cHJlc3Npb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdGlzQWJzdHJhY3Q6IGZhbHNlLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJib2R5XCIsXG5cdFx0XHRcdGlzQm9keTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRm9ybWFsRXhwcmVzc2lvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRXhwcmVzc2lvblwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibGFuZ3VhZ2VcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImV2YWx1YXRlc1RvVHlwZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkl0ZW1EZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIk1lc3NhZ2VcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlJvb3RFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpdGVtUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlJvb3RFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpdGVtS2luZFwiLFxuXHRcdFx0XHR0eXBlOiBcIkl0ZW1LaW5kXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzdHJ1Y3R1cmVSZWZcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzQ29sbGVjdGlvblwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogZmFsc2UsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wb3J0XCIsXG5cdFx0XHRcdHR5cGU6IFwiSW1wb3J0XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkZsb3dFbGVtZW50XCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhdWRpdGluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIkF1ZGl0aW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibW9uaXRvcmluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIk1vbml0b3JpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjYXRlZ29yeVZhbHVlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ2F0ZWdvcnlWYWx1ZVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTZXF1ZW5jZUZsb3dcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkZsb3dFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpc0ltbWVkaWF0ZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvbmRpdGlvbkV4cHJlc3Npb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic291cmNlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRmxvd05vZGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0YXJnZXRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJGbG93Tm9kZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJGbG93RWxlbWVudHNDb250YWluZXJcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxhbmVTZXRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiTGFuZVNldFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZmxvd0VsZW1lbnRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRmxvd0VsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDYWxsYWJsZUVsZW1lbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlvU3BlY2lmaWNhdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0T3V0cHV0U3BlY2lmaWNhdGlvblwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwicHJvcGVydHlcIlxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInN1cHBvcnRlZEludGVyZmFjZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkludGVyZmFjZVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlvQmluZGluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIklucHV0T3V0cHV0QmluZGluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJwcm9wZXJ0eVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkZsb3dOb2RlXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkZsb3dFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbmNvbWluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIlNlcXVlbmNlRmxvd1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dGdvaW5nXCIsXG5cdFx0XHRcdHR5cGU6IFwiU2VxdWVuY2VGbG93XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibGFuZXNcIixcblx0XHRcdFx0dHlwZTogXCJMYW5lXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29ycmVsYXRpb25Qcm9wZXJ0eVJldHJpZXZhbEV4cHJlc3Npb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUGF0aFwiLFxuXHRcdFx0XHR0eXBlOiBcIkZvcm1hbEV4cHJlc3Npb25cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb3JyZWxhdGlvblByb3BlcnR5QmluZGluZ1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRhdGFQYXRoXCIsXG5cdFx0XHRcdHR5cGU6IFwiRm9ybWFsRXhwcmVzc2lvblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvcnJlbGF0aW9uUHJvcGVydHlSZWZcIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvblByb3BlcnR5XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlJlc291cmNlXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVzb3VyY2VQYXJhbWV0ZXJzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVzb3VyY2VQYXJhbWV0ZXJcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZXNvdXJjZVBhcmFtZXRlclwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzUmVxdWlyZWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0eXBlXCIsXG5cdFx0XHRcdHR5cGU6IFwiSXRlbURlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ29ycmVsYXRpb25TdWJzY3JpcHRpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb3JyZWxhdGlvbktleVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkNvcnJlbGF0aW9uS2V5XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29ycmVsYXRpb25Qcm9wZXJ0eUJpbmRpbmdcIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvblByb3BlcnR5QmluZGluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIk1lc3NhZ2VGbG93XCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic291cmNlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW50ZXJhY3Rpb25Ob2RlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW50ZXJhY3Rpb25Ob2RlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibWVzc2FnZVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIk1lc3NhZ2VcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTWVzc2FnZUZsb3dBc3NvY2lhdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlubmVyTWVzc2FnZUZsb3dSZWZcIixcblx0XHRcdFx0dHlwZTogXCJNZXNzYWdlRmxvd1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm91dGVyTWVzc2FnZUZsb3dSZWZcIixcblx0XHRcdFx0dHlwZTogXCJNZXNzYWdlRmxvd1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJbnRlcmFjdGlvbk5vZGVcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbmNvbWluZ0NvbnZlcnNhdGlvbkxpbmtzXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29udmVyc2F0aW9uTGlua1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzVmlydHVhbDogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0Z29pbmdDb252ZXJzYXRpb25MaW5rc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkNvbnZlcnNhdGlvbkxpbmtcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJQYXJ0aWNpcGFudFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiSW50ZXJhY3Rpb25Ob2RlXCIsXG5cdFx0XHRcIkJhc2VFbGVtZW50XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbnRlcmZhY2VSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJbnRlcmZhY2VcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudE11bHRpcGxpY2l0eVwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50TXVsdGlwbGljaXR5XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZW5kUG9pbnRSZWZzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRW5kUG9pbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwcm9jZXNzUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUHJvY2Vzc1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJQYXJ0aWNpcGFudEFzc29jaWF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW5uZXJQYXJ0aWNpcGFudFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3V0ZXJQYXJ0aWNpcGFudFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlBhcnRpY2lwYW50TXVsdGlwbGljaXR5XCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm1pbmltdW1cIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IDAsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJJbnRlZ2VyXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibWF4aW11bVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogMSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkludGVnZXJcIlxuXHRcdFx0fVxuXHRcdF0sXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb2xsYWJvcmF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJSb290RWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNDbG9zZWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudHNcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibWVzc2FnZUZsb3dzXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZUZsb3dcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImFydGlmYWN0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkFydGlmYWN0XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb252ZXJzYXRpb25zXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29udmVyc2F0aW9uTm9kZVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29udmVyc2F0aW9uQXNzb2NpYXRpb25zXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29udmVyc2F0aW9uQXNzb2NpYXRpb25cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudEFzc29jaWF0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50QXNzb2NpYXRpb25cIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm1lc3NhZ2VGbG93QXNzb2NpYXRpb25zXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZUZsb3dBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29ycmVsYXRpb25LZXlzXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29ycmVsYXRpb25LZXlcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNob3Jlb2dyYXBoeVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkNob3Jlb2dyYXBoeVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvbnZlcnNhdGlvbkxpbmtzXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29udmVyc2F0aW9uTGlua1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNob3Jlb2dyYXBoeUFjdGl2aXR5XCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkZsb3dOb2RlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwYXJ0aWNpcGFudFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIlBhcnRpY2lwYW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW5pdGlhdGluZ1BhcnRpY2lwYW50UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUGFydGljaXBhbnRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb3JyZWxhdGlvbktleXNcIixcblx0XHRcdFx0dHlwZTogXCJDb3JyZWxhdGlvbktleVwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibG9vcFR5cGVcIixcblx0XHRcdFx0dHlwZTogXCJDaG9yZW9ncmFwaHlMb29wVHlwZVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCJOb25lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ2FsbENob3Jlb2dyYXBoeVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ2hvcmVvZ3JhcGh5QWN0aXZpdHlcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbGxlZENob3Jlb2dyYXBoeVJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkNob3Jlb2dyYXBoeVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpY2lwYW50QXNzb2NpYXRpb25zXCIsXG5cdFx0XHRcdHR5cGU6IFwiUGFydGljaXBhbnRBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlN1YkNob3Jlb2dyYXBoeVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ2hvcmVvZ3JhcGh5QWN0aXZpdHlcIixcblx0XHRcdFwiRmxvd0VsZW1lbnRzQ29udGFpbmVyXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhcnRpZmFjdHNcIixcblx0XHRcdFx0dHlwZTogXCJBcnRpZmFjdFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNob3Jlb2dyYXBoeVRhc2tcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkNob3Jlb2dyYXBoeUFjdGl2aXR5XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlRmxvd1JlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIk1lc3NhZ2VGbG93XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNob3Jlb2dyYXBoeVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ29sbGFib3JhdGlvblwiLFxuXHRcdFx0XCJGbG93RWxlbWVudHNDb250YWluZXJcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiR2xvYmFsQ2hvcmVvZ3JhcGh5VGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQ2hvcmVvZ3JhcGh5XCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbml0aWF0aW5nUGFydGljaXBhbnRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJUZXh0QW5ub3RhdGlvblwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQXJ0aWZhY3RcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRleHRcIixcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0ZXh0Rm9ybWF0XCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBcInRleHQvcGxhaW5cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJHcm91cFwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQXJ0aWZhY3RcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhdGVnb3J5VmFsdWVSZWZcIixcblx0XHRcdFx0dHlwZTogXCJDYXRlZ29yeVZhbHVlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkFzc29jaWF0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJBcnRpZmFjdFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYXNzb2NpYXRpb25EaXJlY3Rpb25cIixcblx0XHRcdFx0dHlwZTogXCJBc3NvY2lhdGlvbkRpcmVjdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic291cmNlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiQmFzZUVsZW1lbnRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0YXJnZXRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJCYXNlRWxlbWVudFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDYXRlZ29yeVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiUm9vdEVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhdGVnb3J5VmFsdWVcIixcblx0XHRcdFx0dHlwZTogXCJDYXRlZ29yeVZhbHVlXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQXJ0aWZhY3RcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQ2F0ZWdvcnlWYWx1ZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhdGVnb3JpemVkRmxvd0VsZW1lbnRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiRmxvd0VsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInZhbHVlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQWN0aXZpdHlcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRmxvd05vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzRm9yQ29tcGVuc2F0aW9uXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkZWZhdWx0XCIsXG5cdFx0XHRcdHR5cGU6IFwiU2VxdWVuY2VGbG93XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW9TcGVjaWZpY2F0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW5wdXRPdXRwdXRTcGVjaWZpY2F0aW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJwcm9wZXJ0eVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYm91bmRhcnlFdmVudFJlZnNcIixcblx0XHRcdFx0dHlwZTogXCJCb3VuZGFyeUV2ZW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicHJvcGVydGllc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlByb3BlcnR5XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJkYXRhSW5wdXRBc3NvY2lhdGlvbnNcIixcblx0XHRcdFx0dHlwZTogXCJEYXRhSW5wdXRBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZGF0YU91dHB1dEFzc29jaWF0aW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFPdXRwdXRBc3NvY2lhdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3RhcnRRdWFudGl0eVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogMSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkludGVnZXJcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJyZXNvdXJjZXNcIixcblx0XHRcdFx0dHlwZTogXCJSZXNvdXJjZVJvbGVcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNvbXBsZXRpb25RdWFudGl0eVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogMSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkludGVnZXJcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJsb29wQ2hhcmFjdGVyaXN0aWNzXCIsXG5cdFx0XHRcdHR5cGU6IFwiTG9vcENoYXJhY3RlcmlzdGljc1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTZXJ2aWNlVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiVGFza1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm9wZXJhdGlvblJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIk9wZXJhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTdWJQcm9jZXNzXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJBY3Rpdml0eVwiLFxuXHRcdFx0XCJGbG93RWxlbWVudHNDb250YWluZXJcIixcblx0XHRcdFwiSW50ZXJhY3Rpb25Ob2RlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0cmlnZ2VyZWRCeUV2ZW50XCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJhcnRpZmFjdHNcIixcblx0XHRcdFx0dHlwZTogXCJBcnRpZmFjdFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkxvb3BDaGFyYWN0ZXJpc3RpY3NcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTXVsdGlJbnN0YW5jZUxvb3BDaGFyYWN0ZXJpc3RpY3NcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkxvb3BDaGFyYWN0ZXJpc3RpY3NcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzU2VxdWVudGlhbFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogZmFsc2UsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYmVoYXZpb3JcIixcblx0XHRcdFx0dHlwZTogXCJNdWx0aUluc3RhbmNlQmVoYXZpb3JcIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IFwiQWxsXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJsb29wQ2FyZGluYWxpdHlcIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibG9vcERhdGFJbnB1dFJlZlwiLFxuXHRcdFx0XHR0eXBlOiBcIkl0ZW1Bd2FyZUVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibG9vcERhdGFPdXRwdXRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJJdGVtQXdhcmVFbGVtZW50XCIsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlucHV0RGF0YUl0ZW1cIixcblx0XHRcdFx0dHlwZTogXCJEYXRhSW5wdXRcIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInByb3BlcnR5XCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvdXRwdXREYXRhSXRlbVwiLFxuXHRcdFx0XHR0eXBlOiBcIkRhdGFPdXRwdXRcIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInByb3BlcnR5XCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjb21wbGV4QmVoYXZpb3JEZWZpbml0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiQ29tcGxleEJlaGF2aW9yRGVmaW5pdGlvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29tcGxldGlvbkNvbmRpdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIkV4cHJlc3Npb25cIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInhzaTp0eXBlXCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvbmVCZWhhdmlvckV2ZW50UmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXZlbnREZWZpbml0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibm9uZUJlaGF2aW9yRXZlbnRSZWZcIixcblx0XHRcdFx0dHlwZTogXCJFdmVudERlZmluaXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiU3RhbmRhcmRMb29wQ2hhcmFjdGVyaXN0aWNzXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJMb29wQ2hhcmFjdGVyaXN0aWNzXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0ZXN0QmVmb3JlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJsb29wQ29uZGl0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXhwcmVzc2lvblwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwieHNpOnR5cGVcIlxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxvb3BNYXhpbXVtXCIsXG5cdFx0XHRcdHR5cGU6IFwiSW50ZWdlclwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNhbGxBY3Rpdml0eVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQWN0aXZpdHlcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbGxlZEVsZW1lbnRcIixcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJBY3Rpdml0eVwiLFxuXHRcdFx0XCJJbnRlcmFjdGlvbk5vZGVcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiU2VuZFRhc2tcIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlRhc2tcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImltcGxlbWVudGF0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcGVyYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJPcGVyYXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZWNlaXZlVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiVGFza1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImluc3RhbnRpYXRlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBmYWxzZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcGVyYXRpb25SZWZcIixcblx0XHRcdFx0dHlwZTogXCJPcGVyYXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXNzYWdlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiTWVzc2FnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTY3JpcHRUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJUYXNrXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzY3JpcHRGb3JtYXRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNjcmlwdFwiLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJCdXNpbmVzc1J1bGVUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJUYXNrXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpbXBsZW1lbnRhdGlvblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkFkSG9jU3ViUHJvY2Vzc1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiU3ViUHJvY2Vzc1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29tcGxldGlvbkNvbmRpdGlvblwiLFxuXHRcdFx0XHR0eXBlOiBcIkV4cHJlc3Npb25cIixcblx0XHRcdFx0eG1sOiB7XG5cdFx0XHRcdFx0c2VyaWFsaXplOiBcInhzaTp0eXBlXCJcblx0XHRcdFx0fVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvcmRlcmluZ1wiLFxuXHRcdFx0XHR0eXBlOiBcIkFkSG9jT3JkZXJpbmdcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImNhbmNlbFJlbWFpbmluZ0luc3RhbmNlc1wiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogdHJ1ZSxcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiVHJhbnNhY3Rpb25cIixcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIlN1YlByb2Nlc3NcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInByb3RvY29sXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtZXRob2RcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJHbG9iYWxTY3JpcHRUYXNrXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJHbG9iYWxUYXNrXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzY3JpcHRMYW5ndWFnZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic2NyaXB0XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiR2xvYmFsQnVzaW5lc3NSdWxlVGFza1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiR2xvYmFsVGFza1wiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wbGVtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJDb21wbGV4QmVoYXZpb3JEZWZpbml0aW9uXCIsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiY29uZGl0aW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRm9ybWFsRXhwcmVzc2lvblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImV2ZW50XCIsXG5cdFx0XHRcdHR5cGU6IFwiSW1wbGljaXRUaHJvd0V2ZW50XCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlJlc291cmNlUm9sZVwiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInJlc291cmNlUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVzb3VyY2VcIixcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVzb3VyY2VQYXJhbWV0ZXJCaW5kaW5nc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlJlc291cmNlUGFyYW1ldGVyQmluZGluZ1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVzb3VyY2VBc3NpZ25tZW50RXhwcmVzc2lvblwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlc291cmNlQXNzaWdubWVudEV4cHJlc3Npb25cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUmVzb3VyY2VQYXJhbWV0ZXJCaW5kaW5nXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImV4cHJlc3Npb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicGFyYW1ldGVyUmVmXCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVzb3VyY2VQYXJhbWV0ZXJcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fVxuXHRcdF0sXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJCYXNlRWxlbWVudFwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJSZXNvdXJjZUFzc2lnbm1lbnRFeHByZXNzaW9uXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImV4cHJlc3Npb25cIixcblx0XHRcdFx0dHlwZTogXCJFeHByZXNzaW9uXCIsXG5cdFx0XHRcdHhtbDoge1xuXHRcdFx0XHRcdHNlcmlhbGl6ZTogXCJ4c2k6dHlwZVwiXG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiSW1wb3J0XCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImltcG9ydFR5cGVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxvY2F0aW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJuYW1lc3BhY2VcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJEZWZpbml0aW9uc1wiLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiQmFzZUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInRhcmdldE5hbWVzcGFjZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXhwcmVzc2lvbkxhbmd1YWdlXCIsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBcImh0dHA6Ly93d3cudzMub3JnLzE5OTkvWFBhdGhcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInR5cGVMYW5ndWFnZVwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCJodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaW1wb3J0c1wiLFxuXHRcdFx0XHR0eXBlOiBcIkltcG9ydFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXh0ZW5zaW9uc1wiLFxuXHRcdFx0XHR0eXBlOiBcIkV4dGVuc2lvblwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicm9vdEVsZW1lbnRzXCIsXG5cdFx0XHRcdHR5cGU6IFwiUm9vdEVsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRpYWdyYW1zXCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJicG1uZGk6QlBNTkRpYWdyYW1cIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJleHBvcnRlclwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicmVsYXRpb25zaGlwc1wiLFxuXHRcdFx0XHR0eXBlOiBcIlJlbGF0aW9uc2hpcFwiLFxuXHRcdFx0XHRpc01hbnk6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXhwb3J0ZXJWZXJzaW9uXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fVxuXTtcbnZhciBlbnVtZXJhdGlvbnMgPSBbXG5cdHtcblx0XHRuYW1lOiBcIlByb2Nlc3NUeXBlXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIk5vbmVcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJQdWJsaWNcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJQcml2YXRlXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkdhdGV3YXlEaXJlY3Rpb25cIixcblx0XHRsaXRlcmFsVmFsdWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiVW5zcGVjaWZpZWRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJDb252ZXJnaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiRGl2ZXJnaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiTWl4ZWRcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXZlbnRCYXNlZEdhdGV3YXlUeXBlXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIlBhcmFsbGVsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiRXhjbHVzaXZlXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlJlbGF0aW9uc2hpcERpcmVjdGlvblwiLFxuXHRcdGxpdGVyYWxWYWx1ZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJOb25lXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiRm9yd2FyZFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIkJhY2t3YXJkXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiQm90aFwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJdGVtS2luZFwiLFxuXHRcdGxpdGVyYWxWYWx1ZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJQaHlzaWNhbFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIkluZm9ybWF0aW9uXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNob3Jlb2dyYXBoeUxvb3BUeXBlXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIk5vbmVcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJTdGFuZGFyZFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIk11bHRpSW5zdGFuY2VTZXF1ZW50aWFsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiTXVsdGlJbnN0YW5jZVBhcmFsbGVsXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkFzc29jaWF0aW9uRGlyZWN0aW9uXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIk5vbmVcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJPbmVcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJCb3RoXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIk11bHRpSW5zdGFuY2VCZWhhdmlvclwiLFxuXHRcdGxpdGVyYWxWYWx1ZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJOb25lXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiT25lXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiQWxsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiQ29tcGxleFwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJBZEhvY09yZGVyaW5nXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIlBhcmFsbGVsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiU2VxdWVudGlhbFwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIHhtbCA9IHtcblx0dGFnQWxpYXM6IFwibG93ZXJDYXNlXCIsXG5cdHR5cGVQcmVmaXg6IFwidFwiXG59O1xudmFyIEJwbW5QYWNrYWdlID0ge1xuXHRuYW1lOiBuYW1lLFxuXHR1cmk6IHVyaSxcblx0cHJlZml4OiBwcmVmaXgsXG5cdGFzc29jaWF0aW9uczogYXNzb2NpYXRpb25zLFxuXHR0eXBlczogdHlwZXMsXG5cdGVudW1lcmF0aW9uczogZW51bWVyYXRpb25zLFxuXHR4bWw6IHhtbFxufTtcblxudmFyIG5hbWUkMSA9IFwiQlBNTkRJXCI7XG52YXIgdXJpJDEgPSBcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0JQTU4vMjAxMDA1MjQvRElcIjtcbnZhciBwcmVmaXgkMSA9IFwiYnBtbmRpXCI7XG52YXIgdHlwZXMkMSA9IFtcblx0e1xuXHRcdG5hbWU6IFwiQlBNTkRpYWdyYW1cIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwicGxhbmVcIixcblx0XHRcdFx0dHlwZTogXCJCUE1OUGxhbmVcIixcblx0XHRcdFx0cmVkZWZpbmVzOiBcImRpOkRpYWdyYW0jcm9vdEVsZW1lbnRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJsYWJlbFN0eWxlXCIsXG5cdFx0XHRcdHR5cGU6IFwiQlBNTkxhYmVsU3R5bGVcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcImRpOkRpYWdyYW1cIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQlBNTlBsYW5lXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImJwbW5FbGVtZW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiYnBtbjpCYXNlRWxlbWVudFwiLFxuXHRcdFx0XHRyZWRlZmluZXM6IFwiZGk6RGlhZ3JhbUVsZW1lbnQjbW9kZWxFbGVtZW50XCJcblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiZGk6UGxhbmVcIlxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiQlBNTlNoYXBlXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImJwbW5FbGVtZW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiYnBtbjpCYXNlRWxlbWVudFwiLFxuXHRcdFx0XHRyZWRlZmluZXM6IFwiZGk6RGlhZ3JhbUVsZW1lbnQjbW9kZWxFbGVtZW50XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNIb3Jpem9udGFsXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNFeHBhbmRlZFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzTWFya2VyVmlzaWJsZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxhYmVsXCIsXG5cdFx0XHRcdHR5cGU6IFwiQlBNTkxhYmVsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNNZXNzYWdlVmlzaWJsZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInBhcnRpY2lwYW50QmFuZEtpbmRcIixcblx0XHRcdFx0dHlwZTogXCJQYXJ0aWNpcGFudEJhbmRLaW5kXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJjaG9yZW9ncmFwaHlBY3Rpdml0eVNoYXBlXCIsXG5cdFx0XHRcdHR5cGU6IFwiQlBNTlNoYXBlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiZGk6TGFiZWxlZFNoYXBlXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJQTU5FZGdlXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImxhYmVsXCIsXG5cdFx0XHRcdHR5cGU6IFwiQlBNTkxhYmVsXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYnBtbkVsZW1lbnRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJicG1uOkJhc2VFbGVtZW50XCIsXG5cdFx0XHRcdHJlZGVmaW5lczogXCJkaTpEaWFncmFtRWxlbWVudCNtb2RlbEVsZW1lbnRcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzb3VyY2VFbGVtZW50XCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiZGk6RGlhZ3JhbUVsZW1lbnRcIixcblx0XHRcdFx0cmVkZWZpbmVzOiBcImRpOkVkZ2Ujc291cmNlXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0RWxlbWVudFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcImRpOkRpYWdyYW1FbGVtZW50XCIsXG5cdFx0XHRcdHJlZGVmaW5lczogXCJkaTpFZGdlI3RhcmdldFwiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm1lc3NhZ2VWaXNpYmxlS2luZFwiLFxuXHRcdFx0XHR0eXBlOiBcIk1lc3NhZ2VWaXNpYmxlS2luZFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdFwiZGVmYXVsdFwiOiBcImluaXRpYXRpbmdcIlxuXHRcdFx0fVxuXHRcdF0sXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJkaTpMYWJlbGVkRWRnZVwiXG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJCUE1OTGFiZWxcIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibGFiZWxTdHlsZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkJQTU5MYWJlbFN0eWxlXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWUsXG5cdFx0XHRcdHJlZGVmaW5lczogXCJkaTpEaWFncmFtRWxlbWVudCNzdHlsZVwiXG5cdFx0XHR9XG5cdFx0XSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcImRpOkxhYmVsXCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJQTU5MYWJlbFN0eWxlXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZvbnRcIixcblx0XHRcdFx0dHlwZTogXCJkYzpGb250XCJcblx0XHRcdH1cblx0XHRdLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiZGk6U3R5bGVcIlxuXHRcdF1cblx0fVxuXTtcbnZhciBlbnVtZXJhdGlvbnMkMSA9IFtcblx0e1xuXHRcdG5hbWU6IFwiUGFydGljaXBhbnRCYW5kS2luZFwiLFxuXHRcdGxpdGVyYWxWYWx1ZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0b3BfaW5pdGlhdGluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm1pZGRsZV9pbml0aWF0aW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiYm90dG9tX2luaXRpYXRpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ0b3Bfbm9uX2luaXRpYXRpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtaWRkbGVfbm9uX2luaXRpYXRpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJib3R0b21fbm9uX2luaXRpYXRpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiTWVzc2FnZVZpc2libGVLaW5kXCIsXG5cdFx0bGl0ZXJhbFZhbHVlczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImluaXRpYXRpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJub25faW5pdGlhdGluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIGFzc29jaWF0aW9ucyQxID0gW1xuXTtcbnZhciBCcG1uRGlQYWNrYWdlID0ge1xuXHRuYW1lOiBuYW1lJDEsXG5cdHVyaTogdXJpJDEsXG5cdHByZWZpeDogcHJlZml4JDEsXG5cdHR5cGVzOiB0eXBlcyQxLFxuXHRlbnVtZXJhdGlvbnM6IGVudW1lcmF0aW9ucyQxLFxuXHRhc3NvY2lhdGlvbnM6IGFzc29jaWF0aW9ucyQxXG59O1xuXG52YXIgbmFtZSQyID0gXCJEQ1wiO1xudmFyIHVyaSQyID0gXCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9ERC8yMDEwMDUyNC9EQ1wiO1xudmFyIHByZWZpeCQyID0gXCJkY1wiO1xudmFyIHR5cGVzJDIgPSBbXG5cdHtcblx0XHRuYW1lOiBcIkJvb2xlYW5cIlxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJJbnRlZ2VyXCJcblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUmVhbFwiXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlN0cmluZ1wiXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkZvbnRcIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwibmFtZVwiLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic2l6ZVwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzQm9sZFwiLFxuXHRcdFx0XHR0eXBlOiBcIkJvb2xlYW5cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlzSXRhbGljXCIsXG5cdFx0XHRcdHR5cGU6IFwiQm9vbGVhblwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaXNVbmRlcmxpbmVcIixcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpc1N0cmlrZVRocm91Z2hcIixcblx0XHRcdFx0dHlwZTogXCJCb29sZWFuXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiUG9pbnRcIixcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwieFwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IFwiMFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwieVwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0XCJkZWZhdWx0XCI6IFwiMFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkJvdW5kc1wiLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ4XCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVhbFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCIwXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ5XCIsXG5cdFx0XHRcdHR5cGU6IFwiUmVhbFwiLFxuXHRcdFx0XHRcImRlZmF1bHRcIjogXCIwXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ3aWR0aFwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImhlaWdodFwiLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIGFzc29jaWF0aW9ucyQyID0gW1xuXTtcbnZhciBEY1BhY2thZ2UgPSB7XG5cdG5hbWU6IG5hbWUkMixcblx0dXJpOiB1cmkkMixcblx0cHJlZml4OiBwcmVmaXgkMixcblx0dHlwZXM6IHR5cGVzJDIsXG5cdGFzc29jaWF0aW9uczogYXNzb2NpYXRpb25zJDJcbn07XG5cbnZhciBuYW1lJDMgPSBcIkRJXCI7XG52YXIgdXJpJDMgPSBcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0RELzIwMTAwNTI0L0RJXCI7XG52YXIgcHJlZml4JDMgPSBcImRpXCI7XG52YXIgdHlwZXMkMyA9IFtcblx0e1xuXHRcdG5hbWU6IFwiRGlhZ3JhbUVsZW1lbnRcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJpZFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdGlzSWQ6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZXh0ZW5zaW9uXCIsXG5cdFx0XHRcdHR5cGU6IFwiRXh0ZW5zaW9uXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwib3duaW5nRGlhZ3JhbVwiLFxuXHRcdFx0XHR0eXBlOiBcIkRpYWdyYW1cIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvd25pbmdFbGVtZW50XCIsXG5cdFx0XHRcdHR5cGU6IFwiRGlhZ3JhbUVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJtb2RlbEVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJFbGVtZW50XCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwic3R5bGVcIixcblx0XHRcdFx0dHlwZTogXCJTdHlsZVwiLFxuXHRcdFx0XHRpc1JlYWRPbmx5OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWUsXG5cdFx0XHRcdGlzUmVmZXJlbmNlOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm93bmVkRWxlbWVudFwiLFxuXHRcdFx0XHR0eXBlOiBcIkRpYWdyYW1FbGVtZW50XCIsXG5cdFx0XHRcdGlzUmVhZE9ubHk6IHRydWUsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJOb2RlXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIkRpYWdyYW1FbGVtZW50XCJcblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkVkZ2VcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiRGlhZ3JhbUVsZW1lbnRcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInNvdXJjZVwiLFxuXHRcdFx0XHR0eXBlOiBcIkRpYWdyYW1FbGVtZW50XCIsXG5cdFx0XHRcdGlzUmVhZE9ubHk6IHRydWUsXG5cdFx0XHRcdGlzVmlydHVhbDogdHJ1ZSxcblx0XHRcdFx0aXNSZWZlcmVuY2U6IHRydWVcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwidGFyZ2V0XCIsXG5cdFx0XHRcdHR5cGU6IFwiRGlhZ3JhbUVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlLFxuXHRcdFx0XHRpc1JlZmVyZW5jZTogdHJ1ZVxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJ3YXlwb2ludFwiLFxuXHRcdFx0XHRpc1VuaXF1ZTogZmFsc2UsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJkYzpQb2ludFwiLFxuXHRcdFx0XHR4bWw6IHtcblx0XHRcdFx0XHRzZXJpYWxpemU6IFwieHNpOnR5cGVcIlxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJEaWFncmFtXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRwcm9wZXJ0aWVzOiBbXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiaWRcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHRpc0lkOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInJvb3RFbGVtZW50XCIsXG5cdFx0XHRcdHR5cGU6IFwiRGlhZ3JhbUVsZW1lbnRcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm5hbWVcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImRvY3VtZW50YXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInJlc29sdXRpb25cIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlJlYWxcIlxuXHRcdFx0fSxcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvd25lZFN0eWxlXCIsXG5cdFx0XHRcdHR5cGU6IFwiU3R5bGVcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIlNoYXBlXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIk5vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImJvdW5kc1wiLFxuXHRcdFx0XHR0eXBlOiBcImRjOkJvdW5kc1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJQbGFuZVwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJOb2RlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJwbGFuZUVsZW1lbnRcIixcblx0XHRcdFx0dHlwZTogXCJEaWFncmFtRWxlbWVudFwiLFxuXHRcdFx0XHRzdWJzZXR0ZWRQcm9wZXJ0eTogXCJEaWFncmFtRWxlbWVudC1vd25lZEVsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJMYWJlbGVkRWRnZVwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0c3VwZXJDbGFzczogW1xuXHRcdFx0XCJFZGdlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJvd25lZExhYmVsXCIsXG5cdFx0XHRcdHR5cGU6IFwiTGFiZWxcIixcblx0XHRcdFx0aXNSZWFkT25seTogdHJ1ZSxcblx0XHRcdFx0c3Vic2V0dGVkUHJvcGVydHk6IFwiRGlhZ3JhbUVsZW1lbnQtb3duZWRFbGVtZW50XCIsXG5cdFx0XHRcdGlzTWFueTogdHJ1ZSxcblx0XHRcdFx0aXNWaXJ0dWFsOiB0cnVlXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJMYWJlbGVkU2hhcGVcIixcblx0XHRpc0Fic3RyYWN0OiB0cnVlLFxuXHRcdHN1cGVyQ2xhc3M6IFtcblx0XHRcdFwiU2hhcGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcIm93bmVkTGFiZWxcIixcblx0XHRcdFx0dHlwZTogXCJMYWJlbFwiLFxuXHRcdFx0XHRpc1JlYWRPbmx5OiB0cnVlLFxuXHRcdFx0XHRzdWJzZXR0ZWRQcm9wZXJ0eTogXCJEaWFncmFtRWxlbWVudC1vd25lZEVsZW1lbnRcIixcblx0XHRcdFx0aXNNYW55OiB0cnVlLFxuXHRcdFx0XHRpc1ZpcnR1YWw6IHRydWVcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkxhYmVsXCIsXG5cdFx0aXNBYnN0cmFjdDogdHJ1ZSxcblx0XHRzdXBlckNsYXNzOiBbXG5cdFx0XHRcIk5vZGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImJvdW5kc1wiLFxuXHRcdFx0XHR0eXBlOiBcImRjOkJvdW5kc1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9LFxuXHR7XG5cdFx0bmFtZTogXCJTdHlsZVwiLFxuXHRcdGlzQWJzdHJhY3Q6IHRydWUsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImlkXCIsXG5cdFx0XHRcdGlzQXR0cjogdHJ1ZSxcblx0XHRcdFx0aXNJZDogdHJ1ZSxcblx0XHRcdFx0dHlwZTogXCJTdHJpbmdcIlxuXHRcdFx0fVxuXHRcdF1cblx0fSxcblx0e1xuXHRcdG5hbWU6IFwiRXh0ZW5zaW9uXCIsXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInZhbHVlc1wiLFxuXHRcdFx0XHRpc01hbnk6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiRWxlbWVudFwiXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIGFzc29jaWF0aW9ucyQzID0gW1xuXTtcbnZhciB4bWwkMSA9IHtcblx0dGFnQWxpYXM6IFwibG93ZXJDYXNlXCJcbn07XG52YXIgRGlQYWNrYWdlID0ge1xuXHRuYW1lOiBuYW1lJDMsXG5cdHVyaTogdXJpJDMsXG5cdHByZWZpeDogcHJlZml4JDMsXG5cdHR5cGVzOiB0eXBlcyQzLFxuXHRhc3NvY2lhdGlvbnM6IGFzc29jaWF0aW9ucyQzLFxuXHR4bWw6IHhtbCQxXG59O1xuXG52YXIgbmFtZSQ0ID0gXCJicG1uLmlvIGNvbG9ycyBmb3IgQlBNTlwiO1xudmFyIHVyaSQ0ID0gXCJodHRwOi8vYnBtbi5pby9zY2hlbWEvYnBtbi9iaW9jb2xvci8xLjBcIjtcbnZhciBwcmVmaXgkNCA9IFwiYmlvY1wiO1xudmFyIHR5cGVzJDQgPSBbXG5cdHtcblx0XHRuYW1lOiBcIkNvbG9yZWRTaGFwZVwiLFxuXHRcdFwiZXh0ZW5kc1wiOiBbXG5cdFx0XHRcImJwbW5kaTpCUE1OU2hhcGVcIlxuXHRcdF0sXG5cdFx0cHJvcGVydGllczogW1xuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcInN0cm9rZVwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdG5hbWU6IFwiZmlsbFwiLFxuXHRcdFx0XHRpc0F0dHI6IHRydWUsXG5cdFx0XHRcdHR5cGU6IFwiU3RyaW5nXCJcblx0XHRcdH1cblx0XHRdXG5cdH0sXG5cdHtcblx0XHRuYW1lOiBcIkNvbG9yZWRFZGdlXCIsXG5cdFx0XCJleHRlbmRzXCI6IFtcblx0XHRcdFwiYnBtbmRpOkJQTU5FZGdlXCJcblx0XHRdLFxuXHRcdHByb3BlcnRpZXM6IFtcblx0XHRcdHtcblx0XHRcdFx0bmFtZTogXCJzdHJva2VcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0e1xuXHRcdFx0XHRuYW1lOiBcImZpbGxcIixcblx0XHRcdFx0aXNBdHRyOiB0cnVlLFxuXHRcdFx0XHR0eXBlOiBcIlN0cmluZ1wiXG5cdFx0XHR9XG5cdFx0XVxuXHR9XG5dO1xudmFyIGVudW1lcmF0aW9ucyQyID0gW1xuXTtcbnZhciBhc3NvY2lhdGlvbnMkNCA9IFtcbl07XG52YXIgQmlvY1BhY2thZ2UgPSB7XG5cdG5hbWU6IG5hbWUkNCxcblx0dXJpOiB1cmkkNCxcblx0cHJlZml4OiBwcmVmaXgkNCxcblx0dHlwZXM6IHR5cGVzJDQsXG5cdGVudW1lcmF0aW9uczogZW51bWVyYXRpb25zJDIsXG5cdGFzc29jaWF0aW9uczogYXNzb2NpYXRpb25zJDRcbn07XG5cbnZhciBwYWNrYWdlcyA9IHtcbiAgYnBtbjogQnBtblBhY2thZ2UsXG4gIGJwbW5kaTogQnBtbkRpUGFja2FnZSxcbiAgZGM6IERjUGFja2FnZSxcbiAgZGk6IERpUGFja2FnZSxcbiAgYmlvYzogQmlvY1BhY2thZ2Vcbn07XG5cbmZ1bmN0aW9uIHNpbXBsZShhZGRpdGlvbmFsUGFja2FnZXMsIG9wdGlvbnMpIHtcbiAgdmFyIHBrcyA9IGFzc2lnbih7fSwgcGFja2FnZXMsIGFkZGl0aW9uYWxQYWNrYWdlcyk7XG5cbiAgcmV0dXJuIG5ldyBCcG1uTW9kZGxlKHBrcywgb3B0aW9ucyk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IHNpbXBsZTtcbiIsIi8qISBodHRwczovL210aHMuYmUvY3NzZXNjYXBlIHYxLjUuMSBieSBAbWF0aGlhcyB8IE1JVCBsaWNlbnNlICovXG47KGZ1bmN0aW9uKHJvb3QsIGZhY3RvcnkpIHtcblx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL3VtZGpzL3VtZC9ibG9iL21hc3Rlci9yZXR1cm5FeHBvcnRzLmpzXG5cdGlmICh0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0Jykge1xuXHRcdC8vIEZvciBOb2RlLmpzLlxuXHRcdG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyb290KTtcblx0fSBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkge1xuXHRcdC8vIEZvciBBTUQuIFJlZ2lzdGVyIGFzIGFuIGFub255bW91cyBtb2R1bGUuXG5cdFx0ZGVmaW5lKFtdLCBmYWN0b3J5LmJpbmQocm9vdCwgcm9vdCkpO1xuXHR9IGVsc2Uge1xuXHRcdC8vIEZvciBicm93c2VyIGdsb2JhbHMgKG5vdCBleHBvc2luZyB0aGUgZnVuY3Rpb24gc2VwYXJhdGVseSkuXG5cdFx0ZmFjdG9yeShyb290KTtcblx0fVxufSh0eXBlb2YgZ2xvYmFsICE9ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogdGhpcywgZnVuY3Rpb24ocm9vdCkge1xuXG5cdGlmIChyb290LkNTUyAmJiByb290LkNTUy5lc2NhcGUpIHtcblx0XHRyZXR1cm4gcm9vdC5DU1MuZXNjYXBlO1xuXHR9XG5cblx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNzZXJpYWxpemUtYW4taWRlbnRpZmllclxuXHR2YXIgY3NzRXNjYXBlID0gZnVuY3Rpb24odmFsdWUpIHtcblx0XHRpZiAoYXJndW1lbnRzLmxlbmd0aCA9PSAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdgQ1NTLmVzY2FwZWAgcmVxdWlyZXMgYW4gYXJndW1lbnQuJyk7XG5cdFx0fVxuXHRcdHZhciBzdHJpbmcgPSBTdHJpbmcodmFsdWUpO1xuXHRcdHZhciBsZW5ndGggPSBzdHJpbmcubGVuZ3RoO1xuXHRcdHZhciBpbmRleCA9IC0xO1xuXHRcdHZhciBjb2RlVW5pdDtcblx0XHR2YXIgcmVzdWx0ID0gJyc7XG5cdFx0dmFyIGZpcnN0Q29kZVVuaXQgPSBzdHJpbmcuY2hhckNvZGVBdCgwKTtcblx0XHR3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuXHRcdFx0Y29kZVVuaXQgPSBzdHJpbmcuY2hhckNvZGVBdChpbmRleCk7XG5cdFx0XHQvLyBOb3RlOiB0aGVyZeKAmXMgbm8gbmVlZCB0byBzcGVjaWFsLWNhc2UgYXN0cmFsIHN5bWJvbHMsIHN1cnJvZ2F0ZVxuXHRcdFx0Ly8gcGFpcnMsIG9yIGxvbmUgc3Vycm9nYXRlcy5cblxuXHRcdFx0Ly8gSWYgdGhlIGNoYXJhY3RlciBpcyBOVUxMIChVKzAwMDApLCB0aGVuIHRoZSBSRVBMQUNFTUVOVCBDSEFSQUNURVJcblx0XHRcdC8vIChVK0ZGRkQpLlxuXHRcdFx0aWYgKGNvZGVVbml0ID09IDB4MDAwMCkge1xuXHRcdFx0XHRyZXN1bHQgKz0gJ1xcdUZGRkQnO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKFxuXHRcdFx0XHQvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIGluIHRoZSByYW5nZSBbXFwxLVxcMUZdIChVKzAwMDEgdG8gVSswMDFGKSBvciBpc1xuXHRcdFx0XHQvLyBVKzAwN0YsIFvigKZdXG5cdFx0XHRcdChjb2RlVW5pdCA+PSAweDAwMDEgJiYgY29kZVVuaXQgPD0gMHgwMDFGKSB8fCBjb2RlVW5pdCA9PSAweDAwN0YgfHxcblx0XHRcdFx0Ly8gSWYgdGhlIGNoYXJhY3RlciBpcyB0aGUgZmlyc3QgY2hhcmFjdGVyIGFuZCBpcyBpbiB0aGUgcmFuZ2UgWzAtOV1cblx0XHRcdFx0Ly8gKFUrMDAzMCB0byBVKzAwMzkpLCBb4oCmXVxuXHRcdFx0XHQoaW5kZXggPT0gMCAmJiBjb2RlVW5pdCA+PSAweDAwMzAgJiYgY29kZVVuaXQgPD0gMHgwMDM5KSB8fFxuXHRcdFx0XHQvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIHRoZSBzZWNvbmQgY2hhcmFjdGVyIGFuZCBpcyBpbiB0aGUgcmFuZ2UgWzAtOV1cblx0XHRcdFx0Ly8gKFUrMDAzMCB0byBVKzAwMzkpIGFuZCB0aGUgZmlyc3QgY2hhcmFjdGVyIGlzIGEgYC1gIChVKzAwMkQpLCBb4oCmXVxuXHRcdFx0XHQoXG5cdFx0XHRcdFx0aW5kZXggPT0gMSAmJlxuXHRcdFx0XHRcdGNvZGVVbml0ID49IDB4MDAzMCAmJiBjb2RlVW5pdCA8PSAweDAwMzkgJiZcblx0XHRcdFx0XHRmaXJzdENvZGVVbml0ID09IDB4MDAyRFxuXHRcdFx0XHQpXG5cdFx0XHQpIHtcblx0XHRcdFx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNlc2NhcGUtYS1jaGFyYWN0ZXItYXMtY29kZS1wb2ludFxuXHRcdFx0XHRyZXN1bHQgKz0gJ1xcXFwnICsgY29kZVVuaXQudG9TdHJpbmcoMTYpICsgJyAnO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKFxuXHRcdFx0XHQvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYW5kIGlzIGEgYC1gIChVKzAwMkQpLCBhbmRcblx0XHRcdFx0Ly8gdGhlcmUgaXMgbm8gc2Vjb25kIGNoYXJhY3RlciwgW+KApl1cblx0XHRcdFx0aW5kZXggPT0gMCAmJlxuXHRcdFx0XHRsZW5ndGggPT0gMSAmJlxuXHRcdFx0XHRjb2RlVW5pdCA9PSAweDAwMkRcblx0XHRcdCkge1xuXHRcdFx0XHRyZXN1bHQgKz0gJ1xcXFwnICsgc3RyaW5nLmNoYXJBdChpbmRleCk7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGUgY2hhcmFjdGVyIGlzIG5vdCBoYW5kbGVkIGJ5IG9uZSBvZiB0aGUgYWJvdmUgcnVsZXMgYW5kIGlzXG5cdFx0XHQvLyBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8gVSswMDgwLCBpcyBgLWAgKFUrMDAyRCkgb3IgYF9gIChVKzAwNUYpLCBvclxuXHRcdFx0Ly8gaXMgaW4gb25lIG9mIHRoZSByYW5nZXMgWzAtOV0gKFUrMDAzMCB0byBVKzAwMzkpLCBbQS1aXSAoVSswMDQxIHRvXG5cdFx0XHQvLyBVKzAwNUEpLCBvciBbYS16XSAoVSswMDYxIHRvIFUrMDA3QSksIFvigKZdXG5cdFx0XHRpZiAoXG5cdFx0XHRcdGNvZGVVbml0ID49IDB4MDA4MCB8fFxuXHRcdFx0XHRjb2RlVW5pdCA9PSAweDAwMkQgfHxcblx0XHRcdFx0Y29kZVVuaXQgPT0gMHgwMDVGIHx8XG5cdFx0XHRcdGNvZGVVbml0ID49IDB4MDAzMCAmJiBjb2RlVW5pdCA8PSAweDAwMzkgfHxcblx0XHRcdFx0Y29kZVVuaXQgPj0gMHgwMDQxICYmIGNvZGVVbml0IDw9IDB4MDA1QSB8fFxuXHRcdFx0XHRjb2RlVW5pdCA+PSAweDAwNjEgJiYgY29kZVVuaXQgPD0gMHgwMDdBXG5cdFx0XHQpIHtcblx0XHRcdFx0Ly8gdGhlIGNoYXJhY3RlciBpdHNlbGZcblx0XHRcdFx0cmVzdWx0ICs9IHN0cmluZy5jaGFyQXQoaW5kZXgpO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gT3RoZXJ3aXNlLCB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG5cdFx0XHQvLyBodHRwczovL2RyYWZ0cy5jc3N3Zy5vcmcvY3Nzb20vI2VzY2FwZS1hLWNoYXJhY3RlclxuXHRcdFx0cmVzdWx0ICs9ICdcXFxcJyArIHN0cmluZy5jaGFyQXQoaW5kZXgpO1xuXG5cdFx0fVxuXHRcdHJldHVybiByZXN1bHQ7XG5cdH07XG5cblx0aWYgKCFyb290LkNTUykge1xuXHRcdHJvb3QuQ1NTID0ge307XG5cdH1cblxuXHRyb290LkNTUy5lc2NhcGUgPSBjc3NFc2NhcGU7XG5cdHJldHVybiBjc3NFc2NhcGU7XG5cbn0pKTtcbiIsImltcG9ydCBJbnRlcmFjdGlvbkV2ZW50c01vZHVsZSBmcm9tICdkaWFncmFtLWpzL2xpYi9mZWF0dXJlcy9pbnRlcmFjdGlvbi1ldmVudHMnO1xuXG5pbXBvcnQgRGlyZWN0RWRpdGluZyBmcm9tICcuL2xpYi9EaXJlY3RFZGl0aW5nJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBfX2RlcGVuZHNfXzogW1xuICAgIEludGVyYWN0aW9uRXZlbnRzTW9kdWxlXG4gIF0sXG4gIF9faW5pdF9fOiBbICdkaXJlY3RFZGl0aW5nJyBdLFxuICBkaXJlY3RFZGl0aW5nOiBbICd0eXBlJywgRGlyZWN0RWRpdGluZyBdXG59OyIsImltcG9ydCB7XG4gIGJpbmQsXG4gIGZpbmRcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQgVGV4dEJveCBmcm9tICcuL1RleHRCb3gnO1xuXG5cbi8qKlxuICogQSBkaXJlY3QgZWRpdGluZyBjb21wb25lbnQgdGhhdCBhbGxvd3MgdXNlcnNcbiAqIHRvIGVkaXQgYW4gZWxlbWVudHMgdGV4dCBkaXJlY3RseSBpbiB0aGUgZGlhZ3JhbVxuICpcbiAqIEBwYXJhbSB7RXZlbnRCdXN9IGV2ZW50QnVzIHRoZSBldmVudCBidXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRGlyZWN0RWRpdGluZyhldmVudEJ1cywgY2FudmFzKSB7XG5cbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcblxuICB0aGlzLl9wcm92aWRlcnMgPSBbXTtcbiAgdGhpcy5fdGV4dGJveCA9IG5ldyBUZXh0Qm94KHtcbiAgICBjb250YWluZXI6IGNhbnZhcy5nZXRDb250YWluZXIoKSxcbiAgICBrZXlIYW5kbGVyOiBiaW5kKHRoaXMuX2hhbmRsZUtleSwgdGhpcyksXG4gICAgcmVzaXplSGFuZGxlcjogYmluZCh0aGlzLl9oYW5kbGVSZXNpemUsIHRoaXMpXG4gIH0pO1xufVxuXG5EaXJlY3RFZGl0aW5nLiRpbmplY3QgPSBbICdldmVudEJ1cycsICdjYW52YXMnIF07XG5cblxuLyoqXG4gKiBSZWdpc3RlciBhIGRpcmVjdCBlZGl0aW5nIHByb3ZpZGVyXG5cbiAqIEBwYXJhbSB7T2JqZWN0fSBwcm92aWRlciB0aGUgcHJvdmlkZXIsIG11c3QgZXhwb3NlIGFuICNhY3RpdmF0ZShlbGVtZW50KSBtZXRob2QgdGhhdCByZXR1cm5zXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgYW4gYWN0aXZhdGlvbiBjb250ZXh0ICh7IGJvdW5kczoge3gsIHksIHdpZHRoLCBoZWlnaHQgfSwgdGV4dCB9KSBpZlxuICogICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdCBlZGl0aW5nIGlzIGF2YWlsYWJsZSBmb3IgdGhlIGdpdmVuIGVsZW1lbnQuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgQWRkaXRpb25hbGx5IHRoZSBwcm92aWRlciBtdXN0IGV4cG9zZSBhICN1cGRhdGUoZWxlbWVudCwgdmFsdWUpIG1ldGhvZFxuICogICAgICAgICAgICAgICAgICAgICAgICAgIHRvIHJlY2VpdmUgZGlyZWN0IGVkaXRpbmcgdXBkYXRlcy5cbiAqL1xuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUucmVnaXN0ZXJQcm92aWRlciA9IGZ1bmN0aW9uKHByb3ZpZGVyKSB7XG4gIHRoaXMuX3Byb3ZpZGVycy5wdXNoKHByb3ZpZGVyKTtcbn07XG5cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgZGlyZWN0IGVkaXRpbmcgaXMgY3VycmVudGx5IGFjdGl2ZVxuICpcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKi9cbkRpcmVjdEVkaXRpbmcucHJvdG90eXBlLmlzQWN0aXZlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAhIXRoaXMuX2FjdGl2ZTtcbn07XG5cblxuLyoqXG4gKiBDYW5jZWwgZGlyZWN0IGVkaXRpbmcsIGlmIGl0IGlzIGN1cnJlbnRseSBhY3RpdmVcbiAqL1xuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUuY2FuY2VsID0gZnVuY3Rpb24oKSB7XG4gIGlmICghdGhpcy5fYWN0aXZlKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdGhpcy5fZmlyZSgnY2FuY2VsJyk7XG4gIHRoaXMuY2xvc2UoKTtcbn07XG5cblxuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUuX2ZpcmUgPSBmdW5jdGlvbihldmVudCwgY29udGV4dCkge1xuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdkaXJlY3RFZGl0aW5nLicgKyBldmVudCwgY29udGV4dCB8fCB7IGFjdGl2ZTogdGhpcy5fYWN0aXZlIH0pO1xufTtcblxuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUuY2xvc2UgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fdGV4dGJveC5kZXN0cm95KCk7XG5cbiAgdGhpcy5fZmlyZSgnZGVhY3RpdmF0ZScpO1xuXG4gIHRoaXMuX2FjdGl2ZSA9IG51bGw7XG5cbiAgdGhpcy5yZXNpemFibGUgPSB1bmRlZmluZWQ7XG59O1xuXG5cbkRpcmVjdEVkaXRpbmcucHJvdG90eXBlLmNvbXBsZXRlID0gZnVuY3Rpb24oKSB7XG5cbiAgdmFyIGFjdGl2ZSA9IHRoaXMuX2FjdGl2ZTtcblxuICBpZiAoIWFjdGl2ZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBjb250YWluZXJCb3VuZHMsXG4gICAgICBwcmV2aW91c0JvdW5kcyA9IGFjdGl2ZS5jb250ZXh0LmJvdW5kcyxcbiAgICAgIG5ld0JvdW5kcyA9IHRoaXMuJHRleHRib3guZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXG4gICAgICBuZXdUZXh0ID0gdGhpcy5nZXRWYWx1ZSgpLFxuICAgICAgcHJldmlvdXNUZXh0ID0gYWN0aXZlLmNvbnRleHQudGV4dDtcblxuICBpZiAoXG4gICAgbmV3VGV4dCAhPT0gcHJldmlvdXNUZXh0IHx8XG4gICAgbmV3Qm91bmRzLmhlaWdodCAhPT0gcHJldmlvdXNCb3VuZHMuaGVpZ2h0IHx8XG4gICAgbmV3Qm91bmRzLndpZHRoICE9PSBwcmV2aW91c0JvdW5kcy53aWR0aFxuICApIHtcbiAgICBjb250YWluZXJCb3VuZHMgPSB0aGlzLl90ZXh0Ym94LmNvbnRhaW5lci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIGFjdGl2ZS5wcm92aWRlci51cGRhdGUoYWN0aXZlLmVsZW1lbnQsIG5ld1RleHQsIGFjdGl2ZS5jb250ZXh0LnRleHQsIHtcbiAgICAgIHg6IG5ld0JvdW5kcy5sZWZ0IC0gY29udGFpbmVyQm91bmRzLmxlZnQsXG4gICAgICB5OiBuZXdCb3VuZHMudG9wIC0gY29udGFpbmVyQm91bmRzLnRvcCxcbiAgICAgIHdpZHRoOiBuZXdCb3VuZHMud2lkdGgsXG4gICAgICBoZWlnaHQ6IG5ld0JvdW5kcy5oZWlnaHRcbiAgICB9KTtcbiAgfVxuXG4gIHRoaXMuX2ZpcmUoJ2NvbXBsZXRlJyk7XG5cbiAgdGhpcy5jbG9zZSgpO1xufTtcblxuXG5EaXJlY3RFZGl0aW5nLnByb3RvdHlwZS5nZXRWYWx1ZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fdGV4dGJveC5nZXRWYWx1ZSgpO1xufTtcblxuXG5EaXJlY3RFZGl0aW5nLnByb3RvdHlwZS5faGFuZGxlS2V5ID0gZnVuY3Rpb24oZSkge1xuXG4gIC8vIHN0b3AgYnViYmxlXG4gIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG5cbiAgdmFyIGtleSA9IGUua2V5Q29kZSB8fCBlLmNoYXJDb2RlO1xuXG4gIC8vIEVTQ1xuICBpZiAoa2V5ID09PSAyNykge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICByZXR1cm4gdGhpcy5jYW5jZWwoKTtcbiAgfVxuXG4gIC8vIEVudGVyXG4gIGlmIChrZXkgPT09IDEzICYmICFlLnNoaWZ0S2V5KSB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHJldHVybiB0aGlzLmNvbXBsZXRlKCk7XG4gIH1cbn07XG5cblxuRGlyZWN0RWRpdGluZy5wcm90b3R5cGUuX2hhbmRsZVJlc2l6ZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XG4gIHRoaXMuX2ZpcmUoJ3Jlc2l6ZScsIGV2ZW50KTtcbn07XG5cblxuLyoqXG4gKiBBY3RpdmF0ZSBkaXJlY3QgZWRpdGluZyBvbiB0aGUgZ2l2ZW4gZWxlbWVudFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBFbGVtZW50RGVzY3JpcHRvciB0aGUgZGVzY3JpcHRvciBmb3IgYSBzaGFwZSBvciBjb25uZWN0aW9uXG4gKiBAcmV0dXJuIHtCb29sZWFufSB0cnVlIGlmIHRoZSBhY3RpdmF0aW9uIHdhcyBwb3NzaWJsZVxuICovXG5EaXJlY3RFZGl0aW5nLnByb3RvdHlwZS5hY3RpdmF0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgaWYgKHRoaXMuaXNBY3RpdmUoKSkge1xuICAgIHRoaXMuY2FuY2VsKCk7XG4gIH1cblxuICAvLyB0aGUgZGlyZWN0IGVkaXRpbmcgY29udGV4dFxuICB2YXIgY29udGV4dDtcblxuICB2YXIgcHJvdmlkZXIgPSBmaW5kKHRoaXMuX3Byb3ZpZGVycywgZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAoY29udGV4dCA9IHAuYWN0aXZhdGUoZWxlbWVudCkpID8gcCA6IG51bGw7XG4gIH0pO1xuXG4gIC8vIGNoZWNrIGlmIGFjdGl2YXRpb24gdG9vayBwbGFjZVxuICBpZiAoY29udGV4dCkge1xuICAgIHRoaXMuJHRleHRib3ggPSB0aGlzLl90ZXh0Ym94LmNyZWF0ZShcbiAgICAgIGNvbnRleHQuYm91bmRzLFxuICAgICAgY29udGV4dC5zdHlsZSxcbiAgICAgIGNvbnRleHQudGV4dCxcbiAgICAgIGNvbnRleHQub3B0aW9uc1xuICAgICk7XG5cbiAgICB0aGlzLl9hY3RpdmUgPSB7XG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgIHByb3ZpZGVyOiBwcm92aWRlclxuICAgIH07XG5cbiAgICBpZiAoY29udGV4dC5vcHRpb25zICYmIGNvbnRleHQub3B0aW9ucy5yZXNpemFibGUpIHtcbiAgICAgIHRoaXMucmVzaXphYmxlID0gdHJ1ZTtcbiAgICB9XG5cbiAgICB0aGlzLl9maXJlKCdhY3RpdmF0ZScpO1xuICB9XG5cbiAgcmV0dXJuICEhY29udGV4dDtcbn07XG4iLCJpbXBvcnQge1xuICBhc3NpZ24sXG4gIGJpbmQsXG4gIHBpY2tcbn0gZnJvbSAnbWluLWRhc2gnO1xuXG5pbXBvcnQge1xuICBkb21pZnksXG4gIHF1ZXJ5IGFzIGRvbVF1ZXJ5LFxuICBldmVudCBhcyBkb21FdmVudCxcbiAgcmVtb3ZlIGFzIGRvbVJlbW92ZVxufSBmcm9tICdtaW4tZG9tJztcblxudmFyIG1pbiA9IE1hdGgubWluLFxuICAgIG1heCA9IE1hdGgubWF4O1xuXG5mdW5jdGlvbiBwcmV2ZW50RGVmYXVsdChlKSB7XG4gIGUucHJldmVudERlZmF1bHQoKTtcbn1cblxuZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKGUpIHtcbiAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbn1cblxuZnVuY3Rpb24gaXNUZXh0Tm9kZShub2RlKSB7XG4gIHJldHVybiBub2RlLm5vZGVUeXBlID09PSBOb2RlLlRFWFRfTk9ERTtcbn1cblxuZnVuY3Rpb24gdG9BcnJheShub2RlTGlzdCkge1xuICByZXR1cm4gW10uc2xpY2UuY2FsbChub2RlTGlzdCk7XG59XG5cbi8qKlxuICogSW5pdGlhbGl6ZXMgYSBjb250YWluZXIgZm9yIGEgY29udGVudCBlZGl0YWJsZSBkaXYuXG4gKlxuICogU3RydWN0dXJlOlxuICpcbiAqIGNvbnRhaW5lclxuICogICBwYXJlbnRcbiAqICAgICBjb250ZW50XG4gKiAgICAgcmVzaXplLWhhbmRsZVxuICpcbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0ge0RPTUVsZW1lbnR9IG9wdGlvbnMuY29udGFpbmVyIFRoZSBET00gZWxlbWVudCB0byBhcHBlbmQgdGhlIGNvbnRlbnRDb250YWluZXIgdG9cbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdGlvbnMua2V5SGFuZGxlciBIYW5kbGVyIGZvciBrZXkgZXZlbnRzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcHRpb25zLnJlc2l6ZUhhbmRsZXIgSGFuZGxlciBmb3IgcmVzaXplIGV2ZW50c1xuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBUZXh0Qm94KG9wdGlvbnMpIHtcbiAgdGhpcy5jb250YWluZXIgPSBvcHRpb25zLmNvbnRhaW5lcjtcblxuICB0aGlzLnBhcmVudCA9IGRvbWlmeShcbiAgICAnPGRpdiBjbGFzcz1cImRqcy1kaXJlY3QtZWRpdGluZy1wYXJlbnRcIj4nICtcbiAgICAgICc8ZGl2IGNsYXNzPVwiZGpzLWRpcmVjdC1lZGl0aW5nLWNvbnRlbnRcIiBjb250ZW50ZWRpdGFibGU9XCJ0cnVlXCI+PC9kaXY+JyArXG4gICAgJzwvZGl2PidcbiAgKTtcblxuICB0aGlzLmNvbnRlbnQgPSBkb21RdWVyeSgnW2NvbnRlbnRlZGl0YWJsZV0nLCB0aGlzLnBhcmVudCk7XG5cbiAgdGhpcy5rZXlIYW5kbGVyID0gb3B0aW9ucy5rZXlIYW5kbGVyIHx8IGZ1bmN0aW9uKCkge307XG4gIHRoaXMucmVzaXplSGFuZGxlciA9IG9wdGlvbnMucmVzaXplSGFuZGxlciB8fCBmdW5jdGlvbigpIHt9O1xuXG4gIHRoaXMuYXV0b1Jlc2l6ZSA9IGJpbmQodGhpcy5hdXRvUmVzaXplLCB0aGlzKTtcbiAgdGhpcy5oYW5kbGVQYXN0ZSA9IGJpbmQodGhpcy5oYW5kbGVQYXN0ZSwgdGhpcyk7XG59XG5cblxuLyoqXG4gKiBDcmVhdGUgYSB0ZXh0IGJveCB3aXRoIHRoZSBnaXZlbiBwb3NpdGlvbiwgc2l6ZSwgc3R5bGUgYW5kIHRleHQgY29udGVudFxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBib3VuZHNcbiAqIEBwYXJhbSB7TnVtYmVyfSBib3VuZHMueCBhYnNvbHV0ZSB4IHBvc2l0aW9uXG4gKiBAcGFyYW0ge051bWJlcn0gYm91bmRzLnkgYWJzb2x1dGUgeSBwb3NpdGlvblxuICogQHBhcmFtIHtOdW1iZXJ9IFtib3VuZHMud2lkdGhdIGZpeGVkIHdpZHRoIHZhbHVlXG4gKiBAcGFyYW0ge051bWJlcn0gW2JvdW5kcy5oZWlnaHRdIGZpeGVkIGhlaWdodCB2YWx1ZVxuICogQHBhcmFtIHtOdW1iZXJ9IFtib3VuZHMubWF4V2lkdGhdIG1heGltdW0gd2lkdGggdmFsdWVcbiAqIEBwYXJhbSB7TnVtYmVyfSBbYm91bmRzLm1heEhlaWdodF0gbWF4aW11bSBoZWlnaHQgdmFsdWVcbiAqIEBwYXJhbSB7TnVtYmVyfSBbYm91bmRzLm1pbldpZHRoXSBtaW5pbXVtIHdpZHRoIHZhbHVlXG4gKiBAcGFyYW0ge051bWJlcn0gW2JvdW5kcy5taW5IZWlnaHRdIG1pbmltdW0gaGVpZ2h0IHZhbHVlXG4gKiBAcGFyYW0ge09iamVjdH0gW3N0eWxlXVxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlIHRleHQgY29udGVudFxuICpcbiAqIEByZXR1cm4ge0RPTUVsZW1lbnR9IFRoZSBjcmVhdGVkIGNvbnRlbnQgRE9NIGVsZW1lbnRcbiAqL1xuVGV4dEJveC5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24oYm91bmRzLCBzdHlsZSwgdmFsdWUsIG9wdGlvbnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudCxcbiAgICAgIGNvbnRlbnQgPSB0aGlzLmNvbnRlbnQsXG4gICAgICBjb250YWluZXIgPSB0aGlzLmNvbnRhaW5lcjtcblxuICBvcHRpb25zID0gdGhpcy5vcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICBzdHlsZSA9IHRoaXMuc3R5bGUgPSBzdHlsZSB8fCB7fTtcblxuICB2YXIgcGFyZW50U3R5bGUgPSBwaWNrKHN0eWxlLCBbXG4gICAgJ3dpZHRoJyxcbiAgICAnaGVpZ2h0JyxcbiAgICAnbWF4V2lkdGgnLFxuICAgICdtYXhIZWlnaHQnLFxuICAgICdtaW5XaWR0aCcsXG4gICAgJ21pbkhlaWdodCcsXG4gICAgJ2xlZnQnLFxuICAgICd0b3AnLFxuICAgICdiYWNrZ3JvdW5kQ29sb3InLFxuICAgICdwb3NpdGlvbicsXG4gICAgJ292ZXJmbG93JyxcbiAgICAnYm9yZGVyJyxcbiAgICAnd29yZFdyYXAnLFxuICAgICd0ZXh0QWxpZ24nLFxuICAgICdvdXRsaW5lJyxcbiAgICAndHJhbnNmb3JtJ1xuICBdKTtcblxuICBhc3NpZ24ocGFyZW50LnN0eWxlLCB7XG4gICAgd2lkdGg6IGJvdW5kcy53aWR0aCArICdweCcsXG4gICAgaGVpZ2h0OiBib3VuZHMuaGVpZ2h0ICsgJ3B4JyxcbiAgICBtYXhXaWR0aDogYm91bmRzLm1heFdpZHRoICsgJ3B4JyxcbiAgICBtYXhIZWlnaHQ6IGJvdW5kcy5tYXhIZWlnaHQgKyAncHgnLFxuICAgIG1pbldpZHRoOiBib3VuZHMubWluV2lkdGggKyAncHgnLFxuICAgIG1pbkhlaWdodDogYm91bmRzLm1pbkhlaWdodCArICdweCcsXG4gICAgbGVmdDogYm91bmRzLnggKyAncHgnLFxuICAgIHRvcDogYm91bmRzLnkgKyAncHgnLFxuICAgIGJhY2tncm91bmRDb2xvcjogJyNmZmZmZmYnLFxuICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgIG92ZXJmbG93OiAndmlzaWJsZScsXG4gICAgYm9yZGVyOiAnMXB4IHNvbGlkICNjY2MnLFxuICAgIGJveFNpemluZzogJ2JvcmRlci1ib3gnLFxuICAgIHdvcmRXcmFwOiAnbm9ybWFsJyxcbiAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgIG91dGxpbmU6ICdub25lJ1xuICB9LCBwYXJlbnRTdHlsZSk7XG5cbiAgdmFyIGNvbnRlbnRTdHlsZSA9IHBpY2soc3R5bGUsIFtcbiAgICAnZm9udEZhbWlseScsXG4gICAgJ2ZvbnRTaXplJyxcbiAgICAnZm9udFdlaWdodCcsXG4gICAgJ2xpbmVIZWlnaHQnLFxuICAgICdwYWRkaW5nJyxcbiAgICAncGFkZGluZ1RvcCcsXG4gICAgJ3BhZGRpbmdSaWdodCcsXG4gICAgJ3BhZGRpbmdCb3R0b20nLFxuICAgICdwYWRkaW5nTGVmdCdcbiAgXSk7XG5cbiAgYXNzaWduKGNvbnRlbnQuc3R5bGUsIHtcbiAgICBib3hTaXppbmc6ICdib3JkZXItYm94JyxcbiAgICB3aWR0aDogJzEwMCUnLFxuICAgIG91dGxpbmU6ICdub25lJyxcbiAgICB3b3JkV3JhcDogJ2JyZWFrLXdvcmQnXG4gIH0sIGNvbnRlbnRTdHlsZSk7XG5cbiAgaWYgKG9wdGlvbnMuY2VudGVyVmVydGljYWxseSkge1xuICAgIGFzc2lnbihjb250ZW50LnN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIHRvcDogJzUwJScsXG4gICAgICB0cmFuc2Zvcm06ICd0cmFuc2xhdGUoMCwgLTUwJSknXG4gICAgfSwgY29udGVudFN0eWxlKTtcbiAgfVxuXG4gIGNvbnRlbnQuaW5uZXJUZXh0ID0gdmFsdWU7XG5cbiAgZG9tRXZlbnQuYmluZChjb250ZW50LCAna2V5ZG93bicsIHRoaXMua2V5SGFuZGxlcik7XG4gIGRvbUV2ZW50LmJpbmQoY29udGVudCwgJ21vdXNlZG93bicsIHN0b3BQcm9wYWdhdGlvbik7XG4gIGRvbUV2ZW50LmJpbmQoY29udGVudCwgJ3Bhc3RlJywgc2VsZi5oYW5kbGVQYXN0ZSk7XG5cbiAgaWYgKG9wdGlvbnMuYXV0b1Jlc2l6ZSkge1xuICAgIGRvbUV2ZW50LmJpbmQoY29udGVudCwgJ2lucHV0JywgdGhpcy5hdXRvUmVzaXplKTtcbiAgfVxuXG4gIGlmIChvcHRpb25zLnJlc2l6YWJsZSkge1xuICAgIHRoaXMucmVzaXphYmxlKHN0eWxlKTtcbiAgfVxuXG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChwYXJlbnQpO1xuXG4gIC8vIHNldCBzZWxlY3Rpb24gdG8gZW5kIG9mIHRleHRcbiAgdGhpcy5zZXRTZWxlY3Rpb24oY29udGVudC5sYXN0Q2hpbGQsIGNvbnRlbnQubGFzdENoaWxkICYmIGNvbnRlbnQubGFzdENoaWxkLmxlbmd0aCk7XG5cbiAgcmV0dXJuIHBhcmVudDtcbn07XG5cbi8qKlxuICogSW50ZXJjZXB0IHBhc3RlIGV2ZW50cyB0byByZW1vdmUgZm9ybWF0dGluZyBmcm9tIHBhc3RlZCB0ZXh0LlxuICovXG5UZXh0Qm94LnByb3RvdHlwZS5oYW5kbGVQYXN0ZSA9IGZ1bmN0aW9uKGUpIHtcbiAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnMsXG4gICAgICBzdHlsZSA9IHRoaXMuc3R5bGU7XG5cbiAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gIHZhciB0ZXh0O1xuXG4gIGlmIChlLmNsaXBib2FyZERhdGEpIHtcblxuICAgIC8vIENocm9tZSwgRmlyZWZveCwgU2FmYXJpXG4gICAgdGV4dCA9IGUuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCd0ZXh0L3BsYWluJyk7XG4gIH0gZWxzZSB7XG5cbiAgICAvLyBJbnRlcm5ldCBFeHBsb3JlclxuICAgIHRleHQgPSB3aW5kb3cuY2xpcGJvYXJkRGF0YS5nZXREYXRhKCdUZXh0Jyk7XG4gIH1cblxuICB0aGlzLmluc2VydFRleHQodGV4dCk7XG5cbiAgaWYgKG9wdGlvbnMuYXV0b1Jlc2l6ZSkge1xuICAgIHZhciBoYXNSZXNpemVkID0gdGhpcy5hdXRvUmVzaXplKHN0eWxlKTtcblxuICAgIGlmIChoYXNSZXNpemVkKSB7XG4gICAgICB0aGlzLnJlc2l6ZUhhbmRsZXIoaGFzUmVzaXplZCk7XG4gICAgfVxuICB9XG59O1xuXG5UZXh0Qm94LnByb3RvdHlwZS5pbnNlcnRUZXh0ID0gZnVuY3Rpb24odGV4dCkge1xuXG4gIC8vIGluc2VydFRleHQgY29tbWFuZCBub3Qgc3VwcG9ydGVkIGJ5IEludGVybmV0IEV4cGxvcmVyXG4gIHZhciBzdWNjZXNzID0gZG9jdW1lbnQuZXhlY0NvbW1hbmQoJ2luc2VydFRleHQnLCBmYWxzZSwgdGV4dCk7XG5cbiAgaWYgKHN1Y2Nlc3MpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB0aGlzLl9pbnNlcnRUZXh0SUUodGV4dCk7XG59O1xuXG5UZXh0Qm94LnByb3RvdHlwZS5faW5zZXJ0VGV4dElFID0gZnVuY3Rpb24odGV4dCkge1xuXG4gIC8vIEludGVybmV0IEV4cGxvcmVyXG4gIHZhciByYW5nZSA9IHRoaXMuZ2V0U2VsZWN0aW9uKCksXG4gICAgICBzdGFydENvbnRhaW5lciA9IHJhbmdlLnN0YXJ0Q29udGFpbmVyLFxuICAgICAgZW5kQ29udGFpbmVyID0gcmFuZ2UuZW5kQ29udGFpbmVyLFxuICAgICAgc3RhcnRPZmZzZXQgPSByYW5nZS5zdGFydE9mZnNldCxcbiAgICAgIGVuZE9mZnNldCA9IHJhbmdlLmVuZE9mZnNldCxcbiAgICAgIGNvbW1vbkFuY2VzdG9yQ29udGFpbmVyID0gcmFuZ2UuY29tbW9uQW5jZXN0b3JDb250YWluZXI7XG5cbiAgdmFyIGNoaWxkTm9kZXNBcnJheSA9IHRvQXJyYXkoY29tbW9uQW5jZXN0b3JDb250YWluZXIuY2hpbGROb2Rlcyk7XG5cbiAgdmFyIGNvbnRhaW5lcixcbiAgICAgIG9mZnNldDtcblxuICBpZiAoaXNUZXh0Tm9kZShjb21tb25BbmNlc3RvckNvbnRhaW5lcikpIHtcbiAgICB2YXIgY29udGFpbmVyVGV4dENvbnRlbnQgPSBzdGFydENvbnRhaW5lci50ZXh0Q29udGVudDtcblxuICAgIHN0YXJ0Q29udGFpbmVyLnRleHRDb250ZW50ID1cbiAgICAgIGNvbnRhaW5lclRleHRDb250ZW50LnN1YnN0cmluZygwLCBzdGFydE9mZnNldClcbiAgICAgICsgdGV4dFxuICAgICAgKyBjb250YWluZXJUZXh0Q29udGVudC5zdWJzdHJpbmcoZW5kT2Zmc2V0KTtcblxuICAgIGNvbnRhaW5lciA9IHN0YXJ0Q29udGFpbmVyO1xuICAgIG9mZnNldCA9IHN0YXJ0T2Zmc2V0ICsgdGV4dC5sZW5ndGg7XG5cbiAgfSBlbHNlIGlmIChzdGFydENvbnRhaW5lciA9PT0gdGhpcy5jb250ZW50ICYmIGVuZENvbnRhaW5lciA9PT0gdGhpcy5jb250ZW50KSB7XG4gICAgdmFyIHRleHROb2RlID0gZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodGV4dCk7XG5cbiAgICB0aGlzLmNvbnRlbnQuaW5zZXJ0QmVmb3JlKHRleHROb2RlLCBjaGlsZE5vZGVzQXJyYXlbc3RhcnRPZmZzZXRdKTtcblxuICAgIGNvbnRhaW5lciA9IHRleHROb2RlO1xuICAgIG9mZnNldCA9IHRleHROb2RlLnRleHRDb250ZW50Lmxlbmd0aDtcbiAgfSBlbHNlIHtcbiAgICB2YXIgc3RhcnRDb250YWluZXJDaGlsZEluZGV4ID0gY2hpbGROb2Rlc0FycmF5LmluZGV4T2Yoc3RhcnRDb250YWluZXIpLFxuICAgICAgICBlbmRDb250YWluZXJDaGlsZEluZGV4ID0gY2hpbGROb2Rlc0FycmF5LmluZGV4T2YoZW5kQ29udGFpbmVyKTtcblxuICAgIGNoaWxkTm9kZXNBcnJheS5mb3JFYWNoKGZ1bmN0aW9uKGNoaWxkTm9kZSwgaW5kZXgpIHtcblxuICAgICAgaWYgKGluZGV4ID09PSBzdGFydENvbnRhaW5lckNoaWxkSW5kZXgpIHtcbiAgICAgICAgY2hpbGROb2RlLnRleHRDb250ZW50ID1cbiAgICAgICAgICBzdGFydENvbnRhaW5lci50ZXh0Q29udGVudC5zdWJzdHJpbmcoMCwgc3RhcnRPZmZzZXQpICtcbiAgICAgICAgICB0ZXh0ICtcbiAgICAgICAgICBlbmRDb250YWluZXIudGV4dENvbnRlbnQuc3Vic3RyaW5nKGVuZE9mZnNldCk7XG4gICAgICB9IGVsc2UgaWYgKGluZGV4ID4gc3RhcnRDb250YWluZXJDaGlsZEluZGV4ICYmIGluZGV4IDw9IGVuZENvbnRhaW5lckNoaWxkSW5kZXgpIHtcbiAgICAgICAgZG9tUmVtb3ZlKGNoaWxkTm9kZSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjb250YWluZXIgPSBzdGFydENvbnRhaW5lcjtcbiAgICBvZmZzZXQgPSBzdGFydE9mZnNldCArIHRleHQubGVuZ3RoO1xuICB9XG5cbiAgaWYgKGNvbnRhaW5lciAmJiBvZmZzZXQgIT09IHVuZGVmaW5lZCkge1xuXG4gICAgLy8gaXMgbmVjZXNzYXJ5IGluIEludGVybmV0IEV4cGxvcmVyXG4gICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIHNlbGYuc2V0U2VsZWN0aW9uKGNvbnRhaW5lciwgb2Zmc2V0KTtcbiAgICB9KTtcbiAgfVxufTtcblxuLyoqXG4gKiBBdXRvbWF0aWNhbGx5IHJlc2l6ZSBlbGVtZW50IHZlcnRpY2FsbHkgdG8gZml0IGl0cyBjb250ZW50LlxuICovXG5UZXh0Qm94LnByb3RvdHlwZS5hdXRvUmVzaXplID0gZnVuY3Rpb24oKSB7XG4gIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudCxcbiAgICAgIGNvbnRlbnQgPSB0aGlzLmNvbnRlbnQ7XG5cbiAgdmFyIGZvbnRTaXplID0gcGFyc2VJbnQodGhpcy5zdHlsZS5mb250U2l6ZSkgfHwgMTI7XG5cbiAgaWYgKGNvbnRlbnQuc2Nyb2xsSGVpZ2h0ID4gcGFyZW50Lm9mZnNldEhlaWdodCB8fFxuICAgICAgY29udGVudC5zY3JvbGxIZWlnaHQgPCBwYXJlbnQub2Zmc2V0SGVpZ2h0IC0gZm9udFNpemUpIHtcbiAgICB2YXIgYm91bmRzID0gcGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgdmFyIGhlaWdodCA9IGNvbnRlbnQuc2Nyb2xsSGVpZ2h0O1xuICAgIHBhcmVudC5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyAncHgnO1xuXG4gICAgdGhpcy5yZXNpemVIYW5kbGVyKHtcbiAgICAgIHdpZHRoOiBib3VuZHMud2lkdGgsXG4gICAgICBoZWlnaHQ6IGJvdW5kcy5oZWlnaHQsXG4gICAgICBkeDogMCxcbiAgICAgIGR5OiBoZWlnaHQgLSBib3VuZHMuaGVpZ2h0XG4gICAgfSk7XG4gIH1cbn07XG5cbi8qKlxuICogTWFrZSBhbiBlbGVtZW50IHJlc2l6YWJsZSBieSBhZGRpbmcgYSByZXNpemUgaGFuZGxlLlxuICovXG5UZXh0Qm94LnByb3RvdHlwZS5yZXNpemFibGUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudCxcbiAgICAgIHJlc2l6ZUhhbmRsZSA9IHRoaXMucmVzaXplSGFuZGxlO1xuXG4gIHZhciBtaW5XaWR0aCA9IHBhcnNlSW50KHRoaXMuc3R5bGUubWluV2lkdGgpIHx8IDAsXG4gICAgICBtaW5IZWlnaHQgPSBwYXJzZUludCh0aGlzLnN0eWxlLm1pbkhlaWdodCkgfHwgMCxcbiAgICAgIG1heFdpZHRoID0gcGFyc2VJbnQodGhpcy5zdHlsZS5tYXhXaWR0aCkgfHwgSW5maW5pdHksXG4gICAgICBtYXhIZWlnaHQgPSBwYXJzZUludCh0aGlzLnN0eWxlLm1heEhlaWdodCkgfHwgSW5maW5pdHk7XG5cbiAgaWYgKCFyZXNpemVIYW5kbGUpIHtcbiAgICByZXNpemVIYW5kbGUgPSB0aGlzLnJlc2l6ZUhhbmRsZSA9IGRvbWlmeShcbiAgICAgICc8ZGl2IGNsYXNzPVwiZGpzLWRpcmVjdC1lZGl0aW5nLXJlc2l6ZS1oYW5kbGVcIj48L2Rpdj4nXG4gICAgKTtcblxuICAgIHZhciBzdGFydFgsIHN0YXJ0WSwgc3RhcnRXaWR0aCwgc3RhcnRIZWlnaHQ7XG5cbiAgICB2YXIgb25Nb3VzZURvd24gPSBmdW5jdGlvbihlKSB7XG4gICAgICBwcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIHN0b3BQcm9wYWdhdGlvbihlKTtcblxuICAgICAgc3RhcnRYID0gZS5jbGllbnRYO1xuICAgICAgc3RhcnRZID0gZS5jbGllbnRZO1xuXG4gICAgICB2YXIgYm91bmRzID0gcGFyZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgICBzdGFydFdpZHRoID0gYm91bmRzLndpZHRoO1xuICAgICAgc3RhcnRIZWlnaHQgPSBib3VuZHMuaGVpZ2h0O1xuXG4gICAgICBkb21FdmVudC5iaW5kKGRvY3VtZW50LCAnbW91c2Vtb3ZlJywgb25Nb3VzZU1vdmUpO1xuICAgICAgZG9tRXZlbnQuYmluZChkb2N1bWVudCwgJ21vdXNldXAnLCBvbk1vdXNlVXApO1xuICAgIH07XG5cbiAgICB2YXIgb25Nb3VzZU1vdmUgPSBmdW5jdGlvbihlKSB7XG4gICAgICBwcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIHN0b3BQcm9wYWdhdGlvbihlKTtcblxuICAgICAgdmFyIG5ld1dpZHRoID0gbWluKG1heChzdGFydFdpZHRoICsgZS5jbGllbnRYIC0gc3RhcnRYLCBtaW5XaWR0aCksIG1heFdpZHRoKTtcbiAgICAgIHZhciBuZXdIZWlnaHQgPSBtaW4obWF4KHN0YXJ0SGVpZ2h0ICsgZS5jbGllbnRZIC0gc3RhcnRZLCBtaW5IZWlnaHQpLCBtYXhIZWlnaHQpO1xuXG4gICAgICBwYXJlbnQuc3R5bGUud2lkdGggPSBuZXdXaWR0aCArICdweCc7XG4gICAgICBwYXJlbnQuc3R5bGUuaGVpZ2h0ID0gbmV3SGVpZ2h0ICsgJ3B4JztcblxuICAgICAgc2VsZi5yZXNpemVIYW5kbGVyKHtcbiAgICAgICAgd2lkdGg6IHN0YXJ0V2lkdGgsXG4gICAgICAgIGhlaWdodDogc3RhcnRIZWlnaHQsXG4gICAgICAgIGR4OiBlLmNsaWVudFggLSBzdGFydFgsXG4gICAgICAgIGR5OiBlLmNsaWVudFkgLSBzdGFydFlcbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICB2YXIgb25Nb3VzZVVwID0gZnVuY3Rpb24oZSkge1xuICAgICAgcHJldmVudERlZmF1bHQoZSk7XG4gICAgICBzdG9wUHJvcGFnYXRpb24oZSk7XG5cbiAgICAgIGRvbUV2ZW50LnVuYmluZChkb2N1bWVudCwnbW91c2Vtb3ZlJywgb25Nb3VzZU1vdmUsIGZhbHNlKTtcbiAgICAgIGRvbUV2ZW50LnVuYmluZChkb2N1bWVudCwgJ21vdXNldXAnLCBvbk1vdXNlVXAsIGZhbHNlKTtcbiAgICB9O1xuXG4gICAgZG9tRXZlbnQuYmluZChyZXNpemVIYW5kbGUsICdtb3VzZWRvd24nLCBvbk1vdXNlRG93bik7XG4gIH1cblxuICBhc3NpZ24ocmVzaXplSGFuZGxlLnN0eWxlLCB7XG4gICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgYm90dG9tOiAnMHB4JyxcbiAgICByaWdodDogJzBweCcsXG4gICAgY3Vyc29yOiAnbndzZS1yZXNpemUnLFxuICAgIHdpZHRoOiAnMCcsXG4gICAgaGVpZ2h0OiAnMCcsXG4gICAgYm9yZGVyVG9wOiAocGFyc2VJbnQodGhpcy5zdHlsZS5mb250U2l6ZSkgLyA0IHx8IDMpICsgJ3B4IHNvbGlkIHRyYW5zcGFyZW50JyxcbiAgICBib3JkZXJSaWdodDogKHBhcnNlSW50KHRoaXMuc3R5bGUuZm9udFNpemUpIC8gNCB8fCAzKSArICdweCBzb2xpZCAjY2NjJyxcbiAgICBib3JkZXJCb3R0b206IChwYXJzZUludCh0aGlzLnN0eWxlLmZvbnRTaXplKSAvIDQgfHwgMykgKyAncHggc29saWQgI2NjYycsXG4gICAgYm9yZGVyTGVmdDogKHBhcnNlSW50KHRoaXMuc3R5bGUuZm9udFNpemUpIC8gNCB8fCAzKSArICdweCBzb2xpZCB0cmFuc3BhcmVudCdcbiAgfSk7XG5cbiAgcGFyZW50LmFwcGVuZENoaWxkKHJlc2l6ZUhhbmRsZSk7XG59O1xuXG5cbi8qKlxuICogQ2xlYXIgY29udGVudCBhbmQgc3R5bGUgb2YgdGhlIHRleHRib3gsIHVuYmluZCBsaXN0ZW5lcnMgYW5kXG4gKiByZXNldCBDU1Mgc3R5bGUuXG4gKi9cblRleHRCb3gucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHBhcmVudCA9IHRoaXMucGFyZW50LFxuICAgICAgY29udGVudCA9IHRoaXMuY29udGVudCxcbiAgICAgIHJlc2l6ZUhhbmRsZSA9IHRoaXMucmVzaXplSGFuZGxlO1xuXG4gIC8vIGNsZWFyIGNvbnRlbnRcbiAgY29udGVudC5pbm5lclRleHQgPSAnJztcblxuICAvLyBjbGVhciBzdHlsZXNcbiAgcGFyZW50LnJlbW92ZUF0dHJpYnV0ZSgnc3R5bGUnKTtcbiAgY29udGVudC5yZW1vdmVBdHRyaWJ1dGUoJ3N0eWxlJyk7XG5cbiAgZG9tRXZlbnQudW5iaW5kKGNvbnRlbnQsICdrZXlkb3duJywgdGhpcy5rZXlIYW5kbGVyKTtcbiAgZG9tRXZlbnQudW5iaW5kKGNvbnRlbnQsICdtb3VzZWRvd24nLCBzdG9wUHJvcGFnYXRpb24pO1xuICBkb21FdmVudC51bmJpbmQoY29udGVudCwgJ2lucHV0JywgdGhpcy5hdXRvUmVzaXplKTtcbiAgZG9tRXZlbnQudW5iaW5kKGNvbnRlbnQsICdwYXN0ZScsIHRoaXMuaGFuZGxlUGFzdGUpO1xuXG4gIGlmIChyZXNpemVIYW5kbGUpIHtcbiAgICByZXNpemVIYW5kbGUucmVtb3ZlQXR0cmlidXRlKCdzdHlsZScpO1xuXG4gICAgZG9tUmVtb3ZlKHJlc2l6ZUhhbmRsZSk7XG4gIH1cblxuICBkb21SZW1vdmUocGFyZW50KTtcbn07XG5cblxuVGV4dEJveC5wcm90b3R5cGUuZ2V0VmFsdWUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuY29udGVudC5pbm5lclRleHQudHJpbSgpO1xufTtcblxuXG5UZXh0Qm94LnByb3RvdHlwZS5nZXRTZWxlY3Rpb24gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKSxcbiAgICAgIHJhbmdlID0gc2VsZWN0aW9uLmdldFJhbmdlQXQoMCk7XG5cbiAgcmV0dXJuIHJhbmdlO1xufTtcblxuXG5UZXh0Qm94LnByb3RvdHlwZS5zZXRTZWxlY3Rpb24gPSBmdW5jdGlvbihjb250YWluZXIsIG9mZnNldCkge1xuICB2YXIgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuXG4gIGlmIChjb250YWluZXIgPT09IG51bGwpIHtcbiAgICByYW5nZS5zZWxlY3ROb2RlQ29udGVudHModGhpcy5jb250ZW50KTtcbiAgfSBlbHNlIHtcbiAgICByYW5nZS5zZXRTdGFydChjb250YWluZXIsIG9mZnNldCk7XG4gICAgcmFuZ2Uuc2V0RW5kKGNvbnRhaW5lciwgb2Zmc2V0KTtcbiAgfVxuXG4gIHZhciBzZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uKCk7XG5cbiAgc2VsZWN0aW9uLnJlbW92ZUFsbFJhbmdlcygpO1xuICBzZWxlY3Rpb24uYWRkUmFuZ2UocmFuZ2UpO1xufTtcbiIsImltcG9ydCB7XG4gIGZvckVhY2gsXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCB7XG4gIGRlbGVnYXRlIGFzIGRvbURlbGVnYXRlLFxuICBxdWVyeSBhcyBkb21RdWVyeSxcbiAgcXVlcnlBbGwgYXMgZG9tUXVlcnlBbGxcbn0gZnJvbSAnbWluLWRvbSc7XG5cbmltcG9ydCB7IGlzUHJpbWFyeUJ1dHRvbiB9IGZyb20gJy4uLy4uL3V0aWwvTW91c2UnO1xuXG5pbXBvcnQge1xuICBhcHBlbmQgYXMgc3ZnQXBwZW5kLFxuICBhdHRyIGFzIHN2Z0F0dHIsXG4gIGNyZWF0ZSBhcyBzdmdDcmVhdGUsXG4gIHJlbW92ZSBhcyBzdmdSZW1vdmVcbn0gZnJvbSAndGlueS1zdmcnO1xuXG5pbXBvcnQge1xuICBjcmVhdGVMaW5lLFxuICB1cGRhdGVMaW5lXG59IGZyb20gJy4uLy4uL3V0aWwvUmVuZGVyVXRpbCc7XG5cbmZ1bmN0aW9uIGFsbG93QWxsKGUpIHsgcmV0dXJuIHRydWU7IH1cblxudmFyIExPV19QUklPUklUWSA9IDUwMDtcblxuXG4vKipcbiAqIEEgcGx1Z2luIHRoYXQgcHJvdmlkZXMgaW50ZXJhY3Rpb24gZXZlbnRzIGZvciBkaWFncmFtIGVsZW1lbnRzLlxuICpcbiAqIEl0IGVtaXRzIHRoZSBmb2xsb3dpbmcgZXZlbnRzOlxuICpcbiAqICAgKiBlbGVtZW50LmNsaWNrXG4gKiAgICogZWxlbWVudC5jb250ZXh0bWVudVxuICogICAqIGVsZW1lbnQuZGJsY2xpY2tcbiAqICAgKiBlbGVtZW50LmhvdmVyXG4gKiAgICogZWxlbWVudC5tb3VzZWRvd25cbiAqICAgKiBlbGVtZW50Lm1vdXNlbW92ZVxuICogICAqIGVsZW1lbnQubW91c2V1cFxuICogICAqIGVsZW1lbnQub3V0XG4gKlxuICogRWFjaCBldmVudCBpcyBhIHR1cGxlIHsgZWxlbWVudCwgZ2Z4LCBvcmlnaW5hbEV2ZW50IH0uXG4gKlxuICogQ2FuY2VsaW5nIHRoZSBldmVudCB2aWEgRXZlbnQjcHJldmVudERlZmF1bHQoKVxuICogcHJldmVudHMgdGhlIG9yaWdpbmFsIERPTSBvcGVyYXRpb24uXG4gKlxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gSW50ZXJhY3Rpb25FdmVudHMoZXZlbnRCdXMsIGVsZW1lbnRSZWdpc3RyeSwgc3R5bGVzKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIC8qKlxuICAgKiBGaXJlIGFuIGludGVyYWN0aW9uIGV2ZW50LlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSBsb2NhbCBldmVudCBuYW1lLCBlLmcuIGVsZW1lbnQuY2xpY2suXG4gICAqIEBwYXJhbSB7RE9NRXZlbnR9IGV2ZW50IG5hdGl2ZSBldmVudFxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBbZWxlbWVudF0gdGhlIGRpYWdyYW0gZWxlbWVudCB0byBlbWl0IHRoZSBldmVudCBvbjtcbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRzIHRvIHRoZSBldmVudCB0YXJnZXRcbiAgICovXG4gIGZ1bmN0aW9uIGZpcmUodHlwZSwgZXZlbnQsIGVsZW1lbnQpIHtcblxuICAgIGlmIChpc0lnbm9yZWQodHlwZSwgZXZlbnQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdmFyIHRhcmdldCwgZ2Z4LCByZXR1cm5WYWx1ZTtcblxuICAgIGlmICghZWxlbWVudCkge1xuICAgICAgdGFyZ2V0ID0gZXZlbnQuZGVsZWdhdGVUYXJnZXQgfHwgZXZlbnQudGFyZ2V0O1xuXG4gICAgICBpZiAodGFyZ2V0KSB7XG4gICAgICAgIGdmeCA9IHRhcmdldDtcbiAgICAgICAgZWxlbWVudCA9IGVsZW1lbnRSZWdpc3RyeS5nZXQoZ2Z4KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZ2Z4ID0gZWxlbWVudFJlZ2lzdHJ5LmdldEdyYXBoaWNzKGVsZW1lbnQpO1xuICAgIH1cblxuICAgIGlmICghZ2Z4IHx8ICFlbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuVmFsdWUgPSBldmVudEJ1cy5maXJlKHR5cGUsIHtcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXG4gICAgICBnZng6IGdmeCxcbiAgICAgIG9yaWdpbmFsRXZlbnQ6IGV2ZW50XG4gICAgfSk7XG5cbiAgICBpZiAocmV0dXJuVmFsdWUgPT09IGZhbHNlKSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICB9XG5cbiAgLy8gVE9ETyhuaWtrdSk6IGRvY3VtZW50IHRoaXNcbiAgdmFyIGhhbmRsZXJzID0ge307XG5cbiAgZnVuY3Rpb24gbW91c2VIYW5kbGVyKGxvY2FsRXZlbnROYW1lKSB7XG4gICAgcmV0dXJuIGhhbmRsZXJzW2xvY2FsRXZlbnROYW1lXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGlzSWdub3JlZChsb2NhbEV2ZW50TmFtZSwgZXZlbnQpIHtcblxuICAgIHZhciBmaWx0ZXIgPSBpZ25vcmVkRmlsdGVyc1tsb2NhbEV2ZW50TmFtZV0gfHwgaXNQcmltYXJ5QnV0dG9uO1xuXG4gICAgLy8gb25seSByZWFjdCBvbiBsZWZ0IG1vdXNlIGJ1dHRvbiBpbnRlcmFjdGlvbnNcbiAgICAvLyBleGNlcHQgZm9yIGludGVyYWN0aW9uIGV2ZW50cyB0aGF0IGFyZSBlbmFibGVkXG4gICAgLy8gZm9yIHNlY3VuZGFyeSBtb3VzZSBidXR0b25cbiAgICByZXR1cm4gIWZpbHRlcihldmVudCk7XG4gIH1cblxuICB2YXIgYmluZGluZ3MgPSB7XG4gICAgY2xpY2s6ICdlbGVtZW50LmNsaWNrJyxcbiAgICBjb250ZXh0bWVudTogJ2VsZW1lbnQuY29udGV4dG1lbnUnLFxuICAgIGRibGNsaWNrOiAnZWxlbWVudC5kYmxjbGljaycsXG4gICAgbW91c2Vkb3duOiAnZWxlbWVudC5tb3VzZWRvd24nLFxuICAgIG1vdXNlbW92ZTogJ2VsZW1lbnQubW91c2Vtb3ZlJyxcbiAgICBtb3VzZW92ZXI6ICdlbGVtZW50LmhvdmVyJyxcbiAgICBtb3VzZW91dDogJ2VsZW1lbnQub3V0JyxcbiAgICBtb3VzZXVwOiAnZWxlbWVudC5tb3VzZXVwJyxcbiAgfTtcblxuICB2YXIgaWdub3JlZEZpbHRlcnMgPSB7XG4gICAgJ2VsZW1lbnQuY29udGV4dG1lbnUnOiBhbGxvd0FsbFxuICB9O1xuXG5cbiAgLy8gbWFudWFsIGV2ZW50IHRyaWdnZXIgLy8vLy8vLy8vL1xuXG4gIC8qKlxuICAgKiBUcmlnZ2VyIGFuIGludGVyYWN0aW9uIGV2ZW50IChiYXNlZCBvbiBhIG5hdGl2ZSBkb20gZXZlbnQpXG4gICAqIG9uIHRoZSB0YXJnZXQgc2hhcGUgb3IgY29ubmVjdGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50TmFtZSB0aGUgbmFtZSBvZiB0aGUgdHJpZ2dlcmVkIERPTSBldmVudFxuICAgKiBAcGFyYW0ge01vdXNlRXZlbnR9IGV2ZW50XG4gICAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IHRhcmdldEVsZW1lbnRcbiAgICovXG4gIGZ1bmN0aW9uIHRyaWdnZXJNb3VzZUV2ZW50KGV2ZW50TmFtZSwgZXZlbnQsIHRhcmdldEVsZW1lbnQpIHtcblxuICAgIC8vIGkuZS4gZWxlbWVudC5tb3VzZWRvd24uLi5cbiAgICB2YXIgbG9jYWxFdmVudE5hbWUgPSBiaW5kaW5nc1tldmVudE5hbWVdO1xuXG4gICAgaWYgKCFsb2NhbEV2ZW50TmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCd1bm1hcHBlZCBET00gZXZlbnQgbmFtZSA8JyArIGV2ZW50TmFtZSArICc+Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZpcmUobG9jYWxFdmVudE5hbWUsIGV2ZW50LCB0YXJnZXRFbGVtZW50KTtcbiAgfVxuXG5cbiAgdmFyIEVMRU1FTlRfU0VMRUNUT1IgPSAnc3ZnLCAuZGpzLWVsZW1lbnQnO1xuXG4gIC8vIGV2ZW50IGhhbmRsaW5nIC8vLy8vLy9cblxuICBmdW5jdGlvbiByZWdpc3RlckV2ZW50KG5vZGUsIGV2ZW50LCBsb2NhbEV2ZW50LCBpZ25vcmVkRmlsdGVyKSB7XG5cbiAgICB2YXIgaGFuZGxlciA9IGhhbmRsZXJzW2xvY2FsRXZlbnRdID0gZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgIGZpcmUobG9jYWxFdmVudCwgZXZlbnQpO1xuICAgIH07XG5cbiAgICBpZiAoaWdub3JlZEZpbHRlcikge1xuICAgICAgaWdub3JlZEZpbHRlcnNbbG9jYWxFdmVudF0gPSBpZ25vcmVkRmlsdGVyO1xuICAgIH1cblxuICAgIGhhbmRsZXIuJGRlbGVnYXRlID0gZG9tRGVsZWdhdGUuYmluZChub2RlLCBFTEVNRU5UX1NFTEVDVE9SLCBldmVudCwgaGFuZGxlcik7XG4gIH1cblxuICBmdW5jdGlvbiB1bnJlZ2lzdGVyRXZlbnQobm9kZSwgZXZlbnQsIGxvY2FsRXZlbnQpIHtcblxuICAgIHZhciBoYW5kbGVyID0gbW91c2VIYW5kbGVyKGxvY2FsRXZlbnQpO1xuXG4gICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZG9tRGVsZWdhdGUudW5iaW5kKG5vZGUsIGV2ZW50LCBoYW5kbGVyLiRkZWxlZ2F0ZSk7XG4gIH1cblxuICBmdW5jdGlvbiByZWdpc3RlckV2ZW50cyhzdmcpIHtcbiAgICBmb3JFYWNoKGJpbmRpbmdzLCBmdW5jdGlvbih2YWwsIGtleSkge1xuICAgICAgcmVnaXN0ZXJFdmVudChzdmcsIGtleSwgdmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHVucmVnaXN0ZXJFdmVudHMoc3ZnKSB7XG4gICAgZm9yRWFjaChiaW5kaW5ncywgZnVuY3Rpb24odmFsLCBrZXkpIHtcbiAgICAgIHVucmVnaXN0ZXJFdmVudChzdmcsIGtleSwgdmFsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGV2ZW50QnVzLm9uKCdjYW52YXMuZGVzdHJveScsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdW5yZWdpc3RlckV2ZW50cyhldmVudC5zdmcpO1xuICB9KTtcblxuICBldmVudEJ1cy5vbignY2FudmFzLmluaXQnLCBmdW5jdGlvbihldmVudCkge1xuICAgIHJlZ2lzdGVyRXZlbnRzKGV2ZW50LnN2Zyk7XG4gIH0pO1xuXG5cbiAgLy8gaGl0IGJveCB1cGRhdGluZyAvLy8vLy8vLy8vLy8vLy8vXG5cbiAgZXZlbnRCdXMub24oWyAnc2hhcGUuYWRkZWQnLCAnY29ubmVjdGlvbi5hZGRlZCcgXSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ2ludGVyYWN0aW9uRXZlbnRzLmNyZWF0ZUhpdCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH0pO1xuXG4gIC8vIFVwZGF0ZSBkanMtaGl0IG9uIGNoYW5nZS5cbiAgLy8gQSBsb3cgcHJpb3J0aXR5IGlzIG5lY2Vzc2FyeSwgYmVjYXVzZSBkanMtaGl0IG9mIGxhYmVscyBoYXMgdG8gYmUgdXBkYXRlZFxuICAvLyBhZnRlciB0aGUgbGFiZWwgYm91bmRzIGhhdmUgYmVlbiB1cGRhdGVkIGluIHRoZSByZW5kZXJlci5cbiAgZXZlbnRCdXMub24oW1xuICAgICdzaGFwZS5jaGFuZ2VkJyxcbiAgICAnY29ubmVjdGlvbi5jaGFuZ2VkJ1xuICBdLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG5cbiAgICB2YXIgZWxlbWVudCA9IGV2ZW50LmVsZW1lbnQsXG4gICAgICAgIGdmeCA9IGV2ZW50LmdmeDtcblxuICAgIGV2ZW50QnVzLmZpcmUoJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCcsIHsgZWxlbWVudDogZWxlbWVudCwgZ2Z4OiBnZnggfSk7XG4gIH0pO1xuXG4gIGV2ZW50QnVzLm9uKCdpbnRlcmFjdGlvbkV2ZW50cy5jcmVhdGVIaXQnLCBMT1dfUFJJT1JJVFksIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICBzZWxmLmNyZWF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgfSk7XG5cbiAgZXZlbnRCdXMub24oJ2ludGVyYWN0aW9uRXZlbnRzLnVwZGF0ZUhpdCcsIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIGVsZW1lbnQgPSBldmVudC5lbGVtZW50LFxuICAgICAgICBnZnggPSBldmVudC5nZng7XG5cbiAgICBzZWxmLnVwZGF0ZURlZmF1bHRIaXQoZWxlbWVudCwgZ2Z4KTtcbiAgfSk7XG5cblxuICAvLyBoaXQgc3R5bGVzIC8vLy8vLy8vLy8vL1xuXG4gIHZhciBTVFJPS0VfSElUX1NUWUxFID0gY3JlYXRlSGl0U3R5bGUoJ2Rqcy1oaXQgZGpzLWhpdC1zdHJva2UnKTtcblxuICB2YXIgQ0xJQ0tfU1RST0tFX0hJVF9TVFlMRSA9IGNyZWF0ZUhpdFN0eWxlKCdkanMtaGl0IGRqcy1oaXQtY2xpY2stc3Ryb2tlJyk7XG5cbiAgdmFyIEFMTF9ISVRfU1RZTEUgPSBjcmVhdGVIaXRTdHlsZSgnZGpzLWhpdCBkanMtaGl0LWFsbCcpO1xuXG4gIHZhciBISVRfVFlQRVMgPSB7XG4gICAgJ2FsbCc6IEFMTF9ISVRfU1RZTEUsXG4gICAgJ2NsaWNrLXN0cm9rZSc6IENMSUNLX1NUUk9LRV9ISVRfU1RZTEUsXG4gICAgJ3N0cm9rZSc6IFNUUk9LRV9ISVRfU1RZTEVcbiAgfTtcblxuICBmdW5jdGlvbiBjcmVhdGVIaXRTdHlsZShjbGFzc05hbWVzLCBhdHRycykge1xuXG4gICAgYXR0cnMgPSBhc3NpZ24oe1xuICAgICAgc3Ryb2tlOiAnd2hpdGUnLFxuICAgICAgc3Ryb2tlV2lkdGg6IDE1XG4gICAgfSwgYXR0cnMgfHwge30pO1xuXG4gICAgcmV0dXJuIHN0eWxlcy5jbHMoY2xhc3NOYW1lcywgWyAnbm8tZmlsbCcsICduby1ib3JkZXInIF0sIGF0dHJzKTtcbiAgfVxuXG5cbiAgLy8gc3R5bGUgaGVscGVycyAvLy8vLy8vLy8vLy8vLy9cblxuICBmdW5jdGlvbiBhcHBseVN0eWxlKGhpdCwgdHlwZSkge1xuXG4gICAgdmFyIGF0dHJzID0gSElUX1RZUEVTW3R5cGVdO1xuXG4gICAgaWYgKCFhdHRycykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIGhpdCB0eXBlIDwnICsgdHlwZSArICc+Jyk7XG4gICAgfVxuXG4gICAgc3ZnQXR0cihoaXQsIGF0dHJzKTtcblxuICAgIHJldHVybiBoaXQ7XG4gIH1cblxuICBmdW5jdGlvbiBhcHBlbmRIaXQoZ2Z4LCBoaXQpIHtcbiAgICBzdmdBcHBlbmQoZ2Z4LCBoaXQpO1xuICB9XG5cblxuICAvLyBBUElcblxuICAvKipcbiAgICogUmVtb3ZlIGhpbnRzIG9uIHRoZSBnaXZlbiBncmFwaGljcy5cbiAgICpcbiAgICogQHBhcmFtIHtTVkdFbGVtZW50fSBnZnhcbiAgICovXG4gIHRoaXMucmVtb3ZlSGl0cyA9IGZ1bmN0aW9uKGdmeCkge1xuICAgIHZhciBoaXRzID0gZG9tUXVlcnlBbGwoJy5kanMtaGl0JywgZ2Z4KTtcblxuICAgIGZvckVhY2goaGl0cywgc3ZnUmVtb3ZlKTtcbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGRlZmF1bHQgaGl0IGZvciB0aGUgZ2l2ZW4gZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICAgKiBAcGFyYW0ge1NWR0VsZW1lbnR9IGdmeFxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSBjcmVhdGVkIGhpdFxuICAgKi9cbiAgdGhpcy5jcmVhdGVEZWZhdWx0SGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG4gICAgdmFyIHdheXBvaW50cyA9IGVsZW1lbnQud2F5cG9pbnRzLFxuICAgICAgICBpc0ZyYW1lID0gZWxlbWVudC5pc0ZyYW1lLFxuICAgICAgICBib3hUeXBlO1xuXG4gICAgaWYgKHdheXBvaW50cykge1xuICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlV2F5cG9pbnRzSGl0KGdmeCwgd2F5cG9pbnRzKTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICBib3hUeXBlID0gaXNGcmFtZSA/ICdzdHJva2UnIDogJ2FsbCc7XG5cbiAgICAgIHJldHVybiB0aGlzLmNyZWF0ZUJveEhpdChnZngsIGJveFR5cGUsIHtcbiAgICAgICAgd2lkdGg6IGVsZW1lbnQud2lkdGgsXG4gICAgICAgIGhlaWdodDogZWxlbWVudC5oZWlnaHRcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQ3JlYXRlIGhpdHMgZm9yIHRoZSBnaXZlbiB3YXlwb2ludHMuXG4gICAqXG4gICAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gZ2Z4XG4gICAqIEBwYXJhbSB7QXJyYXk8UG9pbnQ+fSB3YXlwb2ludHNcbiAgICpcbiAgICogQHJldHVybiB7U1ZHRWxlbWVudH1cbiAgICovXG4gIHRoaXMuY3JlYXRlV2F5cG9pbnRzSGl0ID0gZnVuY3Rpb24oZ2Z4LCB3YXlwb2ludHMpIHtcblxuICAgIHZhciBoaXQgPSBjcmVhdGVMaW5lKHdheXBvaW50cyk7XG5cbiAgICBhcHBseVN0eWxlKGhpdCwgJ3N0cm9rZScpO1xuXG4gICAgYXBwZW5kSGl0KGdmeCwgaGl0KTtcblxuICAgIHJldHVybiBoaXQ7XG4gIH07XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBoaXRzIGZvciBhIGJveC5cbiAgICpcbiAgICogQHBhcmFtIHtTVkdFbGVtZW50fSBnZnhcbiAgICogQHBhcmFtIHtTdHJpbmd9IGhpdFR5cGVcbiAgICogQHBhcmFtIHtPYmplY3R9IGF0dHJzXG4gICAqXG4gICAqIEByZXR1cm4ge1NWR0VsZW1lbnR9XG4gICAqL1xuICB0aGlzLmNyZWF0ZUJveEhpdCA9IGZ1bmN0aW9uKGdmeCwgdHlwZSwgYXR0cnMpIHtcblxuICAgIGF0dHJzID0gYXNzaWduKHtcbiAgICAgIHg6IDAsXG4gICAgICB5OiAwXG4gICAgfSwgYXR0cnMpO1xuXG4gICAgdmFyIGhpdCA9IHN2Z0NyZWF0ZSgncmVjdCcpO1xuXG4gICAgYXBwbHlTdHlsZShoaXQsIHR5cGUpO1xuXG4gICAgc3ZnQXR0cihoaXQsIGF0dHJzKTtcblxuICAgIGFwcGVuZEhpdChnZngsIGhpdCk7XG5cbiAgICByZXR1cm4gaGl0O1xuICB9O1xuXG4gIC8qKlxuICAgKiBVcGRhdGUgZGVmYXVsdCBoaXQgb2YgdGhlIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gICAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IGdmeFxuICAgKlxuICAgKiBAcmV0dXJuIHtTVkdFbGVtZW50fSB1cGRhdGVkIGhpdFxuICAgKi9cbiAgdGhpcy51cGRhdGVEZWZhdWx0SGl0ID0gZnVuY3Rpb24oZWxlbWVudCwgZ2Z4KSB7XG5cbiAgICB2YXIgaGl0ID0gZG9tUXVlcnkoJy5kanMtaGl0JywgZ2Z4KTtcblxuICAgIGlmICghaGl0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGVsZW1lbnQud2F5cG9pbnRzKSB7XG4gICAgICB1cGRhdGVMaW5lKGhpdCwgZWxlbWVudC53YXlwb2ludHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdmdBdHRyKGhpdCwge1xuICAgICAgICB3aWR0aDogZWxlbWVudC53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBlbGVtZW50LmhlaWdodFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGhpdDtcbiAgfTtcblxuICB0aGlzLmZpcmUgPSBmaXJlO1xuXG4gIHRoaXMudHJpZ2dlck1vdXNlRXZlbnQgPSB0cmlnZ2VyTW91c2VFdmVudDtcblxuICB0aGlzLm1vdXNlSGFuZGxlciA9IG1vdXNlSGFuZGxlcjtcblxuICB0aGlzLnJlZ2lzdGVyRXZlbnQgPSByZWdpc3RlckV2ZW50O1xuICB0aGlzLnVucmVnaXN0ZXJFdmVudCA9IHVucmVnaXN0ZXJFdmVudDtcbn1cblxuXG5JbnRlcmFjdGlvbkV2ZW50cy4kaW5qZWN0ID0gW1xuICAnZXZlbnRCdXMnLFxuICAnZWxlbWVudFJlZ2lzdHJ5JyxcbiAgJ3N0eWxlcydcbl07XG5cblxuLyoqXG4gKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vdXNlIGhvdmVyZWQgb3ZlciBhbiBlbGVtZW50XG4gKlxuICogQGV2ZW50IGVsZW1lbnQuaG92ZXJcbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSBnZnhcbiAqIEBwcm9wZXJ0eSB7RXZlbnR9IG9yaWdpbmFsRXZlbnRcbiAqL1xuXG4vKipcbiAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgbW91c2UgaGFzIGxlZnQgYW4gZWxlbWVudFxuICpcbiAqIEBldmVudCBlbGVtZW50Lm91dFxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBtb3VzZSBoYXMgY2xpY2tlZCBhbiBlbGVtZW50XG4gKlxuICogQGV2ZW50IGVsZW1lbnQuY2xpY2tcbiAqXG4gKiBAdHlwZSB7T2JqZWN0fVxuICogQHByb3BlcnR5IHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxuICogQHByb3BlcnR5IHtTVkdFbGVtZW50fSBnZnhcbiAqIEBwcm9wZXJ0eSB7RXZlbnR9IG9yaWdpbmFsRXZlbnRcbiAqL1xuXG4vKipcbiAqIEFuIGV2ZW50IGluZGljYXRpbmcgdGhhdCB0aGUgbW91c2UgaGFzIGRvdWJsZSBjbGlja2VkIGFuIGVsZW1lbnRcbiAqXG4gKiBAZXZlbnQgZWxlbWVudC5kYmxjbGlja1xuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBtb3VzZSBoYXMgZ29uZSBkb3duIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogQGV2ZW50IGVsZW1lbnQubW91c2Vkb3duXG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gZ2Z4XG4gKiBAcHJvcGVydHkge0V2ZW50fSBvcmlnaW5hbEV2ZW50XG4gKi9cblxuLyoqXG4gKiBBbiBldmVudCBpbmRpY2F0aW5nIHRoYXQgdGhlIG1vdXNlIGhhcyBnb25lIHVwIG9uIGFuIGVsZW1lbnQuXG4gKlxuICogQGV2ZW50IGVsZW1lbnQubW91c2V1cFxuICpcbiAqIEB0eXBlIHtPYmplY3R9XG4gKiBAcHJvcGVydHkge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XG4gKiBAcHJvcGVydHkge1NWR0VsZW1lbnR9IGdmeFxuICogQHByb3BlcnR5IHtFdmVudH0gb3JpZ2luYWxFdmVudFxuICovXG5cbi8qKlxuICogQW4gZXZlbnQgaW5kaWNhdGluZyB0aGF0IHRoZSBjb250ZXh0IG1lbnUgYWN0aW9uIGlzIHRyaWdnZXJlZFxuICogdmlhIG1vdXNlIG9yIHRvdWNoIGNvbnRyb2xzLlxuICpcbiAqIEBldmVudCBlbGVtZW50LmNvbnRleHRtZW51XG4gKlxuICogQHR5cGUge09iamVjdH1cbiAqIEBwcm9wZXJ0eSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcbiAqIEBwcm9wZXJ0eSB7U1ZHRWxlbWVudH0gZ2Z4XG4gKiBAcHJvcGVydHkge0V2ZW50fSBvcmlnaW5hbEV2ZW50XG4gKi8iLCIvKipcbiAqIEEgc2ltcGxlIHRyYW5zbGF0aW9uIHN0dWIgdG8gYmUgdXNlZCBmb3IgbXVsdGktbGFuZ3VhZ2Ugc3VwcG9ydFxuICogaW4gZGlhZ3JhbXMuIENhbiBiZSBlYXNpbHkgcmVwbGFjZWQgd2l0aCBhIG1vcmUgc29waGlzdGljYXRlZFxuICogc29sdXRpb24uXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyB1c2UgaXQgaW5zaWRlIGFueSBkaWFncmFtIGNvbXBvbmVudCBieSBpbmplY3RpbmcgYHRyYW5zbGF0ZWAuXG4gKlxuICogZnVuY3Rpb24gTXlTZXJ2aWNlKHRyYW5zbGF0ZSkge1xuICogICBhbGVydCh0cmFuc2xhdGUoJ0hFTExPIHt5b3V9JywgeyB5b3U6ICdZb3UhJyB9KSk7XG4gKiB9XG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHRlbXBsYXRlIHRvIGludGVycG9sYXRlXG4gKiBAcGFyYW0ge09iamVjdH0gW3JlcGxhY2VtZW50c10gYSBtYXAgd2l0aCBzdWJzdGl0dXRlc1xuICpcbiAqIEByZXR1cm4ge1N0cmluZ30gdGhlIHRyYW5zbGF0ZWQgc3RyaW5nXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHRyYW5zbGF0ZSh0ZW1wbGF0ZSwgcmVwbGFjZW1lbnRzKSB7XG5cbiAgcmVwbGFjZW1lbnRzID0gcmVwbGFjZW1lbnRzIHx8IHt9O1xuXG4gIHJldHVybiB0ZW1wbGF0ZS5yZXBsYWNlKC97KFtefV0rKX0vZywgZnVuY3Rpb24oXywga2V5KSB7XG4gICAgcmV0dXJuIHJlcGxhY2VtZW50c1trZXldIHx8ICd7JyArIGtleSArICd9JztcbiAgfSk7XG59IiwiLyoqXG4gKiBGYWlsc2FmZSByZW1vdmUgYW4gZWxlbWVudCBmcm9tIGEgY29sbGVjdGlvblxuICpcbiAqIEBwYXJhbSAge0FycmF5PE9iamVjdD59IFtjb2xsZWN0aW9uXVxuICogQHBhcmFtICB7T2JqZWN0fSBbZWxlbWVudF1cbiAqXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IHRoZSBwcmV2aW91cyBpbmRleCBvZiB0aGUgZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVtb3ZlKGNvbGxlY3Rpb24sIGVsZW1lbnQpIHtcblxuICBpZiAoIWNvbGxlY3Rpb24gfHwgIWVsZW1lbnQpIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICB2YXIgaWR4ID0gY29sbGVjdGlvbi5pbmRleE9mKGVsZW1lbnQpO1xuXG4gIGlmIChpZHggIT09IC0xKSB7XG4gICAgY29sbGVjdGlvbi5zcGxpY2UoaWR4LCAxKTtcbiAgfVxuXG4gIHJldHVybiBpZHg7XG59XG5cbi8qKlxuICogRmFpbCBzYXZlIGFkZCBhbiBlbGVtZW50IHRvIHRoZSBnaXZlbiBjb25uZWN0aW9uLCBlbnN1cmluZ1xuICogaXQgZG9lcyBub3QgeWV0IGV4aXN0LlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8T2JqZWN0Pn0gY29sbGVjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnRcbiAqIEBwYXJhbSB7TnVtYmVyfSBpZHhcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZChjb2xsZWN0aW9uLCBlbGVtZW50LCBpZHgpIHtcblxuICBpZiAoIWNvbGxlY3Rpb24gfHwgIWVsZW1lbnQpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBpZiAodHlwZW9mIGlkeCAhPT0gJ251bWJlcicpIHtcbiAgICBpZHggPSAtMTtcbiAgfVxuXG4gIHZhciBjdXJyZW50SWR4ID0gY29sbGVjdGlvbi5pbmRleE9mKGVsZW1lbnQpO1xuXG4gIGlmIChjdXJyZW50SWR4ICE9PSAtMSkge1xuXG4gICAgaWYgKGN1cnJlbnRJZHggPT09IGlkeCkge1xuXG4gICAgICAvLyBub3RoaW5nIHRvIGRvLCBwb3NpdGlvbiBoYXMgbm90IGNoYW5nZWRcbiAgICAgIHJldHVybjtcbiAgICB9IGVsc2Uge1xuXG4gICAgICBpZiAoaWR4ICE9PSAtMSkge1xuXG4gICAgICAgIC8vIHJlbW92ZSBmcm9tIGN1cnJlbnQgcG9zaXRpb25cbiAgICAgICAgY29sbGVjdGlvbi5zcGxpY2UoY3VycmVudElkeCwgMSk7XG4gICAgICB9IGVsc2Uge1xuXG4gICAgICAgIC8vIGFscmVhZHkgZXhpc3RzIGluIGNvbGxlY3Rpb25cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChpZHggIT09IC0xKSB7XG5cbiAgICAvLyBpbnNlcnQgYXQgc3BlY2lmaWVkIHBvc2l0aW9uXG4gICAgY29sbGVjdGlvbi5zcGxpY2UoaWR4LCAwLCBlbGVtZW50KTtcbiAgfSBlbHNlIHtcblxuICAgIC8vIHB1c2ggdG8gZW5kXG4gICAgY29sbGVjdGlvbi5wdXNoKGVsZW1lbnQpO1xuICB9XG59XG5cblxuLyoqXG4gKiBGYWlsIHNhdmUgZ2V0IHRoZSBpbmRleCBvZiBhbiBlbGVtZW50IGluIGEgY29sbGVjdGlvbi5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PE9iamVjdD59IGNvbGxlY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7TnVtYmVyfSB0aGUgaW5kZXggb3IgLTEgaWYgY29sbGVjdGlvbiBvciBlbGVtZW50IGRvXG4gKiAgICAgICAgICAgICAgICAgIG5vdCBleGlzdCBvciB0aGUgZWxlbWVudCBpcyBub3QgY29udGFpbmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5kZXhPZihjb2xsZWN0aW9uLCBlbGVtZW50KSB7XG5cbiAgaWYgKCFjb2xsZWN0aW9uIHx8ICFlbGVtZW50KSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG5cbiAgcmV0dXJuIGNvbGxlY3Rpb24uaW5kZXhPZihlbGVtZW50KTtcbn1cbiIsInZhciBDTEFTU19QQVRURVJOID0gL15jbGFzcyAvO1xuXG5mdW5jdGlvbiBpc0NsYXNzKGZuKSB7XG4gIHJldHVybiBDTEFTU19QQVRURVJOLnRlc3QoZm4udG9TdHJpbmcoKSk7XG59XG5cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgQXJyYXldJztcbn1cblxuZnVuY3Rpb24gYW5ub3RhdGUoKSB7XG4gIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtcblxuICBpZiAoYXJncy5sZW5ndGggPT09IDEgJiYgaXNBcnJheShhcmdzWzBdKSkge1xuICAgIGFyZ3MgPSBhcmdzWzBdO1xuICB9XG5cbiAgdmFyIGZuID0gYXJncy5wb3AoKTtcblxuICBmbi4kaW5qZWN0ID0gYXJncztcblxuICByZXR1cm4gZm47XG59XG5cbi8vIEN1cnJlbnQgbGltaXRhdGlvbnM6XG4vLyAtIGNhbid0IHB1dCBpbnRvIFwiZnVuY3Rpb24gYXJnXCIgY29tbWVudHNcbi8vIGZ1bmN0aW9uIC8qIChubyBwYXJlbnRoZXNpcyBsaWtlIHRoaXMpICovICgpe31cbi8vIGZ1bmN0aW9uIGFiYyggLyogeHggKG5vIHBhcmVudGhlc2lzIGxpa2UgdGhpcykgKi8gYSwgYikge31cbi8vXG4vLyBKdXN0IHB1dCB0aGUgY29tbWVudCBiZWZvcmUgZnVuY3Rpb24gb3IgaW5zaWRlOlxuLy8gLyogKCgodGhpcyBpcyBmaW5lKSkpICovIGZ1bmN0aW9uKGEsIGIpIHt9XG4vLyBmdW5jdGlvbiBhYmMoYSkgeyAvKiAoKCh0aGlzIGlzIGZpbmUpKSkgKi99XG4vL1xuLy8gLSBjYW4ndCByZWxpYWJseSBhdXRvLWFubm90YXRlIGNvbnN0cnVjdG9yOyB3ZSdsbCBtYXRjaCB0aGVcbi8vIGZpcnN0IGNvbnN0cnVjdG9yKC4uLikgcGF0dGVybiBmb3VuZCB3aGljaCBtYXkgYmUgdGhlIG9uZVxuLy8gb2YgYSBuZXN0ZWQgY2xhc3MsIHRvby5cblxudmFyIENPTlNUUlVDVE9SX0FSR1MgPSAvY29uc3RydWN0b3JcXHMqW14oXSpcXChcXHMqKFteKV0qKVxcKS9tO1xudmFyIEZOX0FSR1MgPSAvXmZ1bmN0aW9uXFxzKlteKF0qXFwoXFxzKihbXildKilcXCkvbTtcbnZhciBGTl9BUkcgPSAvXFwvXFwqKFteKl0qKVxcKlxcLy9tO1xuXG5mdW5jdGlvbiBwYXJzZShmbikge1xuXG4gIGlmICh0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nhbm5vdCBhbm5vdGF0ZSBcIicgKyBmbiArICdcIi4gRXhwZWN0ZWQgYSBmdW5jdGlvbiEnKTtcbiAgfVxuXG4gIHZhciBtYXRjaCA9IGZuLnRvU3RyaW5nKCkubWF0Y2goaXNDbGFzcyhmbikgPyBDT05TVFJVQ1RPUl9BUkdTIDogRk5fQVJHUyk7XG5cbiAgLy8gbWF5IHBhcnNlIGNsYXNzIHdpdGhvdXQgY29uc3RydWN0b3JcbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHJldHVybiBtYXRjaFsxXSAmJiBtYXRjaFsxXS5zcGxpdCgnLCcpLm1hcChmdW5jdGlvbiAoYXJnKSB7XG4gICAgbWF0Y2ggPSBhcmcubWF0Y2goRk5fQVJHKTtcbiAgICByZXR1cm4gbWF0Y2ggPyBtYXRjaFsxXS50cmltKCkgOiBhcmcudHJpbSgpO1xuICB9KSB8fCBbXTtcbn1cblxuZnVuY3Rpb24gTW9kdWxlKCkge1xuICB2YXIgcHJvdmlkZXJzID0gW107XG5cbiAgdGhpcy5mYWN0b3J5ID0gZnVuY3Rpb24gKG5hbWUsIGZhY3RvcnkpIHtcbiAgICBwcm92aWRlcnMucHVzaChbbmFtZSwgJ2ZhY3RvcnknLCBmYWN0b3J5XSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgdGhpcy52YWx1ZSA9IGZ1bmN0aW9uIChuYW1lLCB2YWx1ZSkge1xuICAgIHByb3ZpZGVycy5wdXNoKFtuYW1lLCAndmFsdWUnLCB2YWx1ZV0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHRoaXMudHlwZSA9IGZ1bmN0aW9uIChuYW1lLCB0eXBlKSB7XG4gICAgcHJvdmlkZXJzLnB1c2goW25hbWUsICd0eXBlJywgdHlwZV0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIHRoaXMuZm9yRWFjaCA9IGZ1bmN0aW9uIChpdGVyYXRvcikge1xuICAgIHByb3ZpZGVycy5mb3JFYWNoKGl0ZXJhdG9yKTtcbiAgfTtcbn1cblxudmFyIF90eXBlb2YgPSB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciA9PT0gXCJzeW1ib2xcIiA/IGZ1bmN0aW9uIChvYmopIHsgcmV0dXJuIHR5cGVvZiBvYmo7IH0gOiBmdW5jdGlvbiAob2JqKSB7IHJldHVybiBvYmogJiYgdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIG9iai5jb25zdHJ1Y3RvciA9PT0gU3ltYm9sICYmIG9iaiAhPT0gU3ltYm9sLnByb3RvdHlwZSA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG5mdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7IGlmIChBcnJheS5pc0FycmF5KGFycikpIHsgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9IGVsc2UgeyByZXR1cm4gQXJyYXkuZnJvbShhcnIpOyB9IH1cblxuZnVuY3Rpb24gSW5qZWN0b3IobW9kdWxlcywgcGFyZW50KSB7XG4gIHBhcmVudCA9IHBhcmVudCB8fCB7XG4gICAgZ2V0OiBmdW5jdGlvbiBnZXQobmFtZSwgc3RyaWN0KSB7XG4gICAgICBjdXJyZW50bHlSZXNvbHZpbmcucHVzaChuYW1lKTtcblxuICAgICAgaWYgKHN0cmljdCA9PT0gZmFsc2UpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBlcnJvcignTm8gcHJvdmlkZXIgZm9yIFwiJyArIG5hbWUgKyAnXCIhJyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBjdXJyZW50bHlSZXNvbHZpbmcgPSBbXTtcbiAgdmFyIHByb3ZpZGVycyA9IHRoaXMuX3Byb3ZpZGVycyA9IE9iamVjdC5jcmVhdGUocGFyZW50Ll9wcm92aWRlcnMgfHwgbnVsbCk7XG4gIHZhciBpbnN0YW5jZXMgPSB0aGlzLl9pbnN0YW5jZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gIHZhciBzZWxmID0gaW5zdGFuY2VzLmluamVjdG9yID0gdGhpcztcblxuICB2YXIgZXJyb3IgPSBmdW5jdGlvbiBlcnJvcihtc2cpIHtcbiAgICB2YXIgc3RhY2sgPSBjdXJyZW50bHlSZXNvbHZpbmcuam9pbignIC0+ICcpO1xuICAgIGN1cnJlbnRseVJlc29sdmluZy5sZW5ndGggPSAwO1xuICAgIHJldHVybiBuZXcgRXJyb3Ioc3RhY2sgPyBtc2cgKyAnIChSZXNvbHZpbmc6ICcgKyBzdGFjayArICcpJyA6IG1zZyk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIG5hbWVkIHNlcnZpY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gW3N0cmljdD10cnVlXSBpZiBmYWxzZSwgcmVzb2x2ZSBtaXNzaW5nIHNlcnZpY2VzIHRvIG51bGxcbiAgICpcbiAgICogQHJldHVybiB7T2JqZWN0fVxuICAgKi9cbiAgdmFyIGdldCA9IGZ1bmN0aW9uIGdldChuYW1lLCBzdHJpY3QpIHtcbiAgICBpZiAoIXByb3ZpZGVyc1tuYW1lXSAmJiBuYW1lLmluZGV4T2YoJy4nKSAhPT0gLTEpIHtcbiAgICAgIHZhciBwYXJ0cyA9IG5hbWUuc3BsaXQoJy4nKTtcbiAgICAgIHZhciBwaXZvdCA9IGdldChwYXJ0cy5zaGlmdCgpKTtcblxuICAgICAgd2hpbGUgKHBhcnRzLmxlbmd0aCkge1xuICAgICAgICBwaXZvdCA9IHBpdm90W3BhcnRzLnNoaWZ0KCldO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcGl2b3Q7XG4gICAgfVxuXG4gICAgaWYgKGhhc1Byb3AoaW5zdGFuY2VzLCBuYW1lKSkge1xuICAgICAgcmV0dXJuIGluc3RhbmNlc1tuYW1lXTtcbiAgICB9XG5cbiAgICBpZiAoaGFzUHJvcChwcm92aWRlcnMsIG5hbWUpKSB7XG4gICAgICBpZiAoY3VycmVudGx5UmVzb2x2aW5nLmluZGV4T2YobmFtZSkgIT09IC0xKSB7XG4gICAgICAgIGN1cnJlbnRseVJlc29sdmluZy5wdXNoKG5hbWUpO1xuICAgICAgICB0aHJvdyBlcnJvcignQ2Fubm90IHJlc29sdmUgY2lyY3VsYXIgZGVwZW5kZW5jeSEnKTtcbiAgICAgIH1cblxuICAgICAgY3VycmVudGx5UmVzb2x2aW5nLnB1c2gobmFtZSk7XG4gICAgICBpbnN0YW5jZXNbbmFtZV0gPSBwcm92aWRlcnNbbmFtZV1bMF0ocHJvdmlkZXJzW25hbWVdWzFdKTtcbiAgICAgIGN1cnJlbnRseVJlc29sdmluZy5wb3AoKTtcblxuICAgICAgcmV0dXJuIGluc3RhbmNlc1tuYW1lXTtcbiAgICB9XG5cbiAgICByZXR1cm4gcGFyZW50LmdldChuYW1lLCBzdHJpY3QpO1xuICB9O1xuXG4gIHZhciBmbkRlZiA9IGZ1bmN0aW9uIGZuRGVmKGZuKSB7XG4gICAgdmFyIGxvY2FscyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxICYmIGFyZ3VtZW50c1sxXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzFdIDoge307XG5cbiAgICBpZiAodHlwZW9mIGZuICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICBpZiAoaXNBcnJheShmbikpIHtcbiAgICAgICAgZm4gPSBhbm5vdGF0ZShmbi5zbGljZSgpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignQ2Fubm90IGludm9rZSBcIicgKyBmbiArICdcIi4gRXhwZWN0ZWQgYSBmdW5jdGlvbiEnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgaW5qZWN0ID0gZm4uJGluamVjdCB8fCBwYXJzZShmbik7XG4gICAgdmFyIGRlcGVuZGVuY2llcyA9IGluamVjdC5tYXAoZnVuY3Rpb24gKGRlcCkge1xuICAgICAgaWYgKGhhc1Byb3AobG9jYWxzLCBkZXApKSB7XG4gICAgICAgIHJldHVybiBsb2NhbHNbZGVwXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBnZXQoZGVwKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBmbjogZm4sXG4gICAgICBkZXBlbmRlbmNpZXM6IGRlcGVuZGVuY2llc1xuICAgIH07XG4gIH07XG5cbiAgdmFyIGluc3RhbnRpYXRlID0gZnVuY3Rpb24gaW5zdGFudGlhdGUoVHlwZSkge1xuICAgIHZhciBfZm5EZWYgPSBmbkRlZihUeXBlKSxcbiAgICAgICAgZGVwZW5kZW5jaWVzID0gX2ZuRGVmLmRlcGVuZGVuY2llcyxcbiAgICAgICAgZm4gPSBfZm5EZWYuZm47XG5cbiAgICByZXR1cm4gbmV3IChGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseShmbiwgW251bGxdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkoZGVwZW5kZW5jaWVzKSkpKSgpO1xuICB9O1xuXG4gIHZhciBpbnZva2UgPSBmdW5jdGlvbiBpbnZva2UoZnVuYywgY29udGV4dCwgbG9jYWxzKSB7XG4gICAgdmFyIF9mbkRlZjIgPSBmbkRlZihmdW5jLCBsb2NhbHMpLFxuICAgICAgICBkZXBlbmRlbmNpZXMgPSBfZm5EZWYyLmRlcGVuZGVuY2llcyxcbiAgICAgICAgZm4gPSBfZm5EZWYyLmZuO1xuXG4gICAgcmV0dXJuIGZuLmNhbGwuYXBwbHkoZm4sIFtjb250ZXh0XS5jb25jYXQoX3RvQ29uc3VtYWJsZUFycmF5KGRlcGVuZGVuY2llcykpKTtcbiAgfTtcblxuICB2YXIgY3JlYXRlUHJpdmF0ZUluamVjdG9yRmFjdG9yeSA9IGZ1bmN0aW9uIGNyZWF0ZVByaXZhdGVJbmplY3RvckZhY3RvcnkocHJpdmF0ZUNoaWxkSW5qZWN0b3IpIHtcbiAgICByZXR1cm4gYW5ub3RhdGUoZnVuY3Rpb24gKGtleSkge1xuICAgICAgcmV0dXJuIHByaXZhdGVDaGlsZEluamVjdG9yLmdldChrZXkpO1xuICAgIH0pO1xuICB9O1xuXG4gIHZhciBjcmVhdGVDaGlsZCA9IGZ1bmN0aW9uIGNyZWF0ZUNoaWxkKG1vZHVsZXMsIGZvcmNlTmV3SW5zdGFuY2VzKSB7XG4gICAgaWYgKGZvcmNlTmV3SW5zdGFuY2VzICYmIGZvcmNlTmV3SW5zdGFuY2VzLmxlbmd0aCkge1xuICAgICAgdmFyIGZyb21QYXJlbnRNb2R1bGUgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgICAgdmFyIG1hdGNoZWRTY29wZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgICB2YXIgcHJpdmF0ZUluamVjdG9yc0NhY2hlID0gW107XG4gICAgICB2YXIgcHJpdmF0ZUNoaWxkSW5qZWN0b3JzID0gW107XG4gICAgICB2YXIgcHJpdmF0ZUNoaWxkRmFjdG9yaWVzID0gW107XG5cbiAgICAgIHZhciBwcm92aWRlcjtcbiAgICAgIHZhciBjYWNoZUlkeDtcbiAgICAgIHZhciBwcml2YXRlQ2hpbGRJbmplY3RvcjtcbiAgICAgIHZhciBwcml2YXRlQ2hpbGRJbmplY3RvckZhY3Rvcnk7XG4gICAgICBmb3IgKHZhciBuYW1lIGluIHByb3ZpZGVycykge1xuICAgICAgICBwcm92aWRlciA9IHByb3ZpZGVyc1tuYW1lXTtcblxuICAgICAgICBpZiAoZm9yY2VOZXdJbnN0YW5jZXMuaW5kZXhPZihuYW1lKSAhPT0gLTEpIHtcbiAgICAgICAgICBpZiAocHJvdmlkZXJbMl0gPT09ICdwcml2YXRlJykge1xuICAgICAgICAgICAgY2FjaGVJZHggPSBwcml2YXRlSW5qZWN0b3JzQ2FjaGUuaW5kZXhPZihwcm92aWRlclszXSk7XG4gICAgICAgICAgICBpZiAoY2FjaGVJZHggPT09IC0xKSB7XG4gICAgICAgICAgICAgIHByaXZhdGVDaGlsZEluamVjdG9yID0gcHJvdmlkZXJbM10uY3JlYXRlQ2hpbGQoW10sIGZvcmNlTmV3SW5zdGFuY2VzKTtcbiAgICAgICAgICAgICAgcHJpdmF0ZUNoaWxkSW5qZWN0b3JGYWN0b3J5ID0gY3JlYXRlUHJpdmF0ZUluamVjdG9yRmFjdG9yeShwcml2YXRlQ2hpbGRJbmplY3Rvcik7XG4gICAgICAgICAgICAgIHByaXZhdGVJbmplY3RvcnNDYWNoZS5wdXNoKHByb3ZpZGVyWzNdKTtcbiAgICAgICAgICAgICAgcHJpdmF0ZUNoaWxkSW5qZWN0b3JzLnB1c2gocHJpdmF0ZUNoaWxkSW5qZWN0b3IpO1xuICAgICAgICAgICAgICBwcml2YXRlQ2hpbGRGYWN0b3JpZXMucHVzaChwcml2YXRlQ2hpbGRJbmplY3RvckZhY3RvcnkpO1xuICAgICAgICAgICAgICBmcm9tUGFyZW50TW9kdWxlW25hbWVdID0gW3ByaXZhdGVDaGlsZEluamVjdG9yRmFjdG9yeSwgbmFtZSwgJ3ByaXZhdGUnLCBwcml2YXRlQ2hpbGRJbmplY3Rvcl07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBmcm9tUGFyZW50TW9kdWxlW25hbWVdID0gW3ByaXZhdGVDaGlsZEZhY3Rvcmllc1tjYWNoZUlkeF0sIG5hbWUsICdwcml2YXRlJywgcHJpdmF0ZUNoaWxkSW5qZWN0b3JzW2NhY2hlSWR4XV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZyb21QYXJlbnRNb2R1bGVbbmFtZV0gPSBbcHJvdmlkZXJbMl0sIHByb3ZpZGVyWzFdXTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbWF0Y2hlZFNjb3Blc1tuYW1lXSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoKHByb3ZpZGVyWzJdID09PSAnZmFjdG9yeScgfHwgcHJvdmlkZXJbMl0gPT09ICd0eXBlJykgJiYgcHJvdmlkZXJbMV0uJHNjb3BlKSB7XG4gICAgICAgICAgLyoganNoaW50IC1XMDgzICovXG4gICAgICAgICAgZm9yY2VOZXdJbnN0YW5jZXMuZm9yRWFjaChmdW5jdGlvbiAoc2NvcGUpIHtcbiAgICAgICAgICAgIGlmIChwcm92aWRlclsxXS4kc2NvcGUuaW5kZXhPZihzY29wZSkgIT09IC0xKSB7XG4gICAgICAgICAgICAgIGZyb21QYXJlbnRNb2R1bGVbbmFtZV0gPSBbcHJvdmlkZXJbMl0sIHByb3ZpZGVyWzFdXTtcbiAgICAgICAgICAgICAgbWF0Y2hlZFNjb3Blc1tzY29wZV0gPSB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGZvcmNlTmV3SW5zdGFuY2VzLmZvckVhY2goZnVuY3Rpb24gKHNjb3BlKSB7XG4gICAgICAgIGlmICghbWF0Y2hlZFNjb3Blc1tzY29wZV0pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHByb3ZpZGVyIGZvciBcIicgKyBzY29wZSArICdcIi4gQ2Fubm90IHVzZSBwcm92aWRlciBmcm9tIHRoZSBwYXJlbnQhJyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICBtb2R1bGVzLnVuc2hpZnQoZnJvbVBhcmVudE1vZHVsZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbmplY3Rvcihtb2R1bGVzLCBzZWxmKTtcbiAgfTtcblxuICB2YXIgZmFjdG9yeU1hcCA9IHtcbiAgICBmYWN0b3J5OiBpbnZva2UsXG4gICAgdHlwZTogaW5zdGFudGlhdGUsXG4gICAgdmFsdWU6IGZ1bmN0aW9uIHZhbHVlKF92YWx1ZSkge1xuICAgICAgcmV0dXJuIF92YWx1ZTtcbiAgICB9XG4gIH07XG5cbiAgbW9kdWxlcy5mb3JFYWNoKGZ1bmN0aW9uIChtb2R1bGUpIHtcblxuICAgIGZ1bmN0aW9uIGFycmF5VW53cmFwKHR5cGUsIHZhbHVlKSB7XG4gICAgICBpZiAodHlwZSAhPT0gJ3ZhbHVlJyAmJiBpc0FycmF5KHZhbHVlKSkge1xuICAgICAgICB2YWx1ZSA9IGFubm90YXRlKHZhbHVlLnNsaWNlKCkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuXG4gICAgLy8gVE9ETyh2b2p0YSk6IGhhbmRsZSB3cm9uZyBpbnB1dHMgKG1vZHVsZXMpXG4gICAgaWYgKG1vZHVsZSBpbnN0YW5jZW9mIE1vZHVsZSkge1xuICAgICAgbW9kdWxlLmZvckVhY2goZnVuY3Rpb24gKHByb3ZpZGVyKSB7XG4gICAgICAgIHZhciBuYW1lID0gcHJvdmlkZXJbMF07XG4gICAgICAgIHZhciB0eXBlID0gcHJvdmlkZXJbMV07XG4gICAgICAgIHZhciB2YWx1ZSA9IHByb3ZpZGVyWzJdO1xuXG4gICAgICAgIHByb3ZpZGVyc1tuYW1lXSA9IFtmYWN0b3J5TWFwW3R5cGVdLCBhcnJheVVud3JhcCh0eXBlLCB2YWx1ZSksIHR5cGVdO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICgodHlwZW9mIG1vZHVsZSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YobW9kdWxlKSkgPT09ICdvYmplY3QnKSB7XG4gICAgICBpZiAobW9kdWxlLl9fZXhwb3J0c19fKSB7XG4gICAgICAgIHZhciBjbG9uZWRNb2R1bGUgPSBPYmplY3Qua2V5cyhtb2R1bGUpLnJlZHVjZShmdW5jdGlvbiAobSwga2V5KSB7XG4gICAgICAgICAgaWYgKGtleS5zdWJzdHJpbmcoMCwgMikgIT09ICdfXycpIHtcbiAgICAgICAgICAgIG1ba2V5XSA9IG1vZHVsZVtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbTtcbiAgICAgICAgfSwgT2JqZWN0LmNyZWF0ZShudWxsKSk7XG5cbiAgICAgICAgdmFyIHByaXZhdGVJbmplY3RvciA9IG5ldyBJbmplY3RvcigobW9kdWxlLl9fbW9kdWxlc19fIHx8IFtdKS5jb25jYXQoW2Nsb25lZE1vZHVsZV0pLCBzZWxmKTtcbiAgICAgICAgdmFyIGdldEZyb21Qcml2YXRlSW5qZWN0b3IgPSBhbm5vdGF0ZShmdW5jdGlvbiAoa2V5KSB7XG4gICAgICAgICAgcmV0dXJuIHByaXZhdGVJbmplY3Rvci5nZXQoa2V5KTtcbiAgICAgICAgfSk7XG4gICAgICAgIG1vZHVsZS5fX2V4cG9ydHNfXy5mb3JFYWNoKGZ1bmN0aW9uIChrZXkpIHtcbiAgICAgICAgICBwcm92aWRlcnNba2V5XSA9IFtnZXRGcm9tUHJpdmF0ZUluamVjdG9yLCBrZXksICdwcml2YXRlJywgcHJpdmF0ZUluamVjdG9yXTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBPYmplY3Qua2V5cyhtb2R1bGUpLmZvckVhY2goZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICBpZiAobW9kdWxlW25hbWVdWzJdID09PSAncHJpdmF0ZScpIHtcbiAgICAgICAgICAgIHByb3ZpZGVyc1tuYW1lXSA9IG1vZHVsZVtuYW1lXTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgdHlwZSA9IG1vZHVsZVtuYW1lXVswXTtcbiAgICAgICAgICB2YXIgdmFsdWUgPSBtb2R1bGVbbmFtZV1bMV07XG5cbiAgICAgICAgICBwcm92aWRlcnNbbmFtZV0gPSBbZmFjdG9yeU1hcFt0eXBlXSwgYXJyYXlVbndyYXAodHlwZSwgdmFsdWUpLCB0eXBlXTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9KTtcblxuICAvLyBwdWJsaWMgQVBJXG4gIHRoaXMuZ2V0ID0gZ2V0O1xuICB0aGlzLmludm9rZSA9IGludm9rZTtcbiAgdGhpcy5pbnN0YW50aWF0ZSA9IGluc3RhbnRpYXRlO1xuICB0aGlzLmNyZWF0ZUNoaWxkID0gY3JlYXRlQ2hpbGQ7XG59XG5cbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gaGFzUHJvcChvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCk7XG59XG5cbmV4cG9ydCB7IGFubm90YXRlLCBNb2R1bGUsIEluamVjdG9yIH07XG4iLCIvKiEgSGFtbWVyLkpTIC0gdjIuMC43IC0gMjAxNi0wNC0yMlxuICogaHR0cDovL2hhbW1lcmpzLmdpdGh1Yi5pby9cbiAqXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYgSm9yaWsgVGFuZ2VsZGVyO1xuICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlICovXG4oZnVuY3Rpb24od2luZG93LCBkb2N1bWVudCwgZXhwb3J0TmFtZSwgdW5kZWZpbmVkKSB7XG4gICd1c2Ugc3RyaWN0JztcblxudmFyIFZFTkRPUl9QUkVGSVhFUyA9IFsnJywgJ3dlYmtpdCcsICdNb3onLCAnTVMnLCAnbXMnLCAnbyddO1xudmFyIFRFU1RfRUxFTUVOVCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2RpdicpO1xuXG52YXIgVFlQRV9GVU5DVElPTiA9ICdmdW5jdGlvbic7XG5cbnZhciByb3VuZCA9IE1hdGgucm91bmQ7XG52YXIgYWJzID0gTWF0aC5hYnM7XG52YXIgbm93ID0gRGF0ZS5ub3c7XG5cbi8qKlxuICogc2V0IGEgdGltZW91dCB3aXRoIGEgZ2l2ZW4gc2NvcGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge051bWJlcn0gdGltZW91dFxuICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcbiAqIEByZXR1cm5zIHtudW1iZXJ9XG4gKi9cbmZ1bmN0aW9uIHNldFRpbWVvdXRDb250ZXh0KGZuLCB0aW1lb3V0LCBjb250ZXh0KSB7XG4gICAgcmV0dXJuIHNldFRpbWVvdXQoYmluZEZuKGZuLCBjb250ZXh0KSwgdGltZW91dCk7XG59XG5cbi8qKlxuICogaWYgdGhlIGFyZ3VtZW50IGlzIGFuIGFycmF5LCB3ZSB3YW50IHRvIGV4ZWN1dGUgdGhlIGZuIG9uIGVhY2ggZW50cnlcbiAqIGlmIGl0IGFpbnQgYW4gYXJyYXkgd2UgZG9uJ3Qgd2FudCB0byBkbyBhIHRoaW5nLlxuICogdGhpcyBpcyB1c2VkIGJ5IGFsbCB0aGUgbWV0aG9kcyB0aGF0IGFjY2VwdCBhIHNpbmdsZSBhbmQgYXJyYXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp8QXJyYXl9IGFyZ1xuICogQHBhcmFtIHtTdHJpbmd9IGZuXG4gKiBAcGFyYW0ge09iamVjdH0gW2NvbnRleHRdXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cbiAqL1xuZnVuY3Rpb24gaW52b2tlQXJyYXlBcmcoYXJnLCBmbiwgY29udGV4dCkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGFyZykpIHtcbiAgICAgICAgZWFjaChhcmcsIGNvbnRleHRbZm5dLCBjb250ZXh0KTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuLyoqXG4gKiB3YWxrIG9iamVjdHMgYW5kIGFycmF5c1xuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0b3JcbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKi9cbmZ1bmN0aW9uIGVhY2gob2JqLCBpdGVyYXRvciwgY29udGV4dCkge1xuICAgIHZhciBpO1xuXG4gICAgaWYgKCFvYmopIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChvYmouZm9yRWFjaCkge1xuICAgICAgICBvYmouZm9yRWFjaChpdGVyYXRvciwgY29udGV4dCk7XG4gICAgfSBlbHNlIGlmIChvYmoubGVuZ3RoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaSA9IDA7XG4gICAgICAgIHdoaWxlIChpIDwgb2JqLmxlbmd0aCkge1xuICAgICAgICAgICAgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaik7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgICBmb3IgKGkgaW4gb2JqKSB7XG4gICAgICAgICAgICBvYmouaGFzT3duUHJvcGVydHkoaSkgJiYgaXRlcmF0b3IuY2FsbChjb250ZXh0LCBvYmpbaV0sIGksIG9iaik7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8qKlxuICogd3JhcCBhIG1ldGhvZCB3aXRoIGEgZGVwcmVjYXRpb24gd2FybmluZyBhbmQgc3RhY2sgdHJhY2VcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1ldGhvZFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IEEgbmV3IGZ1bmN0aW9uIHdyYXBwaW5nIHRoZSBzdXBwbGllZCBtZXRob2QuXG4gKi9cbmZ1bmN0aW9uIGRlcHJlY2F0ZShtZXRob2QsIG5hbWUsIG1lc3NhZ2UpIHtcbiAgICB2YXIgZGVwcmVjYXRpb25NZXNzYWdlID0gJ0RFUFJFQ0FURUQgTUVUSE9EOiAnICsgbmFtZSArICdcXG4nICsgbWVzc2FnZSArICcgQVQgXFxuJztcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBlID0gbmV3IEVycm9yKCdnZXQtc3RhY2stdHJhY2UnKTtcbiAgICAgICAgdmFyIHN0YWNrID0gZSAmJiBlLnN0YWNrID8gZS5zdGFjay5yZXBsYWNlKC9eW15cXChdKz9bXFxuJF0vZ20sICcnKVxuICAgICAgICAgICAgLnJlcGxhY2UoL15cXHMrYXRcXHMrL2dtLCAnJylcbiAgICAgICAgICAgIC5yZXBsYWNlKC9eT2JqZWN0Ljxhbm9ueW1vdXM+XFxzKlxcKC9nbSwgJ3thbm9ueW1vdXN9KClAJykgOiAnVW5rbm93biBTdGFjayBUcmFjZSc7XG5cbiAgICAgICAgdmFyIGxvZyA9IHdpbmRvdy5jb25zb2xlICYmICh3aW5kb3cuY29uc29sZS53YXJuIHx8IHdpbmRvdy5jb25zb2xlLmxvZyk7XG4gICAgICAgIGlmIChsb2cpIHtcbiAgICAgICAgICAgIGxvZy5jYWxsKHdpbmRvdy5jb25zb2xlLCBkZXByZWNhdGlvbk1lc3NhZ2UsIHN0YWNrKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbWV0aG9kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbn1cblxuLyoqXG4gKiBleHRlbmQgb2JqZWN0LlxuICogbWVhbnMgdGhhdCBwcm9wZXJ0aWVzIGluIGRlc3Qgd2lsbCBiZSBvdmVyd3JpdHRlbiBieSB0aGUgb25lcyBpbiBzcmMuXG4gKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0gey4uLk9iamVjdH0gb2JqZWN0c190b19hc3NpZ25cbiAqIEByZXR1cm5zIHtPYmplY3R9IHRhcmdldFxuICovXG52YXIgYXNzaWduO1xuaWYgKHR5cGVvZiBPYmplY3QuYXNzaWduICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgYXNzaWduID0gZnVuY3Rpb24gYXNzaWduKHRhcmdldCkge1xuICAgICAgICBpZiAodGFyZ2V0ID09PSB1bmRlZmluZWQgfHwgdGFyZ2V0ID09PSBudWxsKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdDYW5ub3QgY29udmVydCB1bmRlZmluZWQgb3IgbnVsbCB0byBvYmplY3QnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBvdXRwdXQgPSBPYmplY3QodGFyZ2V0KTtcbiAgICAgICAgZm9yICh2YXIgaW5kZXggPSAxOyBpbmRleCA8IGFyZ3VtZW50cy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaW5kZXhdO1xuICAgICAgICAgICAgaWYgKHNvdXJjZSAhPT0gdW5kZWZpbmVkICYmIHNvdXJjZSAhPT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIG5leHRLZXkgaW4gc291cmNlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuaGFzT3duUHJvcGVydHkobmV4dEtleSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dFtuZXh0S2V5XSA9IHNvdXJjZVtuZXh0S2V5XTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgIH07XG59IGVsc2Uge1xuICAgIGFzc2lnbiA9IE9iamVjdC5hc3NpZ247XG59XG5cbi8qKlxuICogZXh0ZW5kIG9iamVjdC5cbiAqIG1lYW5zIHRoYXQgcHJvcGVydGllcyBpbiBkZXN0IHdpbGwgYmUgb3ZlcndyaXR0ZW4gYnkgdGhlIG9uZXMgaW4gc3JjLlxuICogQHBhcmFtIHtPYmplY3R9IGRlc3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBzcmNcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW21lcmdlPWZhbHNlXVxuICogQHJldHVybnMge09iamVjdH0gZGVzdFxuICovXG52YXIgZXh0ZW5kID0gZGVwcmVjYXRlKGZ1bmN0aW9uIGV4dGVuZChkZXN0LCBzcmMsIG1lcmdlKSB7XG4gICAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhzcmMpO1xuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IGtleXMubGVuZ3RoKSB7XG4gICAgICAgIGlmICghbWVyZ2UgfHwgKG1lcmdlICYmIGRlc3Rba2V5c1tpXV0gPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgICAgIGRlc3Rba2V5c1tpXV0gPSBzcmNba2V5c1tpXV07XG4gICAgICAgIH1cbiAgICAgICAgaSsrO1xuICAgIH1cbiAgICByZXR1cm4gZGVzdDtcbn0sICdleHRlbmQnLCAnVXNlIGBhc3NpZ25gLicpO1xuXG4vKipcbiAqIG1lcmdlIHRoZSB2YWx1ZXMgZnJvbSBzcmMgaW4gdGhlIGRlc3QuXG4gKiBtZWFucyB0aGF0IHByb3BlcnRpZXMgdGhhdCBleGlzdCBpbiBkZXN0IHdpbGwgbm90IGJlIG92ZXJ3cml0dGVuIGJ5IHNyY1xuICogQHBhcmFtIHtPYmplY3R9IGRlc3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBzcmNcbiAqIEByZXR1cm5zIHtPYmplY3R9IGRlc3RcbiAqL1xudmFyIG1lcmdlID0gZGVwcmVjYXRlKGZ1bmN0aW9uIG1lcmdlKGRlc3QsIHNyYykge1xuICAgIHJldHVybiBleHRlbmQoZGVzdCwgc3JjLCB0cnVlKTtcbn0sICdtZXJnZScsICdVc2UgYGFzc2lnbmAuJyk7XG5cbi8qKlxuICogc2ltcGxlIGNsYXNzIGluaGVyaXRhbmNlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjaGlsZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gYmFzZVxuICogQHBhcmFtIHtPYmplY3R9IFtwcm9wZXJ0aWVzXVxuICovXG5mdW5jdGlvbiBpbmhlcml0KGNoaWxkLCBiYXNlLCBwcm9wZXJ0aWVzKSB7XG4gICAgdmFyIGJhc2VQID0gYmFzZS5wcm90b3R5cGUsXG4gICAgICAgIGNoaWxkUDtcblxuICAgIGNoaWxkUCA9IGNoaWxkLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoYmFzZVApO1xuICAgIGNoaWxkUC5jb25zdHJ1Y3RvciA9IGNoaWxkO1xuICAgIGNoaWxkUC5fc3VwZXIgPSBiYXNlUDtcblxuICAgIGlmIChwcm9wZXJ0aWVzKSB7XG4gICAgICAgIGFzc2lnbihjaGlsZFAsIHByb3BlcnRpZXMpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBzaW1wbGUgZnVuY3Rpb24gYmluZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0XG4gKiBAcmV0dXJucyB7RnVuY3Rpb259XG4gKi9cbmZ1bmN0aW9uIGJpbmRGbihmbiwgY29udGV4dCkge1xuICAgIHJldHVybiBmdW5jdGlvbiBib3VuZEZuKCkge1xuICAgICAgICByZXR1cm4gZm4uYXBwbHkoY29udGV4dCwgYXJndW1lbnRzKTtcbiAgICB9O1xufVxuXG4vKipcbiAqIGxldCBhIGJvb2xlYW4gdmFsdWUgYWxzbyBiZSBhIGZ1bmN0aW9uIHRoYXQgbXVzdCByZXR1cm4gYSBib29sZWFuXG4gKiB0aGlzIGZpcnN0IGl0ZW0gaW4gYXJncyB3aWxsIGJlIHVzZWQgYXMgdGhlIGNvbnRleHRcbiAqIEBwYXJhbSB7Qm9vbGVhbnxGdW5jdGlvbn0gdmFsXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJnc11cbiAqIEByZXR1cm5zIHtCb29sZWFufVxuICovXG5mdW5jdGlvbiBib29sT3JGbih2YWwsIGFyZ3MpIHtcbiAgICBpZiAodHlwZW9mIHZhbCA9PSBUWVBFX0ZVTkNUSU9OKSB7XG4gICAgICAgIHJldHVybiB2YWwuYXBwbHkoYXJncyA/IGFyZ3NbMF0gfHwgdW5kZWZpbmVkIDogdW5kZWZpbmVkLCBhcmdzKTtcbiAgICB9XG4gICAgcmV0dXJuIHZhbDtcbn1cblxuLyoqXG4gKiB1c2UgdGhlIHZhbDIgd2hlbiB2YWwxIGlzIHVuZGVmaW5lZFxuICogQHBhcmFtIHsqfSB2YWwxXG4gKiBAcGFyYW0geyp9IHZhbDJcbiAqIEByZXR1cm5zIHsqfVxuICovXG5mdW5jdGlvbiBpZlVuZGVmaW5lZCh2YWwxLCB2YWwyKSB7XG4gICAgcmV0dXJuICh2YWwxID09PSB1bmRlZmluZWQpID8gdmFsMiA6IHZhbDE7XG59XG5cbi8qKlxuICogYWRkRXZlbnRMaXN0ZW5lciB3aXRoIG11bHRpcGxlIGV2ZW50cyBhdCBvbmNlXG4gKiBAcGFyYW0ge0V2ZW50VGFyZ2V0fSB0YXJnZXRcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuICovXG5mdW5jdGlvbiBhZGRFdmVudExpc3RlbmVycyh0YXJnZXQsIHR5cGVzLCBoYW5kbGVyKSB7XG4gICAgZWFjaChzcGxpdFN0cih0eXBlcyksIGZ1bmN0aW9uKHR5cGUpIHtcbiAgICAgICAgdGFyZ2V0LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgaGFuZGxlciwgZmFsc2UpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIHJlbW92ZUV2ZW50TGlzdGVuZXIgd2l0aCBtdWx0aXBsZSBldmVudHMgYXQgb25jZVxuICogQHBhcmFtIHtFdmVudFRhcmdldH0gdGFyZ2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZXNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXJcbiAqL1xuZnVuY3Rpb24gcmVtb3ZlRXZlbnRMaXN0ZW5lcnModGFyZ2V0LCB0eXBlcywgaGFuZGxlcikge1xuICAgIGVhY2goc3BsaXRTdHIodHlwZXMpLCBmdW5jdGlvbih0eXBlKSB7XG4gICAgICAgIHRhcmdldC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsIGhhbmRsZXIsIGZhbHNlKTtcbiAgICB9KTtcbn1cblxuLyoqXG4gKiBmaW5kIGlmIGEgbm9kZSBpcyBpbiB0aGUgZ2l2ZW4gcGFyZW50XG4gKiBAbWV0aG9kIGhhc1BhcmVudFxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gbm9kZVxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gcGFyZW50XG4gKiBAcmV0dXJuIHtCb29sZWFufSBmb3VuZFxuICovXG5mdW5jdGlvbiBoYXNQYXJlbnQobm9kZSwgcGFyZW50KSB7XG4gICAgd2hpbGUgKG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUgPT0gcGFyZW50KSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBub2RlID0gbm9kZS5wYXJlbnROb2RlO1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogc21hbGwgaW5kZXhPZiB3cmFwcGVyXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcGFyYW0ge1N0cmluZ30gZmluZFxuICogQHJldHVybnMge0Jvb2xlYW59IGZvdW5kXG4gKi9cbmZ1bmN0aW9uIGluU3RyKHN0ciwgZmluZCkge1xuICAgIHJldHVybiBzdHIuaW5kZXhPZihmaW5kKSA+IC0xO1xufVxuXG4vKipcbiAqIHNwbGl0IHN0cmluZyBvbiB3aGl0ZXNwYWNlXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gKiBAcmV0dXJucyB7QXJyYXl9IHdvcmRzXG4gKi9cbmZ1bmN0aW9uIHNwbGl0U3RyKHN0cikge1xuICAgIHJldHVybiBzdHIudHJpbSgpLnNwbGl0KC9cXHMrL2cpO1xufVxuXG4vKipcbiAqIGZpbmQgaWYgYSBhcnJheSBjb250YWlucyB0aGUgb2JqZWN0IHVzaW5nIGluZGV4T2Ygb3IgYSBzaW1wbGUgcG9seUZpbGxcbiAqIEBwYXJhbSB7QXJyYXl9IHNyY1xuICogQHBhcmFtIHtTdHJpbmd9IGZpbmRcbiAqIEBwYXJhbSB7U3RyaW5nfSBbZmluZEJ5S2V5XVxuICogQHJldHVybiB7Qm9vbGVhbnxOdW1iZXJ9IGZhbHNlIHdoZW4gbm90IGZvdW5kLCBvciB0aGUgaW5kZXhcbiAqL1xuZnVuY3Rpb24gaW5BcnJheShzcmMsIGZpbmQsIGZpbmRCeUtleSkge1xuICAgIGlmIChzcmMuaW5kZXhPZiAmJiAhZmluZEJ5S2V5KSB7XG4gICAgICAgIHJldHVybiBzcmMuaW5kZXhPZihmaW5kKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgIHdoaWxlIChpIDwgc3JjLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKChmaW5kQnlLZXkgJiYgc3JjW2ldW2ZpbmRCeUtleV0gPT0gZmluZCkgfHwgKCFmaW5kQnlLZXkgJiYgc3JjW2ldID09PSBmaW5kKSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAtMTtcbiAgICB9XG59XG5cbi8qKlxuICogY29udmVydCBhcnJheS1saWtlIG9iamVjdHMgdG8gcmVhbCBhcnJheXNcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqIEByZXR1cm5zIHtBcnJheX1cbiAqL1xuZnVuY3Rpb24gdG9BcnJheShvYmopIHtcbiAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwob2JqLCAwKTtcbn1cblxuLyoqXG4gKiB1bmlxdWUgYXJyYXkgd2l0aCBvYmplY3RzIGJhc2VkIG9uIGEga2V5IChsaWtlICdpZCcpIG9yIGp1c3QgYnkgdGhlIGFycmF5J3MgdmFsdWVcbiAqIEBwYXJhbSB7QXJyYXl9IHNyYyBbe2lkOjF9LHtpZDoyfSx7aWQ6MX1dXG4gKiBAcGFyYW0ge1N0cmluZ30gW2tleV1cbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW3NvcnQ9RmFsc2VdXG4gKiBAcmV0dXJucyB7QXJyYXl9IFt7aWQ6MX0se2lkOjJ9XVxuICovXG5mdW5jdGlvbiB1bmlxdWVBcnJheShzcmMsIGtleSwgc29ydCkge1xuICAgIHZhciByZXN1bHRzID0gW107XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIHZhciBpID0gMDtcblxuICAgIHdoaWxlIChpIDwgc3JjLmxlbmd0aCkge1xuICAgICAgICB2YXIgdmFsID0ga2V5ID8gc3JjW2ldW2tleV0gOiBzcmNbaV07XG4gICAgICAgIGlmIChpbkFycmF5KHZhbHVlcywgdmFsKSA8IDApIHtcbiAgICAgICAgICAgIHJlc3VsdHMucHVzaChzcmNbaV0pO1xuICAgICAgICB9XG4gICAgICAgIHZhbHVlc1tpXSA9IHZhbDtcbiAgICAgICAgaSsrO1xuICAgIH1cblxuICAgIGlmIChzb3J0KSB7XG4gICAgICAgIGlmICgha2V5KSB7XG4gICAgICAgICAgICByZXN1bHRzID0gcmVzdWx0cy5zb3J0KCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXN1bHRzID0gcmVzdWx0cy5zb3J0KGZ1bmN0aW9uIHNvcnRVbmlxdWVBcnJheShhLCBiKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFba2V5XSA+IGJba2V5XTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdHM7XG59XG5cbi8qKlxuICogZ2V0IHRoZSBwcmVmaXhlZCBwcm9wZXJ0eVxuICogQHBhcmFtIHtPYmplY3R9IG9ialxuICogQHBhcmFtIHtTdHJpbmd9IHByb3BlcnR5XG4gKiBAcmV0dXJucyB7U3RyaW5nfFVuZGVmaW5lZH0gcHJlZml4ZWRcbiAqL1xuZnVuY3Rpb24gcHJlZml4ZWQob2JqLCBwcm9wZXJ0eSkge1xuICAgIHZhciBwcmVmaXgsIHByb3A7XG4gICAgdmFyIGNhbWVsUHJvcCA9IHByb3BlcnR5WzBdLnRvVXBwZXJDYXNlKCkgKyBwcm9wZXJ0eS5zbGljZSgxKTtcblxuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IFZFTkRPUl9QUkVGSVhFUy5sZW5ndGgpIHtcbiAgICAgICAgcHJlZml4ID0gVkVORE9SX1BSRUZJWEVTW2ldO1xuICAgICAgICBwcm9wID0gKHByZWZpeCkgPyBwcmVmaXggKyBjYW1lbFByb3AgOiBwcm9wZXJ0eTtcblxuICAgICAgICBpZiAocHJvcCBpbiBvYmopIHtcbiAgICAgICAgICAgIHJldHVybiBwcm9wO1xuICAgICAgICB9XG4gICAgICAgIGkrKztcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBnZXQgYSB1bmlxdWUgaWRcbiAqIEByZXR1cm5zIHtudW1iZXJ9IHVuaXF1ZUlkXG4gKi9cbnZhciBfdW5pcXVlSWQgPSAxO1xuZnVuY3Rpb24gdW5pcXVlSWQoKSB7XG4gICAgcmV0dXJuIF91bmlxdWVJZCsrO1xufVxuXG4vKipcbiAqIGdldCB0aGUgd2luZG93IG9iamVjdCBvZiBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcmV0dXJucyB7RG9jdW1lbnRWaWV3fFdpbmRvd31cbiAqL1xuZnVuY3Rpb24gZ2V0V2luZG93Rm9yRWxlbWVudChlbGVtZW50KSB7XG4gICAgdmFyIGRvYyA9IGVsZW1lbnQub3duZXJEb2N1bWVudCB8fCBlbGVtZW50O1xuICAgIHJldHVybiAoZG9jLmRlZmF1bHRWaWV3IHx8IGRvYy5wYXJlbnRXaW5kb3cgfHwgd2luZG93KTtcbn1cblxudmFyIE1PQklMRV9SRUdFWCA9IC9tb2JpbGV8dGFibGV0fGlwKGFkfGhvbmV8b2QpfGFuZHJvaWQvaTtcblxudmFyIFNVUFBPUlRfVE9VQ0ggPSAoJ29udG91Y2hzdGFydCcgaW4gd2luZG93KTtcbnZhciBTVVBQT1JUX1BPSU5URVJfRVZFTlRTID0gcHJlZml4ZWQod2luZG93LCAnUG9pbnRlckV2ZW50JykgIT09IHVuZGVmaW5lZDtcbnZhciBTVVBQT1JUX09OTFlfVE9VQ0ggPSBTVVBQT1JUX1RPVUNIICYmIE1PQklMRV9SRUdFWC50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG52YXIgSU5QVVRfVFlQRV9UT1VDSCA9ICd0b3VjaCc7XG52YXIgSU5QVVRfVFlQRV9QRU4gPSAncGVuJztcbnZhciBJTlBVVF9UWVBFX01PVVNFID0gJ21vdXNlJztcbnZhciBJTlBVVF9UWVBFX0tJTkVDVCA9ICdraW5lY3QnO1xuXG52YXIgQ09NUFVURV9JTlRFUlZBTCA9IDI1O1xuXG52YXIgSU5QVVRfU1RBUlQgPSAxO1xudmFyIElOUFVUX01PVkUgPSAyO1xudmFyIElOUFVUX0VORCA9IDQ7XG52YXIgSU5QVVRfQ0FOQ0VMID0gODtcblxudmFyIERJUkVDVElPTl9OT05FID0gMTtcbnZhciBESVJFQ1RJT05fTEVGVCA9IDI7XG52YXIgRElSRUNUSU9OX1JJR0hUID0gNDtcbnZhciBESVJFQ1RJT05fVVAgPSA4O1xudmFyIERJUkVDVElPTl9ET1dOID0gMTY7XG5cbnZhciBESVJFQ1RJT05fSE9SSVpPTlRBTCA9IERJUkVDVElPTl9MRUZUIHwgRElSRUNUSU9OX1JJR0hUO1xudmFyIERJUkVDVElPTl9WRVJUSUNBTCA9IERJUkVDVElPTl9VUCB8IERJUkVDVElPTl9ET1dOO1xudmFyIERJUkVDVElPTl9BTEwgPSBESVJFQ1RJT05fSE9SSVpPTlRBTCB8IERJUkVDVElPTl9WRVJUSUNBTDtcblxudmFyIFBST1BTX1hZID0gWyd4JywgJ3knXTtcbnZhciBQUk9QU19DTElFTlRfWFkgPSBbJ2NsaWVudFgnLCAnY2xpZW50WSddO1xuXG4vKipcbiAqIGNyZWF0ZSBuZXcgaW5wdXQgdHlwZSBtYW5hZ2VyXG4gKiBAcGFyYW0ge01hbmFnZXJ9IG1hbmFnZXJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrXG4gKiBAcmV0dXJucyB7SW5wdXR9XG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gSW5wdXQobWFuYWdlciwgY2FsbGJhY2spIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdGhpcy5tYW5hZ2VyID0gbWFuYWdlcjtcbiAgICB0aGlzLmNhbGxiYWNrID0gY2FsbGJhY2s7XG4gICAgdGhpcy5lbGVtZW50ID0gbWFuYWdlci5lbGVtZW50O1xuICAgIHRoaXMudGFyZ2V0ID0gbWFuYWdlci5vcHRpb25zLmlucHV0VGFyZ2V0O1xuXG4gICAgLy8gc21hbGxlciB3cmFwcGVyIGFyb3VuZCB0aGUgaGFuZGxlciwgZm9yIHRoZSBzY29wZSBhbmQgdGhlIGVuYWJsZWQgc3RhdGUgb2YgdGhlIG1hbmFnZXIsXG4gICAgLy8gc28gd2hlbiBkaXNhYmxlZCB0aGUgaW5wdXQgZXZlbnRzIGFyZSBjb21wbGV0ZWx5IGJ5cGFzc2VkLlxuICAgIHRoaXMuZG9tSGFuZGxlciA9IGZ1bmN0aW9uKGV2KSB7XG4gICAgICAgIGlmIChib29sT3JGbihtYW5hZ2VyLm9wdGlvbnMuZW5hYmxlLCBbbWFuYWdlcl0pKSB7XG4gICAgICAgICAgICBzZWxmLmhhbmRsZXIoZXYpO1xuICAgICAgICB9XG4gICAgfTtcblxuICAgIHRoaXMuaW5pdCgpO1xuXG59XG5cbklucHV0LnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBzaG91bGQgaGFuZGxlIHRoZSBpbnB1dEV2ZW50IGRhdGEgYW5kIHRyaWdnZXIgdGhlIGNhbGxiYWNrXG4gICAgICogQHZpcnR1YWxcbiAgICAgKi9cbiAgICBoYW5kbGVyOiBmdW5jdGlvbigpIHsgfSxcblxuICAgIC8qKlxuICAgICAqIGJpbmQgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIGluaXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLmV2RWwgJiYgYWRkRXZlbnRMaXN0ZW5lcnModGhpcy5lbGVtZW50LCB0aGlzLmV2RWwsIHRoaXMuZG9tSGFuZGxlcik7XG4gICAgICAgIHRoaXMuZXZUYXJnZXQgJiYgYWRkRXZlbnRMaXN0ZW5lcnModGhpcy50YXJnZXQsIHRoaXMuZXZUYXJnZXQsIHRoaXMuZG9tSGFuZGxlcik7XG4gICAgICAgIHRoaXMuZXZXaW4gJiYgYWRkRXZlbnRMaXN0ZW5lcnMoZ2V0V2luZG93Rm9yRWxlbWVudCh0aGlzLmVsZW1lbnQpLCB0aGlzLmV2V2luLCB0aGlzLmRvbUhhbmRsZXIpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiB1bmJpbmQgdGhlIGV2ZW50c1xuICAgICAqL1xuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLmV2RWwgJiYgcmVtb3ZlRXZlbnRMaXN0ZW5lcnModGhpcy5lbGVtZW50LCB0aGlzLmV2RWwsIHRoaXMuZG9tSGFuZGxlcik7XG4gICAgICAgIHRoaXMuZXZUYXJnZXQgJiYgcmVtb3ZlRXZlbnRMaXN0ZW5lcnModGhpcy50YXJnZXQsIHRoaXMuZXZUYXJnZXQsIHRoaXMuZG9tSGFuZGxlcik7XG4gICAgICAgIHRoaXMuZXZXaW4gJiYgcmVtb3ZlRXZlbnRMaXN0ZW5lcnMoZ2V0V2luZG93Rm9yRWxlbWVudCh0aGlzLmVsZW1lbnQpLCB0aGlzLmV2V2luLCB0aGlzLmRvbUhhbmRsZXIpO1xuICAgIH1cbn07XG5cbi8qKlxuICogY3JlYXRlIG5ldyBpbnB1dCB0eXBlIG1hbmFnZXJcbiAqIGNhbGxlZCBieSB0aGUgTWFuYWdlciBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtIYW1tZXJ9IG1hbmFnZXJcbiAqIEByZXR1cm5zIHtJbnB1dH1cbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5wdXRJbnN0YW5jZShtYW5hZ2VyKSB7XG4gICAgdmFyIFR5cGU7XG4gICAgdmFyIGlucHV0Q2xhc3MgPSBtYW5hZ2VyLm9wdGlvbnMuaW5wdXRDbGFzcztcblxuICAgIGlmIChpbnB1dENsYXNzKSB7XG4gICAgICAgIFR5cGUgPSBpbnB1dENsYXNzO1xuICAgIH0gZWxzZSBpZiAoU1VQUE9SVF9QT0lOVEVSX0VWRU5UUykge1xuICAgICAgICBUeXBlID0gUG9pbnRlckV2ZW50SW5wdXQ7XG4gICAgfSBlbHNlIGlmIChTVVBQT1JUX09OTFlfVE9VQ0gpIHtcbiAgICAgICAgVHlwZSA9IFRvdWNoSW5wdXQ7XG4gICAgfSBlbHNlIGlmICghU1VQUE9SVF9UT1VDSCkge1xuICAgICAgICBUeXBlID0gTW91c2VJbnB1dDtcbiAgICB9IGVsc2Uge1xuICAgICAgICBUeXBlID0gVG91Y2hNb3VzZUlucHV0O1xuICAgIH1cbiAgICByZXR1cm4gbmV3IChUeXBlKShtYW5hZ2VyLCBpbnB1dEhhbmRsZXIpO1xufVxuXG4vKipcbiAqIGhhbmRsZSBpbnB1dCBldmVudHNcbiAqIEBwYXJhbSB7TWFuYWdlcn0gbWFuYWdlclxuICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50VHlwZVxuICogQHBhcmFtIHtPYmplY3R9IGlucHV0XG4gKi9cbmZ1bmN0aW9uIGlucHV0SGFuZGxlcihtYW5hZ2VyLCBldmVudFR5cGUsIGlucHV0KSB7XG4gICAgdmFyIHBvaW50ZXJzTGVuID0gaW5wdXQucG9pbnRlcnMubGVuZ3RoO1xuICAgIHZhciBjaGFuZ2VkUG9pbnRlcnNMZW4gPSBpbnB1dC5jaGFuZ2VkUG9pbnRlcnMubGVuZ3RoO1xuICAgIHZhciBpc0ZpcnN0ID0gKGV2ZW50VHlwZSAmIElOUFVUX1NUQVJUICYmIChwb2ludGVyc0xlbiAtIGNoYW5nZWRQb2ludGVyc0xlbiA9PT0gMCkpO1xuICAgIHZhciBpc0ZpbmFsID0gKGV2ZW50VHlwZSAmIChJTlBVVF9FTkQgfCBJTlBVVF9DQU5DRUwpICYmIChwb2ludGVyc0xlbiAtIGNoYW5nZWRQb2ludGVyc0xlbiA9PT0gMCkpO1xuXG4gICAgaW5wdXQuaXNGaXJzdCA9ICEhaXNGaXJzdDtcbiAgICBpbnB1dC5pc0ZpbmFsID0gISFpc0ZpbmFsO1xuXG4gICAgaWYgKGlzRmlyc3QpIHtcbiAgICAgICAgbWFuYWdlci5zZXNzaW9uID0ge307XG4gICAgfVxuXG4gICAgLy8gc291cmNlIGV2ZW50IGlzIHRoZSBub3JtYWxpemVkIHZhbHVlIG9mIHRoZSBkb21FdmVudHNcbiAgICAvLyBsaWtlICd0b3VjaHN0YXJ0LCBtb3VzZXVwLCBwb2ludGVyZG93bidcbiAgICBpbnB1dC5ldmVudFR5cGUgPSBldmVudFR5cGU7XG5cbiAgICAvLyBjb21wdXRlIHNjYWxlLCByb3RhdGlvbiBldGNcbiAgICBjb21wdXRlSW5wdXREYXRhKG1hbmFnZXIsIGlucHV0KTtcblxuICAgIC8vIGVtaXQgc2VjcmV0IGV2ZW50XG4gICAgbWFuYWdlci5lbWl0KCdoYW1tZXIuaW5wdXQnLCBpbnB1dCk7XG5cbiAgICBtYW5hZ2VyLnJlY29nbml6ZShpbnB1dCk7XG4gICAgbWFuYWdlci5zZXNzaW9uLnByZXZJbnB1dCA9IGlucHV0O1xufVxuXG4vKipcbiAqIGV4dGVuZCB0aGUgZGF0YSB3aXRoIHNvbWUgdXNhYmxlIHByb3BlcnRpZXMgbGlrZSBzY2FsZSwgcm90YXRlLCB2ZWxvY2l0eSBldGNcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYW5hZ2VyXG4gKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAqL1xuZnVuY3Rpb24gY29tcHV0ZUlucHV0RGF0YShtYW5hZ2VyLCBpbnB1dCkge1xuICAgIHZhciBzZXNzaW9uID0gbWFuYWdlci5zZXNzaW9uO1xuICAgIHZhciBwb2ludGVycyA9IGlucHV0LnBvaW50ZXJzO1xuICAgIHZhciBwb2ludGVyc0xlbmd0aCA9IHBvaW50ZXJzLmxlbmd0aDtcblxuICAgIC8vIHN0b3JlIHRoZSBmaXJzdCBpbnB1dCB0byBjYWxjdWxhdGUgdGhlIGRpc3RhbmNlIGFuZCBkaXJlY3Rpb25cbiAgICBpZiAoIXNlc3Npb24uZmlyc3RJbnB1dCkge1xuICAgICAgICBzZXNzaW9uLmZpcnN0SW5wdXQgPSBzaW1wbGVDbG9uZUlucHV0RGF0YShpbnB1dCk7XG4gICAgfVxuXG4gICAgLy8gdG8gY29tcHV0ZSBzY2FsZSBhbmQgcm90YXRpb24gd2UgbmVlZCB0byBzdG9yZSB0aGUgbXVsdGlwbGUgdG91Y2hlc1xuICAgIGlmIChwb2ludGVyc0xlbmd0aCA+IDEgJiYgIXNlc3Npb24uZmlyc3RNdWx0aXBsZSkge1xuICAgICAgICBzZXNzaW9uLmZpcnN0TXVsdGlwbGUgPSBzaW1wbGVDbG9uZUlucHV0RGF0YShpbnB1dCk7XG4gICAgfSBlbHNlIGlmIChwb2ludGVyc0xlbmd0aCA9PT0gMSkge1xuICAgICAgICBzZXNzaW9uLmZpcnN0TXVsdGlwbGUgPSBmYWxzZTtcbiAgICB9XG5cbiAgICB2YXIgZmlyc3RJbnB1dCA9IHNlc3Npb24uZmlyc3RJbnB1dDtcbiAgICB2YXIgZmlyc3RNdWx0aXBsZSA9IHNlc3Npb24uZmlyc3RNdWx0aXBsZTtcbiAgICB2YXIgb2Zmc2V0Q2VudGVyID0gZmlyc3RNdWx0aXBsZSA/IGZpcnN0TXVsdGlwbGUuY2VudGVyIDogZmlyc3RJbnB1dC5jZW50ZXI7XG5cbiAgICB2YXIgY2VudGVyID0gaW5wdXQuY2VudGVyID0gZ2V0Q2VudGVyKHBvaW50ZXJzKTtcbiAgICBpbnB1dC50aW1lU3RhbXAgPSBub3coKTtcbiAgICBpbnB1dC5kZWx0YVRpbWUgPSBpbnB1dC50aW1lU3RhbXAgLSBmaXJzdElucHV0LnRpbWVTdGFtcDtcblxuICAgIGlucHV0LmFuZ2xlID0gZ2V0QW5nbGUob2Zmc2V0Q2VudGVyLCBjZW50ZXIpO1xuICAgIGlucHV0LmRpc3RhbmNlID0gZ2V0RGlzdGFuY2Uob2Zmc2V0Q2VudGVyLCBjZW50ZXIpO1xuXG4gICAgY29tcHV0ZURlbHRhWFkoc2Vzc2lvbiwgaW5wdXQpO1xuICAgIGlucHV0Lm9mZnNldERpcmVjdGlvbiA9IGdldERpcmVjdGlvbihpbnB1dC5kZWx0YVgsIGlucHV0LmRlbHRhWSk7XG5cbiAgICB2YXIgb3ZlcmFsbFZlbG9jaXR5ID0gZ2V0VmVsb2NpdHkoaW5wdXQuZGVsdGFUaW1lLCBpbnB1dC5kZWx0YVgsIGlucHV0LmRlbHRhWSk7XG4gICAgaW5wdXQub3ZlcmFsbFZlbG9jaXR5WCA9IG92ZXJhbGxWZWxvY2l0eS54O1xuICAgIGlucHV0Lm92ZXJhbGxWZWxvY2l0eVkgPSBvdmVyYWxsVmVsb2NpdHkueTtcbiAgICBpbnB1dC5vdmVyYWxsVmVsb2NpdHkgPSAoYWJzKG92ZXJhbGxWZWxvY2l0eS54KSA+IGFicyhvdmVyYWxsVmVsb2NpdHkueSkpID8gb3ZlcmFsbFZlbG9jaXR5LnggOiBvdmVyYWxsVmVsb2NpdHkueTtcblxuICAgIGlucHV0LnNjYWxlID0gZmlyc3RNdWx0aXBsZSA/IGdldFNjYWxlKGZpcnN0TXVsdGlwbGUucG9pbnRlcnMsIHBvaW50ZXJzKSA6IDE7XG4gICAgaW5wdXQucm90YXRpb24gPSBmaXJzdE11bHRpcGxlID8gZ2V0Um90YXRpb24oZmlyc3RNdWx0aXBsZS5wb2ludGVycywgcG9pbnRlcnMpIDogMDtcblxuICAgIGlucHV0Lm1heFBvaW50ZXJzID0gIXNlc3Npb24ucHJldklucHV0ID8gaW5wdXQucG9pbnRlcnMubGVuZ3RoIDogKChpbnB1dC5wb2ludGVycy5sZW5ndGggPlxuICAgICAgICBzZXNzaW9uLnByZXZJbnB1dC5tYXhQb2ludGVycykgPyBpbnB1dC5wb2ludGVycy5sZW5ndGggOiBzZXNzaW9uLnByZXZJbnB1dC5tYXhQb2ludGVycyk7XG5cbiAgICBjb21wdXRlSW50ZXJ2YWxJbnB1dERhdGEoc2Vzc2lvbiwgaW5wdXQpO1xuXG4gICAgLy8gZmluZCB0aGUgY29ycmVjdCB0YXJnZXRcbiAgICB2YXIgdGFyZ2V0ID0gbWFuYWdlci5lbGVtZW50O1xuICAgIGlmIChoYXNQYXJlbnQoaW5wdXQuc3JjRXZlbnQudGFyZ2V0LCB0YXJnZXQpKSB7XG4gICAgICAgIHRhcmdldCA9IGlucHV0LnNyY0V2ZW50LnRhcmdldDtcbiAgICB9XG4gICAgaW5wdXQudGFyZ2V0ID0gdGFyZ2V0O1xufVxuXG5mdW5jdGlvbiBjb21wdXRlRGVsdGFYWShzZXNzaW9uLCBpbnB1dCkge1xuICAgIHZhciBjZW50ZXIgPSBpbnB1dC5jZW50ZXI7XG4gICAgdmFyIG9mZnNldCA9IHNlc3Npb24ub2Zmc2V0RGVsdGEgfHwge307XG4gICAgdmFyIHByZXZEZWx0YSA9IHNlc3Npb24ucHJldkRlbHRhIHx8IHt9O1xuICAgIHZhciBwcmV2SW5wdXQgPSBzZXNzaW9uLnByZXZJbnB1dCB8fCB7fTtcblxuICAgIGlmIChpbnB1dC5ldmVudFR5cGUgPT09IElOUFVUX1NUQVJUIHx8IHByZXZJbnB1dC5ldmVudFR5cGUgPT09IElOUFVUX0VORCkge1xuICAgICAgICBwcmV2RGVsdGEgPSBzZXNzaW9uLnByZXZEZWx0YSA9IHtcbiAgICAgICAgICAgIHg6IHByZXZJbnB1dC5kZWx0YVggfHwgMCxcbiAgICAgICAgICAgIHk6IHByZXZJbnB1dC5kZWx0YVkgfHwgMFxuICAgICAgICB9O1xuXG4gICAgICAgIG9mZnNldCA9IHNlc3Npb24ub2Zmc2V0RGVsdGEgPSB7XG4gICAgICAgICAgICB4OiBjZW50ZXIueCxcbiAgICAgICAgICAgIHk6IGNlbnRlci55XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgaW5wdXQuZGVsdGFYID0gcHJldkRlbHRhLnggKyAoY2VudGVyLnggLSBvZmZzZXQueCk7XG4gICAgaW5wdXQuZGVsdGFZID0gcHJldkRlbHRhLnkgKyAoY2VudGVyLnkgLSBvZmZzZXQueSk7XG59XG5cbi8qKlxuICogdmVsb2NpdHkgaXMgY2FsY3VsYXRlZCBldmVyeSB4IG1zXG4gKiBAcGFyYW0ge09iamVjdH0gc2Vzc2lvblxuICogQHBhcmFtIHtPYmplY3R9IGlucHV0XG4gKi9cbmZ1bmN0aW9uIGNvbXB1dGVJbnRlcnZhbElucHV0RGF0YShzZXNzaW9uLCBpbnB1dCkge1xuICAgIHZhciBsYXN0ID0gc2Vzc2lvbi5sYXN0SW50ZXJ2YWwgfHwgaW5wdXQsXG4gICAgICAgIGRlbHRhVGltZSA9IGlucHV0LnRpbWVTdGFtcCAtIGxhc3QudGltZVN0YW1wLFxuICAgICAgICB2ZWxvY2l0eSwgdmVsb2NpdHlYLCB2ZWxvY2l0eVksIGRpcmVjdGlvbjtcblxuICAgIGlmIChpbnB1dC5ldmVudFR5cGUgIT0gSU5QVVRfQ0FOQ0VMICYmIChkZWx0YVRpbWUgPiBDT01QVVRFX0lOVEVSVkFMIHx8IGxhc3QudmVsb2NpdHkgPT09IHVuZGVmaW5lZCkpIHtcbiAgICAgICAgdmFyIGRlbHRhWCA9IGlucHV0LmRlbHRhWCAtIGxhc3QuZGVsdGFYO1xuICAgICAgICB2YXIgZGVsdGFZID0gaW5wdXQuZGVsdGFZIC0gbGFzdC5kZWx0YVk7XG5cbiAgICAgICAgdmFyIHYgPSBnZXRWZWxvY2l0eShkZWx0YVRpbWUsIGRlbHRhWCwgZGVsdGFZKTtcbiAgICAgICAgdmVsb2NpdHlYID0gdi54O1xuICAgICAgICB2ZWxvY2l0eVkgPSB2Lnk7XG4gICAgICAgIHZlbG9jaXR5ID0gKGFicyh2LngpID4gYWJzKHYueSkpID8gdi54IDogdi55O1xuICAgICAgICBkaXJlY3Rpb24gPSBnZXREaXJlY3Rpb24oZGVsdGFYLCBkZWx0YVkpO1xuXG4gICAgICAgIHNlc3Npb24ubGFzdEludGVydmFsID0gaW5wdXQ7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gdXNlIGxhdGVzdCB2ZWxvY2l0eSBpbmZvIGlmIGl0IGRvZXNuJ3Qgb3ZlcnRha2UgYSBtaW5pbXVtIHBlcmlvZFxuICAgICAgICB2ZWxvY2l0eSA9IGxhc3QudmVsb2NpdHk7XG4gICAgICAgIHZlbG9jaXR5WCA9IGxhc3QudmVsb2NpdHlYO1xuICAgICAgICB2ZWxvY2l0eVkgPSBsYXN0LnZlbG9jaXR5WTtcbiAgICAgICAgZGlyZWN0aW9uID0gbGFzdC5kaXJlY3Rpb247XG4gICAgfVxuXG4gICAgaW5wdXQudmVsb2NpdHkgPSB2ZWxvY2l0eTtcbiAgICBpbnB1dC52ZWxvY2l0eVggPSB2ZWxvY2l0eVg7XG4gICAgaW5wdXQudmVsb2NpdHlZID0gdmVsb2NpdHlZO1xuICAgIGlucHV0LmRpcmVjdGlvbiA9IGRpcmVjdGlvbjtcbn1cblxuLyoqXG4gKiBjcmVhdGUgYSBzaW1wbGUgY2xvbmUgZnJvbSB0aGUgaW5wdXQgdXNlZCBmb3Igc3RvcmFnZSBvZiBmaXJzdElucHV0IGFuZCBmaXJzdE11bHRpcGxlXG4gKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAqIEByZXR1cm5zIHtPYmplY3R9IGNsb25lZElucHV0RGF0YVxuICovXG5mdW5jdGlvbiBzaW1wbGVDbG9uZUlucHV0RGF0YShpbnB1dCkge1xuICAgIC8vIG1ha2UgYSBzaW1wbGUgY29weSBvZiB0aGUgcG9pbnRlcnMgYmVjYXVzZSB3ZSB3aWxsIGdldCBhIHJlZmVyZW5jZSBpZiB3ZSBkb24ndFxuICAgIC8vIHdlIG9ubHkgbmVlZCBjbGllbnRYWSBmb3IgdGhlIGNhbGN1bGF0aW9uc1xuICAgIHZhciBwb2ludGVycyA9IFtdO1xuICAgIHZhciBpID0gMDtcbiAgICB3aGlsZSAoaSA8IGlucHV0LnBvaW50ZXJzLmxlbmd0aCkge1xuICAgICAgICBwb2ludGVyc1tpXSA9IHtcbiAgICAgICAgICAgIGNsaWVudFg6IHJvdW5kKGlucHV0LnBvaW50ZXJzW2ldLmNsaWVudFgpLFxuICAgICAgICAgICAgY2xpZW50WTogcm91bmQoaW5wdXQucG9pbnRlcnNbaV0uY2xpZW50WSlcbiAgICAgICAgfTtcbiAgICAgICAgaSsrO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHRpbWVTdGFtcDogbm93KCksXG4gICAgICAgIHBvaW50ZXJzOiBwb2ludGVycyxcbiAgICAgICAgY2VudGVyOiBnZXRDZW50ZXIocG9pbnRlcnMpLFxuICAgICAgICBkZWx0YVg6IGlucHV0LmRlbHRhWCxcbiAgICAgICAgZGVsdGFZOiBpbnB1dC5kZWx0YVlcbiAgICB9O1xufVxuXG4vKipcbiAqIGdldCB0aGUgY2VudGVyIG9mIGFsbCB0aGUgcG9pbnRlcnNcbiAqIEBwYXJhbSB7QXJyYXl9IHBvaW50ZXJzXG4gKiBAcmV0dXJuIHtPYmplY3R9IGNlbnRlciBjb250YWlucyBgeGAgYW5kIGB5YCBwcm9wZXJ0aWVzXG4gKi9cbmZ1bmN0aW9uIGdldENlbnRlcihwb2ludGVycykge1xuICAgIHZhciBwb2ludGVyc0xlbmd0aCA9IHBvaW50ZXJzLmxlbmd0aDtcblxuICAgIC8vIG5vIG5lZWQgdG8gbG9vcCB3aGVuIG9ubHkgb25lIHRvdWNoXG4gICAgaWYgKHBvaW50ZXJzTGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB4OiByb3VuZChwb2ludGVyc1swXS5jbGllbnRYKSxcbiAgICAgICAgICAgIHk6IHJvdW5kKHBvaW50ZXJzWzBdLmNsaWVudFkpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgdmFyIHggPSAwLCB5ID0gMCwgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBwb2ludGVyc0xlbmd0aCkge1xuICAgICAgICB4ICs9IHBvaW50ZXJzW2ldLmNsaWVudFg7XG4gICAgICAgIHkgKz0gcG9pbnRlcnNbaV0uY2xpZW50WTtcbiAgICAgICAgaSsrO1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAgIHg6IHJvdW5kKHggLyBwb2ludGVyc0xlbmd0aCksXG4gICAgICAgIHk6IHJvdW5kKHkgLyBwb2ludGVyc0xlbmd0aClcbiAgICB9O1xufVxuXG4vKipcbiAqIGNhbGN1bGF0ZSB0aGUgdmVsb2NpdHkgYmV0d2VlbiB0d28gcG9pbnRzLiB1bml0IGlzIGluIHB4IHBlciBtcy5cbiAqIEBwYXJhbSB7TnVtYmVyfSBkZWx0YVRpbWVcbiAqIEBwYXJhbSB7TnVtYmVyfSB4XG4gKiBAcGFyYW0ge051bWJlcn0geVxuICogQHJldHVybiB7T2JqZWN0fSB2ZWxvY2l0eSBgeGAgYW5kIGB5YFxuICovXG5mdW5jdGlvbiBnZXRWZWxvY2l0eShkZWx0YVRpbWUsIHgsIHkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgICB4OiB4IC8gZGVsdGFUaW1lIHx8IDAsXG4gICAgICAgIHk6IHkgLyBkZWx0YVRpbWUgfHwgMFxuICAgIH07XG59XG5cbi8qKlxuICogZ2V0IHRoZSBkaXJlY3Rpb24gYmV0d2VlbiB0d28gcG9pbnRzXG4gKiBAcGFyYW0ge051bWJlcn0geFxuICogQHBhcmFtIHtOdW1iZXJ9IHlcbiAqIEByZXR1cm4ge051bWJlcn0gZGlyZWN0aW9uXG4gKi9cbmZ1bmN0aW9uIGdldERpcmVjdGlvbih4LCB5KSB7XG4gICAgaWYgKHggPT09IHkpIHtcbiAgICAgICAgcmV0dXJuIERJUkVDVElPTl9OT05FO1xuICAgIH1cblxuICAgIGlmIChhYnMoeCkgPj0gYWJzKHkpKSB7XG4gICAgICAgIHJldHVybiB4IDwgMCA/IERJUkVDVElPTl9MRUZUIDogRElSRUNUSU9OX1JJR0hUO1xuICAgIH1cbiAgICByZXR1cm4geSA8IDAgPyBESVJFQ1RJT05fVVAgOiBESVJFQ1RJT05fRE9XTjtcbn1cblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIGFic29sdXRlIGRpc3RhbmNlIGJldHdlZW4gdHdvIHBvaW50c1xuICogQHBhcmFtIHtPYmplY3R9IHAxIHt4LCB5fVxuICogQHBhcmFtIHtPYmplY3R9IHAyIHt4LCB5fVxuICogQHBhcmFtIHtBcnJheX0gW3Byb3BzXSBjb250YWluaW5nIHggYW5kIHkga2V5c1xuICogQHJldHVybiB7TnVtYmVyfSBkaXN0YW5jZVxuICovXG5mdW5jdGlvbiBnZXREaXN0YW5jZShwMSwgcDIsIHByb3BzKSB7XG4gICAgaWYgKCFwcm9wcykge1xuICAgICAgICBwcm9wcyA9IFBST1BTX1hZO1xuICAgIH1cbiAgICB2YXIgeCA9IHAyW3Byb3BzWzBdXSAtIHAxW3Byb3BzWzBdXSxcbiAgICAgICAgeSA9IHAyW3Byb3BzWzFdXSAtIHAxW3Byb3BzWzFdXTtcblxuICAgIHJldHVybiBNYXRoLnNxcnQoKHggKiB4KSArICh5ICogeSkpO1xufVxuXG4vKipcbiAqIGNhbGN1bGF0ZSB0aGUgYW5nbGUgYmV0d2VlbiB0d28gY29vcmRpbmF0ZXNcbiAqIEBwYXJhbSB7T2JqZWN0fSBwMVxuICogQHBhcmFtIHtPYmplY3R9IHAyXG4gKiBAcGFyYW0ge0FycmF5fSBbcHJvcHNdIGNvbnRhaW5pbmcgeCBhbmQgeSBrZXlzXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IGFuZ2xlXG4gKi9cbmZ1bmN0aW9uIGdldEFuZ2xlKHAxLCBwMiwgcHJvcHMpIHtcbiAgICBpZiAoIXByb3BzKSB7XG4gICAgICAgIHByb3BzID0gUFJPUFNfWFk7XG4gICAgfVxuICAgIHZhciB4ID0gcDJbcHJvcHNbMF1dIC0gcDFbcHJvcHNbMF1dLFxuICAgICAgICB5ID0gcDJbcHJvcHNbMV1dIC0gcDFbcHJvcHNbMV1dO1xuICAgIHJldHVybiBNYXRoLmF0YW4yKHksIHgpICogMTgwIC8gTWF0aC5QSTtcbn1cblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIHJvdGF0aW9uIGRlZ3JlZXMgYmV0d2VlbiB0d28gcG9pbnRlcnNldHNcbiAqIEBwYXJhbSB7QXJyYXl9IHN0YXJ0IGFycmF5IG9mIHBvaW50ZXJzXG4gKiBAcGFyYW0ge0FycmF5fSBlbmQgYXJyYXkgb2YgcG9pbnRlcnNcbiAqIEByZXR1cm4ge051bWJlcn0gcm90YXRpb25cbiAqL1xuZnVuY3Rpb24gZ2V0Um90YXRpb24oc3RhcnQsIGVuZCkge1xuICAgIHJldHVybiBnZXRBbmdsZShlbmRbMV0sIGVuZFswXSwgUFJPUFNfQ0xJRU5UX1hZKSArIGdldEFuZ2xlKHN0YXJ0WzFdLCBzdGFydFswXSwgUFJPUFNfQ0xJRU5UX1hZKTtcbn1cblxuLyoqXG4gKiBjYWxjdWxhdGUgdGhlIHNjYWxlIGZhY3RvciBiZXR3ZWVuIHR3byBwb2ludGVyc2V0c1xuICogbm8gc2NhbGUgaXMgMSwgYW5kIGdvZXMgZG93biB0byAwIHdoZW4gcGluY2hlZCB0b2dldGhlciwgYW5kIGJpZ2dlciB3aGVuIHBpbmNoZWQgb3V0XG4gKiBAcGFyYW0ge0FycmF5fSBzdGFydCBhcnJheSBvZiBwb2ludGVyc1xuICogQHBhcmFtIHtBcnJheX0gZW5kIGFycmF5IG9mIHBvaW50ZXJzXG4gKiBAcmV0dXJuIHtOdW1iZXJ9IHNjYWxlXG4gKi9cbmZ1bmN0aW9uIGdldFNjYWxlKHN0YXJ0LCBlbmQpIHtcbiAgICByZXR1cm4gZ2V0RGlzdGFuY2UoZW5kWzBdLCBlbmRbMV0sIFBST1BTX0NMSUVOVF9YWSkgLyBnZXREaXN0YW5jZShzdGFydFswXSwgc3RhcnRbMV0sIFBST1BTX0NMSUVOVF9YWSk7XG59XG5cbnZhciBNT1VTRV9JTlBVVF9NQVAgPSB7XG4gICAgbW91c2Vkb3duOiBJTlBVVF9TVEFSVCxcbiAgICBtb3VzZW1vdmU6IElOUFVUX01PVkUsXG4gICAgbW91c2V1cDogSU5QVVRfRU5EXG59O1xuXG52YXIgTU9VU0VfRUxFTUVOVF9FVkVOVFMgPSAnbW91c2Vkb3duJztcbnZhciBNT1VTRV9XSU5ET1dfRVZFTlRTID0gJ21vdXNlbW92ZSBtb3VzZXVwJztcblxuLyoqXG4gKiBNb3VzZSBldmVudHMgaW5wdXRcbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgSW5wdXRcbiAqL1xuZnVuY3Rpb24gTW91c2VJbnB1dCgpIHtcbiAgICB0aGlzLmV2RWwgPSBNT1VTRV9FTEVNRU5UX0VWRU5UUztcbiAgICB0aGlzLmV2V2luID0gTU9VU0VfV0lORE9XX0VWRU5UUztcblxuICAgIHRoaXMucHJlc3NlZCA9IGZhbHNlOyAvLyBtb3VzZWRvd24gc3RhdGVcblxuICAgIElucHV0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbmluaGVyaXQoTW91c2VJbnB1dCwgSW5wdXQsIHtcbiAgICAvKipcbiAgICAgKiBoYW5kbGUgbW91c2UgZXZlbnRzXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAgICovXG4gICAgaGFuZGxlcjogZnVuY3Rpb24gTUVoYW5kbGVyKGV2KSB7XG4gICAgICAgIHZhciBldmVudFR5cGUgPSBNT1VTRV9JTlBVVF9NQVBbZXYudHlwZV07XG5cbiAgICAgICAgLy8gb24gc3RhcnQgd2Ugd2FudCB0byBoYXZlIHRoZSBsZWZ0IG1vdXNlIGJ1dHRvbiBkb3duXG4gICAgICAgIGlmIChldmVudFR5cGUgJiBJTlBVVF9TVEFSVCAmJiBldi5idXR0b24gPT09IDApIHtcbiAgICAgICAgICAgIHRoaXMucHJlc3NlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnRUeXBlICYgSU5QVVRfTU9WRSAmJiBldi53aGljaCAhPT0gMSkge1xuICAgICAgICAgICAgZXZlbnRUeXBlID0gSU5QVVRfRU5EO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbW91c2UgbXVzdCBiZSBkb3duXG4gICAgICAgIGlmICghdGhpcy5wcmVzc2VkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZXZlbnRUeXBlICYgSU5QVVRfRU5EKSB7XG4gICAgICAgICAgICB0aGlzLnByZXNzZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FsbGJhY2sodGhpcy5tYW5hZ2VyLCBldmVudFR5cGUsIHtcbiAgICAgICAgICAgIHBvaW50ZXJzOiBbZXZdLFxuICAgICAgICAgICAgY2hhbmdlZFBvaW50ZXJzOiBbZXZdLFxuICAgICAgICAgICAgcG9pbnRlclR5cGU6IElOUFVUX1RZUEVfTU9VU0UsXG4gICAgICAgICAgICBzcmNFdmVudDogZXZcbiAgICAgICAgfSk7XG4gICAgfVxufSk7XG5cbnZhciBQT0lOVEVSX0lOUFVUX01BUCA9IHtcbiAgICBwb2ludGVyZG93bjogSU5QVVRfU1RBUlQsXG4gICAgcG9pbnRlcm1vdmU6IElOUFVUX01PVkUsXG4gICAgcG9pbnRlcnVwOiBJTlBVVF9FTkQsXG4gICAgcG9pbnRlcmNhbmNlbDogSU5QVVRfQ0FOQ0VMLFxuICAgIHBvaW50ZXJvdXQ6IElOUFVUX0NBTkNFTFxufTtcblxuLy8gaW4gSUUxMCB0aGUgcG9pbnRlciB0eXBlcyBpcyBkZWZpbmVkIGFzIGFuIGVudW1cbnZhciBJRTEwX1BPSU5URVJfVFlQRV9FTlVNID0ge1xuICAgIDI6IElOUFVUX1RZUEVfVE9VQ0gsXG4gICAgMzogSU5QVVRfVFlQRV9QRU4sXG4gICAgNDogSU5QVVRfVFlQRV9NT1VTRSxcbiAgICA1OiBJTlBVVF9UWVBFX0tJTkVDVCAvLyBzZWUgaHR0cHM6Ly90d2l0dGVyLmNvbS9qYWNvYnJvc3NpL3N0YXR1cy80ODA1OTY0Mzg0ODk4OTA4MTZcbn07XG5cbnZhciBQT0lOVEVSX0VMRU1FTlRfRVZFTlRTID0gJ3BvaW50ZXJkb3duJztcbnZhciBQT0lOVEVSX1dJTkRPV19FVkVOVFMgPSAncG9pbnRlcm1vdmUgcG9pbnRlcnVwIHBvaW50ZXJjYW5jZWwnO1xuXG4vLyBJRTEwIGhhcyBwcmVmaXhlZCBzdXBwb3J0LCBhbmQgY2FzZS1zZW5zaXRpdmVcbmlmICh3aW5kb3cuTVNQb2ludGVyRXZlbnQgJiYgIXdpbmRvdy5Qb2ludGVyRXZlbnQpIHtcbiAgICBQT0lOVEVSX0VMRU1FTlRfRVZFTlRTID0gJ01TUG9pbnRlckRvd24nO1xuICAgIFBPSU5URVJfV0lORE9XX0VWRU5UUyA9ICdNU1BvaW50ZXJNb3ZlIE1TUG9pbnRlclVwIE1TUG9pbnRlckNhbmNlbCc7XG59XG5cbi8qKlxuICogUG9pbnRlciBldmVudHMgaW5wdXRcbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgSW5wdXRcbiAqL1xuZnVuY3Rpb24gUG9pbnRlckV2ZW50SW5wdXQoKSB7XG4gICAgdGhpcy5ldkVsID0gUE9JTlRFUl9FTEVNRU5UX0VWRU5UUztcbiAgICB0aGlzLmV2V2luID0gUE9JTlRFUl9XSU5ET1dfRVZFTlRTO1xuXG4gICAgSW5wdXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcblxuICAgIHRoaXMuc3RvcmUgPSAodGhpcy5tYW5hZ2VyLnNlc3Npb24ucG9pbnRlckV2ZW50cyA9IFtdKTtcbn1cblxuaW5oZXJpdChQb2ludGVyRXZlbnRJbnB1dCwgSW5wdXQsIHtcbiAgICAvKipcbiAgICAgKiBoYW5kbGUgbW91c2UgZXZlbnRzXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGV2XG4gICAgICovXG4gICAgaGFuZGxlcjogZnVuY3Rpb24gUEVoYW5kbGVyKGV2KSB7XG4gICAgICAgIHZhciBzdG9yZSA9IHRoaXMuc3RvcmU7XG4gICAgICAgIHZhciByZW1vdmVQb2ludGVyID0gZmFsc2U7XG5cbiAgICAgICAgdmFyIGV2ZW50VHlwZU5vcm1hbGl6ZWQgPSBldi50eXBlLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgnbXMnLCAnJyk7XG4gICAgICAgIHZhciBldmVudFR5cGUgPSBQT0lOVEVSX0lOUFVUX01BUFtldmVudFR5cGVOb3JtYWxpemVkXTtcbiAgICAgICAgdmFyIHBvaW50ZXJUeXBlID0gSUUxMF9QT0lOVEVSX1RZUEVfRU5VTVtldi5wb2ludGVyVHlwZV0gfHwgZXYucG9pbnRlclR5cGU7XG5cbiAgICAgICAgdmFyIGlzVG91Y2ggPSAocG9pbnRlclR5cGUgPT0gSU5QVVRfVFlQRV9UT1VDSCk7XG5cbiAgICAgICAgLy8gZ2V0IGluZGV4IG9mIHRoZSBldmVudCBpbiB0aGUgc3RvcmVcbiAgICAgICAgdmFyIHN0b3JlSW5kZXggPSBpbkFycmF5KHN0b3JlLCBldi5wb2ludGVySWQsICdwb2ludGVySWQnKTtcblxuICAgICAgICAvLyBzdGFydCBhbmQgbW91c2UgbXVzdCBiZSBkb3duXG4gICAgICAgIGlmIChldmVudFR5cGUgJiBJTlBVVF9TVEFSVCAmJiAoZXYuYnV0dG9uID09PSAwIHx8IGlzVG91Y2gpKSB7XG4gICAgICAgICAgICBpZiAoc3RvcmVJbmRleCA8IDApIHtcbiAgICAgICAgICAgICAgICBzdG9yZS5wdXNoKGV2KTtcbiAgICAgICAgICAgICAgICBzdG9yZUluZGV4ID0gc3RvcmUubGVuZ3RoIC0gMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChldmVudFR5cGUgJiAoSU5QVVRfRU5EIHwgSU5QVVRfQ0FOQ0VMKSkge1xuICAgICAgICAgICAgcmVtb3ZlUG9pbnRlciA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBpdCBub3QgZm91bmQsIHNvIHRoZSBwb2ludGVyIGhhc24ndCBiZWVuIGRvd24gKHNvIGl0J3MgcHJvYmFibHkgYSBob3ZlcilcbiAgICAgICAgaWYgKHN0b3JlSW5kZXggPCAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyB1cGRhdGUgdGhlIGV2ZW50IGluIHRoZSBzdG9yZVxuICAgICAgICBzdG9yZVtzdG9yZUluZGV4XSA9IGV2O1xuXG4gICAgICAgIHRoaXMuY2FsbGJhY2sodGhpcy5tYW5hZ2VyLCBldmVudFR5cGUsIHtcbiAgICAgICAgICAgIHBvaW50ZXJzOiBzdG9yZSxcbiAgICAgICAgICAgIGNoYW5nZWRQb2ludGVyczogW2V2XSxcbiAgICAgICAgICAgIHBvaW50ZXJUeXBlOiBwb2ludGVyVHlwZSxcbiAgICAgICAgICAgIHNyY0V2ZW50OiBldlxuICAgICAgICB9KTtcblxuICAgICAgICBpZiAocmVtb3ZlUG9pbnRlcikge1xuICAgICAgICAgICAgLy8gcmVtb3ZlIGZyb20gdGhlIHN0b3JlXG4gICAgICAgICAgICBzdG9yZS5zcGxpY2Uoc3RvcmVJbmRleCwgMSk7XG4gICAgICAgIH1cbiAgICB9XG59KTtcblxudmFyIFNJTkdMRV9UT1VDSF9JTlBVVF9NQVAgPSB7XG4gICAgdG91Y2hzdGFydDogSU5QVVRfU1RBUlQsXG4gICAgdG91Y2htb3ZlOiBJTlBVVF9NT1ZFLFxuICAgIHRvdWNoZW5kOiBJTlBVVF9FTkQsXG4gICAgdG91Y2hjYW5jZWw6IElOUFVUX0NBTkNFTFxufTtcblxudmFyIFNJTkdMRV9UT1VDSF9UQVJHRVRfRVZFTlRTID0gJ3RvdWNoc3RhcnQnO1xudmFyIFNJTkdMRV9UT1VDSF9XSU5ET1dfRVZFTlRTID0gJ3RvdWNoc3RhcnQgdG91Y2htb3ZlIHRvdWNoZW5kIHRvdWNoY2FuY2VsJztcblxuLyoqXG4gKiBUb3VjaCBldmVudHMgaW5wdXRcbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgSW5wdXRcbiAqL1xuZnVuY3Rpb24gU2luZ2xlVG91Y2hJbnB1dCgpIHtcbiAgICB0aGlzLmV2VGFyZ2V0ID0gU0lOR0xFX1RPVUNIX1RBUkdFVF9FVkVOVFM7XG4gICAgdGhpcy5ldldpbiA9IFNJTkdMRV9UT1VDSF9XSU5ET1dfRVZFTlRTO1xuICAgIHRoaXMuc3RhcnRlZCA9IGZhbHNlO1xuXG4gICAgSW5wdXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuaW5oZXJpdChTaW5nbGVUb3VjaElucHV0LCBJbnB1dCwge1xuICAgIGhhbmRsZXI6IGZ1bmN0aW9uIFRFaGFuZGxlcihldikge1xuICAgICAgICB2YXIgdHlwZSA9IFNJTkdMRV9UT1VDSF9JTlBVVF9NQVBbZXYudHlwZV07XG5cbiAgICAgICAgLy8gc2hvdWxkIHdlIGhhbmRsZSB0aGUgdG91Y2ggZXZlbnRzP1xuICAgICAgICBpZiAodHlwZSA9PT0gSU5QVVRfU1RBUlQpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhcnRlZCA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuc3RhcnRlZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHRvdWNoZXMgPSBub3JtYWxpemVTaW5nbGVUb3VjaGVzLmNhbGwodGhpcywgZXYsIHR5cGUpO1xuXG4gICAgICAgIC8vIHdoZW4gZG9uZSwgcmVzZXQgdGhlIHN0YXJ0ZWQgc3RhdGVcbiAgICAgICAgaWYgKHR5cGUgJiAoSU5QVVRfRU5EIHwgSU5QVVRfQ0FOQ0VMKSAmJiB0b3VjaGVzWzBdLmxlbmd0aCAtIHRvdWNoZXNbMV0ubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aGlzLnN0YXJ0ZWQgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY2FsbGJhY2sodGhpcy5tYW5hZ2VyLCB0eXBlLCB7XG4gICAgICAgICAgICBwb2ludGVyczogdG91Y2hlc1swXSxcbiAgICAgICAgICAgIGNoYW5nZWRQb2ludGVyczogdG91Y2hlc1sxXSxcbiAgICAgICAgICAgIHBvaW50ZXJUeXBlOiBJTlBVVF9UWVBFX1RPVUNILFxuICAgICAgICAgICAgc3JjRXZlbnQ6IGV2XG4gICAgICAgIH0pO1xuICAgIH1cbn0pO1xuXG4vKipcbiAqIEB0aGlzIHtUb3VjaElucHV0fVxuICogQHBhcmFtIHtPYmplY3R9IGV2XG4gKiBAcGFyYW0ge051bWJlcn0gdHlwZSBmbGFnXG4gKiBAcmV0dXJucyB7dW5kZWZpbmVkfEFycmF5fSBbYWxsLCBjaGFuZ2VkXVxuICovXG5mdW5jdGlvbiBub3JtYWxpemVTaW5nbGVUb3VjaGVzKGV2LCB0eXBlKSB7XG4gICAgdmFyIGFsbCA9IHRvQXJyYXkoZXYudG91Y2hlcyk7XG4gICAgdmFyIGNoYW5nZWQgPSB0b0FycmF5KGV2LmNoYW5nZWRUb3VjaGVzKTtcblxuICAgIGlmICh0eXBlICYgKElOUFVUX0VORCB8IElOUFVUX0NBTkNFTCkpIHtcbiAgICAgICAgYWxsID0gdW5pcXVlQXJyYXkoYWxsLmNvbmNhdChjaGFuZ2VkKSwgJ2lkZW50aWZpZXInLCB0cnVlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gW2FsbCwgY2hhbmdlZF07XG59XG5cbnZhciBUT1VDSF9JTlBVVF9NQVAgPSB7XG4gICAgdG91Y2hzdGFydDogSU5QVVRfU1RBUlQsXG4gICAgdG91Y2htb3ZlOiBJTlBVVF9NT1ZFLFxuICAgIHRvdWNoZW5kOiBJTlBVVF9FTkQsXG4gICAgdG91Y2hjYW5jZWw6IElOUFVUX0NBTkNFTFxufTtcblxudmFyIFRPVUNIX1RBUkdFVF9FVkVOVFMgPSAndG91Y2hzdGFydCB0b3VjaG1vdmUgdG91Y2hlbmQgdG91Y2hjYW5jZWwnO1xuXG4vKipcbiAqIE11bHRpLXVzZXIgdG91Y2ggZXZlbnRzIGlucHV0XG4gKiBAY29uc3RydWN0b3JcbiAqIEBleHRlbmRzIElucHV0XG4gKi9cbmZ1bmN0aW9uIFRvdWNoSW5wdXQoKSB7XG4gICAgdGhpcy5ldlRhcmdldCA9IFRPVUNIX1RBUkdFVF9FVkVOVFM7XG4gICAgdGhpcy50YXJnZXRJZHMgPSB7fTtcblxuICAgIElucHV0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbmluaGVyaXQoVG91Y2hJbnB1dCwgSW5wdXQsIHtcbiAgICBoYW5kbGVyOiBmdW5jdGlvbiBNVEVoYW5kbGVyKGV2KSB7XG4gICAgICAgIHZhciB0eXBlID0gVE9VQ0hfSU5QVVRfTUFQW2V2LnR5cGVdO1xuICAgICAgICB2YXIgdG91Y2hlcyA9IGdldFRvdWNoZXMuY2FsbCh0aGlzLCBldiwgdHlwZSk7XG4gICAgICAgIGlmICghdG91Y2hlcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jYWxsYmFjayh0aGlzLm1hbmFnZXIsIHR5cGUsIHtcbiAgICAgICAgICAgIHBvaW50ZXJzOiB0b3VjaGVzWzBdLFxuICAgICAgICAgICAgY2hhbmdlZFBvaW50ZXJzOiB0b3VjaGVzWzFdLFxuICAgICAgICAgICAgcG9pbnRlclR5cGU6IElOUFVUX1RZUEVfVE9VQ0gsXG4gICAgICAgICAgICBzcmNFdmVudDogZXZcbiAgICAgICAgfSk7XG4gICAgfVxufSk7XG5cbi8qKlxuICogQHRoaXMge1RvdWNoSW5wdXR9XG4gKiBAcGFyYW0ge09iamVjdH0gZXZcbiAqIEBwYXJhbSB7TnVtYmVyfSB0eXBlIGZsYWdcbiAqIEByZXR1cm5zIHt1bmRlZmluZWR8QXJyYXl9IFthbGwsIGNoYW5nZWRdXG4gKi9cbmZ1bmN0aW9uIGdldFRvdWNoZXMoZXYsIHR5cGUpIHtcbiAgICB2YXIgYWxsVG91Y2hlcyA9IHRvQXJyYXkoZXYudG91Y2hlcyk7XG4gICAgdmFyIHRhcmdldElkcyA9IHRoaXMudGFyZ2V0SWRzO1xuXG4gICAgLy8gd2hlbiB0aGVyZSBpcyBvbmx5IG9uZSB0b3VjaCwgdGhlIHByb2Nlc3MgY2FuIGJlIHNpbXBsaWZpZWRcbiAgICBpZiAodHlwZSAmIChJTlBVVF9TVEFSVCB8IElOUFVUX01PVkUpICYmIGFsbFRvdWNoZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHRhcmdldElkc1thbGxUb3VjaGVzWzBdLmlkZW50aWZpZXJdID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIFthbGxUb3VjaGVzLCBhbGxUb3VjaGVzXTtcbiAgICB9XG5cbiAgICB2YXIgaSxcbiAgICAgICAgdGFyZ2V0VG91Y2hlcyxcbiAgICAgICAgY2hhbmdlZFRvdWNoZXMgPSB0b0FycmF5KGV2LmNoYW5nZWRUb3VjaGVzKSxcbiAgICAgICAgY2hhbmdlZFRhcmdldFRvdWNoZXMgPSBbXSxcbiAgICAgICAgdGFyZ2V0ID0gdGhpcy50YXJnZXQ7XG5cbiAgICAvLyBnZXQgdGFyZ2V0IHRvdWNoZXMgZnJvbSB0b3VjaGVzXG4gICAgdGFyZ2V0VG91Y2hlcyA9IGFsbFRvdWNoZXMuZmlsdGVyKGZ1bmN0aW9uKHRvdWNoKSB7XG4gICAgICAgIHJldHVybiBoYXNQYXJlbnQodG91Y2gudGFyZ2V0LCB0YXJnZXQpO1xuICAgIH0pO1xuXG4gICAgLy8gY29sbGVjdCB0b3VjaGVzXG4gICAgaWYgKHR5cGUgPT09IElOUFVUX1NUQVJUKSB7XG4gICAgICAgIGkgPSAwO1xuICAgICAgICB3aGlsZSAoaSA8IHRhcmdldFRvdWNoZXMubGVuZ3RoKSB7XG4gICAgICAgICAgICB0YXJnZXRJZHNbdGFyZ2V0VG91Y2hlc1tpXS5pZGVudGlmaWVyXSA9IHRydWU7XG4gICAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBmaWx0ZXIgY2hhbmdlZCB0b3VjaGVzIHRvIG9ubHkgY29udGFpbiB0b3VjaGVzIHRoYXQgZXhpc3QgaW4gdGhlIGNvbGxlY3RlZCB0YXJnZXQgaWRzXG4gICAgaSA9IDA7XG4gICAgd2hpbGUgKGkgPCBjaGFuZ2VkVG91Y2hlcy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKHRhcmdldElkc1tjaGFuZ2VkVG91Y2hlc1tpXS5pZGVudGlmaWVyXSkge1xuICAgICAgICAgICAgY2hhbmdlZFRhcmdldFRvdWNoZXMucHVzaChjaGFuZ2VkVG91Y2hlc1tpXSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjbGVhbnVwIHJlbW92ZWQgdG91Y2hlc1xuICAgICAgICBpZiAodHlwZSAmIChJTlBVVF9FTkQgfCBJTlBVVF9DQU5DRUwpKSB7XG4gICAgICAgICAgICBkZWxldGUgdGFyZ2V0SWRzW2NoYW5nZWRUb3VjaGVzW2ldLmlkZW50aWZpZXJdO1xuICAgICAgICB9XG4gICAgICAgIGkrKztcbiAgICB9XG5cbiAgICBpZiAoIWNoYW5nZWRUYXJnZXRUb3VjaGVzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIFtcbiAgICAgICAgLy8gbWVyZ2UgdGFyZ2V0VG91Y2hlcyB3aXRoIGNoYW5nZWRUYXJnZXRUb3VjaGVzIHNvIGl0IGNvbnRhaW5zIEFMTCB0b3VjaGVzLCBpbmNsdWRpbmcgJ2VuZCcgYW5kICdjYW5jZWwnXG4gICAgICAgIHVuaXF1ZUFycmF5KHRhcmdldFRvdWNoZXMuY29uY2F0KGNoYW5nZWRUYXJnZXRUb3VjaGVzKSwgJ2lkZW50aWZpZXInLCB0cnVlKSxcbiAgICAgICAgY2hhbmdlZFRhcmdldFRvdWNoZXNcbiAgICBdO1xufVxuXG4vKipcbiAqIENvbWJpbmVkIHRvdWNoIGFuZCBtb3VzZSBpbnB1dFxuICpcbiAqIFRvdWNoIGhhcyBhIGhpZ2hlciBwcmlvcml0eSB0aGVuIG1vdXNlLCBhbmQgd2hpbGUgdG91Y2hpbmcgbm8gbW91c2UgZXZlbnRzIGFyZSBhbGxvd2VkLlxuICogVGhpcyBiZWNhdXNlIHRvdWNoIGRldmljZXMgYWxzbyBlbWl0IG1vdXNlIGV2ZW50cyB3aGlsZSBkb2luZyBhIHRvdWNoLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgSW5wdXRcbiAqL1xuXG52YXIgREVEVVBfVElNRU9VVCA9IDI1MDA7XG52YXIgREVEVVBfRElTVEFOQ0UgPSAyNTtcblxuZnVuY3Rpb24gVG91Y2hNb3VzZUlucHV0KCkge1xuICAgIElucHV0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICB2YXIgaGFuZGxlciA9IGJpbmRGbih0aGlzLmhhbmRsZXIsIHRoaXMpO1xuICAgIHRoaXMudG91Y2ggPSBuZXcgVG91Y2hJbnB1dCh0aGlzLm1hbmFnZXIsIGhhbmRsZXIpO1xuICAgIHRoaXMubW91c2UgPSBuZXcgTW91c2VJbnB1dCh0aGlzLm1hbmFnZXIsIGhhbmRsZXIpO1xuXG4gICAgdGhpcy5wcmltYXJ5VG91Y2ggPSBudWxsO1xuICAgIHRoaXMubGFzdFRvdWNoZXMgPSBbXTtcbn1cblxuaW5oZXJpdChUb3VjaE1vdXNlSW5wdXQsIElucHV0LCB7XG4gICAgLyoqXG4gICAgICogaGFuZGxlIG1vdXNlIGFuZCB0b3VjaCBldmVudHNcbiAgICAgKiBAcGFyYW0ge0hhbW1lcn0gbWFuYWdlclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBpbnB1dEV2ZW50XG4gICAgICogQHBhcmFtIHtPYmplY3R9IGlucHV0RGF0YVxuICAgICAqL1xuICAgIGhhbmRsZXI6IGZ1bmN0aW9uIFRNRWhhbmRsZXIobWFuYWdlciwgaW5wdXRFdmVudCwgaW5wdXREYXRhKSB7XG4gICAgICAgIHZhciBpc1RvdWNoID0gKGlucHV0RGF0YS5wb2ludGVyVHlwZSA9PSBJTlBVVF9UWVBFX1RPVUNIKSxcbiAgICAgICAgICAgIGlzTW91c2UgPSAoaW5wdXREYXRhLnBvaW50ZXJUeXBlID09IElOUFVUX1RZUEVfTU9VU0UpO1xuXG4gICAgICAgIGlmIChpc01vdXNlICYmIGlucHV0RGF0YS5zb3VyY2VDYXBhYmlsaXRpZXMgJiYgaW5wdXREYXRhLnNvdXJjZUNhcGFiaWxpdGllcy5maXJlc1RvdWNoRXZlbnRzKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyB3aGVuIHdlJ3JlIGluIGEgdG91Y2ggZXZlbnQsIHJlY29yZCB0b3VjaGVzIHRvICBkZS1kdXBlIHN5bnRoZXRpYyBtb3VzZSBldmVudFxuICAgICAgICBpZiAoaXNUb3VjaCkge1xuICAgICAgICAgICAgcmVjb3JkVG91Y2hlcy5jYWxsKHRoaXMsIGlucHV0RXZlbnQsIGlucHV0RGF0YSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNNb3VzZSAmJiBpc1N5bnRoZXRpY0V2ZW50LmNhbGwodGhpcywgaW5wdXREYXRhKSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jYWxsYmFjayhtYW5hZ2VyLCBpbnB1dEV2ZW50LCBpbnB1dERhdGEpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiByZW1vdmUgdGhlIGV2ZW50IGxpc3RlbmVyc1xuICAgICAqL1xuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uIGRlc3Ryb3koKSB7XG4gICAgICAgIHRoaXMudG91Y2guZGVzdHJveSgpO1xuICAgICAgICB0aGlzLm1vdXNlLmRlc3Ryb3koKTtcbiAgICB9XG59KTtcblxuZnVuY3Rpb24gcmVjb3JkVG91Y2hlcyhldmVudFR5cGUsIGV2ZW50RGF0YSkge1xuICAgIGlmIChldmVudFR5cGUgJiBJTlBVVF9TVEFSVCkge1xuICAgICAgICB0aGlzLnByaW1hcnlUb3VjaCA9IGV2ZW50RGF0YS5jaGFuZ2VkUG9pbnRlcnNbMF0uaWRlbnRpZmllcjtcbiAgICAgICAgc2V0TGFzdFRvdWNoLmNhbGwodGhpcywgZXZlbnREYXRhKTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50VHlwZSAmIChJTlBVVF9FTkQgfCBJTlBVVF9DQU5DRUwpKSB7XG4gICAgICAgIHNldExhc3RUb3VjaC5jYWxsKHRoaXMsIGV2ZW50RGF0YSk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBzZXRMYXN0VG91Y2goZXZlbnREYXRhKSB7XG4gICAgdmFyIHRvdWNoID0gZXZlbnREYXRhLmNoYW5nZWRQb2ludGVyc1swXTtcblxuICAgIGlmICh0b3VjaC5pZGVudGlmaWVyID09PSB0aGlzLnByaW1hcnlUb3VjaCkge1xuICAgICAgICB2YXIgbGFzdFRvdWNoID0ge3g6IHRvdWNoLmNsaWVudFgsIHk6IHRvdWNoLmNsaWVudFl9O1xuICAgICAgICB0aGlzLmxhc3RUb3VjaGVzLnB1c2gobGFzdFRvdWNoKTtcbiAgICAgICAgdmFyIGx0cyA9IHRoaXMubGFzdFRvdWNoZXM7XG4gICAgICAgIHZhciByZW1vdmVMYXN0VG91Y2ggPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIHZhciBpID0gbHRzLmluZGV4T2YobGFzdFRvdWNoKTtcbiAgICAgICAgICAgIGlmIChpID4gLTEpIHtcbiAgICAgICAgICAgICAgICBsdHMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgICBzZXRUaW1lb3V0KHJlbW92ZUxhc3RUb3VjaCwgREVEVVBfVElNRU9VVCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBpc1N5bnRoZXRpY0V2ZW50KGV2ZW50RGF0YSkge1xuICAgIHZhciB4ID0gZXZlbnREYXRhLnNyY0V2ZW50LmNsaWVudFgsIHkgPSBldmVudERhdGEuc3JjRXZlbnQuY2xpZW50WTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGFzdFRvdWNoZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHQgPSB0aGlzLmxhc3RUb3VjaGVzW2ldO1xuICAgICAgICB2YXIgZHggPSBNYXRoLmFicyh4IC0gdC54KSwgZHkgPSBNYXRoLmFicyh5IC0gdC55KTtcbiAgICAgICAgaWYgKGR4IDw9IERFRFVQX0RJU1RBTkNFICYmIGR5IDw9IERFRFVQX0RJU1RBTkNFKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbnZhciBQUkVGSVhFRF9UT1VDSF9BQ1RJT04gPSBwcmVmaXhlZChURVNUX0VMRU1FTlQuc3R5bGUsICd0b3VjaEFjdGlvbicpO1xudmFyIE5BVElWRV9UT1VDSF9BQ1RJT04gPSBQUkVGSVhFRF9UT1VDSF9BQ1RJT04gIT09IHVuZGVmaW5lZDtcblxuLy8gbWFnaWNhbCB0b3VjaEFjdGlvbiB2YWx1ZVxudmFyIFRPVUNIX0FDVElPTl9DT01QVVRFID0gJ2NvbXB1dGUnO1xudmFyIFRPVUNIX0FDVElPTl9BVVRPID0gJ2F1dG8nO1xudmFyIFRPVUNIX0FDVElPTl9NQU5JUFVMQVRJT04gPSAnbWFuaXB1bGF0aW9uJzsgLy8gbm90IGltcGxlbWVudGVkXG52YXIgVE9VQ0hfQUNUSU9OX05PTkUgPSAnbm9uZSc7XG52YXIgVE9VQ0hfQUNUSU9OX1BBTl9YID0gJ3Bhbi14JztcbnZhciBUT1VDSF9BQ1RJT05fUEFOX1kgPSAncGFuLXknO1xudmFyIFRPVUNIX0FDVElPTl9NQVAgPSBnZXRUb3VjaEFjdGlvblByb3BzKCk7XG5cbi8qKlxuICogVG91Y2ggQWN0aW9uXG4gKiBzZXRzIHRoZSB0b3VjaEFjdGlvbiBwcm9wZXJ0eSBvciB1c2VzIHRoZSBqcyBhbHRlcm5hdGl2ZVxuICogQHBhcmFtIHtNYW5hZ2VyfSBtYW5hZ2VyXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsdWVcbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBUb3VjaEFjdGlvbihtYW5hZ2VyLCB2YWx1ZSkge1xuICAgIHRoaXMubWFuYWdlciA9IG1hbmFnZXI7XG4gICAgdGhpcy5zZXQodmFsdWUpO1xufVxuXG5Ub3VjaEFjdGlvbi5wcm90b3R5cGUgPSB7XG4gICAgLyoqXG4gICAgICogc2V0IHRoZSB0b3VjaEFjdGlvbiB2YWx1ZSBvbiB0aGUgZWxlbWVudCBvciBlbmFibGUgdGhlIHBvbHlmaWxsXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXG4gICAgICovXG4gICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgICAvLyBmaW5kIG91dCB0aGUgdG91Y2gtYWN0aW9uIGJ5IHRoZSBldmVudCBoYW5kbGVyc1xuICAgICAgICBpZiAodmFsdWUgPT0gVE9VQ0hfQUNUSU9OX0NPTVBVVEUpIHtcbiAgICAgICAgICAgIHZhbHVlID0gdGhpcy5jb21wdXRlKCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoTkFUSVZFX1RPVUNIX0FDVElPTiAmJiB0aGlzLm1hbmFnZXIuZWxlbWVudC5zdHlsZSAmJiBUT1VDSF9BQ1RJT05fTUFQW3ZhbHVlXSkge1xuICAgICAgICAgICAgdGhpcy5tYW5hZ2VyLmVsZW1lbnQuc3R5bGVbUFJFRklYRURfVE9VQ0hfQUNUSU9OXSA9IHZhbHVlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYWN0aW9ucyA9IHZhbHVlLnRvTG93ZXJDYXNlKCkudHJpbSgpO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBqdXN0IHJlLXNldCB0aGUgdG91Y2hBY3Rpb24gdmFsdWVcbiAgICAgKi9cbiAgICB1cGRhdGU6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLnNldCh0aGlzLm1hbmFnZXIub3B0aW9ucy50b3VjaEFjdGlvbik7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGNvbXB1dGUgdGhlIHZhbHVlIGZvciB0aGUgdG91Y2hBY3Rpb24gcHJvcGVydHkgYmFzZWQgb24gdGhlIHJlY29nbml6ZXIncyBzZXR0aW5nc1xuICAgICAqIEByZXR1cm5zIHtTdHJpbmd9IHZhbHVlXG4gICAgICovXG4gICAgY29tcHV0ZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBhY3Rpb25zID0gW107XG4gICAgICAgIGVhY2godGhpcy5tYW5hZ2VyLnJlY29nbml6ZXJzLCBmdW5jdGlvbihyZWNvZ25pemVyKSB7XG4gICAgICAgICAgICBpZiAoYm9vbE9yRm4ocmVjb2duaXplci5vcHRpb25zLmVuYWJsZSwgW3JlY29nbml6ZXJdKSkge1xuICAgICAgICAgICAgICAgIGFjdGlvbnMgPSBhY3Rpb25zLmNvbmNhdChyZWNvZ25pemVyLmdldFRvdWNoQWN0aW9uKCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGNsZWFuVG91Y2hBY3Rpb25zKGFjdGlvbnMuam9pbignICcpKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogdGhpcyBtZXRob2QgaXMgY2FsbGVkIG9uIGVhY2ggaW5wdXQgY3ljbGUgYW5kIHByb3ZpZGVzIHRoZSBwcmV2ZW50aW5nIG9mIHRoZSBicm93c2VyIGJlaGF2aW9yXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGlucHV0XG4gICAgICovXG4gICAgcHJldmVudERlZmF1bHRzOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgc3JjRXZlbnQgPSBpbnB1dC5zcmNFdmVudDtcbiAgICAgICAgdmFyIGRpcmVjdGlvbiA9IGlucHV0Lm9mZnNldERpcmVjdGlvbjtcblxuICAgICAgICAvLyBpZiB0aGUgdG91Y2ggYWN0aW9uIGRpZCBwcmV2ZW50ZWQgb25jZSB0aGlzIHNlc3Npb25cbiAgICAgICAgaWYgKHRoaXMubWFuYWdlci5zZXNzaW9uLnByZXZlbnRlZCkge1xuICAgICAgICAgICAgc3JjRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBhY3Rpb25zID0gdGhpcy5hY3Rpb25zO1xuICAgICAgICB2YXIgaGFzTm9uZSA9IGluU3RyKGFjdGlvbnMsIFRPVUNIX0FDVElPTl9OT05FKSAmJiAhVE9VQ0hfQUNUSU9OX01BUFtUT1VDSF9BQ1RJT05fTk9ORV07XG4gICAgICAgIHZhciBoYXNQYW5ZID0gaW5TdHIoYWN0aW9ucywgVE9VQ0hfQUNUSU9OX1BBTl9ZKSAmJiAhVE9VQ0hfQUNUSU9OX01BUFtUT1VDSF9BQ1RJT05fUEFOX1ldO1xuICAgICAgICB2YXIgaGFzUGFuWCA9IGluU3RyKGFjdGlvbnMsIFRPVUNIX0FDVElPTl9QQU5fWCkgJiYgIVRPVUNIX0FDVElPTl9NQVBbVE9VQ0hfQUNUSU9OX1BBTl9YXTtcblxuICAgICAgICBpZiAoaGFzTm9uZSkge1xuICAgICAgICAgICAgLy9kbyBub3QgcHJldmVudCBkZWZhdWx0cyBpZiB0aGlzIGlzIGEgdGFwIGdlc3R1cmVcblxuICAgICAgICAgICAgdmFyIGlzVGFwUG9pbnRlciA9IGlucHV0LnBvaW50ZXJzLmxlbmd0aCA9PT0gMTtcbiAgICAgICAgICAgIHZhciBpc1RhcE1vdmVtZW50ID0gaW5wdXQuZGlzdGFuY2UgPCAyO1xuICAgICAgICAgICAgdmFyIGlzVGFwVG91Y2hUaW1lID0gaW5wdXQuZGVsdGFUaW1lIDwgMjUwO1xuXG4gICAgICAgICAgICBpZiAoaXNUYXBQb2ludGVyICYmIGlzVGFwTW92ZW1lbnQgJiYgaXNUYXBUb3VjaFRpbWUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzUGFuWCAmJiBoYXNQYW5ZKSB7XG4gICAgICAgICAgICAvLyBgcGFuLXggcGFuLXlgIG1lYW5zIGJyb3dzZXIgaGFuZGxlcyBhbGwgc2Nyb2xsaW5nL3Bhbm5pbmcsIGRvIG5vdCBwcmV2ZW50XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaGFzTm9uZSB8fFxuICAgICAgICAgICAgKGhhc1BhblkgJiYgZGlyZWN0aW9uICYgRElSRUNUSU9OX0hPUklaT05UQUwpIHx8XG4gICAgICAgICAgICAoaGFzUGFuWCAmJiBkaXJlY3Rpb24gJiBESVJFQ1RJT05fVkVSVElDQUwpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5wcmV2ZW50U3JjKHNyY0V2ZW50KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBjYWxsIHByZXZlbnREZWZhdWx0IHRvIHByZXZlbnQgdGhlIGJyb3dzZXIncyBkZWZhdWx0IGJlaGF2aW9yIChzY3JvbGxpbmcgaW4gbW9zdCBjYXNlcylcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc3JjRXZlbnRcbiAgICAgKi9cbiAgICBwcmV2ZW50U3JjOiBmdW5jdGlvbihzcmNFdmVudCkge1xuICAgICAgICB0aGlzLm1hbmFnZXIuc2Vzc2lvbi5wcmV2ZW50ZWQgPSB0cnVlO1xuICAgICAgICBzcmNFdmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbn07XG5cbi8qKlxuICogd2hlbiB0aGUgdG91Y2hBY3Rpb25zIGFyZSBjb2xsZWN0ZWQgdGhleSBhcmUgbm90IGEgdmFsaWQgdmFsdWUsIHNvIHdlIG5lZWQgdG8gY2xlYW4gdGhpbmdzIHVwLiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gYWN0aW9uc1xuICogQHJldHVybnMgeyp9XG4gKi9cbmZ1bmN0aW9uIGNsZWFuVG91Y2hBY3Rpb25zKGFjdGlvbnMpIHtcbiAgICAvLyBub25lXG4gICAgaWYgKGluU3RyKGFjdGlvbnMsIFRPVUNIX0FDVElPTl9OT05FKSkge1xuICAgICAgICByZXR1cm4gVE9VQ0hfQUNUSU9OX05PTkU7XG4gICAgfVxuXG4gICAgdmFyIGhhc1BhblggPSBpblN0cihhY3Rpb25zLCBUT1VDSF9BQ1RJT05fUEFOX1gpO1xuICAgIHZhciBoYXNQYW5ZID0gaW5TdHIoYWN0aW9ucywgVE9VQ0hfQUNUSU9OX1BBTl9ZKTtcblxuICAgIC8vIGlmIGJvdGggcGFuLXggYW5kIHBhbi15IGFyZSBzZXQgKGRpZmZlcmVudCByZWNvZ25pemVyc1xuICAgIC8vIGZvciBkaWZmZXJlbnQgZGlyZWN0aW9ucywgZS5nLiBob3Jpem9udGFsIHBhbiBidXQgdmVydGljYWwgc3dpcGU/KVxuICAgIC8vIHdlIG5lZWQgbm9uZSAoYXMgb3RoZXJ3aXNlIHdpdGggcGFuLXggcGFuLXkgY29tYmluZWQgbm9uZSBvZiB0aGVzZVxuICAgIC8vIHJlY29nbml6ZXJzIHdpbGwgd29yaywgc2luY2UgdGhlIGJyb3dzZXIgd291bGQgaGFuZGxlIGFsbCBwYW5uaW5nXG4gICAgaWYgKGhhc1BhblggJiYgaGFzUGFuWSkge1xuICAgICAgICByZXR1cm4gVE9VQ0hfQUNUSU9OX05PTkU7XG4gICAgfVxuXG4gICAgLy8gcGFuLXggT1IgcGFuLXlcbiAgICBpZiAoaGFzUGFuWCB8fCBoYXNQYW5ZKSB7XG4gICAgICAgIHJldHVybiBoYXNQYW5YID8gVE9VQ0hfQUNUSU9OX1BBTl9YIDogVE9VQ0hfQUNUSU9OX1BBTl9ZO1xuICAgIH1cblxuICAgIC8vIG1hbmlwdWxhdGlvblxuICAgIGlmIChpblN0cihhY3Rpb25zLCBUT1VDSF9BQ1RJT05fTUFOSVBVTEFUSU9OKSkge1xuICAgICAgICByZXR1cm4gVE9VQ0hfQUNUSU9OX01BTklQVUxBVElPTjtcbiAgICB9XG5cbiAgICByZXR1cm4gVE9VQ0hfQUNUSU9OX0FVVE87XG59XG5cbmZ1bmN0aW9uIGdldFRvdWNoQWN0aW9uUHJvcHMoKSB7XG4gICAgaWYgKCFOQVRJVkVfVE9VQ0hfQUNUSU9OKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgdmFyIHRvdWNoTWFwID0ge307XG4gICAgdmFyIGNzc1N1cHBvcnRzID0gd2luZG93LkNTUyAmJiB3aW5kb3cuQ1NTLnN1cHBvcnRzO1xuICAgIFsnYXV0bycsICdtYW5pcHVsYXRpb24nLCAncGFuLXknLCAncGFuLXgnLCAncGFuLXggcGFuLXknLCAnbm9uZSddLmZvckVhY2goZnVuY3Rpb24odmFsKSB7XG5cbiAgICAgICAgLy8gSWYgY3NzLnN1cHBvcnRzIGlzIG5vdCBzdXBwb3J0ZWQgYnV0IHRoZXJlIGlzIG5hdGl2ZSB0b3VjaC1hY3Rpb24gYXNzdW1lIGl0IHN1cHBvcnRzXG4gICAgICAgIC8vIGFsbCB2YWx1ZXMuIFRoaXMgaXMgdGhlIGNhc2UgZm9yIElFIDEwIGFuZCAxMS5cbiAgICAgICAgdG91Y2hNYXBbdmFsXSA9IGNzc1N1cHBvcnRzID8gd2luZG93LkNTUy5zdXBwb3J0cygndG91Y2gtYWN0aW9uJywgdmFsKSA6IHRydWU7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRvdWNoTWFwO1xufVxuXG4vKipcbiAqIFJlY29nbml6ZXIgZmxvdyBleHBsYWluZWQ7ICpcbiAqIEFsbCByZWNvZ25pemVycyBoYXZlIHRoZSBpbml0aWFsIHN0YXRlIG9mIFBPU1NJQkxFIHdoZW4gYSBpbnB1dCBzZXNzaW9uIHN0YXJ0cy5cbiAqIFRoZSBkZWZpbml0aW9uIG9mIGEgaW5wdXQgc2Vzc2lvbiBpcyBmcm9tIHRoZSBmaXJzdCBpbnB1dCB1bnRpbCB0aGUgbGFzdCBpbnB1dCwgd2l0aCBhbGwgaXQncyBtb3ZlbWVudCBpbiBpdC4gKlxuICogRXhhbXBsZSBzZXNzaW9uIGZvciBtb3VzZS1pbnB1dDogbW91c2Vkb3duIC0+IG1vdXNlbW92ZSAtPiBtb3VzZXVwXG4gKlxuICogT24gZWFjaCByZWNvZ25pemluZyBjeWNsZSAoc2VlIE1hbmFnZXIucmVjb2duaXplKSB0aGUgLnJlY29nbml6ZSgpIG1ldGhvZCBpcyBleGVjdXRlZFxuICogd2hpY2ggZGV0ZXJtaW5lcyB3aXRoIHN0YXRlIGl0IHNob3VsZCBiZS5cbiAqXG4gKiBJZiB0aGUgcmVjb2duaXplciBoYXMgdGhlIHN0YXRlIEZBSUxFRCwgQ0FOQ0VMTEVEIG9yIFJFQ09HTklaRUQgKGVxdWFscyBFTkRFRCksIGl0IGlzIHJlc2V0IHRvXG4gKiBQT1NTSUJMRSB0byBnaXZlIGl0IGFub3RoZXIgY2hhbmdlIG9uIHRoZSBuZXh0IGN5Y2xlLlxuICpcbiAqICAgICAgICAgICAgICAgUG9zc2libGVcbiAqICAgICAgICAgICAgICAgICAgfFxuICogICAgICAgICAgICArLS0tLS0rLS0tLS0tLS0tLS0tLS0tK1xuICogICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfFxuICogICAgICArLS0tLS0rLS0tLS0rICAgICAgICAgICAgICAgfFxuICogICAgICB8ICAgICAgICAgICB8ICAgICAgICAgICAgICAgfFxuICogICBGYWlsZWQgICAgICBDYW5jZWxsZWQgICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICstLS0tLS0tKy0tLS0tLStcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICBSZWNvZ25pemVkICAgICAgIEJlZ2FuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfFxuICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENoYW5nZWRcbiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8XG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFbmRlZC9SZWNvZ25pemVkXG4gKi9cbnZhciBTVEFURV9QT1NTSUJMRSA9IDE7XG52YXIgU1RBVEVfQkVHQU4gPSAyO1xudmFyIFNUQVRFX0NIQU5HRUQgPSA0O1xudmFyIFNUQVRFX0VOREVEID0gODtcbnZhciBTVEFURV9SRUNPR05JWkVEID0gU1RBVEVfRU5ERUQ7XG52YXIgU1RBVEVfQ0FOQ0VMTEVEID0gMTY7XG52YXIgU1RBVEVfRkFJTEVEID0gMzI7XG5cbi8qKlxuICogUmVjb2duaXplclxuICogRXZlcnkgcmVjb2duaXplciBuZWVkcyB0byBleHRlbmQgZnJvbSB0aGlzIGNsYXNzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICovXG5mdW5jdGlvbiBSZWNvZ25pemVyKG9wdGlvbnMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBhc3NpZ24oe30sIHRoaXMuZGVmYXVsdHMsIG9wdGlvbnMgfHwge30pO1xuXG4gICAgdGhpcy5pZCA9IHVuaXF1ZUlkKCk7XG5cbiAgICB0aGlzLm1hbmFnZXIgPSBudWxsO1xuXG4gICAgLy8gZGVmYXVsdCBpcyBlbmFibGUgdHJ1ZVxuICAgIHRoaXMub3B0aW9ucy5lbmFibGUgPSBpZlVuZGVmaW5lZCh0aGlzLm9wdGlvbnMuZW5hYmxlLCB0cnVlKTtcblxuICAgIHRoaXMuc3RhdGUgPSBTVEFURV9QT1NTSUJMRTtcblxuICAgIHRoaXMuc2ltdWx0YW5lb3VzID0ge307XG4gICAgdGhpcy5yZXF1aXJlRmFpbCA9IFtdO1xufVxuXG5SZWNvZ25pemVyLnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBAdmlydHVhbFxuICAgICAqIEB0eXBlIHtPYmplY3R9XG4gICAgICovXG4gICAgZGVmYXVsdHM6IHt9LFxuXG4gICAgLyoqXG4gICAgICogc2V0IG9wdGlvbnNcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAqIEByZXR1cm4ge1JlY29nbml6ZXJ9XG4gICAgICovXG4gICAgc2V0OiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgIGFzc2lnbih0aGlzLm9wdGlvbnMsIG9wdGlvbnMpO1xuXG4gICAgICAgIC8vIGFsc28gdXBkYXRlIHRoZSB0b3VjaEFjdGlvbiwgaW4gY2FzZSBzb21ldGhpbmcgY2hhbmdlZCBhYm91dCB0aGUgZGlyZWN0aW9ucy9lbmFibGVkIHN0YXRlXG4gICAgICAgIHRoaXMubWFuYWdlciAmJiB0aGlzLm1hbmFnZXIudG91Y2hBY3Rpb24udXBkYXRlKCk7XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiByZWNvZ25pemUgc2ltdWx0YW5lb3VzIHdpdGggYW4gb3RoZXIgcmVjb2duaXplci5cbiAgICAgKiBAcGFyYW0ge1JlY29nbml6ZXJ9IG90aGVyUmVjb2duaXplclxuICAgICAqIEByZXR1cm5zIHtSZWNvZ25pemVyfSB0aGlzXG4gICAgICovXG4gICAgcmVjb2duaXplV2l0aDogZnVuY3Rpb24ob3RoZXJSZWNvZ25pemVyKSB7XG4gICAgICAgIGlmIChpbnZva2VBcnJheUFyZyhvdGhlclJlY29nbml6ZXIsICdyZWNvZ25pemVXaXRoJywgdGhpcykpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHNpbXVsdGFuZW91cyA9IHRoaXMuc2ltdWx0YW5lb3VzO1xuICAgICAgICBvdGhlclJlY29nbml6ZXIgPSBnZXRSZWNvZ25pemVyQnlOYW1lSWZNYW5hZ2VyKG90aGVyUmVjb2duaXplciwgdGhpcyk7XG4gICAgICAgIGlmICghc2ltdWx0YW5lb3VzW290aGVyUmVjb2duaXplci5pZF0pIHtcbiAgICAgICAgICAgIHNpbXVsdGFuZW91c1tvdGhlclJlY29nbml6ZXIuaWRdID0gb3RoZXJSZWNvZ25pemVyO1xuICAgICAgICAgICAgb3RoZXJSZWNvZ25pemVyLnJlY29nbml6ZVdpdGgodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGRyb3AgdGhlIHNpbXVsdGFuZW91cyBsaW5rLiBpdCBkb2VzbnQgcmVtb3ZlIHRoZSBsaW5rIG9uIHRoZSBvdGhlciByZWNvZ25pemVyLlxuICAgICAqIEBwYXJhbSB7UmVjb2duaXplcn0gb3RoZXJSZWNvZ25pemVyXG4gICAgICogQHJldHVybnMge1JlY29nbml6ZXJ9IHRoaXNcbiAgICAgKi9cbiAgICBkcm9wUmVjb2duaXplV2l0aDogZnVuY3Rpb24ob3RoZXJSZWNvZ25pemVyKSB7XG4gICAgICAgIGlmIChpbnZva2VBcnJheUFyZyhvdGhlclJlY29nbml6ZXIsICdkcm9wUmVjb2duaXplV2l0aCcsIHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIG90aGVyUmVjb2duaXplciA9IGdldFJlY29nbml6ZXJCeU5hbWVJZk1hbmFnZXIob3RoZXJSZWNvZ25pemVyLCB0aGlzKTtcbiAgICAgICAgZGVsZXRlIHRoaXMuc2ltdWx0YW5lb3VzW290aGVyUmVjb2duaXplci5pZF07XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiByZWNvZ25pemVyIGNhbiBvbmx5IHJ1biB3aGVuIGFuIG90aGVyIGlzIGZhaWxpbmdcbiAgICAgKiBAcGFyYW0ge1JlY29nbml6ZXJ9IG90aGVyUmVjb2duaXplclxuICAgICAqIEByZXR1cm5zIHtSZWNvZ25pemVyfSB0aGlzXG4gICAgICovXG4gICAgcmVxdWlyZUZhaWx1cmU6IGZ1bmN0aW9uKG90aGVyUmVjb2duaXplcikge1xuICAgICAgICBpZiAoaW52b2tlQXJyYXlBcmcob3RoZXJSZWNvZ25pemVyLCAncmVxdWlyZUZhaWx1cmUnLCB0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgcmVxdWlyZUZhaWwgPSB0aGlzLnJlcXVpcmVGYWlsO1xuICAgICAgICBvdGhlclJlY29nbml6ZXIgPSBnZXRSZWNvZ25pemVyQnlOYW1lSWZNYW5hZ2VyKG90aGVyUmVjb2duaXplciwgdGhpcyk7XG4gICAgICAgIGlmIChpbkFycmF5KHJlcXVpcmVGYWlsLCBvdGhlclJlY29nbml6ZXIpID09PSAtMSkge1xuICAgICAgICAgICAgcmVxdWlyZUZhaWwucHVzaChvdGhlclJlY29nbml6ZXIpO1xuICAgICAgICAgICAgb3RoZXJSZWNvZ25pemVyLnJlcXVpcmVGYWlsdXJlKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBkcm9wIHRoZSByZXF1aXJlRmFpbHVyZSBsaW5rLiBpdCBkb2VzIG5vdCByZW1vdmUgdGhlIGxpbmsgb24gdGhlIG90aGVyIHJlY29nbml6ZXIuXG4gICAgICogQHBhcmFtIHtSZWNvZ25pemVyfSBvdGhlclJlY29nbml6ZXJcbiAgICAgKiBAcmV0dXJucyB7UmVjb2duaXplcn0gdGhpc1xuICAgICAqL1xuICAgIGRyb3BSZXF1aXJlRmFpbHVyZTogZnVuY3Rpb24ob3RoZXJSZWNvZ25pemVyKSB7XG4gICAgICAgIGlmIChpbnZva2VBcnJheUFyZyhvdGhlclJlY29nbml6ZXIsICdkcm9wUmVxdWlyZUZhaWx1cmUnLCB0aGlzKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH1cblxuICAgICAgICBvdGhlclJlY29nbml6ZXIgPSBnZXRSZWNvZ25pemVyQnlOYW1lSWZNYW5hZ2VyKG90aGVyUmVjb2duaXplciwgdGhpcyk7XG4gICAgICAgIHZhciBpbmRleCA9IGluQXJyYXkodGhpcy5yZXF1aXJlRmFpbCwgb3RoZXJSZWNvZ25pemVyKTtcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgIHRoaXMucmVxdWlyZUZhaWwuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogaGFzIHJlcXVpcmUgZmFpbHVyZXMgYm9vbGVhblxuICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuICAgICAqL1xuICAgIGhhc1JlcXVpcmVGYWlsdXJlczogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnJlcXVpcmVGYWlsLmxlbmd0aCA+IDA7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGlmIHRoZSByZWNvZ25pemVyIGNhbiByZWNvZ25pemUgc2ltdWx0YW5lb3VzIHdpdGggYW4gb3RoZXIgcmVjb2duaXplclxuICAgICAqIEBwYXJhbSB7UmVjb2duaXplcn0gb3RoZXJSZWNvZ25pemVyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59XG4gICAgICovXG4gICAgY2FuUmVjb2duaXplV2l0aDogZnVuY3Rpb24ob3RoZXJSZWNvZ25pemVyKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuc2ltdWx0YW5lb3VzW290aGVyUmVjb2duaXplci5pZF07XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFlvdSBzaG91bGQgdXNlIGB0cnlFbWl0YCBpbnN0ZWFkIG9mIGBlbWl0YCBkaXJlY3RseSB0byBjaGVja1xuICAgICAqIHRoYXQgYWxsIHRoZSBuZWVkZWQgcmVjb2duaXplcnMgaGFzIGZhaWxlZCBiZWZvcmUgZW1pdHRpbmcuXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGlucHV0XG4gICAgICovXG4gICAgZW1pdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuXG4gICAgICAgIGZ1bmN0aW9uIGVtaXQoZXZlbnQpIHtcbiAgICAgICAgICAgIHNlbGYubWFuYWdlci5lbWl0KGV2ZW50LCBpbnB1dCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyAncGFuc3RhcnQnIGFuZCAncGFubW92ZSdcbiAgICAgICAgaWYgKHN0YXRlIDwgU1RBVEVfRU5ERUQpIHtcbiAgICAgICAgICAgIGVtaXQoc2VsZi5vcHRpb25zLmV2ZW50ICsgc3RhdGVTdHIoc3RhdGUpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVtaXQoc2VsZi5vcHRpb25zLmV2ZW50KTsgLy8gc2ltcGxlICdldmVudE5hbWUnIGV2ZW50c1xuXG4gICAgICAgIGlmIChpbnB1dC5hZGRpdGlvbmFsRXZlbnQpIHsgLy8gYWRkaXRpb25hbCBldmVudChwYW5sZWZ0LCBwYW5yaWdodCwgcGluY2hpbiwgcGluY2hvdXQuLi4pXG4gICAgICAgICAgICBlbWl0KGlucHV0LmFkZGl0aW9uYWxFdmVudCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBwYW5lbmQgYW5kIHBhbmNhbmNlbFxuICAgICAgICBpZiAoc3RhdGUgPj0gU1RBVEVfRU5ERUQpIHtcbiAgICAgICAgICAgIGVtaXQoc2VsZi5vcHRpb25zLmV2ZW50ICsgc3RhdGVTdHIoc3RhdGUpKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBDaGVjayB0aGF0IGFsbCB0aGUgcmVxdWlyZSBmYWlsdXJlIHJlY29nbml6ZXJzIGhhcyBmYWlsZWQsXG4gICAgICogaWYgdHJ1ZSwgaXQgZW1pdHMgYSBnZXN0dXJlIGV2ZW50LFxuICAgICAqIG90aGVyd2lzZSwgc2V0dXAgdGhlIHN0YXRlIHRvIEZBSUxFRC5cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAgICAgKi9cbiAgICB0cnlFbWl0OiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICBpZiAodGhpcy5jYW5FbWl0KCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVtaXQoaW5wdXQpO1xuICAgICAgICB9XG4gICAgICAgIC8vIGl0J3MgZmFpbGluZyBhbnl3YXlcbiAgICAgICAgdGhpcy5zdGF0ZSA9IFNUQVRFX0ZBSUxFRDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogY2FuIHdlIGVtaXQ/XG4gICAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAgICovXG4gICAgY2FuRW1pdDogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBpID0gMDtcbiAgICAgICAgd2hpbGUgKGkgPCB0aGlzLnJlcXVpcmVGYWlsLmxlbmd0aCkge1xuICAgICAgICAgICAgaWYgKCEodGhpcy5yZXF1aXJlRmFpbFtpXS5zdGF0ZSAmIChTVEFURV9GQUlMRUQgfCBTVEFURV9QT1NTSUJMRSkpKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiB1cGRhdGUgdGhlIHJlY29nbml6ZXJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXREYXRhXG4gICAgICovXG4gICAgcmVjb2duaXplOiBmdW5jdGlvbihpbnB1dERhdGEpIHtcbiAgICAgICAgLy8gbWFrZSBhIG5ldyBjb3B5IG9mIHRoZSBpbnB1dERhdGFcbiAgICAgICAgLy8gc28gd2UgY2FuIGNoYW5nZSB0aGUgaW5wdXREYXRhIHdpdGhvdXQgbWVzc2luZyB1cCB0aGUgb3RoZXIgcmVjb2duaXplcnNcbiAgICAgICAgdmFyIGlucHV0RGF0YUNsb25lID0gYXNzaWduKHt9LCBpbnB1dERhdGEpO1xuXG4gICAgICAgIC8vIGlzIGlzIGVuYWJsZWQgYW5kIGFsbG93IHJlY29nbml6aW5nP1xuICAgICAgICBpZiAoIWJvb2xPckZuKHRoaXMub3B0aW9ucy5lbmFibGUsIFt0aGlzLCBpbnB1dERhdGFDbG9uZV0pKSB7XG4gICAgICAgICAgICB0aGlzLnJlc2V0KCk7XG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gU1RBVEVfRkFJTEVEO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVzZXQgd2hlbiB3ZSd2ZSByZWFjaGVkIHRoZSBlbmRcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgJiAoU1RBVEVfUkVDT0dOSVpFRCB8IFNUQVRFX0NBTkNFTExFRCB8IFNUQVRFX0ZBSUxFRCkpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSBTVEFURV9QT1NTSUJMRTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuc3RhdGUgPSB0aGlzLnByb2Nlc3MoaW5wdXREYXRhQ2xvbmUpO1xuXG4gICAgICAgIC8vIHRoZSByZWNvZ25pemVyIGhhcyByZWNvZ25pemVkIGEgZ2VzdHVyZVxuICAgICAgICAvLyBzbyB0cmlnZ2VyIGFuIGV2ZW50XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICYgKFNUQVRFX0JFR0FOIHwgU1RBVEVfQ0hBTkdFRCB8IFNUQVRFX0VOREVEIHwgU1RBVEVfQ0FOQ0VMTEVEKSkge1xuICAgICAgICAgICAgdGhpcy50cnlFbWl0KGlucHV0RGF0YUNsb25lKTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiByZXR1cm4gdGhlIHN0YXRlIG9mIHRoZSByZWNvZ25pemVyXG4gICAgICogdGhlIGFjdHVhbCByZWNvZ25pemluZyBoYXBwZW5zIGluIHRoaXMgbWV0aG9kXG4gICAgICogQHZpcnR1YWxcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXREYXRhXG4gICAgICogQHJldHVybnMge0NvbnN0fSBTVEFURVxuICAgICAqL1xuICAgIHByb2Nlc3M6IGZ1bmN0aW9uKGlucHV0RGF0YSkgeyB9LCAvLyBqc2hpbnQgaWdub3JlOmxpbmVcblxuICAgIC8qKlxuICAgICAqIHJldHVybiB0aGUgcHJlZmVycmVkIHRvdWNoLWFjdGlvblxuICAgICAqIEB2aXJ0dWFsXG4gICAgICogQHJldHVybnMge0FycmF5fVxuICAgICAqL1xuICAgIGdldFRvdWNoQWN0aW9uOiBmdW5jdGlvbigpIHsgfSxcblxuICAgIC8qKlxuICAgICAqIGNhbGxlZCB3aGVuIHRoZSBnZXN0dXJlIGlzbid0IGFsbG93ZWQgdG8gcmVjb2duaXplXG4gICAgICogbGlrZSB3aGVuIGFub3RoZXIgaXMgYmVpbmcgcmVjb2duaXplZCBvciBpdCBpcyBkaXNhYmxlZFxuICAgICAqIEB2aXJ0dWFsXG4gICAgICovXG4gICAgcmVzZXQ6IGZ1bmN0aW9uKCkgeyB9XG59O1xuXG4vKipcbiAqIGdldCBhIHVzYWJsZSBzdHJpbmcsIHVzZWQgYXMgZXZlbnQgcG9zdGZpeFxuICogQHBhcmFtIHtDb25zdH0gc3RhdGVcbiAqIEByZXR1cm5zIHtTdHJpbmd9IHN0YXRlXG4gKi9cbmZ1bmN0aW9uIHN0YXRlU3RyKHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlICYgU1RBVEVfQ0FOQ0VMTEVEKSB7XG4gICAgICAgIHJldHVybiAnY2FuY2VsJztcbiAgICB9IGVsc2UgaWYgKHN0YXRlICYgU1RBVEVfRU5ERUQpIHtcbiAgICAgICAgcmV0dXJuICdlbmQnO1xuICAgIH0gZWxzZSBpZiAoc3RhdGUgJiBTVEFURV9DSEFOR0VEKSB7XG4gICAgICAgIHJldHVybiAnbW92ZSc7XG4gICAgfSBlbHNlIGlmIChzdGF0ZSAmIFNUQVRFX0JFR0FOKSB7XG4gICAgICAgIHJldHVybiAnc3RhcnQnO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG59XG5cbi8qKlxuICogZGlyZWN0aW9uIGNvbnMgdG8gc3RyaW5nXG4gKiBAcGFyYW0ge0NvbnN0fSBkaXJlY3Rpb25cbiAqIEByZXR1cm5zIHtTdHJpbmd9XG4gKi9cbmZ1bmN0aW9uIGRpcmVjdGlvblN0cihkaXJlY3Rpb24pIHtcbiAgICBpZiAoZGlyZWN0aW9uID09IERJUkVDVElPTl9ET1dOKSB7XG4gICAgICAgIHJldHVybiAnZG93bic7XG4gICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gRElSRUNUSU9OX1VQKSB7XG4gICAgICAgIHJldHVybiAndXAnO1xuICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uID09IERJUkVDVElPTl9MRUZUKSB7XG4gICAgICAgIHJldHVybiAnbGVmdCc7XG4gICAgfSBlbHNlIGlmIChkaXJlY3Rpb24gPT0gRElSRUNUSU9OX1JJR0hUKSB7XG4gICAgICAgIHJldHVybiAncmlnaHQnO1xuICAgIH1cbiAgICByZXR1cm4gJyc7XG59XG5cbi8qKlxuICogZ2V0IGEgcmVjb2duaXplciBieSBuYW1lIGlmIGl0IGlzIGJvdW5kIHRvIGEgbWFuYWdlclxuICogQHBhcmFtIHtSZWNvZ25pemVyfFN0cmluZ30gb3RoZXJSZWNvZ25pemVyXG4gKiBAcGFyYW0ge1JlY29nbml6ZXJ9IHJlY29nbml6ZXJcbiAqIEByZXR1cm5zIHtSZWNvZ25pemVyfVxuICovXG5mdW5jdGlvbiBnZXRSZWNvZ25pemVyQnlOYW1lSWZNYW5hZ2VyKG90aGVyUmVjb2duaXplciwgcmVjb2duaXplcikge1xuICAgIHZhciBtYW5hZ2VyID0gcmVjb2duaXplci5tYW5hZ2VyO1xuICAgIGlmIChtYW5hZ2VyKSB7XG4gICAgICAgIHJldHVybiBtYW5hZ2VyLmdldChvdGhlclJlY29nbml6ZXIpO1xuICAgIH1cbiAgICByZXR1cm4gb3RoZXJSZWNvZ25pemVyO1xufVxuXG4vKipcbiAqIFRoaXMgcmVjb2duaXplciBpcyBqdXN0IHVzZWQgYXMgYSBiYXNlIGZvciB0aGUgc2ltcGxlIGF0dHJpYnV0ZSByZWNvZ25pemVycy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBBdHRyUmVjb2duaXplcigpIHtcbiAgICBSZWNvZ25pemVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbmluaGVyaXQoQXR0clJlY29nbml6ZXIsIFJlY29nbml6ZXIsIHtcbiAgICAvKipcbiAgICAgKiBAbmFtZXNwYWNlXG4gICAgICogQG1lbWJlcm9mIEF0dHJSZWNvZ25pemVyXG4gICAgICovXG4gICAgZGVmYXVsdHM6IHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEB0eXBlIHtOdW1iZXJ9XG4gICAgICAgICAqIEBkZWZhdWx0IDFcbiAgICAgICAgICovXG4gICAgICAgIHBvaW50ZXJzOiAxXG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIFVzZWQgdG8gY2hlY2sgaWYgaXQgdGhlIHJlY29nbml6ZXIgcmVjZWl2ZXMgdmFsaWQgaW5wdXQsIGxpa2UgaW5wdXQuZGlzdGFuY2UgPiAxMC5cbiAgICAgKiBAbWVtYmVyb2YgQXR0clJlY29nbml6ZXJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gcmVjb2duaXplZFxuICAgICAqL1xuICAgIGF0dHJUZXN0OiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgb3B0aW9uUG9pbnRlcnMgPSB0aGlzLm9wdGlvbnMucG9pbnRlcnM7XG4gICAgICAgIHJldHVybiBvcHRpb25Qb2ludGVycyA9PT0gMCB8fCBpbnB1dC5wb2ludGVycy5sZW5ndGggPT09IG9wdGlvblBvaW50ZXJzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBQcm9jZXNzIHRoZSBpbnB1dCBhbmQgcmV0dXJuIHRoZSBzdGF0ZSBmb3IgdGhlIHJlY29nbml6ZXJcbiAgICAgKiBAbWVtYmVyb2YgQXR0clJlY29nbml6ZXJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXRcbiAgICAgKiBAcmV0dXJucyB7Kn0gU3RhdGVcbiAgICAgKi9cbiAgICBwcm9jZXNzOiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlO1xuICAgICAgICB2YXIgZXZlbnRUeXBlID0gaW5wdXQuZXZlbnRUeXBlO1xuXG4gICAgICAgIHZhciBpc1JlY29nbml6ZWQgPSBzdGF0ZSAmIChTVEFURV9CRUdBTiB8IFNUQVRFX0NIQU5HRUQpO1xuICAgICAgICB2YXIgaXNWYWxpZCA9IHRoaXMuYXR0clRlc3QoaW5wdXQpO1xuXG4gICAgICAgIC8vIG9uIGNhbmNlbCBpbnB1dCBhbmQgd2UndmUgcmVjb2duaXplZCBiZWZvcmUsIHJldHVybiBTVEFURV9DQU5DRUxMRURcbiAgICAgICAgaWYgKGlzUmVjb2duaXplZCAmJiAoZXZlbnRUeXBlICYgSU5QVVRfQ0FOQ0VMIHx8ICFpc1ZhbGlkKSkge1xuICAgICAgICAgICAgcmV0dXJuIHN0YXRlIHwgU1RBVEVfQ0FOQ0VMTEVEO1xuICAgICAgICB9IGVsc2UgaWYgKGlzUmVjb2duaXplZCB8fCBpc1ZhbGlkKSB7XG4gICAgICAgICAgICBpZiAoZXZlbnRUeXBlICYgSU5QVVRfRU5EKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0YXRlIHwgU1RBVEVfRU5ERUQ7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKCEoc3RhdGUgJiBTVEFURV9CRUdBTikpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gU1RBVEVfQkVHQU47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gc3RhdGUgfCBTVEFURV9DSEFOR0VEO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBTVEFURV9GQUlMRUQ7XG4gICAgfVxufSk7XG5cbi8qKlxuICogUGFuXG4gKiBSZWNvZ25pemVkIHdoZW4gdGhlIHBvaW50ZXIgaXMgZG93biBhbmQgbW92ZWQgaW4gdGhlIGFsbG93ZWQgZGlyZWN0aW9uLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyBBdHRyUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBQYW5SZWNvZ25pemVyKCkge1xuICAgIEF0dHJSZWNvZ25pemVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICB0aGlzLnBYID0gbnVsbDtcbiAgICB0aGlzLnBZID0gbnVsbDtcbn1cblxuaW5oZXJpdChQYW5SZWNvZ25pemVyLCBBdHRyUmVjb2duaXplciwge1xuICAgIC8qKlxuICAgICAqIEBuYW1lc3BhY2VcbiAgICAgKiBAbWVtYmVyb2YgUGFuUmVjb2duaXplclxuICAgICAqL1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgIGV2ZW50OiAncGFuJyxcbiAgICAgICAgdGhyZXNob2xkOiAxMCxcbiAgICAgICAgcG9pbnRlcnM6IDEsXG4gICAgICAgIGRpcmVjdGlvbjogRElSRUNUSU9OX0FMTFxuICAgIH0sXG5cbiAgICBnZXRUb3VjaEFjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSB0aGlzLm9wdGlvbnMuZGlyZWN0aW9uO1xuICAgICAgICB2YXIgYWN0aW9ucyA9IFtdO1xuICAgICAgICBpZiAoZGlyZWN0aW9uICYgRElSRUNUSU9OX0hPUklaT05UQUwpIHtcbiAgICAgICAgICAgIGFjdGlvbnMucHVzaChUT1VDSF9BQ1RJT05fUEFOX1kpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkaXJlY3Rpb24gJiBESVJFQ1RJT05fVkVSVElDQUwpIHtcbiAgICAgICAgICAgIGFjdGlvbnMucHVzaChUT1VDSF9BQ1RJT05fUEFOX1gpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBhY3Rpb25zO1xuICAgIH0sXG5cbiAgICBkaXJlY3Rpb25UZXN0OiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgb3B0aW9ucyA9IHRoaXMub3B0aW9ucztcbiAgICAgICAgdmFyIGhhc01vdmVkID0gdHJ1ZTtcbiAgICAgICAgdmFyIGRpc3RhbmNlID0gaW5wdXQuZGlzdGFuY2U7XG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSBpbnB1dC5kaXJlY3Rpb247XG4gICAgICAgIHZhciB4ID0gaW5wdXQuZGVsdGFYO1xuICAgICAgICB2YXIgeSA9IGlucHV0LmRlbHRhWTtcblxuICAgICAgICAvLyBsb2NrIHRvIGF4aXM/XG4gICAgICAgIGlmICghKGRpcmVjdGlvbiAmIG9wdGlvbnMuZGlyZWN0aW9uKSkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZGlyZWN0aW9uICYgRElSRUNUSU9OX0hPUklaT05UQUwpIHtcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb24gPSAoeCA9PT0gMCkgPyBESVJFQ1RJT05fTk9ORSA6ICh4IDwgMCkgPyBESVJFQ1RJT05fTEVGVCA6IERJUkVDVElPTl9SSUdIVDtcbiAgICAgICAgICAgICAgICBoYXNNb3ZlZCA9IHggIT0gdGhpcy5wWDtcbiAgICAgICAgICAgICAgICBkaXN0YW5jZSA9IE1hdGguYWJzKGlucHV0LmRlbHRhWCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGRpcmVjdGlvbiA9ICh5ID09PSAwKSA/IERJUkVDVElPTl9OT05FIDogKHkgPCAwKSA/IERJUkVDVElPTl9VUCA6IERJUkVDVElPTl9ET1dOO1xuICAgICAgICAgICAgICAgIGhhc01vdmVkID0geSAhPSB0aGlzLnBZO1xuICAgICAgICAgICAgICAgIGRpc3RhbmNlID0gTWF0aC5hYnMoaW5wdXQuZGVsdGFZKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpbnB1dC5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4gICAgICAgIHJldHVybiBoYXNNb3ZlZCAmJiBkaXN0YW5jZSA+IG9wdGlvbnMudGhyZXNob2xkICYmIGRpcmVjdGlvbiAmIG9wdGlvbnMuZGlyZWN0aW9uO1xuICAgIH0sXG5cbiAgICBhdHRyVGVzdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIEF0dHJSZWNvZ25pemVyLnByb3RvdHlwZS5hdHRyVGVzdC5jYWxsKHRoaXMsIGlucHV0KSAmJlxuICAgICAgICAgICAgKHRoaXMuc3RhdGUgJiBTVEFURV9CRUdBTiB8fCAoISh0aGlzLnN0YXRlICYgU1RBVEVfQkVHQU4pICYmIHRoaXMuZGlyZWN0aW9uVGVzdChpbnB1dCkpKTtcbiAgICB9LFxuXG4gICAgZW1pdDogZnVuY3Rpb24oaW5wdXQpIHtcblxuICAgICAgICB0aGlzLnBYID0gaW5wdXQuZGVsdGFYO1xuICAgICAgICB0aGlzLnBZID0gaW5wdXQuZGVsdGFZO1xuXG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSBkaXJlY3Rpb25TdHIoaW5wdXQuZGlyZWN0aW9uKTtcblxuICAgICAgICBpZiAoZGlyZWN0aW9uKSB7XG4gICAgICAgICAgICBpbnB1dC5hZGRpdGlvbmFsRXZlbnQgPSB0aGlzLm9wdGlvbnMuZXZlbnQgKyBkaXJlY3Rpb247XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc3VwZXIuZW1pdC5jYWxsKHRoaXMsIGlucHV0KTtcbiAgICB9XG59KTtcblxuLyoqXG4gKiBQaW5jaFxuICogUmVjb2duaXplZCB3aGVuIHR3byBvciBtb3JlIHBvaW50ZXJzIGFyZSBtb3ZpbmcgdG93YXJkICh6b29tLWluKSBvciBhd2F5IGZyb20gZWFjaCBvdGhlciAoem9vbS1vdXQpLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyBBdHRyUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBQaW5jaFJlY29nbml6ZXIoKSB7XG4gICAgQXR0clJlY29nbml6ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuaW5oZXJpdChQaW5jaFJlY29nbml6ZXIsIEF0dHJSZWNvZ25pemVyLCB7XG4gICAgLyoqXG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqIEBtZW1iZXJvZiBQaW5jaFJlY29nbml6ZXJcbiAgICAgKi9cbiAgICBkZWZhdWx0czoge1xuICAgICAgICBldmVudDogJ3BpbmNoJyxcbiAgICAgICAgdGhyZXNob2xkOiAwLFxuICAgICAgICBwb2ludGVyczogMlxuICAgIH0sXG5cbiAgICBnZXRUb3VjaEFjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBbVE9VQ0hfQUNUSU9OX05PTkVdO1xuICAgIH0sXG5cbiAgICBhdHRyVGVzdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N1cGVyLmF0dHJUZXN0LmNhbGwodGhpcywgaW5wdXQpICYmXG4gICAgICAgICAgICAoTWF0aC5hYnMoaW5wdXQuc2NhbGUgLSAxKSA+IHRoaXMub3B0aW9ucy50aHJlc2hvbGQgfHwgdGhpcy5zdGF0ZSAmIFNUQVRFX0JFR0FOKTtcbiAgICB9LFxuXG4gICAgZW1pdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgaWYgKGlucHV0LnNjYWxlICE9PSAxKSB7XG4gICAgICAgICAgICB2YXIgaW5PdXQgPSBpbnB1dC5zY2FsZSA8IDEgPyAnaW4nIDogJ291dCc7XG4gICAgICAgICAgICBpbnB1dC5hZGRpdGlvbmFsRXZlbnQgPSB0aGlzLm9wdGlvbnMuZXZlbnQgKyBpbk91dDtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9zdXBlci5lbWl0LmNhbGwodGhpcywgaW5wdXQpO1xuICAgIH1cbn0pO1xuXG4vKipcbiAqIFByZXNzXG4gKiBSZWNvZ25pemVkIHdoZW4gdGhlIHBvaW50ZXIgaXMgZG93biBmb3IgeCBtcyB3aXRob3V0IGFueSBtb3ZlbWVudC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQGV4dGVuZHMgUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBQcmVzc1JlY29nbml6ZXIoKSB7XG4gICAgUmVjb2duaXplci5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuXG4gICAgdGhpcy5fdGltZXIgPSBudWxsO1xuICAgIHRoaXMuX2lucHV0ID0gbnVsbDtcbn1cblxuaW5oZXJpdChQcmVzc1JlY29nbml6ZXIsIFJlY29nbml6ZXIsIHtcbiAgICAvKipcbiAgICAgKiBAbmFtZXNwYWNlXG4gICAgICogQG1lbWJlcm9mIFByZXNzUmVjb2duaXplclxuICAgICAqL1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgIGV2ZW50OiAncHJlc3MnLFxuICAgICAgICBwb2ludGVyczogMSxcbiAgICAgICAgdGltZTogMjUxLCAvLyBtaW5pbWFsIHRpbWUgb2YgdGhlIHBvaW50ZXIgdG8gYmUgcHJlc3NlZFxuICAgICAgICB0aHJlc2hvbGQ6IDkgLy8gYSBtaW5pbWFsIG1vdmVtZW50IGlzIG9rLCBidXQga2VlcCBpdCBsb3dcbiAgICB9LFxuXG4gICAgZ2V0VG91Y2hBY3Rpb246IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gW1RPVUNIX0FDVElPTl9BVVRPXTtcbiAgICB9LFxuXG4gICAgcHJvY2VzczogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG4gICAgICAgIHZhciB2YWxpZFBvaW50ZXJzID0gaW5wdXQucG9pbnRlcnMubGVuZ3RoID09PSBvcHRpb25zLnBvaW50ZXJzO1xuICAgICAgICB2YXIgdmFsaWRNb3ZlbWVudCA9IGlucHV0LmRpc3RhbmNlIDwgb3B0aW9ucy50aHJlc2hvbGQ7XG4gICAgICAgIHZhciB2YWxpZFRpbWUgPSBpbnB1dC5kZWx0YVRpbWUgPiBvcHRpb25zLnRpbWU7XG5cbiAgICAgICAgdGhpcy5faW5wdXQgPSBpbnB1dDtcblxuICAgICAgICAvLyB3ZSBvbmx5IGFsbG93IGxpdHRsZSBtb3ZlbWVudFxuICAgICAgICAvLyBhbmQgd2UndmUgcmVhY2hlZCBhbiBlbmQgZXZlbnQsIHNvIGEgdGFwIGlzIHBvc3NpYmxlXG4gICAgICAgIGlmICghdmFsaWRNb3ZlbWVudCB8fCAhdmFsaWRQb2ludGVycyB8fCAoaW5wdXQuZXZlbnRUeXBlICYgKElOUFVUX0VORCB8IElOUFVUX0NBTkNFTCkgJiYgIXZhbGlkVGltZSkpIHtcbiAgICAgICAgICAgIHRoaXMucmVzZXQoKTtcbiAgICAgICAgfSBlbHNlIGlmIChpbnB1dC5ldmVudFR5cGUgJiBJTlBVVF9TVEFSVCkge1xuICAgICAgICAgICAgdGhpcy5yZXNldCgpO1xuICAgICAgICAgICAgdGhpcy5fdGltZXIgPSBzZXRUaW1lb3V0Q29udGV4dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXRlID0gU1RBVEVfUkVDT0dOSVpFRDtcbiAgICAgICAgICAgICAgICB0aGlzLnRyeUVtaXQoKTtcbiAgICAgICAgICAgIH0sIG9wdGlvbnMudGltZSwgdGhpcyk7XG4gICAgICAgIH0gZWxzZSBpZiAoaW5wdXQuZXZlbnRUeXBlICYgSU5QVVRfRU5EKSB7XG4gICAgICAgICAgICByZXR1cm4gU1RBVEVfUkVDT0dOSVpFRDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU1RBVEVfRkFJTEVEO1xuICAgIH0sXG5cbiAgICByZXNldDogZnVuY3Rpb24oKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLl90aW1lcik7XG4gICAgfSxcblxuICAgIGVtaXQ6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIGlmICh0aGlzLnN0YXRlICE9PSBTVEFURV9SRUNPR05JWkVEKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaW5wdXQgJiYgKGlucHV0LmV2ZW50VHlwZSAmIElOUFVUX0VORCkpIHtcbiAgICAgICAgICAgIHRoaXMubWFuYWdlci5lbWl0KHRoaXMub3B0aW9ucy5ldmVudCArICd1cCcsIGlucHV0KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2lucHV0LnRpbWVTdGFtcCA9IG5vdygpO1xuICAgICAgICAgICAgdGhpcy5tYW5hZ2VyLmVtaXQodGhpcy5vcHRpb25zLmV2ZW50LCB0aGlzLl9pbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG59KTtcblxuLyoqXG4gKiBSb3RhdGVcbiAqIFJlY29nbml6ZWQgd2hlbiB0d28gb3IgbW9yZSBwb2ludGVyIGFyZSBtb3ZpbmcgaW4gYSBjaXJjdWxhciBtb3Rpb24uXG4gKiBAY29uc3RydWN0b3JcbiAqIEBleHRlbmRzIEF0dHJSZWNvZ25pemVyXG4gKi9cbmZ1bmN0aW9uIFJvdGF0ZVJlY29nbml6ZXIoKSB7XG4gICAgQXR0clJlY29nbml6ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuaW5oZXJpdChSb3RhdGVSZWNvZ25pemVyLCBBdHRyUmVjb2duaXplciwge1xuICAgIC8qKlxuICAgICAqIEBuYW1lc3BhY2VcbiAgICAgKiBAbWVtYmVyb2YgUm90YXRlUmVjb2duaXplclxuICAgICAqL1xuICAgIGRlZmF1bHRzOiB7XG4gICAgICAgIGV2ZW50OiAncm90YXRlJyxcbiAgICAgICAgdGhyZXNob2xkOiAwLFxuICAgICAgICBwb2ludGVyczogMlxuICAgIH0sXG5cbiAgICBnZXRUb3VjaEFjdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBbVE9VQ0hfQUNUSU9OX05PTkVdO1xuICAgIH0sXG5cbiAgICBhdHRyVGVzdDogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3N1cGVyLmF0dHJUZXN0LmNhbGwodGhpcywgaW5wdXQpICYmXG4gICAgICAgICAgICAoTWF0aC5hYnMoaW5wdXQucm90YXRpb24pID4gdGhpcy5vcHRpb25zLnRocmVzaG9sZCB8fCB0aGlzLnN0YXRlICYgU1RBVEVfQkVHQU4pO1xuICAgIH1cbn0pO1xuXG4vKipcbiAqIFN3aXBlXG4gKiBSZWNvZ25pemVkIHdoZW4gdGhlIHBvaW50ZXIgaXMgbW92aW5nIGZhc3QgKHZlbG9jaXR5KSwgd2l0aCBlbm91Z2ggZGlzdGFuY2UgaW4gdGhlIGFsbG93ZWQgZGlyZWN0aW9uLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAZXh0ZW5kcyBBdHRyUmVjb2duaXplclxuICovXG5mdW5jdGlvbiBTd2lwZVJlY29nbml6ZXIoKSB7XG4gICAgQXR0clJlY29nbml6ZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbn1cblxuaW5oZXJpdChTd2lwZVJlY29nbml6ZXIsIEF0dHJSZWNvZ25pemVyLCB7XG4gICAgLyoqXG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqIEBtZW1iZXJvZiBTd2lwZVJlY29nbml6ZXJcbiAgICAgKi9cbiAgICBkZWZhdWx0czoge1xuICAgICAgICBldmVudDogJ3N3aXBlJyxcbiAgICAgICAgdGhyZXNob2xkOiAxMCxcbiAgICAgICAgdmVsb2NpdHk6IDAuMyxcbiAgICAgICAgZGlyZWN0aW9uOiBESVJFQ1RJT05fSE9SSVpPTlRBTCB8IERJUkVDVElPTl9WRVJUSUNBTCxcbiAgICAgICAgcG9pbnRlcnM6IDFcbiAgICB9LFxuXG4gICAgZ2V0VG91Y2hBY3Rpb246IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gUGFuUmVjb2duaXplci5wcm90b3R5cGUuZ2V0VG91Y2hBY3Rpb24uY2FsbCh0aGlzKTtcbiAgICB9LFxuXG4gICAgYXR0clRlc3Q6IGZ1bmN0aW9uKGlucHV0KSB7XG4gICAgICAgIHZhciBkaXJlY3Rpb24gPSB0aGlzLm9wdGlvbnMuZGlyZWN0aW9uO1xuICAgICAgICB2YXIgdmVsb2NpdHk7XG5cbiAgICAgICAgaWYgKGRpcmVjdGlvbiAmIChESVJFQ1RJT05fSE9SSVpPTlRBTCB8IERJUkVDVElPTl9WRVJUSUNBTCkpIHtcbiAgICAgICAgICAgIHZlbG9jaXR5ID0gaW5wdXQub3ZlcmFsbFZlbG9jaXR5O1xuICAgICAgICB9IGVsc2UgaWYgKGRpcmVjdGlvbiAmIERJUkVDVElPTl9IT1JJWk9OVEFMKSB7XG4gICAgICAgICAgICB2ZWxvY2l0eSA9IGlucHV0Lm92ZXJhbGxWZWxvY2l0eVg7XG4gICAgICAgIH0gZWxzZSBpZiAoZGlyZWN0aW9uICYgRElSRUNUSU9OX1ZFUlRJQ0FMKSB7XG4gICAgICAgICAgICB2ZWxvY2l0eSA9IGlucHV0Lm92ZXJhbGxWZWxvY2l0eVk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcy5fc3VwZXIuYXR0clRlc3QuY2FsbCh0aGlzLCBpbnB1dCkgJiZcbiAgICAgICAgICAgIGRpcmVjdGlvbiAmIGlucHV0Lm9mZnNldERpcmVjdGlvbiAmJlxuICAgICAgICAgICAgaW5wdXQuZGlzdGFuY2UgPiB0aGlzLm9wdGlvbnMudGhyZXNob2xkICYmXG4gICAgICAgICAgICBpbnB1dC5tYXhQb2ludGVycyA9PSB0aGlzLm9wdGlvbnMucG9pbnRlcnMgJiZcbiAgICAgICAgICAgIGFicyh2ZWxvY2l0eSkgPiB0aGlzLm9wdGlvbnMudmVsb2NpdHkgJiYgaW5wdXQuZXZlbnRUeXBlICYgSU5QVVRfRU5EO1xuICAgIH0sXG5cbiAgICBlbWl0OiBmdW5jdGlvbihpbnB1dCkge1xuICAgICAgICB2YXIgZGlyZWN0aW9uID0gZGlyZWN0aW9uU3RyKGlucHV0Lm9mZnNldERpcmVjdGlvbik7XG4gICAgICAgIGlmIChkaXJlY3Rpb24pIHtcbiAgICAgICAgICAgIHRoaXMubWFuYWdlci5lbWl0KHRoaXMub3B0aW9ucy5ldmVudCArIGRpcmVjdGlvbiwgaW5wdXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tYW5hZ2VyLmVtaXQodGhpcy5vcHRpb25zLmV2ZW50LCBpbnB1dCk7XG4gICAgfVxufSk7XG5cbi8qKlxuICogQSB0YXAgaXMgZWNvZ25pemVkIHdoZW4gdGhlIHBvaW50ZXIgaXMgZG9pbmcgYSBzbWFsbCB0YXAvY2xpY2suIE11bHRpcGxlIHRhcHMgYXJlIHJlY29nbml6ZWQgaWYgdGhleSBvY2N1clxuICogYmV0d2VlbiB0aGUgZ2l2ZW4gaW50ZXJ2YWwgYW5kIHBvc2l0aW9uLiBUaGUgZGVsYXkgb3B0aW9uIGNhbiBiZSB1c2VkIHRvIHJlY29nbml6ZSBtdWx0aS10YXBzIHdpdGhvdXQgZmlyaW5nXG4gKiBhIHNpbmdsZSB0YXAuXG4gKlxuICogVGhlIGV2ZW50RGF0YSBmcm9tIHRoZSBlbWl0dGVkIGV2ZW50IGNvbnRhaW5zIHRoZSBwcm9wZXJ0eSBgdGFwQ291bnRgLCB3aGljaCBjb250YWlucyB0aGUgYW1vdW50IG9mXG4gKiBtdWx0aS10YXBzIGJlaW5nIHJlY29nbml6ZWQuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBleHRlbmRzIFJlY29nbml6ZXJcbiAqL1xuZnVuY3Rpb24gVGFwUmVjb2duaXplcigpIHtcbiAgICBSZWNvZ25pemVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cbiAgICAvLyBwcmV2aW91cyB0aW1lIGFuZCBjZW50ZXIsXG4gICAgLy8gdXNlZCBmb3IgdGFwIGNvdW50aW5nXG4gICAgdGhpcy5wVGltZSA9IGZhbHNlO1xuICAgIHRoaXMucENlbnRlciA9IGZhbHNlO1xuXG4gICAgdGhpcy5fdGltZXIgPSBudWxsO1xuICAgIHRoaXMuX2lucHV0ID0gbnVsbDtcbiAgICB0aGlzLmNvdW50ID0gMDtcbn1cblxuaW5oZXJpdChUYXBSZWNvZ25pemVyLCBSZWNvZ25pemVyLCB7XG4gICAgLyoqXG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqIEBtZW1iZXJvZiBQaW5jaFJlY29nbml6ZXJcbiAgICAgKi9cbiAgICBkZWZhdWx0czoge1xuICAgICAgICBldmVudDogJ3RhcCcsXG4gICAgICAgIHBvaW50ZXJzOiAxLFxuICAgICAgICB0YXBzOiAxLFxuICAgICAgICBpbnRlcnZhbDogMzAwLCAvLyBtYXggdGltZSBiZXR3ZWVuIHRoZSBtdWx0aS10YXAgdGFwc1xuICAgICAgICB0aW1lOiAyNTAsIC8vIG1heCB0aW1lIG9mIHRoZSBwb2ludGVyIHRvIGJlIGRvd24gKGxpa2UgZmluZ2VyIG9uIHRoZSBzY3JlZW4pXG4gICAgICAgIHRocmVzaG9sZDogOSwgLy8gYSBtaW5pbWFsIG1vdmVtZW50IGlzIG9rLCBidXQga2VlcCBpdCBsb3dcbiAgICAgICAgcG9zVGhyZXNob2xkOiAxMCAvLyBhIG11bHRpLXRhcCBjYW4gYmUgYSBiaXQgb2ZmIHRoZSBpbml0aWFsIHBvc2l0aW9uXG4gICAgfSxcblxuICAgIGdldFRvdWNoQWN0aW9uOiBmdW5jdGlvbigpIHtcbiAgICAgICAgcmV0dXJuIFtUT1VDSF9BQ1RJT05fTUFOSVBVTEFUSU9OXTtcbiAgICB9LFxuXG4gICAgcHJvY2VzczogZnVuY3Rpb24oaW5wdXQpIHtcbiAgICAgICAgdmFyIG9wdGlvbnMgPSB0aGlzLm9wdGlvbnM7XG5cbiAgICAgICAgdmFyIHZhbGlkUG9pbnRlcnMgPSBpbnB1dC5wb2ludGVycy5sZW5ndGggPT09IG9wdGlvbnMucG9pbnRlcnM7XG4gICAgICAgIHZhciB2YWxpZE1vdmVtZW50ID0gaW5wdXQuZGlzdGFuY2UgPCBvcHRpb25zLnRocmVzaG9sZDtcbiAgICAgICAgdmFyIHZhbGlkVG91Y2hUaW1lID0gaW5wdXQuZGVsdGFUaW1lIDwgb3B0aW9ucy50aW1lO1xuXG4gICAgICAgIHRoaXMucmVzZXQoKTtcblxuICAgICAgICBpZiAoKGlucHV0LmV2ZW50VHlwZSAmIElOUFVUX1NUQVJUKSAmJiAodGhpcy5jb3VudCA9PT0gMCkpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZhaWxUaW1lb3V0KCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB3ZSBvbmx5IGFsbG93IGxpdHRsZSBtb3ZlbWVudFxuICAgICAgICAvLyBhbmQgd2UndmUgcmVhY2hlZCBhbiBlbmQgZXZlbnQsIHNvIGEgdGFwIGlzIHBvc3NpYmxlXG4gICAgICAgIGlmICh2YWxpZE1vdmVtZW50ICYmIHZhbGlkVG91Y2hUaW1lICYmIHZhbGlkUG9pbnRlcnMpIHtcbiAgICAgICAgICAgIGlmIChpbnB1dC5ldmVudFR5cGUgIT0gSU5QVVRfRU5EKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZmFpbFRpbWVvdXQoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHZhbGlkSW50ZXJ2YWwgPSB0aGlzLnBUaW1lID8gKGlucHV0LnRpbWVTdGFtcCAtIHRoaXMucFRpbWUgPCBvcHRpb25zLmludGVydmFsKSA6IHRydWU7XG4gICAgICAgICAgICB2YXIgdmFsaWRNdWx0aVRhcCA9ICF0aGlzLnBDZW50ZXIgfHwgZ2V0RGlzdGFuY2UodGhpcy5wQ2VudGVyLCBpbnB1dC5jZW50ZXIpIDwgb3B0aW9ucy5wb3NUaHJlc2hvbGQ7XG5cbiAgICAgICAgICAgIHRoaXMucFRpbWUgPSBpbnB1dC50aW1lU3RhbXA7XG4gICAgICAgICAgICB0aGlzLnBDZW50ZXIgPSBpbnB1dC5jZW50ZXI7XG5cbiAgICAgICAgICAgIGlmICghdmFsaWRNdWx0aVRhcCB8fCAhdmFsaWRJbnRlcnZhbCkge1xuICAgICAgICAgICAgICAgIHRoaXMuY291bnQgPSAxO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNvdW50ICs9IDE7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuX2lucHV0ID0gaW5wdXQ7XG5cbiAgICAgICAgICAgIC8vIGlmIHRhcCBjb3VudCBtYXRjaGVzIHdlIGhhdmUgcmVjb2duaXplZCBpdCxcbiAgICAgICAgICAgIC8vIGVsc2UgaXQgaGFzIGJlZ2FuIHJlY29nbml6aW5nLi4uXG4gICAgICAgICAgICB2YXIgdGFwQ291bnQgPSB0aGlzLmNvdW50ICUgb3B0aW9ucy50YXBzO1xuICAgICAgICAgICAgaWYgKHRhcENvdW50ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gbm8gZmFpbGluZyByZXF1aXJlbWVudHMsIGltbWVkaWF0ZWx5IHRyaWdnZXIgdGhlIHRhcCBldmVudFxuICAgICAgICAgICAgICAgIC8vIG9yIHdhaXQgYXMgbG9uZyBhcyB0aGUgbXVsdGl0YXAgaW50ZXJ2YWwgdG8gdHJpZ2dlclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5oYXNSZXF1aXJlRmFpbHVyZXMoKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gU1RBVEVfUkVDT0dOSVpFRDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLl90aW1lciA9IHNldFRpbWVvdXRDb250ZXh0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNUQVRFX1JFQ09HTklaRUQ7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRyeUVtaXQoKTtcbiAgICAgICAgICAgICAgICAgICAgfSwgb3B0aW9ucy5pbnRlcnZhbCwgdGhpcyk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBTVEFURV9CRUdBTjtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIFNUQVRFX0ZBSUxFRDtcbiAgICB9LFxuXG4gICAgZmFpbFRpbWVvdXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLl90aW1lciA9IHNldFRpbWVvdXRDb250ZXh0KGZ1bmN0aW9uKCkge1xuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9IFNUQVRFX0ZBSUxFRDtcbiAgICAgICAgfSwgdGhpcy5vcHRpb25zLmludGVydmFsLCB0aGlzKTtcbiAgICAgICAgcmV0dXJuIFNUQVRFX0ZBSUxFRDtcbiAgICB9LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fdGltZXIpO1xuICAgIH0sXG5cbiAgICBlbWl0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT0gU1RBVEVfUkVDT0dOSVpFRCkge1xuICAgICAgICAgICAgdGhpcy5faW5wdXQudGFwQ291bnQgPSB0aGlzLmNvdW50O1xuICAgICAgICAgICAgdGhpcy5tYW5hZ2VyLmVtaXQodGhpcy5vcHRpb25zLmV2ZW50LCB0aGlzLl9pbnB1dCk7XG4gICAgICAgIH1cbiAgICB9XG59KTtcblxuLyoqXG4gKiBTaW1wbGUgd2F5IHRvIGNyZWF0ZSBhIG1hbmFnZXIgd2l0aCBhIGRlZmF1bHQgc2V0IG9mIHJlY29nbml6ZXJzLlxuICogQHBhcmFtIHtIVE1MRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXVxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIEhhbW1lcihlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgb3B0aW9ucy5yZWNvZ25pemVycyA9IGlmVW5kZWZpbmVkKG9wdGlvbnMucmVjb2duaXplcnMsIEhhbW1lci5kZWZhdWx0cy5wcmVzZXQpO1xuICAgIHJldHVybiBuZXcgTWFuYWdlcihlbGVtZW50LCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBAY29uc3Qge3N0cmluZ31cbiAqL1xuSGFtbWVyLlZFUlNJT04gPSAnMi4wLjcnO1xuXG4vKipcbiAqIGRlZmF1bHQgc2V0dGluZ3NcbiAqIEBuYW1lc3BhY2VcbiAqL1xuSGFtbWVyLmRlZmF1bHRzID0ge1xuICAgIC8qKlxuICAgICAqIHNldCBpZiBET00gZXZlbnRzIGFyZSBiZWluZyB0cmlnZ2VyZWQuXG4gICAgICogQnV0IHRoaXMgaXMgc2xvd2VyIGFuZCB1bnVzZWQgYnkgc2ltcGxlIGltcGxlbWVudGF0aW9ucywgc28gZGlzYWJsZWQgYnkgZGVmYXVsdC5cbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgICAqL1xuICAgIGRvbUV2ZW50czogZmFsc2UsXG5cbiAgICAvKipcbiAgICAgKiBUaGUgdmFsdWUgZm9yIHRoZSB0b3VjaEFjdGlvbiBwcm9wZXJ0eS9mYWxsYmFjay5cbiAgICAgKiBXaGVuIHNldCB0byBgY29tcHV0ZWAgaXQgd2lsbCBtYWdpY2FsbHkgc2V0IHRoZSBjb3JyZWN0IHZhbHVlIGJhc2VkIG9uIHRoZSBhZGRlZCByZWNvZ25pemVycy5cbiAgICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgICAqIEBkZWZhdWx0IGNvbXB1dGVcbiAgICAgKi9cbiAgICB0b3VjaEFjdGlvbjogVE9VQ0hfQUNUSU9OX0NPTVBVVEUsXG5cbiAgICAvKipcbiAgICAgKiBAdHlwZSB7Qm9vbGVhbn1cbiAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICovXG4gICAgZW5hYmxlOiB0cnVlLFxuXG4gICAgLyoqXG4gICAgICogRVhQRVJJTUVOVEFMIEZFQVRVUkUgLS0gY2FuIGJlIHJlbW92ZWQvY2hhbmdlZFxuICAgICAqIENoYW5nZSB0aGUgcGFyZW50IGlucHV0IHRhcmdldCBlbGVtZW50LlxuICAgICAqIElmIE51bGwsIHRoZW4gaXQgaXMgYmVpbmcgc2V0IHRoZSB0byBtYWluIGVsZW1lbnQuXG4gICAgICogQHR5cGUge051bGx8RXZlbnRUYXJnZXR9XG4gICAgICogQGRlZmF1bHQgbnVsbFxuICAgICAqL1xuICAgIGlucHV0VGFyZ2V0OiBudWxsLFxuXG4gICAgLyoqXG4gICAgICogZm9yY2UgYW4gaW5wdXQgY2xhc3NcbiAgICAgKiBAdHlwZSB7TnVsbHxGdW5jdGlvbn1cbiAgICAgKiBAZGVmYXVsdCBudWxsXG4gICAgICovXG4gICAgaW5wdXRDbGFzczogbnVsbCxcblxuICAgIC8qKlxuICAgICAqIERlZmF1bHQgcmVjb2duaXplciBzZXR1cCB3aGVuIGNhbGxpbmcgYEhhbW1lcigpYFxuICAgICAqIFdoZW4gY3JlYXRpbmcgYSBuZXcgTWFuYWdlciB0aGVzZSB3aWxsIGJlIHNraXBwZWQuXG4gICAgICogQHR5cGUge0FycmF5fVxuICAgICAqL1xuICAgIHByZXNldDogW1xuICAgICAgICAvLyBSZWNvZ25pemVyQ2xhc3MsIG9wdGlvbnMsIFtyZWNvZ25pemVXaXRoLCAuLi5dLCBbcmVxdWlyZUZhaWx1cmUsIC4uLl1cbiAgICAgICAgW1JvdGF0ZVJlY29nbml6ZXIsIHtlbmFibGU6IGZhbHNlfV0sXG4gICAgICAgIFtQaW5jaFJlY29nbml6ZXIsIHtlbmFibGU6IGZhbHNlfSwgWydyb3RhdGUnXV0sXG4gICAgICAgIFtTd2lwZVJlY29nbml6ZXIsIHtkaXJlY3Rpb246IERJUkVDVElPTl9IT1JJWk9OVEFMfV0sXG4gICAgICAgIFtQYW5SZWNvZ25pemVyLCB7ZGlyZWN0aW9uOiBESVJFQ1RJT05fSE9SSVpPTlRBTH0sIFsnc3dpcGUnXV0sXG4gICAgICAgIFtUYXBSZWNvZ25pemVyXSxcbiAgICAgICAgW1RhcFJlY29nbml6ZXIsIHtldmVudDogJ2RvdWJsZXRhcCcsIHRhcHM6IDJ9LCBbJ3RhcCddXSxcbiAgICAgICAgW1ByZXNzUmVjb2duaXplcl1cbiAgICBdLFxuXG4gICAgLyoqXG4gICAgICogU29tZSBDU1MgcHJvcGVydGllcyBjYW4gYmUgdXNlZCB0byBpbXByb3ZlIHRoZSB3b3JraW5nIG9mIEhhbW1lci5cbiAgICAgKiBBZGQgdGhlbSB0byB0aGlzIG1ldGhvZCBhbmQgdGhleSB3aWxsIGJlIHNldCB3aGVuIGNyZWF0aW5nIGEgbmV3IE1hbmFnZXIuXG4gICAgICogQG5hbWVzcGFjZVxuICAgICAqL1xuICAgIGNzc1Byb3BzOiB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNhYmxlcyB0ZXh0IHNlbGVjdGlvbiB0byBpbXByb3ZlIHRoZSBkcmFnZ2luZyBnZXN0dXJlLiBNYWlubHkgZm9yIGRlc2t0b3AgYnJvd3NlcnMuXG4gICAgICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICAgICAqIEBkZWZhdWx0ICdub25lJ1xuICAgICAgICAgKi9cbiAgICAgICAgdXNlclNlbGVjdDogJ25vbmUnLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNhYmxlIHRoZSBXaW5kb3dzIFBob25lIGdyaXBwZXJzIHdoZW4gcHJlc3NpbmcgYW4gZWxlbWVudC5cbiAgICAgICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgICAgICogQGRlZmF1bHQgJ25vbmUnXG4gICAgICAgICAqL1xuICAgICAgICB0b3VjaFNlbGVjdDogJ25vbmUnLFxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEaXNhYmxlcyB0aGUgZGVmYXVsdCBjYWxsb3V0IHNob3duIHdoZW4geW91IHRvdWNoIGFuZCBob2xkIGEgdG91Y2ggdGFyZ2V0LlxuICAgICAgICAgKiBPbiBpT1MsIHdoZW4geW91IHRvdWNoIGFuZCBob2xkIGEgdG91Y2ggdGFyZ2V0IHN1Y2ggYXMgYSBsaW5rLCBTYWZhcmkgZGlzcGxheXNcbiAgICAgICAgICogYSBjYWxsb3V0IGNvbnRhaW5pbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGxpbmsuIFRoaXMgcHJvcGVydHkgYWxsb3dzIHlvdSB0byBkaXNhYmxlIHRoYXQgY2FsbG91dC5cbiAgICAgICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgICAgICogQGRlZmF1bHQgJ25vbmUnXG4gICAgICAgICAqL1xuICAgICAgICB0b3VjaENhbGxvdXQ6ICdub25lJyxcblxuICAgICAgICAvKipcbiAgICAgICAgICogU3BlY2lmaWVzIHdoZXRoZXIgem9vbWluZyBpcyBlbmFibGVkLiBVc2VkIGJ5IElFMTA+XG4gICAgICAgICAqIEB0eXBlIHtTdHJpbmd9XG4gICAgICAgICAqIEBkZWZhdWx0ICdub25lJ1xuICAgICAgICAgKi9cbiAgICAgICAgY29udGVudFpvb21pbmc6ICdub25lJyxcblxuICAgICAgICAvKipcbiAgICAgICAgICogU3BlY2lmaWVzIHRoYXQgYW4gZW50aXJlIGVsZW1lbnQgc2hvdWxkIGJlIGRyYWdnYWJsZSBpbnN0ZWFkIG9mIGl0cyBjb250ZW50cy4gTWFpbmx5IGZvciBkZXNrdG9wIGJyb3dzZXJzLlxuICAgICAgICAgKiBAdHlwZSB7U3RyaW5nfVxuICAgICAgICAgKiBAZGVmYXVsdCAnbm9uZSdcbiAgICAgICAgICovXG4gICAgICAgIHVzZXJEcmFnOiAnbm9uZScsXG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE92ZXJyaWRlcyB0aGUgaGlnaGxpZ2h0IGNvbG9yIHNob3duIHdoZW4gdGhlIHVzZXIgdGFwcyBhIGxpbmsgb3IgYSBKYXZhU2NyaXB0XG4gICAgICAgICAqIGNsaWNrYWJsZSBlbGVtZW50IGluIGlPUy4gVGhpcyBwcm9wZXJ0eSBvYmV5cyB0aGUgYWxwaGEgdmFsdWUsIGlmIHNwZWNpZmllZC5cbiAgICAgICAgICogQHR5cGUge1N0cmluZ31cbiAgICAgICAgICogQGRlZmF1bHQgJ3JnYmEoMCwwLDAsMCknXG4gICAgICAgICAqL1xuICAgICAgICB0YXBIaWdobGlnaHRDb2xvcjogJ3JnYmEoMCwwLDAsMCknXG4gICAgfVxufTtcblxudmFyIFNUT1AgPSAxO1xudmFyIEZPUkNFRF9TVE9QID0gMjtcblxuLyoqXG4gKiBNYW5hZ2VyXG4gKiBAcGFyYW0ge0hUTUxFbGVtZW50fSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gTWFuYWdlcihlbGVtZW50LCBvcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0gYXNzaWduKHt9LCBIYW1tZXIuZGVmYXVsdHMsIG9wdGlvbnMgfHwge30pO1xuXG4gICAgdGhpcy5vcHRpb25zLmlucHV0VGFyZ2V0ID0gdGhpcy5vcHRpb25zLmlucHV0VGFyZ2V0IHx8IGVsZW1lbnQ7XG5cbiAgICB0aGlzLmhhbmRsZXJzID0ge307XG4gICAgdGhpcy5zZXNzaW9uID0ge307XG4gICAgdGhpcy5yZWNvZ25pemVycyA9IFtdO1xuICAgIHRoaXMub2xkQ3NzUHJvcHMgPSB7fTtcblxuICAgIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgdGhpcy5pbnB1dCA9IGNyZWF0ZUlucHV0SW5zdGFuY2UodGhpcyk7XG4gICAgdGhpcy50b3VjaEFjdGlvbiA9IG5ldyBUb3VjaEFjdGlvbih0aGlzLCB0aGlzLm9wdGlvbnMudG91Y2hBY3Rpb24pO1xuXG4gICAgdG9nZ2xlQ3NzUHJvcHModGhpcywgdHJ1ZSk7XG5cbiAgICBlYWNoKHRoaXMub3B0aW9ucy5yZWNvZ25pemVycywgZnVuY3Rpb24oaXRlbSkge1xuICAgICAgICB2YXIgcmVjb2duaXplciA9IHRoaXMuYWRkKG5ldyAoaXRlbVswXSkoaXRlbVsxXSkpO1xuICAgICAgICBpdGVtWzJdICYmIHJlY29nbml6ZXIucmVjb2duaXplV2l0aChpdGVtWzJdKTtcbiAgICAgICAgaXRlbVszXSAmJiByZWNvZ25pemVyLnJlcXVpcmVGYWlsdXJlKGl0ZW1bM10pO1xuICAgIH0sIHRoaXMpO1xufVxuXG5NYW5hZ2VyLnByb3RvdHlwZSA9IHtcbiAgICAvKipcbiAgICAgKiBzZXQgb3B0aW9uc1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gICAgICogQHJldHVybnMge01hbmFnZXJ9XG4gICAgICovXG4gICAgc2V0OiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICAgIGFzc2lnbih0aGlzLm9wdGlvbnMsIG9wdGlvbnMpO1xuXG4gICAgICAgIC8vIE9wdGlvbnMgdGhhdCBuZWVkIGEgbGl0dGxlIG1vcmUgc2V0dXBcbiAgICAgICAgaWYgKG9wdGlvbnMudG91Y2hBY3Rpb24pIHtcbiAgICAgICAgICAgIHRoaXMudG91Y2hBY3Rpb24udXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG9wdGlvbnMuaW5wdXRUYXJnZXQpIHtcbiAgICAgICAgICAgIC8vIENsZWFuIHVwIGV4aXN0aW5nIGV2ZW50IGxpc3RlbmVycyBhbmQgcmVpbml0aWFsaXplXG4gICAgICAgICAgICB0aGlzLmlucHV0LmRlc3Ryb3koKTtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQudGFyZ2V0ID0gb3B0aW9ucy5pbnB1dFRhcmdldDtcbiAgICAgICAgICAgIHRoaXMuaW5wdXQuaW5pdCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBzdG9wIHJlY29nbml6aW5nIGZvciB0aGlzIHNlc3Npb24uXG4gICAgICogVGhpcyBzZXNzaW9uIHdpbGwgYmUgZGlzY2FyZGVkLCB3aGVuIGEgbmV3IFtpbnB1dF1zdGFydCBldmVudCBpcyBmaXJlZC5cbiAgICAgKiBXaGVuIGZvcmNlZCwgdGhlIHJlY29nbml6ZXIgY3ljbGUgaXMgc3RvcHBlZCBpbW1lZGlhdGVseS5cbiAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IFtmb3JjZV1cbiAgICAgKi9cbiAgICBzdG9wOiBmdW5jdGlvbihmb3JjZSkge1xuICAgICAgICB0aGlzLnNlc3Npb24uc3RvcHBlZCA9IGZvcmNlID8gRk9SQ0VEX1NUT1AgOiBTVE9QO1xuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBydW4gdGhlIHJlY29nbml6ZXJzIVxuICAgICAqIGNhbGxlZCBieSB0aGUgaW5wdXRIYW5kbGVyIGZ1bmN0aW9uIG9uIGV2ZXJ5IG1vdmVtZW50IG9mIHRoZSBwb2ludGVycyAodG91Y2hlcylcbiAgICAgKiBpdCB3YWxrcyB0aHJvdWdoIGFsbCB0aGUgcmVjb2duaXplcnMgYW5kIHRyaWVzIHRvIGRldGVjdCB0aGUgZ2VzdHVyZSB0aGF0IGlzIGJlaW5nIG1hZGVcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXREYXRhXG4gICAgICovXG4gICAgcmVjb2duaXplOiBmdW5jdGlvbihpbnB1dERhdGEpIHtcbiAgICAgICAgdmFyIHNlc3Npb24gPSB0aGlzLnNlc3Npb247XG4gICAgICAgIGlmIChzZXNzaW9uLnN0b3BwZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJ1biB0aGUgdG91Y2gtYWN0aW9uIHBvbHlmaWxsXG4gICAgICAgIHRoaXMudG91Y2hBY3Rpb24ucHJldmVudERlZmF1bHRzKGlucHV0RGF0YSk7XG5cbiAgICAgICAgdmFyIHJlY29nbml6ZXI7XG4gICAgICAgIHZhciByZWNvZ25pemVycyA9IHRoaXMucmVjb2duaXplcnM7XG5cbiAgICAgICAgLy8gdGhpcyBob2xkcyB0aGUgcmVjb2duaXplciB0aGF0IGlzIGJlaW5nIHJlY29nbml6ZWQuXG4gICAgICAgIC8vIHNvIHRoZSByZWNvZ25pemVyJ3Mgc3RhdGUgbmVlZHMgdG8gYmUgQkVHQU4sIENIQU5HRUQsIEVOREVEIG9yIFJFQ09HTklaRURcbiAgICAgICAgLy8gaWYgbm8gcmVjb2duaXplciBpcyBkZXRlY3RpbmcgYSB0aGluZywgaXQgaXMgc2V0IHRvIGBudWxsYFxuICAgICAgICB2YXIgY3VyUmVjb2duaXplciA9IHNlc3Npb24uY3VyUmVjb2duaXplcjtcblxuICAgICAgICAvLyByZXNldCB3aGVuIHRoZSBsYXN0IHJlY29nbml6ZXIgaXMgcmVjb2duaXplZFxuICAgICAgICAvLyBvciB3aGVuIHdlJ3JlIGluIGEgbmV3IHNlc3Npb25cbiAgICAgICAgaWYgKCFjdXJSZWNvZ25pemVyIHx8IChjdXJSZWNvZ25pemVyICYmIGN1clJlY29nbml6ZXIuc3RhdGUgJiBTVEFURV9SRUNPR05JWkVEKSkge1xuICAgICAgICAgICAgY3VyUmVjb2duaXplciA9IHNlc3Npb24uY3VyUmVjb2duaXplciA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgIHdoaWxlIChpIDwgcmVjb2duaXplcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZWNvZ25pemVyID0gcmVjb2duaXplcnNbaV07XG5cbiAgICAgICAgICAgIC8vIGZpbmQgb3V0IGlmIHdlIGFyZSBhbGxvd2VkIHRyeSB0byByZWNvZ25pemUgdGhlIGlucHV0IGZvciB0aGlzIG9uZS5cbiAgICAgICAgICAgIC8vIDEuICAgYWxsb3cgaWYgdGhlIHNlc3Npb24gaXMgTk9UIGZvcmNlZCBzdG9wcGVkIChzZWUgdGhlIC5zdG9wKCkgbWV0aG9kKVxuICAgICAgICAgICAgLy8gMi4gICBhbGxvdyBpZiB3ZSBzdGlsbCBoYXZlbid0IHJlY29nbml6ZWQgYSBnZXN0dXJlIGluIHRoaXMgc2Vzc2lvbiwgb3IgdGhlIHRoaXMgcmVjb2duaXplciBpcyB0aGUgb25lXG4gICAgICAgICAgICAvLyAgICAgIHRoYXQgaXMgYmVpbmcgcmVjb2duaXplZC5cbiAgICAgICAgICAgIC8vIDMuICAgYWxsb3cgaWYgdGhlIHJlY29nbml6ZXIgaXMgYWxsb3dlZCB0byBydW4gc2ltdWx0YW5lb3VzIHdpdGggdGhlIGN1cnJlbnQgcmVjb2duaXplZCByZWNvZ25pemVyLlxuICAgICAgICAgICAgLy8gICAgICB0aGlzIGNhbiBiZSBzZXR1cCB3aXRoIHRoZSBgcmVjb2duaXplV2l0aCgpYCBtZXRob2Qgb24gdGhlIHJlY29nbml6ZXIuXG4gICAgICAgICAgICBpZiAoc2Vzc2lvbi5zdG9wcGVkICE9PSBGT1JDRURfU1RPUCAmJiAoIC8vIDFcbiAgICAgICAgICAgICAgICAgICAgIWN1clJlY29nbml6ZXIgfHwgcmVjb2duaXplciA9PSBjdXJSZWNvZ25pemVyIHx8IC8vIDJcbiAgICAgICAgICAgICAgICAgICAgcmVjb2duaXplci5jYW5SZWNvZ25pemVXaXRoKGN1clJlY29nbml6ZXIpKSkgeyAvLyAzXG4gICAgICAgICAgICAgICAgcmVjb2duaXplci5yZWNvZ25pemUoaW5wdXREYXRhKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmVjb2duaXplci5yZXNldCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBpZiB0aGUgcmVjb2duaXplciBoYXMgYmVlbiByZWNvZ25pemluZyB0aGUgaW5wdXQgYXMgYSB2YWxpZCBnZXN0dXJlLCB3ZSB3YW50IHRvIHN0b3JlIHRoaXMgb25lIGFzIHRoZVxuICAgICAgICAgICAgLy8gY3VycmVudCBhY3RpdmUgcmVjb2duaXplci4gYnV0IG9ubHkgaWYgd2UgZG9uJ3QgYWxyZWFkeSBoYXZlIGFuIGFjdGl2ZSByZWNvZ25pemVyXG4gICAgICAgICAgICBpZiAoIWN1clJlY29nbml6ZXIgJiYgcmVjb2duaXplci5zdGF0ZSAmIChTVEFURV9CRUdBTiB8IFNUQVRFX0NIQU5HRUQgfCBTVEFURV9FTkRFRCkpIHtcbiAgICAgICAgICAgICAgICBjdXJSZWNvZ25pemVyID0gc2Vzc2lvbi5jdXJSZWNvZ25pemVyID0gcmVjb2duaXplcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBnZXQgYSByZWNvZ25pemVyIGJ5IGl0cyBldmVudCBuYW1lLlxuICAgICAqIEBwYXJhbSB7UmVjb2duaXplcnxTdHJpbmd9IHJlY29nbml6ZXJcbiAgICAgKiBAcmV0dXJucyB7UmVjb2duaXplcnxOdWxsfVxuICAgICAqL1xuICAgIGdldDogZnVuY3Rpb24ocmVjb2duaXplcikge1xuICAgICAgICBpZiAocmVjb2duaXplciBpbnN0YW5jZW9mIFJlY29nbml6ZXIpIHtcbiAgICAgICAgICAgIHJldHVybiByZWNvZ25pemVyO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHJlY29nbml6ZXJzID0gdGhpcy5yZWNvZ25pemVycztcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByZWNvZ25pemVycy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKHJlY29nbml6ZXJzW2ldLm9wdGlvbnMuZXZlbnQgPT0gcmVjb2duaXplcikge1xuICAgICAgICAgICAgICAgIHJldHVybiByZWNvZ25pemVyc1tpXTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogYWRkIGEgcmVjb2duaXplciB0byB0aGUgbWFuYWdlclxuICAgICAqIGV4aXN0aW5nIHJlY29nbml6ZXJzIHdpdGggdGhlIHNhbWUgZXZlbnQgbmFtZSB3aWxsIGJlIHJlbW92ZWRcbiAgICAgKiBAcGFyYW0ge1JlY29nbml6ZXJ9IHJlY29nbml6ZXJcbiAgICAgKiBAcmV0dXJucyB7UmVjb2duaXplcnxNYW5hZ2VyfVxuICAgICAqL1xuICAgIGFkZDogZnVuY3Rpb24ocmVjb2duaXplcikge1xuICAgICAgICBpZiAoaW52b2tlQXJyYXlBcmcocmVjb2duaXplciwgJ2FkZCcsIHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHJlbW92ZSBleGlzdGluZ1xuICAgICAgICB2YXIgZXhpc3RpbmcgPSB0aGlzLmdldChyZWNvZ25pemVyLm9wdGlvbnMuZXZlbnQpO1xuICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlKGV4aXN0aW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMucmVjb2duaXplcnMucHVzaChyZWNvZ25pemVyKTtcbiAgICAgICAgcmVjb2duaXplci5tYW5hZ2VyID0gdGhpcztcblxuICAgICAgICB0aGlzLnRvdWNoQWN0aW9uLnVwZGF0ZSgpO1xuICAgICAgICByZXR1cm4gcmVjb2duaXplcjtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogcmVtb3ZlIGEgcmVjb2duaXplciBieSBuYW1lIG9yIGluc3RhbmNlXG4gICAgICogQHBhcmFtIHtSZWNvZ25pemVyfFN0cmluZ30gcmVjb2duaXplclxuICAgICAqIEByZXR1cm5zIHtNYW5hZ2VyfVxuICAgICAqL1xuICAgIHJlbW92ZTogZnVuY3Rpb24ocmVjb2duaXplcikge1xuICAgICAgICBpZiAoaW52b2tlQXJyYXlBcmcocmVjb2duaXplciwgJ3JlbW92ZScsIHRoaXMpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJlY29nbml6ZXIgPSB0aGlzLmdldChyZWNvZ25pemVyKTtcblxuICAgICAgICAvLyBsZXQncyBtYWtlIHN1cmUgdGhpcyByZWNvZ25pemVyIGV4aXN0c1xuICAgICAgICBpZiAocmVjb2duaXplcikge1xuICAgICAgICAgICAgdmFyIHJlY29nbml6ZXJzID0gdGhpcy5yZWNvZ25pemVycztcbiAgICAgICAgICAgIHZhciBpbmRleCA9IGluQXJyYXkocmVjb2duaXplcnMsIHJlY29nbml6ZXIpO1xuXG4gICAgICAgICAgICBpZiAoaW5kZXggIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgcmVjb2duaXplcnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB0aGlzLnRvdWNoQWN0aW9uLnVwZGF0ZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIGJpbmQgZXZlbnRcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRzXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlclxuICAgICAqIEByZXR1cm5zIHtFdmVudEVtaXR0ZXJ9IHRoaXNcbiAgICAgKi9cbiAgICBvbjogZnVuY3Rpb24oZXZlbnRzLCBoYW5kbGVyKSB7XG4gICAgICAgIGlmIChldmVudHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChoYW5kbGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBoYW5kbGVycyA9IHRoaXMuaGFuZGxlcnM7XG4gICAgICAgIGVhY2goc3BsaXRTdHIoZXZlbnRzKSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGhhbmRsZXJzW2V2ZW50XSA9IGhhbmRsZXJzW2V2ZW50XSB8fCBbXTtcbiAgICAgICAgICAgIGhhbmRsZXJzW2V2ZW50XS5wdXNoKGhhbmRsZXIpO1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcblxuICAgIC8qKlxuICAgICAqIHVuYmluZCBldmVudCwgbGVhdmUgZW1pdCBibGFuayB0byByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50c1xuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtoYW5kbGVyXVxuICAgICAqIEByZXR1cm5zIHtFdmVudEVtaXR0ZXJ9IHRoaXNcbiAgICAgKi9cbiAgICBvZmY6IGZ1bmN0aW9uKGV2ZW50cywgaGFuZGxlcikge1xuICAgICAgICBpZiAoZXZlbnRzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBoYW5kbGVycyA9IHRoaXMuaGFuZGxlcnM7XG4gICAgICAgIGVhY2goc3BsaXRTdHIoZXZlbnRzKSwgZnVuY3Rpb24oZXZlbnQpIHtcbiAgICAgICAgICAgIGlmICghaGFuZGxlcikge1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBoYW5kbGVyc1tldmVudF07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGhhbmRsZXJzW2V2ZW50XSAmJiBoYW5kbGVyc1tldmVudF0uc3BsaWNlKGluQXJyYXkoaGFuZGxlcnNbZXZlbnRdLCBoYW5kbGVyKSwgMSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogZW1pdCBldmVudCB0byB0aGUgbGlzdGVuZXJzXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gICAgICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAgICAgKi9cbiAgICBlbWl0OiBmdW5jdGlvbihldmVudCwgZGF0YSkge1xuICAgICAgICAvLyB3ZSBhbHNvIHdhbnQgdG8gdHJpZ2dlciBkb20gZXZlbnRzXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuZG9tRXZlbnRzKSB7XG4gICAgICAgICAgICB0cmlnZ2VyRG9tRXZlbnQoZXZlbnQsIGRhdGEpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbm8gaGFuZGxlcnMsIHNvIHNraXAgaXQgYWxsXG4gICAgICAgIHZhciBoYW5kbGVycyA9IHRoaXMuaGFuZGxlcnNbZXZlbnRdICYmIHRoaXMuaGFuZGxlcnNbZXZlbnRdLnNsaWNlKCk7XG4gICAgICAgIGlmICghaGFuZGxlcnMgfHwgIWhhbmRsZXJzLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgZGF0YS50eXBlID0gZXZlbnQ7XG4gICAgICAgIGRhdGEucHJldmVudERlZmF1bHQgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGRhdGEuc3JjRXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfTtcblxuICAgICAgICB2YXIgaSA9IDA7XG4gICAgICAgIHdoaWxlIChpIDwgaGFuZGxlcnMubGVuZ3RoKSB7XG4gICAgICAgICAgICBoYW5kbGVyc1tpXShkYXRhKTtcbiAgICAgICAgICAgIGkrKztcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICAvKipcbiAgICAgKiBkZXN0cm95IHRoZSBtYW5hZ2VyIGFuZCB1bmJpbmRzIGFsbCBldmVudHNcbiAgICAgKiBpdCBkb2Vzbid0IHVuYmluZCBkb20gZXZlbnRzLCB0aGF0IGlzIHRoZSB1c2VyIG93biByZXNwb25zaWJpbGl0eVxuICAgICAqL1xuICAgIGRlc3Ryb3k6IGZ1bmN0aW9uKCkge1xuICAgICAgICB0aGlzLmVsZW1lbnQgJiYgdG9nZ2xlQ3NzUHJvcHModGhpcywgZmFsc2UpO1xuXG4gICAgICAgIHRoaXMuaGFuZGxlcnMgPSB7fTtcbiAgICAgICAgdGhpcy5zZXNzaW9uID0ge307XG4gICAgICAgIHRoaXMuaW5wdXQuZGVzdHJveSgpO1xuICAgICAgICB0aGlzLmVsZW1lbnQgPSBudWxsO1xuICAgIH1cbn07XG5cbi8qKlxuICogYWRkL3JlbW92ZSB0aGUgY3NzIHByb3BlcnRpZXMgYXMgZGVmaW5lZCBpbiBtYW5hZ2VyLm9wdGlvbnMuY3NzUHJvcHNcbiAqIEBwYXJhbSB7TWFuYWdlcn0gbWFuYWdlclxuICogQHBhcmFtIHtCb29sZWFufSBhZGRcbiAqL1xuZnVuY3Rpb24gdG9nZ2xlQ3NzUHJvcHMobWFuYWdlciwgYWRkKSB7XG4gICAgdmFyIGVsZW1lbnQgPSBtYW5hZ2VyLmVsZW1lbnQ7XG4gICAgaWYgKCFlbGVtZW50LnN0eWxlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdmFyIHByb3A7XG4gICAgZWFjaChtYW5hZ2VyLm9wdGlvbnMuY3NzUHJvcHMsIGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG4gICAgICAgIHByb3AgPSBwcmVmaXhlZChlbGVtZW50LnN0eWxlLCBuYW1lKTtcbiAgICAgICAgaWYgKGFkZCkge1xuICAgICAgICAgICAgbWFuYWdlci5vbGRDc3NQcm9wc1twcm9wXSA9IGVsZW1lbnQuc3R5bGVbcHJvcF07XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlW3Byb3BdID0gdmFsdWU7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlW3Byb3BdID0gbWFuYWdlci5vbGRDc3NQcm9wc1twcm9wXSB8fCAnJztcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIGlmICghYWRkKSB7XG4gICAgICAgIG1hbmFnZXIub2xkQ3NzUHJvcHMgPSB7fTtcbiAgICB9XG59XG5cbi8qKlxuICogdHJpZ2dlciBkb20gZXZlbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICogQHBhcmFtIHtPYmplY3R9IGRhdGFcbiAqL1xuZnVuY3Rpb24gdHJpZ2dlckRvbUV2ZW50KGV2ZW50LCBkYXRhKSB7XG4gICAgdmFyIGdlc3R1cmVFdmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdFdmVudCcpO1xuICAgIGdlc3R1cmVFdmVudC5pbml0RXZlbnQoZXZlbnQsIHRydWUsIHRydWUpO1xuICAgIGdlc3R1cmVFdmVudC5nZXN0dXJlID0gZGF0YTtcbiAgICBkYXRhLnRhcmdldC5kaXNwYXRjaEV2ZW50KGdlc3R1cmVFdmVudCk7XG59XG5cbmFzc2lnbihIYW1tZXIsIHtcbiAgICBJTlBVVF9TVEFSVDogSU5QVVRfU1RBUlQsXG4gICAgSU5QVVRfTU9WRTogSU5QVVRfTU9WRSxcbiAgICBJTlBVVF9FTkQ6IElOUFVUX0VORCxcbiAgICBJTlBVVF9DQU5DRUw6IElOUFVUX0NBTkNFTCxcblxuICAgIFNUQVRFX1BPU1NJQkxFOiBTVEFURV9QT1NTSUJMRSxcbiAgICBTVEFURV9CRUdBTjogU1RBVEVfQkVHQU4sXG4gICAgU1RBVEVfQ0hBTkdFRDogU1RBVEVfQ0hBTkdFRCxcbiAgICBTVEFURV9FTkRFRDogU1RBVEVfRU5ERUQsXG4gICAgU1RBVEVfUkVDT0dOSVpFRDogU1RBVEVfUkVDT0dOSVpFRCxcbiAgICBTVEFURV9DQU5DRUxMRUQ6IFNUQVRFX0NBTkNFTExFRCxcbiAgICBTVEFURV9GQUlMRUQ6IFNUQVRFX0ZBSUxFRCxcblxuICAgIERJUkVDVElPTl9OT05FOiBESVJFQ1RJT05fTk9ORSxcbiAgICBESVJFQ1RJT05fTEVGVDogRElSRUNUSU9OX0xFRlQsXG4gICAgRElSRUNUSU9OX1JJR0hUOiBESVJFQ1RJT05fUklHSFQsXG4gICAgRElSRUNUSU9OX1VQOiBESVJFQ1RJT05fVVAsXG4gICAgRElSRUNUSU9OX0RPV046IERJUkVDVElPTl9ET1dOLFxuICAgIERJUkVDVElPTl9IT1JJWk9OVEFMOiBESVJFQ1RJT05fSE9SSVpPTlRBTCxcbiAgICBESVJFQ1RJT05fVkVSVElDQUw6IERJUkVDVElPTl9WRVJUSUNBTCxcbiAgICBESVJFQ1RJT05fQUxMOiBESVJFQ1RJT05fQUxMLFxuXG4gICAgTWFuYWdlcjogTWFuYWdlcixcbiAgICBJbnB1dDogSW5wdXQsXG4gICAgVG91Y2hBY3Rpb246IFRvdWNoQWN0aW9uLFxuXG4gICAgVG91Y2hJbnB1dDogVG91Y2hJbnB1dCxcbiAgICBNb3VzZUlucHV0OiBNb3VzZUlucHV0LFxuICAgIFBvaW50ZXJFdmVudElucHV0OiBQb2ludGVyRXZlbnRJbnB1dCxcbiAgICBUb3VjaE1vdXNlSW5wdXQ6IFRvdWNoTW91c2VJbnB1dCxcbiAgICBTaW5nbGVUb3VjaElucHV0OiBTaW5nbGVUb3VjaElucHV0LFxuXG4gICAgUmVjb2duaXplcjogUmVjb2duaXplcixcbiAgICBBdHRyUmVjb2duaXplcjogQXR0clJlY29nbml6ZXIsXG4gICAgVGFwOiBUYXBSZWNvZ25pemVyLFxuICAgIFBhbjogUGFuUmVjb2duaXplcixcbiAgICBTd2lwZTogU3dpcGVSZWNvZ25pemVyLFxuICAgIFBpbmNoOiBQaW5jaFJlY29nbml6ZXIsXG4gICAgUm90YXRlOiBSb3RhdGVSZWNvZ25pemVyLFxuICAgIFByZXNzOiBQcmVzc1JlY29nbml6ZXIsXG5cbiAgICBvbjogYWRkRXZlbnRMaXN0ZW5lcnMsXG4gICAgb2ZmOiByZW1vdmVFdmVudExpc3RlbmVycyxcbiAgICBlYWNoOiBlYWNoLFxuICAgIG1lcmdlOiBtZXJnZSxcbiAgICBleHRlbmQ6IGV4dGVuZCxcbiAgICBhc3NpZ246IGFzc2lnbixcbiAgICBpbmhlcml0OiBpbmhlcml0LFxuICAgIGJpbmRGbjogYmluZEZuLFxuICAgIHByZWZpeGVkOiBwcmVmaXhlZFxufSk7XG5cbi8vIHRoaXMgcHJldmVudHMgZXJyb3JzIHdoZW4gSGFtbWVyIGlzIGxvYWRlZCBpbiB0aGUgcHJlc2VuY2Ugb2YgYW4gQU1EXG4vLyAgc3R5bGUgbG9hZGVyIGJ1dCBieSBzY3JpcHQgdGFnLCBub3QgYnkgdGhlIGxvYWRlci5cbnZhciBmcmVlR2xvYmFsID0gKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnID8gd2luZG93IDogKHR5cGVvZiBzZWxmICE9PSAndW5kZWZpbmVkJyA/IHNlbGYgOiB7fSkpOyAvLyBqc2hpbnQgaWdub3JlOmxpbmVcbmZyZWVHbG9iYWwuSGFtbWVyID0gSGFtbWVyO1xuXG5pZiAodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKSB7XG4gICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gSGFtbWVyO1xuICAgIH0pO1xufSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlICE9ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgbW9kdWxlLmV4cG9ydHMgPSBIYW1tZXI7XG59IGVsc2Uge1xuICAgIHdpbmRvd1tleHBvcnROYW1lXSA9IEhhbW1lcjtcbn1cblxufSkod2luZG93LCBkb2N1bWVudCwgJ0hhbW1lcicpO1xuIiwidmFyIGhhdCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGJpdHMsIGJhc2UpIHtcbiAgICBpZiAoIWJhc2UpIGJhc2UgPSAxNjtcbiAgICBpZiAoYml0cyA9PT0gdW5kZWZpbmVkKSBiaXRzID0gMTI4O1xuICAgIGlmIChiaXRzIDw9IDApIHJldHVybiAnMCc7XG4gICAgXG4gICAgdmFyIGRpZ2l0cyA9IE1hdGgubG9nKE1hdGgucG93KDIsIGJpdHMpKSAvIE1hdGgubG9nKGJhc2UpO1xuICAgIGZvciAodmFyIGkgPSAyOyBkaWdpdHMgPT09IEluZmluaXR5OyBpICo9IDIpIHtcbiAgICAgICAgZGlnaXRzID0gTWF0aC5sb2coTWF0aC5wb3coMiwgYml0cyAvIGkpKSAvIE1hdGgubG9nKGJhc2UpICogaTtcbiAgICB9XG4gICAgXG4gICAgdmFyIHJlbSA9IGRpZ2l0cyAtIE1hdGguZmxvb3IoZGlnaXRzKTtcbiAgICBcbiAgICB2YXIgcmVzID0gJyc7XG4gICAgXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBNYXRoLmZsb29yKGRpZ2l0cyk7IGkrKykge1xuICAgICAgICB2YXIgeCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGJhc2UpLnRvU3RyaW5nKGJhc2UpO1xuICAgICAgICByZXMgPSB4ICsgcmVzO1xuICAgIH1cbiAgICBcbiAgICBpZiAocmVtKSB7XG4gICAgICAgIHZhciBiID0gTWF0aC5wb3coYmFzZSwgcmVtKTtcbiAgICAgICAgdmFyIHggPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiBiKS50b1N0cmluZyhiYXNlKTtcbiAgICAgICAgcmVzID0geCArIHJlcztcbiAgICB9XG4gICAgXG4gICAgdmFyIHBhcnNlZCA9IHBhcnNlSW50KHJlcywgYmFzZSk7XG4gICAgaWYgKHBhcnNlZCAhPT0gSW5maW5pdHkgJiYgcGFyc2VkID49IE1hdGgucG93KDIsIGJpdHMpKSB7XG4gICAgICAgIHJldHVybiBoYXQoYml0cywgYmFzZSlcbiAgICB9XG4gICAgZWxzZSByZXR1cm4gcmVzO1xufTtcblxuaGF0LnJhY2sgPSBmdW5jdGlvbiAoYml0cywgYmFzZSwgZXhwYW5kQnkpIHtcbiAgICB2YXIgZm4gPSBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICB2YXIgaXRlcnMgPSAwO1xuICAgICAgICBkbyB7XG4gICAgICAgICAgICBpZiAoaXRlcnMgKysgPiAxMCkge1xuICAgICAgICAgICAgICAgIGlmIChleHBhbmRCeSkgYml0cyArPSBleHBhbmRCeTtcbiAgICAgICAgICAgICAgICBlbHNlIHRocm93IG5ldyBFcnJvcigndG9vIG1hbnkgSUQgY29sbGlzaW9ucywgdXNlIG1vcmUgYml0cycpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHZhciBpZCA9IGhhdChiaXRzLCBiYXNlKTtcbiAgICAgICAgfSB3aGlsZSAoT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwoaGF0cywgaWQpKTtcbiAgICAgICAgXG4gICAgICAgIGhhdHNbaWRdID0gZGF0YTtcbiAgICAgICAgcmV0dXJuIGlkO1xuICAgIH07XG4gICAgdmFyIGhhdHMgPSBmbi5oYXRzID0ge307XG4gICAgXG4gICAgZm4uZ2V0ID0gZnVuY3Rpb24gKGlkKSB7XG4gICAgICAgIHJldHVybiBmbi5oYXRzW2lkXTtcbiAgICB9O1xuICAgIFxuICAgIGZuLnNldCA9IGZ1bmN0aW9uIChpZCwgdmFsdWUpIHtcbiAgICAgICAgZm4uaGF0c1tpZF0gPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuIGZuO1xuICAgIH07XG4gICAgXG4gICAgZm4uYml0cyA9IGJpdHMgfHwgMTI4O1xuICAgIGZuLmJhc2UgPSBiYXNlIHx8IDE2O1xuICAgIHJldHVybiBmbjtcbn07XG4iLCJpbXBvcnQgaGF0IGZyb20gJ2hhdCc7XG5cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgaWQgZ2VuZXJhdG9yIC8gY2FjaGUgaW5zdGFuY2UuXG4gKlxuICogWW91IG1heSBvcHRpb25hbGx5IHByb3ZpZGUgYSBzZWVkIHRoYXQgaXMgdXNlZCBpbnRlcm5hbGx5LlxuICpcbiAqIEBwYXJhbSB7U2VlZH0gc2VlZFxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBJZHMoc2VlZCkge1xuXG4gIGlmICghKHRoaXMgaW5zdGFuY2VvZiBJZHMpKSB7XG4gICAgcmV0dXJuIG5ldyBJZHMoc2VlZCk7XG4gIH1cblxuICBzZWVkID0gc2VlZCB8fCBbIDEyOCwgMzYsIDEgXTtcbiAgdGhpcy5fc2VlZCA9IHNlZWQubGVuZ3RoID8gaGF0LnJhY2soc2VlZFswXSwgc2VlZFsxXSwgc2VlZFsyXSkgOiBzZWVkO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIGEgbmV4dCBpZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gW2VsZW1lbnRdIGVsZW1lbnQgdG8gYmluZCB0aGUgaWQgdG9cbiAqXG4gKiBAcmV0dXJuIHtTdHJpbmd9IGlkXG4gKi9cbklkcy5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHRoaXMuX3NlZWQoZWxlbWVudCB8fCB0cnVlKTtcbn07XG5cbi8qKlxuICogR2VuZXJhdGUgYSBuZXh0IGlkIHdpdGggYSBnaXZlbiBwcmVmaXguXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IFtlbGVtZW50XSBlbGVtZW50IHRvIGJpbmQgdGhlIGlkIHRvXG4gKlxuICogQHJldHVybiB7U3RyaW5nfSBpZFxuICovXG5JZHMucHJvdG90eXBlLm5leHRQcmVmaXhlZCA9IGZ1bmN0aW9uKHByZWZpeCwgZWxlbWVudCkge1xuICB2YXIgaWQ7XG5cbiAgZG8ge1xuICAgIGlkID0gcHJlZml4ICsgdGhpcy5uZXh0KHRydWUpO1xuICB9IHdoaWxlICh0aGlzLmFzc2lnbmVkKGlkKSk7XG5cbiAgLy8gY2xhaW0ge3ByZWZpeH17cmFuZG9tfVxuICB0aGlzLmNsYWltKGlkLCBlbGVtZW50KTtcblxuICAvLyByZXR1cm5cbiAgcmV0dXJuIGlkO1xufTtcblxuLyoqXG4gKiBNYW51YWxseSBjbGFpbSBhbiBleGlzdGluZyBpZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gaWRcbiAqIEBwYXJhbSB7U3RyaW5nfSBbZWxlbWVudF0gZWxlbWVudCB0aGUgaWQgaXMgY2xhaW1lZCBieVxuICovXG5JZHMucHJvdG90eXBlLmNsYWltID0gZnVuY3Rpb24oaWQsIGVsZW1lbnQpIHtcbiAgdGhpcy5fc2VlZC5zZXQoaWQsIGVsZW1lbnQgfHwgdHJ1ZSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gaWQgaGFzIGFscmVhZHkgYmVlbiBhc3NpZ25lZC5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGlkXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5JZHMucHJvdG90eXBlLmFzc2lnbmVkID0gZnVuY3Rpb24oaWQpIHtcbiAgcmV0dXJuIHRoaXMuX3NlZWQuZ2V0KGlkKSB8fCBmYWxzZTtcbn07XG5cbi8qKlxuICogVW5jbGFpbSBhbiBpZC5cbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IGlkIHRoZSBpZCB0byB1bmNsYWltXG4gKi9cbklkcy5wcm90b3R5cGUudW5jbGFpbSA9IGZ1bmN0aW9uKGlkKSB7XG4gIGRlbGV0ZSB0aGlzLl9zZWVkLmhhdHNbaWRdO1xufTtcblxuXG4vKipcbiAqIENsZWFyIGFsbCBjbGFpbWVkIGlkcy5cbiAqL1xuSWRzLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciBoYXRzID0gdGhpcy5fc2VlZC5oYXRzLFxuICAgICAgaWQ7XG5cbiAgZm9yIChpZCBpbiBoYXRzKSB7XG4gICAgdGhpcy51bmNsYWltKGlkKTtcbiAgfVxufTsiLCJpZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBpZiAoc3VwZXJDdG9yKSB7XG4gICAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgICAgY3Rvci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHN1cGVyQ3Rvci5wcm90b3R5cGUsIHtcbiAgICAgICAgY29uc3RydWN0b3I6IHtcbiAgICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG4gIH07XG59IGVsc2Uge1xuICAvLyBvbGQgc2Nob29sIHNoaW0gZm9yIG9sZCBicm93c2Vyc1xuICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGluaGVyaXRzKGN0b3IsIHN1cGVyQ3Rvcikge1xuICAgIGlmIChzdXBlckN0b3IpIHtcbiAgICAgIGN0b3Iuc3VwZXJfID0gc3VwZXJDdG9yXG4gICAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgICAgVGVtcEN0b3IucHJvdG90eXBlID0gc3VwZXJDdG9yLnByb3RvdHlwZVxuICAgICAgY3Rvci5wcm90b3R5cGUgPSBuZXcgVGVtcEN0b3IoKVxuICAgICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gICAgfVxuICB9XG59XG4iLCIvKiFcbiAqIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjMuNS4xXG4gKiBodHRwczovL2pxdWVyeS5jb20vXG4gKlxuICogSW5jbHVkZXMgU2l6emxlLmpzXG4gKiBodHRwczovL3NpenpsZWpzLmNvbS9cbiAqXG4gKiBDb3B5cmlnaHQgSlMgRm91bmRhdGlvbiBhbmQgb3RoZXIgY29udHJpYnV0b3JzXG4gKiBSZWxlYXNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2VcbiAqIGh0dHBzOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAyMC0wNS0wNFQyMjo0OVpcbiAqL1xuKCBmdW5jdGlvbiggZ2xvYmFsLCBmYWN0b3J5ICkge1xuXG5cdFwidXNlIHN0cmljdFwiO1xuXG5cdGlmICggdHlwZW9mIG1vZHVsZSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlLmV4cG9ydHMgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHQvLyBGb3IgQ29tbW9uSlMgYW5kIENvbW1vbkpTLWxpa2UgZW52aXJvbm1lbnRzIHdoZXJlIGEgcHJvcGVyIGB3aW5kb3dgXG5cdFx0Ly8gaXMgcHJlc2VudCwgZXhlY3V0ZSB0aGUgZmFjdG9yeSBhbmQgZ2V0IGpRdWVyeS5cblx0XHQvLyBGb3IgZW52aXJvbm1lbnRzIHRoYXQgZG8gbm90IGhhdmUgYSBgd2luZG93YCB3aXRoIGEgYGRvY3VtZW50YFxuXHRcdC8vIChzdWNoIGFzIE5vZGUuanMpLCBleHBvc2UgYSBmYWN0b3J5IGFzIG1vZHVsZS5leHBvcnRzLlxuXHRcdC8vIFRoaXMgYWNjZW50dWF0ZXMgdGhlIG5lZWQgZm9yIHRoZSBjcmVhdGlvbiBvZiBhIHJlYWwgYHdpbmRvd2AuXG5cdFx0Ly8gZS5nLiB2YXIgalF1ZXJ5ID0gcmVxdWlyZShcImpxdWVyeVwiKSh3aW5kb3cpO1xuXHRcdC8vIFNlZSB0aWNrZXQgIzE0NTQ5IGZvciBtb3JlIGluZm8uXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBnbG9iYWwuZG9jdW1lbnQgP1xuXHRcdFx0ZmFjdG9yeSggZ2xvYmFsLCB0cnVlICkgOlxuXHRcdFx0ZnVuY3Rpb24oIHcgKSB7XG5cdFx0XHRcdGlmICggIXcuZG9jdW1lbnQgKSB7XG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCBcImpRdWVyeSByZXF1aXJlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnRcIiApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBmYWN0b3J5KCB3ICk7XG5cdFx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdGZhY3RvcnkoIGdsb2JhbCApO1xuXHR9XG5cbi8vIFBhc3MgdGhpcyBpZiB3aW5kb3cgaXMgbm90IGRlZmluZWQgeWV0XG59ICkoIHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0aGlzLCBmdW5jdGlvbiggd2luZG93LCBub0dsb2JhbCApIHtcblxuLy8gRWRnZSA8PSAxMiAtIDEzKywgRmlyZWZveCA8PTE4IC0gNDUrLCBJRSAxMCAtIDExLCBTYWZhcmkgNS4xIC0gOSssIGlPUyA2IC0gOS4xXG4vLyB0aHJvdyBleGNlcHRpb25zIHdoZW4gbm9uLXN0cmljdCBjb2RlIChlLmcuLCBBU1AuTkVUIDQuNSkgYWNjZXNzZXMgc3RyaWN0IG1vZGVcbi8vIGFyZ3VtZW50cy5jYWxsZWUuY2FsbGVyICh0cmFjLTEzMzM1KS4gQnV0IGFzIG9mIGpRdWVyeSAzLjAgKDIwMTYpLCBzdHJpY3QgbW9kZSBzaG91bGQgYmUgY29tbW9uXG4vLyBlbm91Z2ggdGhhdCBhbGwgc3VjaCBhdHRlbXB0cyBhcmUgZ3VhcmRlZCBpbiBhIHRyeSBibG9jay5cblwidXNlIHN0cmljdFwiO1xuXG52YXIgYXJyID0gW107XG5cbnZhciBnZXRQcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZjtcblxudmFyIHNsaWNlID0gYXJyLnNsaWNlO1xuXG52YXIgZmxhdCA9IGFyci5mbGF0ID8gZnVuY3Rpb24oIGFycmF5ICkge1xuXHRyZXR1cm4gYXJyLmZsYXQuY2FsbCggYXJyYXkgKTtcbn0gOiBmdW5jdGlvbiggYXJyYXkgKSB7XG5cdHJldHVybiBhcnIuY29uY2F0LmFwcGx5KCBbXSwgYXJyYXkgKTtcbn07XG5cblxudmFyIHB1c2ggPSBhcnIucHVzaDtcblxudmFyIGluZGV4T2YgPSBhcnIuaW5kZXhPZjtcblxudmFyIGNsYXNzMnR5cGUgPSB7fTtcblxudmFyIHRvU3RyaW5nID0gY2xhc3MydHlwZS50b1N0cmluZztcblxudmFyIGhhc093biA9IGNsYXNzMnR5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBmblRvU3RyaW5nID0gaGFzT3duLnRvU3RyaW5nO1xuXG52YXIgT2JqZWN0RnVuY3Rpb25TdHJpbmcgPSBmblRvU3RyaW5nLmNhbGwoIE9iamVjdCApO1xuXG52YXIgc3VwcG9ydCA9IHt9O1xuXG52YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIGlzRnVuY3Rpb24oIG9iaiApIHtcblxuICAgICAgLy8gU3VwcG9ydDogQ2hyb21lIDw9NTcsIEZpcmVmb3ggPD01MlxuICAgICAgLy8gSW4gc29tZSBicm93c2VycywgdHlwZW9mIHJldHVybnMgXCJmdW5jdGlvblwiIGZvciBIVE1MIDxvYmplY3Q+IGVsZW1lbnRzXG4gICAgICAvLyAoaS5lLiwgYHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9iamVjdFwiICkgPT09IFwiZnVuY3Rpb25cImApLlxuICAgICAgLy8gV2UgZG9uJ3Qgd2FudCB0byBjbGFzc2lmeSAqYW55KiBET00gbm9kZSBhcyBhIGZ1bmN0aW9uLlxuICAgICAgcmV0dXJuIHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2Ygb2JqLm5vZGVUeXBlICE9PSBcIm51bWJlclwiO1xuICB9O1xuXG5cbnZhciBpc1dpbmRvdyA9IGZ1bmN0aW9uIGlzV2luZG93KCBvYmogKSB7XG5cdFx0cmV0dXJuIG9iaiAhPSBudWxsICYmIG9iaiA9PT0gb2JqLndpbmRvdztcblx0fTtcblxuXG52YXIgZG9jdW1lbnQgPSB3aW5kb3cuZG9jdW1lbnQ7XG5cblxuXG5cdHZhciBwcmVzZXJ2ZWRTY3JpcHRBdHRyaWJ1dGVzID0ge1xuXHRcdHR5cGU6IHRydWUsXG5cdFx0c3JjOiB0cnVlLFxuXHRcdG5vbmNlOiB0cnVlLFxuXHRcdG5vTW9kdWxlOiB0cnVlXG5cdH07XG5cblx0ZnVuY3Rpb24gRE9NRXZhbCggY29kZSwgbm9kZSwgZG9jICkge1xuXHRcdGRvYyA9IGRvYyB8fCBkb2N1bWVudDtcblxuXHRcdHZhciBpLCB2YWwsXG5cdFx0XHRzY3JpcHQgPSBkb2MuY3JlYXRlRWxlbWVudCggXCJzY3JpcHRcIiApO1xuXG5cdFx0c2NyaXB0LnRleHQgPSBjb2RlO1xuXHRcdGlmICggbm9kZSApIHtcblx0XHRcdGZvciAoIGkgaW4gcHJlc2VydmVkU2NyaXB0QXR0cmlidXRlcyApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDY0KywgRWRnZSAxOCtcblx0XHRcdFx0Ly8gU29tZSBicm93c2VycyBkb24ndCBzdXBwb3J0IHRoZSBcIm5vbmNlXCIgcHJvcGVydHkgb24gc2NyaXB0cy5cblx0XHRcdFx0Ly8gT24gdGhlIG90aGVyIGhhbmQsIGp1c3QgdXNpbmcgYGdldEF0dHJpYnV0ZWAgaXMgbm90IGVub3VnaCBhc1xuXHRcdFx0XHQvLyB0aGUgYG5vbmNlYCBhdHRyaWJ1dGUgaXMgcmVzZXQgdG8gYW4gZW1wdHkgc3RyaW5nIHdoZW5ldmVyIGl0XG5cdFx0XHRcdC8vIGJlY29tZXMgYnJvd3NpbmctY29udGV4dCBjb25uZWN0ZWQuXG5cdFx0XHRcdC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vd2hhdHdnL2h0bWwvaXNzdWVzLzIzNjlcblx0XHRcdFx0Ly8gU2VlIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI25vbmNlLWF0dHJpYnV0ZXNcblx0XHRcdFx0Ly8gVGhlIGBub2RlLmdldEF0dHJpYnV0ZWAgY2hlY2sgd2FzIGFkZGVkIGZvciB0aGUgc2FrZSBvZlxuXHRcdFx0XHQvLyBgalF1ZXJ5Lmdsb2JhbEV2YWxgIHNvIHRoYXQgaXQgY2FuIGZha2UgYSBub25jZS1jb250YWluaW5nIG5vZGVcblx0XHRcdFx0Ly8gdmlhIGFuIG9iamVjdC5cblx0XHRcdFx0dmFsID0gbm9kZVsgaSBdIHx8IG5vZGUuZ2V0QXR0cmlidXRlICYmIG5vZGUuZ2V0QXR0cmlidXRlKCBpICk7XG5cdFx0XHRcdGlmICggdmFsICkge1xuXHRcdFx0XHRcdHNjcmlwdC5zZXRBdHRyaWJ1dGUoIGksIHZhbCApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGRvYy5oZWFkLmFwcGVuZENoaWxkKCBzY3JpcHQgKS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBzY3JpcHQgKTtcblx0fVxuXG5cbmZ1bmN0aW9uIHRvVHlwZSggb2JqICkge1xuXHRpZiAoIG9iaiA9PSBudWxsICkge1xuXHRcdHJldHVybiBvYmogKyBcIlwiO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTIuMyBvbmx5IChmdW5jdGlvbmlzaCBSZWdFeHApXG5cdHJldHVybiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiA/XG5cdFx0Y2xhc3MydHlwZVsgdG9TdHJpbmcuY2FsbCggb2JqICkgXSB8fCBcIm9iamVjdFwiIDpcblx0XHR0eXBlb2Ygb2JqO1xufVxuLyogZ2xvYmFsIFN5bWJvbCAqL1xuLy8gRGVmaW5pbmcgdGhpcyBnbG9iYWwgaW4gLmVzbGludHJjLmpzb24gd291bGQgY3JlYXRlIGEgZGFuZ2VyIG9mIHVzaW5nIHRoZSBnbG9iYWxcbi8vIHVuZ3VhcmRlZCBpbiBhbm90aGVyIHBsYWNlLCBpdCBzZWVtcyBzYWZlciB0byBkZWZpbmUgZ2xvYmFsIG9ubHkgZm9yIHRoaXMgbW9kdWxlXG5cblxuXG52YXJcblx0dmVyc2lvbiA9IFwiMy41LjFcIixcblxuXHQvLyBEZWZpbmUgYSBsb2NhbCBjb3B5IG9mIGpRdWVyeVxuXHRqUXVlcnkgPSBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cblx0XHQvLyBUaGUgalF1ZXJ5IG9iamVjdCBpcyBhY3R1YWxseSBqdXN0IHRoZSBpbml0IGNvbnN0cnVjdG9yICdlbmhhbmNlZCdcblx0XHQvLyBOZWVkIGluaXQgaWYgalF1ZXJ5IGlzIGNhbGxlZCAoanVzdCBhbGxvdyBlcnJvciB0byBiZSB0aHJvd24gaWYgbm90IGluY2x1ZGVkKVxuXHRcdHJldHVybiBuZXcgalF1ZXJ5LmZuLmluaXQoIHNlbGVjdG9yLCBjb250ZXh0ICk7XG5cdH07XG5cbmpRdWVyeS5mbiA9IGpRdWVyeS5wcm90b3R5cGUgPSB7XG5cblx0Ly8gVGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBqUXVlcnkgYmVpbmcgdXNlZFxuXHRqcXVlcnk6IHZlcnNpb24sXG5cblx0Y29uc3RydWN0b3I6IGpRdWVyeSxcblxuXHQvLyBUaGUgZGVmYXVsdCBsZW5ndGggb2YgYSBqUXVlcnkgb2JqZWN0IGlzIDBcblx0bGVuZ3RoOiAwLFxuXG5cdHRvQXJyYXk6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7XG5cdH0sXG5cblx0Ly8gR2V0IHRoZSBOdGggZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBlbGVtZW50IHNldCBPUlxuXHQvLyBHZXQgdGhlIHdob2xlIG1hdGNoZWQgZWxlbWVudCBzZXQgYXMgYSBjbGVhbiBhcnJheVxuXHRnZXQ6IGZ1bmN0aW9uKCBudW0gKSB7XG5cblx0XHQvLyBSZXR1cm4gYWxsIHRoZSBlbGVtZW50cyBpbiBhIGNsZWFuIGFycmF5XG5cdFx0aWYgKCBudW0gPT0gbnVsbCApIHtcblx0XHRcdHJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIGp1c3QgdGhlIG9uZSBlbGVtZW50IGZyb20gdGhlIHNldFxuXHRcdHJldHVybiBudW0gPCAwID8gdGhpc1sgbnVtICsgdGhpcy5sZW5ndGggXSA6IHRoaXNbIG51bSBdO1xuXHR9LFxuXG5cdC8vIFRha2UgYW4gYXJyYXkgb2YgZWxlbWVudHMgYW5kIHB1c2ggaXQgb250byB0aGUgc3RhY2tcblx0Ly8gKHJldHVybmluZyB0aGUgbmV3IG1hdGNoZWQgZWxlbWVudCBzZXQpXG5cdHB1c2hTdGFjazogZnVuY3Rpb24oIGVsZW1zICkge1xuXG5cdFx0Ly8gQnVpbGQgYSBuZXcgalF1ZXJ5IG1hdGNoZWQgZWxlbWVudCBzZXRcblx0XHR2YXIgcmV0ID0galF1ZXJ5Lm1lcmdlKCB0aGlzLmNvbnN0cnVjdG9yKCksIGVsZW1zICk7XG5cblx0XHQvLyBBZGQgdGhlIG9sZCBvYmplY3Qgb250byB0aGUgc3RhY2sgKGFzIGEgcmVmZXJlbmNlKVxuXHRcdHJldC5wcmV2T2JqZWN0ID0gdGhpcztcblxuXHRcdC8vIFJldHVybiB0aGUgbmV3bHktZm9ybWVkIGVsZW1lbnQgc2V0XG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHQvLyBFeGVjdXRlIGEgY2FsbGJhY2sgZm9yIGV2ZXJ5IGVsZW1lbnQgaW4gdGhlIG1hdGNoZWQgc2V0LlxuXHRlYWNoOiBmdW5jdGlvbiggY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5lYWNoKCB0aGlzLCBjYWxsYmFjayApO1xuXHR9LFxuXG5cdG1hcDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5Lm1hcCggdGhpcywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gY2FsbGJhY2suY2FsbCggZWxlbSwgaSwgZWxlbSApO1xuXHRcdH0gKSApO1xuXHR9LFxuXG5cdHNsaWNlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHNsaWNlLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSApO1xuXHR9LFxuXG5cdGZpcnN0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lcSggMCApO1xuXHR9LFxuXG5cdGxhc3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVxKCAtMSApO1xuXHR9LFxuXG5cdGV2ZW46IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5LmdyZXAoIHRoaXMsIGZ1bmN0aW9uKCBfZWxlbSwgaSApIHtcblx0XHRcdHJldHVybiAoIGkgKyAxICkgJSAyO1xuXHRcdH0gKSApO1xuXHR9LFxuXG5cdG9kZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkuZ3JlcCggdGhpcywgZnVuY3Rpb24oIF9lbGVtLCBpICkge1xuXHRcdFx0cmV0dXJuIGkgJSAyO1xuXHRcdH0gKSApO1xuXHR9LFxuXG5cdGVxOiBmdW5jdGlvbiggaSApIHtcblx0XHR2YXIgbGVuID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRqID0gK2kgKyAoIGkgPCAwID8gbGVuIDogMCApO1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggaiA+PSAwICYmIGogPCBsZW4gPyBbIHRoaXNbIGogXSBdIDogW10gKTtcblx0fSxcblxuXHRlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnByZXZPYmplY3QgfHwgdGhpcy5jb25zdHJ1Y3RvcigpO1xuXHR9LFxuXG5cdC8vIEZvciBpbnRlcm5hbCB1c2Ugb25seS5cblx0Ly8gQmVoYXZlcyBsaWtlIGFuIEFycmF5J3MgbWV0aG9kLCBub3QgbGlrZSBhIGpRdWVyeSBtZXRob2QuXG5cdHB1c2g6IHB1c2gsXG5cdHNvcnQ6IGFyci5zb3J0LFxuXHRzcGxpY2U6IGFyci5zcGxpY2Vcbn07XG5cbmpRdWVyeS5leHRlbmQgPSBqUXVlcnkuZm4uZXh0ZW5kID0gZnVuY3Rpb24oKSB7XG5cdHZhciBvcHRpb25zLCBuYW1lLCBzcmMsIGNvcHksIGNvcHlJc0FycmF5LCBjbG9uZSxcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbIDAgXSB8fCB7fSxcblx0XHRpID0gMSxcblx0XHRsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxuXHRcdGRlZXAgPSBmYWxzZTtcblxuXHQvLyBIYW5kbGUgYSBkZWVwIGNvcHkgc2l0dWF0aW9uXG5cdGlmICggdHlwZW9mIHRhcmdldCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0ZGVlcCA9IHRhcmdldDtcblxuXHRcdC8vIFNraXAgdGhlIGJvb2xlYW4gYW5kIHRoZSB0YXJnZXRcblx0XHR0YXJnZXQgPSBhcmd1bWVudHNbIGkgXSB8fCB7fTtcblx0XHRpKys7XG5cdH1cblxuXHQvLyBIYW5kbGUgY2FzZSB3aGVuIHRhcmdldCBpcyBhIHN0cmluZyBvciBzb21ldGhpbmcgKHBvc3NpYmxlIGluIGRlZXAgY29weSlcblx0aWYgKCB0eXBlb2YgdGFyZ2V0ICE9PSBcIm9iamVjdFwiICYmICFpc0Z1bmN0aW9uKCB0YXJnZXQgKSApIHtcblx0XHR0YXJnZXQgPSB7fTtcblx0fVxuXG5cdC8vIEV4dGVuZCBqUXVlcnkgaXRzZWxmIGlmIG9ubHkgb25lIGFyZ3VtZW50IGlzIHBhc3NlZFxuXHRpZiAoIGkgPT09IGxlbmd0aCApIHtcblx0XHR0YXJnZXQgPSB0aGlzO1xuXHRcdGktLTtcblx0fVxuXG5cdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXG5cdFx0Ly8gT25seSBkZWFsIHdpdGggbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlc1xuXHRcdGlmICggKCBvcHRpb25zID0gYXJndW1lbnRzWyBpIF0gKSAhPSBudWxsICkge1xuXG5cdFx0XHQvLyBFeHRlbmQgdGhlIGJhc2Ugb2JqZWN0XG5cdFx0XHRmb3IgKCBuYW1lIGluIG9wdGlvbnMgKSB7XG5cdFx0XHRcdGNvcHkgPSBvcHRpb25zWyBuYW1lIF07XG5cblx0XHRcdFx0Ly8gUHJldmVudCBPYmplY3QucHJvdG90eXBlIHBvbGx1dGlvblxuXHRcdFx0XHQvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXG5cdFx0XHRcdGlmICggbmFtZSA9PT0gXCJfX3Byb3RvX19cIiB8fCB0YXJnZXQgPT09IGNvcHkgKSB7XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBSZWN1cnNlIGlmIHdlJ3JlIG1lcmdpbmcgcGxhaW4gb2JqZWN0cyBvciBhcnJheXNcblx0XHRcdFx0aWYgKCBkZWVwICYmIGNvcHkgJiYgKCBqUXVlcnkuaXNQbGFpbk9iamVjdCggY29weSApIHx8XG5cdFx0XHRcdFx0KCBjb3B5SXNBcnJheSA9IEFycmF5LmlzQXJyYXkoIGNvcHkgKSApICkgKSB7XG5cdFx0XHRcdFx0c3JjID0gdGFyZ2V0WyBuYW1lIF07XG5cblx0XHRcdFx0XHQvLyBFbnN1cmUgcHJvcGVyIHR5cGUgZm9yIHRoZSBzb3VyY2UgdmFsdWVcblx0XHRcdFx0XHRpZiAoIGNvcHlJc0FycmF5ICYmICFBcnJheS5pc0FycmF5KCBzcmMgKSApIHtcblx0XHRcdFx0XHRcdGNsb25lID0gW107XG5cdFx0XHRcdFx0fSBlbHNlIGlmICggIWNvcHlJc0FycmF5ICYmICFqUXVlcnkuaXNQbGFpbk9iamVjdCggc3JjICkgKSB7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IHt9O1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IHNyYztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y29weUlzQXJyYXkgPSBmYWxzZTtcblxuXHRcdFx0XHRcdC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxuXHRcdFx0XHRcdHRhcmdldFsgbmFtZSBdID0galF1ZXJ5LmV4dGVuZCggZGVlcCwgY2xvbmUsIGNvcHkgKTtcblxuXHRcdFx0XHQvLyBEb24ndCBicmluZyBpbiB1bmRlZmluZWQgdmFsdWVzXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGNvcHkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHR0YXJnZXRbIG5hbWUgXSA9IGNvcHk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIG1vZGlmaWVkIG9iamVjdFxuXHRyZXR1cm4gdGFyZ2V0O1xufTtcblxualF1ZXJ5LmV4dGVuZCgge1xuXG5cdC8vIFVuaXF1ZSBmb3IgZWFjaCBjb3B5IG9mIGpRdWVyeSBvbiB0aGUgcGFnZVxuXHRleHBhbmRvOiBcImpRdWVyeVwiICsgKCB2ZXJzaW9uICsgTWF0aC5yYW5kb20oKSApLnJlcGxhY2UoIC9cXEQvZywgXCJcIiApLFxuXG5cdC8vIEFzc3VtZSBqUXVlcnkgaXMgcmVhZHkgd2l0aG91dCB0aGUgcmVhZHkgbW9kdWxlXG5cdGlzUmVhZHk6IHRydWUsXG5cblx0ZXJyb3I6IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCBtc2cgKTtcblx0fSxcblxuXHRub29wOiBmdW5jdGlvbigpIHt9LFxuXG5cdGlzUGxhaW5PYmplY3Q6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0dmFyIHByb3RvLCBDdG9yO1xuXG5cdFx0Ly8gRGV0ZWN0IG9idmlvdXMgbmVnYXRpdmVzXG5cdFx0Ly8gVXNlIHRvU3RyaW5nIGluc3RlYWQgb2YgalF1ZXJ5LnR5cGUgdG8gY2F0Y2ggaG9zdCBvYmplY3RzXG5cdFx0aWYgKCAhb2JqIHx8IHRvU3RyaW5nLmNhbGwoIG9iaiApICE9PSBcIltvYmplY3QgT2JqZWN0XVwiICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHByb3RvID0gZ2V0UHJvdG8oIG9iaiApO1xuXG5cdFx0Ly8gT2JqZWN0cyB3aXRoIG5vIHByb3RvdHlwZSAoZS5nLiwgYE9iamVjdC5jcmVhdGUoIG51bGwgKWApIGFyZSBwbGFpblxuXHRcdGlmICggIXByb3RvICkge1xuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gT2JqZWN0cyB3aXRoIHByb3RvdHlwZSBhcmUgcGxhaW4gaWZmIHRoZXkgd2VyZSBjb25zdHJ1Y3RlZCBieSBhIGdsb2JhbCBPYmplY3QgZnVuY3Rpb25cblx0XHRDdG9yID0gaGFzT3duLmNhbGwoIHByb3RvLCBcImNvbnN0cnVjdG9yXCIgKSAmJiBwcm90by5jb25zdHJ1Y3Rvcjtcblx0XHRyZXR1cm4gdHlwZW9mIEN0b3IgPT09IFwiZnVuY3Rpb25cIiAmJiBmblRvU3RyaW5nLmNhbGwoIEN0b3IgKSA9PT0gT2JqZWN0RnVuY3Rpb25TdHJpbmc7XG5cdH0sXG5cblx0aXNFbXB0eU9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcblx0XHR2YXIgbmFtZTtcblxuXHRcdGZvciAoIG5hbWUgaW4gb2JqICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fSxcblxuXHQvLyBFdmFsdWF0ZXMgYSBzY3JpcHQgaW4gYSBwcm92aWRlZCBjb250ZXh0OyBmYWxscyBiYWNrIHRvIHRoZSBnbG9iYWwgb25lXG5cdC8vIGlmIG5vdCBzcGVjaWZpZWQuXG5cdGdsb2JhbEV2YWw6IGZ1bmN0aW9uKCBjb2RlLCBvcHRpb25zLCBkb2MgKSB7XG5cdFx0RE9NRXZhbCggY29kZSwgeyBub25jZTogb3B0aW9ucyAmJiBvcHRpb25zLm5vbmNlIH0sIGRvYyApO1xuXHR9LFxuXG5cdGVhY2g6IGZ1bmN0aW9uKCBvYmosIGNhbGxiYWNrICkge1xuXHRcdHZhciBsZW5ndGgsIGkgPSAwO1xuXG5cdFx0aWYgKCBpc0FycmF5TGlrZSggb2JqICkgKSB7XG5cdFx0XHRsZW5ndGggPSBvYmoubGVuZ3RoO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdGlmICggY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGZvciAoIGkgaW4gb2JqICkge1xuXHRcdFx0XHRpZiAoIGNhbGxiYWNrLmNhbGwoIG9ialsgaSBdLCBpLCBvYmpbIGkgXSApID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBvYmo7XG5cdH0sXG5cblx0Ly8gcmVzdWx0cyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxuXHRtYWtlQXJyYXk6IGZ1bmN0aW9uKCBhcnIsIHJlc3VsdHMgKSB7XG5cdFx0dmFyIHJldCA9IHJlc3VsdHMgfHwgW107XG5cblx0XHRpZiAoIGFyciAhPSBudWxsICkge1xuXHRcdFx0aWYgKCBpc0FycmF5TGlrZSggT2JqZWN0KCBhcnIgKSApICkge1xuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIHJldCxcblx0XHRcdFx0XHR0eXBlb2YgYXJyID09PSBcInN0cmluZ1wiID9cblx0XHRcdFx0XHRbIGFyciBdIDogYXJyXG5cdFx0XHRcdCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmNhbGwoIHJldCwgYXJyICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblxuXHRpbkFycmF5OiBmdW5jdGlvbiggZWxlbSwgYXJyLCBpICkge1xuXHRcdHJldHVybiBhcnIgPT0gbnVsbCA/IC0xIDogaW5kZXhPZi5jYWxsKCBhcnIsIGVsZW0sIGkgKTtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRtZXJnZTogZnVuY3Rpb24oIGZpcnN0LCBzZWNvbmQgKSB7XG5cdFx0dmFyIGxlbiA9ICtzZWNvbmQubGVuZ3RoLFxuXHRcdFx0aiA9IDAsXG5cdFx0XHRpID0gZmlyc3QubGVuZ3RoO1xuXG5cdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XG5cdFx0XHRmaXJzdFsgaSsrIF0gPSBzZWNvbmRbIGogXTtcblx0XHR9XG5cblx0XHRmaXJzdC5sZW5ndGggPSBpO1xuXG5cdFx0cmV0dXJuIGZpcnN0O1xuXHR9LFxuXG5cdGdyZXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGludmVydCApIHtcblx0XHR2YXIgY2FsbGJhY2tJbnZlcnNlLFxuXHRcdFx0bWF0Y2hlcyA9IFtdLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsZW5ndGggPSBlbGVtcy5sZW5ndGgsXG5cdFx0XHRjYWxsYmFja0V4cGVjdCA9ICFpbnZlcnQ7XG5cblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgb25seSBzYXZpbmcgdGhlIGl0ZW1zXG5cdFx0Ly8gdGhhdCBwYXNzIHRoZSB2YWxpZGF0b3IgZnVuY3Rpb25cblx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdGNhbGxiYWNrSW52ZXJzZSA9ICFjYWxsYmFjayggZWxlbXNbIGkgXSwgaSApO1xuXHRcdFx0aWYgKCBjYWxsYmFja0ludmVyc2UgIT09IGNhbGxiYWNrRXhwZWN0ICkge1xuXHRcdFx0XHRtYXRjaGVzLnB1c2goIGVsZW1zWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gbWF0Y2hlcztcblx0fSxcblxuXHQvLyBhcmcgaXMgZm9yIGludGVybmFsIHVzYWdlIG9ubHlcblx0bWFwOiBmdW5jdGlvbiggZWxlbXMsIGNhbGxiYWNrLCBhcmcgKSB7XG5cdFx0dmFyIGxlbmd0aCwgdmFsdWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdHJldCA9IFtdO1xuXG5cdFx0Ly8gR28gdGhyb3VnaCB0aGUgYXJyYXksIHRyYW5zbGF0aW5nIGVhY2ggb2YgdGhlIGl0ZW1zIHRvIHRoZWlyIG5ldyB2YWx1ZXNcblx0XHRpZiAoIGlzQXJyYXlMaWtlKCBlbGVtcyApICkge1xuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XG5cdFx0XHRcdHZhbHVlID0gY2FsbGJhY2soIGVsZW1zWyBpIF0sIGksIGFyZyApO1xuXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXQucHVzaCggdmFsdWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0Ly8gR28gdGhyb3VnaCBldmVyeSBrZXkgb24gdGhlIG9iamVjdCxcblx0XHR9IGVsc2Uge1xuXHRcdFx0Zm9yICggaSBpbiBlbGVtcyApIHtcblx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjayggZWxlbXNbIGkgXSwgaSwgYXJnICk7XG5cblx0XHRcdFx0aWYgKCB2YWx1ZSAhPSBudWxsICkge1xuXHRcdFx0XHRcdHJldC5wdXNoKCB2YWx1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRcdHJldHVybiBmbGF0KCByZXQgKTtcblx0fSxcblxuXHQvLyBBIGdsb2JhbCBHVUlEIGNvdW50ZXIgZm9yIG9iamVjdHNcblx0Z3VpZDogMSxcblxuXHQvLyBqUXVlcnkuc3VwcG9ydCBpcyBub3QgdXNlZCBpbiBDb3JlIGJ1dCBvdGhlciBwcm9qZWN0cyBhdHRhY2ggdGhlaXJcblx0Ly8gcHJvcGVydGllcyB0byBpdCBzbyBpdCBuZWVkcyB0byBleGlzdC5cblx0c3VwcG9ydDogc3VwcG9ydFxufSApO1xuXG5pZiAoIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiApIHtcblx0alF1ZXJ5LmZuWyBTeW1ib2wuaXRlcmF0b3IgXSA9IGFyclsgU3ltYm9sLml0ZXJhdG9yIF07XG59XG5cbi8vIFBvcHVsYXRlIHRoZSBjbGFzczJ0eXBlIG1hcFxualF1ZXJ5LmVhY2goIFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2xcIi5zcGxpdCggXCIgXCIgKSxcbmZ1bmN0aW9uKCBfaSwgbmFtZSApIHtcblx0Y2xhc3MydHlwZVsgXCJbb2JqZWN0IFwiICsgbmFtZSArIFwiXVwiIF0gPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG59ICk7XG5cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKCBvYmogKSB7XG5cblx0Ly8gU3VwcG9ydDogcmVhbCBpT1MgOC4yIG9ubHkgKG5vdCByZXByb2R1Y2libGUgaW4gc2ltdWxhdG9yKVxuXHQvLyBgaW5gIGNoZWNrIHVzZWQgdG8gcHJldmVudCBKSVQgZXJyb3IgKGdoLTIxNDUpXG5cdC8vIGhhc093biBpc24ndCB1c2VkIGhlcmUgZHVlIHRvIGZhbHNlIG5lZ2F0aXZlc1xuXHQvLyByZWdhcmRpbmcgTm9kZWxpc3QgbGVuZ3RoIGluIElFXG5cdHZhciBsZW5ndGggPSAhIW9iaiAmJiBcImxlbmd0aFwiIGluIG9iaiAmJiBvYmoubGVuZ3RoLFxuXHRcdHR5cGUgPSB0b1R5cGUoIG9iaiApO1xuXG5cdGlmICggaXNGdW5jdGlvbiggb2JqICkgfHwgaXNXaW5kb3coIG9iaiApICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdHJldHVybiB0eXBlID09PSBcImFycmF5XCIgfHwgbGVuZ3RoID09PSAwIHx8XG5cdFx0dHlwZW9mIGxlbmd0aCA9PT0gXCJudW1iZXJcIiAmJiBsZW5ndGggPiAwICYmICggbGVuZ3RoIC0gMSApIGluIG9iajtcbn1cbnZhciBTaXp6bGUgPVxuLyohXG4gKiBTaXp6bGUgQ1NTIFNlbGVjdG9yIEVuZ2luZSB2Mi4zLjVcbiAqIGh0dHBzOi8vc2l6emxlanMuY29tL1xuICpcbiAqIENvcHlyaWdodCBKUyBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcbiAqIFJlbGVhc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZVxuICogaHR0cHM6Ly9qcy5mb3VuZGF0aW9uL1xuICpcbiAqIERhdGU6IDIwMjAtMDMtMTRcbiAqL1xuKCBmdW5jdGlvbiggd2luZG93ICkge1xudmFyIGksXG5cdHN1cHBvcnQsXG5cdEV4cHIsXG5cdGdldFRleHQsXG5cdGlzWE1MLFxuXHR0b2tlbml6ZSxcblx0Y29tcGlsZSxcblx0c2VsZWN0LFxuXHRvdXRlcm1vc3RDb250ZXh0LFxuXHRzb3J0SW5wdXQsXG5cdGhhc0R1cGxpY2F0ZSxcblxuXHQvLyBMb2NhbCBkb2N1bWVudCB2YXJzXG5cdHNldERvY3VtZW50LFxuXHRkb2N1bWVudCxcblx0ZG9jRWxlbSxcblx0ZG9jdW1lbnRJc0hUTUwsXG5cdHJidWdneVFTQSxcblx0cmJ1Z2d5TWF0Y2hlcyxcblx0bWF0Y2hlcyxcblx0Y29udGFpbnMsXG5cblx0Ly8gSW5zdGFuY2Utc3BlY2lmaWMgZGF0YVxuXHRleHBhbmRvID0gXCJzaXp6bGVcIiArIDEgKiBuZXcgRGF0ZSgpLFxuXHRwcmVmZXJyZWREb2MgPSB3aW5kb3cuZG9jdW1lbnQsXG5cdGRpcnJ1bnMgPSAwLFxuXHRkb25lID0gMCxcblx0Y2xhc3NDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHRva2VuQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRjb21waWxlckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0bm9ubmF0aXZlU2VsZWN0b3JDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHNvcnRPcmRlciA9IGZ1bmN0aW9uKCBhLCBiICkge1xuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9LFxuXG5cdC8vIEluc3RhbmNlIG1ldGhvZHNcblx0aGFzT3duID0gKCB7fSApLmhhc093blByb3BlcnR5LFxuXHRhcnIgPSBbXSxcblx0cG9wID0gYXJyLnBvcCxcblx0cHVzaE5hdGl2ZSA9IGFyci5wdXNoLFxuXHRwdXNoID0gYXJyLnB1c2gsXG5cdHNsaWNlID0gYXJyLnNsaWNlLFxuXG5cdC8vIFVzZSBhIHN0cmlwcGVkLWRvd24gaW5kZXhPZiBhcyBpdCdzIGZhc3RlciB0aGFuIG5hdGl2ZVxuXHQvLyBodHRwczovL2pzcGVyZi5jb20vdGhvci1pbmRleG9mLXZzLWZvci81XG5cdGluZGV4T2YgPSBmdW5jdGlvbiggbGlzdCwgZWxlbSApIHtcblx0XHR2YXIgaSA9IDAsXG5cdFx0XHRsZW4gPSBsaXN0Lmxlbmd0aDtcblx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGlmICggbGlzdFsgaSBdID09PSBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIC0xO1xuXHR9LFxuXG5cdGJvb2xlYW5zID0gXCJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58XCIgK1xuXHRcdFwiaXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZFwiLFxuXG5cdC8vIFJlZ3VsYXIgZXhwcmVzc2lvbnNcblxuXHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9jc3MzLXNlbGVjdG9ycy8jd2hpdGVzcGFjZVxuXHR3aGl0ZXNwYWNlID0gXCJbXFxcXHgyMFxcXFx0XFxcXHJcXFxcblxcXFxmXVwiLFxuXG5cdC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9jc3Mtc3ludGF4LTMvI2lkZW50LXRva2VuLWRpYWdyYW1cblx0aWRlbnRpZmllciA9IFwiKD86XFxcXFxcXFxbXFxcXGRhLWZBLUZdezEsNn1cIiArIHdoaXRlc3BhY2UgK1xuXHRcdFwiP3xcXFxcXFxcXFteXFxcXHJcXFxcblxcXFxmXXxbXFxcXHctXXxbXlxcMC1cXFxceDdmXSkrXCIsXG5cblx0Ly8gQXR0cmlidXRlIHNlbGVjdG9yczogaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzXG5cdGF0dHJpYnV0ZXMgPSBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFwiICsgaWRlbnRpZmllciArIFwiKSg/OlwiICsgd2hpdGVzcGFjZSArXG5cblx0XHQvLyBPcGVyYXRvciAoY2FwdHVyZSAyKVxuXHRcdFwiKihbKl4kfCF+XT89KVwiICsgd2hpdGVzcGFjZSArXG5cblx0XHQvLyBcIkF0dHJpYnV0ZSB2YWx1ZXMgbXVzdCBiZSBDU1MgaWRlbnRpZmllcnMgW2NhcHR1cmUgNV1cblx0XHQvLyBvciBzdHJpbmdzIFtjYXB0dXJlIDMgb3IgY2FwdHVyZSA0XVwiXG5cdFx0XCIqKD86JygoPzpcXFxcXFxcXC58W15cXFxcXFxcXCddKSopJ3xcXFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcXFxcIl0pKilcXFwifChcIiArIGlkZW50aWZpZXIgKyBcIikpfClcIiArXG5cdFx0d2hpdGVzcGFjZSArIFwiKlxcXFxdXCIsXG5cblx0cHNldWRvcyA9IFwiOihcIiArIGlkZW50aWZpZXIgKyBcIikoPzpcXFxcKChcIiArXG5cblx0XHQvLyBUbyByZWR1Y2UgdGhlIG51bWJlciBvZiBzZWxlY3RvcnMgbmVlZGluZyB0b2tlbml6ZSBpbiB0aGUgcHJlRmlsdGVyLCBwcmVmZXIgYXJndW1lbnRzOlxuXHRcdC8vIDEuIHF1b3RlZCAoY2FwdHVyZSAzOyBjYXB0dXJlIDQgb3IgY2FwdHVyZSA1KVxuXHRcdFwiKCcoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcIil8XCIgK1xuXG5cdFx0Ly8gMi4gc2ltcGxlIChjYXB0dXJlIDYpXG5cdFx0XCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFwoKVtcXFxcXV18XCIgKyBhdHRyaWJ1dGVzICsgXCIpKil8XCIgK1xuXG5cdFx0Ly8gMy4gYW55dGhpbmcgZWxzZSAoY2FwdHVyZSAyKVxuXHRcdFwiLipcIiArXG5cdFx0XCIpXFxcXCl8KVwiLFxuXG5cdC8vIExlYWRpbmcgYW5kIG5vbi1lc2NhcGVkIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGNhcHR1cmluZyBzb21lIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcnMgcHJlY2VkaW5nIHRoZSBsYXR0ZXJcblx0cndoaXRlc3BhY2UgPSBuZXcgUmVnRXhwKCB3aGl0ZXNwYWNlICsgXCIrXCIsIFwiZ1wiICksXG5cdHJ0cmltID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIrfCgoPzpefFteXFxcXFxcXFxdKSg/OlxcXFxcXFxcLikqKVwiICtcblx0XHR3aGl0ZXNwYWNlICsgXCIrJFwiLCBcImdcIiApLFxuXG5cdHJjb21tYSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKixcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxuXHRyY29tYmluYXRvcnMgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiooWz4rfl18XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcIipcIiApLFxuXHRyZGVzY2VuZCA9IG5ldyBSZWdFeHAoIHdoaXRlc3BhY2UgKyBcInw+XCIgKSxcblxuXHRycHNldWRvID0gbmV3IFJlZ0V4cCggcHNldWRvcyApLFxuXHRyaWRlbnRpZmllciA9IG5ldyBSZWdFeHAoIFwiXlwiICsgaWRlbnRpZmllciArIFwiJFwiICksXG5cblx0bWF0Y2hFeHByID0ge1xuXHRcdFwiSURcIjogbmV3IFJlZ0V4cCggXCJeIyhcIiArIGlkZW50aWZpZXIgKyBcIilcIiApLFxuXHRcdFwiQ0xBU1NcIjogbmV3IFJlZ0V4cCggXCJeXFxcXC4oXCIgKyBpZGVudGlmaWVyICsgXCIpXCIgKSxcblx0XHRcIlRBR1wiOiBuZXcgUmVnRXhwKCBcIl4oXCIgKyBpZGVudGlmaWVyICsgXCJ8WypdKVwiICksXG5cdFx0XCJBVFRSXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgYXR0cmlidXRlcyApLFxuXHRcdFwiUFNFVURPXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgcHNldWRvcyApLFxuXHRcdFwiQ0hJTERcIjogbmV3IFJlZ0V4cCggXCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXFxcKFwiICtcblx0XHRcdHdoaXRlc3BhY2UgKyBcIiooZXZlbnxvZGR8KChbKy1dfCkoXFxcXGQqKW58KVwiICsgd2hpdGVzcGFjZSArIFwiKig/OihbKy1dfClcIiArXG5cdFx0XHR3aGl0ZXNwYWNlICsgXCIqKFxcXFxkKyl8KSlcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpXCIsIFwiaVwiICksXG5cdFx0XCJib29sXCI6IG5ldyBSZWdFeHAoIFwiXig/OlwiICsgYm9vbGVhbnMgKyBcIikkXCIsIFwiaVwiICksXG5cblx0XHQvLyBGb3IgdXNlIGluIGxpYnJhcmllcyBpbXBsZW1lbnRpbmcgLmlzKClcblx0XHQvLyBXZSB1c2UgdGhpcyBmb3IgUE9TIG1hdGNoaW5nIGluIGBzZWxlY3RgXG5cdFx0XCJuZWVkc0NvbnRleHRcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICtcblx0XHRcdFwiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFxcXChcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFx0XCIqKCg/Oi1cXFxcZCk/XFxcXGQqKVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFwpfCkoPz1bXi1dfCQpXCIsIFwiaVwiIClcblx0fSxcblxuXHRyaHRtbCA9IC9IVE1MJC9pLFxuXHRyaW5wdXRzID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxcblx0cmhlYWRlciA9IC9eaFxcZCQvaSxcblxuXHRybmF0aXZlID0gL15bXntdK1xce1xccypcXFtuYXRpdmUgXFx3LyxcblxuXHQvLyBFYXNpbHktcGFyc2VhYmxlL3JldHJpZXZhYmxlIElEIG9yIFRBRyBvciBDTEFTUyBzZWxlY3RvcnNcblx0cnF1aWNrRXhwciA9IC9eKD86IyhbXFx3LV0rKXwoXFx3Kyl8XFwuKFtcXHctXSspKSQvLFxuXG5cdHJzaWJsaW5nID0gL1srfl0vLFxuXG5cdC8vIENTUyBlc2NhcGVzXG5cdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCNlc2NhcGVkLWNoYXJhY3RlcnNcblx0cnVuZXNjYXBlID0gbmV3IFJlZ0V4cCggXCJcXFxcXFxcXFtcXFxcZGEtZkEtRl17MSw2fVwiICsgd2hpdGVzcGFjZSArIFwiP3xcXFxcXFxcXChbXlxcXFxyXFxcXG5cXFxcZl0pXCIsIFwiZ1wiICksXG5cdGZ1bmVzY2FwZSA9IGZ1bmN0aW9uKCBlc2NhcGUsIG5vbkhleCApIHtcblx0XHR2YXIgaGlnaCA9IFwiMHhcIiArIGVzY2FwZS5zbGljZSggMSApIC0gMHgxMDAwMDtcblxuXHRcdHJldHVybiBub25IZXggP1xuXG5cdFx0XHQvLyBTdHJpcCB0aGUgYmFja3NsYXNoIHByZWZpeCBmcm9tIGEgbm9uLWhleCBlc2NhcGUgc2VxdWVuY2Vcblx0XHRcdG5vbkhleCA6XG5cblx0XHRcdC8vIFJlcGxhY2UgYSBoZXhhZGVjaW1hbCBlc2NhcGUgc2VxdWVuY2Ugd2l0aCB0aGUgZW5jb2RlZCBVbmljb2RlIGNvZGUgcG9pbnRcblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9MTErXG5cdFx0XHQvLyBGb3IgdmFsdWVzIG91dHNpZGUgdGhlIEJhc2ljIE11bHRpbGluZ3VhbCBQbGFuZSAoQk1QKSwgbWFudWFsbHkgY29uc3RydWN0IGFcblx0XHRcdC8vIHN1cnJvZ2F0ZSBwYWlyXG5cdFx0XHRoaWdoIDwgMCA/XG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggKyAweDEwMDAwICkgOlxuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoID4+IDEwIHwgMHhEODAwLCBoaWdoICYgMHgzRkYgfCAweERDMDAgKTtcblx0fSxcblxuXHQvLyBDU1Mgc3RyaW5nL2lkZW50aWZpZXIgc2VyaWFsaXphdGlvblxuXHQvLyBodHRwczovL2RyYWZ0cy5jc3N3Zy5vcmcvY3Nzb20vI2NvbW1vbi1zZXJpYWxpemluZy1pZGlvbXNcblx0cmNzc2VzY2FwZSA9IC8oW1xcMC1cXHgxZlxceDdmXXxeLT9cXGQpfF4tJHxbXlxcMC1cXHgxZlxceDdmLVxcdUZGRkZcXHctXS9nLFxuXHRmY3NzZXNjYXBlID0gZnVuY3Rpb24oIGNoLCBhc0NvZGVQb2ludCApIHtcblx0XHRpZiAoIGFzQ29kZVBvaW50ICkge1xuXG5cdFx0XHQvLyBVKzAwMDAgTlVMTCBiZWNvbWVzIFUrRkZGRCBSRVBMQUNFTUVOVCBDSEFSQUNURVJcblx0XHRcdGlmICggY2ggPT09IFwiXFwwXCIgKSB7XG5cdFx0XHRcdHJldHVybiBcIlxcdUZGRkRcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udHJvbCBjaGFyYWN0ZXJzIGFuZCAoZGVwZW5kZW50IHVwb24gcG9zaXRpb24pIG51bWJlcnMgZ2V0IGVzY2FwZWQgYXMgY29kZSBwb2ludHNcblx0XHRcdHJldHVybiBjaC5zbGljZSggMCwgLTEgKSArIFwiXFxcXFwiICtcblx0XHRcdFx0Y2guY2hhckNvZGVBdCggY2gubGVuZ3RoIC0gMSApLnRvU3RyaW5nKCAxNiApICsgXCIgXCI7XG5cdFx0fVxuXG5cdFx0Ly8gT3RoZXIgcG90ZW50aWFsbHktc3BlY2lhbCBBU0NJSSBjaGFyYWN0ZXJzIGdldCBiYWNrc2xhc2gtZXNjYXBlZFxuXHRcdHJldHVybiBcIlxcXFxcIiArIGNoO1xuXHR9LFxuXG5cdC8vIFVzZWQgZm9yIGlmcmFtZXNcblx0Ly8gU2VlIHNldERvY3VtZW50KClcblx0Ly8gUmVtb3ZpbmcgdGhlIGZ1bmN0aW9uIHdyYXBwZXIgY2F1c2VzIGEgXCJQZXJtaXNzaW9uIERlbmllZFwiXG5cdC8vIGVycm9yIGluIElFXG5cdHVubG9hZEhhbmRsZXIgPSBmdW5jdGlvbigpIHtcblx0XHRzZXREb2N1bWVudCgpO1xuXHR9LFxuXG5cdGluRGlzYWJsZWRGaWVsZHNldCA9IGFkZENvbWJpbmF0b3IoXG5cdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gdHJ1ZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiZmllbGRzZXRcIjtcblx0XHR9LFxuXHRcdHsgZGlyOiBcInBhcmVudE5vZGVcIiwgbmV4dDogXCJsZWdlbmRcIiB9XG5cdCk7XG5cbi8vIE9wdGltaXplIGZvciBwdXNoLmFwcGx5KCBfLCBOb2RlTGlzdCApXG50cnkge1xuXHRwdXNoLmFwcGx5KFxuXHRcdCggYXJyID0gc2xpY2UuY2FsbCggcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMgKSApLFxuXHRcdHByZWZlcnJlZERvYy5jaGlsZE5vZGVzXG5cdCk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjBcblx0Ly8gRGV0ZWN0IHNpbGVudGx5IGZhaWxpbmcgcHVzaC5hcHBseVxuXHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG5cdGFyclsgcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMubGVuZ3RoIF0ubm9kZVR5cGU7XG59IGNhdGNoICggZSApIHtcblx0cHVzaCA9IHsgYXBwbHk6IGFyci5sZW5ndGggP1xuXG5cdFx0Ly8gTGV2ZXJhZ2Ugc2xpY2UgaWYgcG9zc2libGVcblx0XHRmdW5jdGlvbiggdGFyZ2V0LCBlbHMgKSB7XG5cdFx0XHRwdXNoTmF0aXZlLmFwcGx5KCB0YXJnZXQsIHNsaWNlLmNhbGwoIGVscyApICk7XG5cdFx0fSA6XG5cblx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZCBkaXJlY3RseVxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcblx0XHRcdHZhciBqID0gdGFyZ2V0Lmxlbmd0aCxcblx0XHRcdFx0aSA9IDA7XG5cblx0XHRcdC8vIENhbid0IHRydXN0IE5vZGVMaXN0Lmxlbmd0aFxuXHRcdFx0d2hpbGUgKCAoIHRhcmdldFsgaisrIF0gPSBlbHNbIGkrKyBdICkgKSB7fVxuXHRcdFx0dGFyZ2V0Lmxlbmd0aCA9IGogLSAxO1xuXHRcdH1cblx0fTtcbn1cblxuZnVuY3Rpb24gU2l6emxlKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcblx0dmFyIG0sIGksIGVsZW0sIG5pZCwgbWF0Y2gsIGdyb3VwcywgbmV3U2VsZWN0b3IsXG5cdFx0bmV3Q29udGV4dCA9IGNvbnRleHQgJiYgY29udGV4dC5vd25lckRvY3VtZW50LFxuXG5cdFx0Ly8gbm9kZVR5cGUgZGVmYXVsdHMgdG8gOSwgc2luY2UgY29udGV4dCBkZWZhdWx0cyB0byBkb2N1bWVudFxuXHRcdG5vZGVUeXBlID0gY29udGV4dCA/IGNvbnRleHQubm9kZVR5cGUgOiA5O1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFJldHVybiBlYXJseSBmcm9tIGNhbGxzIHdpdGggaW52YWxpZCBzZWxlY3RvciBvciBjb250ZXh0XG5cdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiIHx8ICFzZWxlY3RvciB8fFxuXHRcdG5vZGVUeXBlICE9PSAxICYmIG5vZGVUeXBlICE9PSA5ICYmIG5vZGVUeXBlICE9PSAxMSApIHtcblxuXHRcdHJldHVybiByZXN1bHRzO1xuXHR9XG5cblx0Ly8gVHJ5IHRvIHNob3J0Y3V0IGZpbmQgb3BlcmF0aW9ucyAoYXMgb3Bwb3NlZCB0byBmaWx0ZXJzKSBpbiBIVE1MIGRvY3VtZW50c1xuXHRpZiAoICFzZWVkICkge1xuXHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XG5cdFx0Y29udGV4dCA9IGNvbnRleHQgfHwgZG9jdW1lbnQ7XG5cblx0XHRpZiAoIGRvY3VtZW50SXNIVE1MICkge1xuXG5cdFx0XHQvLyBJZiB0aGUgc2VsZWN0b3IgaXMgc3VmZmljaWVudGx5IHNpbXBsZSwgdHJ5IHVzaW5nIGEgXCJnZXQqQnkqXCIgRE9NIG1ldGhvZFxuXHRcdFx0Ly8gKGV4Y2VwdGluZyBEb2N1bWVudEZyYWdtZW50IGNvbnRleHQsIHdoZXJlIHRoZSBtZXRob2RzIGRvbid0IGV4aXN0KVxuXHRcdFx0aWYgKCBub2RlVHlwZSAhPT0gMTEgJiYgKCBtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKSApICkge1xuXG5cdFx0XHRcdC8vIElEIHNlbGVjdG9yXG5cdFx0XHRcdGlmICggKCBtID0gbWF0Y2hbIDEgXSApICkge1xuXG5cdFx0XHRcdFx0Ly8gRG9jdW1lbnQgY29udGV4dFxuXHRcdFx0XHRcdGlmICggbm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSApICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFLCBPcGVyYSwgV2Via2l0XG5cdFx0XHRcdFx0XHRcdC8vIFRPRE86IGlkZW50aWZ5IHZlcnNpb25zXG5cdFx0XHRcdFx0XHRcdC8vIGdldEVsZW1lbnRCeUlkIGNhbiBtYXRjaCBlbGVtZW50cyBieSBuYW1lIGluc3RlYWQgb2YgSURcblx0XHRcdFx0XHRcdFx0aWYgKCBlbGVtLmlkID09PSBtICkge1xuXHRcdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIEVsZW1lbnQgY29udGV4dFxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFLCBPcGVyYSwgV2Via2l0XG5cdFx0XHRcdFx0XHQvLyBUT0RPOiBpZGVudGlmeSB2ZXJzaW9uc1xuXHRcdFx0XHRcdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgY2FuIG1hdGNoIGVsZW1lbnRzIGJ5IG5hbWUgaW5zdGVhZCBvZiBJRFxuXHRcdFx0XHRcdFx0aWYgKCBuZXdDb250ZXh0ICYmICggZWxlbSA9IG5ld0NvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSApICYmXG5cdFx0XHRcdFx0XHRcdGNvbnRhaW5zKCBjb250ZXh0LCBlbGVtICkgJiZcblx0XHRcdFx0XHRcdFx0ZWxlbS5pZCA9PT0gbSApIHtcblxuXHRcdFx0XHRcdFx0XHRyZXN1bHRzLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFR5cGUgc2VsZWN0b3Jcblx0XHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbIDIgXSApIHtcblx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCBzZWxlY3RvciApICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cblx0XHRcdFx0Ly8gQ2xhc3Mgc2VsZWN0b3Jcblx0XHRcdFx0fSBlbHNlIGlmICggKCBtID0gbWF0Y2hbIDMgXSApICYmIHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJlxuXHRcdFx0XHRcdGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApIHtcblxuXHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggbSApICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gVGFrZSBhZHZhbnRhZ2Ugb2YgcXVlcnlTZWxlY3RvckFsbFxuXHRcdFx0aWYgKCBzdXBwb3J0LnFzYSAmJlxuXHRcdFx0XHQhbm9ubmF0aXZlU2VsZWN0b3JDYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdICYmXG5cdFx0XHRcdCggIXJidWdneVFTQSB8fCAhcmJ1Z2d5UVNBLnRlc3QoIHNlbGVjdG9yICkgKSAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDggb25seVxuXHRcdFx0XHQvLyBFeGNsdWRlIG9iamVjdCBlbGVtZW50c1xuXHRcdFx0XHQoIG5vZGVUeXBlICE9PSAxIHx8IGNvbnRleHQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPT0gXCJvYmplY3RcIiApICkge1xuXG5cdFx0XHRcdG5ld1NlbGVjdG9yID0gc2VsZWN0b3I7XG5cdFx0XHRcdG5ld0NvbnRleHQgPSBjb250ZXh0O1xuXG5cdFx0XHRcdC8vIHFTQSBjb25zaWRlcnMgZWxlbWVudHMgb3V0c2lkZSBhIHNjb3Bpbmcgcm9vdCB3aGVuIGV2YWx1YXRpbmcgY2hpbGQgb3Jcblx0XHRcdFx0Ly8gZGVzY2VuZGFudCBjb21iaW5hdG9ycywgd2hpY2ggaXMgbm90IHdoYXQgd2Ugd2FudC5cblx0XHRcdFx0Ly8gSW4gc3VjaCBjYXNlcywgd2Ugd29yayBhcm91bmQgdGhlIGJlaGF2aW9yIGJ5IHByZWZpeGluZyBldmVyeSBzZWxlY3RvciBpbiB0aGVcblx0XHRcdFx0Ly8gbGlzdCB3aXRoIGFuIElEIHNlbGVjdG9yIHJlZmVyZW5jaW5nIHRoZSBzY29wZSBjb250ZXh0LlxuXHRcdFx0XHQvLyBUaGUgdGVjaG5pcXVlIGhhcyB0byBiZSB1c2VkIGFzIHdlbGwgd2hlbiBhIGxlYWRpbmcgY29tYmluYXRvciBpcyB1c2VkXG5cdFx0XHRcdC8vIGFzIHN1Y2ggc2VsZWN0b3JzIGFyZSBub3QgcmVjb2duaXplZCBieSBxdWVyeVNlbGVjdG9yQWxsLlxuXHRcdFx0XHQvLyBUaGFua3MgdG8gQW5kcmV3IER1cG9udCBmb3IgdGhpcyB0ZWNobmlxdWUuXG5cdFx0XHRcdGlmICggbm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0XHQoIHJkZXNjZW5kLnRlc3QoIHNlbGVjdG9yICkgfHwgcmNvbWJpbmF0b3JzLnRlc3QoIHNlbGVjdG9yICkgKSApIHtcblxuXHRcdFx0XHRcdC8vIEV4cGFuZCBjb250ZXh0IGZvciBzaWJsaW5nIHNlbGVjdG9yc1xuXHRcdFx0XHRcdG5ld0NvbnRleHQgPSByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fFxuXHRcdFx0XHRcdFx0Y29udGV4dDtcblxuXHRcdFx0XHRcdC8vIFdlIGNhbiB1c2UgOnNjb3BlIGluc3RlYWQgb2YgdGhlIElEIGhhY2sgaWYgdGhlIGJyb3dzZXJcblx0XHRcdFx0XHQvLyBzdXBwb3J0cyBpdCAmIGlmIHdlJ3JlIG5vdCBjaGFuZ2luZyB0aGUgY29udGV4dC5cblx0XHRcdFx0XHRpZiAoIG5ld0NvbnRleHQgIT09IGNvbnRleHQgfHwgIXN1cHBvcnQuc2NvcGUgKSB7XG5cblx0XHRcdFx0XHRcdC8vIENhcHR1cmUgdGhlIGNvbnRleHQgSUQsIHNldHRpbmcgaXQgZmlyc3QgaWYgbmVjZXNzYXJ5XG5cdFx0XHRcdFx0XHRpZiAoICggbmlkID0gY29udGV4dC5nZXRBdHRyaWJ1dGUoIFwiaWRcIiApICkgKSB7XG5cdFx0XHRcdFx0XHRcdG5pZCA9IG5pZC5yZXBsYWNlKCByY3NzZXNjYXBlLCBmY3NzZXNjYXBlICk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRjb250ZXh0LnNldEF0dHJpYnV0ZSggXCJpZFwiLCAoIG5pZCA9IGV4cGFuZG8gKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFByZWZpeCBldmVyeSBzZWxlY3RvciBpbiB0aGUgbGlzdFxuXHRcdFx0XHRcdGdyb3VwcyA9IHRva2VuaXplKCBzZWxlY3RvciApO1xuXHRcdFx0XHRcdGkgPSBncm91cHMubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0Z3JvdXBzWyBpIF0gPSAoIG5pZCA/IFwiI1wiICsgbmlkIDogXCI6c2NvcGVcIiApICsgXCIgXCIgK1xuXHRcdFx0XHRcdFx0XHR0b1NlbGVjdG9yKCBncm91cHNbIGkgXSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRuZXdTZWxlY3RvciA9IGdyb3Vwcy5qb2luKCBcIixcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLFxuXHRcdFx0XHRcdFx0bmV3Q29udGV4dC5xdWVyeVNlbGVjdG9yQWxsKCBuZXdTZWxlY3RvciApXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0fSBjYXRjaCAoIHFzYUVycm9yICkge1xuXHRcdFx0XHRcdG5vbm5hdGl2ZVNlbGVjdG9yQ2FjaGUoIHNlbGVjdG9yLCB0cnVlICk7XG5cdFx0XHRcdH0gZmluYWxseSB7XG5cdFx0XHRcdFx0aWYgKCBuaWQgPT09IGV4cGFuZG8gKSB7XG5cdFx0XHRcdFx0XHRjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZSggXCJpZFwiICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQWxsIG90aGVyc1xuXHRyZXR1cm4gc2VsZWN0KCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUga2V5LXZhbHVlIGNhY2hlcyBvZiBsaW1pdGVkIHNpemVcbiAqIEByZXR1cm5zIHtmdW5jdGlvbihzdHJpbmcsIG9iamVjdCl9IFJldHVybnMgdGhlIE9iamVjdCBkYXRhIGFmdGVyIHN0b3JpbmcgaXQgb24gaXRzZWxmIHdpdGhcbiAqXHRwcm9wZXJ0eSBuYW1lIHRoZSAoc3BhY2Utc3VmZml4ZWQpIHN0cmluZyBhbmQgKGlmIHRoZSBjYWNoZSBpcyBsYXJnZXIgdGhhbiBFeHByLmNhY2hlTGVuZ3RoKVxuICpcdGRlbGV0aW5nIHRoZSBvbGRlc3QgZW50cnlcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7XG5cdHZhciBrZXlzID0gW107XG5cblx0ZnVuY3Rpb24gY2FjaGUoIGtleSwgdmFsdWUgKSB7XG5cblx0XHQvLyBVc2UgKGtleSArIFwiIFwiKSB0byBhdm9pZCBjb2xsaXNpb24gd2l0aCBuYXRpdmUgcHJvdG90eXBlIHByb3BlcnRpZXMgKHNlZSBJc3N1ZSAjMTU3KVxuXHRcdGlmICgga2V5cy5wdXNoKCBrZXkgKyBcIiBcIiApID4gRXhwci5jYWNoZUxlbmd0aCApIHtcblxuXHRcdFx0Ly8gT25seSBrZWVwIHRoZSBtb3N0IHJlY2VudCBlbnRyaWVzXG5cdFx0XHRkZWxldGUgY2FjaGVbIGtleXMuc2hpZnQoKSBdO1xuXHRcdH1cblx0XHRyZXR1cm4gKCBjYWNoZVsga2V5ICsgXCIgXCIgXSA9IHZhbHVlICk7XG5cdH1cblx0cmV0dXJuIGNhY2hlO1xufVxuXG4vKipcbiAqIE1hcmsgYSBmdW5jdGlvbiBmb3Igc3BlY2lhbCB1c2UgYnkgU2l6emxlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBUaGUgZnVuY3Rpb24gdG8gbWFya1xuICovXG5mdW5jdGlvbiBtYXJrRnVuY3Rpb24oIGZuICkge1xuXHRmblsgZXhwYW5kbyBdID0gdHJ1ZTtcblx0cmV0dXJuIGZuO1xufVxuXG4vKipcbiAqIFN1cHBvcnQgdGVzdGluZyB1c2luZyBhbiBlbGVtZW50XG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmbiBQYXNzZWQgdGhlIGNyZWF0ZWQgZWxlbWVudCBhbmQgcmV0dXJucyBhIGJvb2xlYW4gcmVzdWx0XG4gKi9cbmZ1bmN0aW9uIGFzc2VydCggZm4gKSB7XG5cdHZhciBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZmllbGRzZXRcIiApO1xuXG5cdHRyeSB7XG5cdFx0cmV0dXJuICEhZm4oIGVsICk7XG5cdH0gY2F0Y2ggKCBlICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fSBmaW5hbGx5IHtcblxuXHRcdC8vIFJlbW92ZSBmcm9tIGl0cyBwYXJlbnQgYnkgZGVmYXVsdFxuXHRcdGlmICggZWwucGFyZW50Tm9kZSApIHtcblx0XHRcdGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGVsICk7XG5cdFx0fVxuXG5cdFx0Ly8gcmVsZWFzZSBtZW1vcnkgaW4gSUVcblx0XHRlbCA9IG51bGw7XG5cdH1cbn1cblxuLyoqXG4gKiBBZGRzIHRoZSBzYW1lIGhhbmRsZXIgZm9yIGFsbCBvZiB0aGUgc3BlY2lmaWVkIGF0dHJzXG4gKiBAcGFyYW0ge1N0cmluZ30gYXR0cnMgUGlwZS1zZXBhcmF0ZWQgbGlzdCBvZiBhdHRyaWJ1dGVzXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyIFRoZSBtZXRob2QgdGhhdCB3aWxsIGJlIGFwcGxpZWRcbiAqL1xuZnVuY3Rpb24gYWRkSGFuZGxlKCBhdHRycywgaGFuZGxlciApIHtcblx0dmFyIGFyciA9IGF0dHJzLnNwbGl0KCBcInxcIiApLFxuXHRcdGkgPSBhcnIubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdEV4cHIuYXR0ckhhbmRsZVsgYXJyWyBpIF0gXSA9IGhhbmRsZXI7XG5cdH1cbn1cblxuLyoqXG4gKiBDaGVja3MgZG9jdW1lbnQgb3JkZXIgb2YgdHdvIHNpYmxpbmdzXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGFcbiAqIEBwYXJhbSB7RWxlbWVudH0gYlxuICogQHJldHVybnMge051bWJlcn0gUmV0dXJucyBsZXNzIHRoYW4gMCBpZiBhIHByZWNlZGVzIGIsIGdyZWF0ZXIgdGhhbiAwIGlmIGEgZm9sbG93cyBiXG4gKi9cbmZ1bmN0aW9uIHNpYmxpbmdDaGVjayggYSwgYiApIHtcblx0dmFyIGN1ciA9IGIgJiYgYSxcblx0XHRkaWZmID0gY3VyICYmIGEubm9kZVR5cGUgPT09IDEgJiYgYi5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0YS5zb3VyY2VJbmRleCAtIGIuc291cmNlSW5kZXg7XG5cblx0Ly8gVXNlIElFIHNvdXJjZUluZGV4IGlmIGF2YWlsYWJsZSBvbiBib3RoIG5vZGVzXG5cdGlmICggZGlmZiApIHtcblx0XHRyZXR1cm4gZGlmZjtcblx0fVxuXG5cdC8vIENoZWNrIGlmIGIgZm9sbG93cyBhXG5cdGlmICggY3VyICkge1xuXHRcdHdoaWxlICggKCBjdXIgPSBjdXIubmV4dFNpYmxpbmcgKSApIHtcblx0XHRcdGlmICggY3VyID09PSBiICkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGEgPyAxIDogLTE7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBpbnB1dCB0eXBlc1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlSW5wdXRQc2V1ZG8oIHR5cGUgKSB7XG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRyZXR1cm4gbmFtZSA9PT0gXCJpbnB1dFwiICYmIGVsZW0udHlwZSA9PT0gdHlwZTtcblx0fTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIGJ1dHRvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJ1dHRvblBzZXVkbyggdHlwZSApIHtcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdHJldHVybiAoIG5hbWUgPT09IFwiaW5wdXRcIiB8fCBuYW1lID09PSBcImJ1dHRvblwiICkgJiYgZWxlbS50eXBlID09PSB0eXBlO1xuXHR9O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgOmVuYWJsZWQvOmRpc2FibGVkXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGRpc2FibGVkIHRydWUgZm9yIDpkaXNhYmxlZDsgZmFsc2UgZm9yIDplbmFibGVkXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZURpc2FibGVkUHNldWRvKCBkaXNhYmxlZCApIHtcblxuXHQvLyBLbm93biA6ZGlzYWJsZWQgZmFsc2UgcG9zaXRpdmVzOiBmaWVsZHNldFtkaXNhYmxlZF0gPiBsZWdlbmQ6bnRoLW9mLXR5cGUobisyKSA6Y2FuLWRpc2FibGVcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gT25seSBjZXJ0YWluIGVsZW1lbnRzIGNhbiBtYXRjaCA6ZW5hYmxlZCBvciA6ZGlzYWJsZWRcblx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zY3JpcHRpbmcuaHRtbCNzZWxlY3Rvci1lbmFibGVkXG5cdFx0Ly8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvc2NyaXB0aW5nLmh0bWwjc2VsZWN0b3ItZGlzYWJsZWRcblx0XHRpZiAoIFwiZm9ybVwiIGluIGVsZW0gKSB7XG5cblx0XHRcdC8vIENoZWNrIGZvciBpbmhlcml0ZWQgZGlzYWJsZWRuZXNzIG9uIHJlbGV2YW50IG5vbi1kaXNhYmxlZCBlbGVtZW50czpcblx0XHRcdC8vICogbGlzdGVkIGZvcm0tYXNzb2NpYXRlZCBlbGVtZW50cyBpbiBhIGRpc2FibGVkIGZpZWxkc2V0XG5cdFx0XHQvLyAgIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Zvcm1zLmh0bWwjY2F0ZWdvcnktbGlzdGVkXG5cdFx0XHQvLyAgIGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Zvcm1zLmh0bWwjY29uY2VwdC1mZS1kaXNhYmxlZFxuXHRcdFx0Ly8gKiBvcHRpb24gZWxlbWVudHMgaW4gYSBkaXNhYmxlZCBvcHRncm91cFxuXHRcdFx0Ly8gICBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9mb3Jtcy5odG1sI2NvbmNlcHQtb3B0aW9uLWRpc2FibGVkXG5cdFx0XHQvLyBBbGwgc3VjaCBlbGVtZW50cyBoYXZlIGEgXCJmb3JtXCIgcHJvcGVydHkuXG5cdFx0XHRpZiAoIGVsZW0ucGFyZW50Tm9kZSAmJiBlbGVtLmRpc2FibGVkID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHQvLyBPcHRpb24gZWxlbWVudHMgZGVmZXIgdG8gYSBwYXJlbnQgb3B0Z3JvdXAgaWYgcHJlc2VudFxuXHRcdFx0XHRpZiAoIFwibGFiZWxcIiBpbiBlbGVtICkge1xuXHRcdFx0XHRcdGlmICggXCJsYWJlbFwiIGluIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtLnBhcmVudE5vZGUuZGlzYWJsZWQgPT09IGRpc2FibGVkO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgNiAtIDExXG5cdFx0XHRcdC8vIFVzZSB0aGUgaXNEaXNhYmxlZCBzaG9ydGN1dCBwcm9wZXJ0eSB0byBjaGVjayBmb3IgZGlzYWJsZWQgZmllbGRzZXQgYW5jZXN0b3JzXG5cdFx0XHRcdHJldHVybiBlbGVtLmlzRGlzYWJsZWQgPT09IGRpc2FibGVkIHx8XG5cblx0XHRcdFx0XHQvLyBXaGVyZSB0aGVyZSBpcyBubyBpc0Rpc2FibGVkLCBjaGVjayBtYW51YWxseVxuXHRcdFx0XHRcdC8qIGpzaGludCAtVzAxOCAqL1xuXHRcdFx0XHRcdGVsZW0uaXNEaXNhYmxlZCAhPT0gIWRpc2FibGVkICYmXG5cdFx0XHRcdFx0aW5EaXNhYmxlZEZpZWxkc2V0KCBlbGVtICkgPT09IGRpc2FibGVkO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cblx0XHQvLyBUcnkgdG8gd2lubm93IG91dCBlbGVtZW50cyB0aGF0IGNhbid0IGJlIGRpc2FibGVkIGJlZm9yZSB0cnVzdGluZyB0aGUgZGlzYWJsZWQgcHJvcGVydHkuXG5cdFx0Ly8gU29tZSB2aWN0aW1zIGdldCBjYXVnaHQgaW4gb3VyIG5ldCAobGFiZWwsIGxlZ2VuZCwgbWVudSwgdHJhY2spLCBidXQgaXQgc2hvdWxkbid0XG5cdFx0Ly8gZXZlbiBleGlzdCBvbiB0aGVtLCBsZXQgYWxvbmUgaGF2ZSBhIGJvb2xlYW4gdmFsdWUuXG5cdFx0fSBlbHNlIGlmICggXCJsYWJlbFwiIGluIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kaXNhYmxlZCA9PT0gZGlzYWJsZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gUmVtYWluaW5nIGVsZW1lbnRzIGFyZSBuZWl0aGVyIDplbmFibGVkIG5vciA6ZGlzYWJsZWRcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH07XG59XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRvIHVzZSBpbiBwc2V1ZG9zIGZvciBwb3NpdGlvbmFsc1xuICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZm4gKSB7XG5cdHJldHVybiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBhcmd1bWVudCApIHtcblx0XHRhcmd1bWVudCA9ICthcmd1bWVudDtcblx0XHRyZXR1cm4gbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcblx0XHRcdHZhciBqLFxuXHRcdFx0XHRtYXRjaEluZGV4ZXMgPSBmbiggW10sIHNlZWQubGVuZ3RoLCBhcmd1bWVudCApLFxuXHRcdFx0XHRpID0gbWF0Y2hJbmRleGVzLmxlbmd0aDtcblxuXHRcdFx0Ly8gTWF0Y2ggZWxlbWVudHMgZm91bmQgYXQgdGhlIHNwZWNpZmllZCBpbmRleGVzXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCBzZWVkWyAoIGogPSBtYXRjaEluZGV4ZXNbIGkgXSApIF0gKSB7XG5cdFx0XHRcdFx0c2VlZFsgaiBdID0gISggbWF0Y2hlc1sgaiBdID0gc2VlZFsgaiBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9ICk7XG5cdH0gKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgYSBub2RlIGZvciB2YWxpZGl0eSBhcyBhIFNpenpsZSBjb250ZXh0XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0PX0gY29udGV4dFxuICogQHJldHVybnMge0VsZW1lbnR8T2JqZWN0fEJvb2xlYW59IFRoZSBpbnB1dCBub2RlIGlmIGFjY2VwdGFibGUsIG90aGVyd2lzZSBhIGZhbHN5IHZhbHVlXG4gKi9cbmZ1bmN0aW9uIHRlc3RDb250ZXh0KCBjb250ZXh0ICkge1xuXHRyZXR1cm4gY29udGV4dCAmJiB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjb250ZXh0O1xufVxuXG4vLyBFeHBvc2Ugc3VwcG9ydCB2YXJzIGZvciBjb252ZW5pZW5jZVxuc3VwcG9ydCA9IFNpenpsZS5zdXBwb3J0ID0ge307XG5cbi8qKlxuICogRGV0ZWN0cyBYTUwgbm9kZXNcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IGVsZW0gQW4gZWxlbWVudCBvciBhIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZmYgZWxlbSBpcyBhIG5vbi1IVE1MIFhNTCBub2RlXG4gKi9cbmlzWE1MID0gU2l6emxlLmlzWE1MID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciBuYW1lc3BhY2UgPSBlbGVtLm5hbWVzcGFjZVVSSSxcblx0XHRkb2NFbGVtID0gKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApLmRvY3VtZW50RWxlbWVudDtcblxuXHQvLyBTdXBwb3J0OiBJRSA8PThcblx0Ly8gQXNzdW1lIEhUTUwgd2hlbiBkb2N1bWVudEVsZW1lbnQgZG9lc24ndCB5ZXQgZXhpc3QsIHN1Y2ggYXMgaW5zaWRlIGxvYWRpbmcgaWZyYW1lc1xuXHQvLyBodHRwczovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvNDgzM1xuXHRyZXR1cm4gIXJodG1sLnRlc3QoIG5hbWVzcGFjZSB8fCBkb2NFbGVtICYmIGRvY0VsZW0ubm9kZU5hbWUgfHwgXCJIVE1MXCIgKTtcbn07XG5cbi8qKlxuICogU2V0cyBkb2N1bWVudC1yZWxhdGVkIHZhcmlhYmxlcyBvbmNlIGJhc2VkIG9uIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0fSBbZG9jXSBBbiBlbGVtZW50IG9yIGRvY3VtZW50IG9iamVjdCB0byB1c2UgdG8gc2V0IHRoZSBkb2N1bWVudFxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY3VycmVudCBkb2N1bWVudFxuICovXG5zZXREb2N1bWVudCA9IFNpenpsZS5zZXREb2N1bWVudCA9IGZ1bmN0aW9uKCBub2RlICkge1xuXHR2YXIgaGFzQ29tcGFyZSwgc3ViV2luZG93LFxuXHRcdGRvYyA9IG5vZGUgPyBub2RlLm93bmVyRG9jdW1lbnQgfHwgbm9kZSA6IHByZWZlcnJlZERvYztcblxuXHQvLyBSZXR1cm4gZWFybHkgaWYgZG9jIGlzIGludmFsaWQgb3IgYWxyZWFkeSBzZWxlY3RlZFxuXHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRpZiAoIGRvYyA9PSBkb2N1bWVudCB8fCBkb2Mubm9kZVR5cGUgIT09IDkgfHwgIWRvYy5kb2N1bWVudEVsZW1lbnQgKSB7XG5cdFx0cmV0dXJuIGRvY3VtZW50O1xuXHR9XG5cblx0Ly8gVXBkYXRlIGdsb2JhbCB2YXJpYWJsZXNcblx0ZG9jdW1lbnQgPSBkb2M7XG5cdGRvY0VsZW0gPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG5cdGRvY3VtZW50SXNIVE1MID0gIWlzWE1MKCBkb2N1bWVudCApO1xuXG5cdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSssIEVkZ2UgMTIgLSAxOCtcblx0Ly8gQWNjZXNzaW5nIGlmcmFtZSBkb2N1bWVudHMgYWZ0ZXIgdW5sb2FkIHRocm93cyBcInBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3JzIChqUXVlcnkgIzEzOTM2KVxuXHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRpZiAoIHByZWZlcnJlZERvYyAhPSBkb2N1bWVudCAmJlxuXHRcdCggc3ViV2luZG93ID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcgKSAmJiBzdWJXaW5kb3cudG9wICE9PSBzdWJXaW5kb3cgKSB7XG5cblx0XHQvLyBTdXBwb3J0OiBJRSAxMSwgRWRnZVxuXHRcdGlmICggc3ViV2luZG93LmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRzdWJXaW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggXCJ1bmxvYWRcIiwgdW5sb2FkSGFuZGxlciwgZmFsc2UgKTtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgLSAxMCBvbmx5XG5cdFx0fSBlbHNlIGlmICggc3ViV2luZG93LmF0dGFjaEV2ZW50ICkge1xuXHRcdFx0c3ViV2luZG93LmF0dGFjaEV2ZW50KCBcIm9udW5sb2FkXCIsIHVubG9hZEhhbmRsZXIgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBTdXBwb3J0OiBJRSA4IC0gMTErLCBFZGdlIDEyIC0gMTgrLCBDaHJvbWUgPD0xNiAtIDI1IG9ubHksIEZpcmVmb3ggPD0zLjYgLSAzMSBvbmx5LFxuXHQvLyBTYWZhcmkgNCAtIDUgb25seSwgT3BlcmEgPD0xMS42IC0gMTIueCBvbmx5XG5cdC8vIElFL0VkZ2UgJiBvbGRlciBicm93c2VycyBkb24ndCBzdXBwb3J0IHRoZSA6c2NvcGUgcHNldWRvLWNsYXNzLlxuXHQvLyBTdXBwb3J0OiBTYWZhcmkgNi4wIG9ubHlcblx0Ly8gU2FmYXJpIDYuMCBzdXBwb3J0cyA6c2NvcGUgYnV0IGl0J3MgYW4gYWxpYXMgb2YgOnJvb3QgdGhlcmUuXG5cdHN1cHBvcnQuc2NvcGUgPSBhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBlbCApLmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkgKTtcblx0XHRyZXR1cm4gdHlwZW9mIGVsLnF1ZXJ5U2VsZWN0b3JBbGwgIT09IFwidW5kZWZpbmVkXCIgJiZcblx0XHRcdCFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIjpzY29wZSBmaWVsZHNldCBkaXZcIiApLmxlbmd0aDtcblx0fSApO1xuXG5cdC8qIEF0dHJpYnV0ZXNcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIFN1cHBvcnQ6IElFPDhcblx0Ly8gVmVyaWZ5IHRoYXQgZ2V0QXR0cmlidXRlIHJlYWxseSByZXR1cm5zIGF0dHJpYnV0ZXMgYW5kIG5vdCBwcm9wZXJ0aWVzXG5cdC8vIChleGNlcHRpbmcgSUU4IGJvb2xlYW5zKVxuXHRzdXBwb3J0LmF0dHJpYnV0ZXMgPSBhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0XHRlbC5jbGFzc05hbWUgPSBcImlcIjtcblx0XHRyZXR1cm4gIWVsLmdldEF0dHJpYnV0ZSggXCJjbGFzc05hbWVcIiApO1xuXHR9ICk7XG5cblx0LyogZ2V0RWxlbWVudChzKUJ5KlxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCIqXCIpIHJldHVybnMgb25seSBlbGVtZW50c1xuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlUYWdOYW1lID0gYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdFx0ZWwuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUNvbW1lbnQoIFwiXCIgKSApO1xuXHRcdHJldHVybiAhZWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwiKlwiICkubGVuZ3RoO1xuXHR9ICk7XG5cblx0Ly8gU3VwcG9ydDogSUU8OVxuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgPSBybmF0aXZlLnRlc3QoIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKTtcblxuXHQvLyBTdXBwb3J0OiBJRTwxMFxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50QnlJZCByZXR1cm5zIGVsZW1lbnRzIGJ5IG5hbWVcblx0Ly8gVGhlIGJyb2tlbiBnZXRFbGVtZW50QnlJZCBtZXRob2RzIGRvbid0IHBpY2sgdXAgcHJvZ3JhbW1hdGljYWxseS1zZXQgbmFtZXMsXG5cdC8vIHNvIHVzZSBhIHJvdW5kYWJvdXQgZ2V0RWxlbWVudHNCeU5hbWUgdGVzdFxuXHRzdXBwb3J0LmdldEJ5SWQgPSBhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBlbCApLmlkID0gZXhwYW5kbztcblx0XHRyZXR1cm4gIWRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lIHx8ICFkb2N1bWVudC5nZXRFbGVtZW50c0J5TmFtZSggZXhwYW5kbyApLmxlbmd0aDtcblx0fSApO1xuXG5cdC8vIElEIGZpbHRlciBhbmQgZmluZFxuXHRpZiAoIHN1cHBvcnQuZ2V0QnlJZCApIHtcblx0XHRFeHByLmZpbHRlclsgXCJJRFwiIF0gPSBmdW5jdGlvbiggaWQgKSB7XG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCBcImlkXCIgKSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXHRcdEV4cHIuZmluZFsgXCJJRFwiIF0gPSBmdW5jdGlvbiggaWQsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSBcInVuZGVmaW5lZFwiICYmIGRvY3VtZW50SXNIVE1MICkge1xuXHRcdFx0XHR2YXIgZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIGlkICk7XG5cdFx0XHRcdHJldHVybiBlbGVtID8gWyBlbGVtIF0gOiBbXTtcblx0XHRcdH1cblx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdEV4cHIuZmlsdGVyWyBcIklEXCIgXSA9ICBmdW5jdGlvbiggaWQgKSB7XG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIG5vZGUgPSB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGVOb2RlICE9PSBcInVuZGVmaW5lZFwiICYmXG5cdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBcImlkXCIgKTtcblx0XHRcdFx0cmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgNiAtIDcgb25seVxuXHRcdC8vIGdldEVsZW1lbnRCeUlkIGlzIG5vdCByZWxpYWJsZSBhcyBhIGZpbmQgc2hvcnRjdXRcblx0XHRFeHByLmZpbmRbIFwiSURcIiBdID0gZnVuY3Rpb24oIGlkLCBjb250ZXh0ICkge1xuXHRcdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50QnlJZCAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudElzSFRNTCApIHtcblx0XHRcdFx0dmFyIG5vZGUsIGksIGVsZW1zLFxuXHRcdFx0XHRcdGVsZW0gPSBjb250ZXh0LmdldEVsZW1lbnRCeUlkKCBpZCApO1xuXG5cdFx0XHRcdGlmICggZWxlbSApIHtcblxuXHRcdFx0XHRcdC8vIFZlcmlmeSB0aGUgaWQgYXR0cmlidXRlXG5cdFx0XHRcdFx0bm9kZSA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggXCJpZFwiICk7XG5cdFx0XHRcdFx0aWYgKCBub2RlICYmIG5vZGUudmFsdWUgPT09IGlkICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIFsgZWxlbSBdO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIEZhbGwgYmFjayBvbiBnZXRFbGVtZW50c0J5TmFtZVxuXHRcdFx0XHRcdGVsZW1zID0gY29udGV4dC5nZXRFbGVtZW50c0J5TmFtZSggaWQgKTtcblx0XHRcdFx0XHRpID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoICggZWxlbSA9IGVsZW1zWyBpKysgXSApICkge1xuXHRcdFx0XHRcdFx0bm9kZSA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggXCJpZFwiICk7XG5cdFx0XHRcdFx0XHRpZiAoIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gaWQgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBbIGVsZW0gXTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gW107XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxuXG5cdC8vIFRhZ1xuXHRFeHByLmZpbmRbIFwiVEFHXCIgXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgP1xuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdC8vIERvY3VtZW50RnJhZ21lbnQgbm9kZXMgZG9uJ3QgaGF2ZSBnRUJUTlxuXHRcdFx0fSBlbHNlIGlmICggc3VwcG9ydC5xc2EgKSB7XG5cdFx0XHRcdHJldHVybiBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIHRhZyApO1xuXHRcdFx0fVxuXHRcdH0gOlxuXG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdHZhciBlbGVtLFxuXHRcdFx0XHR0bXAgPSBbXSxcblx0XHRcdFx0aSA9IDAsXG5cblx0XHRcdFx0Ly8gQnkgaGFwcHkgY29pbmNpZGVuY2UsIGEgKGJyb2tlbikgZ0VCVE4gYXBwZWFycyBvbiBEb2N1bWVudEZyYWdtZW50IG5vZGVzIHRvb1xuXHRcdFx0XHRyZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdC8vIEZpbHRlciBvdXQgcG9zc2libGUgY29tbWVudHNcblx0XHRcdGlmICggdGFnID09PSBcIipcIiApIHtcblx0XHRcdFx0d2hpbGUgKCAoIGVsZW0gPSByZXN1bHRzWyBpKysgXSApICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdHRtcC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHRtcDtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdH07XG5cblx0Ly8gQ2xhc3Ncblx0RXhwci5maW5kWyBcIkNMQVNTXCIgXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAmJiBmdW5jdGlvbiggY2xhc3NOYW1lLCBjb250ZXh0ICkge1xuXHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBkb2N1bWVudElzSFRNTCApIHtcblx0XHRcdHJldHVybiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoIGNsYXNzTmFtZSApO1xuXHRcdH1cblx0fTtcblxuXHQvKiBRU0EvbWF0Y2hlc1NlbGVjdG9yXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBRU0EgYW5kIG1hdGNoZXNTZWxlY3RvciBzdXBwb3J0XG5cblx0Ly8gbWF0Y2hlc1NlbGVjdG9yKDphY3RpdmUpIHJlcG9ydHMgZmFsc2Ugd2hlbiB0cnVlIChJRTkvT3BlcmEgMTEuNSlcblx0cmJ1Z2d5TWF0Y2hlcyA9IFtdO1xuXG5cdC8vIHFTYSg6Zm9jdXMpIHJlcG9ydHMgZmFsc2Ugd2hlbiB0cnVlIChDaHJvbWUgMjEpXG5cdC8vIFdlIGFsbG93IHRoaXMgYmVjYXVzZSBvZiBhIGJ1ZyBpbiBJRTgvOSB0aGF0IHRocm93cyBhbiBlcnJvclxuXHQvLyB3aGVuZXZlciBgZG9jdW1lbnQuYWN0aXZlRWxlbWVudGAgaXMgYWNjZXNzZWQgb24gYW4gaWZyYW1lXG5cdC8vIFNvLCB3ZSBhbGxvdyA6Zm9jdXMgdG8gcGFzcyB0aHJvdWdoIFFTQSBhbGwgdGhlIHRpbWUgdG8gYXZvaWQgdGhlIElFIGVycm9yXG5cdC8vIFNlZSBodHRwczovL2J1Z3MuanF1ZXJ5LmNvbS90aWNrZXQvMTMzNzhcblx0cmJ1Z2d5UVNBID0gW107XG5cblx0aWYgKCAoIHN1cHBvcnQucXNhID0gcm5hdGl2ZS50ZXN0KCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsICkgKSApIHtcblxuXHRcdC8vIEJ1aWxkIFFTQSByZWdleFxuXHRcdC8vIFJlZ2V4IHN0cmF0ZWd5IGFkb3B0ZWQgZnJvbSBEaWVnbyBQZXJpbmlcblx0XHRhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblxuXHRcdFx0dmFyIGlucHV0O1xuXG5cdFx0XHQvLyBTZWxlY3QgaXMgc2V0IHRvIGVtcHR5IHN0cmluZyBvbiBwdXJwb3NlXG5cdFx0XHQvLyBUaGlzIGlzIHRvIHRlc3QgSUUncyB0cmVhdG1lbnQgb2Ygbm90IGV4cGxpY2l0bHlcblx0XHRcdC8vIHNldHRpbmcgYSBib29sZWFuIGNvbnRlbnQgYXR0cmlidXRlLFxuXHRcdFx0Ly8gc2luY2UgaXRzIHByZXNlbmNlIHNob3VsZCBiZSBlbm91Z2hcblx0XHRcdC8vIGh0dHBzOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC8xMjM1OVxuXHRcdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggZWwgKS5pbm5lckhUTUwgPSBcIjxhIGlkPSdcIiArIGV4cGFuZG8gKyBcIic+PC9hPlwiICtcblx0XHRcdFx0XCI8c2VsZWN0IGlkPSdcIiArIGV4cGFuZG8gKyBcIi1cXHJcXFxcJyBtc2FsbG93Y2FwdHVyZT0nJz5cIiArXG5cdFx0XHRcdFwiPG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD5cIjtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4LCBPcGVyYSAxMS0xMi4xNlxuXHRcdFx0Ly8gTm90aGluZyBzaG91bGQgYmUgc2VsZWN0ZWQgd2hlbiBlbXB0eSBzdHJpbmdzIGZvbGxvdyBePSBvciAkPSBvciAqPVxuXHRcdFx0Ly8gVGhlIHRlc3QgYXR0cmlidXRlIG11c3QgYmUgdW5rbm93biBpbiBPcGVyYSBidXQgXCJzYWZlXCIgZm9yIFdpblJUXG5cdFx0XHQvLyBodHRwczovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2hoNDY1Mzg4LmFzcHgjYXR0cmlidXRlX3NlY3Rpb25cblx0XHRcdGlmICggZWwucXVlcnlTZWxlY3RvckFsbCggXCJbbXNhbGxvd2NhcHR1cmVePScnXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJbKl4kXT1cIiArIHdoaXRlc3BhY2UgKyBcIiooPzonJ3xcXFwiXFxcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcblx0XHRcdC8vIEJvb2xlYW4gYXR0cmlidXRlcyBhbmQgXCJ2YWx1ZVwiIGFyZSBub3QgdHJlYXRlZCBjb3JyZWN0bHlcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiW3NlbGVjdGVkXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKig/OnZhbHVlfFwiICsgYm9vbGVhbnMgKyBcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWU8MjksIEFuZHJvaWQ8NC40LCBTYWZhcmk8Ny4wKywgaU9TPDcuMCssIFBoYW50b21KUzwxLjkuOCtcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiW2lkfj1cIiArIGV4cGFuZG8gKyBcIi1dXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIn49XCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE1IC0gMTgrXG5cdFx0XHQvLyBJRSAxMS9FZGdlIGRvbid0IGZpbmQgZWxlbWVudHMgb24gYSBgW25hbWU9JyddYCBxdWVyeSBpbiBzb21lIGNhc2VzLlxuXHRcdFx0Ly8gQWRkaW5nIGEgdGVtcG9yYXJ5IGF0dHJpYnV0ZSB0byB0aGUgZG9jdW1lbnQgYmVmb3JlIHRoZSBzZWxlY3Rpb24gd29ya3Ncblx0XHRcdC8vIGFyb3VuZCB0aGUgaXNzdWUuXG5cdFx0XHQvLyBJbnRlcmVzdGluZ2x5LCBJRSAxMCAmIG9sZGVyIGRvbid0IHNlZW0gdG8gaGF2ZSB0aGUgaXNzdWUuXG5cdFx0XHRpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApO1xuXHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJcIiApO1xuXHRcdFx0ZWwuYXBwZW5kQ2hpbGQoIGlucHV0ICk7XG5cdFx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIltuYW1lPScnXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKm5hbWVcIiArIHdoaXRlc3BhY2UgKyBcIio9XCIgK1xuXHRcdFx0XHRcdHdoaXRlc3BhY2UgKyBcIiooPzonJ3xcXFwiXFxcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBXZWJraXQvT3BlcmEgLSA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIHNlbGVjdGVkIG9wdGlvbiBlbGVtZW50c1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAxMS9SRUMtY3NzMy1zZWxlY3RvcnMtMjAxMTA5MjkvI2NoZWNrZWRcblx0XHRcdC8vIElFOCB0aHJvd3MgZXJyb3IgaGVyZSBhbmQgd2lsbCBub3Qgc2VlIGxhdGVyIHRlc3RzXG5cdFx0XHRpZiAoICFlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIjpjaGVja2VkXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIjpjaGVja2VkXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogU2FmYXJpIDgrLCBpT1MgOCtcblx0XHRcdC8vIGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xMzY4NTFcblx0XHRcdC8vIEluLXBhZ2UgYHNlbGVjdG9yI2lkIHNpYmxpbmctY29tYmluYXRvciBzZWxlY3RvcmAgZmFpbHNcblx0XHRcdGlmICggIWVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiYSNcIiArIGV4cGFuZG8gKyBcIisqXCIgKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIi4jLitbK35dXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA8PTMuNiAtIDUgb25seVxuXHRcdFx0Ly8gT2xkIEZpcmVmb3ggZG9lc24ndCB0aHJvdyBvbiBhIGJhZGx5LWVzY2FwZWQgaWRlbnRpZmllci5cblx0XHRcdGVsLnF1ZXJ5U2VsZWN0b3JBbGwoIFwiXFxcXFxcZlwiICk7XG5cdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJbXFxcXHJcXFxcblxcXFxmXVwiICk7XG5cdFx0fSApO1xuXG5cdFx0YXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdFx0XHRlbC5pbm5lckhUTUwgPSBcIjxhIGhyZWY9JycgZGlzYWJsZWQ9J2Rpc2FibGVkJz48L2E+XCIgK1xuXHRcdFx0XHRcIjxzZWxlY3QgZGlzYWJsZWQ9J2Rpc2FibGVkJz48b3B0aW9uLz48L3NlbGVjdD5cIjtcblxuXHRcdFx0Ly8gU3VwcG9ydDogV2luZG93cyA4IE5hdGl2ZSBBcHBzXG5cdFx0XHQvLyBUaGUgdHlwZSBhbmQgbmFtZSBhdHRyaWJ1dGVzIGFyZSByZXN0cmljdGVkIGR1cmluZyAuaW5uZXJIVE1MIGFzc2lnbm1lbnRcblx0XHRcdHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApO1xuXHRcdFx0aW5wdXQuc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgXCJoaWRkZW5cIiApO1xuXHRcdFx0ZWwuYXBwZW5kQ2hpbGQoIGlucHV0ICkuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJEXCIgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4XG5cdFx0XHQvLyBFbmZvcmNlIGNhc2Utc2Vuc2l0aXZpdHkgb2YgbmFtZSBhdHRyaWJ1dGVcblx0XHRcdGlmICggZWwucXVlcnlTZWxlY3RvckFsbCggXCJbbmFtZT1kXVwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJuYW1lXCIgKyB3aGl0ZXNwYWNlICsgXCIqWypeJHwhfl0/PVwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZGIDMuNSAtIDplbmFibGVkLzpkaXNhYmxlZCBhbmQgaGlkZGVuIGVsZW1lbnRzIChoaWRkZW4gZWxlbWVudHMgYXJlIHN0aWxsIGVuYWJsZWQpXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xuXHRcdFx0aWYgKCBlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIjplbmFibGVkXCIgKS5sZW5ndGggIT09IDIgKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIjplbmFibGVkXCIsIFwiOmRpc2FibGVkXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU5LTExK1xuXHRcdFx0Ly8gSUUncyA6ZGlzYWJsZWQgc2VsZWN0b3IgZG9lcyBub3QgcGljayB1cCB0aGUgY2hpbGRyZW4gb2YgZGlzYWJsZWQgZmllbGRzZXRzXG5cdFx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBlbCApLmRpc2FibGVkID0gdHJ1ZTtcblx0XHRcdGlmICggZWwucXVlcnlTZWxlY3RvckFsbCggXCI6ZGlzYWJsZWRcIiApLmxlbmd0aCAhPT0gMiApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiOmVuYWJsZWRcIiwgXCI6ZGlzYWJsZWRcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBPcGVyYSAxMCAtIDExIG9ubHlcblx0XHRcdC8vIE9wZXJhIDEwLTExIGRvZXMgbm90IHRocm93IG9uIHBvc3QtY29tbWEgaW52YWxpZCBwc2V1ZG9zXG5cdFx0XHRlbC5xdWVyeVNlbGVjdG9yQWxsKCBcIiosOnhcIiApO1xuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiLC4qOlwiICk7XG5cdFx0fSApO1xuXHR9XG5cblx0aWYgKCAoIHN1cHBvcnQubWF0Y2hlc1NlbGVjdG9yID0gcm5hdGl2ZS50ZXN0KCAoIG1hdGNoZXMgPSBkb2NFbGVtLm1hdGNoZXMgfHxcblx0XHRkb2NFbGVtLndlYmtpdE1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ubW96TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5vTWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5tc01hdGNoZXNTZWxlY3RvciApICkgKSApIHtcblxuXHRcdGFzc2VydCggZnVuY3Rpb24oIGVsICkge1xuXG5cdFx0XHQvLyBDaGVjayB0byBzZWUgaWYgaXQncyBwb3NzaWJsZSB0byBkbyBtYXRjaGVzU2VsZWN0b3Jcblx0XHRcdC8vIG9uIGEgZGlzY29ubmVjdGVkIG5vZGUgKElFIDkpXG5cdFx0XHRzdXBwb3J0LmRpc2Nvbm5lY3RlZE1hdGNoID0gbWF0Y2hlcy5jYWxsKCBlbCwgXCIqXCIgKTtcblxuXHRcdFx0Ly8gVGhpcyBzaG91bGQgZmFpbCB3aXRoIGFuIGV4Y2VwdGlvblxuXHRcdFx0Ly8gR2Vja28gZG9lcyBub3QgZXJyb3IsIHJldHVybnMgZmFsc2UgaW5zdGVhZFxuXHRcdFx0bWF0Y2hlcy5jYWxsKCBlbCwgXCJbcyE9JyddOnhcIiApO1xuXHRcdFx0cmJ1Z2d5TWF0Y2hlcy5wdXNoKCBcIiE9XCIsIHBzZXVkb3MgKTtcblx0XHR9ICk7XG5cdH1cblxuXHRyYnVnZ3lRU0EgPSByYnVnZ3lRU0EubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneVFTQS5qb2luKCBcInxcIiApICk7XG5cdHJidWdneU1hdGNoZXMgPSByYnVnZ3lNYXRjaGVzLmxlbmd0aCAmJiBuZXcgUmVnRXhwKCByYnVnZ3lNYXRjaGVzLmpvaW4oIFwifFwiICkgKTtcblxuXHQvKiBDb250YWluc1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cdGhhc0NvbXBhcmUgPSBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29tcGFyZURvY3VtZW50UG9zaXRpb24gKTtcblxuXHQvLyBFbGVtZW50IGNvbnRhaW5zIGFub3RoZXJcblx0Ly8gUHVycG9zZWZ1bGx5IHNlbGYtZXhjbHVzaXZlXG5cdC8vIEFzIGluLCBhbiBlbGVtZW50IGRvZXMgbm90IGNvbnRhaW4gaXRzZWxmXG5cdGNvbnRhaW5zID0gaGFzQ29tcGFyZSB8fCBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29udGFpbnMgKSA/XG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0XHR2YXIgYWRvd24gPSBhLm5vZGVUeXBlID09PSA5ID8gYS5kb2N1bWVudEVsZW1lbnQgOiBhLFxuXHRcdFx0XHRidXAgPSBiICYmIGIucGFyZW50Tm9kZTtcblx0XHRcdHJldHVybiBhID09PSBidXAgfHwgISEoIGJ1cCAmJiBidXAubm9kZVR5cGUgPT09IDEgJiYgKFxuXHRcdFx0XHRhZG93bi5jb250YWlucyA/XG5cdFx0XHRcdFx0YWRvd24uY29udGFpbnMoIGJ1cCApIDpcblx0XHRcdFx0XHRhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uICYmIGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGJ1cCApICYgMTZcblx0XHRcdCkgKTtcblx0XHR9IDpcblx0XHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdGlmICggYiApIHtcblx0XHRcdFx0d2hpbGUgKCAoIGIgPSBiLnBhcmVudE5vZGUgKSApIHtcblx0XHRcdFx0XHRpZiAoIGIgPT09IGEgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9O1xuXG5cdC8qIFNvcnRpbmdcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIERvY3VtZW50IG9yZGVyIHNvcnRpbmdcblx0c29ydE9yZGVyID0gaGFzQ29tcGFyZSA/XG5cdGZ1bmN0aW9uKCBhLCBiICkge1xuXG5cdFx0Ly8gRmxhZyBmb3IgZHVwbGljYXRlIHJlbW92YWxcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0Ly8gU29ydCBvbiBtZXRob2QgZXhpc3RlbmNlIGlmIG9ubHkgb25lIGlucHV0IGhhcyBjb21wYXJlRG9jdW1lbnRQb3NpdGlvblxuXHRcdHZhciBjb21wYXJlID0gIWEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gLSAhYi5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbjtcblx0XHRpZiAoIGNvbXBhcmUgKSB7XG5cdFx0XHRyZXR1cm4gY29tcGFyZTtcblx0XHR9XG5cblx0XHQvLyBDYWxjdWxhdGUgcG9zaXRpb24gaWYgYm90aCBpbnB1dHMgYmVsb25nIHRvIHRoZSBzYW1lIGRvY3VtZW50XG5cdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRjb21wYXJlID0gKCBhLm93bmVyRG9jdW1lbnQgfHwgYSApID09ICggYi5vd25lckRvY3VtZW50IHx8IGIgKSA/XG5cdFx0XHRhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBiICkgOlxuXG5cdFx0XHQvLyBPdGhlcndpc2Ugd2Uga25vdyB0aGV5IGFyZSBkaXNjb25uZWN0ZWRcblx0XHRcdDE7XG5cblx0XHQvLyBEaXNjb25uZWN0ZWQgbm9kZXNcblx0XHRpZiAoIGNvbXBhcmUgJiAxIHx8XG5cdFx0XHQoICFzdXBwb3J0LnNvcnREZXRhY2hlZCAmJiBiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBhICkgPT09IGNvbXBhcmUgKSApIHtcblxuXHRcdFx0Ly8gQ2hvb3NlIHRoZSBmaXJzdCBlbGVtZW50IHRoYXQgaXMgcmVsYXRlZCB0byBvdXIgcHJlZmVycmVkIGRvY3VtZW50XG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0aWYgKCBhID09IGRvY3VtZW50IHx8IGEub3duZXJEb2N1bWVudCA9PSBwcmVmZXJyZWREb2MgJiZcblx0XHRcdFx0Y29udGFpbnMoIHByZWZlcnJlZERvYywgYSApICkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExKywgRWRnZSAxNyAtIDE4K1xuXHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgZXFlcWVxXG5cdFx0XHRpZiAoIGIgPT0gZG9jdW1lbnQgfHwgYi5vd25lckRvY3VtZW50ID09IHByZWZlcnJlZERvYyAmJlxuXHRcdFx0XHRjb250YWlucyggcHJlZmVycmVkRG9jLCBiICkgKSB7XG5cdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBNYWludGFpbiBvcmlnaW5hbCBvcmRlclxuXHRcdFx0cmV0dXJuIHNvcnRJbnB1dCA/XG5cdFx0XHRcdCggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDpcblx0XHRcdFx0MDtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29tcGFyZSAmIDQgPyAtMSA6IDE7XG5cdH0gOlxuXHRmdW5jdGlvbiggYSwgYiApIHtcblxuXHRcdC8vIEV4aXQgZWFybHkgaWYgdGhlIG5vZGVzIGFyZSBpZGVudGljYWxcblx0XHRpZiAoIGEgPT09IGIgKSB7XG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0dmFyIGN1cixcblx0XHRcdGkgPSAwLFxuXHRcdFx0YXVwID0gYS5wYXJlbnROb2RlLFxuXHRcdFx0YnVwID0gYi5wYXJlbnROb2RlLFxuXHRcdFx0YXAgPSBbIGEgXSxcblx0XHRcdGJwID0gWyBiIF07XG5cblx0XHQvLyBQYXJlbnRsZXNzIG5vZGVzIGFyZSBlaXRoZXIgZG9jdW1lbnRzIG9yIGRpc2Nvbm5lY3RlZFxuXHRcdGlmICggIWF1cCB8fCAhYnVwICkge1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0LyogZXNsaW50LWRpc2FibGUgZXFlcWVxICovXG5cdFx0XHRyZXR1cm4gYSA9PSBkb2N1bWVudCA/IC0xIDpcblx0XHRcdFx0YiA9PSBkb2N1bWVudCA/IDEgOlxuXHRcdFx0XHQvKiBlc2xpbnQtZW5hYmxlIGVxZXFlcSAqL1xuXHRcdFx0XHRhdXAgPyAtMSA6XG5cdFx0XHRcdGJ1cCA/IDEgOlxuXHRcdFx0XHRzb3J0SW5wdXQgP1xuXHRcdFx0XHQoIGluZGV4T2YoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZiggc29ydElucHV0LCBiICkgKSA6XG5cdFx0XHRcdDA7XG5cblx0XHQvLyBJZiB0aGUgbm9kZXMgYXJlIHNpYmxpbmdzLCB3ZSBjYW4gZG8gYSBxdWljayBjaGVja1xuXHRcdH0gZWxzZSBpZiAoIGF1cCA9PT0gYnVwICkge1xuXHRcdFx0cmV0dXJuIHNpYmxpbmdDaGVjayggYSwgYiApO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyd2lzZSB3ZSBuZWVkIGZ1bGwgbGlzdHMgb2YgdGhlaXIgYW5jZXN0b3JzIGZvciBjb21wYXJpc29uXG5cdFx0Y3VyID0gYTtcblx0XHR3aGlsZSAoICggY3VyID0gY3VyLnBhcmVudE5vZGUgKSApIHtcblx0XHRcdGFwLnVuc2hpZnQoIGN1ciApO1xuXHRcdH1cblx0XHRjdXIgPSBiO1xuXHRcdHdoaWxlICggKCBjdXIgPSBjdXIucGFyZW50Tm9kZSApICkge1xuXHRcdFx0YnAudW5zaGlmdCggY3VyICk7XG5cdFx0fVxuXG5cdFx0Ly8gV2FsayBkb3duIHRoZSB0cmVlIGxvb2tpbmcgZm9yIGEgZGlzY3JlcGFuY3lcblx0XHR3aGlsZSAoIGFwWyBpIF0gPT09IGJwWyBpIF0gKSB7XG5cdFx0XHRpKys7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGkgP1xuXG5cdFx0XHQvLyBEbyBhIHNpYmxpbmcgY2hlY2sgaWYgdGhlIG5vZGVzIGhhdmUgYSBjb21tb24gYW5jZXN0b3Jcblx0XHRcdHNpYmxpbmdDaGVjayggYXBbIGkgXSwgYnBbIGkgXSApIDpcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIG5vZGVzIGluIG91ciBkb2N1bWVudCBzb3J0IGZpcnN0XG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0LyogZXNsaW50LWRpc2FibGUgZXFlcWVxICovXG5cdFx0XHRhcFsgaSBdID09IHByZWZlcnJlZERvYyA/IC0xIDpcblx0XHRcdGJwWyBpIF0gPT0gcHJlZmVycmVkRG9jID8gMSA6XG5cdFx0XHQvKiBlc2xpbnQtZW5hYmxlIGVxZXFlcSAqL1xuXHRcdFx0MDtcblx0fTtcblxuXHRyZXR1cm4gZG9jdW1lbnQ7XG59O1xuXG5TaXp6bGUubWF0Y2hlcyA9IGZ1bmN0aW9uKCBleHByLCBlbGVtZW50cyApIHtcblx0cmV0dXJuIFNpenpsZSggZXhwciwgbnVsbCwgbnVsbCwgZWxlbWVudHMgKTtcbn07XG5cblNpenpsZS5tYXRjaGVzU2VsZWN0b3IgPSBmdW5jdGlvbiggZWxlbSwgZXhwciApIHtcblx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblxuXHRpZiAoIHN1cHBvcnQubWF0Y2hlc1NlbGVjdG9yICYmIGRvY3VtZW50SXNIVE1MICYmXG5cdFx0IW5vbm5hdGl2ZVNlbGVjdG9yQ2FjaGVbIGV4cHIgKyBcIiBcIiBdICYmXG5cdFx0KCAhcmJ1Z2d5TWF0Y2hlcyB8fCAhcmJ1Z2d5TWF0Y2hlcy50ZXN0KCBleHByICkgKSAmJlxuXHRcdCggIXJidWdneVFTQSAgICAgfHwgIXJidWdneVFTQS50ZXN0KCBleHByICkgKSApIHtcblxuXHRcdHRyeSB7XG5cdFx0XHR2YXIgcmV0ID0gbWF0Y2hlcy5jYWxsKCBlbGVtLCBleHByICk7XG5cblx0XHRcdC8vIElFIDkncyBtYXRjaGVzU2VsZWN0b3IgcmV0dXJucyBmYWxzZSBvbiBkaXNjb25uZWN0ZWQgbm9kZXNcblx0XHRcdGlmICggcmV0IHx8IHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggfHxcblxuXHRcdFx0XHQvLyBBcyB3ZWxsLCBkaXNjb25uZWN0ZWQgbm9kZXMgYXJlIHNhaWQgdG8gYmUgaW4gYSBkb2N1bWVudFxuXHRcdFx0XHQvLyBmcmFnbWVudCBpbiBJRSA5XG5cdFx0XHRcdGVsZW0uZG9jdW1lbnQgJiYgZWxlbS5kb2N1bWVudC5ub2RlVHlwZSAhPT0gMTEgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRub25uYXRpdmVTZWxlY3RvckNhY2hlKCBleHByLCB0cnVlICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIFNpenpsZSggZXhwciwgZG9jdW1lbnQsIG51bGwsIFsgZWxlbSBdICkubGVuZ3RoID4gMDtcbn07XG5cblNpenpsZS5jb250YWlucyA9IGZ1bmN0aW9uKCBjb250ZXh0LCBlbGVtICkge1xuXG5cdC8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZFxuXHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRpZiAoICggY29udGV4dC5vd25lckRvY3VtZW50IHx8IGNvbnRleHQgKSAhPSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHR9XG5cdHJldHVybiBjb250YWlucyggY29udGV4dCwgZWxlbSApO1xufTtcblxuU2l6emxlLmF0dHIgPSBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblxuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdC8vIElFL0VkZ2Ugc29tZXRpbWVzIHRocm93IGEgXCJQZXJtaXNzaW9uIGRlbmllZFwiIGVycm9yIHdoZW4gc3RyaWN0LWNvbXBhcmluZ1xuXHQvLyB0d28gZG9jdW1lbnRzOyBzaGFsbG93IGNvbXBhcmlzb25zIHdvcmsuXG5cdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT0gZG9jdW1lbnQgKSB7XG5cdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcblx0fVxuXG5cdHZhciBmbiA9IEV4cHIuYXR0ckhhbmRsZVsgbmFtZS50b0xvd2VyQ2FzZSgpIF0sXG5cblx0XHQvLyBEb24ndCBnZXQgZm9vbGVkIGJ5IE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoalF1ZXJ5ICMxMzgwNylcblx0XHR2YWwgPSBmbiAmJiBoYXNPd24uY2FsbCggRXhwci5hdHRySGFuZGxlLCBuYW1lLnRvTG93ZXJDYXNlKCkgKSA/XG5cdFx0XHRmbiggZWxlbSwgbmFtZSwgIWRvY3VtZW50SXNIVE1MICkgOlxuXHRcdFx0dW5kZWZpbmVkO1xuXG5cdHJldHVybiB2YWwgIT09IHVuZGVmaW5lZCA/XG5cdFx0dmFsIDpcblx0XHRzdXBwb3J0LmF0dHJpYnV0ZXMgfHwgIWRvY3VtZW50SXNIVE1MID9cblx0XHRcdGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lICkgOlxuXHRcdFx0KCB2YWwgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIG5hbWUgKSApICYmIHZhbC5zcGVjaWZpZWQgP1xuXHRcdFx0XHR2YWwudmFsdWUgOlxuXHRcdFx0XHRudWxsO1xufTtcblxuU2l6emxlLmVzY2FwZSA9IGZ1bmN0aW9uKCBzZWwgKSB7XG5cdHJldHVybiAoIHNlbCArIFwiXCIgKS5yZXBsYWNlKCByY3NzZXNjYXBlLCBmY3NzZXNjYXBlICk7XG59O1xuXG5TaXp6bGUuZXJyb3IgPSBmdW5jdGlvbiggbXNnICkge1xuXHR0aHJvdyBuZXcgRXJyb3IoIFwiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogXCIgKyBtc2cgKTtcbn07XG5cbi8qKlxuICogRG9jdW1lbnQgc29ydGluZyBhbmQgcmVtb3ZpbmcgZHVwbGljYXRlc1xuICogQHBhcmFtIHtBcnJheUxpa2V9IHJlc3VsdHNcbiAqL1xuU2l6emxlLnVuaXF1ZVNvcnQgPSBmdW5jdGlvbiggcmVzdWx0cyApIHtcblx0dmFyIGVsZW0sXG5cdFx0ZHVwbGljYXRlcyA9IFtdLFxuXHRcdGogPSAwLFxuXHRcdGkgPSAwO1xuXG5cdC8vIFVubGVzcyB3ZSAqa25vdyogd2UgY2FuIGRldGVjdCBkdXBsaWNhdGVzLCBhc3N1bWUgdGhlaXIgcHJlc2VuY2Vcblx0aGFzRHVwbGljYXRlID0gIXN1cHBvcnQuZGV0ZWN0RHVwbGljYXRlcztcblx0c29ydElucHV0ID0gIXN1cHBvcnQuc29ydFN0YWJsZSAmJiByZXN1bHRzLnNsaWNlKCAwICk7XG5cdHJlc3VsdHMuc29ydCggc29ydE9yZGVyICk7XG5cblx0aWYgKCBoYXNEdXBsaWNhdGUgKSB7XG5cdFx0d2hpbGUgKCAoIGVsZW0gPSByZXN1bHRzWyBpKysgXSApICkge1xuXHRcdFx0aWYgKCBlbGVtID09PSByZXN1bHRzWyBpIF0gKSB7XG5cdFx0XHRcdGogPSBkdXBsaWNhdGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRyZXN1bHRzLnNwbGljZSggZHVwbGljYXRlc1sgaiBdLCAxICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2xlYXIgaW5wdXQgYWZ0ZXIgc29ydGluZyB0byByZWxlYXNlIG9iamVjdHNcblx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvc2l6emxlL3B1bGwvMjI1XG5cdHNvcnRJbnB1dCA9IG51bGw7XG5cblx0cmV0dXJuIHJlc3VsdHM7XG59O1xuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gZm9yIHJldHJpZXZpbmcgdGhlIHRleHQgdmFsdWUgb2YgYW4gYXJyYXkgb2YgRE9NIG5vZGVzXG4gKiBAcGFyYW0ge0FycmF5fEVsZW1lbnR9IGVsZW1cbiAqL1xuZ2V0VGV4dCA9IFNpenpsZS5nZXRUZXh0ID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciBub2RlLFxuXHRcdHJldCA9IFwiXCIsXG5cdFx0aSA9IDAsXG5cdFx0bm9kZVR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdGlmICggIW5vZGVUeXBlICkge1xuXG5cdFx0Ly8gSWYgbm8gbm9kZVR5cGUsIHRoaXMgaXMgZXhwZWN0ZWQgdG8gYmUgYW4gYXJyYXlcblx0XHR3aGlsZSAoICggbm9kZSA9IGVsZW1bIGkrKyBdICkgKSB7XG5cblx0XHRcdC8vIERvIG5vdCB0cmF2ZXJzZSBjb21tZW50IG5vZGVzXG5cdFx0XHRyZXQgKz0gZ2V0VGV4dCggbm9kZSApO1xuXHRcdH1cblx0fSBlbHNlIGlmICggbm9kZVR5cGUgPT09IDEgfHwgbm9kZVR5cGUgPT09IDkgfHwgbm9kZVR5cGUgPT09IDExICkge1xuXG5cdFx0Ly8gVXNlIHRleHRDb250ZW50IGZvciBlbGVtZW50c1xuXHRcdC8vIGlubmVyVGV4dCB1c2FnZSByZW1vdmVkIGZvciBjb25zaXN0ZW5jeSBvZiBuZXcgbGluZXMgKGpRdWVyeSAjMTExNTMpXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS50ZXh0Q29udGVudCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBlbGVtLnRleHRDb250ZW50O1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIFRyYXZlcnNlIGl0cyBjaGlsZHJlblxuXHRcdFx0Zm9yICggZWxlbSA9IGVsZW0uZmlyc3RDaGlsZDsgZWxlbTsgZWxlbSA9IGVsZW0ubmV4dFNpYmxpbmcgKSB7XG5cdFx0XHRcdHJldCArPSBnZXRUZXh0KCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9IGVsc2UgaWYgKCBub2RlVHlwZSA9PT0gMyB8fCBub2RlVHlwZSA9PT0gNCApIHtcblx0XHRyZXR1cm4gZWxlbS5ub2RlVmFsdWU7XG5cdH1cblxuXHQvLyBEbyBub3QgaW5jbHVkZSBjb21tZW50IG9yIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZXNcblxuXHRyZXR1cm4gcmV0O1xufTtcblxuRXhwciA9IFNpenpsZS5zZWxlY3RvcnMgPSB7XG5cblx0Ly8gQ2FuIGJlIGFkanVzdGVkIGJ5IHRoZSB1c2VyXG5cdGNhY2hlTGVuZ3RoOiA1MCxcblxuXHRjcmVhdGVQc2V1ZG86IG1hcmtGdW5jdGlvbixcblxuXHRtYXRjaDogbWF0Y2hFeHByLFxuXG5cdGF0dHJIYW5kbGU6IHt9LFxuXG5cdGZpbmQ6IHt9LFxuXG5cdHJlbGF0aXZlOiB7XG5cdFx0XCI+XCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiwgZmlyc3Q6IHRydWUgfSxcblx0XHRcIiBcIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiIH0sXG5cdFx0XCIrXCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiLCBmaXJzdDogdHJ1ZSB9LFxuXHRcdFwiflwiOiB7IGRpcjogXCJwcmV2aW91c1NpYmxpbmdcIiB9XG5cdH0sXG5cblx0cHJlRmlsdGVyOiB7XG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdG1hdGNoWyAxIF0gPSBtYXRjaFsgMSBdLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cblx0XHRcdC8vIE1vdmUgdGhlIGdpdmVuIHZhbHVlIHRvIG1hdGNoWzNdIHdoZXRoZXIgcXVvdGVkIG9yIHVucXVvdGVkXG5cdFx0XHRtYXRjaFsgMyBdID0gKCBtYXRjaFsgMyBdIHx8IG1hdGNoWyA0IF0gfHxcblx0XHRcdFx0bWF0Y2hbIDUgXSB8fCBcIlwiICkucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsgMiBdID09PSBcIn49XCIgKSB7XG5cdFx0XHRcdG1hdGNoWyAzIF0gPSBcIiBcIiArIG1hdGNoWyAzIF0gKyBcIiBcIjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXG5cdFx0XHQvKiBtYXRjaGVzIGZyb20gbWF0Y2hFeHByW1wiQ0hJTERcIl1cblx0XHRcdFx0MSB0eXBlIChvbmx5fG50aHwuLi4pXG5cdFx0XHRcdDIgd2hhdCAoY2hpbGR8b2YtdHlwZSlcblx0XHRcdFx0MyBhcmd1bWVudCAoZXZlbnxvZGR8XFxkKnxcXGQqbihbKy1dXFxkKyk/fC4uLilcblx0XHRcdFx0NCB4bi1jb21wb25lbnQgb2YgeG4reSBhcmd1bWVudCAoWystXT9cXGQqbnwpXG5cdFx0XHRcdDUgc2lnbiBvZiB4bi1jb21wb25lbnRcblx0XHRcdFx0NiB4IG9mIHhuLWNvbXBvbmVudFxuXHRcdFx0XHQ3IHNpZ24gb2YgeS1jb21wb25lbnRcblx0XHRcdFx0OCB5IG9mIHktY29tcG9uZW50XG5cdFx0XHQqL1xuXHRcdFx0bWF0Y2hbIDEgXSA9IG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsgMSBdLnNsaWNlKCAwLCAzICkgPT09IFwibnRoXCIgKSB7XG5cblx0XHRcdFx0Ly8gbnRoLSogcmVxdWlyZXMgYXJndW1lbnRcblx0XHRcdFx0aWYgKCAhbWF0Y2hbIDMgXSApIHtcblx0XHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWyAwIF0gKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIG51bWVyaWMgeCBhbmQgeSBwYXJhbWV0ZXJzIGZvciBFeHByLmZpbHRlci5DSElMRFxuXHRcdFx0XHQvLyByZW1lbWJlciB0aGF0IGZhbHNlL3RydWUgY2FzdCByZXNwZWN0aXZlbHkgdG8gMC8xXG5cdFx0XHRcdG1hdGNoWyA0IF0gPSArKCBtYXRjaFsgNCBdID9cblx0XHRcdFx0XHRtYXRjaFsgNSBdICsgKCBtYXRjaFsgNiBdIHx8IDEgKSA6XG5cdFx0XHRcdFx0MiAqICggbWF0Y2hbIDMgXSA9PT0gXCJldmVuXCIgfHwgbWF0Y2hbIDMgXSA9PT0gXCJvZGRcIiApICk7XG5cdFx0XHRcdG1hdGNoWyA1IF0gPSArKCAoIG1hdGNoWyA3IF0gKyBtYXRjaFsgOCBdICkgfHwgbWF0Y2hbIDMgXSA9PT0gXCJvZGRcIiApO1xuXG5cdFx0XHRcdC8vIG90aGVyIHR5cGVzIHByb2hpYml0IGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbIDMgXSApIHtcblx0XHRcdFx0U2l6emxlLmVycm9yKCBtYXRjaFsgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBtYXRjaDtcblx0XHR9LFxuXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0dmFyIGV4Y2Vzcyxcblx0XHRcdFx0dW5xdW90ZWQgPSAhbWF0Y2hbIDYgXSAmJiBtYXRjaFsgMiBdO1xuXG5cdFx0XHRpZiAoIG1hdGNoRXhwclsgXCJDSElMRFwiIF0udGVzdCggbWF0Y2hbIDAgXSApICkge1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWNjZXB0IHF1b3RlZCBhcmd1bWVudHMgYXMtaXNcblx0XHRcdGlmICggbWF0Y2hbIDMgXSApIHtcblx0XHRcdFx0bWF0Y2hbIDIgXSA9IG1hdGNoWyA0IF0gfHwgbWF0Y2hbIDUgXSB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTdHJpcCBleGNlc3MgY2hhcmFjdGVycyBmcm9tIHVucXVvdGVkIGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggdW5xdW90ZWQgJiYgcnBzZXVkby50ZXN0KCB1bnF1b3RlZCApICYmXG5cblx0XHRcdFx0Ly8gR2V0IGV4Y2VzcyBmcm9tIHRva2VuaXplIChyZWN1cnNpdmVseSlcblx0XHRcdFx0KCBleGNlc3MgPSB0b2tlbml6ZSggdW5xdW90ZWQsIHRydWUgKSApICYmXG5cblx0XHRcdFx0Ly8gYWR2YW5jZSB0byB0aGUgbmV4dCBjbG9zaW5nIHBhcmVudGhlc2lzXG5cdFx0XHRcdCggZXhjZXNzID0gdW5xdW90ZWQuaW5kZXhPZiggXCIpXCIsIHVucXVvdGVkLmxlbmd0aCAtIGV4Y2VzcyApIC0gdW5xdW90ZWQubGVuZ3RoICkgKSB7XG5cblx0XHRcdFx0Ly8gZXhjZXNzIGlzIGEgbmVnYXRpdmUgaW5kZXhcblx0XHRcdFx0bWF0Y2hbIDAgXSA9IG1hdGNoWyAwIF0uc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0XHRtYXRjaFsgMiBdID0gdW5xdW90ZWQuc2xpY2UoIDAsIGV4Y2VzcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXR1cm4gb25seSBjYXB0dXJlcyBuZWVkZWQgYnkgdGhlIHBzZXVkbyBmaWx0ZXIgbWV0aG9kICh0eXBlIGFuZCBhcmd1bWVudClcblx0XHRcdHJldHVybiBtYXRjaC5zbGljZSggMCwgMyApO1xuXHRcdH1cblx0fSxcblxuXHRmaWx0ZXI6IHtcblxuXHRcdFwiVEFHXCI6IGZ1bmN0aW9uKCBub2RlTmFtZVNlbGVjdG9yICkge1xuXHRcdFx0dmFyIG5vZGVOYW1lID0gbm9kZU5hbWVTZWxlY3Rvci5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gbm9kZU5hbWVTZWxlY3RvciA9PT0gXCIqXCIgP1xuXHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbm9kZU5hbWU7XG5cdFx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiQ0xBU1NcIjogZnVuY3Rpb24oIGNsYXNzTmFtZSApIHtcblx0XHRcdHZhciBwYXR0ZXJuID0gY2xhc3NDYWNoZVsgY2xhc3NOYW1lICsgXCIgXCIgXTtcblxuXHRcdFx0cmV0dXJuIHBhdHRlcm4gfHxcblx0XHRcdFx0KCBwYXR0ZXJuID0gbmV3IFJlZ0V4cCggXCIoXnxcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFx0XHRcdFwiKVwiICsgY2xhc3NOYW1lICsgXCIoXCIgKyB3aGl0ZXNwYWNlICsgXCJ8JClcIiApICkgJiYgY2xhc3NDYWNoZShcblx0XHRcdFx0XHRcdGNsYXNzTmFtZSwgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBwYXR0ZXJuLnRlc3QoXG5cdFx0XHRcdFx0XHRcdFx0dHlwZW9mIGVsZW0uY2xhc3NOYW1lID09PSBcInN0cmluZ1wiICYmIGVsZW0uY2xhc3NOYW1lIHx8XG5cdFx0XHRcdFx0XHRcdFx0dHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlICE9PSBcInVuZGVmaW5lZFwiICYmXG5cdFx0XHRcdFx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHxcblx0XHRcdFx0XHRcdFx0XHRcIlwiXG5cdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdH0gKTtcblx0XHR9LFxuXG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBuYW1lLCBvcGVyYXRvciwgY2hlY2sgKSB7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciByZXN1bHQgPSBTaXp6bGUuYXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0XHRcdGlmICggcmVzdWx0ID09IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIiE9XCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0aWYgKCAhb3BlcmF0b3IgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXN1bHQgKz0gXCJcIjtcblxuXHRcdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBtYXgtbGVuICovXG5cblx0XHRcdFx0cmV0dXJuIG9wZXJhdG9yID09PSBcIj1cIiA/IHJlc3VsdCA9PT0gY2hlY2sgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIiE9XCIgPyByZXN1bHQgIT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJePVwiID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPT09IDAgOlxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcIio9XCIgPyBjaGVjayAmJiByZXN1bHQuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIkPVwiID8gY2hlY2sgJiYgcmVzdWx0LnNsaWNlKCAtY2hlY2subGVuZ3RoICkgPT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ+PVwiID8gKCBcIiBcIiArIHJlc3VsdC5yZXBsYWNlKCByd2hpdGVzcGFjZSwgXCIgXCIgKSArIFwiIFwiICkuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ8PVwiID8gcmVzdWx0ID09PSBjaGVjayB8fCByZXN1bHQuc2xpY2UoIDAsIGNoZWNrLmxlbmd0aCArIDEgKSA9PT0gY2hlY2sgKyBcIi1cIiA6XG5cdFx0XHRcdFx0ZmFsc2U7XG5cdFx0XHRcdC8qIGVzbGludC1lbmFibGUgbWF4LWxlbiAqL1xuXG5cdFx0XHR9O1xuXHRcdH0sXG5cblx0XHRcIkNISUxEXCI6IGZ1bmN0aW9uKCB0eXBlLCB3aGF0LCBfYXJndW1lbnQsIGZpcnN0LCBsYXN0ICkge1xuXHRcdFx0dmFyIHNpbXBsZSA9IHR5cGUuc2xpY2UoIDAsIDMgKSAhPT0gXCJudGhcIixcblx0XHRcdFx0Zm9yd2FyZCA9IHR5cGUuc2xpY2UoIC00ICkgIT09IFwibGFzdFwiLFxuXHRcdFx0XHRvZlR5cGUgPSB3aGF0ID09PSBcIm9mLXR5cGVcIjtcblxuXHRcdFx0cmV0dXJuIGZpcnN0ID09PSAxICYmIGxhc3QgPT09IDAgP1xuXG5cdFx0XHRcdC8vIFNob3J0Y3V0IGZvciA6bnRoLSoobilcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuICEhZWxlbS5wYXJlbnROb2RlO1xuXHRcdFx0XHR9IDpcblxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSwgX2NvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHR2YXIgY2FjaGUsIHVuaXF1ZUNhY2hlLCBvdXRlckNhY2hlLCBub2RlLCBub2RlSW5kZXgsIHN0YXJ0LFxuXHRcdFx0XHRcdFx0ZGlyID0gc2ltcGxlICE9PSBmb3J3YXJkID8gXCJuZXh0U2libGluZ1wiIDogXCJwcmV2aW91c1NpYmxpbmdcIixcblx0XHRcdFx0XHRcdHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZSxcblx0XHRcdFx0XHRcdG5hbWUgPSBvZlR5cGUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLFxuXHRcdFx0XHRcdFx0dXNlQ2FjaGUgPSAheG1sICYmICFvZlR5cGUsXG5cdFx0XHRcdFx0XHRkaWZmID0gZmFsc2U7XG5cblx0XHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblxuXHRcdFx0XHRcdFx0Ly8gOihmaXJzdHxsYXN0fG9ubHkpLShjaGlsZHxvZi10eXBlKVxuXHRcdFx0XHRcdFx0aWYgKCBzaW1wbGUgKSB7XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggZGlyICkge1xuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xuXHRcdFx0XHRcdFx0XHRcdHdoaWxlICggKCBub2RlID0gbm9kZVsgZGlyIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggb2ZUeXBlID9cblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBuYW1lIDpcblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gUmV2ZXJzZSBkaXJlY3Rpb24gZm9yIDpvbmx5LSogKGlmIHdlIGhhdmVuJ3QgeWV0IGRvbmUgc28pXG5cdFx0XHRcdFx0XHRcdFx0c3RhcnQgPSBkaXIgPSB0eXBlID09PSBcIm9ubHlcIiAmJiAhc3RhcnQgJiYgXCJuZXh0U2libGluZ1wiO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRzdGFydCA9IFsgZm9yd2FyZCA/IHBhcmVudC5maXJzdENoaWxkIDogcGFyZW50Lmxhc3RDaGlsZCBdO1xuXG5cdFx0XHRcdFx0XHQvLyBub24teG1sIDpudGgtY2hpbGQoLi4uKSBzdG9yZXMgY2FjaGUgZGF0YSBvbiBgcGFyZW50YFxuXHRcdFx0XHRcdFx0aWYgKCBmb3J3YXJkICYmIHVzZUNhY2hlICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFNlZWsgYGVsZW1gIGZyb20gYSBwcmV2aW91c2x5LWNhY2hlZCBpbmRleFxuXG5cdFx0XHRcdFx0XHRcdC8vIC4uLmluIGEgZ3ppcC1mcmllbmRseSB3YXlcblx0XHRcdFx0XHRcdFx0bm9kZSA9IHBhcmVudDtcblx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IG5vZGVbIGV4cGFuZG8gXSB8fCAoIG5vZGVbIGV4cGFuZG8gXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPDkgb25seVxuXHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcblx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGUgPSBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gfHxcblx0XHRcdFx0XHRcdFx0XHQoIG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdFx0Y2FjaGUgPSB1bmlxdWVDYWNoZVsgdHlwZSBdIHx8IFtdO1xuXHRcdFx0XHRcdFx0XHRub2RlSW5kZXggPSBjYWNoZVsgMCBdID09PSBkaXJydW5zICYmIGNhY2hlWyAxIF07XG5cdFx0XHRcdFx0XHRcdGRpZmYgPSBub2RlSW5kZXggJiYgY2FjaGVbIDIgXTtcblx0XHRcdFx0XHRcdFx0bm9kZSA9IG5vZGVJbmRleCAmJiBwYXJlbnQuY2hpbGROb2Rlc1sgbm9kZUluZGV4IF07XG5cblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBGYWxsYmFjayB0byBzZWVraW5nIGBlbGVtYCBmcm9tIHRoZSBzdGFydFxuXHRcdFx0XHRcdFx0XHRcdCggZGlmZiA9IG5vZGVJbmRleCA9IDAgKSB8fCBzdGFydC5wb3AoKSApICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gV2hlbiBmb3VuZCwgY2FjaGUgaW5kZXhlcyBvbiBgcGFyZW50YCBhbmQgYnJlYWtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgKytkaWZmICYmIG5vZGUgPT09IGVsZW0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZVsgdHlwZSBdID0gWyBkaXJydW5zLCBub2RlSW5kZXgsIGRpZmYgXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFVzZSBwcmV2aW91c2x5LWNhY2hlZCBlbGVtZW50IGluZGV4IGlmIGF2YWlsYWJsZVxuXHRcdFx0XHRcdFx0XHRpZiAoIHVzZUNhY2hlICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gLi4uaW4gYSBnemlwLWZyaWVuZGx5IHdheVxuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xuXHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHwgKCBub2RlWyBleHBhbmRvIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPDkgb25seVxuXHRcdFx0XHRcdFx0XHRcdC8vIERlZmVuZCBhZ2FpbnN0IGNsb25lZCBhdHRyb3BlcnRpZXMgKGpRdWVyeSBnaC0xNzA5KVxuXHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0XHQoIG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdFx0XHRjYWNoZSA9IHVuaXF1ZUNhY2hlWyB0eXBlIF0gfHwgW107XG5cdFx0XHRcdFx0XHRcdFx0bm9kZUluZGV4ID0gY2FjaGVbIDAgXSA9PT0gZGlycnVucyAmJiBjYWNoZVsgMSBdO1xuXHRcdFx0XHRcdFx0XHRcdGRpZmYgPSBub2RlSW5kZXg7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHQvLyB4bWwgOm50aC1jaGlsZCguLi4pXG5cdFx0XHRcdFx0XHRcdC8vIG9yIDpudGgtbGFzdC1jaGlsZCguLi4pIG9yIDpudGgoLWxhc3QpPy1vZi10eXBlKC4uLilcblx0XHRcdFx0XHRcdFx0aWYgKCBkaWZmID09PSBmYWxzZSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIFVzZSB0aGUgc2FtZSBsb29wIGFzIGFib3ZlIHRvIHNlZWsgYGVsZW1gIGZyb20gdGhlIHN0YXJ0XG5cdFx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0XHQoIGRpZmYgPSBub2RlSW5kZXggPSAwICkgfHwgc3RhcnQucG9wKCkgKSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCAoIG9mVHlwZSA/XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6XG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZVR5cGUgPT09IDEgKSAmJlxuXHRcdFx0XHRcdFx0XHRcdFx0XHQrK2RpZmYgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gQ2FjaGUgdGhlIGluZGV4IG9mIGVhY2ggZW5jb3VudGVyZWQgZWxlbWVudFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIHVzZUNhY2hlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdCggbm9kZVsgZXhwYW5kbyBdID0ge30gKTtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0KCBvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGVbIHR5cGUgXSA9IFsgZGlycnVucywgZGlmZiBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBub2RlID09PSBlbGVtICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIEluY29ycG9yYXRlIHRoZSBvZmZzZXQsIHRoZW4gY2hlY2sgYWdhaW5zdCBjeWNsZSBzaXplXG5cdFx0XHRcdFx0XHRkaWZmIC09IGxhc3Q7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZGlmZiA9PT0gZmlyc3QgfHwgKCBkaWZmICUgZmlyc3QgPT09IDAgJiYgZGlmZiAvIGZpcnN0ID49IDAgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiUFNFVURPXCI6IGZ1bmN0aW9uKCBwc2V1ZG8sIGFyZ3VtZW50ICkge1xuXG5cdFx0XHQvLyBwc2V1ZG8tY2xhc3MgbmFtZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmVcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jcHNldWRvLWNsYXNzZXNcblx0XHRcdC8vIFByaW9yaXRpemUgYnkgY2FzZSBzZW5zaXRpdml0eSBpbiBjYXNlIGN1c3RvbSBwc2V1ZG9zIGFyZSBhZGRlZCB3aXRoIHVwcGVyY2FzZSBsZXR0ZXJzXG5cdFx0XHQvLyBSZW1lbWJlciB0aGF0IHNldEZpbHRlcnMgaW5oZXJpdHMgZnJvbSBwc2V1ZG9zXG5cdFx0XHR2YXIgYXJncyxcblx0XHRcdFx0Zm4gPSBFeHByLnBzZXVkb3NbIHBzZXVkbyBdIHx8IEV4cHIuc2V0RmlsdGVyc1sgcHNldWRvLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBwc2V1ZG86IFwiICsgcHNldWRvICk7XG5cblx0XHRcdC8vIFRoZSB1c2VyIG1heSB1c2UgY3JlYXRlUHNldWRvIHRvIGluZGljYXRlIHRoYXRcblx0XHRcdC8vIGFyZ3VtZW50cyBhcmUgbmVlZGVkIHRvIGNyZWF0ZSB0aGUgZmlsdGVyIGZ1bmN0aW9uXG5cdFx0XHQvLyBqdXN0IGFzIFNpenpsZSBkb2VzXG5cdFx0XHRpZiAoIGZuWyBleHBhbmRvIF0gKSB7XG5cdFx0XHRcdHJldHVybiBmbiggYXJndW1lbnQgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQnV0IG1haW50YWluIHN1cHBvcnQgZm9yIG9sZCBzaWduYXR1cmVzXG5cdFx0XHRpZiAoIGZuLmxlbmd0aCA+IDEgKSB7XG5cdFx0XHRcdGFyZ3MgPSBbIHBzZXVkbywgcHNldWRvLCBcIlwiLCBhcmd1bWVudCBdO1xuXHRcdFx0XHRyZXR1cm4gRXhwci5zZXRGaWx0ZXJzLmhhc093blByb3BlcnR5KCBwc2V1ZG8udG9Mb3dlckNhc2UoKSApID9cblx0XHRcdFx0XHRtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWVkLCBtYXRjaGVzICkge1xuXHRcdFx0XHRcdFx0dmFyIGlkeCxcblx0XHRcdFx0XHRcdFx0bWF0Y2hlZCA9IGZuKCBzZWVkLCBhcmd1bWVudCApLFxuXHRcdFx0XHRcdFx0XHRpID0gbWF0Y2hlZC5sZW5ndGg7XG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdFx0aWR4ID0gaW5kZXhPZiggc2VlZCwgbWF0Y2hlZFsgaSBdICk7XG5cdFx0XHRcdFx0XHRcdHNlZWRbIGlkeCBdID0gISggbWF0Y2hlc1sgaWR4IF0gPSBtYXRjaGVkWyBpIF0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9ICkgOlxuXHRcdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZuKCBlbGVtLCAwLCBhcmdzICk7XG5cdFx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZuO1xuXHRcdH1cblx0fSxcblxuXHRwc2V1ZG9zOiB7XG5cblx0XHQvLyBQb3RlbnRpYWxseSBjb21wbGV4IHBzZXVkb3Ncblx0XHRcIm5vdFwiOiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblxuXHRcdFx0Ly8gVHJpbSB0aGUgc2VsZWN0b3IgcGFzc2VkIHRvIGNvbXBpbGVcblx0XHRcdC8vIHRvIGF2b2lkIHRyZWF0aW5nIGxlYWRpbmcgYW5kIHRyYWlsaW5nXG5cdFx0XHQvLyBzcGFjZXMgYXMgY29tYmluYXRvcnNcblx0XHRcdHZhciBpbnB1dCA9IFtdLFxuXHRcdFx0XHRyZXN1bHRzID0gW10sXG5cdFx0XHRcdG1hdGNoZXIgPSBjb21waWxlKCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICkgKTtcblxuXHRcdFx0cmV0dXJuIG1hdGNoZXJbIGV4cGFuZG8gXSA/XG5cdFx0XHRcdG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMsIF9jb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0dmFyIGVsZW0sXG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQgPSBtYXRjaGVyKCBzZWVkLCBudWxsLCB4bWwsIFtdICksXG5cdFx0XHRcdFx0XHRpID0gc2VlZC5sZW5ndGg7XG5cblx0XHRcdFx0XHQvLyBNYXRjaCBlbGVtZW50cyB1bm1hdGNoZWQgYnkgYG1hdGNoZXJgXG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZWxlbSA9IHVubWF0Y2hlZFsgaSBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdHNlZWRbIGkgXSA9ICEoIG1hdGNoZXNbIGkgXSA9IGVsZW0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gKSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBfY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdGlucHV0WyAwIF0gPSBlbGVtO1xuXHRcdFx0XHRcdG1hdGNoZXIoIGlucHV0LCBudWxsLCB4bWwsIHJlc3VsdHMgKTtcblxuXHRcdFx0XHRcdC8vIERvbid0IGtlZXAgdGhlIGVsZW1lbnQgKGlzc3VlICMyOTkpXG5cdFx0XHRcdFx0aW5wdXRbIDAgXSA9IG51bGw7XG5cdFx0XHRcdFx0cmV0dXJuICFyZXN1bHRzLnBvcCgpO1xuXHRcdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdFwiaGFzXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gU2l6emxlKCBzZWxlY3RvciwgZWxlbSApLmxlbmd0aCA+IDA7XG5cdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdFwiY29udGFpbnNcIjogbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRcdHRleHQgPSB0ZXh0LnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHJldHVybiAoIGVsZW0udGV4dENvbnRlbnQgfHwgZ2V0VGV4dCggZWxlbSApICkuaW5kZXhPZiggdGV4dCApID4gLTE7XG5cdFx0XHR9O1xuXHRcdH0gKSxcblxuXHRcdC8vIFwiV2hldGhlciBhbiBlbGVtZW50IGlzIHJlcHJlc2VudGVkIGJ5IGEgOmxhbmcoKSBzZWxlY3RvclxuXHRcdC8vIGlzIGJhc2VkIHNvbGVseSBvbiB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlXG5cdFx0Ly8gYmVpbmcgZXF1YWwgdG8gdGhlIGlkZW50aWZpZXIgQyxcblx0XHQvLyBvciBiZWdpbm5pbmcgd2l0aCB0aGUgaWRlbnRpZmllciBDIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IFwiLVwiLlxuXHRcdC8vIFRoZSBtYXRjaGluZyBvZiBDIGFnYWluc3QgdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZSBpcyBwZXJmb3JtZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LlxuXHRcdC8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuXCJcblx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2xhbmctcHNldWRvXG5cdFx0XCJsYW5nXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGxhbmcgKSB7XG5cblx0XHRcdC8vIGxhbmcgdmFsdWUgbXVzdCBiZSBhIHZhbGlkIGlkZW50aWZpZXJcblx0XHRcdGlmICggIXJpZGVudGlmaWVyLnRlc3QoIGxhbmcgfHwgXCJcIiApICkge1xuXHRcdFx0XHRTaXp6bGUuZXJyb3IoIFwidW5zdXBwb3J0ZWQgbGFuZzogXCIgKyBsYW5nICk7XG5cdFx0XHR9XG5cdFx0XHRsYW5nID0gbGFuZy5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciBlbGVtTGFuZztcblx0XHRcdFx0ZG8ge1xuXHRcdFx0XHRcdGlmICggKCBlbGVtTGFuZyA9IGRvY3VtZW50SXNIVE1MID9cblx0XHRcdFx0XHRcdGVsZW0ubGFuZyA6XG5cdFx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZSggXCJ4bWw6bGFuZ1wiICkgfHwgZWxlbS5nZXRBdHRyaWJ1dGUoIFwibGFuZ1wiICkgKSApIHtcblxuXHRcdFx0XHRcdFx0ZWxlbUxhbmcgPSBlbGVtTGFuZy50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVsZW1MYW5nID09PSBsYW5nIHx8IGVsZW1MYW5nLmluZGV4T2YoIGxhbmcgKyBcIi1cIiApID09PSAwO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSB3aGlsZSAoICggZWxlbSA9IGVsZW0ucGFyZW50Tm9kZSApICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fTtcblx0XHR9ICksXG5cblx0XHQvLyBNaXNjZWxsYW5lb3VzXG5cdFx0XCJ0YXJnZXRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgaGFzaCA9IHdpbmRvdy5sb2NhdGlvbiAmJiB3aW5kb3cubG9jYXRpb24uaGFzaDtcblx0XHRcdHJldHVybiBoYXNoICYmIGhhc2guc2xpY2UoIDEgKSA9PT0gZWxlbS5pZDtcblx0XHR9LFxuXG5cdFx0XCJyb290XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGRvY0VsZW07XG5cdFx0fSxcblxuXHRcdFwiZm9jdXNcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCAmJlxuXHRcdFx0XHQoICFkb2N1bWVudC5oYXNGb2N1cyB8fCBkb2N1bWVudC5oYXNGb2N1cygpICkgJiZcblx0XHRcdFx0ISEoIGVsZW0udHlwZSB8fCBlbGVtLmhyZWYgfHwgfmVsZW0udGFiSW5kZXggKTtcblx0XHR9LFxuXG5cdFx0Ly8gQm9vbGVhbiBwcm9wZXJ0aWVzXG5cdFx0XCJlbmFibGVkXCI6IGNyZWF0ZURpc2FibGVkUHNldWRvKCBmYWxzZSApLFxuXHRcdFwiZGlzYWJsZWRcIjogY3JlYXRlRGlzYWJsZWRQc2V1ZG8oIHRydWUgKSxcblxuXHRcdFwiY2hlY2tlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0Ly8gSW4gQ1NTMywgOmNoZWNrZWQgc2hvdWxkIHJldHVybiBib3RoIGNoZWNrZWQgYW5kIHNlbGVjdGVkIGVsZW1lbnRzXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDExL1JFQy1jc3MzLXNlbGVjdG9ycy0yMDExMDkyOS8jY2hlY2tlZFxuXHRcdFx0dmFyIG5vZGVOYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuICggbm9kZU5hbWUgPT09IFwiaW5wdXRcIiAmJiAhIWVsZW0uY2hlY2tlZCApIHx8XG5cdFx0XHRcdCggbm9kZU5hbWUgPT09IFwib3B0aW9uXCIgJiYgISFlbGVtLnNlbGVjdGVkICk7XG5cdFx0fSxcblxuXHRcdFwic2VsZWN0ZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cblx0XHRcdC8vIEFjY2Vzc2luZyB0aGlzIHByb3BlcnR5IG1ha2VzIHNlbGVjdGVkLWJ5LWRlZmF1bHRcblx0XHRcdC8vIG9wdGlvbnMgaW4gU2FmYXJpIHdvcmsgcHJvcGVybHlcblx0XHRcdGlmICggZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHQvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdW51c2VkLWV4cHJlc3Npb25zXG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0Ly8gQ29udGVudHNcblx0XHRcImVtcHR5XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2VtcHR5LXBzZXVkb1xuXHRcdFx0Ly8gOmVtcHR5IGlzIG5lZ2F0ZWQgYnkgZWxlbWVudCAoMSkgb3IgY29udGVudCBub2RlcyAodGV4dDogMzsgY2RhdGE6IDQ7IGVudGl0eSByZWY6IDUpLFxuXHRcdFx0Ly8gICBidXQgbm90IGJ5IG90aGVycyAoY29tbWVudDogODsgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbjogNzsgZXRjLilcblx0XHRcdC8vIG5vZGVUeXBlIDwgNiB3b3JrcyBiZWNhdXNlIGF0dHJpYnV0ZXMgKDIpIGRvIG5vdCBhcHBlYXIgYXMgY2hpbGRyZW5cblx0XHRcdGZvciAoIGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7IGVsZW07IGVsZW0gPSBlbGVtLm5leHRTaWJsaW5nICkge1xuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPCA2ICkge1xuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdFwicGFyZW50XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuICFFeHByLnBzZXVkb3NbIFwiZW1wdHlcIiBdKCBlbGVtICk7XG5cdFx0fSxcblxuXHRcdC8vIEVsZW1lbnQvaW5wdXQgdHlwZXNcblx0XHRcImhlYWRlclwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiByaGVhZGVyLnRlc3QoIGVsZW0ubm9kZU5hbWUgKTtcblx0XHR9LFxuXG5cdFx0XCJpbnB1dFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiByaW5wdXRzLnRlc3QoIGVsZW0ubm9kZU5hbWUgKTtcblx0XHR9LFxuXG5cdFx0XCJidXR0b25cIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgbmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBuYW1lID09PSBcImlucHV0XCIgJiYgZWxlbS50eXBlID09PSBcImJ1dHRvblwiIHx8IG5hbWUgPT09IFwiYnV0dG9uXCI7XG5cdFx0fSxcblxuXHRcdFwidGV4dFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBhdHRyO1xuXHRcdFx0cmV0dXJuIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJpbnB1dFwiICYmXG5cdFx0XHRcdGVsZW0udHlwZSA9PT0gXCJ0ZXh0XCIgJiZcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRTw4XG5cdFx0XHRcdC8vIE5ldyBIVE1MNSBhdHRyaWJ1dGUgdmFsdWVzIChlLmcuLCBcInNlYXJjaFwiKSBhcHBlYXIgd2l0aCBlbGVtLnR5cGUgPT09IFwidGV4dFwiXG5cdFx0XHRcdCggKCBhdHRyID0gZWxlbS5nZXRBdHRyaWJ1dGUoIFwidHlwZVwiICkgKSA9PSBudWxsIHx8XG5cdFx0XHRcdFx0YXR0ci50b0xvd2VyQ2FzZSgpID09PSBcInRleHRcIiApO1xuXHRcdH0sXG5cblx0XHQvLyBQb3NpdGlvbi1pbi1jb2xsZWN0aW9uXG5cdFx0XCJmaXJzdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBbIDAgXTtcblx0XHR9ICksXG5cblx0XHRcImxhc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIF9tYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHJldHVybiBbIGxlbmd0aCAtIDEgXTtcblx0XHR9ICksXG5cblx0XHRcImVxXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBfbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xuXHRcdFx0cmV0dXJuIFsgYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudCBdO1xuXHRcdH0gKSxcblxuXHRcdFwiZXZlblwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkgKz0gMiApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSApLFxuXG5cdFx0XCJvZGRcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAxO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0gKSxcblxuXHRcdFwibHRcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyggZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID9cblx0XHRcdFx0YXJndW1lbnQgKyBsZW5ndGggOlxuXHRcdFx0XHRhcmd1bWVudCA+IGxlbmd0aCA/XG5cdFx0XHRcdFx0bGVuZ3RoIDpcblx0XHRcdFx0XHRhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgLS1pID49IDA7ICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9ICksXG5cblx0XHRcImd0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCwgYXJndW1lbnQgKSB7XG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XG5cdFx0XHRmb3IgKCA7ICsraSA8IGxlbmd0aDsgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0gKVxuXHR9XG59O1xuXG5FeHByLnBzZXVkb3NbIFwibnRoXCIgXSA9IEV4cHIucHNldWRvc1sgXCJlcVwiIF07XG5cbi8vIEFkZCBidXR0b24vaW5wdXQgdHlwZSBwc2V1ZG9zXG5mb3IgKCBpIGluIHsgcmFkaW86IHRydWUsIGNoZWNrYm94OiB0cnVlLCBmaWxlOiB0cnVlLCBwYXNzd29yZDogdHJ1ZSwgaW1hZ2U6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApO1xufVxuZm9yICggaSBpbiB7IHN1Ym1pdDogdHJ1ZSwgcmVzZXQ6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVCdXR0b25Qc2V1ZG8oIGkgKTtcbn1cblxuLy8gRWFzeSBBUEkgZm9yIGNyZWF0aW5nIG5ldyBzZXRGaWx0ZXJzXG5mdW5jdGlvbiBzZXRGaWx0ZXJzKCkge31cbnNldEZpbHRlcnMucHJvdG90eXBlID0gRXhwci5maWx0ZXJzID0gRXhwci5wc2V1ZG9zO1xuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcblxudG9rZW5pemUgPSBTaXp6bGUudG9rZW5pemUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIHBhcnNlT25seSApIHtcblx0dmFyIG1hdGNoZWQsIG1hdGNoLCB0b2tlbnMsIHR5cGUsXG5cdFx0c29GYXIsIGdyb3VwcywgcHJlRmlsdGVycyxcblx0XHRjYWNoZWQgPSB0b2tlbkNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCBjYWNoZWQgKSB7XG5cdFx0cmV0dXJuIHBhcnNlT25seSA/IDAgOiBjYWNoZWQuc2xpY2UoIDAgKTtcblx0fVxuXG5cdHNvRmFyID0gc2VsZWN0b3I7XG5cdGdyb3VwcyA9IFtdO1xuXHRwcmVGaWx0ZXJzID0gRXhwci5wcmVGaWx0ZXI7XG5cblx0d2hpbGUgKCBzb0ZhciApIHtcblxuXHRcdC8vIENvbW1hIGFuZCBmaXJzdCBydW5cblx0XHRpZiAoICFtYXRjaGVkIHx8ICggbWF0Y2ggPSByY29tbWEuZXhlYyggc29GYXIgKSApICkge1xuXHRcdFx0aWYgKCBtYXRjaCApIHtcblxuXHRcdFx0XHQvLyBEb24ndCBjb25zdW1lIHRyYWlsaW5nIGNvbW1hcyBhcyB2YWxpZFxuXHRcdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaFsgMCBdLmxlbmd0aCApIHx8IHNvRmFyO1xuXHRcdFx0fVxuXHRcdFx0Z3JvdXBzLnB1c2goICggdG9rZW5zID0gW10gKSApO1xuXHRcdH1cblxuXHRcdG1hdGNoZWQgPSBmYWxzZTtcblxuXHRcdC8vIENvbWJpbmF0b3JzXG5cdFx0aWYgKCAoIG1hdGNoID0gcmNvbWJpbmF0b3JzLmV4ZWMoIHNvRmFyICkgKSApIHtcblx0XHRcdG1hdGNoZWQgPSBtYXRjaC5zaGlmdCgpO1xuXHRcdFx0dG9rZW5zLnB1c2goIHtcblx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cblx0XHRcdFx0Ly8gQ2FzdCBkZXNjZW5kYW50IGNvbWJpbmF0b3JzIHRvIHNwYWNlXG5cdFx0XHRcdHR5cGU6IG1hdGNoWyAwIF0ucmVwbGFjZSggcnRyaW0sIFwiIFwiIClcblx0XHRcdH0gKTtcblx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoZWQubGVuZ3RoICk7XG5cdFx0fVxuXG5cdFx0Ly8gRmlsdGVyc1xuXHRcdGZvciAoIHR5cGUgaW4gRXhwci5maWx0ZXIgKSB7XG5cdFx0XHRpZiAoICggbWF0Y2ggPSBtYXRjaEV4cHJbIHR5cGUgXS5leGVjKCBzb0ZhciApICkgJiYgKCAhcHJlRmlsdGVyc1sgdHlwZSBdIHx8XG5cdFx0XHRcdCggbWF0Y2ggPSBwcmVGaWx0ZXJzWyB0eXBlIF0oIG1hdGNoICkgKSApICkge1xuXHRcdFx0XHRtYXRjaGVkID0gbWF0Y2guc2hpZnQoKTtcblx0XHRcdFx0dG9rZW5zLnB1c2goIHtcblx0XHRcdFx0XHR2YWx1ZTogbWF0Y2hlZCxcblx0XHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRcdG1hdGNoZXM6IG1hdGNoXG5cdFx0XHRcdH0gKTtcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoICFtYXRjaGVkICkge1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGludmFsaWQgZXhjZXNzXG5cdC8vIGlmIHdlJ3JlIGp1c3QgcGFyc2luZ1xuXHQvLyBPdGhlcndpc2UsIHRocm93IGFuIGVycm9yIG9yIHJldHVybiB0b2tlbnNcblx0cmV0dXJuIHBhcnNlT25seSA/XG5cdFx0c29GYXIubGVuZ3RoIDpcblx0XHRzb0ZhciA/XG5cdFx0XHRTaXp6bGUuZXJyb3IoIHNlbGVjdG9yICkgOlxuXG5cdFx0XHQvLyBDYWNoZSB0aGUgdG9rZW5zXG5cdFx0XHR0b2tlbkNhY2hlKCBzZWxlY3RvciwgZ3JvdXBzICkuc2xpY2UoIDAgKTtcbn07XG5cbmZ1bmN0aW9uIHRvU2VsZWN0b3IoIHRva2VucyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IHRva2Vucy5sZW5ndGgsXG5cdFx0c2VsZWN0b3IgPSBcIlwiO1xuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRzZWxlY3RvciArPSB0b2tlbnNbIGkgXS52YWx1ZTtcblx0fVxuXHRyZXR1cm4gc2VsZWN0b3I7XG59XG5cbmZ1bmN0aW9uIGFkZENvbWJpbmF0b3IoIG1hdGNoZXIsIGNvbWJpbmF0b3IsIGJhc2UgKSB7XG5cdHZhciBkaXIgPSBjb21iaW5hdG9yLmRpcixcblx0XHRza2lwID0gY29tYmluYXRvci5uZXh0LFxuXHRcdGtleSA9IHNraXAgfHwgZGlyLFxuXHRcdGNoZWNrTm9uRWxlbWVudHMgPSBiYXNlICYmIGtleSA9PT0gXCJwYXJlbnROb2RlXCIsXG5cdFx0ZG9uZU5hbWUgPSBkb25lKys7XG5cblx0cmV0dXJuIGNvbWJpbmF0b3IuZmlyc3QgP1xuXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBjbG9zZXN0IGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHdoaWxlICggKCBlbGVtID0gZWxlbVsgZGlyIF0gKSApIHtcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fSA6XG5cblx0XHQvLyBDaGVjayBhZ2FpbnN0IGFsbCBhbmNlc3Rvci9wcmVjZWRpbmcgZWxlbWVudHNcblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIG9sZENhY2hlLCB1bmlxdWVDYWNoZSwgb3V0ZXJDYWNoZSxcblx0XHRcdFx0bmV3Q2FjaGUgPSBbIGRpcnJ1bnMsIGRvbmVOYW1lIF07XG5cblx0XHRcdC8vIFdlIGNhbid0IHNldCBhcmJpdHJhcnkgZGF0YSBvbiBYTUwgbm9kZXMsIHNvIHRoZXkgZG9uJ3QgYmVuZWZpdCBmcm9tIGNvbWJpbmF0b3IgY2FjaGluZ1xuXHRcdFx0aWYgKCB4bWwgKSB7XG5cdFx0XHRcdHdoaWxlICggKCBlbGVtID0gZWxlbVsgZGlyIF0gKSApIHtcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0d2hpbGUgKCAoIGVsZW0gPSBlbGVtWyBkaXIgXSApICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xuXHRcdFx0XHRcdFx0b3V0ZXJDYWNoZSA9IGVsZW1bIGV4cGFuZG8gXSB8fCAoIGVsZW1bIGV4cGFuZG8gXSA9IHt9ICk7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcblx0XHRcdFx0XHRcdC8vIERlZmVuZCBhZ2FpbnN0IGNsb25lZCBhdHRyb3BlcnRpZXMgKGpRdWVyeSBnaC0xNzA5KVxuXHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGUgPSBvdXRlckNhY2hlWyBlbGVtLnVuaXF1ZUlEIF0gfHxcblx0XHRcdFx0XHRcdFx0KCBvdXRlckNhY2hlWyBlbGVtLnVuaXF1ZUlEIF0gPSB7fSApO1xuXG5cdFx0XHRcdFx0XHRpZiAoIHNraXAgJiYgc2tpcCA9PT0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpICkge1xuXHRcdFx0XHRcdFx0XHRlbGVtID0gZWxlbVsgZGlyIF0gfHwgZWxlbTtcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoICggb2xkQ2FjaGUgPSB1bmlxdWVDYWNoZVsga2V5IF0gKSAmJlxuXHRcdFx0XHRcdFx0XHRvbGRDYWNoZVsgMCBdID09PSBkaXJydW5zICYmIG9sZENhY2hlWyAxIF0gPT09IGRvbmVOYW1lICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEFzc2lnbiB0byBuZXdDYWNoZSBzbyByZXN1bHRzIGJhY2stcHJvcGFnYXRlIHRvIHByZXZpb3VzIGVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdHJldHVybiAoIG5ld0NhY2hlWyAyIF0gPSBvbGRDYWNoZVsgMiBdICk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdC8vIFJldXNlIG5ld2NhY2hlIHNvIHJlc3VsdHMgYmFjay1wcm9wYWdhdGUgdG8gcHJldmlvdXMgZWxlbWVudHNcblx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGVbIGtleSBdID0gbmV3Q2FjaGU7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQSBtYXRjaCBtZWFucyB3ZSdyZSBkb25lOyBhIGZhaWwgbWVhbnMgd2UgaGF2ZSB0byBrZWVwIGNoZWNraW5nXG5cdFx0XHRcdFx0XHRcdGlmICggKCBuZXdDYWNoZVsgMiBdID0gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG59XG5cbmZ1bmN0aW9uIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApIHtcblx0cmV0dXJuIG1hdGNoZXJzLmxlbmd0aCA+IDEgP1xuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR2YXIgaSA9IG1hdGNoZXJzLmxlbmd0aDtcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRpZiAoICFtYXRjaGVyc1sgaSBdKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gOlxuXHRcdG1hdGNoZXJzWyAwIF07XG59XG5cbmZ1bmN0aW9uIG11bHRpcGxlQ29udGV4dHMoIHNlbGVjdG9yLCBjb250ZXh0cywgcmVzdWx0cyApIHtcblx0dmFyIGkgPSAwLFxuXHRcdGxlbiA9IGNvbnRleHRzLmxlbmd0aDtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0U2l6emxlKCBzZWxlY3RvciwgY29udGV4dHNbIGkgXSwgcmVzdWx0cyApO1xuXHR9XG5cdHJldHVybiByZXN1bHRzO1xufVxuXG5mdW5jdGlvbiBjb25kZW5zZSggdW5tYXRjaGVkLCBtYXAsIGZpbHRlciwgY29udGV4dCwgeG1sICkge1xuXHR2YXIgZWxlbSxcblx0XHRuZXdVbm1hdGNoZWQgPSBbXSxcblx0XHRpID0gMCxcblx0XHRsZW4gPSB1bm1hdGNoZWQubGVuZ3RoLFxuXHRcdG1hcHBlZCA9IG1hcCAhPSBudWxsO1xuXG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdGlmICggKCBlbGVtID0gdW5tYXRjaGVkWyBpIF0gKSApIHtcblx0XHRcdGlmICggIWZpbHRlciB8fCBmaWx0ZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRuZXdVbm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRpZiAoIG1hcHBlZCApIHtcblx0XHRcdFx0XHRtYXAucHVzaCggaSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIG5ld1VubWF0Y2hlZDtcbn1cblxuZnVuY3Rpb24gc2V0TWF0Y2hlciggcHJlRmlsdGVyLCBzZWxlY3RvciwgbWF0Y2hlciwgcG9zdEZpbHRlciwgcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICkge1xuXHRpZiAoIHBvc3RGaWx0ZXIgJiYgIXBvc3RGaWx0ZXJbIGV4cGFuZG8gXSApIHtcblx0XHRwb3N0RmlsdGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbHRlciApO1xuXHR9XG5cdGlmICggcG9zdEZpbmRlciAmJiAhcG9zdEZpbmRlclsgZXhwYW5kbyBdICkge1xuXHRcdHBvc3RGaW5kZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKTtcblx0fVxuXHRyZXR1cm4gbWFya0Z1bmN0aW9uKCBmdW5jdGlvbiggc2VlZCwgcmVzdWx0cywgY29udGV4dCwgeG1sICkge1xuXHRcdHZhciB0ZW1wLCBpLCBlbGVtLFxuXHRcdFx0cHJlTWFwID0gW10sXG5cdFx0XHRwb3N0TWFwID0gW10sXG5cdFx0XHRwcmVleGlzdGluZyA9IHJlc3VsdHMubGVuZ3RoLFxuXG5cdFx0XHQvLyBHZXQgaW5pdGlhbCBlbGVtZW50cyBmcm9tIHNlZWQgb3IgY29udGV4dFxuXHRcdFx0ZWxlbXMgPSBzZWVkIHx8IG11bHRpcGxlQ29udGV4dHMoXG5cdFx0XHRcdHNlbGVjdG9yIHx8IFwiKlwiLFxuXHRcdFx0XHRjb250ZXh0Lm5vZGVUeXBlID8gWyBjb250ZXh0IF0gOiBjb250ZXh0LFxuXHRcdFx0XHRbXVxuXHRcdFx0KSxcblxuXHRcdFx0Ly8gUHJlZmlsdGVyIHRvIGdldCBtYXRjaGVyIGlucHV0LCBwcmVzZXJ2aW5nIGEgbWFwIGZvciBzZWVkLXJlc3VsdHMgc3luY2hyb25pemF0aW9uXG5cdFx0XHRtYXRjaGVySW4gPSBwcmVGaWx0ZXIgJiYgKCBzZWVkIHx8ICFzZWxlY3RvciApID9cblx0XHRcdFx0Y29uZGVuc2UoIGVsZW1zLCBwcmVNYXAsIHByZUZpbHRlciwgY29udGV4dCwgeG1sICkgOlxuXHRcdFx0XHRlbGVtcyxcblxuXHRcdFx0bWF0Y2hlck91dCA9IG1hdGNoZXIgP1xuXG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgYSBwb3N0RmluZGVyLCBvciBmaWx0ZXJlZCBzZWVkLCBvciBub24tc2VlZCBwb3N0RmlsdGVyIG9yIHByZWV4aXN0aW5nIHJlc3VsdHMsXG5cdFx0XHRcdHBvc3RGaW5kZXIgfHwgKCBzZWVkID8gcHJlRmlsdGVyIDogcHJlZXhpc3RpbmcgfHwgcG9zdEZpbHRlciApID9cblxuXHRcdFx0XHRcdC8vIC4uLmludGVybWVkaWF0ZSBwcm9jZXNzaW5nIGlzIG5lY2Vzc2FyeVxuXHRcdFx0XHRcdFtdIDpcblxuXHRcdFx0XHRcdC8vIC4uLm90aGVyd2lzZSB1c2UgcmVzdWx0cyBkaXJlY3RseVxuXHRcdFx0XHRcdHJlc3VsdHMgOlxuXHRcdFx0XHRtYXRjaGVySW47XG5cblx0XHQvLyBGaW5kIHByaW1hcnkgbWF0Y2hlc1xuXHRcdGlmICggbWF0Y2hlciApIHtcblx0XHRcdG1hdGNoZXIoIG1hdGNoZXJJbiwgbWF0Y2hlck91dCwgY29udGV4dCwgeG1sICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcG9zdEZpbHRlclxuXHRcdGlmICggcG9zdEZpbHRlciApIHtcblx0XHRcdHRlbXAgPSBjb25kZW5zZSggbWF0Y2hlck91dCwgcG9zdE1hcCApO1xuXHRcdFx0cG9zdEZpbHRlciggdGVtcCwgW10sIGNvbnRleHQsIHhtbCApO1xuXG5cdFx0XHQvLyBVbi1tYXRjaCBmYWlsaW5nIGVsZW1lbnRzIGJ5IG1vdmluZyB0aGVtIGJhY2sgdG8gbWF0Y2hlckluXG5cdFx0XHRpID0gdGVtcC5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAoIGVsZW0gPSB0ZW1wWyBpIF0gKSApIHtcblx0XHRcdFx0XHRtYXRjaGVyT3V0WyBwb3N0TWFwWyBpIF0gXSA9ICEoIG1hdGNoZXJJblsgcG9zdE1hcFsgaSBdIF0gPSBlbGVtICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRpZiAoIHBvc3RGaW5kZXIgfHwgcHJlRmlsdGVyICkge1xuXHRcdFx0XHRpZiAoIHBvc3RGaW5kZXIgKSB7XG5cblx0XHRcdFx0XHQvLyBHZXQgdGhlIGZpbmFsIG1hdGNoZXJPdXQgYnkgY29uZGVuc2luZyB0aGlzIGludGVybWVkaWF0ZSBpbnRvIHBvc3RGaW5kZXIgY29udGV4dHNcblx0XHRcdFx0XHR0ZW1wID0gW107XG5cdFx0XHRcdFx0aSA9IG1hdGNoZXJPdXQubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoIGVsZW0gPSBtYXRjaGVyT3V0WyBpIF0gKSApIHtcblxuXHRcdFx0XHRcdFx0XHQvLyBSZXN0b3JlIG1hdGNoZXJJbiBzaW5jZSBlbGVtIGlzIG5vdCB5ZXQgYSBmaW5hbCBtYXRjaFxuXHRcdFx0XHRcdFx0XHR0ZW1wLnB1c2goICggbWF0Y2hlckluWyBpIF0gPSBlbGVtICkgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgKCBtYXRjaGVyT3V0ID0gW10gKSwgdGVtcCwgeG1sICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBNb3ZlIG1hdGNoZWQgZWxlbWVudHMgZnJvbSBzZWVkIHRvIHJlc3VsdHMgdG8ga2VlcCB0aGVtIHN5bmNocm9uaXplZFxuXHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdGlmICggKCBlbGVtID0gbWF0Y2hlck91dFsgaSBdICkgJiZcblx0XHRcdFx0XHRcdCggdGVtcCA9IHBvc3RGaW5kZXIgPyBpbmRleE9mKCBzZWVkLCBlbGVtICkgOiBwcmVNYXBbIGkgXSApID4gLTEgKSB7XG5cblx0XHRcdFx0XHRcdHNlZWRbIHRlbXAgXSA9ICEoIHJlc3VsdHNbIHRlbXAgXSA9IGVsZW0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEFkZCBlbGVtZW50cyB0byByZXN1bHRzLCB0aHJvdWdoIHBvc3RGaW5kZXIgaWYgZGVmaW5lZFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRtYXRjaGVyT3V0ID0gY29uZGVuc2UoXG5cdFx0XHRcdG1hdGNoZXJPdXQgPT09IHJlc3VsdHMgP1xuXHRcdFx0XHRcdG1hdGNoZXJPdXQuc3BsaWNlKCBwcmVleGlzdGluZywgbWF0Y2hlck91dC5sZW5ndGggKSA6XG5cdFx0XHRcdFx0bWF0Y2hlck91dFxuXHRcdFx0KTtcblx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgcmVzdWx0cywgbWF0Y2hlck91dCwgeG1sICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBtYXRjaGVyT3V0ICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMgKSB7XG5cdHZhciBjaGVja0NvbnRleHQsIG1hdGNoZXIsIGosXG5cdFx0bGVuID0gdG9rZW5zLmxlbmd0aCxcblx0XHRsZWFkaW5nUmVsYXRpdmUgPSBFeHByLnJlbGF0aXZlWyB0b2tlbnNbIDAgXS50eXBlIF0sXG5cdFx0aW1wbGljaXRSZWxhdGl2ZSA9IGxlYWRpbmdSZWxhdGl2ZSB8fCBFeHByLnJlbGF0aXZlWyBcIiBcIiBdLFxuXHRcdGkgPSBsZWFkaW5nUmVsYXRpdmUgPyAxIDogMCxcblxuXHRcdC8vIFRoZSBmb3VuZGF0aW9uYWwgbWF0Y2hlciBlbnN1cmVzIHRoYXQgZWxlbWVudHMgYXJlIHJlYWNoYWJsZSBmcm9tIHRvcC1sZXZlbCBjb250ZXh0KHMpXG5cdFx0bWF0Y2hDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gY2hlY2tDb250ZXh0O1xuXHRcdH0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSxcblx0XHRtYXRjaEFueUNvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBpbmRleE9mKCBjaGVja0NvbnRleHQsIGVsZW0gKSA+IC0xO1xuXHRcdH0sIGltcGxpY2l0UmVsYXRpdmUsIHRydWUgKSxcblx0XHRtYXRjaGVycyA9IFsgZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciByZXQgPSAoICFsZWFkaW5nUmVsYXRpdmUgJiYgKCB4bWwgfHwgY29udGV4dCAhPT0gb3V0ZXJtb3N0Q29udGV4dCApICkgfHwgKFxuXHRcdFx0XHQoIGNoZWNrQ29udGV4dCA9IGNvbnRleHQgKS5ub2RlVHlwZSA/XG5cdFx0XHRcdFx0bWF0Y2hDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdFx0bWF0Y2hBbnlDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSApO1xuXG5cdFx0XHQvLyBBdm9pZCBoYW5naW5nIG9udG8gZWxlbWVudCAoaXNzdWUgIzI5OSlcblx0XHRcdGNoZWNrQ29udGV4dCA9IG51bGw7XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH0gXTtcblxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRpZiAoICggbWF0Y2hlciA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1sgaSBdLnR5cGUgXSApICkge1xuXHRcdFx0bWF0Y2hlcnMgPSBbIGFkZENvbWJpbmF0b3IoIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLCBtYXRjaGVyICkgXTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWF0Y2hlciA9IEV4cHIuZmlsdGVyWyB0b2tlbnNbIGkgXS50eXBlIF0uYXBwbHkoIG51bGwsIHRva2Vuc1sgaSBdLm1hdGNoZXMgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIHNwZWNpYWwgdXBvbiBzZWVpbmcgYSBwb3NpdGlvbmFsIG1hdGNoZXJcblx0XHRcdGlmICggbWF0Y2hlclsgZXhwYW5kbyBdICkge1xuXG5cdFx0XHRcdC8vIEZpbmQgdGhlIG5leHQgcmVsYXRpdmUgb3BlcmF0b3IgKGlmIGFueSkgZm9yIHByb3BlciBoYW5kbGluZ1xuXHRcdFx0XHRqID0gKytpO1xuXHRcdFx0XHRmb3IgKCA7IGogPCBsZW47IGorKyApIHtcblx0XHRcdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbIHRva2Vuc1sgaiBdLnR5cGUgXSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gc2V0TWF0Y2hlcihcblx0XHRcdFx0XHRpID4gMSAmJiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSxcblx0XHRcdFx0XHRpID4gMSAmJiB0b1NlbGVjdG9yKFxuXG5cdFx0XHRcdFx0Ly8gSWYgdGhlIHByZWNlZGluZyB0b2tlbiB3YXMgYSBkZXNjZW5kYW50IGNvbWJpbmF0b3IsIGluc2VydCBhbiBpbXBsaWNpdCBhbnktZWxlbWVudCBgKmBcblx0XHRcdFx0XHR0b2tlbnNcblx0XHRcdFx0XHRcdC5zbGljZSggMCwgaSAtIDEgKVxuXHRcdFx0XHRcdFx0LmNvbmNhdCggeyB2YWx1ZTogdG9rZW5zWyBpIC0gMiBdLnR5cGUgPT09IFwiIFwiID8gXCIqXCIgOiBcIlwiIH0gKVxuXHRcdFx0XHRcdCkucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApLFxuXHRcdFx0XHRcdG1hdGNoZXIsXG5cdFx0XHRcdFx0aSA8IGogJiYgbWF0Y2hlckZyb21Ub2tlbnMoIHRva2Vucy5zbGljZSggaSwgaiApICksXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiBtYXRjaGVyRnJvbVRva2VucyggKCB0b2tlbnMgPSB0b2tlbnMuc2xpY2UoIGogKSApICksXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKVxuXHRcdFx0XHQpO1xuXHRcdFx0fVxuXHRcdFx0bWF0Y2hlcnMucHVzaCggbWF0Y2hlciApO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKTtcbn1cblxuZnVuY3Rpb24gbWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzICkge1xuXHR2YXIgYnlTZXQgPSBzZXRNYXRjaGVycy5sZW5ndGggPiAwLFxuXHRcdGJ5RWxlbWVudCA9IGVsZW1lbnRNYXRjaGVycy5sZW5ndGggPiAwLFxuXHRcdHN1cGVyTWF0Y2hlciA9IGZ1bmN0aW9uKCBzZWVkLCBjb250ZXh0LCB4bWwsIHJlc3VsdHMsIG91dGVybW9zdCApIHtcblx0XHRcdHZhciBlbGVtLCBqLCBtYXRjaGVyLFxuXHRcdFx0XHRtYXRjaGVkQ291bnQgPSAwLFxuXHRcdFx0XHRpID0gXCIwXCIsXG5cdFx0XHRcdHVubWF0Y2hlZCA9IHNlZWQgJiYgW10sXG5cdFx0XHRcdHNldE1hdGNoZWQgPSBbXSxcblx0XHRcdFx0Y29udGV4dEJhY2t1cCA9IG91dGVybW9zdENvbnRleHQsXG5cblx0XHRcdFx0Ly8gV2UgbXVzdCBhbHdheXMgaGF2ZSBlaXRoZXIgc2VlZCBlbGVtZW50cyBvciBvdXRlcm1vc3QgY29udGV4dFxuXHRcdFx0XHRlbGVtcyA9IHNlZWQgfHwgYnlFbGVtZW50ICYmIEV4cHIuZmluZFsgXCJUQUdcIiBdKCBcIipcIiwgb3V0ZXJtb3N0ICksXG5cblx0XHRcdFx0Ly8gVXNlIGludGVnZXIgZGlycnVucyBpZmYgdGhpcyBpcyB0aGUgb3V0ZXJtb3N0IG1hdGNoZXJcblx0XHRcdFx0ZGlycnVuc1VuaXF1ZSA9ICggZGlycnVucyArPSBjb250ZXh0QmFja3VwID09IG51bGwgPyAxIDogTWF0aC5yYW5kb20oKSB8fCAwLjEgKSxcblx0XHRcdFx0bGVuID0gZWxlbXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSssIEVkZ2UgMTcgLSAxOCtcblx0XHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHRcdC8vIHR3byBkb2N1bWVudHM7IHNoYWxsb3cgY29tcGFyaXNvbnMgd29yay5cblx0XHRcdFx0Ly8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGVxZXFlcVxuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dCA9PSBkb2N1bWVudCB8fCBjb250ZXh0IHx8IG91dGVybW9zdDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIGVsZW1lbnRzIHBhc3NpbmcgZWxlbWVudE1hdGNoZXJzIGRpcmVjdGx5IHRvIHJlc3VsdHNcblx0XHRcdC8vIFN1cHBvcnQ6IElFPDksIFNhZmFyaVxuXHRcdFx0Ly8gVG9sZXJhdGUgTm9kZUxpc3QgcHJvcGVydGllcyAoSUU6IFwibGVuZ3RoXCI7IFNhZmFyaTogPG51bWJlcj4pIG1hdGNoaW5nIGVsZW1lbnRzIGJ5IGlkXG5cdFx0XHRmb3IgKCA7IGkgIT09IGxlbiAmJiAoIGVsZW0gPSBlbGVtc1sgaSBdICkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGJ5RWxlbWVudCAmJiBlbGVtICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgMTErLCBFZGdlIDE3IC0gMTgrXG5cdFx0XHRcdFx0Ly8gSUUvRWRnZSBzb21ldGltZXMgdGhyb3cgYSBcIlBlcm1pc3Npb24gZGVuaWVkXCIgZXJyb3Igd2hlbiBzdHJpY3QtY29tcGFyaW5nXG5cdFx0XHRcdFx0Ly8gdHdvIGRvY3VtZW50czsgc2hhbGxvdyBjb21wYXJpc29ucyB3b3JrLlxuXHRcdFx0XHRcdC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBlcWVxZXFcblx0XHRcdFx0XHRpZiAoICFjb250ZXh0ICYmIGVsZW0ub3duZXJEb2N1bWVudCAhPSBkb2N1bWVudCApIHtcblx0XHRcdFx0XHRcdHNldERvY3VtZW50KCBlbGVtICk7XG5cdFx0XHRcdFx0XHR4bWwgPSAhZG9jdW1lbnRJc0hUTUw7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHdoaWxlICggKCBtYXRjaGVyID0gZWxlbWVudE1hdGNoZXJzWyBqKysgXSApICkge1xuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVyKCBlbGVtLCBjb250ZXh0IHx8IGRvY3VtZW50LCB4bWwgKSApIHtcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFRyYWNrIHVubWF0Y2hlZCBlbGVtZW50cyBmb3Igc2V0IGZpbHRlcnNcblx0XHRcdFx0aWYgKCBieVNldCApIHtcblxuXHRcdFx0XHRcdC8vIFRoZXkgd2lsbCBoYXZlIGdvbmUgdGhyb3VnaCBhbGwgcG9zc2libGUgbWF0Y2hlcnNcblx0XHRcdFx0XHRpZiAoICggZWxlbSA9ICFtYXRjaGVyICYmIGVsZW0gKSApIHtcblx0XHRcdFx0XHRcdG1hdGNoZWRDb3VudC0tO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIExlbmd0aGVuIHRoZSBhcnJheSBmb3IgZXZlcnkgZWxlbWVudCwgbWF0Y2hlZCBvciBub3Rcblx0XHRcdFx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBgaWAgaXMgbm93IHRoZSBjb3VudCBvZiBlbGVtZW50cyB2aXNpdGVkIGFib3ZlLCBhbmQgYWRkaW5nIGl0IHRvIGBtYXRjaGVkQ291bnRgXG5cdFx0XHQvLyBtYWtlcyB0aGUgbGF0dGVyIG5vbm5lZ2F0aXZlLlxuXHRcdFx0bWF0Y2hlZENvdW50ICs9IGk7XG5cblx0XHRcdC8vIEFwcGx5IHNldCBmaWx0ZXJzIHRvIHVubWF0Y2hlZCBlbGVtZW50c1xuXHRcdFx0Ly8gTk9URTogVGhpcyBjYW4gYmUgc2tpcHBlZCBpZiB0aGVyZSBhcmUgbm8gdW5tYXRjaGVkIGVsZW1lbnRzIChpLmUuLCBgbWF0Y2hlZENvdW50YFxuXHRcdFx0Ly8gZXF1YWxzIGBpYCksIHVubGVzcyB3ZSBkaWRuJ3QgdmlzaXQgX2FueV8gZWxlbWVudHMgaW4gdGhlIGFib3ZlIGxvb3AgYmVjYXVzZSB3ZSBoYXZlXG5cdFx0XHQvLyBubyBlbGVtZW50IG1hdGNoZXJzIGFuZCBubyBzZWVkLlxuXHRcdFx0Ly8gSW5jcmVtZW50aW5nIGFuIGluaXRpYWxseS1zdHJpbmcgXCIwXCIgYGlgIGFsbG93cyBgaWAgdG8gcmVtYWluIGEgc3RyaW5nIG9ubHkgaW4gdGhhdFxuXHRcdFx0Ly8gY2FzZSwgd2hpY2ggd2lsbCByZXN1bHQgaW4gYSBcIjAwXCIgYG1hdGNoZWRDb3VudGAgdGhhdCBkaWZmZXJzIGZyb20gYGlgIGJ1dCBpcyBhbHNvXG5cdFx0XHQvLyBudW1lcmljYWxseSB6ZXJvLlxuXHRcdFx0aWYgKCBieVNldCAmJiBpICE9PSBtYXRjaGVkQ291bnQgKSB7XG5cdFx0XHRcdGogPSAwO1xuXHRcdFx0XHR3aGlsZSAoICggbWF0Y2hlciA9IHNldE1hdGNoZXJzWyBqKysgXSApICkge1xuXHRcdFx0XHRcdG1hdGNoZXIoIHVubWF0Y2hlZCwgc2V0TWF0Y2hlZCwgY29udGV4dCwgeG1sICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRpZiAoIHNlZWQgKSB7XG5cblx0XHRcdFx0XHQvLyBSZWludGVncmF0ZSBlbGVtZW50IG1hdGNoZXMgdG8gZWxpbWluYXRlIHRoZSBuZWVkIGZvciBzb3J0aW5nXG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVkQ291bnQgPiAwICkge1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggISggdW5tYXRjaGVkWyBpIF0gfHwgc2V0TWF0Y2hlZFsgaSBdICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c2V0TWF0Y2hlZFsgaSBdID0gcG9wLmNhbGwoIHJlc3VsdHMgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIERpc2NhcmQgaW5kZXggcGxhY2Vob2xkZXIgdmFsdWVzIHRvIGdldCBvbmx5IGFjdHVhbCBtYXRjaGVzXG5cdFx0XHRcdFx0c2V0TWF0Y2hlZCA9IGNvbmRlbnNlKCBzZXRNYXRjaGVkICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBZGQgbWF0Y2hlcyB0byByZXN1bHRzXG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNldE1hdGNoZWQgKTtcblxuXHRcdFx0XHQvLyBTZWVkbGVzcyBzZXQgbWF0Y2hlcyBzdWNjZWVkaW5nIG11bHRpcGxlIHN1Y2Nlc3NmdWwgbWF0Y2hlcnMgc3RpcHVsYXRlIHNvcnRpbmdcblx0XHRcdFx0aWYgKCBvdXRlcm1vc3QgJiYgIXNlZWQgJiYgc2V0TWF0Y2hlZC5sZW5ndGggPiAwICYmXG5cdFx0XHRcdFx0KCBtYXRjaGVkQ291bnQgKyBzZXRNYXRjaGVycy5sZW5ndGggKSA+IDEgKSB7XG5cblx0XHRcdFx0XHRTaXp6bGUudW5pcXVlU29ydCggcmVzdWx0cyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIE92ZXJyaWRlIG1hbmlwdWxhdGlvbiBvZiBnbG9iYWxzIGJ5IG5lc3RlZCBtYXRjaGVyc1xuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdGRpcnJ1bnMgPSBkaXJydW5zVW5pcXVlO1xuXHRcdFx0XHRvdXRlcm1vc3RDb250ZXh0ID0gY29udGV4dEJhY2t1cDtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIHVubWF0Y2hlZDtcblx0XHR9O1xuXG5cdHJldHVybiBieVNldCA/XG5cdFx0bWFya0Z1bmN0aW9uKCBzdXBlck1hdGNoZXIgKSA6XG5cdFx0c3VwZXJNYXRjaGVyO1xufVxuXG5jb21waWxlID0gU2l6emxlLmNvbXBpbGUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIG1hdGNoIC8qIEludGVybmFsIFVzZSBPbmx5ICovICkge1xuXHR2YXIgaSxcblx0XHRzZXRNYXRjaGVycyA9IFtdLFxuXHRcdGVsZW1lbnRNYXRjaGVycyA9IFtdLFxuXHRcdGNhY2hlZCA9IGNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXTtcblxuXHRpZiAoICFjYWNoZWQgKSB7XG5cblx0XHQvLyBHZW5lcmF0ZSBhIGZ1bmN0aW9uIG9mIHJlY3Vyc2l2ZSBmdW5jdGlvbnMgdGhhdCBjYW4gYmUgdXNlZCB0byBjaGVjayBlYWNoIGVsZW1lbnRcblx0XHRpZiAoICFtYXRjaCApIHtcblx0XHRcdG1hdGNoID0gdG9rZW5pemUoIHNlbGVjdG9yICk7XG5cdFx0fVxuXHRcdGkgPSBtYXRjaC5sZW5ndGg7XG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRjYWNoZWQgPSBtYXRjaGVyRnJvbVRva2VucyggbWF0Y2hbIGkgXSApO1xuXHRcdFx0aWYgKCBjYWNoZWRbIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0c2V0TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlbGVtZW50TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FjaGUgdGhlIGNvbXBpbGVkIGZ1bmN0aW9uXG5cdFx0Y2FjaGVkID0gY29tcGlsZXJDYWNoZShcblx0XHRcdHNlbGVjdG9yLFxuXHRcdFx0bWF0Y2hlckZyb21Hcm91cE1hdGNoZXJzKCBlbGVtZW50TWF0Y2hlcnMsIHNldE1hdGNoZXJzIClcblx0XHQpO1xuXG5cdFx0Ly8gU2F2ZSBzZWxlY3RvciBhbmQgdG9rZW5pemF0aW9uXG5cdFx0Y2FjaGVkLnNlbGVjdG9yID0gc2VsZWN0b3I7XG5cdH1cblx0cmV0dXJuIGNhY2hlZDtcbn07XG5cbi8qKlxuICogQSBsb3ctbGV2ZWwgc2VsZWN0aW9uIGZ1bmN0aW9uIHRoYXQgd29ya3Mgd2l0aCBTaXp6bGUncyBjb21waWxlZFxuICogIHNlbGVjdG9yIGZ1bmN0aW9uc1xuICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHNlbGVjdG9yIEEgc2VsZWN0b3Igb3IgYSBwcmUtY29tcGlsZWRcbiAqICBzZWxlY3RvciBmdW5jdGlvbiBidWlsdCB3aXRoIFNpenpsZS5jb21waWxlXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGNvbnRleHRcbiAqIEBwYXJhbSB7QXJyYXl9IFtyZXN1bHRzXVxuICogQHBhcmFtIHtBcnJheX0gW3NlZWRdIEEgc2V0IG9mIGVsZW1lbnRzIHRvIG1hdGNoIGFnYWluc3RcbiAqL1xuc2VsZWN0ID0gU2l6emxlLnNlbGVjdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcblx0dmFyIGksIHRva2VucywgdG9rZW4sIHR5cGUsIGZpbmQsXG5cdFx0Y29tcGlsZWQgPSB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiAmJiBzZWxlY3Rvcixcblx0XHRtYXRjaCA9ICFzZWVkICYmIHRva2VuaXplKCAoIHNlbGVjdG9yID0gY29tcGlsZWQuc2VsZWN0b3IgfHwgc2VsZWN0b3IgKSApO1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFRyeSB0byBtaW5pbWl6ZSBvcGVyYXRpb25zIGlmIHRoZXJlIGlzIG9ubHkgb25lIHNlbGVjdG9yIGluIHRoZSBsaXN0IGFuZCBubyBzZWVkXG5cdC8vICh0aGUgbGF0dGVyIG9mIHdoaWNoIGd1YXJhbnRlZXMgdXMgY29udGV4dClcblx0aWYgKCBtYXRjaC5sZW5ndGggPT09IDEgKSB7XG5cblx0XHQvLyBSZWR1Y2UgY29udGV4dCBpZiB0aGUgbGVhZGluZyBjb21wb3VuZCBzZWxlY3RvciBpcyBhbiBJRFxuXHRcdHRva2VucyA9IG1hdGNoWyAwIF0gPSBtYXRjaFsgMCBdLnNsaWNlKCAwICk7XG5cdFx0aWYgKCB0b2tlbnMubGVuZ3RoID4gMiAmJiAoIHRva2VuID0gdG9rZW5zWyAwIF0gKS50eXBlID09PSBcIklEXCIgJiZcblx0XHRcdGNvbnRleHQubm9kZVR5cGUgPT09IDkgJiYgZG9jdW1lbnRJc0hUTUwgJiYgRXhwci5yZWxhdGl2ZVsgdG9rZW5zWyAxIF0udHlwZSBdICkge1xuXG5cdFx0XHRjb250ZXh0ID0gKCBFeHByLmZpbmRbIFwiSURcIiBdKCB0b2tlbi5tYXRjaGVzWyAwIF1cblx0XHRcdFx0LnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICksIGNvbnRleHQgKSB8fCBbXSApWyAwIF07XG5cdFx0XHRpZiAoICFjb250ZXh0ICkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0Ly8gUHJlY29tcGlsZWQgbWF0Y2hlcnMgd2lsbCBzdGlsbCB2ZXJpZnkgYW5jZXN0cnksIHNvIHN0ZXAgdXAgYSBsZXZlbFxuXHRcdFx0fSBlbHNlIGlmICggY29tcGlsZWQgKSB7XG5cdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0LnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cblx0XHRcdHNlbGVjdG9yID0gc2VsZWN0b3Iuc2xpY2UoIHRva2Vucy5zaGlmdCgpLnZhbHVlLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZldGNoIGEgc2VlZCBzZXQgZm9yIHJpZ2h0LXRvLWxlZnQgbWF0Y2hpbmdcblx0XHRpID0gbWF0Y2hFeHByWyBcIm5lZWRzQ29udGV4dFwiIF0udGVzdCggc2VsZWN0b3IgKSA/IDAgOiB0b2tlbnMubGVuZ3RoO1xuXHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0dG9rZW4gPSB0b2tlbnNbIGkgXTtcblxuXHRcdFx0Ly8gQWJvcnQgaWYgd2UgaGl0IGEgY29tYmluYXRvclxuXHRcdFx0aWYgKCBFeHByLnJlbGF0aXZlWyAoIHR5cGUgPSB0b2tlbi50eXBlICkgXSApIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoICggZmluZCA9IEV4cHIuZmluZFsgdHlwZSBdICkgKSB7XG5cblx0XHRcdFx0Ly8gU2VhcmNoLCBleHBhbmRpbmcgY29udGV4dCBmb3IgbGVhZGluZyBzaWJsaW5nIGNvbWJpbmF0b3JzXG5cdFx0XHRcdGlmICggKCBzZWVkID0gZmluZChcblx0XHRcdFx0XHR0b2tlbi5tYXRjaGVzWyAwIF0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKSxcblx0XHRcdFx0XHRyc2libGluZy50ZXN0KCB0b2tlbnNbIDAgXS50eXBlICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8XG5cdFx0XHRcdFx0XHRjb250ZXh0XG5cdFx0XHRcdCkgKSApIHtcblxuXHRcdFx0XHRcdC8vIElmIHNlZWQgaXMgZW1wdHkgb3Igbm8gdG9rZW5zIHJlbWFpbiwgd2UgY2FuIHJldHVybiBlYXJseVxuXHRcdFx0XHRcdHRva2Vucy5zcGxpY2UoIGksIDEgKTtcblx0XHRcdFx0XHRzZWxlY3RvciA9IHNlZWQubGVuZ3RoICYmIHRvU2VsZWN0b3IoIHRva2VucyApO1xuXHRcdFx0XHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2VlZCApO1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBDb21waWxlIGFuZCBleGVjdXRlIGEgZmlsdGVyaW5nIGZ1bmN0aW9uIGlmIG9uZSBpcyBub3QgcHJvdmlkZWRcblx0Ly8gUHJvdmlkZSBgbWF0Y2hgIHRvIGF2b2lkIHJldG9rZW5pemF0aW9uIGlmIHdlIG1vZGlmaWVkIHRoZSBzZWxlY3RvciBhYm92ZVxuXHQoIGNvbXBpbGVkIHx8IGNvbXBpbGUoIHNlbGVjdG9yLCBtYXRjaCApICkoXG5cdFx0c2VlZCxcblx0XHRjb250ZXh0LFxuXHRcdCFkb2N1bWVudElzSFRNTCxcblx0XHRyZXN1bHRzLFxuXHRcdCFjb250ZXh0IHx8IHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcblx0KTtcblx0cmV0dXJuIHJlc3VsdHM7XG59O1xuXG4vLyBPbmUtdGltZSBhc3NpZ25tZW50c1xuXG4vLyBTb3J0IHN0YWJpbGl0eVxuc3VwcG9ydC5zb3J0U3RhYmxlID0gZXhwYW5kby5zcGxpdCggXCJcIiApLnNvcnQoIHNvcnRPcmRlciApLmpvaW4oIFwiXCIgKSA9PT0gZXhwYW5kbztcblxuLy8gU3VwcG9ydDogQ2hyb21lIDE0LTM1K1xuLy8gQWx3YXlzIGFzc3VtZSBkdXBsaWNhdGVzIGlmIHRoZXkgYXJlbid0IHBhc3NlZCB0byB0aGUgY29tcGFyaXNvbiBmdW5jdGlvblxuc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzID0gISFoYXNEdXBsaWNhdGU7XG5cbi8vIEluaXRpYWxpemUgYWdhaW5zdCB0aGUgZGVmYXVsdCBkb2N1bWVudFxuc2V0RG9jdW1lbnQoKTtcblxuLy8gU3VwcG9ydDogV2Via2l0PDUzNy4zMiAtIFNhZmFyaSA2LjAuMy9DaHJvbWUgMjUgKGZpeGVkIGluIENocm9tZSAyNylcbi8vIERldGFjaGVkIG5vZGVzIGNvbmZvdW5kaW5nbHkgZm9sbG93ICplYWNoIG90aGVyKlxuc3VwcG9ydC5zb3J0RGV0YWNoZWQgPSBhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblxuXHQvLyBTaG91bGQgcmV0dXJuIDEsIGJ1dCByZXR1cm5zIDQgKGZvbGxvd2luZylcblx0cmV0dXJuIGVsLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImZpZWxkc2V0XCIgKSApICYgMTtcbn0gKTtcblxuLy8gU3VwcG9ydDogSUU8OFxuLy8gUHJldmVudCBhdHRyaWJ1dGUvcHJvcGVydHkgXCJpbnRlcnBvbGF0aW9uXCJcbi8vIGh0dHBzOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvbXM1MzY0MjklMjhWUy44NSUyOS5hc3B4XG5pZiAoICFhc3NlcnQoIGZ1bmN0aW9uKCBlbCApIHtcblx0ZWwuaW5uZXJIVE1MID0gXCI8YSBocmVmPScjJz48L2E+XCI7XG5cdHJldHVybiBlbC5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSggXCJocmVmXCIgKSA9PT0gXCIjXCI7XG59ICkgKSB7XG5cdGFkZEhhbmRsZSggXCJ0eXBlfGhyZWZ8aGVpZ2h0fHdpZHRoXCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSwgbmFtZS50b0xvd2VyQ2FzZSgpID09PSBcInR5cGVcIiA/IDEgOiAyICk7XG5cdFx0fVxuXHR9ICk7XG59XG5cbi8vIFN1cHBvcnQ6IElFPDlcbi8vIFVzZSBkZWZhdWx0VmFsdWUgaW4gcGxhY2Ugb2YgZ2V0QXR0cmlidXRlKFwidmFsdWVcIilcbmlmICggIXN1cHBvcnQuYXR0cmlidXRlcyB8fCAhYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdGVsLmlubmVySFRNTCA9IFwiPGlucHV0Lz5cIjtcblx0ZWwuZmlyc3RDaGlsZC5zZXRBdHRyaWJ1dGUoIFwidmFsdWVcIiwgXCJcIiApO1xuXHRyZXR1cm4gZWwuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoIFwidmFsdWVcIiApID09PSBcIlwiO1xufSApICkge1xuXHRhZGRIYW5kbGUoIFwidmFsdWVcIiwgZnVuY3Rpb24oIGVsZW0sIF9uYW1lLCBpc1hNTCApIHtcblx0XHRpZiAoICFpc1hNTCAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiApIHtcblx0XHRcdHJldHVybiBlbGVtLmRlZmF1bHRWYWx1ZTtcblx0XHR9XG5cdH0gKTtcbn1cblxuLy8gU3VwcG9ydDogSUU8OVxuLy8gVXNlIGdldEF0dHJpYnV0ZU5vZGUgdG8gZmV0Y2ggYm9vbGVhbnMgd2hlbiBnZXRBdHRyaWJ1dGUgbGllc1xuaWYgKCAhYXNzZXJ0KCBmdW5jdGlvbiggZWwgKSB7XG5cdHJldHVybiBlbC5nZXRBdHRyaWJ1dGUoIFwiZGlzYWJsZWRcIiApID09IG51bGw7XG59ICkgKSB7XG5cdGFkZEhhbmRsZSggYm9vbGVhbnMsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHR2YXIgdmFsO1xuXHRcdGlmICggIWlzWE1MICkge1xuXHRcdFx0cmV0dXJuIGVsZW1bIG5hbWUgXSA9PT0gdHJ1ZSA/IG5hbWUudG9Mb3dlckNhc2UoKSA6XG5cdFx0XHRcdCggdmFsID0gZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKCBuYW1lICkgKSAmJiB2YWwuc3BlY2lmaWVkID9cblx0XHRcdFx0XHR2YWwudmFsdWUgOlxuXHRcdFx0XHRcdG51bGw7XG5cdFx0fVxuXHR9ICk7XG59XG5cbnJldHVybiBTaXp6bGU7XG5cbn0gKSggd2luZG93ICk7XG5cblxuXG5qUXVlcnkuZmluZCA9IFNpenpsZTtcbmpRdWVyeS5leHByID0gU2l6emxlLnNlbGVjdG9ycztcblxuLy8gRGVwcmVjYXRlZFxualF1ZXJ5LmV4cHJbIFwiOlwiIF0gPSBqUXVlcnkuZXhwci5wc2V1ZG9zO1xualF1ZXJ5LnVuaXF1ZVNvcnQgPSBqUXVlcnkudW5pcXVlID0gU2l6emxlLnVuaXF1ZVNvcnQ7XG5qUXVlcnkudGV4dCA9IFNpenpsZS5nZXRUZXh0O1xualF1ZXJ5LmlzWE1MRG9jID0gU2l6emxlLmlzWE1MO1xualF1ZXJ5LmNvbnRhaW5zID0gU2l6emxlLmNvbnRhaW5zO1xualF1ZXJ5LmVzY2FwZVNlbGVjdG9yID0gU2l6emxlLmVzY2FwZTtcblxuXG5cblxudmFyIGRpciA9IGZ1bmN0aW9uKCBlbGVtLCBkaXIsIHVudGlsICkge1xuXHR2YXIgbWF0Y2hlZCA9IFtdLFxuXHRcdHRydW5jYXRlID0gdW50aWwgIT09IHVuZGVmaW5lZDtcblxuXHR3aGlsZSAoICggZWxlbSA9IGVsZW1bIGRpciBdICkgJiYgZWxlbS5ub2RlVHlwZSAhPT0gOSApIHtcblx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRpZiAoIHRydW5jYXRlICYmIGpRdWVyeSggZWxlbSApLmlzKCB1bnRpbCApICkge1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHRcdG1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gbWF0Y2hlZDtcbn07XG5cblxudmFyIHNpYmxpbmdzID0gZnVuY3Rpb24oIG4sIGVsZW0gKSB7XG5cdHZhciBtYXRjaGVkID0gW107XG5cblx0Zm9yICggOyBuOyBuID0gbi5uZXh0U2libGluZyApIHtcblx0XHRpZiAoIG4ubm9kZVR5cGUgPT09IDEgJiYgbiAhPT0gZWxlbSApIHtcblx0XHRcdG1hdGNoZWQucHVzaCggbiApO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBtYXRjaGVkO1xufTtcblxuXG52YXIgcm5lZWRzQ29udGV4dCA9IGpRdWVyeS5leHByLm1hdGNoLm5lZWRzQ29udGV4dDtcblxuXG5cbmZ1bmN0aW9uIG5vZGVOYW1lKCBlbGVtLCBuYW1lICkge1xuXG4gIHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpO1xuXG59O1xudmFyIHJzaW5nbGVUYWcgPSAoIC9ePChbYS16XVteXFwvXFwwPjpcXHgyMFxcdFxcclxcblxcZl0qKVtcXHgyMFxcdFxcclxcblxcZl0qXFwvPz4oPzo8XFwvXFwxPnwpJC9pICk7XG5cblxuXG4vLyBJbXBsZW1lbnQgdGhlIGlkZW50aWNhbCBmdW5jdGlvbmFsaXR5IGZvciBmaWx0ZXIgYW5kIG5vdFxuZnVuY3Rpb24gd2lubm93KCBlbGVtZW50cywgcXVhbGlmaWVyLCBub3QgKSB7XG5cdGlmICggaXNGdW5jdGlvbiggcXVhbGlmaWVyICkgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0sIGkgKSB7XG5cdFx0XHRyZXR1cm4gISFxdWFsaWZpZXIuY2FsbCggZWxlbSwgaSwgZWxlbSApICE9PSBub3Q7XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gU2luZ2xlIGVsZW1lbnRcblx0aWYgKCBxdWFsaWZpZXIubm9kZVR5cGUgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBlbGVtID09PSBxdWFsaWZpZXIgKSAhPT0gbm90O1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIEFycmF5bGlrZSBvZiBlbGVtZW50cyAoalF1ZXJ5LCBhcmd1bWVudHMsIEFycmF5KVxuXHRpZiAoIHR5cGVvZiBxdWFsaWZpZXIgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gKCBpbmRleE9mLmNhbGwoIHF1YWxpZmllciwgZWxlbSApID4gLTEgKSAhPT0gbm90O1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIEZpbHRlcmVkIGRpcmVjdGx5IGZvciBib3RoIHNpbXBsZSBhbmQgY29tcGxleCBzZWxlY3RvcnNcblx0cmV0dXJuIGpRdWVyeS5maWx0ZXIoIHF1YWxpZmllciwgZWxlbWVudHMsIG5vdCApO1xufVxuXG5qUXVlcnkuZmlsdGVyID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1zLCBub3QgKSB7XG5cdHZhciBlbGVtID0gZWxlbXNbIDAgXTtcblxuXHRpZiAoIG5vdCApIHtcblx0XHRleHByID0gXCI6bm90KFwiICsgZXhwciArIFwiKVwiO1xuXHR9XG5cblx0aWYgKCBlbGVtcy5sZW5ndGggPT09IDEgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKCBlbGVtLCBleHByICkgPyBbIGVsZW0gXSA6IFtdO1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeS5maW5kLm1hdGNoZXMoIGV4cHIsIGpRdWVyeS5ncmVwKCBlbGVtcywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGVsZW0ubm9kZVR5cGUgPT09IDE7XG5cdH0gKSApO1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRmaW5kOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGksIHJldCxcblx0XHRcdGxlbiA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0c2VsZiA9IHRoaXM7XG5cblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5KCBzZWxlY3RvciApLmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdFx0aWYgKCBqUXVlcnkuY29udGFpbnMoIHNlbGZbIGkgXSwgdGhpcyApICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9ICkgKTtcblx0XHR9XG5cblx0XHRyZXQgPSB0aGlzLnB1c2hTdGFjayggW10gKTtcblxuXHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRqUXVlcnkuZmluZCggc2VsZWN0b3IsIHNlbGZbIGkgXSwgcmV0ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGxlbiA+IDEgPyBqUXVlcnkudW5pcXVlU29ydCggcmV0ICkgOiByZXQ7XG5cdH0sXG5cdGZpbHRlcjogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggd2lubm93KCB0aGlzLCBzZWxlY3RvciB8fCBbXSwgZmFsc2UgKSApO1xuXHR9LFxuXHRub3Q6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyggdGhpcywgc2VsZWN0b3IgfHwgW10sIHRydWUgKSApO1xuXHR9LFxuXHRpczogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHJldHVybiAhIXdpbm5vdyhcblx0XHRcdHRoaXMsXG5cblx0XHRcdC8vIElmIHRoaXMgaXMgYSBwb3NpdGlvbmFsL3JlbGF0aXZlIHNlbGVjdG9yLCBjaGVjayBtZW1iZXJzaGlwIGluIHRoZSByZXR1cm5lZCBzZXRcblx0XHRcdC8vIHNvICQoXCJwOmZpcnN0XCIpLmlzKFwicDpsYXN0XCIpIHdvbid0IHJldHVybiB0cnVlIGZvciBhIGRvYyB3aXRoIHR3byBcInBcIi5cblx0XHRcdHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiAmJiBybmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9yICkgP1xuXHRcdFx0XHRqUXVlcnkoIHNlbGVjdG9yICkgOlxuXHRcdFx0XHRzZWxlY3RvciB8fCBbXSxcblx0XHRcdGZhbHNlXG5cdFx0KS5sZW5ndGg7XG5cdH1cbn0gKTtcblxuXG4vLyBJbml0aWFsaXplIGEgalF1ZXJ5IG9iamVjdFxuXG5cbi8vIEEgY2VudHJhbCByZWZlcmVuY2UgdG8gdGhlIHJvb3QgalF1ZXJ5KGRvY3VtZW50KVxudmFyIHJvb3RqUXVlcnksXG5cblx0Ly8gQSBzaW1wbGUgd2F5IHRvIGNoZWNrIGZvciBIVE1MIHN0cmluZ3Ncblx0Ly8gUHJpb3JpdGl6ZSAjaWQgb3ZlciA8dGFnPiB0byBhdm9pZCBYU1MgdmlhIGxvY2F0aW9uLmhhc2ggKCM5NTIxKVxuXHQvLyBTdHJpY3QgSFRNTCByZWNvZ25pdGlvbiAoIzExMjkwOiBtdXN0IHN0YXJ0IHdpdGggPClcblx0Ly8gU2hvcnRjdXQgc2ltcGxlICNpZCBjYXNlIGZvciBzcGVlZFxuXHRycXVpY2tFeHByID0gL14oPzpcXHMqKDxbXFx3XFxXXSs+KVtePl0qfCMoW1xcdy1dKykpJC8sXG5cblx0aW5pdCA9IGpRdWVyeS5mbi5pbml0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0LCByb290ICkge1xuXHRcdHZhciBtYXRjaCwgZWxlbTtcblxuXHRcdC8vIEhBTkRMRTogJChcIlwiKSwgJChudWxsKSwgJCh1bmRlZmluZWQpLCAkKGZhbHNlKVxuXHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Ly8gTWV0aG9kIGluaXQoKSBhY2NlcHRzIGFuIGFsdGVybmF0ZSByb290alF1ZXJ5XG5cdFx0Ly8gc28gbWlncmF0ZSBjYW4gc3VwcG9ydCBqUXVlcnkuc3ViIChnaC0yMTAxKVxuXHRcdHJvb3QgPSByb290IHx8IHJvb3RqUXVlcnk7XG5cblx0XHQvLyBIYW5kbGUgSFRNTCBzdHJpbmdzXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRpZiAoIHNlbGVjdG9yWyAwIF0gPT09IFwiPFwiICYmXG5cdFx0XHRcdHNlbGVjdG9yWyBzZWxlY3Rvci5sZW5ndGggLSAxIF0gPT09IFwiPlwiICYmXG5cdFx0XHRcdHNlbGVjdG9yLmxlbmd0aCA+PSAzICkge1xuXG5cdFx0XHRcdC8vIEFzc3VtZSB0aGF0IHN0cmluZ3MgdGhhdCBzdGFydCBhbmQgZW5kIHdpdGggPD4gYXJlIEhUTUwgYW5kIHNraXAgdGhlIHJlZ2V4IGNoZWNrXG5cdFx0XHRcdG1hdGNoID0gWyBudWxsLCBzZWxlY3RvciwgbnVsbCBdO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWF0Y2ggaHRtbCBvciBtYWtlIHN1cmUgbm8gY29udGV4dCBpcyBzcGVjaWZpZWQgZm9yICNpZFxuXHRcdFx0aWYgKCBtYXRjaCAmJiAoIG1hdGNoWyAxIF0gfHwgIWNvbnRleHQgKSApIHtcblxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoaHRtbCkgLT4gJChhcnJheSlcblx0XHRcdFx0aWYgKCBtYXRjaFsgMSBdICkge1xuXHRcdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0IGluc3RhbmNlb2YgalF1ZXJ5ID8gY29udGV4dFsgMCBdIDogY29udGV4dDtcblxuXHRcdFx0XHRcdC8vIE9wdGlvbiB0byBydW4gc2NyaXB0cyBpcyB0cnVlIGZvciBiYWNrLWNvbXBhdFxuXHRcdFx0XHRcdC8vIEludGVudGlvbmFsbHkgbGV0IHRoZSBlcnJvciBiZSB0aHJvd24gaWYgcGFyc2VIVE1MIGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLCBqUXVlcnkucGFyc2VIVE1MKFxuXHRcdFx0XHRcdFx0bWF0Y2hbIDEgXSxcblx0XHRcdFx0XHRcdGNvbnRleHQgJiYgY29udGV4dC5ub2RlVHlwZSA/IGNvbnRleHQub3duZXJEb2N1bWVudCB8fCBjb250ZXh0IDogZG9jdW1lbnQsXG5cdFx0XHRcdFx0XHR0cnVlXG5cdFx0XHRcdFx0KSApO1xuXG5cdFx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwsIHByb3BzKVxuXHRcdFx0XHRcdGlmICggcnNpbmdsZVRhZy50ZXN0KCBtYXRjaFsgMSBdICkgJiYgalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGNvbnRleHQgKSApIHtcblx0XHRcdFx0XHRcdGZvciAoIG1hdGNoIGluIGNvbnRleHQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gUHJvcGVydGllcyBvZiBjb250ZXh0IGFyZSBjYWxsZWQgYXMgbWV0aG9kcyBpZiBwb3NzaWJsZVxuXHRcdFx0XHRcdFx0XHRpZiAoIGlzRnVuY3Rpb24oIHRoaXNbIG1hdGNoIF0gKSApIHtcblx0XHRcdFx0XHRcdFx0XHR0aGlzWyBtYXRjaCBdKCBjb250ZXh0WyBtYXRjaCBdICk7XG5cblx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIG90aGVyd2lzZSBzZXQgYXMgYXR0cmlidXRlc1xuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXMuYXR0ciggbWF0Y2gsIGNvbnRleHRbIG1hdGNoIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXG5cdFx0XHRcdC8vIEhBTkRMRTogJCgjaWQpXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0ZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtYXRjaFsgMiBdICk7XG5cblx0XHRcdFx0XHRpZiAoIGVsZW0gKSB7XG5cblx0XHRcdFx0XHRcdC8vIEluamVjdCB0aGUgZWxlbWVudCBkaXJlY3RseSBpbnRvIHRoZSBqUXVlcnkgb2JqZWN0XG5cdFx0XHRcdFx0XHR0aGlzWyAwIF0gPSBlbGVtO1xuXHRcdFx0XHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBIQU5ETEU6ICQoZXhwciwgJCguLi4pKVxuXHRcdFx0fSBlbHNlIGlmICggIWNvbnRleHQgfHwgY29udGV4dC5qcXVlcnkgKSB7XG5cdFx0XHRcdHJldHVybiAoIGNvbnRleHQgfHwgcm9vdCApLmZpbmQoIHNlbGVjdG9yICk7XG5cblx0XHRcdC8vIEhBTkRMRTogJChleHByLCBjb250ZXh0KVxuXHRcdFx0Ly8gKHdoaWNoIGlzIGp1c3QgZXF1aXZhbGVudCB0bzogJChjb250ZXh0KS5maW5kKGV4cHIpXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gdGhpcy5jb25zdHJ1Y3RvciggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yICk7XG5cdFx0XHR9XG5cblx0XHQvLyBIQU5ETEU6ICQoRE9NRWxlbWVudClcblx0XHR9IGVsc2UgaWYgKCBzZWxlY3Rvci5ub2RlVHlwZSApIHtcblx0XHRcdHRoaXNbIDAgXSA9IHNlbGVjdG9yO1xuXHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHQvLyBIQU5ETEU6ICQoZnVuY3Rpb24pXG5cdFx0Ly8gU2hvcnRjdXQgZm9yIGRvY3VtZW50IHJlYWR5XG5cdFx0fSBlbHNlIGlmICggaXNGdW5jdGlvbiggc2VsZWN0b3IgKSApIHtcblx0XHRcdHJldHVybiByb290LnJlYWR5ICE9PSB1bmRlZmluZWQgP1xuXHRcdFx0XHRyb290LnJlYWR5KCBzZWxlY3RvciApIDpcblxuXHRcdFx0XHQvLyBFeGVjdXRlIGltbWVkaWF0ZWx5IGlmIHJlYWR5IGlzIG5vdCBwcmVzZW50XG5cdFx0XHRcdHNlbGVjdG9yKCBqUXVlcnkgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5Lm1ha2VBcnJheSggc2VsZWN0b3IsIHRoaXMgKTtcblx0fTtcblxuLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvblxuaW5pdC5wcm90b3R5cGUgPSBqUXVlcnkuZm47XG5cbi8vIEluaXRpYWxpemUgY2VudHJhbCByZWZlcmVuY2VcbnJvb3RqUXVlcnkgPSBqUXVlcnkoIGRvY3VtZW50ICk7XG5cblxudmFyIHJwYXJlbnRzcHJldiA9IC9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLFxuXG5cdC8vIE1ldGhvZHMgZ3VhcmFudGVlZCB0byBwcm9kdWNlIGEgdW5pcXVlIHNldCB3aGVuIHN0YXJ0aW5nIGZyb20gYSB1bmlxdWUgc2V0XG5cdGd1YXJhbnRlZWRVbmlxdWUgPSB7XG5cdFx0Y2hpbGRyZW46IHRydWUsXG5cdFx0Y29udGVudHM6IHRydWUsXG5cdFx0bmV4dDogdHJ1ZSxcblx0XHRwcmV2OiB0cnVlXG5cdH07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0aGFzOiBmdW5jdGlvbiggdGFyZ2V0ICkge1xuXHRcdHZhciB0YXJnZXRzID0galF1ZXJ5KCB0YXJnZXQsIHRoaXMgKSxcblx0XHRcdGwgPSB0YXJnZXRzLmxlbmd0aDtcblxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgaSA9IDA7XG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggalF1ZXJ5LmNvbnRhaW5zKCB0aGlzLCB0YXJnZXRzWyBpIF0gKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRjbG9zZXN0OiBmdW5jdGlvbiggc2VsZWN0b3JzLCBjb250ZXh0ICkge1xuXHRcdHZhciBjdXIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aCxcblx0XHRcdG1hdGNoZWQgPSBbXSxcblx0XHRcdHRhcmdldHMgPSB0eXBlb2Ygc2VsZWN0b3JzICE9PSBcInN0cmluZ1wiICYmIGpRdWVyeSggc2VsZWN0b3JzICk7XG5cblx0XHQvLyBQb3NpdGlvbmFsIHNlbGVjdG9ycyBuZXZlciBtYXRjaCwgc2luY2UgdGhlcmUncyBubyBfc2VsZWN0aW9uXyBjb250ZXh0XG5cdFx0aWYgKCAhcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvcnMgKSApIHtcblx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0Zm9yICggY3VyID0gdGhpc1sgaSBdOyBjdXIgJiYgY3VyICE9PSBjb250ZXh0OyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblxuXHRcdFx0XHRcdC8vIEFsd2F5cyBza2lwIGRvY3VtZW50IGZyYWdtZW50c1xuXHRcdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKCB0YXJnZXRzID9cblx0XHRcdFx0XHRcdHRhcmdldHMuaW5kZXgoIGN1ciApID4gLTEgOlxuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGVcblx0XHRcdFx0XHRcdGN1ci5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGN1ciwgc2VsZWN0b3JzICkgKSApIHtcblxuXHRcdFx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZC5sZW5ndGggPiAxID8galF1ZXJ5LnVuaXF1ZVNvcnQoIG1hdGNoZWQgKSA6IG1hdGNoZWQgKTtcblx0fSxcblxuXHQvLyBEZXRlcm1pbmUgdGhlIHBvc2l0aW9uIG9mIGFuIGVsZW1lbnQgd2l0aGluIHRoZSBzZXRcblx0aW5kZXg6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gTm8gYXJndW1lbnQsIHJldHVybiBpbmRleCBpbiBwYXJlbnRcblx0XHRpZiAoICFlbGVtICkge1xuXHRcdFx0cmV0dXJuICggdGhpc1sgMCBdICYmIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xuXHRcdH1cblxuXHRcdC8vIEluZGV4IGluIHNlbGVjdG9yXG5cdFx0aWYgKCB0eXBlb2YgZWxlbSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGpRdWVyeSggZWxlbSApLCB0aGlzWyAwIF0gKTtcblx0XHR9XG5cblx0XHQvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnRcblx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLFxuXG5cdFx0XHQvLyBJZiBpdCByZWNlaXZlcyBhIGpRdWVyeSBvYmplY3QsIHRoZSBmaXJzdCBlbGVtZW50IGlzIHVzZWRcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbVxuXHRcdCk7XG5cdH0sXG5cblx0YWRkOiBmdW5jdGlvbiggc2VsZWN0b3IsIGNvbnRleHQgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKFxuXHRcdFx0alF1ZXJ5LnVuaXF1ZVNvcnQoXG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcy5nZXQoKSwgalF1ZXJ5KCBzZWxlY3RvciwgY29udGV4dCApIClcblx0XHRcdClcblx0XHQpO1xuXHR9LFxuXG5cdGFkZEJhY2s6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5hZGQoIHNlbGVjdG9yID09IG51bGwgP1xuXHRcdFx0dGhpcy5wcmV2T2JqZWN0IDogdGhpcy5wcmV2T2JqZWN0LmZpbHRlciggc2VsZWN0b3IgKVxuXHRcdCk7XG5cdH1cbn0gKTtcblxuZnVuY3Rpb24gc2libGluZyggY3VyLCBkaXIgKSB7XG5cdHdoaWxlICggKCBjdXIgPSBjdXJbIGRpciBdICkgJiYgY3VyLm5vZGVUeXBlICE9PSAxICkge31cblx0cmV0dXJuIGN1cjtcbn1cblxualF1ZXJ5LmVhY2goIHtcblx0cGFyZW50OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlICE9PSAxMSA/IHBhcmVudCA6IG51bGw7XG5cdH0sXG5cdHBhcmVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiICk7XG5cdH0sXG5cdHBhcmVudHNVbnRpbDogZnVuY3Rpb24oIGVsZW0sIF9pLCB1bnRpbCApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcInBhcmVudE5vZGVcIiwgdW50aWwgKTtcblx0fSxcblx0bmV4dDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIHNpYmxpbmcoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xuXHR9LFxuXHRwcmV2OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIgKTtcblx0fSxcblx0cHJldkFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiApO1xuXHR9LFxuXHRuZXh0VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBfaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJuZXh0U2libGluZ1wiLCB1bnRpbCApO1xuXHR9LFxuXHRwcmV2VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBfaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0c2libGluZ3M6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5ncyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7XG5cdH0sXG5cdGNoaWxkcmVuOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZ3MoIGVsZW0uZmlyc3RDaGlsZCApO1xuXHR9LFxuXHRjb250ZW50czogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0aWYgKCBlbGVtLmNvbnRlbnREb2N1bWVudCAhPSBudWxsICYmXG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDExK1xuXHRcdFx0Ly8gPG9iamVjdD4gZWxlbWVudHMgd2l0aCBubyBgZGF0YWAgYXR0cmlidXRlIGhhcyBhbiBvYmplY3Rcblx0XHRcdC8vIGBjb250ZW50RG9jdW1lbnRgIHdpdGggYSBgbnVsbGAgcHJvdG90eXBlLlxuXHRcdFx0Z2V0UHJvdG8oIGVsZW0uY29udGVudERvY3VtZW50ICkgKSB7XG5cblx0XHRcdHJldHVybiBlbGVtLmNvbnRlbnREb2N1bWVudDtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTEgb25seSwgaU9TIDcgb25seSwgQW5kcm9pZCBCcm93c2VyIDw9NC4zIG9ubHlcblx0XHQvLyBUcmVhdCB0aGUgdGVtcGxhdGUgZWxlbWVudCBhcyBhIHJlZ3VsYXIgb25lIGluIGJyb3dzZXJzIHRoYXRcblx0XHQvLyBkb24ndCBzdXBwb3J0IGl0LlxuXHRcdGlmICggbm9kZU5hbWUoIGVsZW0sIFwidGVtcGxhdGVcIiApICkge1xuXHRcdFx0ZWxlbSA9IGVsZW0uY29udGVudCB8fCBlbGVtO1xuXHRcdH1cblxuXHRcdHJldHVybiBqUXVlcnkubWVyZ2UoIFtdLCBlbGVtLmNoaWxkTm9kZXMgKTtcblx0fVxufSwgZnVuY3Rpb24oIG5hbWUsIGZuICkge1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCB1bnRpbCwgc2VsZWN0b3IgKSB7XG5cdFx0dmFyIG1hdGNoZWQgPSBqUXVlcnkubWFwKCB0aGlzLCBmbiwgdW50aWwgKTtcblxuXHRcdGlmICggbmFtZS5zbGljZSggLTUgKSAhPT0gXCJVbnRpbFwiICkge1xuXHRcdFx0c2VsZWN0b3IgPSB1bnRpbDtcblx0XHR9XG5cblx0XHRpZiAoIHNlbGVjdG9yICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdG1hdGNoZWQgPSBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgbWF0Y2hlZCApO1xuXHRcdH1cblxuXHRcdGlmICggdGhpcy5sZW5ndGggPiAxICkge1xuXG5cdFx0XHQvLyBSZW1vdmUgZHVwbGljYXRlc1xuXHRcdFx0aWYgKCAhZ3VhcmFudGVlZFVuaXF1ZVsgbmFtZSBdICkge1xuXHRcdFx0XHRqUXVlcnkudW5pcXVlU29ydCggbWF0Y2hlZCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXZlcnNlIG9yZGVyIGZvciBwYXJlbnRzKiBhbmQgcHJldi1kZXJpdmF0aXZlc1xuXHRcdFx0aWYgKCBycGFyZW50c3ByZXYudGVzdCggbmFtZSApICkge1xuXHRcdFx0XHRtYXRjaGVkLnJldmVyc2UoKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIG1hdGNoZWQgKTtcblx0fTtcbn0gKTtcbnZhciBybm90aHRtbHdoaXRlID0gKCAvW15cXHgyMFxcdFxcclxcblxcZl0rL2cgKTtcblxuXG5cbi8vIENvbnZlcnQgU3RyaW5nLWZvcm1hdHRlZCBvcHRpb25zIGludG8gT2JqZWN0LWZvcm1hdHRlZCBvbmVzXG5mdW5jdGlvbiBjcmVhdGVPcHRpb25zKCBvcHRpb25zICkge1xuXHR2YXIgb2JqZWN0ID0ge307XG5cdGpRdWVyeS5lYWNoKCBvcHRpb25zLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW10sIGZ1bmN0aW9uKCBfLCBmbGFnICkge1xuXHRcdG9iamVjdFsgZmxhZyBdID0gdHJ1ZTtcblx0fSApO1xuXHRyZXR1cm4gb2JqZWN0O1xufVxuXG4vKlxuICogQ3JlYXRlIGEgY2FsbGJhY2sgbGlzdCB1c2luZyB0aGUgZm9sbG93aW5nIHBhcmFtZXRlcnM6XG4gKlxuICpcdG9wdGlvbnM6IGFuIG9wdGlvbmFsIGxpc3Qgb2Ygc3BhY2Utc2VwYXJhdGVkIG9wdGlvbnMgdGhhdCB3aWxsIGNoYW5nZSBob3dcbiAqXHRcdFx0dGhlIGNhbGxiYWNrIGxpc3QgYmVoYXZlcyBvciBhIG1vcmUgdHJhZGl0aW9uYWwgb3B0aW9uIG9iamVjdFxuICpcbiAqIEJ5IGRlZmF1bHQgYSBjYWxsYmFjayBsaXN0IHdpbGwgYWN0IGxpa2UgYW4gZXZlbnQgY2FsbGJhY2sgbGlzdCBhbmQgY2FuIGJlXG4gKiBcImZpcmVkXCIgbXVsdGlwbGUgdGltZXMuXG4gKlxuICogUG9zc2libGUgb3B0aW9uczpcbiAqXG4gKlx0b25jZTpcdFx0XHR3aWxsIGVuc3VyZSB0aGUgY2FsbGJhY2sgbGlzdCBjYW4gb25seSBiZSBmaXJlZCBvbmNlIChsaWtlIGEgRGVmZXJyZWQpXG4gKlxuICpcdG1lbW9yeTpcdFx0XHR3aWxsIGtlZXAgdHJhY2sgb2YgcHJldmlvdXMgdmFsdWVzIGFuZCB3aWxsIGNhbGwgYW55IGNhbGxiYWNrIGFkZGVkXG4gKlx0XHRcdFx0XHRhZnRlciB0aGUgbGlzdCBoYXMgYmVlbiBmaXJlZCByaWdodCBhd2F5IHdpdGggdGhlIGxhdGVzdCBcIm1lbW9yaXplZFwiXG4gKlx0XHRcdFx0XHR2YWx1ZXMgKGxpa2UgYSBEZWZlcnJlZClcbiAqXG4gKlx0dW5pcXVlOlx0XHRcdHdpbGwgZW5zdXJlIGEgY2FsbGJhY2sgY2FuIG9ubHkgYmUgYWRkZWQgb25jZSAobm8gZHVwbGljYXRlIGluIHRoZSBsaXN0KVxuICpcbiAqXHRzdG9wT25GYWxzZTpcdGludGVycnVwdCBjYWxsaW5ncyB3aGVuIGEgY2FsbGJhY2sgcmV0dXJucyBmYWxzZVxuICpcbiAqL1xualF1ZXJ5LkNhbGxiYWNrcyA9IGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXG5cdC8vIENvbnZlcnQgb3B0aW9ucyBmcm9tIFN0cmluZy1mb3JtYXR0ZWQgdG8gT2JqZWN0LWZvcm1hdHRlZCBpZiBuZWVkZWRcblx0Ly8gKHdlIGNoZWNrIGluIGNhY2hlIGZpcnN0KVxuXHRvcHRpb25zID0gdHlwZW9mIG9wdGlvbnMgPT09IFwic3RyaW5nXCIgP1xuXHRcdGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSA6XG5cdFx0alF1ZXJ5LmV4dGVuZCgge30sIG9wdGlvbnMgKTtcblxuXHR2YXIgLy8gRmxhZyB0byBrbm93IGlmIGxpc3QgaXMgY3VycmVudGx5IGZpcmluZ1xuXHRcdGZpcmluZyxcblxuXHRcdC8vIExhc3QgZmlyZSB2YWx1ZSBmb3Igbm9uLWZvcmdldHRhYmxlIGxpc3RzXG5cdFx0bWVtb3J5LFxuXG5cdFx0Ly8gRmxhZyB0byBrbm93IGlmIGxpc3Qgd2FzIGFscmVhZHkgZmlyZWRcblx0XHRmaXJlZCxcblxuXHRcdC8vIEZsYWcgdG8gcHJldmVudCBmaXJpbmdcblx0XHRsb2NrZWQsXG5cblx0XHQvLyBBY3R1YWwgY2FsbGJhY2sgbGlzdFxuXHRcdGxpc3QgPSBbXSxcblxuXHRcdC8vIFF1ZXVlIG9mIGV4ZWN1dGlvbiBkYXRhIGZvciByZXBlYXRhYmxlIGxpc3RzXG5cdFx0cXVldWUgPSBbXSxcblxuXHRcdC8vIEluZGV4IG9mIGN1cnJlbnRseSBmaXJpbmcgY2FsbGJhY2sgKG1vZGlmaWVkIGJ5IGFkZC9yZW1vdmUgYXMgbmVlZGVkKVxuXHRcdGZpcmluZ0luZGV4ID0gLTEsXG5cblx0XHQvLyBGaXJlIGNhbGxiYWNrc1xuXHRcdGZpcmUgPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gRW5mb3JjZSBzaW5nbGUtZmlyaW5nXG5cdFx0XHRsb2NrZWQgPSBsb2NrZWQgfHwgb3B0aW9ucy5vbmNlO1xuXG5cdFx0XHQvLyBFeGVjdXRlIGNhbGxiYWNrcyBmb3IgYWxsIHBlbmRpbmcgZXhlY3V0aW9ucyxcblx0XHRcdC8vIHJlc3BlY3RpbmcgZmlyaW5nSW5kZXggb3ZlcnJpZGVzIGFuZCBydW50aW1lIGNoYW5nZXNcblx0XHRcdGZpcmVkID0gZmlyaW5nID0gdHJ1ZTtcblx0XHRcdGZvciAoIDsgcXVldWUubGVuZ3RoOyBmaXJpbmdJbmRleCA9IC0xICkge1xuXHRcdFx0XHRtZW1vcnkgPSBxdWV1ZS5zaGlmdCgpO1xuXHRcdFx0XHR3aGlsZSAoICsrZmlyaW5nSW5kZXggPCBsaXN0Lmxlbmd0aCApIHtcblxuXHRcdFx0XHRcdC8vIFJ1biBjYWxsYmFjayBhbmQgY2hlY2sgZm9yIGVhcmx5IHRlcm1pbmF0aW9uXG5cdFx0XHRcdFx0aWYgKCBsaXN0WyBmaXJpbmdJbmRleCBdLmFwcGx5KCBtZW1vcnlbIDAgXSwgbWVtb3J5WyAxIF0gKSA9PT0gZmFsc2UgJiZcblx0XHRcdFx0XHRcdG9wdGlvbnMuc3RvcE9uRmFsc2UgKSB7XG5cblx0XHRcdFx0XHRcdC8vIEp1bXAgdG8gZW5kIGFuZCBmb3JnZXQgdGhlIGRhdGEgc28gLmFkZCBkb2Vzbid0IHJlLWZpcmVcblx0XHRcdFx0XHRcdGZpcmluZ0luZGV4ID0gbGlzdC5sZW5ndGg7XG5cdFx0XHRcdFx0XHRtZW1vcnkgPSBmYWxzZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gRm9yZ2V0IHRoZSBkYXRhIGlmIHdlJ3JlIGRvbmUgd2l0aCBpdFxuXHRcdFx0aWYgKCAhb3B0aW9ucy5tZW1vcnkgKSB7XG5cdFx0XHRcdG1lbW9yeSA9IGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHRmaXJpbmcgPSBmYWxzZTtcblxuXHRcdFx0Ly8gQ2xlYW4gdXAgaWYgd2UncmUgZG9uZSBmaXJpbmcgZm9yIGdvb2Rcblx0XHRcdGlmICggbG9ja2VkICkge1xuXG5cdFx0XHRcdC8vIEtlZXAgYW4gZW1wdHkgbGlzdCBpZiB3ZSBoYXZlIGRhdGEgZm9yIGZ1dHVyZSBhZGQgY2FsbHNcblx0XHRcdFx0aWYgKCBtZW1vcnkgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IFtdO1xuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSwgdGhpcyBvYmplY3QgaXMgc3BlbnRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRsaXN0ID0gXCJcIjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHQvLyBBY3R1YWwgQ2FsbGJhY2tzIG9iamVjdFxuXHRcdHNlbGYgPSB7XG5cblx0XHRcdC8vIEFkZCBhIGNhbGxiYWNrIG9yIGEgY29sbGVjdGlvbiBvZiBjYWxsYmFja3MgdG8gdGhlIGxpc3Rcblx0XHRcdGFkZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblxuXHRcdFx0XHRcdC8vIElmIHdlIGhhdmUgbWVtb3J5IGZyb20gYSBwYXN0IHJ1biwgd2Ugc2hvdWxkIGZpcmUgYWZ0ZXIgYWRkaW5nXG5cdFx0XHRcdFx0aWYgKCBtZW1vcnkgJiYgIWZpcmluZyApIHtcblx0XHRcdFx0XHRcdGZpcmluZ0luZGV4ID0gbGlzdC5sZW5ndGggLSAxO1xuXHRcdFx0XHRcdFx0cXVldWUucHVzaCggbWVtb3J5ICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0KCBmdW5jdGlvbiBhZGQoIGFyZ3MgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJncywgZnVuY3Rpb24oIF8sIGFyZyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCBhcmcgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoICFvcHRpb25zLnVuaXF1ZSB8fCAhc2VsZi5oYXMoIGFyZyApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0bGlzdC5wdXNoKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIGFyZyAmJiBhcmcubGVuZ3RoICYmIHRvVHlwZSggYXJnICkgIT09IFwic3RyaW5nXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBJbnNwZWN0IHJlY3Vyc2l2ZWx5XG5cdFx0XHRcdFx0XHRcdFx0YWRkKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSApO1xuXHRcdFx0XHRcdH0gKSggYXJndW1lbnRzICk7XG5cblx0XHRcdFx0XHRpZiAoIG1lbW9yeSAmJiAhZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIFJlbW92ZSBhIGNhbGxiYWNrIGZyb20gdGhlIGxpc3Rcblx0XHRcdHJlbW92ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5lYWNoKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0dmFyIGluZGV4O1xuXHRcdFx0XHRcdHdoaWxlICggKCBpbmRleCA9IGpRdWVyeS5pbkFycmF5KCBhcmcsIGxpc3QsIGluZGV4ICkgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0bGlzdC5zcGxpY2UoIGluZGV4LCAxICk7XG5cblx0XHRcdFx0XHRcdC8vIEhhbmRsZSBmaXJpbmcgaW5kZXhlc1xuXHRcdFx0XHRcdFx0aWYgKCBpbmRleCA8PSBmaXJpbmdJbmRleCApIHtcblx0XHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXgtLTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBDaGVjayBpZiBhIGdpdmVuIGNhbGxiYWNrIGlzIGluIHRoZSBsaXN0LlxuXHRcdFx0Ly8gSWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4sIHJldHVybiB3aGV0aGVyIG9yIG5vdCBsaXN0IGhhcyBjYWxsYmFja3MgYXR0YWNoZWQuXG5cdFx0XHRoYXM6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0cmV0dXJuIGZuID9cblx0XHRcdFx0XHRqUXVlcnkuaW5BcnJheSggZm4sIGxpc3QgKSA+IC0xIDpcblx0XHRcdFx0XHRsaXN0Lmxlbmd0aCA+IDA7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBSZW1vdmUgYWxsIGNhbGxiYWNrcyBmcm9tIHRoZSBsaXN0XG5cdFx0XHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggbGlzdCApIHtcblx0XHRcdFx0XHRsaXN0ID0gW107XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXG5cdFx0XHQvLyBEaXNhYmxlIC5maXJlIGFuZCAuYWRkXG5cdFx0XHQvLyBBYm9ydCBhbnkgY3VycmVudC9wZW5kaW5nIGV4ZWN1dGlvbnNcblx0XHRcdC8vIENsZWFyIGFsbCBjYWxsYmFja3MgYW5kIHZhbHVlc1xuXHRcdFx0ZGlzYWJsZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGxvY2tlZCA9IHF1ZXVlID0gW107XG5cdFx0XHRcdGxpc3QgPSBtZW1vcnkgPSBcIlwiO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHRkaXNhYmxlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhbGlzdDtcblx0XHRcdH0sXG5cblx0XHRcdC8vIERpc2FibGUgLmZpcmVcblx0XHRcdC8vIEFsc28gZGlzYWJsZSAuYWRkIHVubGVzcyB3ZSBoYXZlIG1lbW9yeSAoc2luY2UgaXQgd291bGQgaGF2ZSBubyBlZmZlY3QpXG5cdFx0XHQvLyBBYm9ydCBhbnkgcGVuZGluZyBleGVjdXRpb25zXG5cdFx0XHRsb2NrOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0bG9ja2VkID0gcXVldWUgPSBbXTtcblx0XHRcdFx0aWYgKCAhbWVtb3J5ICYmICFmaXJpbmcgKSB7XG5cdFx0XHRcdFx0bGlzdCA9IG1lbW9yeSA9IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0bG9ja2VkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICEhbG9ja2VkO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gQ2FsbCBhbGwgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGNvbnRleHQgYW5kIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZVdpdGg6IGZ1bmN0aW9uKCBjb250ZXh0LCBhcmdzICkge1xuXHRcdFx0XHRpZiAoICFsb2NrZWQgKSB7XG5cdFx0XHRcdFx0YXJncyA9IGFyZ3MgfHwgW107XG5cdFx0XHRcdFx0YXJncyA9IFsgY29udGV4dCwgYXJncy5zbGljZSA/IGFyZ3Muc2xpY2UoKSA6IGFyZ3MgXTtcblx0XHRcdFx0XHRxdWV1ZS5wdXNoKCBhcmdzICk7XG5cdFx0XHRcdFx0aWYgKCAhZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0ZmlyZSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cblx0XHRcdC8vIENhbGwgYWxsIHRoZSBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzXG5cdFx0XHRmaXJlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0c2VsZi5maXJlV2l0aCggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblxuXHRcdFx0Ly8gVG8ga25vdyBpZiB0aGUgY2FsbGJhY2tzIGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZCBhdCBsZWFzdCBvbmNlXG5cdFx0XHRmaXJlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhIWZpcmVkO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0cmV0dXJuIHNlbGY7XG59O1xuXG5cbmZ1bmN0aW9uIElkZW50aXR5KCB2ICkge1xuXHRyZXR1cm4gdjtcbn1cbmZ1bmN0aW9uIFRocm93ZXIoIGV4ICkge1xuXHR0aHJvdyBleDtcbn1cblxuZnVuY3Rpb24gYWRvcHRWYWx1ZSggdmFsdWUsIHJlc29sdmUsIHJlamVjdCwgbm9WYWx1ZSApIHtcblx0dmFyIG1ldGhvZDtcblxuXHR0cnkge1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIHByb21pc2UgYXNwZWN0IGZpcnN0IHRvIHByaXZpbGVnZSBzeW5jaHJvbm91cyBiZWhhdmlvclxuXHRcdGlmICggdmFsdWUgJiYgaXNGdW5jdGlvbiggKCBtZXRob2QgPSB2YWx1ZS5wcm9taXNlICkgKSApIHtcblx0XHRcdG1ldGhvZC5jYWxsKCB2YWx1ZSApLmRvbmUoIHJlc29sdmUgKS5mYWlsKCByZWplY3QgKTtcblxuXHRcdC8vIE90aGVyIHRoZW5hYmxlc1xuXHRcdH0gZWxzZSBpZiAoIHZhbHVlICYmIGlzRnVuY3Rpb24oICggbWV0aG9kID0gdmFsdWUudGhlbiApICkgKSB7XG5cdFx0XHRtZXRob2QuY2FsbCggdmFsdWUsIHJlc29sdmUsIHJlamVjdCApO1xuXG5cdFx0Ly8gT3RoZXIgbm9uLXRoZW5hYmxlc1xuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIENvbnRyb2wgYHJlc29sdmVgIGFyZ3VtZW50cyBieSBsZXR0aW5nIEFycmF5I3NsaWNlIGNhc3QgYm9vbGVhbiBgbm9WYWx1ZWAgdG8gaW50ZWdlcjpcblx0XHRcdC8vICogZmFsc2U6IFsgdmFsdWUgXS5zbGljZSggMCApID0+IHJlc29sdmUoIHZhbHVlIClcblx0XHRcdC8vICogdHJ1ZTogWyB2YWx1ZSBdLnNsaWNlKCAxICkgPT4gcmVzb2x2ZSgpXG5cdFx0XHRyZXNvbHZlLmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXS5zbGljZSggbm9WYWx1ZSApICk7XG5cdFx0fVxuXG5cdC8vIEZvciBQcm9taXNlcy9BKywgY29udmVydCBleGNlcHRpb25zIGludG8gcmVqZWN0aW9uc1xuXHQvLyBTaW5jZSBqUXVlcnkud2hlbiBkb2Vzbid0IHVud3JhcCB0aGVuYWJsZXMsIHdlIGNhbiBza2lwIHRoZSBleHRyYSBjaGVja3MgYXBwZWFyaW5nIGluXG5cdC8vIERlZmVycmVkI3RoZW4gdG8gY29uZGl0aW9uYWxseSBzdXBwcmVzcyByZWplY3Rpb24uXG5cdH0gY2F0Y2ggKCB2YWx1ZSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIG9ubHlcblx0XHQvLyBTdHJpY3QgbW9kZSBmdW5jdGlvbnMgaW52b2tlZCB3aXRob3V0IC5jYWxsLy5hcHBseSBnZXQgZ2xvYmFsLW9iamVjdCBjb250ZXh0XG5cdFx0cmVqZWN0LmFwcGx5KCB1bmRlZmluZWQsIFsgdmFsdWUgXSApO1xuXHR9XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHREZWZlcnJlZDogZnVuY3Rpb24oIGZ1bmMgKSB7XG5cdFx0dmFyIHR1cGxlcyA9IFtcblxuXHRcdFx0XHQvLyBhY3Rpb24sIGFkZCBsaXN0ZW5lciwgY2FsbGJhY2tzLFxuXHRcdFx0XHQvLyAuLi4gLnRoZW4gaGFuZGxlcnMsIGFyZ3VtZW50IGluZGV4LCBbZmluYWwgc3RhdGVdXG5cdFx0XHRcdFsgXCJub3RpZnlcIiwgXCJwcm9ncmVzc1wiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm1lbW9yeVwiICksXG5cdFx0XHRcdFx0alF1ZXJ5LkNhbGxiYWNrcyggXCJtZW1vcnlcIiApLCAyIF0sXG5cdFx0XHRcdFsgXCJyZXNvbHZlXCIsIFwiZG9uZVwiLCBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSxcblx0XHRcdFx0XHRqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKSwgMCwgXCJyZXNvbHZlZFwiIF0sXG5cdFx0XHRcdFsgXCJyZWplY3RcIiwgXCJmYWlsXCIsIGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLFxuXHRcdFx0XHRcdGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLCAxLCBcInJlamVjdGVkXCIgXVxuXHRcdFx0XSxcblx0XHRcdHN0YXRlID0gXCJwZW5kaW5nXCIsXG5cdFx0XHRwcm9taXNlID0ge1xuXHRcdFx0XHRzdGF0ZTogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRhbHdheXM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGRlZmVycmVkLmRvbmUoIGFyZ3VtZW50cyApLmZhaWwoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXHRcdFx0XHRcImNhdGNoXCI6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcHJvbWlzZS50aGVuKCBudWxsLCBmbiApO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIEtlZXAgcGlwZSBmb3IgYmFjay1jb21wYXRcblx0XHRcdFx0cGlwZTogZnVuY3Rpb24oIC8qIGZuRG9uZSwgZm5GYWlsLCBmblByb2dyZXNzICovICkge1xuXHRcdFx0XHRcdHZhciBmbnMgPSBhcmd1bWVudHM7XG5cblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggX2ksIHR1cGxlICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIE1hcCB0dXBsZXMgKHByb2dyZXNzLCBkb25lLCBmYWlsKSB0byBhcmd1bWVudHMgKGRvbmUsIGZhaWwsIHByb2dyZXNzKVxuXHRcdFx0XHRcdFx0XHR2YXIgZm4gPSBpc0Z1bmN0aW9uKCBmbnNbIHR1cGxlWyA0IF0gXSApICYmIGZuc1sgdHVwbGVbIDQgXSBdO1xuXG5cdFx0XHRcdFx0XHRcdC8vIGRlZmVycmVkLnByb2dyZXNzKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLm5vdGlmeSB9KVxuXHRcdFx0XHRcdFx0XHQvLyBkZWZlcnJlZC5kb25lKGZ1bmN0aW9uKCkgeyBiaW5kIHRvIG5ld0RlZmVyIG9yIG5ld0RlZmVyLnJlc29sdmUgfSlcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWQuZmFpbChmdW5jdGlvbigpIHsgYmluZCB0byBuZXdEZWZlciBvciBuZXdEZWZlci5yZWplY3QgfSlcblx0XHRcdFx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAxIF0gXSggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkID0gZm4gJiYgZm4uYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdFx0XHRcdGlmICggcmV0dXJuZWQgJiYgaXNGdW5jdGlvbiggcmV0dXJuZWQucHJvbWlzZSApICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQucHJvbWlzZSgpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5wcm9ncmVzcyggbmV3RGVmZXIubm90aWZ5IClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmRvbmUoIG5ld0RlZmVyLnJlc29sdmUgKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuZmFpbCggbmV3RGVmZXIucmVqZWN0ICk7XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRcdG5ld0RlZmVyWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXShcblx0XHRcdFx0XHRcdFx0XHRcdFx0dGhpcyxcblx0XHRcdFx0XHRcdFx0XHRcdFx0Zm4gPyBbIHJldHVybmVkIF0gOiBhcmd1bWVudHNcblx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHRmbnMgPSBudWxsO1xuXHRcdFx0XHRcdH0gKS5wcm9taXNlKCk7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRoZW46IGZ1bmN0aW9uKCBvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCwgb25Qcm9ncmVzcyApIHtcblx0XHRcdFx0XHR2YXIgbWF4RGVwdGggPSAwO1xuXHRcdFx0XHRcdGZ1bmN0aW9uIHJlc29sdmUoIGRlcHRoLCBkZWZlcnJlZCwgaGFuZGxlciwgc3BlY2lhbCApIHtcblx0XHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdFx0dmFyIHRoYXQgPSB0aGlzLFxuXHRcdFx0XHRcdFx0XHRcdGFyZ3MgPSBhcmd1bWVudHMsXG5cdFx0XHRcdFx0XHRcdFx0bWlnaHRUaHJvdyA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdFx0dmFyIHJldHVybmVkLCB0aGVuO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4zLjMuM1xuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTlcblx0XHRcdFx0XHRcdFx0XHRcdC8vIElnbm9yZSBkb3VibGUtcmVzb2x1dGlvbiBhdHRlbXB0c1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBkZXB0aCA8IG1heERlcHRoICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm47XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkID0gaGFuZGxlci5hcHBseSggdGhhdCwgYXJncyApO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy4xXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBodHRwczovL3Byb21pc2VzYXBsdXMuY29tLyNwb2ludC00OFxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCByZXR1cm5lZCA9PT0gZGVmZXJyZWQucHJvbWlzZSgpICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCBcIlRoZW5hYmxlIHNlbGYtcmVzb2x1dGlvblwiICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IFByb21pc2VzL0ErIHNlY3Rpb25zIDIuMy4zLjEsIDMuNVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTRcblx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTc1XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBSZXRyaWV2ZSBgdGhlbmAgb25seSBvbmNlXG5cdFx0XHRcdFx0XHRcdFx0XHR0aGVuID0gcmV0dXJuZWQgJiZcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBQcm9taXNlcy9BKyBzZWN0aW9uIDIuMy40XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTY0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgY2hlY2sgb2JqZWN0cyBhbmQgZnVuY3Rpb25zIGZvciB0aGVuYWJpbGl0eVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQoIHR5cGVvZiByZXR1cm5lZCA9PT0gXCJvYmplY3RcIiB8fFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiByZXR1cm5lZCA9PT0gXCJmdW5jdGlvblwiICkgJiZcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuZWQudGhlbjtcblxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSGFuZGxlIGEgcmV0dXJuZWQgdGhlbmFibGVcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggaXNGdW5jdGlvbiggdGhlbiApICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFNwZWNpYWwgcHJvY2Vzc29ycyAobm90aWZ5KSBqdXN0IHdhaXQgZm9yIHJlc29sdXRpb25cblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoZW4uY2FsbChcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBJZGVudGl0eSwgc3BlY2lhbCApLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBUaHJvd2VyLCBzcGVjaWFsIClcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE5vcm1hbCBwcm9jZXNzb3JzIChyZXNvbHZlKSBhbHNvIGhvb2sgaW50byBwcm9ncmVzc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gLi4uYW5kIGRpc3JlZ2FyZCBvbGRlciByZXNvbHV0aW9uIHZhbHVlc1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG1heERlcHRoKys7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGVuLmNhbGwoXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5lZCxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgSWRlbnRpdHksIHNwZWNpYWwgKSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdHJlc29sdmUoIG1heERlcHRoLCBkZWZlcnJlZCwgVGhyb3dlciwgc3BlY2lhbCApLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cmVzb2x2ZSggbWF4RGVwdGgsIGRlZmVycmVkLCBJZGVudGl0eSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCApXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBIYW5kbGUgYWxsIG90aGVyIHJldHVybmVkIHZhbHVlc1xuXHRcdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBPbmx5IHN1YnN0aXR1dGUgaGFuZGxlcnMgcGFzcyBvbiBjb250ZXh0XG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGFuZCBtdWx0aXBsZSB2YWx1ZXMgKG5vbi1zcGVjIGJlaGF2aW9yKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRpZiAoIGhhbmRsZXIgIT09IElkZW50aXR5ICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHRoYXQgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YXJncyA9IFsgcmV0dXJuZWQgXTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIFByb2Nlc3MgdGhlIHZhbHVlKHMpXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIERlZmF1bHQgcHJvY2VzcyBpcyByZXNvbHZlXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCggc3BlY2lhbCB8fCBkZWZlcnJlZC5yZXNvbHZlV2l0aCApKCB0aGF0LCBhcmdzICk7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fSxcblxuXHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgbm9ybWFsIHByb2Nlc3NvcnMgKHJlc29sdmUpIGNhdGNoIGFuZCByZWplY3QgZXhjZXB0aW9uc1xuXHRcdFx0XHRcdFx0XHRcdHByb2Nlc3MgPSBzcGVjaWFsID9cblx0XHRcdFx0XHRcdFx0XHRcdG1pZ2h0VGhyb3cgOlxuXHRcdFx0XHRcdFx0XHRcdFx0ZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0bWlnaHRUaHJvdygpO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR9IGNhdGNoICggZSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LkRlZmVycmVkLmV4Y2VwdGlvbkhvb2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayggZSxcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0cHJvY2Vzcy5zdGFja1RyYWNlICk7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMy4zLjQuMVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGh0dHBzOi8vcHJvbWlzZXNhcGx1cy5jb20vI3BvaW50LTYxXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0Ly8gSWdub3JlIHBvc3QtcmVzb2x1dGlvbiBleGNlcHRpb25zXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBkZXB0aCArIDEgPj0gbWF4RGVwdGggKSB7XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIE9ubHkgc3Vic3RpdHV0ZSBoYW5kbGVycyBwYXNzIG9uIGNvbnRleHRcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdC8vIGFuZCBtdWx0aXBsZSB2YWx1ZXMgKG5vbi1zcGVjIGJlaGF2aW9yKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBoYW5kbGVyICE9PSBUaHJvd2VyICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR0aGF0ID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHRhcmdzID0gWyBlIF07XG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIHRoYXQsIGFyZ3MgKTtcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRcdH07XG5cblx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogUHJvbWlzZXMvQSsgc2VjdGlvbiAyLjMuMy4zLjFcblx0XHRcdFx0XHRcdFx0Ly8gaHR0cHM6Ly9wcm9taXNlc2FwbHVzLmNvbS8jcG9pbnQtNTdcblx0XHRcdFx0XHRcdFx0Ly8gUmUtcmVzb2x2ZSBwcm9taXNlcyBpbW1lZGlhdGVseSB0byBkb2RnZSBmYWxzZSByZWplY3Rpb24gZnJvbVxuXHRcdFx0XHRcdFx0XHQvLyBzdWJzZXF1ZW50IGVycm9yc1xuXHRcdFx0XHRcdFx0XHRpZiAoIGRlcHRoICkge1xuXHRcdFx0XHRcdFx0XHRcdHByb2Nlc3MoKTtcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIENhbGwgYW4gb3B0aW9uYWwgaG9vayB0byByZWNvcmQgdGhlIHN0YWNrLCBpbiBjYXNlIG9mIGV4Y2VwdGlvblxuXHRcdFx0XHRcdFx0XHRcdC8vIHNpbmNlIGl0J3Mgb3RoZXJ3aXNlIGxvc3Qgd2hlbiBleGVjdXRpb24gZ29lcyBhc3luY1xuXHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5LkRlZmVycmVkLmdldFN0YWNrSG9vayApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHByb2Nlc3Muc3RhY2tUcmFjZSA9IGpRdWVyeS5EZWZlcnJlZC5nZXRTdGFja0hvb2soKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0d2luZG93LnNldFRpbWVvdXQoIHByb2Nlc3MgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XG5cblx0XHRcdFx0XHRcdC8vIHByb2dyZXNzX2hhbmRsZXJzLmFkZCggLi4uIClcblx0XHRcdFx0XHRcdHR1cGxlc1sgMCBdWyAzIF0uYWRkKFxuXHRcdFx0XHRcdFx0XHRyZXNvbHZlKFxuXHRcdFx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIsXG5cdFx0XHRcdFx0XHRcdFx0aXNGdW5jdGlvbiggb25Qcm9ncmVzcyApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uUHJvZ3Jlc3MgOlxuXHRcdFx0XHRcdFx0XHRcdFx0SWRlbnRpdHksXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIubm90aWZ5V2l0aFxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHQvLyBmdWxmaWxsZWRfaGFuZGxlcnMuYWRkKCAuLi4gKVxuXHRcdFx0XHRcdFx0dHVwbGVzWyAxIF1bIDMgXS5hZGQoXG5cdFx0XHRcdFx0XHRcdHJlc29sdmUoXG5cdFx0XHRcdFx0XHRcdFx0MCxcblx0XHRcdFx0XHRcdFx0XHRuZXdEZWZlcixcblx0XHRcdFx0XHRcdFx0XHRpc0Z1bmN0aW9uKCBvbkZ1bGZpbGxlZCApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uRnVsZmlsbGVkIDpcblx0XHRcdFx0XHRcdFx0XHRcdElkZW50aXR5XG5cdFx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmFkZCggLi4uIClcblx0XHRcdFx0XHRcdHR1cGxlc1sgMiBdWyAzIF0uYWRkKFxuXHRcdFx0XHRcdFx0XHRyZXNvbHZlKFxuXHRcdFx0XHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXIsXG5cdFx0XHRcdFx0XHRcdFx0aXNGdW5jdGlvbiggb25SZWplY3RlZCApID9cblx0XHRcdFx0XHRcdFx0XHRcdG9uUmVqZWN0ZWQgOlxuXHRcdFx0XHRcdFx0XHRcdFx0VGhyb3dlclxuXHRcdFx0XHRcdFx0XHQpXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH0gKS5wcm9taXNlKCk7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gR2V0IGEgcHJvbWlzZSBmb3IgdGhpcyBkZWZlcnJlZFxuXHRcdFx0XHQvLyBJZiBvYmogaXMgcHJvdmlkZWQsIHRoZSBwcm9taXNlIGFzcGVjdCBpcyBhZGRlZCB0byB0aGUgb2JqZWN0XG5cdFx0XHRcdHByb21pc2U6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9iaiAhPSBudWxsID8galF1ZXJ5LmV4dGVuZCggb2JqLCBwcm9taXNlICkgOiBwcm9taXNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVmZXJyZWQgPSB7fTtcblxuXHRcdC8vIEFkZCBsaXN0LXNwZWNpZmljIG1ldGhvZHNcblx0XHRqUXVlcnkuZWFjaCggdHVwbGVzLCBmdW5jdGlvbiggaSwgdHVwbGUgKSB7XG5cdFx0XHR2YXIgbGlzdCA9IHR1cGxlWyAyIF0sXG5cdFx0XHRcdHN0YXRlU3RyaW5nID0gdHVwbGVbIDUgXTtcblxuXHRcdFx0Ly8gcHJvbWlzZS5wcm9ncmVzcyA9IGxpc3QuYWRkXG5cdFx0XHQvLyBwcm9taXNlLmRvbmUgPSBsaXN0LmFkZFxuXHRcdFx0Ly8gcHJvbWlzZS5mYWlsID0gbGlzdC5hZGRcblx0XHRcdHByb21pc2VbIHR1cGxlWyAxIF0gXSA9IGxpc3QuYWRkO1xuXG5cdFx0XHQvLyBIYW5kbGUgc3RhdGVcblx0XHRcdGlmICggc3RhdGVTdHJpbmcgKSB7XG5cdFx0XHRcdGxpc3QuYWRkKFxuXHRcdFx0XHRcdGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdFx0XHQvLyBzdGF0ZSA9IFwicmVzb2x2ZWRcIiAoaS5lLiwgZnVsZmlsbGVkKVxuXHRcdFx0XHRcdFx0Ly8gc3RhdGUgPSBcInJlamVjdGVkXCJcblx0XHRcdFx0XHRcdHN0YXRlID0gc3RhdGVTdHJpbmc7XG5cdFx0XHRcdFx0fSxcblxuXHRcdFx0XHRcdC8vIHJlamVjdGVkX2NhbGxiYWNrcy5kaXNhYmxlXG5cdFx0XHRcdFx0Ly8gZnVsZmlsbGVkX2NhbGxiYWNrcy5kaXNhYmxlXG5cdFx0XHRcdFx0dHVwbGVzWyAzIC0gaSBdWyAyIF0uZGlzYWJsZSxcblxuXHRcdFx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmRpc2FibGVcblx0XHRcdFx0XHQvLyBmdWxmaWxsZWRfaGFuZGxlcnMuZGlzYWJsZVxuXHRcdFx0XHRcdHR1cGxlc1sgMyAtIGkgXVsgMyBdLmRpc2FibGUsXG5cblx0XHRcdFx0XHQvLyBwcm9ncmVzc19jYWxsYmFja3MubG9ja1xuXHRcdFx0XHRcdHR1cGxlc1sgMCBdWyAyIF0ubG9jayxcblxuXHRcdFx0XHRcdC8vIHByb2dyZXNzX2hhbmRsZXJzLmxvY2tcblx0XHRcdFx0XHR0dXBsZXNbIDAgXVsgMyBdLmxvY2tcblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gcHJvZ3Jlc3NfaGFuZGxlcnMuZmlyZVxuXHRcdFx0Ly8gZnVsZmlsbGVkX2hhbmRsZXJzLmZpcmVcblx0XHRcdC8vIHJlamVjdGVkX2hhbmRsZXJzLmZpcmVcblx0XHRcdGxpc3QuYWRkKCB0dXBsZVsgMyBdLmZpcmUgKTtcblxuXHRcdFx0Ly8gZGVmZXJyZWQubm90aWZ5ID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLm5vdGlmeVdpdGgoLi4uKSB9XG5cdFx0XHQvLyBkZWZlcnJlZC5yZXNvbHZlID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLnJlc29sdmVXaXRoKC4uLikgfVxuXHRcdFx0Ly8gZGVmZXJyZWQucmVqZWN0ID0gZnVuY3Rpb24oKSB7IGRlZmVycmVkLnJlamVjdFdpdGgoLi4uKSB9XG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbIDAgXSBdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGRlZmVycmVkWyB0dXBsZVsgMCBdICsgXCJXaXRoXCIgXSggdGhpcyA9PT0gZGVmZXJyZWQgPyB1bmRlZmluZWQgOiB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9O1xuXG5cdFx0XHQvLyBkZWZlcnJlZC5ub3RpZnlXaXRoID0gbGlzdC5maXJlV2l0aFxuXHRcdFx0Ly8gZGVmZXJyZWQucmVzb2x2ZVdpdGggPSBsaXN0LmZpcmVXaXRoXG5cdFx0XHQvLyBkZWZlcnJlZC5yZWplY3RXaXRoID0gbGlzdC5maXJlV2l0aFxuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdID0gbGlzdC5maXJlV2l0aDtcblx0XHR9ICk7XG5cblx0XHQvLyBNYWtlIHRoZSBkZWZlcnJlZCBhIHByb21pc2Vcblx0XHRwcm9taXNlLnByb21pc2UoIGRlZmVycmVkICk7XG5cblx0XHQvLyBDYWxsIGdpdmVuIGZ1bmMgaWYgYW55XG5cdFx0aWYgKCBmdW5jICkge1xuXHRcdFx0ZnVuYy5jYWxsKCBkZWZlcnJlZCwgZGVmZXJyZWQgKTtcblx0XHR9XG5cblx0XHQvLyBBbGwgZG9uZSFcblx0XHRyZXR1cm4gZGVmZXJyZWQ7XG5cdH0sXG5cblx0Ly8gRGVmZXJyZWQgaGVscGVyXG5cdHdoZW46IGZ1bmN0aW9uKCBzaW5nbGVWYWx1ZSApIHtcblx0XHR2YXJcblxuXHRcdFx0Ly8gY291bnQgb2YgdW5jb21wbGV0ZWQgc3Vib3JkaW5hdGVzXG5cdFx0XHRyZW1haW5pbmcgPSBhcmd1bWVudHMubGVuZ3RoLFxuXG5cdFx0XHQvLyBjb3VudCBvZiB1bnByb2Nlc3NlZCBhcmd1bWVudHNcblx0XHRcdGkgPSByZW1haW5pbmcsXG5cblx0XHRcdC8vIHN1Ym9yZGluYXRlIGZ1bGZpbGxtZW50IGRhdGFcblx0XHRcdHJlc29sdmVDb250ZXh0cyA9IEFycmF5KCBpICksXG5cdFx0XHRyZXNvbHZlVmFsdWVzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICksXG5cblx0XHRcdC8vIHRoZSBtYXN0ZXIgRGVmZXJyZWRcblx0XHRcdG1hc3RlciA9IGpRdWVyeS5EZWZlcnJlZCgpLFxuXG5cdFx0XHQvLyBzdWJvcmRpbmF0ZSBjYWxsYmFjayBmYWN0b3J5XG5cdFx0XHR1cGRhdGVGdW5jID0gZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdHJldHVybiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmVzb2x2ZUNvbnRleHRzWyBpIF0gPSB0aGlzO1xuXHRcdFx0XHRcdHJlc29sdmVWYWx1ZXNbIGkgXSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gc2xpY2UuY2FsbCggYXJndW1lbnRzICkgOiB2YWx1ZTtcblx0XHRcdFx0XHRpZiAoICEoIC0tcmVtYWluaW5nICkgKSB7XG5cdFx0XHRcdFx0XHRtYXN0ZXIucmVzb2x2ZVdpdGgoIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdH07XG5cblx0XHQvLyBTaW5nbGUtIGFuZCBlbXB0eSBhcmd1bWVudHMgYXJlIGFkb3B0ZWQgbGlrZSBQcm9taXNlLnJlc29sdmVcblx0XHRpZiAoIHJlbWFpbmluZyA8PSAxICkge1xuXHRcdFx0YWRvcHRWYWx1ZSggc2luZ2xlVmFsdWUsIG1hc3Rlci5kb25lKCB1cGRhdGVGdW5jKCBpICkgKS5yZXNvbHZlLCBtYXN0ZXIucmVqZWN0LFxuXHRcdFx0XHQhcmVtYWluaW5nICk7XG5cblx0XHRcdC8vIFVzZSAudGhlbigpIHRvIHVud3JhcCBzZWNvbmRhcnkgdGhlbmFibGVzIChjZi4gZ2gtMzAwMClcblx0XHRcdGlmICggbWFzdGVyLnN0YXRlKCkgPT09IFwicGVuZGluZ1wiIHx8XG5cdFx0XHRcdGlzRnVuY3Rpb24oIHJlc29sdmVWYWx1ZXNbIGkgXSAmJiByZXNvbHZlVmFsdWVzWyBpIF0udGhlbiApICkge1xuXG5cdFx0XHRcdHJldHVybiBtYXN0ZXIudGhlbigpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIE11bHRpcGxlIGFyZ3VtZW50cyBhcmUgYWdncmVnYXRlZCBsaWtlIFByb21pc2UuYWxsIGFycmF5IGVsZW1lbnRzXG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRhZG9wdFZhbHVlKCByZXNvbHZlVmFsdWVzWyBpIF0sIHVwZGF0ZUZ1bmMoIGkgKSwgbWFzdGVyLnJlamVjdCApO1xuXHRcdH1cblxuXHRcdHJldHVybiBtYXN0ZXIucHJvbWlzZSgpO1xuXHR9XG59ICk7XG5cblxuLy8gVGhlc2UgdXN1YWxseSBpbmRpY2F0ZSBhIHByb2dyYW1tZXIgbWlzdGFrZSBkdXJpbmcgZGV2ZWxvcG1lbnQsXG4vLyB3YXJuIGFib3V0IHRoZW0gQVNBUCByYXRoZXIgdGhhbiBzd2FsbG93aW5nIHRoZW0gYnkgZGVmYXVsdC5cbnZhciByZXJyb3JOYW1lcyA9IC9eKEV2YWx8SW50ZXJuYWx8UmFuZ2V8UmVmZXJlbmNlfFN5bnRheHxUeXBlfFVSSSlFcnJvciQvO1xuXG5qUXVlcnkuRGVmZXJyZWQuZXhjZXB0aW9uSG9vayA9IGZ1bmN0aW9uKCBlcnJvciwgc3RhY2sgKSB7XG5cblx0Ly8gU3VwcG9ydDogSUUgOCAtIDkgb25seVxuXHQvLyBDb25zb2xlIGV4aXN0cyB3aGVuIGRldiB0b29scyBhcmUgb3Blbiwgd2hpY2ggY2FuIGhhcHBlbiBhdCBhbnkgdGltZVxuXHRpZiAoIHdpbmRvdy5jb25zb2xlICYmIHdpbmRvdy5jb25zb2xlLndhcm4gJiYgZXJyb3IgJiYgcmVycm9yTmFtZXMudGVzdCggZXJyb3IubmFtZSApICkge1xuXHRcdHdpbmRvdy5jb25zb2xlLndhcm4oIFwialF1ZXJ5LkRlZmVycmVkIGV4Y2VwdGlvbjogXCIgKyBlcnJvci5tZXNzYWdlLCBlcnJvci5zdGFjaywgc3RhY2sgKTtcblx0fVxufTtcblxuXG5cblxualF1ZXJ5LnJlYWR5RXhjZXB0aW9uID0gZnVuY3Rpb24oIGVycm9yICkge1xuXHR3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0dGhyb3cgZXJyb3I7XG5cdH0gKTtcbn07XG5cblxuXG5cbi8vIFRoZSBkZWZlcnJlZCB1c2VkIG9uIERPTSByZWFkeVxudmFyIHJlYWR5TGlzdCA9IGpRdWVyeS5EZWZlcnJlZCgpO1xuXG5qUXVlcnkuZm4ucmVhZHkgPSBmdW5jdGlvbiggZm4gKSB7XG5cblx0cmVhZHlMaXN0XG5cdFx0LnRoZW4oIGZuIClcblxuXHRcdC8vIFdyYXAgalF1ZXJ5LnJlYWR5RXhjZXB0aW9uIGluIGEgZnVuY3Rpb24gc28gdGhhdCB0aGUgbG9va3VwXG5cdFx0Ly8gaGFwcGVucyBhdCB0aGUgdGltZSBvZiBlcnJvciBoYW5kbGluZyBpbnN0ZWFkIG9mIGNhbGxiYWNrXG5cdFx0Ly8gcmVnaXN0cmF0aW9uLlxuXHRcdC5jYXRjaCggZnVuY3Rpb24oIGVycm9yICkge1xuXHRcdFx0alF1ZXJ5LnJlYWR5RXhjZXB0aW9uKCBlcnJvciApO1xuXHRcdH0gKTtcblxuXHRyZXR1cm4gdGhpcztcbn07XG5cbmpRdWVyeS5leHRlbmQoIHtcblxuXHQvLyBJcyB0aGUgRE9NIHJlYWR5IHRvIGJlIHVzZWQ/IFNldCB0byB0cnVlIG9uY2UgaXQgb2NjdXJzLlxuXHRpc1JlYWR5OiBmYWxzZSxcblxuXHQvLyBBIGNvdW50ZXIgdG8gdHJhY2sgaG93IG1hbnkgaXRlbXMgdG8gd2FpdCBmb3IgYmVmb3JlXG5cdC8vIHRoZSByZWFkeSBldmVudCBmaXJlcy4gU2VlICM2NzgxXG5cdHJlYWR5V2FpdDogMSxcblxuXHQvLyBIYW5kbGUgd2hlbiB0aGUgRE9NIGlzIHJlYWR5XG5cdHJlYWR5OiBmdW5jdGlvbiggd2FpdCApIHtcblxuXHRcdC8vIEFib3J0IGlmIHRoZXJlIGFyZSBwZW5kaW5nIGhvbGRzIG9yIHdlJ3JlIGFscmVhZHkgcmVhZHlcblx0XHRpZiAoIHdhaXQgPT09IHRydWUgPyAtLWpRdWVyeS5yZWFkeVdhaXQgOiBqUXVlcnkuaXNSZWFkeSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBSZW1lbWJlciB0aGF0IHRoZSBET00gaXMgcmVhZHlcblx0XHRqUXVlcnkuaXNSZWFkeSA9IHRydWU7XG5cblx0XHQvLyBJZiBhIG5vcm1hbCBET00gUmVhZHkgZXZlbnQgZmlyZWQsIGRlY3JlbWVudCwgYW5kIHdhaXQgaWYgbmVlZCBiZVxuXHRcdGlmICggd2FpdCAhPT0gdHJ1ZSAmJiAtLWpRdWVyeS5yZWFkeVdhaXQgPiAwICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZXJlIGFyZSBmdW5jdGlvbnMgYm91bmQsIHRvIGV4ZWN1dGVcblx0XHRyZWFkeUxpc3QucmVzb2x2ZVdpdGgoIGRvY3VtZW50LCBbIGpRdWVyeSBdICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LnJlYWR5LnRoZW4gPSByZWFkeUxpc3QudGhlbjtcblxuLy8gVGhlIHJlYWR5IGV2ZW50IGhhbmRsZXIgYW5kIHNlbGYgY2xlYW51cCBtZXRob2RcbmZ1bmN0aW9uIGNvbXBsZXRlZCgpIHtcblx0ZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCApO1xuXHR3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lciggXCJsb2FkXCIsIGNvbXBsZXRlZCApO1xuXHRqUXVlcnkucmVhZHkoKTtcbn1cblxuLy8gQ2F0Y2ggY2FzZXMgd2hlcmUgJChkb2N1bWVudCkucmVhZHkoKSBpcyBjYWxsZWRcbi8vIGFmdGVyIHRoZSBicm93c2VyIGV2ZW50IGhhcyBhbHJlYWR5IG9jY3VycmVkLlxuLy8gU3VwcG9ydDogSUUgPD05IC0gMTAgb25seVxuLy8gT2xkZXIgSUUgc29tZXRpbWVzIHNpZ25hbHMgXCJpbnRlcmFjdGl2ZVwiIHRvbyBzb29uXG5pZiAoIGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiB8fFxuXHQoIGRvY3VtZW50LnJlYWR5U3RhdGUgIT09IFwibG9hZGluZ1wiICYmICFkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZG9TY3JvbGwgKSApIHtcblxuXHQvLyBIYW5kbGUgaXQgYXN5bmNocm9ub3VzbHkgdG8gYWxsb3cgc2NyaXB0cyB0aGUgb3Bwb3J0dW5pdHkgdG8gZGVsYXkgcmVhZHlcblx0d2luZG93LnNldFRpbWVvdXQoIGpRdWVyeS5yZWFkeSApO1xuXG59IGVsc2Uge1xuXG5cdC8vIFVzZSB0aGUgaGFuZHkgZXZlbnQgY2FsbGJhY2tcblx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCApO1xuXG5cdC8vIEEgZmFsbGJhY2sgdG8gd2luZG93Lm9ubG9hZCwgdGhhdCB3aWxsIGFsd2F5cyB3b3JrXG5cdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCBcImxvYWRcIiwgY29tcGxldGVkICk7XG59XG5cblxuXG5cbi8vIE11bHRpZnVuY3Rpb25hbCBtZXRob2QgdG8gZ2V0IGFuZCBzZXQgdmFsdWVzIG9mIGEgY29sbGVjdGlvblxuLy8gVGhlIHZhbHVlL3MgY2FuIG9wdGlvbmFsbHkgYmUgZXhlY3V0ZWQgaWYgaXQncyBhIGZ1bmN0aW9uXG52YXIgYWNjZXNzID0gZnVuY3Rpb24oIGVsZW1zLCBmbiwga2V5LCB2YWx1ZSwgY2hhaW5hYmxlLCBlbXB0eUdldCwgcmF3ICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bGVuID0gZWxlbXMubGVuZ3RoLFxuXHRcdGJ1bGsgPSBrZXkgPT0gbnVsbDtcblxuXHQvLyBTZXRzIG1hbnkgdmFsdWVzXG5cdGlmICggdG9UeXBlKCBrZXkgKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRjaGFpbmFibGUgPSB0cnVlO1xuXHRcdGZvciAoIGkgaW4ga2V5ICkge1xuXHRcdFx0YWNjZXNzKCBlbGVtcywgZm4sIGksIGtleVsgaSBdLCB0cnVlLCBlbXB0eUdldCwgcmF3ICk7XG5cdFx0fVxuXG5cdC8vIFNldHMgb25lIHZhbHVlXG5cdH0gZWxzZSBpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcblxuXHRcdGlmICggIWlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyYXcgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmICggYnVsayApIHtcblxuXHRcdFx0Ly8gQnVsayBvcGVyYXRpb25zIHJ1biBhZ2FpbnN0IHRoZSBlbnRpcmUgc2V0XG5cdFx0XHRpZiAoIHJhdyApIHtcblx0XHRcdFx0Zm4uY2FsbCggZWxlbXMsIHZhbHVlICk7XG5cdFx0XHRcdGZuID0gbnVsbDtcblxuXHRcdFx0Ly8gLi4uZXhjZXB0IHdoZW4gZXhlY3V0aW5nIGZ1bmN0aW9uIHZhbHVlc1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0YnVsayA9IGZuO1xuXHRcdFx0XHRmbiA9IGZ1bmN0aW9uKCBlbGVtLCBfa2V5LCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gYnVsay5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdmFsdWUgKTtcblx0XHRcdFx0fTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoIGZuICkge1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdGZuKFxuXHRcdFx0XHRcdGVsZW1zWyBpIF0sIGtleSwgcmF3ID9cblx0XHRcdFx0XHR2YWx1ZSA6XG5cdFx0XHRcdFx0dmFsdWUuY2FsbCggZWxlbXNbIGkgXSwgaSwgZm4oIGVsZW1zWyBpIF0sIGtleSApIClcblx0XHRcdFx0KTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRpZiAoIGNoYWluYWJsZSApIHtcblx0XHRyZXR1cm4gZWxlbXM7XG5cdH1cblxuXHQvLyBHZXRzXG5cdGlmICggYnVsayApIHtcblx0XHRyZXR1cm4gZm4uY2FsbCggZWxlbXMgKTtcblx0fVxuXG5cdHJldHVybiBsZW4gPyBmbiggZWxlbXNbIDAgXSwga2V5ICkgOiBlbXB0eUdldDtcbn07XG5cblxuLy8gTWF0Y2hlcyBkYXNoZWQgc3RyaW5nIGZvciBjYW1lbGl6aW5nXG52YXIgcm1zUHJlZml4ID0gL14tbXMtLyxcblx0cmRhc2hBbHBoYSA9IC8tKFthLXpdKS9nO1xuXG4vLyBVc2VkIGJ5IGNhbWVsQ2FzZSBhcyBjYWxsYmFjayB0byByZXBsYWNlKClcbmZ1bmN0aW9uIGZjYW1lbENhc2UoIF9hbGwsIGxldHRlciApIHtcblx0cmV0dXJuIGxldHRlci50b1VwcGVyQ2FzZSgpO1xufVxuXG4vLyBDb252ZXJ0IGRhc2hlZCB0byBjYW1lbENhc2U7IHVzZWQgYnkgdGhlIGNzcyBhbmQgZGF0YSBtb2R1bGVzXG4vLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSwgRWRnZSAxMiAtIDE1XG4vLyBNaWNyb3NvZnQgZm9yZ290IHRvIGh1bXAgdGhlaXIgdmVuZG9yIHByZWZpeCAoIzk1NzIpXG5mdW5jdGlvbiBjYW1lbENhc2UoIHN0cmluZyApIHtcblx0cmV0dXJuIHN0cmluZy5yZXBsYWNlKCBybXNQcmVmaXgsIFwibXMtXCIgKS5yZXBsYWNlKCByZGFzaEFscGhhLCBmY2FtZWxDYXNlICk7XG59XG52YXIgYWNjZXB0RGF0YSA9IGZ1bmN0aW9uKCBvd25lciApIHtcblxuXHQvLyBBY2NlcHRzIG9ubHk6XG5cdC8vICAtIE5vZGVcblx0Ly8gICAgLSBOb2RlLkVMRU1FTlRfTk9ERVxuXHQvLyAgICAtIE5vZGUuRE9DVU1FTlRfTk9ERVxuXHQvLyAgLSBPYmplY3Rcblx0Ly8gICAgLSBBbnlcblx0cmV0dXJuIG93bmVyLm5vZGVUeXBlID09PSAxIHx8IG93bmVyLm5vZGVUeXBlID09PSA5IHx8ICEoICtvd25lci5ub2RlVHlwZSApO1xufTtcblxuXG5cblxuZnVuY3Rpb24gRGF0YSgpIHtcblx0dGhpcy5leHBhbmRvID0galF1ZXJ5LmV4cGFuZG8gKyBEYXRhLnVpZCsrO1xufVxuXG5EYXRhLnVpZCA9IDE7XG5cbkRhdGEucHJvdG90eXBlID0ge1xuXG5cdGNhY2hlOiBmdW5jdGlvbiggb3duZXIgKSB7XG5cblx0XHQvLyBDaGVjayBpZiB0aGUgb3duZXIgb2JqZWN0IGFscmVhZHkgaGFzIGEgY2FjaGVcblx0XHR2YXIgdmFsdWUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cblx0XHQvLyBJZiBub3QsIGNyZWF0ZSBvbmVcblx0XHRpZiAoICF2YWx1ZSApIHtcblx0XHRcdHZhbHVlID0ge307XG5cblx0XHRcdC8vIFdlIGNhbiBhY2NlcHQgZGF0YSBmb3Igbm9uLWVsZW1lbnQgbm9kZXMgaW4gbW9kZXJuIGJyb3dzZXJzLFxuXHRcdFx0Ly8gYnV0IHdlIHNob3VsZCBub3QsIHNlZSAjODMzNS5cblx0XHRcdC8vIEFsd2F5cyByZXR1cm4gYW4gZW1wdHkgb2JqZWN0LlxuXHRcdFx0aWYgKCBhY2NlcHREYXRhKCBvd25lciApICkge1xuXG5cdFx0XHRcdC8vIElmIGl0IGlzIGEgbm9kZSB1bmxpa2VseSB0byBiZSBzdHJpbmdpZnktZWQgb3IgbG9vcGVkIG92ZXJcblx0XHRcdFx0Ly8gdXNlIHBsYWluIGFzc2lnbm1lbnRcblx0XHRcdFx0aWYgKCBvd25lci5ub2RlVHlwZSApIHtcblx0XHRcdFx0XHRvd25lclsgdGhpcy5leHBhbmRvIF0gPSB2YWx1ZTtcblxuXHRcdFx0XHQvLyBPdGhlcndpc2Ugc2VjdXJlIGl0IGluIGEgbm9uLWVudW1lcmFibGUgcHJvcGVydHlcblx0XHRcdFx0Ly8gY29uZmlndXJhYmxlIG11c3QgYmUgdHJ1ZSB0byBhbGxvdyB0aGUgcHJvcGVydHkgdG8gYmVcblx0XHRcdFx0Ly8gZGVsZXRlZCB3aGVuIGRhdGEgaXMgcmVtb3ZlZFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggb3duZXIsIHRoaXMuZXhwYW5kbywge1xuXHRcdFx0XHRcdFx0dmFsdWU6IHZhbHVlLFxuXHRcdFx0XHRcdFx0Y29uZmlndXJhYmxlOiB0cnVlXG5cdFx0XHRcdFx0fSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9LFxuXHRzZXQ6IGZ1bmN0aW9uKCBvd25lciwgZGF0YSwgdmFsdWUgKSB7XG5cdFx0dmFyIHByb3AsXG5cdFx0XHRjYWNoZSA9IHRoaXMuY2FjaGUoIG93bmVyICk7XG5cblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIGtleSwgdmFsdWUgXSBhcmdzXG5cdFx0Ly8gQWx3YXlzIHVzZSBjYW1lbENhc2Uga2V5IChnaC0yMjU3KVxuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRjYWNoZVsgY2FtZWxDYXNlKCBkYXRhICkgXSA9IHZhbHVlO1xuXG5cdFx0Ly8gSGFuZGxlOiBbIG93bmVyLCB7IHByb3BlcnRpZXMgfSBdIGFyZ3Ncblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyBDb3B5IHRoZSBwcm9wZXJ0aWVzIG9uZS1ieS1vbmUgdG8gdGhlIGNhY2hlIG9iamVjdFxuXHRcdFx0Zm9yICggcHJvcCBpbiBkYXRhICkge1xuXHRcdFx0XHRjYWNoZVsgY2FtZWxDYXNlKCBwcm9wICkgXSA9IGRhdGFbIHByb3AgXTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGNhY2hlO1xuXHR9LFxuXHRnZXQ6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xuXHRcdHJldHVybiBrZXkgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHR0aGlzLmNhY2hlKCBvd25lciApIDpcblxuXHRcdFx0Ly8gQWx3YXlzIHVzZSBjYW1lbENhc2Uga2V5IChnaC0yMjU3KVxuXHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdICYmIG93bmVyWyB0aGlzLmV4cGFuZG8gXVsgY2FtZWxDYXNlKCBrZXkgKSBdO1xuXHR9LFxuXHRhY2Nlc3M6IGZ1bmN0aW9uKCBvd25lciwga2V5LCB2YWx1ZSApIHtcblxuXHRcdC8vIEluIGNhc2VzIHdoZXJlIGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gTm8ga2V5IHdhcyBzcGVjaWZpZWRcblx0XHQvLyAgIDIuIEEgc3RyaW5nIGtleSB3YXMgc3BlY2lmaWVkLCBidXQgbm8gdmFsdWUgcHJvdmlkZWRcblx0XHQvL1xuXHRcdC8vIFRha2UgdGhlIFwicmVhZFwiIHBhdGggYW5kIGFsbG93IHRoZSBnZXQgbWV0aG9kIHRvIGRldGVybWluZVxuXHRcdC8vIHdoaWNoIHZhbHVlIHRvIHJldHVybiwgcmVzcGVjdGl2ZWx5IGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gVGhlIGVudGlyZSBjYWNoZSBvYmplY3Rcblx0XHQvLyAgIDIuIFRoZSBkYXRhIHN0b3JlZCBhdCB0aGUga2V5XG5cdFx0Ly9cblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkIHx8XG5cdFx0XHRcdCggKCBrZXkgJiYgdHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiApICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSApIHtcblxuXHRcdFx0cmV0dXJuIHRoaXMuZ2V0KCBvd25lciwga2V5ICk7XG5cdFx0fVxuXG5cdFx0Ly8gV2hlbiB0aGUga2V5IGlzIG5vdCBhIHN0cmluZywgb3IgYm90aCBhIGtleSBhbmQgdmFsdWVcblx0XHQvLyBhcmUgc3BlY2lmaWVkLCBzZXQgb3IgZXh0ZW5kIChleGlzdGluZyBvYmplY3RzKSB3aXRoIGVpdGhlcjpcblx0XHQvL1xuXHRcdC8vICAgMS4gQW4gb2JqZWN0IG9mIHByb3BlcnRpZXNcblx0XHQvLyAgIDIuIEEga2V5IGFuZCB2YWx1ZVxuXHRcdC8vXG5cdFx0dGhpcy5zZXQoIG93bmVyLCBrZXksIHZhbHVlICk7XG5cblx0XHQvLyBTaW5jZSB0aGUgXCJzZXRcIiBwYXRoIGNhbiBoYXZlIHR3byBwb3NzaWJsZSBlbnRyeSBwb2ludHNcblx0XHQvLyByZXR1cm4gdGhlIGV4cGVjdGVkIGRhdGEgYmFzZWQgb24gd2hpY2ggcGF0aCB3YXMgdGFrZW5bKl1cblx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDoga2V5O1xuXHR9LFxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xuXHRcdHZhciBpLFxuXHRcdFx0Y2FjaGUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cblx0XHRpZiAoIGNhY2hlID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCBrZXkgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0Ly8gU3VwcG9ydCBhcnJheSBvciBzcGFjZSBzZXBhcmF0ZWQgc3RyaW5nIG9mIGtleXNcblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSgga2V5ICkgKSB7XG5cblx0XHRcdFx0Ly8gSWYga2V5IGlzIGFuIGFycmF5IG9mIGtleXMuLi5cblx0XHRcdFx0Ly8gV2UgYWx3YXlzIHNldCBjYW1lbENhc2Uga2V5cywgc28gcmVtb3ZlIHRoYXQuXG5cdFx0XHRcdGtleSA9IGtleS5tYXAoIGNhbWVsQ2FzZSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0a2V5ID0gY2FtZWxDYXNlKCBrZXkgKTtcblxuXHRcdFx0XHQvLyBJZiBhIGtleSB3aXRoIHRoZSBzcGFjZXMgZXhpc3RzLCB1c2UgaXQuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSwgY3JlYXRlIGFuIGFycmF5IGJ5IG1hdGNoaW5nIG5vbi13aGl0ZXNwYWNlXG5cdFx0XHRcdGtleSA9IGtleSBpbiBjYWNoZSA/XG5cdFx0XHRcdFx0WyBrZXkgXSA6XG5cdFx0XHRcdFx0KCBrZXkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbXSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpID0ga2V5Lmxlbmd0aDtcblxuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGRlbGV0ZSBjYWNoZVsga2V5WyBpIF0gXTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBSZW1vdmUgdGhlIGV4cGFuZG8gaWYgdGhlcmUncyBubyBtb3JlIGRhdGFcblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkIHx8IGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBjYWNoZSApICkge1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0zNSAtIDQ1XG5cdFx0XHQvLyBXZWJraXQgJiBCbGluayBwZXJmb3JtYW5jZSBzdWZmZXJzIHdoZW4gZGVsZXRpbmcgcHJvcGVydGllc1xuXHRcdFx0Ly8gZnJvbSBET00gbm9kZXMsIHNvIHNldCB0byB1bmRlZmluZWQgaW5zdGVhZFxuXHRcdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9Mzc4NjA3IChidWcgcmVzdHJpY3RlZClcblx0XHRcdGlmICggb3duZXIubm9kZVR5cGUgKSB7XG5cdFx0XHRcdG93bmVyWyB0aGlzLmV4cGFuZG8gXSA9IHVuZGVmaW5lZDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlbGV0ZSBvd25lclsgdGhpcy5leHBhbmRvIF07XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRoYXNEYXRhOiBmdW5jdGlvbiggb3duZXIgKSB7XG5cdFx0dmFyIGNhY2hlID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xuXHRcdHJldHVybiBjYWNoZSAhPT0gdW5kZWZpbmVkICYmICFqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKTtcblx0fVxufTtcbnZhciBkYXRhUHJpdiA9IG5ldyBEYXRhKCk7XG5cbnZhciBkYXRhVXNlciA9IG5ldyBEYXRhKCk7XG5cblxuXG4vL1x0SW1wbGVtZW50YXRpb24gU3VtbWFyeVxuLy9cbi8vXHQxLiBFbmZvcmNlIEFQSSBzdXJmYWNlIGFuZCBzZW1hbnRpYyBjb21wYXRpYmlsaXR5IHdpdGggMS45LnggYnJhbmNoXG4vL1x0Mi4gSW1wcm92ZSB0aGUgbW9kdWxlJ3MgbWFpbnRhaW5hYmlsaXR5IGJ5IHJlZHVjaW5nIHRoZSBzdG9yYWdlXG4vL1x0XHRwYXRocyB0byBhIHNpbmdsZSBtZWNoYW5pc20uXG4vL1x0My4gVXNlIHRoZSBzYW1lIHNpbmdsZSBtZWNoYW5pc20gdG8gc3VwcG9ydCBcInByaXZhdGVcIiBhbmQgXCJ1c2VyXCIgZGF0YS5cbi8vXHQ0LiBfTmV2ZXJfIGV4cG9zZSBcInByaXZhdGVcIiBkYXRhIHRvIHVzZXIgY29kZSAoVE9ETzogRHJvcCBfZGF0YSwgX3JlbW92ZURhdGEpXG4vL1x0NS4gQXZvaWQgZXhwb3NpbmcgaW1wbGVtZW50YXRpb24gZGV0YWlscyBvbiB1c2VyIG9iamVjdHMgKGVnLiBleHBhbmRvIHByb3BlcnRpZXMpXG4vL1x0Ni4gUHJvdmlkZSBhIGNsZWFyIHBhdGggZm9yIGltcGxlbWVudGF0aW9uIHVwZ3JhZGUgdG8gV2Vha01hcCBpbiAyMDE0XG5cbnZhciByYnJhY2UgPSAvXig/Olxce1tcXHdcXFddKlxcfXxcXFtbXFx3XFxXXSpcXF0pJC8sXG5cdHJtdWx0aURhc2ggPSAvW0EtWl0vZztcblxuZnVuY3Rpb24gZ2V0RGF0YSggZGF0YSApIHtcblx0aWYgKCBkYXRhID09PSBcInRydWVcIiApIHtcblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxuXG5cdGlmICggZGF0YSA9PT0gXCJmYWxzZVwiICkge1xuXHRcdHJldHVybiBmYWxzZTtcblx0fVxuXG5cdGlmICggZGF0YSA9PT0gXCJudWxsXCIgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblxuXHQvLyBPbmx5IGNvbnZlcnQgdG8gYSBudW1iZXIgaWYgaXQgZG9lc24ndCBjaGFuZ2UgdGhlIHN0cmluZ1xuXHRpZiAoIGRhdGEgPT09ICtkYXRhICsgXCJcIiApIHtcblx0XHRyZXR1cm4gK2RhdGE7XG5cdH1cblxuXHRpZiAoIHJicmFjZS50ZXN0KCBkYXRhICkgKSB7XG5cdFx0cmV0dXJuIEpTT04ucGFyc2UoIGRhdGEgKTtcblx0fVxuXG5cdHJldHVybiBkYXRhO1xufVxuXG5mdW5jdGlvbiBkYXRhQXR0ciggZWxlbSwga2V5LCBkYXRhICkge1xuXHR2YXIgbmFtZTtcblxuXHQvLyBJZiBub3RoaW5nIHdhcyBmb3VuZCBpbnRlcm5hbGx5LCB0cnkgdG8gZmV0Y2ggYW55XG5cdC8vIGRhdGEgZnJvbSB0aGUgSFRNTDUgZGF0YS0qIGF0dHJpYnV0ZVxuXHRpZiAoIGRhdGEgPT09IHVuZGVmaW5lZCAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdG5hbWUgPSBcImRhdGEtXCIgKyBrZXkucmVwbGFjZSggcm11bHRpRGFzaCwgXCItJCZcIiApLnRvTG93ZXJDYXNlKCk7XG5cdFx0ZGF0YSA9IGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lICk7XG5cblx0XHRpZiAoIHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0ZGF0YSA9IGdldERhdGEoIGRhdGEgKTtcblx0XHRcdH0gY2F0Y2ggKCBlICkge31cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHdlIHNldCB0aGUgZGF0YSBzbyBpdCBpc24ndCBjaGFuZ2VkIGxhdGVyXG5cdFx0XHRkYXRhVXNlci5zZXQoIGVsZW0sIGtleSwgZGF0YSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0fVxuXHRyZXR1cm4gZGF0YTtcbn1cblxualF1ZXJ5LmV4dGVuZCgge1xuXHRoYXNEYXRhOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZGF0YVVzZXIuaGFzRGF0YSggZWxlbSApIHx8IGRhdGFQcml2Lmhhc0RhdGEoIGVsZW0gKTtcblx0fSxcblxuXHRkYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gZGF0YVVzZXIuYWNjZXNzKCBlbGVtLCBuYW1lLCBkYXRhICk7XG5cdH0sXG5cblx0cmVtb3ZlRGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XG5cdFx0ZGF0YVVzZXIucmVtb3ZlKCBlbGVtLCBuYW1lICk7XG5cdH0sXG5cblx0Ly8gVE9ETzogTm93IHRoYXQgYWxsIGNhbGxzIHRvIF9kYXRhIGFuZCBfcmVtb3ZlRGF0YSBoYXZlIGJlZW4gcmVwbGFjZWRcblx0Ly8gd2l0aCBkaXJlY3QgY2FsbHMgdG8gZGF0YVByaXYgbWV0aG9kcywgdGhlc2UgY2FuIGJlIGRlcHJlY2F0ZWQuXG5cdF9kYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBuYW1lLCBkYXRhICk7XG5cdH0sXG5cblx0X3JlbW92ZURhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgbmFtZSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0ZGF0YTogZnVuY3Rpb24oIGtleSwgdmFsdWUgKSB7XG5cdFx0dmFyIGksIG5hbWUsIGRhdGEsXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdLFxuXHRcdFx0YXR0cnMgPSBlbGVtICYmIGVsZW0uYXR0cmlidXRlcztcblxuXHRcdC8vIEdldHMgYWxsIHZhbHVlc1xuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRpZiAoIHRoaXMubGVuZ3RoICkge1xuXHRcdFx0XHRkYXRhID0gZGF0YVVzZXIuZ2V0KCBlbGVtICk7XG5cblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICFkYXRhUHJpdi5nZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIgKSApIHtcblx0XHRcdFx0XHRpID0gYXR0cnMubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSBvbmx5XG5cdFx0XHRcdFx0XHQvLyBUaGUgYXR0cnMgZWxlbWVudHMgY2FuIGJlIG51bGwgKCMxNDg5NClcblx0XHRcdFx0XHRcdGlmICggYXR0cnNbIGkgXSApIHtcblx0XHRcdFx0XHRcdFx0bmFtZSA9IGF0dHJzWyBpIF0ubmFtZTtcblx0XHRcdFx0XHRcdFx0aWYgKCBuYW1lLmluZGV4T2YoIFwiZGF0YS1cIiApID09PSAwICkge1xuXHRcdFx0XHRcdFx0XHRcdG5hbWUgPSBjYW1lbENhc2UoIG5hbWUuc2xpY2UoIDUgKSApO1xuXHRcdFx0XHRcdFx0XHRcdGRhdGFBdHRyKCBlbGVtLCBuYW1lLCBkYXRhWyBuYW1lIF0gKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZGF0YTtcblx0XHR9XG5cblx0XHQvLyBTZXRzIG11bHRpcGxlIHZhbHVlc1xuXHRcdGlmICggdHlwZW9mIGtleSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhVXNlci5zZXQoIHRoaXMsIGtleSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBkYXRhO1xuXG5cdFx0XHQvLyBUaGUgY2FsbGluZyBqUXVlcnkgb2JqZWN0IChlbGVtZW50IG1hdGNoZXMpIGlzIG5vdCBlbXB0eVxuXHRcdFx0Ly8gKGFuZCB0aGVyZWZvcmUgaGFzIGFuIGVsZW1lbnQgYXBwZWFycyBhdCB0aGlzWyAwIF0pIGFuZCB0aGVcblx0XHRcdC8vIGB2YWx1ZWAgcGFyYW1ldGVyIHdhcyBub3QgdW5kZWZpbmVkLiBBbiBlbXB0eSBqUXVlcnkgb2JqZWN0XG5cdFx0XHQvLyB3aWxsIHJlc3VsdCBpbiBgdW5kZWZpbmVkYCBmb3IgZWxlbSA9IHRoaXNbIDAgXSB3aGljaCB3aWxsXG5cdFx0XHQvLyB0aHJvdyBhbiBleGNlcHRpb24gaWYgYW4gYXR0ZW1wdCB0byByZWFkIGEgZGF0YSBjYWNoZSBpcyBtYWRlLlxuXHRcdFx0aWYgKCBlbGVtICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSB7XG5cblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBnZXQgZGF0YSBmcm9tIHRoZSBjYWNoZVxuXHRcdFx0XHQvLyBUaGUga2V5IHdpbGwgYWx3YXlzIGJlIGNhbWVsQ2FzZWQgaW4gRGF0YVxuXHRcdFx0XHRkYXRhID0gZGF0YVVzZXIuZ2V0KCBlbGVtLCBrZXkgKTtcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGRhdGE7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBBdHRlbXB0IHRvIFwiZGlzY292ZXJcIiB0aGUgZGF0YSBpblxuXHRcdFx0XHQvLyBIVE1MNSBjdXN0b20gZGF0YS0qIGF0dHJzXG5cdFx0XHRcdGRhdGEgPSBkYXRhQXR0ciggZWxlbSwga2V5ICk7XG5cdFx0XHRcdGlmICggZGF0YSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gV2UgdHJpZWQgcmVhbGx5IGhhcmQsIGJ1dCB0aGUgZGF0YSBkb2Vzbid0IGV4aXN0LlxuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCB0aGUgZGF0YS4uLlxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBXZSBhbHdheXMgc3RvcmUgdGhlIGNhbWVsQ2FzZWQga2V5XG5cdFx0XHRcdGRhdGFVc2VyLnNldCggdGhpcywga2V5LCB2YWx1ZSApO1xuXHRcdFx0fSApO1xuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSwgbnVsbCwgdHJ1ZSApO1xuXHR9LFxuXG5cdHJlbW92ZURhdGE6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRkYXRhVXNlci5yZW1vdmUoIHRoaXMsIGtleSApO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5cbmpRdWVyeS5leHRlbmQoIHtcblx0cXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBkYXRhICkge1xuXHRcdHZhciBxdWV1ZTtcblxuXHRcdGlmICggZWxlbSApIHtcblx0XHRcdHR5cGUgPSAoIHR5cGUgfHwgXCJmeFwiICkgKyBcInF1ZXVlXCI7XG5cdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmdldCggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHQvLyBTcGVlZCB1cCBkZXF1ZXVlIGJ5IGdldHRpbmcgb3V0IHF1aWNrbHkgaWYgdGhpcyBpcyBqdXN0IGEgbG9va3VwXG5cdFx0XHRpZiAoIGRhdGEgKSB7XG5cdFx0XHRcdGlmICggIXF1ZXVlIHx8IEFycmF5LmlzQXJyYXkoIGRhdGEgKSApIHtcblx0XHRcdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmFjY2VzcyggZWxlbSwgdHlwZSwgalF1ZXJ5Lm1ha2VBcnJheSggZGF0YSApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0cXVldWUucHVzaCggZGF0YSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcXVldWUgfHwgW107XG5cdFx0fVxuXHR9LFxuXG5cdGRlcXVldWU6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRcdHZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggZWxlbSwgdHlwZSApLFxuXHRcdFx0c3RhcnRMZW5ndGggPSBxdWV1ZS5sZW5ndGgsXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCksXG5cdFx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgdHlwZSApLFxuXHRcdFx0bmV4dCA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggZWxlbSwgdHlwZSApO1xuXHRcdFx0fTtcblxuXHRcdC8vIElmIHRoZSBmeCBxdWV1ZSBpcyBkZXF1ZXVlZCwgYWx3YXlzIHJlbW92ZSB0aGUgcHJvZ3Jlc3Mgc2VudGluZWxcblx0XHRpZiAoIGZuID09PSBcImlucHJvZ3Jlc3NcIiApIHtcblx0XHRcdGZuID0gcXVldWUuc2hpZnQoKTtcblx0XHRcdHN0YXJ0TGVuZ3RoLS07XG5cdFx0fVxuXG5cdFx0aWYgKCBmbiApIHtcblxuXHRcdFx0Ly8gQWRkIGEgcHJvZ3Jlc3Mgc2VudGluZWwgdG8gcHJldmVudCB0aGUgZnggcXVldWUgZnJvbSBiZWluZ1xuXHRcdFx0Ly8gYXV0b21hdGljYWxseSBkZXF1ZXVlZFxuXHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgKSB7XG5cdFx0XHRcdHF1ZXVlLnVuc2hpZnQoIFwiaW5wcm9ncmVzc1wiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENsZWFyIHVwIHRoZSBsYXN0IHF1ZXVlIHN0b3AgZnVuY3Rpb25cblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xuXHRcdFx0Zm4uY2FsbCggZWxlbSwgbmV4dCwgaG9va3MgKTtcblx0XHR9XG5cblx0XHRpZiAoICFzdGFydExlbmd0aCAmJiBob29rcyApIHtcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHR9XG5cdH0sXG5cblx0Ly8gTm90IHB1YmxpYyAtIGdlbmVyYXRlIGEgcXVldWVIb29rcyBvYmplY3QsIG9yIHJldHVybiB0aGUgY3VycmVudCBvbmVcblx0X3F1ZXVlSG9va3M6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlICkge1xuXHRcdHZhciBrZXkgPSB0eXBlICsgXCJxdWV1ZUhvb2tzXCI7XG5cdFx0cmV0dXJuIGRhdGFQcml2LmdldCggZWxlbSwga2V5ICkgfHwgZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBrZXksIHtcblx0XHRcdGVtcHR5OiBqUXVlcnkuQ2FsbGJhY2tzKCBcIm9uY2UgbWVtb3J5XCIgKS5hZGQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFsgdHlwZSArIFwicXVldWVcIiwga2V5IF0gKTtcblx0XHRcdH0gKVxuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHF1ZXVlOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgc2V0dGVyID0gMjtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRkYXRhID0gdHlwZTtcblx0XHRcdHR5cGUgPSBcImZ4XCI7XG5cdFx0XHRzZXR0ZXItLTtcblx0XHR9XG5cblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPCBzZXR0ZXIgKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LnF1ZXVlKCB0aGlzWyAwIF0sIHR5cGUgKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZGF0YSA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHRoaXMgOlxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCB0aGlzLCB0eXBlLCBkYXRhICk7XG5cblx0XHRcdFx0Ly8gRW5zdXJlIGEgaG9va3MgZm9yIHRoaXMgcXVldWVcblx0XHRcdFx0alF1ZXJ5Ll9xdWV1ZUhvb2tzKCB0aGlzLCB0eXBlICk7XG5cblx0XHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgJiYgcXVldWVbIDAgXSAhPT0gXCJpbnByb2dyZXNzXCIgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHR9LFxuXHRkZXF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0fSApO1xuXHR9LFxuXHRjbGVhclF1ZXVlOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSB8fCBcImZ4XCIsIFtdICk7XG5cdH0sXG5cblx0Ly8gR2V0IGEgcHJvbWlzZSByZXNvbHZlZCB3aGVuIHF1ZXVlcyBvZiBhIGNlcnRhaW4gdHlwZVxuXHQvLyBhcmUgZW1wdGllZCAoZnggaXMgdGhlIHR5cGUgYnkgZGVmYXVsdClcblx0cHJvbWlzZTogZnVuY3Rpb24oIHR5cGUsIG9iaiApIHtcblx0XHR2YXIgdG1wLFxuXHRcdFx0Y291bnQgPSAxLFxuXHRcdFx0ZGVmZXIgPSBqUXVlcnkuRGVmZXJyZWQoKSxcblx0XHRcdGVsZW1lbnRzID0gdGhpcyxcblx0XHRcdGkgPSB0aGlzLmxlbmd0aCxcblx0XHRcdHJlc29sdmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhKCAtLWNvdW50ICkgKSB7XG5cdFx0XHRcdFx0ZGVmZXIucmVzb2x2ZVdpdGgoIGVsZW1lbnRzLCBbIGVsZW1lbnRzIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRvYmogPSB0eXBlO1xuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHR0bXAgPSBkYXRhUHJpdi5nZXQoIGVsZW1lbnRzWyBpIF0sIHR5cGUgKyBcInF1ZXVlSG9va3NcIiApO1xuXHRcdFx0aWYgKCB0bXAgJiYgdG1wLmVtcHR5ICkge1xuXHRcdFx0XHRjb3VudCsrO1xuXHRcdFx0XHR0bXAuZW1wdHkuYWRkKCByZXNvbHZlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJlc29sdmUoKTtcblx0XHRyZXR1cm4gZGVmZXIucHJvbWlzZSggb2JqICk7XG5cdH1cbn0gKTtcbnZhciBwbnVtID0gKCAvWystXT8oPzpcXGQqXFwufClcXGQrKD86W2VFXVsrLV0/XFxkK3wpLyApLnNvdXJjZTtcblxudmFyIHJjc3NOdW0gPSBuZXcgUmVnRXhwKCBcIl4oPzooWystXSk9fCkoXCIgKyBwbnVtICsgXCIpKFthLXolXSopJFwiLCBcImlcIiApO1xuXG5cbnZhciBjc3NFeHBhbmQgPSBbIFwiVG9wXCIsIFwiUmlnaHRcIiwgXCJCb3R0b21cIiwgXCJMZWZ0XCIgXTtcblxudmFyIGRvY3VtZW50RWxlbWVudCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuXG5cblx0dmFyIGlzQXR0YWNoZWQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApO1xuXHRcdH0sXG5cdFx0Y29tcG9zZWQgPSB7IGNvbXBvc2VkOiB0cnVlIH07XG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExKywgRWRnZSAxMiAtIDE4KywgaU9TIDEwLjAgLSAxMC4yIG9ubHlcblx0Ly8gQ2hlY2sgYXR0YWNobWVudCBhY3Jvc3Mgc2hhZG93IERPTSBib3VuZGFyaWVzIHdoZW4gcG9zc2libGUgKGdoLTM1MDQpXG5cdC8vIFN1cHBvcnQ6IGlPUyAxMC4wLTEwLjIgb25seVxuXHQvLyBFYXJseSBpT1MgMTAgdmVyc2lvbnMgc3VwcG9ydCBgYXR0YWNoU2hhZG93YCBidXQgbm90IGBnZXRSb290Tm9kZWAsXG5cdC8vIGxlYWRpbmcgdG8gZXJyb3JzLiBXZSBuZWVkIHRvIGNoZWNrIGZvciBgZ2V0Um9vdE5vZGVgLlxuXHRpZiAoIGRvY3VtZW50RWxlbWVudC5nZXRSb290Tm9kZSApIHtcblx0XHRpc0F0dGFjaGVkID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKSB8fFxuXHRcdFx0XHRlbGVtLmdldFJvb3ROb2RlKCBjb21wb3NlZCApID09PSBlbGVtLm93bmVyRG9jdW1lbnQ7XG5cdFx0fTtcblx0fVxudmFyIGlzSGlkZGVuV2l0aGluVHJlZSA9IGZ1bmN0aW9uKCBlbGVtLCBlbCApIHtcblxuXHRcdC8vIGlzSGlkZGVuV2l0aGluVHJlZSBtaWdodCBiZSBjYWxsZWQgZnJvbSBqUXVlcnkjZmlsdGVyIGZ1bmN0aW9uO1xuXHRcdC8vIGluIHRoYXQgY2FzZSwgZWxlbWVudCB3aWxsIGJlIHNlY29uZCBhcmd1bWVudFxuXHRcdGVsZW0gPSBlbCB8fCBlbGVtO1xuXG5cdFx0Ly8gSW5saW5lIHN0eWxlIHRydW1wcyBhbGxcblx0XHRyZXR1cm4gZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIm5vbmVcIiB8fFxuXHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmXG5cblx0XHRcdC8vIE90aGVyd2lzZSwgY2hlY2sgY29tcHV0ZWQgc3R5bGVcblx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD00MyAtIDQ1XG5cdFx0XHQvLyBEaXNjb25uZWN0ZWQgZWxlbWVudHMgY2FuIGhhdmUgY29tcHV0ZWQgZGlzcGxheTogbm9uZSwgc28gZmlyc3QgY29uZmlybSB0aGF0IGVsZW0gaXNcblx0XHRcdC8vIGluIHRoZSBkb2N1bWVudC5cblx0XHRcdGlzQXR0YWNoZWQoIGVsZW0gKSAmJlxuXG5cdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApID09PSBcIm5vbmVcIjtcblx0fTtcblxuXG5cbmZ1bmN0aW9uIGFkanVzdENTUyggZWxlbSwgcHJvcCwgdmFsdWVQYXJ0cywgdHdlZW4gKSB7XG5cdHZhciBhZGp1c3RlZCwgc2NhbGUsXG5cdFx0bWF4SXRlcmF0aW9ucyA9IDIwLFxuXHRcdGN1cnJlbnRWYWx1ZSA9IHR3ZWVuID9cblx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gdHdlZW4uY3VyKCk7XG5cdFx0XHR9IDpcblx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4galF1ZXJ5LmNzcyggZWxlbSwgcHJvcCwgXCJcIiApO1xuXHRcdFx0fSxcblx0XHRpbml0aWFsID0gY3VycmVudFZhbHVlKCksXG5cdFx0dW5pdCA9IHZhbHVlUGFydHMgJiYgdmFsdWVQYXJ0c1sgMyBdIHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApLFxuXG5cdFx0Ly8gU3RhcnRpbmcgdmFsdWUgY29tcHV0YXRpb24gaXMgcmVxdWlyZWQgZm9yIHBvdGVudGlhbCB1bml0IG1pc21hdGNoZXNcblx0XHRpbml0aWFsSW5Vbml0ID0gZWxlbS5ub2RlVHlwZSAmJlxuXHRcdFx0KCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gfHwgdW5pdCAhPT0gXCJweFwiICYmICtpbml0aWFsICkgJiZcblx0XHRcdHJjc3NOdW0uZXhlYyggalF1ZXJ5LmNzcyggZWxlbSwgcHJvcCApICk7XG5cblx0aWYgKCBpbml0aWFsSW5Vbml0ICYmIGluaXRpYWxJblVuaXRbIDMgXSAhPT0gdW5pdCApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD01NFxuXHRcdC8vIEhhbHZlIHRoZSBpdGVyYXRpb24gdGFyZ2V0IHZhbHVlIHRvIHByZXZlbnQgaW50ZXJmZXJlbmNlIGZyb20gQ1NTIHVwcGVyIGJvdW5kcyAoZ2gtMjE0NClcblx0XHRpbml0aWFsID0gaW5pdGlhbCAvIDI7XG5cblx0XHQvLyBUcnVzdCB1bml0cyByZXBvcnRlZCBieSBqUXVlcnkuY3NzXG5cdFx0dW5pdCA9IHVuaXQgfHwgaW5pdGlhbEluVW5pdFsgMyBdO1xuXG5cdFx0Ly8gSXRlcmF0aXZlbHkgYXBwcm94aW1hdGUgZnJvbSBhIG5vbnplcm8gc3RhcnRpbmcgcG9pbnRcblx0XHRpbml0aWFsSW5Vbml0ID0gK2luaXRpYWwgfHwgMTtcblxuXHRcdHdoaWxlICggbWF4SXRlcmF0aW9ucy0tICkge1xuXG5cdFx0XHQvLyBFdmFsdWF0ZSBhbmQgdXBkYXRlIG91ciBiZXN0IGd1ZXNzIChkb3VibGluZyBndWVzc2VzIHRoYXQgemVybyBvdXQpLlxuXHRcdFx0Ly8gRmluaXNoIGlmIHRoZSBzY2FsZSBlcXVhbHMgb3IgY3Jvc3NlcyAxIChtYWtpbmcgdGhlIG9sZCpuZXcgcHJvZHVjdCBub24tcG9zaXRpdmUpLlxuXHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBpbml0aWFsSW5Vbml0ICsgdW5pdCApO1xuXHRcdFx0aWYgKCAoIDEgLSBzY2FsZSApICogKCAxIC0gKCBzY2FsZSA9IGN1cnJlbnRWYWx1ZSgpIC8gaW5pdGlhbCB8fCAwLjUgKSApIDw9IDAgKSB7XG5cdFx0XHRcdG1heEl0ZXJhdGlvbnMgPSAwO1xuXHRcdFx0fVxuXHRcdFx0aW5pdGlhbEluVW5pdCA9IGluaXRpYWxJblVuaXQgLyBzY2FsZTtcblxuXHRcdH1cblxuXHRcdGluaXRpYWxJblVuaXQgPSBpbml0aWFsSW5Vbml0ICogMjtcblx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AsIGluaXRpYWxJblVuaXQgKyB1bml0ICk7XG5cblx0XHQvLyBNYWtlIHN1cmUgd2UgdXBkYXRlIHRoZSB0d2VlbiBwcm9wZXJ0aWVzIGxhdGVyIG9uXG5cdFx0dmFsdWVQYXJ0cyA9IHZhbHVlUGFydHMgfHwgW107XG5cdH1cblxuXHRpZiAoIHZhbHVlUGFydHMgKSB7XG5cdFx0aW5pdGlhbEluVW5pdCA9ICtpbml0aWFsSW5Vbml0IHx8ICtpbml0aWFsIHx8IDA7XG5cblx0XHQvLyBBcHBseSByZWxhdGl2ZSBvZmZzZXQgKCs9Ly09KSBpZiBzcGVjaWZpZWRcblx0XHRhZGp1c3RlZCA9IHZhbHVlUGFydHNbIDEgXSA/XG5cdFx0XHRpbml0aWFsSW5Vbml0ICsgKCB2YWx1ZVBhcnRzWyAxIF0gKyAxICkgKiB2YWx1ZVBhcnRzWyAyIF0gOlxuXHRcdFx0K3ZhbHVlUGFydHNbIDIgXTtcblx0XHRpZiAoIHR3ZWVuICkge1xuXHRcdFx0dHdlZW4udW5pdCA9IHVuaXQ7XG5cdFx0XHR0d2Vlbi5zdGFydCA9IGluaXRpYWxJblVuaXQ7XG5cdFx0XHR0d2Vlbi5lbmQgPSBhZGp1c3RlZDtcblx0XHR9XG5cdH1cblx0cmV0dXJuIGFkanVzdGVkO1xufVxuXG5cbnZhciBkZWZhdWx0RGlzcGxheU1hcCA9IHt9O1xuXG5mdW5jdGlvbiBnZXREZWZhdWx0RGlzcGxheSggZWxlbSApIHtcblx0dmFyIHRlbXAsXG5cdFx0ZG9jID0gZWxlbS5vd25lckRvY3VtZW50LFxuXHRcdG5vZGVOYW1lID0gZWxlbS5ub2RlTmFtZSxcblx0XHRkaXNwbGF5ID0gZGVmYXVsdERpc3BsYXlNYXBbIG5vZGVOYW1lIF07XG5cblx0aWYgKCBkaXNwbGF5ICkge1xuXHRcdHJldHVybiBkaXNwbGF5O1xuXHR9XG5cblx0dGVtcCA9IGRvYy5ib2R5LmFwcGVuZENoaWxkKCBkb2MuY3JlYXRlRWxlbWVudCggbm9kZU5hbWUgKSApO1xuXHRkaXNwbGF5ID0galF1ZXJ5LmNzcyggdGVtcCwgXCJkaXNwbGF5XCIgKTtcblxuXHR0ZW1wLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHRlbXAgKTtcblxuXHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdGRpc3BsYXkgPSBcImJsb2NrXCI7XG5cdH1cblx0ZGVmYXVsdERpc3BsYXlNYXBbIG5vZGVOYW1lIF0gPSBkaXNwbGF5O1xuXG5cdHJldHVybiBkaXNwbGF5O1xufVxuXG5mdW5jdGlvbiBzaG93SGlkZSggZWxlbWVudHMsIHNob3cgKSB7XG5cdHZhciBkaXNwbGF5LCBlbGVtLFxuXHRcdHZhbHVlcyA9IFtdLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBlbGVtZW50cy5sZW5ndGg7XG5cblx0Ly8gRGV0ZXJtaW5lIG5ldyBkaXNwbGF5IHZhbHVlIGZvciBlbGVtZW50cyB0aGF0IG5lZWQgdG8gY2hhbmdlXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXHRcdGlmICggIWVsZW0uc3R5bGUgKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHRkaXNwbGF5ID0gZWxlbS5zdHlsZS5kaXNwbGF5O1xuXHRcdGlmICggc2hvdyApIHtcblxuXHRcdFx0Ly8gU2luY2Ugd2UgZm9yY2UgdmlzaWJpbGl0eSB1cG9uIGNhc2NhZGUtaGlkZGVuIGVsZW1lbnRzLCBhbiBpbW1lZGlhdGUgKGFuZCBzbG93KVxuXHRcdFx0Ly8gY2hlY2sgaXMgcmVxdWlyZWQgaW4gdGhpcyBmaXJzdCBsb29wIHVubGVzcyB3ZSBoYXZlIGEgbm9uZW1wdHkgZGlzcGxheSB2YWx1ZSAoZWl0aGVyXG5cdFx0XHQvLyBpbmxpbmUgb3IgYWJvdXQtdG8tYmUtcmVzdG9yZWQpXG5cdFx0XHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBkYXRhUHJpdi5nZXQoIGVsZW0sIFwiZGlzcGxheVwiICkgfHwgbnVsbDtcblx0XHRcdFx0aWYgKCAhdmFsdWVzWyBpbmRleCBdICkge1xuXHRcdFx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9IFwiXCI7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGlmICggZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmIGlzSGlkZGVuV2l0aGluVHJlZSggZWxlbSApICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBnZXREZWZhdWx0RGlzcGxheSggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIGRpc3BsYXkgIT09IFwibm9uZVwiICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBcIm5vbmVcIjtcblxuXHRcdFx0XHQvLyBSZW1lbWJlciB3aGF0IHdlJ3JlIG92ZXJ3cml0aW5nXG5cdFx0XHRcdGRhdGFQcml2LnNldCggZWxlbSwgXCJkaXNwbGF5XCIsIGRpc3BsYXkgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBTZXQgdGhlIGRpc3BsYXkgb2YgdGhlIGVsZW1lbnRzIGluIGEgc2Vjb25kIGxvb3AgdG8gYXZvaWQgY29uc3RhbnQgcmVmbG93XG5cdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0aWYgKCB2YWx1ZXNbIGluZGV4IF0gIT0gbnVsbCApIHtcblx0XHRcdGVsZW1lbnRzWyBpbmRleCBdLnN0eWxlLmRpc3BsYXkgPSB2YWx1ZXNbIGluZGV4IF07XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnRzO1xufVxuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdHNob3c6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcywgdHJ1ZSApO1xuXHR9LFxuXHRoaWRlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gc2hvd0hpZGUoIHRoaXMgKTtcblx0fSxcblx0dG9nZ2xlOiBmdW5jdGlvbiggc3RhdGUgKSB7XG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGUgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0cmV0dXJuIHN0YXRlID8gdGhpcy5zaG93KCkgOiB0aGlzLmhpZGUoKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggaXNIaWRkZW5XaXRoaW5UcmVlKCB0aGlzICkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnNob3coKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmhpZGUoKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH1cbn0gKTtcbnZhciByY2hlY2thYmxlVHlwZSA9ICggL14oPzpjaGVja2JveHxyYWRpbykkL2kgKTtcblxudmFyIHJ0YWdOYW1lID0gKCAvPChbYS16XVteXFwvXFwwPlxceDIwXFx0XFxyXFxuXFxmXSopL2kgKTtcblxudmFyIHJzY3JpcHRUeXBlID0gKCAvXiR8Xm1vZHVsZSR8XFwvKD86amF2YXxlY21hKXNjcmlwdC9pICk7XG5cblxuXG4oIGZ1bmN0aW9uKCkge1xuXHR2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCksXG5cdFx0ZGl2ID0gZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApLFxuXHRcdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAgLSA0LjMgb25seVxuXHQvLyBDaGVjayBzdGF0ZSBsb3N0IGlmIHRoZSBuYW1lIGlzIHNldCAoIzExMjE3KVxuXHQvLyBTdXBwb3J0OiBXaW5kb3dzIFdlYiBBcHBzIChXV0EpXG5cdC8vIGBuYW1lYCBhbmQgYHR5cGVgIG11c3QgdXNlIC5zZXRBdHRyaWJ1dGUgZm9yIFdXQSAoIzE0OTAxKVxuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCBcInJhZGlvXCIgKTtcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcImNoZWNrZWRcIiwgXCJjaGVja2VkXCIgKTtcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJ0XCIgKTtcblxuXHRkaXYuYXBwZW5kQ2hpbGQoIGlucHV0ICk7XG5cblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMSBvbmx5XG5cdC8vIE9sZGVyIFdlYktpdCBkb2Vzbid0IGNsb25lIGNoZWNrZWQgc3RhdGUgY29ycmVjdGx5IGluIGZyYWdtZW50c1xuXHRzdXBwb3J0LmNoZWNrQ2xvbmUgPSBkaXYuY2xvbmVOb2RlKCB0cnVlICkuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmNoZWNrZWQ7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIE1ha2Ugc3VyZSB0ZXh0YXJlYSAoYW5kIGNoZWNrYm94KSBkZWZhdWx0VmFsdWUgaXMgcHJvcGVybHkgY2xvbmVkXG5cdGRpdi5pbm5lckhUTUwgPSBcIjx0ZXh0YXJlYT54PC90ZXh0YXJlYT5cIjtcblx0c3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCA9ICEhZGl2LmNsb25lTm9kZSggdHJ1ZSApLmxhc3RDaGlsZC5kZWZhdWx0VmFsdWU7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0Ly8gSUUgPD05IHJlcGxhY2VzIDxvcHRpb24+IHRhZ3Mgd2l0aCB0aGVpciBjb250ZW50cyB3aGVuIGluc2VydGVkIG91dHNpZGUgb2Zcblx0Ly8gdGhlIHNlbGVjdCBlbGVtZW50LlxuXHRkaXYuaW5uZXJIVE1MID0gXCI8b3B0aW9uPjwvb3B0aW9uPlwiO1xuXHRzdXBwb3J0Lm9wdGlvbiA9ICEhZGl2Lmxhc3RDaGlsZDtcbn0gKSgpO1xuXG5cbi8vIFdlIGhhdmUgdG8gY2xvc2UgdGhlc2UgdGFncyB0byBzdXBwb3J0IFhIVE1MICgjMTMyMDApXG52YXIgd3JhcE1hcCA9IHtcblxuXHQvLyBYSFRNTCBwYXJzZXJzIGRvIG5vdCBtYWdpY2FsbHkgaW5zZXJ0IGVsZW1lbnRzIGluIHRoZVxuXHQvLyBzYW1lIHdheSB0aGF0IHRhZyBzb3VwIHBhcnNlcnMgZG8uIFNvIHdlIGNhbm5vdCBzaG9ydGVuXG5cdC8vIHRoaXMgYnkgb21pdHRpbmcgPHRib2R5PiBvciBvdGhlciByZXF1aXJlZCBlbGVtZW50cy5cblx0dGhlYWQ6IFsgMSwgXCI8dGFibGU+XCIsIFwiPC90YWJsZT5cIiBdLFxuXHRjb2w6IFsgMiwgXCI8dGFibGU+PGNvbGdyb3VwPlwiLCBcIjwvY29sZ3JvdXA+PC90YWJsZT5cIiBdLFxuXHR0cjogWyAyLCBcIjx0YWJsZT48dGJvZHk+XCIsIFwiPC90Ym9keT48L3RhYmxlPlwiIF0sXG5cdHRkOiBbIDMsIFwiPHRhYmxlPjx0Ym9keT48dHI+XCIsIFwiPC90cj48L3Rib2R5PjwvdGFibGU+XCIgXSxcblxuXHRfZGVmYXVsdDogWyAwLCBcIlwiLCBcIlwiIF1cbn07XG5cbndyYXBNYXAudGJvZHkgPSB3cmFwTWFwLnRmb290ID0gd3JhcE1hcC5jb2xncm91cCA9IHdyYXBNYXAuY2FwdGlvbiA9IHdyYXBNYXAudGhlYWQ7XG53cmFwTWFwLnRoID0gd3JhcE1hcC50ZDtcblxuLy8gU3VwcG9ydDogSUUgPD05IG9ubHlcbmlmICggIXN1cHBvcnQub3B0aW9uICkge1xuXHR3cmFwTWFwLm9wdGdyb3VwID0gd3JhcE1hcC5vcHRpb24gPSBbIDEsIFwiPHNlbGVjdCBtdWx0aXBsZT0nbXVsdGlwbGUnPlwiLCBcIjwvc2VsZWN0PlwiIF07XG59XG5cblxuZnVuY3Rpb24gZ2V0QWxsKCBjb250ZXh0LCB0YWcgKSB7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHQvLyBVc2UgdHlwZW9mIHRvIGF2b2lkIHplcm8tYXJndW1lbnQgbWV0aG9kIGludm9jYXRpb24gb24gaG9zdCBvYmplY3RzICgjMTUxNTEpXG5cdHZhciByZXQ7XG5cblx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRyZXQgPSBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgfHwgXCIqXCIgKTtcblxuXHR9IGVsc2UgaWYgKCB0eXBlb2YgY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsICE9PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdHJldCA9IGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnIHx8IFwiKlwiICk7XG5cblx0fSBlbHNlIHtcblx0XHRyZXQgPSBbXTtcblx0fVxuXG5cdGlmICggdGFnID09PSB1bmRlZmluZWQgfHwgdGFnICYmIG5vZGVOYW1lKCBjb250ZXh0LCB0YWcgKSApIHtcblx0XHRyZXR1cm4galF1ZXJ5Lm1lcmdlKCBbIGNvbnRleHQgXSwgcmV0ICk7XG5cdH1cblxuXHRyZXR1cm4gcmV0O1xufVxuXG5cbi8vIE1hcmsgc2NyaXB0cyBhcyBoYXZpbmcgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZFxuZnVuY3Rpb24gc2V0R2xvYmFsRXZhbCggZWxlbXMsIHJlZkVsZW1lbnRzICkge1xuXHR2YXIgaSA9IDAsXG5cdFx0bCA9IGVsZW1zLmxlbmd0aDtcblxuXHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0ZGF0YVByaXYuc2V0KFxuXHRcdFx0ZWxlbXNbIGkgXSxcblx0XHRcdFwiZ2xvYmFsRXZhbFwiLFxuXHRcdFx0IXJlZkVsZW1lbnRzIHx8IGRhdGFQcml2LmdldCggcmVmRWxlbWVudHNbIGkgXSwgXCJnbG9iYWxFdmFsXCIgKVxuXHRcdCk7XG5cdH1cbn1cblxuXG52YXIgcmh0bWwgPSAvPHwmIz9cXHcrOy87XG5cbmZ1bmN0aW9uIGJ1aWxkRnJhZ21lbnQoIGVsZW1zLCBjb250ZXh0LCBzY3JpcHRzLCBzZWxlY3Rpb24sIGlnbm9yZWQgKSB7XG5cdHZhciBlbGVtLCB0bXAsIHRhZywgd3JhcCwgYXR0YWNoZWQsIGosXG5cdFx0ZnJhZ21lbnQgPSBjb250ZXh0LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSxcblx0XHRub2RlcyA9IFtdLFxuXHRcdGkgPSAwLFxuXHRcdGwgPSBlbGVtcy5sZW5ndGg7XG5cblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdGVsZW0gPSBlbGVtc1sgaSBdO1xuXG5cdFx0aWYgKCBlbGVtIHx8IGVsZW0gPT09IDAgKSB7XG5cblx0XHRcdC8vIEFkZCBub2RlcyBkaXJlY3RseVxuXHRcdFx0aWYgKCB0b1R5cGUoIGVsZW0gKSA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHksIFBoYW50b21KUyAxIG9ubHlcblx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIG5vZGVzLCBlbGVtLm5vZGVUeXBlID8gWyBlbGVtIF0gOiBlbGVtICk7XG5cblx0XHRcdC8vIENvbnZlcnQgbm9uLWh0bWwgaW50byBhIHRleHQgbm9kZVxuXHRcdFx0fSBlbHNlIGlmICggIXJodG1sLnRlc3QoIGVsZW0gKSApIHtcblx0XHRcdFx0bm9kZXMucHVzaCggY29udGV4dC5jcmVhdGVUZXh0Tm9kZSggZWxlbSApICk7XG5cblx0XHRcdC8vIENvbnZlcnQgaHRtbCBpbnRvIERPTSBub2Rlc1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dG1wID0gdG1wIHx8IGZyYWdtZW50LmFwcGVuZENoaWxkKCBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApO1xuXG5cdFx0XHRcdC8vIERlc2VyaWFsaXplIGEgc3RhbmRhcmQgcmVwcmVzZW50YXRpb25cblx0XHRcdFx0dGFnID0gKCBydGFnTmFtZS5leGVjKCBlbGVtICkgfHwgWyBcIlwiLCBcIlwiIF0gKVsgMSBdLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdHdyYXAgPSB3cmFwTWFwWyB0YWcgXSB8fCB3cmFwTWFwLl9kZWZhdWx0O1xuXHRcdFx0XHR0bXAuaW5uZXJIVE1MID0gd3JhcFsgMSBdICsgalF1ZXJ5Lmh0bWxQcmVmaWx0ZXIoIGVsZW0gKSArIHdyYXBbIDIgXTtcblxuXHRcdFx0XHQvLyBEZXNjZW5kIHRocm91Z2ggd3JhcHBlcnMgdG8gdGhlIHJpZ2h0IGNvbnRlbnRcblx0XHRcdFx0aiA9IHdyYXBbIDAgXTtcblx0XHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdFx0dG1wID0gdG1wLmxhc3RDaGlsZDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seVxuXHRcdFx0XHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdFx0XHRcdGpRdWVyeS5tZXJnZSggbm9kZXMsIHRtcC5jaGlsZE5vZGVzICk7XG5cblx0XHRcdFx0Ly8gUmVtZW1iZXIgdGhlIHRvcC1sZXZlbCBjb250YWluZXJcblx0XHRcdFx0dG1wID0gZnJhZ21lbnQuZmlyc3RDaGlsZDtcblxuXHRcdFx0XHQvLyBFbnN1cmUgdGhlIGNyZWF0ZWQgbm9kZXMgYXJlIG9ycGhhbmVkICgjMTIzOTIpXG5cdFx0XHRcdHRtcC50ZXh0Q29udGVudCA9IFwiXCI7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmVtb3ZlIHdyYXBwZXIgZnJvbSBmcmFnbWVudFxuXHRmcmFnbWVudC50ZXh0Q29udGVudCA9IFwiXCI7XG5cblx0aSA9IDA7XG5cdHdoaWxlICggKCBlbGVtID0gbm9kZXNbIGkrKyBdICkgKSB7XG5cblx0XHQvLyBTa2lwIGVsZW1lbnRzIGFscmVhZHkgaW4gdGhlIGNvbnRleHQgY29sbGVjdGlvbiAodHJhYy00MDg3KVxuXHRcdGlmICggc2VsZWN0aW9uICYmIGpRdWVyeS5pbkFycmF5KCBlbGVtLCBzZWxlY3Rpb24gKSA+IC0xICkge1xuXHRcdFx0aWYgKCBpZ25vcmVkICkge1xuXHRcdFx0XHRpZ25vcmVkLnB1c2goIGVsZW0gKTtcblx0XHRcdH1cblx0XHRcdGNvbnRpbnVlO1xuXHRcdH1cblxuXHRcdGF0dGFjaGVkID0gaXNBdHRhY2hlZCggZWxlbSApO1xuXG5cdFx0Ly8gQXBwZW5kIHRvIGZyYWdtZW50XG5cdFx0dG1wID0gZ2V0QWxsKCBmcmFnbWVudC5hcHBlbmRDaGlsZCggZWxlbSApLCBcInNjcmlwdFwiICk7XG5cblx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XG5cdFx0aWYgKCBhdHRhY2hlZCApIHtcblx0XHRcdHNldEdsb2JhbEV2YWwoIHRtcCApO1xuXHRcdH1cblxuXHRcdC8vIENhcHR1cmUgZXhlY3V0YWJsZXNcblx0XHRpZiAoIHNjcmlwdHMgKSB7XG5cdFx0XHRqID0gMDtcblx0XHRcdHdoaWxlICggKCBlbGVtID0gdG1wWyBqKysgXSApICkge1xuXHRcdFx0XHRpZiAoIHJzY3JpcHRUeXBlLnRlc3QoIGVsZW0udHlwZSB8fCBcIlwiICkgKSB7XG5cdFx0XHRcdFx0c2NyaXB0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZnJhZ21lbnQ7XG59XG5cblxudmFyXG5cdHJrZXlFdmVudCA9IC9ea2V5Lyxcblx0cm1vdXNlRXZlbnQgPSAvXig/Om1vdXNlfHBvaW50ZXJ8Y29udGV4dG1lbnV8ZHJhZ3xkcm9wKXxjbGljay8sXG5cdHJ0eXBlbmFtZXNwYWNlID0gL14oW14uXSopKD86XFwuKC4rKXwpLztcblxuZnVuY3Rpb24gcmV0dXJuVHJ1ZSgpIHtcblx0cmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJldHVybkZhbHNlKCkge1xuXHRyZXR1cm4gZmFsc2U7XG59XG5cbi8vIFN1cHBvcnQ6IElFIDw9OSAtIDExK1xuLy8gZm9jdXMoKSBhbmQgYmx1cigpIGFyZSBhc3luY2hyb25vdXMsIGV4Y2VwdCB3aGVuIHRoZXkgYXJlIG5vLW9wLlxuLy8gU28gZXhwZWN0IGZvY3VzIHRvIGJlIHN5bmNocm9ub3VzIHdoZW4gdGhlIGVsZW1lbnQgaXMgYWxyZWFkeSBhY3RpdmUsXG4vLyBhbmQgYmx1ciB0byBiZSBzeW5jaHJvbm91cyB3aGVuIHRoZSBlbGVtZW50IGlzIG5vdCBhbHJlYWR5IGFjdGl2ZS5cbi8vIChmb2N1cyBhbmQgYmx1ciBhcmUgYWx3YXlzIHN5bmNocm9ub3VzIGluIG90aGVyIHN1cHBvcnRlZCBicm93c2Vycyxcbi8vIHRoaXMganVzdCBkZWZpbmVzIHdoZW4gd2UgY2FuIGNvdW50IG9uIGl0KS5cbmZ1bmN0aW9uIGV4cGVjdFN5bmMoIGVsZW0sIHR5cGUgKSB7XG5cdHJldHVybiAoIGVsZW0gPT09IHNhZmVBY3RpdmVFbGVtZW50KCkgKSA9PT0gKCB0eXBlID09PSBcImZvY3VzXCIgKTtcbn1cblxuLy8gU3VwcG9ydDogSUUgPD05IG9ubHlcbi8vIEFjY2Vzc2luZyBkb2N1bWVudC5hY3RpdmVFbGVtZW50IGNhbiB0aHJvdyB1bmV4cGVjdGVkbHlcbi8vIGh0dHBzOi8vYnVncy5qcXVlcnkuY29tL3RpY2tldC8xMzM5M1xuZnVuY3Rpb24gc2FmZUFjdGl2ZUVsZW1lbnQoKSB7XG5cdHRyeSB7XG5cdFx0cmV0dXJuIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XG5cdH0gY2F0Y2ggKCBlcnIgKSB7IH1cbn1cblxuZnVuY3Rpb24gb24oIGVsZW0sIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIG9uZSApIHtcblx0dmFyIG9yaWdGbiwgdHlwZTtcblxuXHQvLyBUeXBlcyBjYW4gYmUgYSBtYXAgb2YgdHlwZXMvaGFuZGxlcnNcblx0aWYgKCB0eXBlb2YgdHlwZXMgPT09IFwib2JqZWN0XCIgKSB7XG5cblx0XHQvLyAoIHR5cGVzLU9iamVjdCwgc2VsZWN0b3IsIGRhdGEgKVxuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzLU9iamVjdCwgZGF0YSApXG5cdFx0XHRkYXRhID0gZGF0YSB8fCBzZWxlY3Rvcjtcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRmb3IgKCB0eXBlIGluIHR5cGVzICkge1xuXHRcdFx0b24oIGVsZW0sIHR5cGUsIHNlbGVjdG9yLCBkYXRhLCB0eXBlc1sgdHlwZSBdLCBvbmUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIGVsZW07XG5cdH1cblxuXHRpZiAoIGRhdGEgPT0gbnVsbCAmJiBmbiA9PSBudWxsICkge1xuXG5cdFx0Ly8gKCB0eXBlcywgZm4gKVxuXHRcdGZuID0gc2VsZWN0b3I7XG5cdFx0ZGF0YSA9IHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHR9IGVsc2UgaWYgKCBmbiA9PSBudWxsICkge1xuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzLCBzZWxlY3RvciwgZm4gKVxuXHRcdFx0Zm4gPSBkYXRhO1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9IGVsc2Uge1xuXG5cdFx0XHQvLyAoIHR5cGVzLCBkYXRhLCBmbiApXG5cdFx0XHRmbiA9IGRhdGE7XG5cdFx0XHRkYXRhID0gc2VsZWN0b3I7XG5cdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblx0aWYgKCBmbiA9PT0gZmFsc2UgKSB7XG5cdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0fSBlbHNlIGlmICggIWZuICkge1xuXHRcdHJldHVybiBlbGVtO1xuXHR9XG5cblx0aWYgKCBvbmUgPT09IDEgKSB7XG5cdFx0b3JpZ0ZuID0gZm47XG5cdFx0Zm4gPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cblx0XHRcdC8vIENhbiB1c2UgYW4gZW1wdHkgc2V0LCBzaW5jZSBldmVudCBjb250YWlucyB0aGUgaW5mb1xuXHRcdFx0alF1ZXJ5KCkub2ZmKCBldmVudCApO1xuXHRcdFx0cmV0dXJuIG9yaWdGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fTtcblxuXHRcdC8vIFVzZSBzYW1lIGd1aWQgc28gY2FsbGVyIGNhbiByZW1vdmUgdXNpbmcgb3JpZ0ZuXG5cdFx0Zm4uZ3VpZCA9IG9yaWdGbi5ndWlkIHx8ICggb3JpZ0ZuLmd1aWQgPSBqUXVlcnkuZ3VpZCsrICk7XG5cdH1cblx0cmV0dXJuIGVsZW0uZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0alF1ZXJ5LmV2ZW50LmFkZCggdGhpcywgdHlwZXMsIGZuLCBkYXRhLCBzZWxlY3RvciApO1xuXHR9ICk7XG59XG5cbi8qXG4gKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBtYW5hZ2luZyBldmVudHMgLS0gbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuXG4gKiBQcm9wcyB0byBEZWFuIEVkd2FyZHMnIGFkZEV2ZW50IGxpYnJhcnkgZm9yIG1hbnkgb2YgdGhlIGlkZWFzLlxuICovXG5qUXVlcnkuZXZlbnQgPSB7XG5cblx0Z2xvYmFsOiB7fSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlcywgaGFuZGxlciwgZGF0YSwgc2VsZWN0b3IgKSB7XG5cblx0XHR2YXIgaGFuZGxlT2JqSW4sIGV2ZW50SGFuZGxlLCB0bXAsXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcblx0XHRcdHNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSxcblx0XHRcdGVsZW1EYXRhID0gZGF0YVByaXYuZ2V0KCBlbGVtICk7XG5cblx0XHQvLyBPbmx5IGF0dGFjaCBldmVudHMgdG8gb2JqZWN0cyB0aGF0IGFjY2VwdCBkYXRhXG5cdFx0aWYgKCAhYWNjZXB0RGF0YSggZWxlbSApICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhbiBvYmplY3Qgb2YgY3VzdG9tIGRhdGEgaW4gbGlldSBvZiB0aGUgaGFuZGxlclxuXHRcdGlmICggaGFuZGxlci5oYW5kbGVyICkge1xuXHRcdFx0aGFuZGxlT2JqSW4gPSBoYW5kbGVyO1xuXHRcdFx0aGFuZGxlciA9IGhhbmRsZU9iakluLmhhbmRsZXI7XG5cdFx0XHRzZWxlY3RvciA9IGhhbmRsZU9iakluLnNlbGVjdG9yO1xuXHRcdH1cblxuXHRcdC8vIEVuc3VyZSB0aGF0IGludmFsaWQgc2VsZWN0b3JzIHRocm93IGV4Y2VwdGlvbnMgYXQgYXR0YWNoIHRpbWVcblx0XHQvLyBFdmFsdWF0ZSBhZ2FpbnN0IGRvY3VtZW50RWxlbWVudCBpbiBjYXNlIGVsZW0gaXMgYSBub24tZWxlbWVudCBub2RlIChlLmcuLCBkb2N1bWVudClcblx0XHRpZiAoIHNlbGVjdG9yICkge1xuXHRcdFx0alF1ZXJ5LmZpbmQubWF0Y2hlc1NlbGVjdG9yKCBkb2N1bWVudEVsZW1lbnQsIHNlbGVjdG9yICk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgdGhlIGhhbmRsZXIgaGFzIGEgdW5pcXVlIElELCB1c2VkIHRvIGZpbmQvcmVtb3ZlIGl0IGxhdGVyXG5cdFx0aWYgKCAhaGFuZGxlci5ndWlkICkge1xuXHRcdFx0aGFuZGxlci5ndWlkID0galF1ZXJ5Lmd1aWQrKztcblx0XHR9XG5cblx0XHQvLyBJbml0IHRoZSBlbGVtZW50J3MgZXZlbnQgc3RydWN0dXJlIGFuZCBtYWluIGhhbmRsZXIsIGlmIHRoaXMgaXMgdGhlIGZpcnN0XG5cdFx0aWYgKCAhKCBldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgKSApIHtcblx0XHRcdGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyA9IE9iamVjdC5jcmVhdGUoIG51bGwgKTtcblx0XHR9XG5cdFx0aWYgKCAhKCBldmVudEhhbmRsZSA9IGVsZW1EYXRhLmhhbmRsZSApICkge1xuXHRcdFx0ZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgPSBmdW5jdGlvbiggZSApIHtcblxuXHRcdFx0XHQvLyBEaXNjYXJkIHRoZSBzZWNvbmQgZXZlbnQgb2YgYSBqUXVlcnkuZXZlbnQudHJpZ2dlcigpIGFuZFxuXHRcdFx0XHQvLyB3aGVuIGFuIGV2ZW50IGlzIGNhbGxlZCBhZnRlciBhIHBhZ2UgaGFzIHVubG9hZGVkXG5cdFx0XHRcdHJldHVybiB0eXBlb2YgalF1ZXJ5ICE9PSBcInVuZGVmaW5lZFwiICYmIGpRdWVyeS5ldmVudC50cmlnZ2VyZWQgIT09IGUudHlwZSA/XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmRpc3BhdGNoLmFwcGx5KCBlbGVtLCBhcmd1bWVudHMgKSA6IHVuZGVmaW5lZDtcblx0XHRcdH07XG5cdFx0fVxuXG5cdFx0Ly8gSGFuZGxlIG11bHRpcGxlIGV2ZW50cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZVxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbIHQgXSApIHx8IFtdO1xuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWyAxIF07XG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbIDIgXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBUaGVyZSAqbXVzdCogYmUgYSB0eXBlLCBubyBhdHRhY2hpbmcgbmFtZXNwYWNlLW9ubHkgaGFuZGxlcnNcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiBldmVudCBjaGFuZ2VzIGl0cyB0eXBlLCB1c2UgdGhlIHNwZWNpYWwgZXZlbnQgaGFuZGxlcnMgZm9yIHRoZSBjaGFuZ2VkIHR5cGVcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXG5cdFx0XHQvLyBJZiBzZWxlY3RvciBkZWZpbmVkLCBkZXRlcm1pbmUgc3BlY2lhbCBldmVudCBhcGkgdHlwZSwgb3RoZXJ3aXNlIGdpdmVuIHR5cGVcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblxuXHRcdFx0Ly8gVXBkYXRlIHNwZWNpYWwgYmFzZWQgb24gbmV3bHkgcmVzZXQgdHlwZVxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XG5cblx0XHRcdC8vIGhhbmRsZU9iaiBpcyBwYXNzZWQgdG8gYWxsIGV2ZW50IGhhbmRsZXJzXG5cdFx0XHRoYW5kbGVPYmogPSBqUXVlcnkuZXh0ZW5kKCB7XG5cdFx0XHRcdHR5cGU6IHR5cGUsXG5cdFx0XHRcdG9yaWdUeXBlOiBvcmlnVHlwZSxcblx0XHRcdFx0ZGF0YTogZGF0YSxcblx0XHRcdFx0aGFuZGxlcjogaGFuZGxlcixcblx0XHRcdFx0Z3VpZDogaGFuZGxlci5ndWlkLFxuXHRcdFx0XHRzZWxlY3Rvcjogc2VsZWN0b3IsXG5cdFx0XHRcdG5lZWRzQ29udGV4dDogc2VsZWN0b3IgJiYgalF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9yICksXG5cdFx0XHRcdG5hbWVzcGFjZTogbmFtZXNwYWNlcy5qb2luKCBcIi5cIiApXG5cdFx0XHR9LCBoYW5kbGVPYmpJbiApO1xuXG5cdFx0XHQvLyBJbml0IHRoZSBldmVudCBoYW5kbGVyIHF1ZXVlIGlmIHdlJ3JlIHRoZSBmaXJzdFxuXHRcdFx0aWYgKCAhKCBoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdICkgKSB7XG5cdFx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gPSBbXTtcblx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudCA9IDA7XG5cblx0XHRcdFx0Ly8gT25seSB1c2UgYWRkRXZlbnRMaXN0ZW5lciBpZiB0aGUgc3BlY2lhbCBldmVudHMgaGFuZGxlciByZXR1cm5zIGZhbHNlXG5cdFx0XHRcdGlmICggIXNwZWNpYWwuc2V0dXAgfHxcblx0XHRcdFx0XHRzcGVjaWFsLnNldHVwLmNhbGwoIGVsZW0sIGRhdGEsIG5hbWVzcGFjZXMsIGV2ZW50SGFuZGxlICkgPT09IGZhbHNlICkge1xuXG5cdFx0XHRcdFx0aWYgKCBlbGVtLmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGV2ZW50SGFuZGxlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggc3BlY2lhbC5hZGQgKSB7XG5cdFx0XHRcdHNwZWNpYWwuYWRkLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xuXG5cdFx0XHRcdGlmICggIWhhbmRsZU9iai5oYW5kbGVyLmd1aWQgKSB7XG5cdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCA9IGhhbmRsZXIuZ3VpZDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgdG8gdGhlIGVsZW1lbnQncyBoYW5kbGVyIGxpc3QsIGRlbGVnYXRlcyBpbiBmcm9udFxuXHRcdFx0aWYgKCBzZWxlY3RvciApIHtcblx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50KyssIDAsIGhhbmRsZU9iaiApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aGFuZGxlcnMucHVzaCggaGFuZGxlT2JqICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEtlZXAgdHJhY2sgb2Ygd2hpY2ggZXZlbnRzIGhhdmUgZXZlciBiZWVuIHVzZWQsIGZvciBldmVudCBvcHRpbWl6YXRpb25cblx0XHRcdGpRdWVyeS5ldmVudC5nbG9iYWxbIHR5cGUgXSA9IHRydWU7XG5cdFx0fVxuXG5cdH0sXG5cblx0Ly8gRGV0YWNoIGFuIGV2ZW50IG9yIHNldCBvZiBldmVudHMgZnJvbSBhbiBlbGVtZW50XG5cdHJlbW92ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBzZWxlY3RvciwgbWFwcGVkVHlwZXMgKSB7XG5cblx0XHR2YXIgaiwgb3JpZ0NvdW50LCB0bXAsXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcblx0XHRcdHNwZWNpYWwsIGhhbmRsZXJzLCB0eXBlLCBuYW1lc3BhY2VzLCBvcmlnVHlwZSxcblx0XHRcdGVsZW1EYXRhID0gZGF0YVByaXYuaGFzRGF0YSggZWxlbSApICYmIGRhdGFQcml2LmdldCggZWxlbSApO1xuXG5cdFx0aWYgKCAhZWxlbURhdGEgfHwgISggZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gT25jZSBmb3IgZWFjaCB0eXBlLm5hbWVzcGFjZSBpbiB0eXBlczsgdHlwZSBtYXkgYmUgb21pdHRlZFxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbIHQgXSApIHx8IFtdO1xuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWyAxIF07XG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbIDIgXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBVbmJpbmQgYWxsIGV2ZW50cyAob24gdGhpcyBuYW1lc3BhY2UsIGlmIHByb3ZpZGVkKSBmb3IgdGhlIGVsZW1lbnRcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGZvciAoIHR5cGUgaW4gZXZlbnRzICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIGVsZW0sIHR5cGUgKyB0eXBlc1sgdCBdLCBoYW5kbGVyLCBzZWxlY3RvciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gfHwgW107XG5cdFx0XHR0bXAgPSB0bXBbIDIgXSAmJlxuXHRcdFx0XHRuZXcgUmVnRXhwKCBcIihefFxcXFwuKVwiICsgbmFtZXNwYWNlcy5qb2luKCBcIlxcXFwuKD86LipcXFxcLnwpXCIgKSArIFwiKFxcXFwufCQpXCIgKTtcblxuXHRcdFx0Ly8gUmVtb3ZlIG1hdGNoaW5nIGV2ZW50c1xuXHRcdFx0b3JpZ0NvdW50ID0gaiA9IGhhbmRsZXJzLmxlbmd0aDtcblx0XHRcdHdoaWxlICggai0tICkge1xuXHRcdFx0XHRoYW5kbGVPYmogPSBoYW5kbGVyc1sgaiBdO1xuXG5cdFx0XHRcdGlmICggKCBtYXBwZWRUeXBlcyB8fCBvcmlnVHlwZSA9PT0gaGFuZGxlT2JqLm9yaWdUeXBlICkgJiZcblx0XHRcdFx0XHQoICFoYW5kbGVyIHx8IGhhbmRsZXIuZ3VpZCA9PT0gaGFuZGxlT2JqLmd1aWQgKSAmJlxuXHRcdFx0XHRcdCggIXRtcCB8fCB0bXAudGVzdCggaGFuZGxlT2JqLm5hbWVzcGFjZSApICkgJiZcblx0XHRcdFx0XHQoICFzZWxlY3RvciB8fCBzZWxlY3RvciA9PT0gaGFuZGxlT2JqLnNlbGVjdG9yIHx8XG5cdFx0XHRcdFx0XHRzZWxlY3RvciA9PT0gXCIqKlwiICYmIGhhbmRsZU9iai5zZWxlY3RvciApICkge1xuXHRcdFx0XHRcdGhhbmRsZXJzLnNwbGljZSggaiwgMSApO1xuXG5cdFx0XHRcdFx0aWYgKCBoYW5kbGVPYmouc2VsZWN0b3IgKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVycy5kZWxlZ2F0ZUNvdW50LS07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggc3BlY2lhbC5yZW1vdmUgKSB7XG5cdFx0XHRcdFx0XHRzcGVjaWFsLnJlbW92ZS5jYWxsKCBlbGVtLCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gUmVtb3ZlIGdlbmVyaWMgZXZlbnQgaGFuZGxlciBpZiB3ZSByZW1vdmVkIHNvbWV0aGluZyBhbmQgbm8gbW9yZSBoYW5kbGVycyBleGlzdFxuXHRcdFx0Ly8gKGF2b2lkcyBwb3RlbnRpYWwgZm9yIGVuZGxlc3MgcmVjdXJzaW9uIGR1cmluZyByZW1vdmFsIG9mIHNwZWNpYWwgZXZlbnQgaGFuZGxlcnMpXG5cdFx0XHRpZiAoIG9yaWdDb3VudCAmJiAhaGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0XHRpZiAoICFzcGVjaWFsLnRlYXJkb3duIHx8XG5cdFx0XHRcdFx0c3BlY2lhbC50ZWFyZG93bi5jYWxsKCBlbGVtLCBuYW1lc3BhY2VzLCBlbGVtRGF0YS5oYW5kbGUgKSA9PT0gZmFsc2UgKSB7XG5cblx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGVsZW1EYXRhLmhhbmRsZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGVsZXRlIGV2ZW50c1sgdHlwZSBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSBkYXRhIGFuZCB0aGUgZXhwYW5kbyBpZiBpdCdzIG5vIGxvbmdlciB1c2VkXG5cdFx0aWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggZXZlbnRzICkgKSB7XG5cdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFwiaGFuZGxlIGV2ZW50c1wiICk7XG5cdFx0fVxuXHR9LFxuXG5cdGRpc3BhdGNoOiBmdW5jdGlvbiggbmF0aXZlRXZlbnQgKSB7XG5cblx0XHR2YXIgaSwgaiwgcmV0LCBtYXRjaGVkLCBoYW5kbGVPYmosIGhhbmRsZXJRdWV1ZSxcblx0XHRcdGFyZ3MgPSBuZXcgQXJyYXkoIGFyZ3VtZW50cy5sZW5ndGggKSxcblxuXHRcdFx0Ly8gTWFrZSBhIHdyaXRhYmxlIGpRdWVyeS5FdmVudCBmcm9tIHRoZSBuYXRpdmUgZXZlbnQgb2JqZWN0XG5cdFx0XHRldmVudCA9IGpRdWVyeS5ldmVudC5maXgoIG5hdGl2ZUV2ZW50ICksXG5cblx0XHRcdGhhbmRsZXJzID0gKFxuXHRcdFx0XHRcdGRhdGFQcml2LmdldCggdGhpcywgXCJldmVudHNcIiApIHx8IE9iamVjdC5jcmVhdGUoIG51bGwgKVxuXHRcdFx0XHQpWyBldmVudC50eXBlIF0gfHwgW10sXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGV2ZW50LnR5cGUgXSB8fCB7fTtcblxuXHRcdC8vIFVzZSB0aGUgZml4LWVkIGpRdWVyeS5FdmVudCByYXRoZXIgdGhhbiB0aGUgKHJlYWQtb25seSkgbmF0aXZlIGV2ZW50XG5cdFx0YXJnc1sgMCBdID0gZXZlbnQ7XG5cblx0XHRmb3IgKCBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKyApIHtcblx0XHRcdGFyZ3NbIGkgXSA9IGFyZ3VtZW50c1sgaSBdO1xuXHRcdH1cblxuXHRcdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gdGhpcztcblxuXHRcdC8vIENhbGwgdGhlIHByZURpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZSwgYW5kIGxldCBpdCBiYWlsIGlmIGRlc2lyZWRcblx0XHRpZiAoIHNwZWNpYWwucHJlRGlzcGF0Y2ggJiYgc3BlY2lhbC5wcmVEaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgaGFuZGxlcnNcblx0XHRoYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7XG5cblx0XHQvLyBSdW4gZGVsZWdhdGVzIGZpcnN0OyB0aGV5IG1heSB3YW50IHRvIHN0b3AgcHJvcGFnYXRpb24gYmVuZWF0aCB1c1xuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKCBtYXRjaGVkID0gaGFuZGxlclF1ZXVlWyBpKysgXSApICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0ZXZlbnQuY3VycmVudFRhcmdldCA9IG1hdGNoZWQuZWxlbTtcblxuXHRcdFx0aiA9IDA7XG5cdFx0XHR3aGlsZSAoICggaGFuZGxlT2JqID0gbWF0Y2hlZC5oYW5kbGVyc1sgaisrIF0gKSAmJlxuXHRcdFx0XHQhZXZlbnQuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblxuXHRcdFx0XHQvLyBJZiB0aGUgZXZlbnQgaXMgbmFtZXNwYWNlZCwgdGhlbiBlYWNoIGhhbmRsZXIgaXMgb25seSBpbnZva2VkIGlmIGl0IGlzXG5cdFx0XHRcdC8vIHNwZWNpYWxseSB1bml2ZXJzYWwgb3IgaXRzIG5hbWVzcGFjZXMgYXJlIGEgc3VwZXJzZXQgb2YgdGhlIGV2ZW50J3MuXG5cdFx0XHRcdGlmICggIWV2ZW50LnJuYW1lc3BhY2UgfHwgaGFuZGxlT2JqLm5hbWVzcGFjZSA9PT0gZmFsc2UgfHxcblx0XHRcdFx0XHRldmVudC5ybmFtZXNwYWNlLnRlc3QoIGhhbmRsZU9iai5uYW1lc3BhY2UgKSApIHtcblxuXHRcdFx0XHRcdGV2ZW50LmhhbmRsZU9iaiA9IGhhbmRsZU9iajtcblx0XHRcdFx0XHRldmVudC5kYXRhID0gaGFuZGxlT2JqLmRhdGE7XG5cblx0XHRcdFx0XHRyZXQgPSAoICggalF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGhhbmRsZU9iai5vcmlnVHlwZSBdIHx8IHt9ICkuaGFuZGxlIHx8XG5cdFx0XHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlciApLmFwcGx5KCBtYXRjaGVkLmVsZW0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggcmV0ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoICggZXZlbnQucmVzdWx0ID0gcmV0ICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHRcdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWxsIHRoZSBwb3N0RGlzcGF0Y2ggaG9vayBmb3IgdGhlIG1hcHBlZCB0eXBlXG5cdFx0aWYgKCBzcGVjaWFsLnBvc3REaXNwYXRjaCApIHtcblx0XHRcdHNwZWNpYWwucG9zdERpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50LnJlc3VsdDtcblx0fSxcblxuXHRoYW5kbGVyczogZnVuY3Rpb24oIGV2ZW50LCBoYW5kbGVycyApIHtcblx0XHR2YXIgaSwgaGFuZGxlT2JqLCBzZWwsIG1hdGNoZWRIYW5kbGVycywgbWF0Y2hlZFNlbGVjdG9ycyxcblx0XHRcdGhhbmRsZXJRdWV1ZSA9IFtdLFxuXHRcdFx0ZGVsZWdhdGVDb3VudCA9IGhhbmRsZXJzLmRlbGVnYXRlQ291bnQsXG5cdFx0XHRjdXIgPSBldmVudC50YXJnZXQ7XG5cblx0XHQvLyBGaW5kIGRlbGVnYXRlIGhhbmRsZXJzXG5cdFx0aWYgKCBkZWxlZ2F0ZUNvdW50ICYmXG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OVxuXHRcdFx0Ly8gQmxhY2staG9sZSBTVkcgPHVzZT4gaW5zdGFuY2UgdHJlZXMgKHRyYWMtMTMxODApXG5cdFx0XHRjdXIubm9kZVR5cGUgJiZcblxuXHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveCA8PTQyXG5cdFx0XHQvLyBTdXBwcmVzcyBzcGVjLXZpb2xhdGluZyBjbGlja3MgaW5kaWNhdGluZyBhIG5vbi1wcmltYXJ5IHBvaW50ZXIgYnV0dG9uICh0cmFjLTM4NjEpXG5cdFx0XHQvLyBodHRwczovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudC10eXBlLWNsaWNrXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSAxMSBvbmx5XG5cdFx0XHQvLyAuLi5idXQgbm90IGFycm93IGtleSBcImNsaWNrc1wiIG9mIHJhZGlvIGlucHV0cywgd2hpY2ggY2FuIGhhdmUgYGJ1dHRvbmAgLTEgKGdoLTIzNDMpXG5cdFx0XHQhKCBldmVudC50eXBlID09PSBcImNsaWNrXCIgJiYgZXZlbnQuYnV0dG9uID49IDEgKSApIHtcblxuXHRcdFx0Zm9yICggOyBjdXIgIT09IHRoaXM7IGN1ciA9IGN1ci5wYXJlbnROb2RlIHx8IHRoaXMgKSB7XG5cblx0XHRcdFx0Ly8gRG9uJ3QgY2hlY2sgbm9uLWVsZW1lbnRzICgjMTMyMDgpXG5cdFx0XHRcdC8vIERvbid0IHByb2Nlc3MgY2xpY2tzIG9uIGRpc2FibGVkIGVsZW1lbnRzICgjNjkxMSwgIzgxNjUsICMxMTM4MiwgIzExNzY0KVxuXHRcdFx0XHRpZiAoIGN1ci5ub2RlVHlwZSA9PT0gMSAmJiAhKCBldmVudC50eXBlID09PSBcImNsaWNrXCIgJiYgY3VyLmRpc2FibGVkID09PSB0cnVlICkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlZEhhbmRsZXJzID0gW107XG5cdFx0XHRcdFx0bWF0Y2hlZFNlbGVjdG9ycyA9IHt9O1xuXHRcdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgZGVsZWdhdGVDb3VudDsgaSsrICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlT2JqID0gaGFuZGxlcnNbIGkgXTtcblxuXHRcdFx0XHRcdFx0Ly8gRG9uJ3QgY29uZmxpY3Qgd2l0aCBPYmplY3QucHJvdG90eXBlIHByb3BlcnRpZXMgKCMxMzIwMylcblx0XHRcdFx0XHRcdHNlbCA9IGhhbmRsZU9iai5zZWxlY3RvciArIFwiIFwiO1xuXG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZWRTZWxlY3RvcnNbIHNlbCBdID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRcdG1hdGNoZWRTZWxlY3RvcnNbIHNlbCBdID0gaGFuZGxlT2JqLm5lZWRzQ29udGV4dCA/XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5KCBzZWwsIHRoaXMgKS5pbmRleCggY3VyICkgPiAtMSA6XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmZpbmQoIHNlbCwgdGhpcywgbnVsbCwgWyBjdXIgXSApLmxlbmd0aDtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlZFNlbGVjdG9yc1sgc2VsIF0gKSB7XG5cdFx0XHRcdFx0XHRcdG1hdGNoZWRIYW5kbGVycy5wdXNoKCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVkSGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlclF1ZXVlLnB1c2goIHsgZWxlbTogY3VyLCBoYW5kbGVyczogbWF0Y2hlZEhhbmRsZXJzIH0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBBZGQgdGhlIHJlbWFpbmluZyAoZGlyZWN0bHktYm91bmQpIGhhbmRsZXJzXG5cdFx0Y3VyID0gdGhpcztcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgPCBoYW5kbGVycy5sZW5ndGggKSB7XG5cdFx0XHRoYW5kbGVyUXVldWUucHVzaCggeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBoYW5kbGVycy5zbGljZSggZGVsZWdhdGVDb3VudCApIH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gaGFuZGxlclF1ZXVlO1xuXHR9LFxuXG5cdGFkZFByb3A6IGZ1bmN0aW9uKCBuYW1lLCBob29rICkge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggalF1ZXJ5LkV2ZW50LnByb3RvdHlwZSwgbmFtZSwge1xuXHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblxuXHRcdFx0Z2V0OiBpc0Z1bmN0aW9uKCBob29rICkgP1xuXHRcdFx0XHRmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRpZiAoIHRoaXMub3JpZ2luYWxFdmVudCApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGhvb2soIHRoaXMub3JpZ2luYWxFdmVudCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlmICggdGhpcy5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdGhpcy5vcmlnaW5hbEV2ZW50WyBuYW1lIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9LFxuXG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KCB0aGlzLCBuYW1lLCB7XG5cdFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcblx0XHRcdFx0XHRjb25maWd1cmFibGU6IHRydWUsXG5cdFx0XHRcdFx0d3JpdGFibGU6IHRydWUsXG5cdFx0XHRcdFx0dmFsdWU6IHZhbHVlXG5cdFx0XHRcdH0gKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdH0sXG5cblx0Zml4OiBmdW5jdGlvbiggb3JpZ2luYWxFdmVudCApIHtcblx0XHRyZXR1cm4gb3JpZ2luYWxFdmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XG5cdFx0XHRvcmlnaW5hbEV2ZW50IDpcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoIG9yaWdpbmFsRXZlbnQgKTtcblx0fSxcblxuXHRzcGVjaWFsOiB7XG5cdFx0bG9hZDoge1xuXG5cdFx0XHQvLyBQcmV2ZW50IHRyaWdnZXJlZCBpbWFnZS5sb2FkIGV2ZW50cyBmcm9tIGJ1YmJsaW5nIHRvIHdpbmRvdy5sb2FkXG5cdFx0XHRub0J1YmJsZTogdHJ1ZVxuXHRcdH0sXG5cdFx0Y2xpY2s6IHtcblxuXHRcdFx0Ly8gVXRpbGl6ZSBuYXRpdmUgZXZlbnQgdG8gZW5zdXJlIGNvcnJlY3Qgc3RhdGUgZm9yIGNoZWNrYWJsZSBpbnB1dHNcblx0XHRcdHNldHVwOiBmdW5jdGlvbiggZGF0YSApIHtcblxuXHRcdFx0XHQvLyBGb3IgbXV0dWFsIGNvbXByZXNzaWJpbGl0eSB3aXRoIF9kZWZhdWx0LCByZXBsYWNlIGB0aGlzYCBhY2Nlc3Mgd2l0aCBhIGxvY2FsIHZhci5cblx0XHRcdFx0Ly8gYHx8IGRhdGFgIGlzIGRlYWQgY29kZSBtZWFudCBvbmx5IHRvIHByZXNlcnZlIHRoZSB2YXJpYWJsZSB0aHJvdWdoIG1pbmlmaWNhdGlvbi5cblx0XHRcdFx0dmFyIGVsID0gdGhpcyB8fCBkYXRhO1xuXG5cdFx0XHRcdC8vIENsYWltIHRoZSBmaXJzdCBoYW5kbGVyXG5cdFx0XHRcdGlmICggcmNoZWNrYWJsZVR5cGUudGVzdCggZWwudHlwZSApICYmXG5cdFx0XHRcdFx0ZWwuY2xpY2sgJiYgbm9kZU5hbWUoIGVsLCBcImlucHV0XCIgKSApIHtcblxuXHRcdFx0XHRcdC8vIGRhdGFQcml2LnNldCggZWwsIFwiY2xpY2tcIiwgLi4uIClcblx0XHRcdFx0XHRsZXZlcmFnZU5hdGl2ZSggZWwsIFwiY2xpY2tcIiwgcmV0dXJuVHJ1ZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmV0dXJuIGZhbHNlIHRvIGFsbG93IG5vcm1hbCBwcm9jZXNzaW5nIGluIHRoZSBjYWxsZXJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSxcblx0XHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCBkYXRhICkge1xuXG5cdFx0XHRcdC8vIEZvciBtdXR1YWwgY29tcHJlc3NpYmlsaXR5IHdpdGggX2RlZmF1bHQsIHJlcGxhY2UgYHRoaXNgIGFjY2VzcyB3aXRoIGEgbG9jYWwgdmFyLlxuXHRcdFx0XHQvLyBgfHwgZGF0YWAgaXMgZGVhZCBjb2RlIG1lYW50IG9ubHkgdG8gcHJlc2VydmUgdGhlIHZhcmlhYmxlIHRocm91Z2ggbWluaWZpY2F0aW9uLlxuXHRcdFx0XHR2YXIgZWwgPSB0aGlzIHx8IGRhdGE7XG5cblx0XHRcdFx0Ly8gRm9yY2Ugc2V0dXAgYmVmb3JlIHRyaWdnZXJpbmcgYSBjbGlja1xuXHRcdFx0XHRpZiAoIHJjaGVja2FibGVUeXBlLnRlc3QoIGVsLnR5cGUgKSAmJlxuXHRcdFx0XHRcdGVsLmNsaWNrICYmIG5vZGVOYW1lKCBlbCwgXCJpbnB1dFwiICkgKSB7XG5cblx0XHRcdFx0XHRsZXZlcmFnZU5hdGl2ZSggZWwsIFwiY2xpY2tcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmV0dXJuIG5vbi1mYWxzZSB0byBhbGxvdyBub3JtYWwgZXZlbnQtcGF0aCBwcm9wYWdhdGlvblxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH0sXG5cblx0XHRcdC8vIEZvciBjcm9zcy1icm93c2VyIGNvbnNpc3RlbmN5LCBzdXBwcmVzcyBuYXRpdmUgLmNsaWNrKCkgb24gbGlua3Ncblx0XHRcdC8vIEFsc28gcHJldmVudCBpdCBpZiB3ZSdyZSBjdXJyZW50bHkgaW5zaWRlIGEgbGV2ZXJhZ2VkIG5hdGl2ZS1ldmVudCBzdGFja1xuXHRcdFx0X2RlZmF1bHQ6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IGV2ZW50LnRhcmdldDtcblx0XHRcdFx0cmV0dXJuIHJjaGVja2FibGVUeXBlLnRlc3QoIHRhcmdldC50eXBlICkgJiZcblx0XHRcdFx0XHR0YXJnZXQuY2xpY2sgJiYgbm9kZU5hbWUoIHRhcmdldCwgXCJpbnB1dFwiICkgJiZcblx0XHRcdFx0XHRkYXRhUHJpdi5nZXQoIHRhcmdldCwgXCJjbGlja1wiICkgfHxcblx0XHRcdFx0XHRub2RlTmFtZSggdGFyZ2V0LCBcImFcIiApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRiZWZvcmV1bmxvYWQ6IHtcblx0XHRcdHBvc3REaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggMjArXG5cdFx0XHRcdC8vIEZpcmVmb3ggZG9lc24ndCBhbGVydCBpZiB0aGUgcmV0dXJuVmFsdWUgZmllbGQgaXMgbm90IHNldC5cblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgIT09IHVuZGVmaW5lZCAmJiBldmVudC5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdGV2ZW50Lm9yaWdpbmFsRXZlbnQucmV0dXJuVmFsdWUgPSBldmVudC5yZXN1bHQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cbi8vIEVuc3VyZSB0aGUgcHJlc2VuY2Ugb2YgYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBoYW5kbGVzIG1hbnVhbGx5LXRyaWdnZXJlZFxuLy8gc3ludGhldGljIGV2ZW50cyBieSBpbnRlcnJ1cHRpbmcgcHJvZ3Jlc3MgdW50aWwgcmVpbnZva2VkIGluIHJlc3BvbnNlIHRvXG4vLyAqbmF0aXZlKiBldmVudHMgdGhhdCBpdCBmaXJlcyBkaXJlY3RseSwgZW5zdXJpbmcgdGhhdCBzdGF0ZSBjaGFuZ2VzIGhhdmVcbi8vIGFscmVhZHkgb2NjdXJyZWQgYmVmb3JlIG90aGVyIGxpc3RlbmVycyBhcmUgaW52b2tlZC5cbmZ1bmN0aW9uIGxldmVyYWdlTmF0aXZlKCBlbCwgdHlwZSwgZXhwZWN0U3luYyApIHtcblxuXHQvLyBNaXNzaW5nIGV4cGVjdFN5bmMgaW5kaWNhdGVzIGEgdHJpZ2dlciBjYWxsLCB3aGljaCBtdXN0IGZvcmNlIHNldHVwIHRocm91Z2ggalF1ZXJ5LmV2ZW50LmFkZFxuXHRpZiAoICFleHBlY3RTeW5jICkge1xuXHRcdGlmICggZGF0YVByaXYuZ2V0KCBlbCwgdHlwZSApID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuYWRkKCBlbCwgdHlwZSwgcmV0dXJuVHJ1ZSApO1xuXHRcdH1cblx0XHRyZXR1cm47XG5cdH1cblxuXHQvLyBSZWdpc3RlciB0aGUgY29udHJvbGxlciBhcyBhIHNwZWNpYWwgdW5pdmVyc2FsIGhhbmRsZXIgZm9yIGFsbCBldmVudCBuYW1lc3BhY2VzXG5cdGRhdGFQcml2LnNldCggZWwsIHR5cGUsIGZhbHNlICk7XG5cdGpRdWVyeS5ldmVudC5hZGQoIGVsLCB0eXBlLCB7XG5cdFx0bmFtZXNwYWNlOiBmYWxzZSxcblx0XHRoYW5kbGVyOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHR2YXIgbm90QXN5bmMsIHJlc3VsdCxcblx0XHRcdFx0c2F2ZWQgPSBkYXRhUHJpdi5nZXQoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0aWYgKCAoIGV2ZW50LmlzVHJpZ2dlciAmIDEgKSAmJiB0aGlzWyB0eXBlIF0gKSB7XG5cblx0XHRcdFx0Ly8gSW50ZXJydXB0IHByb2Nlc3Npbmcgb2YgdGhlIG91dGVyIHN5bnRoZXRpYyAudHJpZ2dlcigpZWQgZXZlbnRcblx0XHRcdFx0Ly8gU2F2ZWQgZGF0YSBzaG91bGQgYmUgZmFsc2UgaW4gc3VjaCBjYXNlcywgYnV0IG1pZ2h0IGJlIGEgbGVmdG92ZXIgY2FwdHVyZSBvYmplY3Rcblx0XHRcdFx0Ly8gZnJvbSBhbiBhc3luYyBuYXRpdmUgaGFuZGxlciAoZ2gtNDM1MClcblx0XHRcdFx0aWYgKCAhc2F2ZWQubGVuZ3RoICkge1xuXG5cdFx0XHRcdFx0Ly8gU3RvcmUgYXJndW1lbnRzIGZvciB1c2Ugd2hlbiBoYW5kbGluZyB0aGUgaW5uZXIgbmF0aXZlIGV2ZW50XG5cdFx0XHRcdFx0Ly8gVGhlcmUgd2lsbCBhbHdheXMgYmUgYXQgbGVhc3Qgb25lIGFyZ3VtZW50IChhbiBldmVudCBvYmplY3QpLCBzbyB0aGlzIGFycmF5XG5cdFx0XHRcdFx0Ly8gd2lsbCBub3QgYmUgY29uZnVzZWQgd2l0aCBhIGxlZnRvdmVyIGNhcHR1cmUgb2JqZWN0LlxuXHRcdFx0XHRcdHNhdmVkID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCB0eXBlLCBzYXZlZCApO1xuXG5cdFx0XHRcdFx0Ly8gVHJpZ2dlciB0aGUgbmF0aXZlIGV2ZW50IGFuZCBjYXB0dXJlIGl0cyByZXN1bHRcblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMStcblx0XHRcdFx0XHQvLyBmb2N1cygpIGFuZCBibHVyKCkgYXJlIGFzeW5jaHJvbm91c1xuXHRcdFx0XHRcdG5vdEFzeW5jID0gZXhwZWN0U3luYyggdGhpcywgdHlwZSApO1xuXHRcdFx0XHRcdHRoaXNbIHR5cGUgXSgpO1xuXHRcdFx0XHRcdHJlc3VsdCA9IGRhdGFQcml2LmdldCggdGhpcywgdHlwZSApO1xuXHRcdFx0XHRcdGlmICggc2F2ZWQgIT09IHJlc3VsdCB8fCBub3RBc3luYyApIHtcblx0XHRcdFx0XHRcdGRhdGFQcml2LnNldCggdGhpcywgdHlwZSwgZmFsc2UgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmVzdWx0ID0ge307XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGlmICggc2F2ZWQgIT09IHJlc3VsdCApIHtcblxuXHRcdFx0XHRcdFx0Ly8gQ2FuY2VsIHRoZSBvdXRlciBzeW50aGV0aWMgZXZlbnRcblx0XHRcdFx0XHRcdGV2ZW50LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuXHRcdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHQudmFsdWU7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIElmIHRoaXMgaXMgYW4gaW5uZXIgc3ludGhldGljIGV2ZW50IGZvciBhbiBldmVudCB3aXRoIGEgYnViYmxpbmcgc3Vycm9nYXRlXG5cdFx0XHRcdC8vIChmb2N1cyBvciBibHVyKSwgYXNzdW1lIHRoYXQgdGhlIHN1cnJvZ2F0ZSBhbHJlYWR5IHByb3BhZ2F0ZWQgZnJvbSB0cmlnZ2VyaW5nIHRoZVxuXHRcdFx0XHQvLyBuYXRpdmUgZXZlbnQgYW5kIHByZXZlbnQgdGhhdCBmcm9tIGhhcHBlbmluZyBhZ2FpbiBoZXJlLlxuXHRcdFx0XHQvLyBUaGlzIHRlY2huaWNhbGx5IGdldHMgdGhlIG9yZGVyaW5nIHdyb25nIHcuci50LiB0byBgLnRyaWdnZXIoKWAgKGluIHdoaWNoIHRoZVxuXHRcdFx0XHQvLyBidWJibGluZyBzdXJyb2dhdGUgcHJvcGFnYXRlcyAqYWZ0ZXIqIHRoZSBub24tYnViYmxpbmcgYmFzZSksIGJ1dCB0aGF0IHNlZW1zXG5cdFx0XHRcdC8vIGxlc3MgYmFkIHRoYW4gZHVwbGljYXRpb24uXG5cdFx0XHRcdH0gZWxzZSBpZiAoICggalF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fSApLmRlbGVnYXRlVHlwZSApIHtcblx0XHRcdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgbmF0aXZlIGV2ZW50IHRyaWdnZXJlZCBhYm92ZSwgZXZlcnl0aGluZyBpcyBub3cgaW4gb3JkZXJcblx0XHRcdC8vIEZpcmUgYW4gaW5uZXIgc3ludGhldGljIGV2ZW50IHdpdGggdGhlIG9yaWdpbmFsIGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggc2F2ZWQubGVuZ3RoICkge1xuXG5cdFx0XHRcdC8vIC4uLmFuZCBjYXB0dXJlIHRoZSByZXN1bHRcblx0XHRcdFx0ZGF0YVByaXYuc2V0KCB0aGlzLCB0eXBlLCB7XG5cdFx0XHRcdFx0dmFsdWU6IGpRdWVyeS5ldmVudC50cmlnZ2VyKFxuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMStcblx0XHRcdFx0XHRcdC8vIEV4dGVuZCB3aXRoIHRoZSBwcm90b3R5cGUgdG8gcmVzZXQgdGhlIGFib3ZlIHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpXG5cdFx0XHRcdFx0XHRqUXVlcnkuZXh0ZW5kKCBzYXZlZFsgMCBdLCBqUXVlcnkuRXZlbnQucHJvdG90eXBlICksXG5cdFx0XHRcdFx0XHRzYXZlZC5zbGljZSggMSApLFxuXHRcdFx0XHRcdFx0dGhpc1xuXHRcdFx0XHRcdClcblx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdC8vIEFib3J0IGhhbmRsaW5nIG9mIHRoZSBuYXRpdmUgZXZlbnRcblx0XHRcdFx0ZXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9ICk7XG59XG5cbmpRdWVyeS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBoYW5kbGUgKSB7XG5cblx0Ly8gVGhpcyBcImlmXCIgaXMgbmVlZGVkIGZvciBwbGFpbiBvYmplY3RzXG5cdGlmICggZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyICkge1xuXHRcdGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgaGFuZGxlICk7XG5cdH1cbn07XG5cbmpRdWVyeS5FdmVudCA9IGZ1bmN0aW9uKCBzcmMsIHByb3BzICkge1xuXG5cdC8vIEFsbG93IGluc3RhbnRpYXRpb24gd2l0aG91dCB0aGUgJ25ldycga2V5d29yZFxuXHRpZiAoICEoIHRoaXMgaW5zdGFuY2VvZiBqUXVlcnkuRXZlbnQgKSApIHtcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5FdmVudCggc3JjLCBwcm9wcyApO1xuXHR9XG5cblx0Ly8gRXZlbnQgb2JqZWN0XG5cdGlmICggc3JjICYmIHNyYy50eXBlICkge1xuXHRcdHRoaXMub3JpZ2luYWxFdmVudCA9IHNyYztcblx0XHR0aGlzLnR5cGUgPSBzcmMudHlwZTtcblxuXHRcdC8vIEV2ZW50cyBidWJibGluZyB1cCB0aGUgZG9jdW1lbnQgbWF5IGhhdmUgYmVlbiBtYXJrZWQgYXMgcHJldmVudGVkXG5cdFx0Ly8gYnkgYSBoYW5kbGVyIGxvd2VyIGRvd24gdGhlIHRyZWU7IHJlZmxlY3QgdGhlIGNvcnJlY3QgdmFsdWUuXG5cdFx0dGhpcy5pc0RlZmF1bHRQcmV2ZW50ZWQgPSBzcmMuZGVmYXVsdFByZXZlbnRlZCB8fFxuXHRcdFx0XHRzcmMuZGVmYXVsdFByZXZlbnRlZCA9PT0gdW5kZWZpbmVkICYmXG5cblx0XHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTIuMyBvbmx5XG5cdFx0XHRcdHNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0cmV0dXJuVHJ1ZSA6XG5cdFx0XHRyZXR1cm5GYWxzZTtcblxuXHRcdC8vIENyZWF0ZSB0YXJnZXQgcHJvcGVydGllc1xuXHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA8PTYgLSA3IG9ubHlcblx0XHQvLyBUYXJnZXQgc2hvdWxkIG5vdCBiZSBhIHRleHQgbm9kZSAoIzUwNCwgIzEzMTQzKVxuXHRcdHRoaXMudGFyZ2V0ID0gKCBzcmMudGFyZ2V0ICYmIHNyYy50YXJnZXQubm9kZVR5cGUgPT09IDMgKSA/XG5cdFx0XHRzcmMudGFyZ2V0LnBhcmVudE5vZGUgOlxuXHRcdFx0c3JjLnRhcmdldDtcblxuXHRcdHRoaXMuY3VycmVudFRhcmdldCA9IHNyYy5jdXJyZW50VGFyZ2V0O1xuXHRcdHRoaXMucmVsYXRlZFRhcmdldCA9IHNyYy5yZWxhdGVkVGFyZ2V0O1xuXG5cdC8vIEV2ZW50IHR5cGVcblx0fSBlbHNlIHtcblx0XHR0aGlzLnR5cGUgPSBzcmM7XG5cdH1cblxuXHQvLyBQdXQgZXhwbGljaXRseSBwcm92aWRlZCBwcm9wZXJ0aWVzIG9udG8gdGhlIGV2ZW50IG9iamVjdFxuXHRpZiAoIHByb3BzICkge1xuXHRcdGpRdWVyeS5leHRlbmQoIHRoaXMsIHByb3BzICk7XG5cdH1cblxuXHQvLyBDcmVhdGUgYSB0aW1lc3RhbXAgaWYgaW5jb21pbmcgZXZlbnQgZG9lc24ndCBoYXZlIG9uZVxuXHR0aGlzLnRpbWVTdGFtcCA9IHNyYyAmJiBzcmMudGltZVN0YW1wIHx8IERhdGUubm93KCk7XG5cblx0Ly8gTWFyayBpdCBhcyBmaXhlZFxuXHR0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTtcbn07XG5cbi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZ1xuLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSLzIwMDMvV0QtRE9NLUxldmVsLTMtRXZlbnRzLTIwMDMwMzMxL2VjbWEtc2NyaXB0LWJpbmRpbmcuaHRtbFxualF1ZXJ5LkV2ZW50LnByb3RvdHlwZSA9IHtcblx0Y29uc3RydWN0b3I6IGpRdWVyeS5FdmVudCxcblx0aXNEZWZhdWx0UHJldmVudGVkOiByZXR1cm5GYWxzZSxcblx0aXNQcm9wYWdhdGlvblN0b3BwZWQ6IHJldHVybkZhbHNlLFxuXHRpc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cdGlzU2ltdWxhdGVkOiBmYWxzZSxcblxuXHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9LFxuXHRzdG9wUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdH1cblx0fSxcblx0c3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcblxuXHRcdHRoaXMuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQgPSByZXR1cm5UcnVlO1xuXG5cdFx0aWYgKCBlICYmICF0aGlzLmlzU2ltdWxhdGVkICkge1xuXHRcdFx0ZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcblx0XHR9XG5cblx0XHR0aGlzLnN0b3BQcm9wYWdhdGlvbigpO1xuXHR9XG59O1xuXG4vLyBJbmNsdWRlcyBhbGwgY29tbW9uIGV2ZW50IHByb3BzIGluY2x1ZGluZyBLZXlFdmVudCBhbmQgTW91c2VFdmVudCBzcGVjaWZpYyBwcm9wc1xualF1ZXJ5LmVhY2goIHtcblx0YWx0S2V5OiB0cnVlLFxuXHRidWJibGVzOiB0cnVlLFxuXHRjYW5jZWxhYmxlOiB0cnVlLFxuXHRjaGFuZ2VkVG91Y2hlczogdHJ1ZSxcblx0Y3RybEtleTogdHJ1ZSxcblx0ZGV0YWlsOiB0cnVlLFxuXHRldmVudFBoYXNlOiB0cnVlLFxuXHRtZXRhS2V5OiB0cnVlLFxuXHRwYWdlWDogdHJ1ZSxcblx0cGFnZVk6IHRydWUsXG5cdHNoaWZ0S2V5OiB0cnVlLFxuXHR2aWV3OiB0cnVlLFxuXHRcImNoYXJcIjogdHJ1ZSxcblx0Y29kZTogdHJ1ZSxcblx0Y2hhckNvZGU6IHRydWUsXG5cdGtleTogdHJ1ZSxcblx0a2V5Q29kZTogdHJ1ZSxcblx0YnV0dG9uOiB0cnVlLFxuXHRidXR0b25zOiB0cnVlLFxuXHRjbGllbnRYOiB0cnVlLFxuXHRjbGllbnRZOiB0cnVlLFxuXHRvZmZzZXRYOiB0cnVlLFxuXHRvZmZzZXRZOiB0cnVlLFxuXHRwb2ludGVySWQ6IHRydWUsXG5cdHBvaW50ZXJUeXBlOiB0cnVlLFxuXHRzY3JlZW5YOiB0cnVlLFxuXHRzY3JlZW5ZOiB0cnVlLFxuXHR0YXJnZXRUb3VjaGVzOiB0cnVlLFxuXHR0b0VsZW1lbnQ6IHRydWUsXG5cdHRvdWNoZXM6IHRydWUsXG5cblx0d2hpY2g6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHR2YXIgYnV0dG9uID0gZXZlbnQuYnV0dG9uO1xuXG5cdFx0Ly8gQWRkIHdoaWNoIGZvciBrZXkgZXZlbnRzXG5cdFx0aWYgKCBldmVudC53aGljaCA9PSBudWxsICYmIHJrZXlFdmVudC50ZXN0KCBldmVudC50eXBlICkgKSB7XG5cdFx0XHRyZXR1cm4gZXZlbnQuY2hhckNvZGUgIT0gbnVsbCA/IGV2ZW50LmNoYXJDb2RlIDogZXZlbnQua2V5Q29kZTtcblx0XHR9XG5cblx0XHQvLyBBZGQgd2hpY2ggZm9yIGNsaWNrOiAxID09PSBsZWZ0OyAyID09PSBtaWRkbGU7IDMgPT09IHJpZ2h0XG5cdFx0aWYgKCAhZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQgJiYgcm1vdXNlRXZlbnQudGVzdCggZXZlbnQudHlwZSApICkge1xuXHRcdFx0aWYgKCBidXR0b24gJiAxICkge1xuXHRcdFx0XHRyZXR1cm4gMTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBidXR0b24gJiAyICkge1xuXHRcdFx0XHRyZXR1cm4gMztcblx0XHRcdH1cblxuXHRcdFx0aWYgKCBidXR0b24gJiA0ICkge1xuXHRcdFx0XHRyZXR1cm4gMjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIDA7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGV2ZW50LndoaWNoO1xuXHR9XG59LCBqUXVlcnkuZXZlbnQuYWRkUHJvcCApO1xuXG5qUXVlcnkuZWFjaCggeyBmb2N1czogXCJmb2N1c2luXCIsIGJsdXI6IFwiZm9jdXNvdXRcIiB9LCBmdW5jdGlvbiggdHlwZSwgZGVsZWdhdGVUeXBlICkge1xuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdID0ge1xuXG5cdFx0Ly8gVXRpbGl6ZSBuYXRpdmUgZXZlbnQgaWYgcG9zc2libGUgc28gYmx1ci9mb2N1cyBzZXF1ZW5jZSBpcyBjb3JyZWN0XG5cdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBDbGFpbSB0aGUgZmlyc3QgaGFuZGxlclxuXHRcdFx0Ly8gZGF0YVByaXYuc2V0KCB0aGlzLCBcImZvY3VzXCIsIC4uLiApXG5cdFx0XHQvLyBkYXRhUHJpdi5zZXQoIHRoaXMsIFwiYmx1clwiLCAuLi4gKVxuXHRcdFx0bGV2ZXJhZ2VOYXRpdmUoIHRoaXMsIHR5cGUsIGV4cGVjdFN5bmMgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIGZhbHNlIHRvIGFsbG93IG5vcm1hbCBwcm9jZXNzaW5nIGluIHRoZSBjYWxsZXJcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdHRyaWdnZXI6IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBGb3JjZSBzZXR1cCBiZWZvcmUgdHJpZ2dlclxuXHRcdFx0bGV2ZXJhZ2VOYXRpdmUoIHRoaXMsIHR5cGUgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIG5vbi1mYWxzZSB0byBhbGxvdyBub3JtYWwgZXZlbnQtcGF0aCBwcm9wYWdhdGlvblxuXHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0fSxcblxuXHRcdGRlbGVnYXRlVHlwZTogZGVsZWdhdGVUeXBlXG5cdH07XG59ICk7XG5cbi8vIENyZWF0ZSBtb3VzZWVudGVyL2xlYXZlIGV2ZW50cyB1c2luZyBtb3VzZW92ZXIvb3V0IGFuZCBldmVudC10aW1lIGNoZWNrc1xuLy8gc28gdGhhdCBldmVudCBkZWxlZ2F0aW9uIHdvcmtzIGluIGpRdWVyeS5cbi8vIERvIHRoZSBzYW1lIGZvciBwb2ludGVyZW50ZXIvcG9pbnRlcmxlYXZlIGFuZCBwb2ludGVyb3Zlci9wb2ludGVyb3V0XG4vL1xuLy8gU3VwcG9ydDogU2FmYXJpIDcgb25seVxuLy8gU2FmYXJpIHNlbmRzIG1vdXNlZW50ZXIgdG9vIG9mdGVuOyBzZWU6XG4vLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NzAyNThcbi8vIGZvciB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGJ1ZyAoaXQgZXhpc3RlZCBpbiBvbGRlciBDaHJvbWUgdmVyc2lvbnMgYXMgd2VsbCkuXG5qUXVlcnkuZWFjaCgge1xuXHRtb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLFxuXHRtb3VzZWxlYXZlOiBcIm1vdXNlb3V0XCIsXG5cdHBvaW50ZXJlbnRlcjogXCJwb2ludGVyb3ZlclwiLFxuXHRwb2ludGVybGVhdmU6IFwicG9pbnRlcm91dFwiXG59LCBmdW5jdGlvbiggb3JpZywgZml4ICkge1xuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgb3JpZyBdID0ge1xuXHRcdGRlbGVnYXRlVHlwZTogZml4LFxuXHRcdGJpbmRUeXBlOiBmaXgsXG5cblx0XHRoYW5kbGU6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdHZhciByZXQsXG5cdFx0XHRcdHRhcmdldCA9IHRoaXMsXG5cdFx0XHRcdHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0LFxuXHRcdFx0XHRoYW5kbGVPYmogPSBldmVudC5oYW5kbGVPYmo7XG5cblx0XHRcdC8vIEZvciBtb3VzZWVudGVyL2xlYXZlIGNhbGwgdGhlIGhhbmRsZXIgaWYgcmVsYXRlZCBpcyBvdXRzaWRlIHRoZSB0YXJnZXQuXG5cdFx0XHQvLyBOQjogTm8gcmVsYXRlZFRhcmdldCBpZiB0aGUgbW91c2UgbGVmdC9lbnRlcmVkIHRoZSBicm93c2VyIHdpbmRvd1xuXHRcdFx0aWYgKCAhcmVsYXRlZCB8fCAoIHJlbGF0ZWQgIT09IHRhcmdldCAmJiAhalF1ZXJ5LmNvbnRhaW5zKCB0YXJnZXQsIHJlbGF0ZWQgKSApICkge1xuXHRcdFx0XHRldmVudC50eXBlID0gaGFuZGxlT2JqLm9yaWdUeXBlO1xuXHRcdFx0XHRyZXQgPSBoYW5kbGVPYmouaGFuZGxlci5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdGV2ZW50LnR5cGUgPSBmaXg7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmV0O1xuXHRcdH1cblx0fTtcbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdG9uOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gb24oIHRoaXMsIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4gKTtcblx0fSxcblx0b25lOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gb24oIHRoaXMsIHR5cGVzLCBzZWxlY3RvciwgZGF0YSwgZm4sIDEgKTtcblx0fSxcblx0b2ZmOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBmbiApIHtcblx0XHR2YXIgaGFuZGxlT2JqLCB0eXBlO1xuXHRcdGlmICggdHlwZXMgJiYgdHlwZXMucHJldmVudERlZmF1bHQgJiYgdHlwZXMuaGFuZGxlT2JqICkge1xuXG5cdFx0XHQvLyAoIGV2ZW50ICkgIGRpc3BhdGNoZWQgalF1ZXJ5LkV2ZW50XG5cdFx0XHRoYW5kbGVPYmogPSB0eXBlcy5oYW5kbGVPYmo7XG5cdFx0XHRqUXVlcnkoIHR5cGVzLmRlbGVnYXRlVGFyZ2V0ICkub2ZmKFxuXHRcdFx0XHRoYW5kbGVPYmoubmFtZXNwYWNlID9cblx0XHRcdFx0XHRoYW5kbGVPYmoub3JpZ1R5cGUgKyBcIi5cIiArIGhhbmRsZU9iai5uYW1lc3BhY2UgOlxuXHRcdFx0XHRcdGhhbmRsZU9iai5vcmlnVHlwZSxcblx0XHRcdFx0aGFuZGxlT2JqLnNlbGVjdG9yLFxuXHRcdFx0XHRoYW5kbGVPYmouaGFuZGxlclxuXHRcdFx0KTtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcblxuXHRcdFx0Ly8gKCB0eXBlcy1vYmplY3QgWywgc2VsZWN0b3JdIClcblx0XHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XG5cdFx0XHRcdHRoaXMub2ZmKCB0eXBlLCBzZWxlY3RvciwgdHlwZXNbIHR5cGUgXSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXHRcdGlmICggc2VsZWN0b3IgPT09IGZhbHNlIHx8IHR5cGVvZiBzZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiICkge1xuXG5cdFx0XHQvLyAoIHR5cGVzIFssIGZuXSApXG5cdFx0XHRmbiA9IHNlbGVjdG9yO1xuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICggZm4gPT09IGZhbHNlICkge1xuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCB0eXBlcywgZm4sIHNlbGVjdG9yICk7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cblxudmFyXG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMCAtIDExLCBFZGdlIDEyIC0gMTMgb25seVxuXHQvLyBJbiBJRS9FZGdlIHVzaW5nIHJlZ2V4IGdyb3VwcyBoZXJlIGNhdXNlcyBzZXZlcmUgc2xvd2Rvd25zLlxuXHQvLyBTZWUgaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vSUUvZmVlZGJhY2svZGV0YWlscy8xNzM2NTEyL1xuXHRybm9Jbm5lcmh0bWwgPSAvPHNjcmlwdHw8c3R5bGV8PGxpbmsvaSxcblxuXHQvLyBjaGVja2VkPVwiY2hlY2tlZFwiIG9yIGNoZWNrZWRcblx0cmNoZWNrZWQgPSAvY2hlY2tlZFxccyooPzpbXj1dfD1cXHMqLmNoZWNrZWQuKS9pLFxuXHRyY2xlYW5TY3JpcHQgPSAvXlxccyo8ISg/OlxcW0NEQVRBXFxbfC0tKXwoPzpcXF1cXF18LS0pPlxccyokL2c7XG5cbi8vIFByZWZlciBhIHRib2R5IG92ZXIgaXRzIHBhcmVudCB0YWJsZSBmb3IgY29udGFpbmluZyBuZXcgcm93c1xuZnVuY3Rpb24gbWFuaXB1bGF0aW9uVGFyZ2V0KCBlbGVtLCBjb250ZW50ICkge1xuXHRpZiAoIG5vZGVOYW1lKCBlbGVtLCBcInRhYmxlXCIgKSAmJlxuXHRcdG5vZGVOYW1lKCBjb250ZW50Lm5vZGVUeXBlICE9PSAxMSA/IGNvbnRlbnQgOiBjb250ZW50LmZpcnN0Q2hpbGQsIFwidHJcIiApICkge1xuXG5cdFx0cmV0dXJuIGpRdWVyeSggZWxlbSApLmNoaWxkcmVuKCBcInRib2R5XCIgKVsgMCBdIHx8IGVsZW07XG5cdH1cblxuXHRyZXR1cm4gZWxlbTtcbn1cblxuLy8gUmVwbGFjZS9yZXN0b3JlIHRoZSB0eXBlIGF0dHJpYnV0ZSBvZiBzY3JpcHQgZWxlbWVudHMgZm9yIHNhZmUgRE9NIG1hbmlwdWxhdGlvblxuZnVuY3Rpb24gZGlzYWJsZVNjcmlwdCggZWxlbSApIHtcblx0ZWxlbS50eXBlID0gKCBlbGVtLmdldEF0dHJpYnV0ZSggXCJ0eXBlXCIgKSAhPT0gbnVsbCApICsgXCIvXCIgKyBlbGVtLnR5cGU7XG5cdHJldHVybiBlbGVtO1xufVxuZnVuY3Rpb24gcmVzdG9yZVNjcmlwdCggZWxlbSApIHtcblx0aWYgKCAoIGVsZW0udHlwZSB8fCBcIlwiICkuc2xpY2UoIDAsIDUgKSA9PT0gXCJ0cnVlL1wiICkge1xuXHRcdGVsZW0udHlwZSA9IGVsZW0udHlwZS5zbGljZSggNSApO1xuXHR9IGVsc2Uge1xuXHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBcInR5cGVcIiApO1xuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmZ1bmN0aW9uIGNsb25lQ29weUV2ZW50KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBpLCBsLCB0eXBlLCBwZGF0YU9sZCwgdWRhdGFPbGQsIHVkYXRhQ3VyLCBldmVudHM7XG5cblx0aWYgKCBkZXN0Lm5vZGVUeXBlICE9PSAxICkge1xuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIDEuIENvcHkgcHJpdmF0ZSBkYXRhOiBldmVudHMsIGhhbmRsZXJzLCBldGMuXG5cdGlmICggZGF0YVByaXYuaGFzRGF0YSggc3JjICkgKSB7XG5cdFx0cGRhdGFPbGQgPSBkYXRhUHJpdi5nZXQoIHNyYyApO1xuXHRcdGV2ZW50cyA9IHBkYXRhT2xkLmV2ZW50cztcblxuXHRcdGlmICggZXZlbnRzICkge1xuXHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBkZXN0LCBcImhhbmRsZSBldmVudHNcIiApO1xuXG5cdFx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcblx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBldmVudHNbIHR5cGUgXS5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggZGVzdCwgdHlwZSwgZXZlbnRzWyB0eXBlIF1bIGkgXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gMi4gQ29weSB1c2VyIGRhdGFcblx0aWYgKCBkYXRhVXNlci5oYXNEYXRhKCBzcmMgKSApIHtcblx0XHR1ZGF0YU9sZCA9IGRhdGFVc2VyLmFjY2Vzcyggc3JjICk7XG5cdFx0dWRhdGFDdXIgPSBqUXVlcnkuZXh0ZW5kKCB7fSwgdWRhdGFPbGQgKTtcblxuXHRcdGRhdGFVc2VyLnNldCggZGVzdCwgdWRhdGFDdXIgKTtcblx0fVxufVxuXG4vLyBGaXggSUUgYnVncywgc2VlIHN1cHBvcnQgdGVzdHNcbmZ1bmN0aW9uIGZpeElucHV0KCBzcmMsIGRlc3QgKSB7XG5cdHZhciBub2RlTmFtZSA9IGRlc3Qubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcblxuXHQvLyBGYWlscyB0byBwZXJzaXN0IHRoZSBjaGVja2VkIHN0YXRlIG9mIGEgY2xvbmVkIGNoZWNrYm94IG9yIHJhZGlvIGJ1dHRvbi5cblx0aWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmIHJjaGVja2FibGVUeXBlLnRlc3QoIHNyYy50eXBlICkgKSB7XG5cdFx0ZGVzdC5jaGVja2VkID0gc3JjLmNoZWNrZWQ7XG5cblx0Ly8gRmFpbHMgdG8gcmV0dXJuIHRoZSBzZWxlY3RlZCBvcHRpb24gdG8gdGhlIGRlZmF1bHQgc2VsZWN0ZWQgc3RhdGUgd2hlbiBjbG9uaW5nIG9wdGlvbnNcblx0fSBlbHNlIGlmICggbm9kZU5hbWUgPT09IFwiaW5wdXRcIiB8fCBub2RlTmFtZSA9PT0gXCJ0ZXh0YXJlYVwiICkge1xuXHRcdGRlc3QuZGVmYXVsdFZhbHVlID0gc3JjLmRlZmF1bHRWYWx1ZTtcblx0fVxufVxuXG5mdW5jdGlvbiBkb21NYW5pcCggY29sbGVjdGlvbiwgYXJncywgY2FsbGJhY2ssIGlnbm9yZWQgKSB7XG5cblx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xuXHRhcmdzID0gZmxhdCggYXJncyApO1xuXG5cdHZhciBmcmFnbWVudCwgZmlyc3QsIHNjcmlwdHMsIGhhc1NjcmlwdHMsIG5vZGUsIGRvYyxcblx0XHRpID0gMCxcblx0XHRsID0gY29sbGVjdGlvbi5sZW5ndGgsXG5cdFx0aU5vQ2xvbmUgPSBsIC0gMSxcblx0XHR2YWx1ZSA9IGFyZ3NbIDAgXSxcblx0XHR2YWx1ZUlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdC8vIFdlIGNhbid0IGNsb25lTm9kZSBmcmFnbWVudHMgdGhhdCBjb250YWluIGNoZWNrZWQsIGluIFdlYktpdFxuXHRpZiAoIHZhbHVlSXNGdW5jdGlvbiB8fFxuXHRcdFx0KCBsID4gMSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiZcblx0XHRcdFx0IXN1cHBvcnQuY2hlY2tDbG9uZSAmJiByY2hlY2tlZC50ZXN0KCB2YWx1ZSApICkgKSB7XG5cdFx0cmV0dXJuIGNvbGxlY3Rpb24uZWFjaCggZnVuY3Rpb24oIGluZGV4ICkge1xuXHRcdFx0dmFyIHNlbGYgPSBjb2xsZWN0aW9uLmVxKCBpbmRleCApO1xuXHRcdFx0aWYgKCB2YWx1ZUlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdGFyZ3NbIDAgXSA9IHZhbHVlLmNhbGwoIHRoaXMsIGluZGV4LCBzZWxmLmh0bWwoKSApO1xuXHRcdFx0fVxuXHRcdFx0ZG9tTWFuaXAoIHNlbGYsIGFyZ3MsIGNhbGxiYWNrLCBpZ25vcmVkICk7XG5cdFx0fSApO1xuXHR9XG5cblx0aWYgKCBsICkge1xuXHRcdGZyYWdtZW50ID0gYnVpbGRGcmFnbWVudCggYXJncywgY29sbGVjdGlvblsgMCBdLm93bmVyRG9jdW1lbnQsIGZhbHNlLCBjb2xsZWN0aW9uLCBpZ25vcmVkICk7XG5cdFx0Zmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkO1xuXG5cdFx0aWYgKCBmcmFnbWVudC5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSApIHtcblx0XHRcdGZyYWdtZW50ID0gZmlyc3Q7XG5cdFx0fVxuXG5cdFx0Ly8gUmVxdWlyZSBlaXRoZXIgbmV3IGNvbnRlbnQgb3IgYW4gaW50ZXJlc3QgaW4gaWdub3JlZCBlbGVtZW50cyB0byBpbnZva2UgdGhlIGNhbGxiYWNrXG5cdFx0aWYgKCBmaXJzdCB8fCBpZ25vcmVkICkge1xuXHRcdFx0c2NyaXB0cyA9IGpRdWVyeS5tYXAoIGdldEFsbCggZnJhZ21lbnQsIFwic2NyaXB0XCIgKSwgZGlzYWJsZVNjcmlwdCApO1xuXHRcdFx0aGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoO1xuXG5cdFx0XHQvLyBVc2UgdGhlIG9yaWdpbmFsIGZyYWdtZW50IGZvciB0aGUgbGFzdCBpdGVtXG5cdFx0XHQvLyBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXBcblx0XHRcdC8vIGJlaW5nIGVtcHRpZWQgaW5jb3JyZWN0bHkgaW4gY2VydGFpbiBzaXR1YXRpb25zICgjODA3MCkuXG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdG5vZGUgPSBmcmFnbWVudDtcblxuXHRcdFx0XHRpZiAoIGkgIT09IGlOb0Nsb25lICkge1xuXHRcdFx0XHRcdG5vZGUgPSBqUXVlcnkuY2xvbmUoIG5vZGUsIHRydWUsIHRydWUgKTtcblxuXHRcdFx0XHRcdC8vIEtlZXAgcmVmZXJlbmNlcyB0byBjbG9uZWQgc2NyaXB0cyBmb3IgbGF0ZXIgcmVzdG9yYXRpb25cblx0XHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjAgb25seSwgUGhhbnRvbUpTIDEgb25seVxuXHRcdFx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxuXHRcdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBzY3JpcHRzLCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdGNhbGxiYWNrLmNhbGwoIGNvbGxlY3Rpb25bIGkgXSwgbm9kZSwgaSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XG5cdFx0XHRcdGRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRcdFx0Ly8gUmVlbmFibGUgc2NyaXB0c1xuXHRcdFx0XHRqUXVlcnkubWFwKCBzY3JpcHRzLCByZXN0b3JlU2NyaXB0ICk7XG5cblx0XHRcdFx0Ly8gRXZhbHVhdGUgZXhlY3V0YWJsZSBzY3JpcHRzIG9uIGZpcnN0IGRvY3VtZW50IGluc2VydGlvblxuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGhhc1NjcmlwdHM7IGkrKyApIHtcblx0XHRcdFx0XHRub2RlID0gc2NyaXB0c1sgaSBdO1xuXHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggbm9kZS50eXBlIHx8IFwiXCIgKSAmJlxuXHRcdFx0XHRcdFx0IWRhdGFQcml2LmFjY2Vzcyggbm9kZSwgXCJnbG9iYWxFdmFsXCIgKSAmJlxuXHRcdFx0XHRcdFx0alF1ZXJ5LmNvbnRhaW5zKCBkb2MsIG5vZGUgKSApIHtcblxuXHRcdFx0XHRcdFx0aWYgKCBub2RlLnNyYyAmJiAoIG5vZGUudHlwZSB8fCBcIlwiICkudG9Mb3dlckNhc2UoKSAgIT09IFwibW9kdWxlXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gT3B0aW9uYWwgQUpBWCBkZXBlbmRlbmN5LCBidXQgd29uJ3QgcnVuIHNjcmlwdHMgaWYgbm90IHByZXNlbnRcblx0XHRcdFx0XHRcdFx0aWYgKCBqUXVlcnkuX2V2YWxVcmwgJiYgIW5vZGUubm9Nb2R1bGUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5Ll9ldmFsVXJsKCBub2RlLnNyYywge1xuXHRcdFx0XHRcdFx0XHRcdFx0bm9uY2U6IG5vZGUubm9uY2UgfHwgbm9kZS5nZXRBdHRyaWJ1dGUoIFwibm9uY2VcIiApXG5cdFx0XHRcdFx0XHRcdFx0fSwgZG9jICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdERPTUV2YWwoIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICksIG5vZGUsIGRvYyApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBjb2xsZWN0aW9uO1xufVxuXG5mdW5jdGlvbiByZW1vdmUoIGVsZW0sIHNlbGVjdG9yLCBrZWVwRGF0YSApIHtcblx0dmFyIG5vZGUsXG5cdFx0bm9kZXMgPSBzZWxlY3RvciA/IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCBlbGVtICkgOiBlbGVtLFxuXHRcdGkgPSAwO1xuXG5cdGZvciAoIDsgKCBub2RlID0gbm9kZXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcblx0XHRpZiAoICFrZWVwRGF0YSAmJiBub2RlLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBub2RlICkgKTtcblx0XHR9XG5cblx0XHRpZiAoIG5vZGUucGFyZW50Tm9kZSApIHtcblx0XHRcdGlmICgga2VlcERhdGEgJiYgaXNBdHRhY2hlZCggbm9kZSApICkge1xuXHRcdFx0XHRzZXRHbG9iYWxFdmFsKCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xuXHRcdFx0fVxuXHRcdFx0bm9kZS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBub2RlICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW07XG59XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0aHRtbFByZWZpbHRlcjogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0cmV0dXJuIGh0bWw7XG5cdH0sXG5cblx0Y2xvbmU6IGZ1bmN0aW9uKCBlbGVtLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHR2YXIgaSwgbCwgc3JjRWxlbWVudHMsIGRlc3RFbGVtZW50cyxcblx0XHRcdGNsb25lID0gZWxlbS5jbG9uZU5vZGUoIHRydWUgKSxcblx0XHRcdGluUGFnZSA9IGlzQXR0YWNoZWQoIGVsZW0gKTtcblxuXHRcdC8vIEZpeCBJRSBjbG9uaW5nIGlzc3Vlc1xuXHRcdGlmICggIXN1cHBvcnQubm9DbG9uZUNoZWNrZWQgJiYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGVsZW0ubm9kZVR5cGUgPT09IDExICkgJiZcblx0XHRcdFx0IWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXG5cdFx0XHQvLyBXZSBlc2NoZXcgU2l6emxlIGhlcmUgZm9yIHBlcmZvcm1hbmNlIHJlYXNvbnM6IGh0dHBzOi8vanNwZXJmLmNvbS9nZXRhbGwtdnMtc2l6emxlLzJcblx0XHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUgKTtcblx0XHRcdHNyY0VsZW1lbnRzID0gZ2V0QWxsKCBlbGVtICk7XG5cblx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRmaXhJbnB1dCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDb3B5IHRoZSBldmVudHMgZnJvbSB0aGUgb3JpZ2luYWwgdG8gdGhlIGNsb25lXG5cdFx0aWYgKCBkYXRhQW5kRXZlbnRzICkge1xuXHRcdFx0aWYgKCBkZWVwRGF0YUFuZEV2ZW50cyApIHtcblx0XHRcdFx0c3JjRWxlbWVudHMgPSBzcmNFbGVtZW50cyB8fCBnZXRBbGwoIGVsZW0gKTtcblx0XHRcdFx0ZGVzdEVsZW1lbnRzID0gZGVzdEVsZW1lbnRzIHx8IGdldEFsbCggY2xvbmUgKTtcblxuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IHNyY0VsZW1lbnRzLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcblx0XHRcdFx0XHRjbG9uZUNvcHlFdmVudCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIGVsZW0sIGNsb25lICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUHJlc2VydmUgc2NyaXB0IGV2YWx1YXRpb24gaGlzdG9yeVxuXHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUsIFwic2NyaXB0XCIgKTtcblx0XHRpZiAoIGRlc3RFbGVtZW50cy5sZW5ndGggPiAwICkge1xuXHRcdFx0c2V0R2xvYmFsRXZhbCggZGVzdEVsZW1lbnRzLCAhaW5QYWdlICYmIGdldEFsbCggZWxlbSwgXCJzY3JpcHRcIiApICk7XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuIHRoZSBjbG9uZWQgc2V0XG5cdFx0cmV0dXJuIGNsb25lO1xuXHR9LFxuXG5cdGNsZWFuRGF0YTogZnVuY3Rpb24oIGVsZW1zICkge1xuXHRcdHZhciBkYXRhLCBlbGVtLCB0eXBlLFxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7ICggZWxlbSA9IGVsZW1zWyBpIF0gKSAhPT0gdW5kZWZpbmVkOyBpKysgKSB7XG5cdFx0XHRpZiAoIGFjY2VwdERhdGEoIGVsZW0gKSApIHtcblx0XHRcdFx0aWYgKCAoIGRhdGEgPSBlbGVtWyBkYXRhUHJpdi5leHBhbmRvIF0gKSApIHtcblx0XHRcdFx0XHRpZiAoIGRhdGEuZXZlbnRzICkge1xuXHRcdFx0XHRcdFx0Zm9yICggdHlwZSBpbiBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsWyB0eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIFRoaXMgaXMgYSBzaG9ydGN1dCB0byBhdm9pZCBqUXVlcnkuZXZlbnQucmVtb3ZlJ3Mgb3ZlcmhlYWRcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGRhdGEuaGFuZGxlICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0zNSAtIDQ1K1xuXHRcdFx0XHRcdC8vIEFzc2lnbiB1bmRlZmluZWQgaW5zdGVhZCBvZiB1c2luZyBkZWxldGUsIHNlZSBEYXRhI3JlbW92ZVxuXHRcdFx0XHRcdGVsZW1bIGRhdGFQcml2LmV4cGFuZG8gXSA9IHVuZGVmaW5lZDtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoIGVsZW1bIGRhdGFVc2VyLmV4cGFuZG8gXSApIHtcblxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PTM1IC0gNDUrXG5cdFx0XHRcdFx0Ly8gQXNzaWduIHVuZGVmaW5lZCBpbnN0ZWFkIG9mIHVzaW5nIGRlbGV0ZSwgc2VlIERhdGEjcmVtb3ZlXG5cdFx0XHRcdFx0ZWxlbVsgZGF0YVVzZXIuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59ICk7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0ZGV0YWNoOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHJlbW92ZSggdGhpcywgc2VsZWN0b3IsIHRydWUgKTtcblx0fSxcblxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gcmVtb3ZlKCB0aGlzLCBzZWxlY3RvciApO1xuXHR9LFxuXG5cdHRleHQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS50ZXh0KCB0aGlzICkgOlxuXHRcdFx0XHR0aGlzLmVtcHR5KCkuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0XHR0aGlzLnRleHRDb250ZW50ID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9ICk7XG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggKTtcblx0fSxcblxuXHRhcHBlbmQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XG5cdFx0XHRcdHRhcmdldC5hcHBlbmRDaGlsZCggZWxlbSApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRwcmVwZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0YXJnZXQuZmlyc3RDaGlsZCApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRiZWZvcmU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdGFmdGVyOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0dGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcy5uZXh0U2libGluZyApO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRlbXB0eTogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGVsZW0sXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKCBlbGVtID0gdGhpc1sgaSBdICkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXG5cdFx0XHRcdC8vIFByZXZlbnQgbWVtb3J5IGxlYWtzXG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggZWxlbSwgZmFsc2UgKSApO1xuXG5cdFx0XHRcdC8vIFJlbW92ZSBhbnkgcmVtYWluaW5nIG5vZGVzXG5cdFx0XHRcdGVsZW0udGV4dENvbnRlbnQgPSBcIlwiO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiggZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0ZGF0YUFuZEV2ZW50cyA9IGRhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGZhbHNlIDogZGF0YUFuZEV2ZW50cztcblx0XHRkZWVwRGF0YUFuZEV2ZW50cyA9IGRlZXBEYXRhQW5kRXZlbnRzID09IG51bGwgPyBkYXRhQW5kRXZlbnRzIDogZGVlcERhdGFBbmRFdmVudHM7XG5cblx0XHRyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5jbG9uZSggdGhpcywgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKTtcblx0XHR9ICk7XG5cdH0sXG5cblx0aHRtbDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBlbGVtID0gdGhpc1sgMCBdIHx8IHt9LFxuXHRcdFx0XHRpID0gMCxcblx0XHRcdFx0bCA9IHRoaXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIHZhbHVlID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uaW5uZXJIVE1MO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTZWUgaWYgd2UgY2FuIHRha2UgYSBzaG9ydGN1dCBhbmQganVzdCB1c2UgaW5uZXJIVE1MXG5cdFx0XHRpZiAoIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiAhcm5vSW5uZXJodG1sLnRlc3QoIHZhbHVlICkgJiZcblx0XHRcdFx0IXdyYXBNYXBbICggcnRhZ05hbWUuZXhlYyggdmFsdWUgKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKSBdICkge1xuXG5cdFx0XHRcdHZhbHVlID0galF1ZXJ5Lmh0bWxQcmVmaWx0ZXIoIHZhbHVlICk7XG5cblx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0XHRlbGVtID0gdGhpc1sgaSBdIHx8IHt9O1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgZWxlbWVudCBub2RlcyBhbmQgcHJldmVudCBtZW1vcnkgbGVha3Ncblx0XHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cdFx0XHRcdFx0XHRcdGVsZW0uaW5uZXJIVE1MID0gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZWxlbSA9IDA7XG5cblx0XHRcdFx0Ly8gSWYgdXNpbmcgaW5uZXJIVE1MIHRocm93cyBhbiBleGNlcHRpb24sIHVzZSB0aGUgZmFsbGJhY2sgbWV0aG9kXG5cdFx0XHRcdH0gY2F0Y2ggKCBlICkge31cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHR0aGlzLmVtcHR5KCkuYXBwZW5kKCB2YWx1ZSApO1xuXHRcdFx0fVxuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoICk7XG5cdH0sXG5cblx0cmVwbGFjZVdpdGg6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBpZ25vcmVkID0gW107XG5cblx0XHQvLyBNYWtlIHRoZSBjaGFuZ2VzLCByZXBsYWNpbmcgZWFjaCBub24taWdub3JlZCBjb250ZXh0IGVsZW1lbnQgd2l0aCB0aGUgbmV3IGNvbnRlbnRcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHR2YXIgcGFyZW50ID0gdGhpcy5wYXJlbnROb2RlO1xuXG5cdFx0XHRpZiAoIGpRdWVyeS5pbkFycmF5KCB0aGlzLCBpZ25vcmVkICkgPCAwICkge1xuXHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIHRoaXMgKSApO1xuXHRcdFx0XHRpZiAoIHBhcmVudCApIHtcblx0XHRcdFx0XHRwYXJlbnQucmVwbGFjZUNoaWxkKCBlbGVtLCB0aGlzICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdC8vIEZvcmNlIGNhbGxiYWNrIGludm9jYXRpb25cblx0XHR9LCBpZ25vcmVkICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIHtcblx0YXBwZW5kVG86IFwiYXBwZW5kXCIsXG5cdHByZXBlbmRUbzogXCJwcmVwZW5kXCIsXG5cdGluc2VydEJlZm9yZTogXCJiZWZvcmVcIixcblx0aW5zZXJ0QWZ0ZXI6IFwiYWZ0ZXJcIixcblx0cmVwbGFjZUFsbDogXCJyZXBsYWNlV2l0aFwiXG59LCBmdW5jdGlvbiggbmFtZSwgb3JpZ2luYWwgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBlbGVtcyxcblx0XHRcdHJldCA9IFtdLFxuXHRcdFx0aW5zZXJ0ID0galF1ZXJ5KCBzZWxlY3RvciApLFxuXHRcdFx0bGFzdCA9IGluc2VydC5sZW5ndGggLSAxLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7IGkgPD0gbGFzdDsgaSsrICkge1xuXHRcdFx0ZWxlbXMgPSBpID09PSBsYXN0ID8gdGhpcyA6IHRoaXMuY2xvbmUoIHRydWUgKTtcblx0XHRcdGpRdWVyeSggaW5zZXJ0WyBpIF0gKVsgb3JpZ2luYWwgXSggZWxlbXMgKTtcblxuXHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMCBvbmx5LCBQaGFudG9tSlMgMSBvbmx5XG5cdFx0XHQvLyAuZ2V0KCkgYmVjYXVzZSBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XG5cdFx0XHRwdXNoLmFwcGx5KCByZXQsIGVsZW1zLmdldCgpICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTtcblx0fTtcbn0gKTtcbnZhciBybnVtbm9ucHggPSBuZXcgUmVnRXhwKCBcIl4oXCIgKyBwbnVtICsgXCIpKD8hcHgpW2EteiVdKyRcIiwgXCJpXCIgKTtcblxudmFyIGdldFN0eWxlcyA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5LCBGaXJlZm94IDw9MzAgKCMxNTA5OCwgIzE0MTUwKVxuXHRcdC8vIElFIHRocm93cyBvbiBlbGVtZW50cyBjcmVhdGVkIGluIHBvcHVwc1xuXHRcdC8vIEZGIG1lYW53aGlsZSB0aHJvd3Mgb24gZnJhbWUgZWxlbWVudHMgdGhyb3VnaCBcImRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGVcIlxuXHRcdHZhciB2aWV3ID0gZWxlbS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3O1xuXG5cdFx0aWYgKCAhdmlldyB8fCAhdmlldy5vcGVuZXIgKSB7XG5cdFx0XHR2aWV3ID0gd2luZG93O1xuXHRcdH1cblxuXHRcdHJldHVybiB2aWV3LmdldENvbXB1dGVkU3R5bGUoIGVsZW0gKTtcblx0fTtcblxudmFyIHN3YXAgPSBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgY2FsbGJhY2sgKSB7XG5cdHZhciByZXQsIG5hbWUsXG5cdFx0b2xkID0ge307XG5cblx0Ly8gUmVtZW1iZXIgdGhlIG9sZCB2YWx1ZXMsIGFuZCBpbnNlcnQgdGhlIG5ldyBvbmVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRvbGRbIG5hbWUgXSA9IGVsZW0uc3R5bGVbIG5hbWUgXTtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvcHRpb25zWyBuYW1lIF07XG5cdH1cblxuXHRyZXQgPSBjYWxsYmFjay5jYWxsKCBlbGVtICk7XG5cblx0Ly8gUmV2ZXJ0IHRoZSBvbGQgdmFsdWVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvbGRbIG5hbWUgXTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59O1xuXG5cbnZhciByYm94U3R5bGUgPSBuZXcgUmVnRXhwKCBjc3NFeHBhbmQuam9pbiggXCJ8XCIgKSwgXCJpXCIgKTtcblxuXG5cbiggZnVuY3Rpb24oKSB7XG5cblx0Ly8gRXhlY3V0aW5nIGJvdGggcGl4ZWxQb3NpdGlvbiAmIGJveFNpemluZ1JlbGlhYmxlIHRlc3RzIHJlcXVpcmUgb25seSBvbmUgbGF5b3V0XG5cdC8vIHNvIHRoZXkncmUgZXhlY3V0ZWQgYXQgdGhlIHNhbWUgdGltZSB0byBzYXZlIHRoZSBzZWNvbmQgY29tcHV0YXRpb24uXG5cdGZ1bmN0aW9uIGNvbXB1dGVTdHlsZVRlc3RzKCkge1xuXG5cdFx0Ly8gVGhpcyBpcyBhIHNpbmdsZXRvbiwgd2UgbmVlZCB0byBleGVjdXRlIGl0IG9ubHkgb25jZVxuXHRcdGlmICggIWRpdiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9IFwicG9zaXRpb246YWJzb2x1dGU7bGVmdDotMTExMTFweDt3aWR0aDo2MHB4O1wiICtcblx0XHRcdFwibWFyZ2luLXRvcDoxcHg7cGFkZGluZzowO2JvcmRlcjowXCI7XG5cdFx0ZGl2LnN0eWxlLmNzc1RleHQgPVxuXHRcdFx0XCJwb3NpdGlvbjpyZWxhdGl2ZTtkaXNwbGF5OmJsb2NrO2JveC1zaXppbmc6Ym9yZGVyLWJveDtvdmVyZmxvdzpzY3JvbGw7XCIgK1xuXHRcdFx0XCJtYXJnaW46YXV0bztib3JkZXI6MXB4O3BhZGRpbmc6MXB4O1wiICtcblx0XHRcdFwid2lkdGg6NjAlO3RvcDoxJVwiO1xuXHRcdGRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZCggY29udGFpbmVyICkuYXBwZW5kQ2hpbGQoIGRpdiApO1xuXG5cdFx0dmFyIGRpdlN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoIGRpdiApO1xuXHRcdHBpeGVsUG9zaXRpb25WYWwgPSBkaXZTdHlsZS50b3AgIT09IFwiMSVcIjtcblxuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgNC4wIC0gNC4zIG9ubHksIEZpcmVmb3ggPD0zIC0gNDRcblx0XHRyZWxpYWJsZU1hcmdpbkxlZnRWYWwgPSByb3VuZFBpeGVsTWVhc3VyZXMoIGRpdlN0eWxlLm1hcmdpbkxlZnQgKSA9PT0gMTI7XG5cblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5LCBTYWZhcmkgPD05LjEgLSAxMC4xLCBpT1MgPD03LjAgLSA5LjNcblx0XHQvLyBTb21lIHN0eWxlcyBjb21lIGJhY2sgd2l0aCBwZXJjZW50YWdlIHZhbHVlcywgZXZlbiB0aG91Z2ggdGhleSBzaG91bGRuJ3Rcblx0XHRkaXYuc3R5bGUucmlnaHQgPSBcIjYwJVwiO1xuXHRcdHBpeGVsQm94U3R5bGVzVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXZTdHlsZS5yaWdodCApID09PSAzNjtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgLSAxMSBvbmx5XG5cdFx0Ly8gRGV0ZWN0IG1pc3JlcG9ydGluZyBvZiBjb250ZW50IGRpbWVuc2lvbnMgZm9yIGJveC1zaXppbmc6Ym9yZGVyLWJveCBlbGVtZW50c1xuXHRcdGJveFNpemluZ1JlbGlhYmxlVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXZTdHlsZS53aWR0aCApID09PSAzNjtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDkgb25seVxuXHRcdC8vIERldGVjdCBvdmVyZmxvdzpzY3JvbGwgc2NyZXdpbmVzcyAoZ2gtMzY5OSlcblx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD02NFxuXHRcdC8vIERvbid0IGdldCB0cmlja2VkIHdoZW4gem9vbSBhZmZlY3RzIG9mZnNldFdpZHRoIChnaC00MDI5KVxuXHRcdGRpdi5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcblx0XHRzY3JvbGxib3hTaXplVmFsID0gcm91bmRQaXhlbE1lYXN1cmVzKCBkaXYub2Zmc2V0V2lkdGggLyAzICkgPT09IDEyO1xuXG5cdFx0ZG9jdW1lbnRFbGVtZW50LnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcblxuXHRcdC8vIE51bGxpZnkgdGhlIGRpdiBzbyBpdCB3b3VsZG4ndCBiZSBzdG9yZWQgaW4gdGhlIG1lbW9yeSBhbmRcblx0XHQvLyBpdCB3aWxsIGFsc28gYmUgYSBzaWduIHRoYXQgY2hlY2tzIGFscmVhZHkgcGVyZm9ybWVkXG5cdFx0ZGl2ID0gbnVsbDtcblx0fVxuXG5cdGZ1bmN0aW9uIHJvdW5kUGl4ZWxNZWFzdXJlcyggbWVhc3VyZSApIHtcblx0XHRyZXR1cm4gTWF0aC5yb3VuZCggcGFyc2VGbG9hdCggbWVhc3VyZSApICk7XG5cdH1cblxuXHR2YXIgcGl4ZWxQb3NpdGlvblZhbCwgYm94U2l6aW5nUmVsaWFibGVWYWwsIHNjcm9sbGJveFNpemVWYWwsIHBpeGVsQm94U3R5bGVzVmFsLFxuXHRcdHJlbGlhYmxlVHJEaW1lbnNpb25zVmFsLCByZWxpYWJsZU1hcmdpbkxlZnRWYWwsXG5cdFx0Y29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApLFxuXHRcdGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHQvLyBGaW5pc2ggZWFybHkgaW4gbGltaXRlZCAobm9uLWJyb3dzZXIpIGVudmlyb25tZW50c1xuXHRpZiAoICFkaXYuc3R5bGUgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHQvLyBTdHlsZSBvZiBjbG9uZWQgZWxlbWVudCBhZmZlY3RzIHNvdXJjZSBlbGVtZW50IGNsb25lZCAoIzg5MDgpXG5cdGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9IFwiY29udGVudC1ib3hcIjtcblx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJcIjtcblx0c3VwcG9ydC5jbGVhckNsb25lU3R5bGUgPSBkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPT09IFwiY29udGVudC1ib3hcIjtcblxuXHRqUXVlcnkuZXh0ZW5kKCBzdXBwb3J0LCB7XG5cdFx0Ym94U2l6aW5nUmVsaWFibGU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybiBib3hTaXppbmdSZWxpYWJsZVZhbDtcblx0XHR9LFxuXHRcdHBpeGVsQm94U3R5bGVzOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gcGl4ZWxCb3hTdHlsZXNWYWw7XG5cdFx0fSxcblx0XHRwaXhlbFBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHRyZXR1cm4gcGl4ZWxQb3NpdGlvblZhbDtcblx0XHR9LFxuXHRcdHJlbGlhYmxlTWFyZ2luTGVmdDogZnVuY3Rpb24oKSB7XG5cdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xuXHRcdFx0cmV0dXJuIHJlbGlhYmxlTWFyZ2luTGVmdFZhbDtcblx0XHR9LFxuXHRcdHNjcm9sbGJveFNpemU6IGZ1bmN0aW9uKCkge1xuXHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdHJldHVybiBzY3JvbGxib3hTaXplVmFsO1xuXHRcdH0sXG5cblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTErLCBFZGdlIDE1IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBtaXNyZXBvcnQgYGdldENvbXB1dGVkU3R5bGVgIG9mIHRhYmxlIHJvd3Mgd2l0aCB3aWR0aC9oZWlnaHRcblx0XHQvLyBzZXQgaW4gQ1NTIHdoaWxlIGBvZmZzZXQqYCBwcm9wZXJ0aWVzIHJlcG9ydCBjb3JyZWN0IHZhbHVlcy5cblx0XHQvLyBCZWhhdmlvciBpbiBJRSA5IGlzIG1vcmUgc3VidGxlIHRoYW4gaW4gbmV3ZXIgdmVyc2lvbnMgJiBpdCBwYXNzZXNcblx0XHQvLyBzb21lIHZlcnNpb25zIG9mIHRoaXMgdGVzdDsgbWFrZSBzdXJlIG5vdCB0byBtYWtlIGl0IHBhc3MgdGhlcmUhXG5cdFx0cmVsaWFibGVUckRpbWVuc2lvbnM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHRhYmxlLCB0ciwgdHJDaGlsZCwgdHJTdHlsZTtcblx0XHRcdGlmICggcmVsaWFibGVUckRpbWVuc2lvbnNWYWwgPT0gbnVsbCApIHtcblx0XHRcdFx0dGFibGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInRhYmxlXCIgKTtcblx0XHRcdFx0dHIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInRyXCIgKTtcblx0XHRcdFx0dHJDaGlsZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHRcdFx0XHR0YWJsZS5zdHlsZS5jc3NUZXh0ID0gXCJwb3NpdGlvbjphYnNvbHV0ZTtsZWZ0Oi0xMTExMXB4XCI7XG5cdFx0XHRcdHRyLnN0eWxlLmhlaWdodCA9IFwiMXB4XCI7XG5cdFx0XHRcdHRyQ2hpbGQuc3R5bGUuaGVpZ2h0ID0gXCI5cHhcIjtcblxuXHRcdFx0XHRkb2N1bWVudEVsZW1lbnRcblx0XHRcdFx0XHQuYXBwZW5kQ2hpbGQoIHRhYmxlIClcblx0XHRcdFx0XHQuYXBwZW5kQ2hpbGQoIHRyIClcblx0XHRcdFx0XHQuYXBwZW5kQ2hpbGQoIHRyQ2hpbGQgKTtcblxuXHRcdFx0XHR0clN0eWxlID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoIHRyICk7XG5cdFx0XHRcdHJlbGlhYmxlVHJEaW1lbnNpb25zVmFsID0gcGFyc2VJbnQoIHRyU3R5bGUuaGVpZ2h0ICkgPiAzO1xuXG5cdFx0XHRcdGRvY3VtZW50RWxlbWVudC5yZW1vdmVDaGlsZCggdGFibGUgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZWxpYWJsZVRyRGltZW5zaW9uc1ZhbDtcblx0XHR9XG5cdH0gKTtcbn0gKSgpO1xuXG5cbmZ1bmN0aW9uIGN1ckNTUyggZWxlbSwgbmFtZSwgY29tcHV0ZWQgKSB7XG5cdHZhciB3aWR0aCwgbWluV2lkdGgsIG1heFdpZHRoLCByZXQsXG5cblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDUxK1xuXHRcdC8vIFJldHJpZXZpbmcgc3R5bGUgYmVmb3JlIGNvbXB1dGVkIHNvbWVob3dcblx0XHQvLyBmaXhlcyBhbiBpc3N1ZSB3aXRoIGdldHRpbmcgd3JvbmcgdmFsdWVzXG5cdFx0Ly8gb24gZGV0YWNoZWQgZWxlbWVudHNcblx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0Y29tcHV0ZWQgPSBjb21wdXRlZCB8fCBnZXRTdHlsZXMoIGVsZW0gKTtcblxuXHQvLyBnZXRQcm9wZXJ0eVZhbHVlIGlzIG5lZWRlZCBmb3I6XG5cdC8vICAgLmNzcygnZmlsdGVyJykgKElFIDkgb25seSwgIzEyNTM3KVxuXHQvLyAgIC5jc3MoJy0tY3VzdG9tUHJvcGVydHkpICgjMzE0NClcblx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRyZXQgPSBjb21wdXRlZC5nZXRQcm9wZXJ0eVZhbHVlKCBuYW1lICkgfHwgY29tcHV0ZWRbIG5hbWUgXTtcblxuXHRcdGlmICggcmV0ID09PSBcIlwiICYmICFpc0F0dGFjaGVkKCBlbGVtICkgKSB7XG5cdFx0XHRyZXQgPSBqUXVlcnkuc3R5bGUoIGVsZW0sIG5hbWUgKTtcblx0XHR9XG5cblx0XHQvLyBBIHRyaWJ1dGUgdG8gdGhlIFwiYXdlc29tZSBoYWNrIGJ5IERlYW4gRWR3YXJkc1wiXG5cdFx0Ly8gQW5kcm9pZCBCcm93c2VyIHJldHVybnMgcGVyY2VudGFnZSBmb3Igc29tZSB2YWx1ZXMsXG5cdFx0Ly8gYnV0IHdpZHRoIHNlZW1zIHRvIGJlIHJlbGlhYmx5IHBpeGVscy5cblx0XHQvLyBUaGlzIGlzIGFnYWluc3QgdGhlIENTU09NIGRyYWZ0IHNwZWM6XG5cdFx0Ly8gaHR0cHM6Ly9kcmFmdHMuY3Nzd2cub3JnL2Nzc29tLyNyZXNvbHZlZC12YWx1ZXNcblx0XHRpZiAoICFzdXBwb3J0LnBpeGVsQm94U3R5bGVzKCkgJiYgcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJib3hTdHlsZS50ZXN0KCBuYW1lICkgKSB7XG5cblx0XHRcdC8vIFJlbWVtYmVyIHRoZSBvcmlnaW5hbCB2YWx1ZXNcblx0XHRcdHdpZHRoID0gc3R5bGUud2lkdGg7XG5cdFx0XHRtaW5XaWR0aCA9IHN0eWxlLm1pbldpZHRoO1xuXHRcdFx0bWF4V2lkdGggPSBzdHlsZS5tYXhXaWR0aDtcblxuXHRcdFx0Ly8gUHV0IGluIHRoZSBuZXcgdmFsdWVzIHRvIGdldCBhIGNvbXB1dGVkIHZhbHVlIG91dFxuXHRcdFx0c3R5bGUubWluV2lkdGggPSBzdHlsZS5tYXhXaWR0aCA9IHN0eWxlLndpZHRoID0gcmV0O1xuXHRcdFx0cmV0ID0gY29tcHV0ZWQud2lkdGg7XG5cblx0XHRcdC8vIFJldmVydCB0aGUgY2hhbmdlZCB2YWx1ZXNcblx0XHRcdHN0eWxlLndpZHRoID0gd2lkdGg7XG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IG1pbldpZHRoO1xuXHRcdFx0c3R5bGUubWF4V2lkdGggPSBtYXhXaWR0aDtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gcmV0ICE9PSB1bmRlZmluZWQgP1xuXG5cdFx0Ly8gU3VwcG9ydDogSUUgPD05IC0gMTEgb25seVxuXHRcdC8vIElFIHJldHVybnMgekluZGV4IHZhbHVlIGFzIGFuIGludGVnZXIuXG5cdFx0cmV0ICsgXCJcIiA6XG5cdFx0cmV0O1xufVxuXG5cbmZ1bmN0aW9uIGFkZEdldEhvb2tJZiggY29uZGl0aW9uRm4sIGhvb2tGbiApIHtcblxuXHQvLyBEZWZpbmUgdGhlIGhvb2ssIHdlJ2xsIGNoZWNrIG9uIHRoZSBmaXJzdCBydW4gaWYgaXQncyByZWFsbHkgbmVlZGVkLlxuXHRyZXR1cm4ge1xuXHRcdGdldDogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGNvbmRpdGlvbkZuKCkgKSB7XG5cblx0XHRcdFx0Ly8gSG9vayBub3QgbmVlZGVkIChvciBpdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgaXQgZHVlXG5cdFx0XHRcdC8vIHRvIG1pc3NpbmcgZGVwZW5kZW5jeSksIHJlbW92ZSBpdC5cblx0XHRcdFx0ZGVsZXRlIHRoaXMuZ2V0O1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIEhvb2sgbmVlZGVkOyByZWRlZmluZSBpdCBzbyB0aGF0IHRoZSBzdXBwb3J0IHRlc3QgaXMgbm90IGV4ZWN1dGVkIGFnYWluLlxuXHRcdFx0cmV0dXJuICggdGhpcy5nZXQgPSBob29rRm4gKS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fVxuXHR9O1xufVxuXG5cbnZhciBjc3NQcmVmaXhlcyA9IFsgXCJXZWJraXRcIiwgXCJNb3pcIiwgXCJtc1wiIF0sXG5cdGVtcHR5U3R5bGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICkuc3R5bGUsXG5cdHZlbmRvclByb3BzID0ge307XG5cbi8vIFJldHVybiBhIHZlbmRvci1wcmVmaXhlZCBwcm9wZXJ0eSBvciB1bmRlZmluZWRcbmZ1bmN0aW9uIHZlbmRvclByb3BOYW1lKCBuYW1lICkge1xuXG5cdC8vIENoZWNrIGZvciB2ZW5kb3IgcHJlZml4ZWQgbmFtZXNcblx0dmFyIGNhcE5hbWUgPSBuYW1lWyAwIF0udG9VcHBlckNhc2UoKSArIG5hbWUuc2xpY2UoIDEgKSxcblx0XHRpID0gY3NzUHJlZml4ZXMubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdG5hbWUgPSBjc3NQcmVmaXhlc1sgaSBdICsgY2FwTmFtZTtcblx0XHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRcdHJldHVybiBuYW1lO1xuXHRcdH1cblx0fVxufVxuXG4vLyBSZXR1cm4gYSBwb3RlbnRpYWxseS1tYXBwZWQgalF1ZXJ5LmNzc1Byb3BzIG9yIHZlbmRvciBwcmVmaXhlZCBwcm9wZXJ0eVxuZnVuY3Rpb24gZmluYWxQcm9wTmFtZSggbmFtZSApIHtcblx0dmFyIGZpbmFsID0galF1ZXJ5LmNzc1Byb3BzWyBuYW1lIF0gfHwgdmVuZG9yUHJvcHNbIG5hbWUgXTtcblxuXHRpZiAoIGZpbmFsICkge1xuXHRcdHJldHVybiBmaW5hbDtcblx0fVxuXHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcblx0XHRyZXR1cm4gbmFtZTtcblx0fVxuXHRyZXR1cm4gdmVuZG9yUHJvcHNbIG5hbWUgXSA9IHZlbmRvclByb3BOYW1lKCBuYW1lICkgfHwgbmFtZTtcbn1cblxuXG52YXJcblxuXHQvLyBTd2FwcGFibGUgaWYgZGlzcGxheSBpcyBub25lIG9yIHN0YXJ0cyB3aXRoIHRhYmxlXG5cdC8vIGV4Y2VwdCBcInRhYmxlXCIsIFwidGFibGUtY2VsbFwiLCBvciBcInRhYmxlLWNhcHRpb25cIlxuXHQvLyBTZWUgaGVyZSBmb3IgZGlzcGxheSB2YWx1ZXM6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvQ1NTL2Rpc3BsYXlcblx0cmRpc3BsYXlzd2FwID0gL14obm9uZXx0YWJsZSg/IS1jW2VhXSkuKykvLFxuXHRyY3VzdG9tUHJvcCA9IC9eLS0vLFxuXHRjc3NTaG93ID0geyBwb3NpdGlvbjogXCJhYnNvbHV0ZVwiLCB2aXNpYmlsaXR5OiBcImhpZGRlblwiLCBkaXNwbGF5OiBcImJsb2NrXCIgfSxcblx0Y3NzTm9ybWFsVHJhbnNmb3JtID0ge1xuXHRcdGxldHRlclNwYWNpbmc6IFwiMFwiLFxuXHRcdGZvbnRXZWlnaHQ6IFwiNDAwXCJcblx0fTtcblxuZnVuY3Rpb24gc2V0UG9zaXRpdmVOdW1iZXIoIF9lbGVtLCB2YWx1ZSwgc3VidHJhY3QgKSB7XG5cblx0Ly8gQW55IHJlbGF0aXZlICgrLy0pIHZhbHVlcyBoYXZlIGFscmVhZHkgYmVlblxuXHQvLyBub3JtYWxpemVkIGF0IHRoaXMgcG9pbnRcblx0dmFyIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICk7XG5cdHJldHVybiBtYXRjaGVzID9cblxuXHRcdC8vIEd1YXJkIGFnYWluc3QgdW5kZWZpbmVkIFwic3VidHJhY3RcIiwgZS5nLiwgd2hlbiB1c2VkIGFzIGluIGNzc0hvb2tzXG5cdFx0TWF0aC5tYXgoIDAsIG1hdGNoZXNbIDIgXSAtICggc3VidHJhY3QgfHwgMCApICkgKyAoIG1hdGNoZXNbIDMgXSB8fCBcInB4XCIgKSA6XG5cdFx0dmFsdWU7XG59XG5cbmZ1bmN0aW9uIGJveE1vZGVsQWRqdXN0bWVudCggZWxlbSwgZGltZW5zaW9uLCBib3gsIGlzQm9yZGVyQm94LCBzdHlsZXMsIGNvbXB1dGVkVmFsICkge1xuXHR2YXIgaSA9IGRpbWVuc2lvbiA9PT0gXCJ3aWR0aFwiID8gMSA6IDAsXG5cdFx0ZXh0cmEgPSAwLFxuXHRcdGRlbHRhID0gMDtcblxuXHQvLyBBZGp1c3RtZW50IG1heSBub3QgYmUgbmVjZXNzYXJ5XG5cdGlmICggYm94ID09PSAoIGlzQm9yZGVyQm94ID8gXCJib3JkZXJcIiA6IFwiY29udGVudFwiICkgKSB7XG5cdFx0cmV0dXJuIDA7XG5cdH1cblxuXHRmb3IgKCA7IGkgPCA0OyBpICs9IDIgKSB7XG5cblx0XHQvLyBCb3RoIGJveCBtb2RlbHMgZXhjbHVkZSBtYXJnaW5cblx0XHRpZiAoIGJveCA9PT0gXCJtYXJnaW5cIiApIHtcblx0XHRcdGRlbHRhICs9IGpRdWVyeS5jc3MoIGVsZW0sIGJveCArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHR9XG5cblx0XHQvLyBJZiB3ZSBnZXQgaGVyZSB3aXRoIGEgY29udGVudC1ib3gsIHdlJ3JlIHNlZWtpbmcgXCJwYWRkaW5nXCIgb3IgXCJib3JkZXJcIiBvciBcIm1hcmdpblwiXG5cdFx0aWYgKCAhaXNCb3JkZXJCb3ggKSB7XG5cblx0XHRcdC8vIEFkZCBwYWRkaW5nXG5cdFx0XHRkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblxuXHRcdFx0Ly8gRm9yIFwiYm9yZGVyXCIgb3IgXCJtYXJnaW5cIiwgYWRkIGJvcmRlclxuXHRcdFx0aWYgKCBib3ggIT09IFwicGFkZGluZ1wiICkge1xuXHRcdFx0XHRkZWx0YSArPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXG5cdFx0XHQvLyBCdXQgc3RpbGwga2VlcCB0cmFjayBvZiBpdCBvdGhlcndpc2Vcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGV4dHJhICs9IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm9yZGVyXCIgKyBjc3NFeHBhbmRbIGkgXSArIFwiV2lkdGhcIiwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cblx0XHQvLyBJZiB3ZSBnZXQgaGVyZSB3aXRoIGEgYm9yZGVyLWJveCAoY29udGVudCArIHBhZGRpbmcgKyBib3JkZXIpLCB3ZSdyZSBzZWVraW5nIFwiY29udGVudFwiIG9yXG5cdFx0Ly8gXCJwYWRkaW5nXCIgb3IgXCJtYXJnaW5cIlxuXHRcdH0gZWxzZSB7XG5cblx0XHRcdC8vIEZvciBcImNvbnRlbnRcIiwgc3VidHJhY3QgcGFkZGluZ1xuXHRcdFx0aWYgKCBib3ggPT09IFwiY29udGVudFwiICkge1xuXHRcdFx0XHRkZWx0YSAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBhZGRpbmdcIiArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gRm9yIFwiY29udGVudFwiIG9yIFwicGFkZGluZ1wiLCBzdWJ0cmFjdCBib3JkZXJcblx0XHRcdGlmICggYm94ICE9PSBcIm1hcmdpblwiICkge1xuXHRcdFx0XHRkZWx0YSAtPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIEFjY291bnQgZm9yIHBvc2l0aXZlIGNvbnRlbnQtYm94IHNjcm9sbCBndXR0ZXIgd2hlbiByZXF1ZXN0ZWQgYnkgcHJvdmlkaW5nIGNvbXB1dGVkVmFsXG5cdGlmICggIWlzQm9yZGVyQm94ICYmIGNvbXB1dGVkVmFsID49IDAgKSB7XG5cblx0XHQvLyBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgaXMgYSByb3VuZGVkIHN1bSBvZiBjb250ZW50LCBwYWRkaW5nLCBzY3JvbGwgZ3V0dGVyLCBhbmQgYm9yZGVyXG5cdFx0Ly8gQXNzdW1pbmcgaW50ZWdlciBzY3JvbGwgZ3V0dGVyLCBzdWJ0cmFjdCB0aGUgcmVzdCBhbmQgcm91bmQgZG93blxuXHRcdGRlbHRhICs9IE1hdGgubWF4KCAwLCBNYXRoLmNlaWwoXG5cdFx0XHRlbGVtWyBcIm9mZnNldFwiICsgZGltZW5zaW9uWyAwIF0udG9VcHBlckNhc2UoKSArIGRpbWVuc2lvbi5zbGljZSggMSApIF0gLVxuXHRcdFx0Y29tcHV0ZWRWYWwgLVxuXHRcdFx0ZGVsdGEgLVxuXHRcdFx0ZXh0cmEgLVxuXHRcdFx0MC41XG5cblx0XHQvLyBJZiBvZmZzZXRXaWR0aC9vZmZzZXRIZWlnaHQgaXMgdW5rbm93biwgdGhlbiB3ZSBjYW4ndCBkZXRlcm1pbmUgY29udGVudC1ib3ggc2Nyb2xsIGd1dHRlclxuXHRcdC8vIFVzZSBhbiBleHBsaWNpdCB6ZXJvIHRvIGF2b2lkIE5hTiAoZ2gtMzk2NClcblx0XHQpICkgfHwgMDtcblx0fVxuXG5cdHJldHVybiBkZWx0YTtcbn1cblxuZnVuY3Rpb24gZ2V0V2lkdGhPckhlaWdodCggZWxlbSwgZGltZW5zaW9uLCBleHRyYSApIHtcblxuXHQvLyBTdGFydCB3aXRoIGNvbXB1dGVkIHN0eWxlXG5cdHZhciBzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKSxcblxuXHRcdC8vIFRvIGF2b2lkIGZvcmNpbmcgYSByZWZsb3csIG9ubHkgZmV0Y2ggYm94U2l6aW5nIGlmIHdlIG5lZWQgaXQgKGdoLTQzMjIpLlxuXHRcdC8vIEZha2UgY29udGVudC1ib3ggdW50aWwgd2Uga25vdyBpdCdzIG5lZWRlZCB0byBrbm93IHRoZSB0cnVlIHZhbHVlLlxuXHRcdGJveFNpemluZ05lZWRlZCA9ICFzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgfHwgZXh0cmEsXG5cdFx0aXNCb3JkZXJCb3ggPSBib3hTaXppbmdOZWVkZWQgJiZcblx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCIsXG5cdFx0dmFsdWVJc0JvcmRlckJveCA9IGlzQm9yZGVyQm94LFxuXG5cdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBkaW1lbnNpb24sIHN0eWxlcyApLFxuXHRcdG9mZnNldFByb3AgPSBcIm9mZnNldFwiICsgZGltZW5zaW9uWyAwIF0udG9VcHBlckNhc2UoKSArIGRpbWVuc2lvbi5zbGljZSggMSApO1xuXG5cdC8vIFN1cHBvcnQ6IEZpcmVmb3ggPD01NFxuXHQvLyBSZXR1cm4gYSBjb25mb3VuZGluZyBub24tcGl4ZWwgdmFsdWUgb3IgZmVpZ24gaWdub3JhbmNlLCBhcyBhcHByb3ByaWF0ZS5cblx0aWYgKCBybnVtbm9ucHgudGVzdCggdmFsICkgKSB7XG5cdFx0aWYgKCAhZXh0cmEgKSB7XG5cdFx0XHRyZXR1cm4gdmFsO1xuXHRcdH1cblx0XHR2YWwgPSBcImF1dG9cIjtcblx0fVxuXG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExIG9ubHlcblx0Ly8gVXNlIG9mZnNldFdpZHRoL29mZnNldEhlaWdodCBmb3Igd2hlbiBib3ggc2l6aW5nIGlzIHVucmVsaWFibGUuXG5cdC8vIEluIHRob3NlIGNhc2VzLCB0aGUgY29tcHV0ZWQgdmFsdWUgY2FuIGJlIHRydXN0ZWQgdG8gYmUgYm9yZGVyLWJveC5cblx0aWYgKCAoICFzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgJiYgaXNCb3JkZXJCb3ggfHxcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDEwIC0gMTErLCBFZGdlIDE1IC0gMTgrXG5cdFx0Ly8gSUUvRWRnZSBtaXNyZXBvcnQgYGdldENvbXB1dGVkU3R5bGVgIG9mIHRhYmxlIHJvd3Mgd2l0aCB3aWR0aC9oZWlnaHRcblx0XHQvLyBzZXQgaW4gQ1NTIHdoaWxlIGBvZmZzZXQqYCBwcm9wZXJ0aWVzIHJlcG9ydCBjb3JyZWN0IHZhbHVlcy5cblx0XHQvLyBJbnRlcmVzdGluZ2x5LCBpbiBzb21lIGNhc2VzIElFIDkgZG9lc24ndCBzdWZmZXIgZnJvbSB0aGlzIGlzc3VlLlxuXHRcdCFzdXBwb3J0LnJlbGlhYmxlVHJEaW1lbnNpb25zKCkgJiYgbm9kZU5hbWUoIGVsZW0sIFwidHJcIiApIHx8XG5cblx0XHQvLyBGYWxsIGJhY2sgdG8gb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IHdoZW4gdmFsdWUgaXMgXCJhdXRvXCJcblx0XHQvLyBUaGlzIGhhcHBlbnMgZm9yIGlubGluZSBlbGVtZW50cyB3aXRoIG5vIGV4cGxpY2l0IHNldHRpbmcgKGdoLTM1NzEpXG5cdFx0dmFsID09PSBcImF1dG9cIiB8fFxuXG5cdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA8PTQuMSAtIDQuMyBvbmx5XG5cdFx0Ly8gQWxzbyB1c2Ugb2Zmc2V0V2lkdGgvb2Zmc2V0SGVpZ2h0IGZvciBtaXNyZXBvcnRlZCBpbmxpbmUgZGltZW5zaW9ucyAoZ2gtMzYwMilcblx0XHQhcGFyc2VGbG9hdCggdmFsICkgJiYgalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJpbmxpbmVcIiApICYmXG5cblx0XHQvLyBNYWtlIHN1cmUgdGhlIGVsZW1lbnQgaXMgdmlzaWJsZSAmIGNvbm5lY3RlZFxuXHRcdGVsZW0uZ2V0Q2xpZW50UmVjdHMoKS5sZW5ndGggKSB7XG5cblx0XHRpc0JvcmRlckJveCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCI7XG5cblx0XHQvLyBXaGVyZSBhdmFpbGFibGUsIG9mZnNldFdpZHRoL29mZnNldEhlaWdodCBhcHByb3hpbWF0ZSBib3JkZXIgYm94IGRpbWVuc2lvbnMuXG5cdFx0Ly8gV2hlcmUgbm90IGF2YWlsYWJsZSAoZS5nLiwgU1ZHKSwgYXNzdW1lIHVucmVsaWFibGUgYm94LXNpemluZyBhbmQgaW50ZXJwcmV0IHRoZVxuXHRcdC8vIHJldHJpZXZlZCB2YWx1ZSBhcyBhIGNvbnRlbnQgYm94IGRpbWVuc2lvbi5cblx0XHR2YWx1ZUlzQm9yZGVyQm94ID0gb2Zmc2V0UHJvcCBpbiBlbGVtO1xuXHRcdGlmICggdmFsdWVJc0JvcmRlckJveCApIHtcblx0XHRcdHZhbCA9IGVsZW1bIG9mZnNldFByb3AgXTtcblx0XHR9XG5cdH1cblxuXHQvLyBOb3JtYWxpemUgXCJcIiBhbmQgYXV0b1xuXHR2YWwgPSBwYXJzZUZsb2F0KCB2YWwgKSB8fCAwO1xuXG5cdC8vIEFkanVzdCBmb3IgdGhlIGVsZW1lbnQncyBib3ggbW9kZWxcblx0cmV0dXJuICggdmFsICtcblx0XHRib3hNb2RlbEFkanVzdG1lbnQoXG5cdFx0XHRlbGVtLFxuXHRcdFx0ZGltZW5zaW9uLFxuXHRcdFx0ZXh0cmEgfHwgKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApLFxuXHRcdFx0dmFsdWVJc0JvcmRlckJveCxcblx0XHRcdHN0eWxlcyxcblxuXHRcdFx0Ly8gUHJvdmlkZSB0aGUgY3VycmVudCBjb21wdXRlZCBzaXplIHRvIHJlcXVlc3Qgc2Nyb2xsIGd1dHRlciBjYWxjdWxhdGlvbiAoZ2gtMzU4OSlcblx0XHRcdHZhbFxuXHRcdClcblx0KSArIFwicHhcIjtcbn1cblxualF1ZXJ5LmV4dGVuZCgge1xuXG5cdC8vIEFkZCBpbiBzdHlsZSBwcm9wZXJ0eSBob29rcyBmb3Igb3ZlcnJpZGluZyB0aGUgZGVmYXVsdFxuXHQvLyBiZWhhdmlvciBvZiBnZXR0aW5nIGFuZCBzZXR0aW5nIGEgc3R5bGUgcHJvcGVydHlcblx0Y3NzSG9va3M6IHtcblx0XHRvcGFjaXR5OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblxuXHRcdFx0XHRcdC8vIFdlIHNob3VsZCBhbHdheXMgZ2V0IGEgbnVtYmVyIGJhY2sgZnJvbSBvcGFjaXR5XG5cdFx0XHRcdFx0dmFyIHJldCA9IGN1ckNTUyggZWxlbSwgXCJvcGFjaXR5XCIgKTtcblx0XHRcdFx0XHRyZXR1cm4gcmV0ID09PSBcIlwiID8gXCIxXCIgOiByZXQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0Ly8gRG9uJ3QgYXV0b21hdGljYWxseSBhZGQgXCJweFwiIHRvIHRoZXNlIHBvc3NpYmx5LXVuaXRsZXNzIHByb3BlcnRpZXNcblx0Y3NzTnVtYmVyOiB7XG5cdFx0XCJhbmltYXRpb25JdGVyYXRpb25Db3VudFwiOiB0cnVlLFxuXHRcdFwiY29sdW1uQ291bnRcIjogdHJ1ZSxcblx0XHRcImZpbGxPcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJmbGV4R3Jvd1wiOiB0cnVlLFxuXHRcdFwiZmxleFNocmlua1wiOiB0cnVlLFxuXHRcdFwiZm9udFdlaWdodFwiOiB0cnVlLFxuXHRcdFwiZ3JpZEFyZWFcIjogdHJ1ZSxcblx0XHRcImdyaWRDb2x1bW5cIjogdHJ1ZSxcblx0XHRcImdyaWRDb2x1bW5FbmRcIjogdHJ1ZSxcblx0XHRcImdyaWRDb2x1bW5TdGFydFwiOiB0cnVlLFxuXHRcdFwiZ3JpZFJvd1wiOiB0cnVlLFxuXHRcdFwiZ3JpZFJvd0VuZFwiOiB0cnVlLFxuXHRcdFwiZ3JpZFJvd1N0YXJ0XCI6IHRydWUsXG5cdFx0XCJsaW5lSGVpZ2h0XCI6IHRydWUsXG5cdFx0XCJvcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJvcmRlclwiOiB0cnVlLFxuXHRcdFwib3JwaGFuc1wiOiB0cnVlLFxuXHRcdFwid2lkb3dzXCI6IHRydWUsXG5cdFx0XCJ6SW5kZXhcIjogdHJ1ZSxcblx0XHRcInpvb21cIjogdHJ1ZVxuXHR9LFxuXG5cdC8vIEFkZCBpbiBwcm9wZXJ0aWVzIHdob3NlIG5hbWVzIHlvdSB3aXNoIHRvIGZpeCBiZWZvcmVcblx0Ly8gc2V0dGluZyBvciBnZXR0aW5nIHRoZSB2YWx1ZVxuXHRjc3NQcm9wczoge30sXG5cblx0Ly8gR2V0IGFuZCBzZXQgdGhlIHN0eWxlIHByb3BlcnR5IG9uIGEgRE9NIE5vZGVcblx0c3R5bGU6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSwgZXh0cmEgKSB7XG5cblx0XHQvLyBEb24ndCBzZXQgc3R5bGVzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCB8fCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWVcblx0XHR2YXIgcmV0LCB0eXBlLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0gY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICksXG5cdFx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWUuIFdlIGRvbid0XG5cdFx0Ly8gd2FudCB0byBxdWVyeSB0aGUgdmFsdWUgaWYgaXQgaXMgYSBDU1MgY3VzdG9tIHByb3BlcnR5XG5cdFx0Ly8gc2luY2UgdGhleSBhcmUgdXNlci1kZWZpbmVkLlxuXHRcdGlmICggIWlzQ3VzdG9tUHJvcCApIHtcblx0XHRcdG5hbWUgPSBmaW5hbFByb3BOYW1lKCBvcmlnTmFtZSApO1xuXHRcdH1cblxuXHRcdC8vIEdldHMgaG9vayBmb3IgdGhlIHByZWZpeGVkIHZlcnNpb24sIHRoZW4gdW5wcmVmaXhlZCB2ZXJzaW9uXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBDaGVjayBpZiB3ZSdyZSBzZXR0aW5nIGEgdmFsdWVcblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR0eXBlID0gdHlwZW9mIHZhbHVlO1xuXG5cdFx0XHQvLyBDb252ZXJ0IFwiKz1cIiBvciBcIi09XCIgdG8gcmVsYXRpdmUgbnVtYmVycyAoIzczNDUpXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwic3RyaW5nXCIgJiYgKCByZXQgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICkgKSAmJiByZXRbIDEgXSApIHtcblx0XHRcdFx0dmFsdWUgPSBhZGp1c3RDU1MoIGVsZW0sIG5hbWUsIHJldCApO1xuXG5cdFx0XHRcdC8vIEZpeGVzIGJ1ZyAjOTIzN1xuXHRcdFx0XHR0eXBlID0gXCJudW1iZXJcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgbnVsbCBhbmQgTmFOIHZhbHVlcyBhcmVuJ3Qgc2V0ICgjNzExNilcblx0XHRcdGlmICggdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUgKSB7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBudW1iZXIgd2FzIHBhc3NlZCBpbiwgYWRkIHRoZSB1bml0IChleGNlcHQgZm9yIGNlcnRhaW4gQ1NTIHByb3BlcnRpZXMpXG5cdFx0XHQvLyBUaGUgaXNDdXN0b21Qcm9wIGNoZWNrIGNhbiBiZSByZW1vdmVkIGluIGpRdWVyeSA0LjAgd2hlbiB3ZSBvbmx5IGF1dG8tYXBwZW5kXG5cdFx0XHQvLyBcInB4XCIgdG8gYSBmZXcgaGFyZGNvZGVkIHZhbHVlcy5cblx0XHRcdGlmICggdHlwZSA9PT0gXCJudW1iZXJcIiAmJiAhaXNDdXN0b21Qcm9wICkge1xuXHRcdFx0XHR2YWx1ZSArPSByZXQgJiYgcmV0WyAzIF0gfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBvcmlnTmFtZSBdID8gXCJcIiA6IFwicHhcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBiYWNrZ3JvdW5kLSogcHJvcHMgYWZmZWN0IG9yaWdpbmFsIGNsb25lJ3MgdmFsdWVzXG5cdFx0XHRpZiAoICFzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSAmJiB2YWx1ZSA9PT0gXCJcIiAmJiBuYW1lLmluZGV4T2YoIFwiYmFja2dyb3VuZFwiICkgPT09IDAgKSB7XG5cdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSBcImluaGVyaXRcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCwgdXNlIHRoYXQgdmFsdWUsIG90aGVyd2lzZSBqdXN0IHNldCB0aGUgc3BlY2lmaWVkIHZhbHVlXG5cdFx0XHRpZiAoICFob29rcyB8fCAhKCBcInNldFwiIGluIGhvb2tzICkgfHxcblx0XHRcdFx0KCB2YWx1ZSA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIGV4dHJhICkgKSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdGlmICggaXNDdXN0b21Qcm9wICkge1xuXHRcdFx0XHRcdHN0eWxlLnNldFByb3BlcnR5KCBuYW1lLCB2YWx1ZSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCBnZXQgdGhlIG5vbi1jb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXG5cdFx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiZcblx0XHRcdFx0KCByZXQgPSBob29rcy5nZXQoIGVsZW0sIGZhbHNlLCBleHRyYSApICkgIT09IHVuZGVmaW5lZCApIHtcblxuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdGhlcndpc2UganVzdCBnZXQgdGhlIHZhbHVlIGZyb20gdGhlIHN0eWxlIG9iamVjdFxuXHRcdFx0cmV0dXJuIHN0eWxlWyBuYW1lIF07XG5cdFx0fVxuXHR9LFxuXG5cdGNzczogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGV4dHJhLCBzdHlsZXMgKSB7XG5cdFx0dmFyIHZhbCwgbnVtLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0gY2FtZWxDYXNlKCBuYW1lICksXG5cdFx0XHRpc0N1c3RvbVByb3AgPSByY3VzdG9tUHJvcC50ZXN0KCBuYW1lICk7XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWUuIFdlIGRvbid0XG5cdFx0Ly8gd2FudCB0byBtb2RpZnkgdGhlIHZhbHVlIGlmIGl0IGlzIGEgQ1NTIGN1c3RvbSBwcm9wZXJ0eVxuXHRcdC8vIHNpbmNlIHRoZXkgYXJlIHVzZXItZGVmaW5lZC5cblx0XHRpZiAoICFpc0N1c3RvbVByb3AgKSB7XG5cdFx0XHRuYW1lID0gZmluYWxQcm9wTmFtZSggb3JpZ05hbWUgKTtcblx0XHR9XG5cblx0XHQvLyBUcnkgcHJlZml4ZWQgbmFtZSBmb2xsb3dlZCBieSB0aGUgdW5wcmVmaXhlZCBuYW1lXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XG5cblx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZVxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbCA9IGhvb2tzLmdldCggZWxlbSwgdHJ1ZSwgZXh0cmEgKTtcblx0XHR9XG5cblx0XHQvLyBPdGhlcndpc2UsIGlmIGEgd2F5IHRvIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZXhpc3RzLCB1c2UgdGhhdFxuXHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHR2YWwgPSBjdXJDU1MoIGVsZW0sIG5hbWUsIHN0eWxlcyApO1xuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgXCJub3JtYWxcIiB0byBjb21wdXRlZCB2YWx1ZVxuXHRcdGlmICggdmFsID09PSBcIm5vcm1hbFwiICYmIG5hbWUgaW4gY3NzTm9ybWFsVHJhbnNmb3JtICkge1xuXHRcdFx0dmFsID0gY3NzTm9ybWFsVHJhbnNmb3JtWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBudW1lcmljIGlmIGZvcmNlZCBvciBhIHF1YWxpZmllciB3YXMgcHJvdmlkZWQgYW5kIHZhbCBsb29rcyBudW1lcmljXG5cdFx0aWYgKCBleHRyYSA9PT0gXCJcIiB8fCBleHRyYSApIHtcblx0XHRcdG51bSA9IHBhcnNlRmxvYXQoIHZhbCApO1xuXHRcdFx0cmV0dXJuIGV4dHJhID09PSB0cnVlIHx8IGlzRmluaXRlKCBudW0gKSA/IG51bSB8fCAwIDogdmFsO1xuXHRcdH1cblxuXHRcdHJldHVybiB2YWw7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmVhY2goIFsgXCJoZWlnaHRcIiwgXCJ3aWR0aFwiIF0sIGZ1bmN0aW9uKCBfaSwgZGltZW5zaW9uICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIGRpbWVuc2lvbiBdID0ge1xuXHRcdGdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkLCBleHRyYSApIHtcblx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cblx0XHRcdFx0Ly8gQ2VydGFpbiBlbGVtZW50cyBjYW4gaGF2ZSBkaW1lbnNpb24gaW5mbyBpZiB3ZSBpbnZpc2libHkgc2hvdyB0aGVtXG5cdFx0XHRcdC8vIGJ1dCBpdCBtdXN0IGhhdmUgYSBjdXJyZW50IGRpc3BsYXkgc3R5bGUgdGhhdCB3b3VsZCBiZW5lZml0XG5cdFx0XHRcdHJldHVybiByZGlzcGxheXN3YXAudGVzdCggalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSApICYmXG5cblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgOCtcblx0XHRcdFx0XHQvLyBUYWJsZSBjb2x1bW5zIGluIFNhZmFyaSBoYXZlIG5vbi16ZXJvIG9mZnNldFdpZHRoICYgemVyb1xuXHRcdFx0XHRcdC8vIGdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoIHVubGVzcyBkaXNwbGF5IGlzIGNoYW5nZWQuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdFx0XHRcdFx0Ly8gUnVubmluZyBnZXRCb3VuZGluZ0NsaWVudFJlY3Qgb24gYSBkaXNjb25uZWN0ZWQgbm9kZVxuXHRcdFx0XHRcdC8vIGluIElFIHRocm93cyBhbiBlcnJvci5cblx0XHRcdFx0XHQoICFlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoIHx8ICFlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoICkgP1xuXHRcdFx0XHRcdFx0c3dhcCggZWxlbSwgY3NzU2hvdywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBkaW1lbnNpb24sIGV4dHJhICk7XG5cdFx0XHRcdFx0XHR9ICkgOlxuXHRcdFx0XHRcdFx0Z2V0V2lkdGhPckhlaWdodCggZWxlbSwgZGltZW5zaW9uLCBleHRyYSApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgZXh0cmEgKSB7XG5cdFx0XHR2YXIgbWF0Y2hlcyxcblx0XHRcdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICksXG5cblx0XHRcdFx0Ly8gT25seSByZWFkIHN0eWxlcy5wb3NpdGlvbiBpZiB0aGUgdGVzdCBoYXMgYSBjaGFuY2UgdG8gZmFpbFxuXHRcdFx0XHQvLyB0byBhdm9pZCBmb3JjaW5nIGEgcmVmbG93LlxuXHRcdFx0XHRzY3JvbGxib3hTaXplQnVnZ3kgPSAhc3VwcG9ydC5zY3JvbGxib3hTaXplKCkgJiZcblx0XHRcdFx0XHRzdHlsZXMucG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIixcblxuXHRcdFx0XHQvLyBUbyBhdm9pZCBmb3JjaW5nIGEgcmVmbG93LCBvbmx5IGZldGNoIGJveFNpemluZyBpZiB3ZSBuZWVkIGl0IChnaC0zOTkxKVxuXHRcdFx0XHRib3hTaXppbmdOZWVkZWQgPSBzY3JvbGxib3hTaXplQnVnZ3kgfHwgZXh0cmEsXG5cdFx0XHRcdGlzQm9yZGVyQm94ID0gYm94U2l6aW5nTmVlZGVkICYmXG5cdFx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIixcblx0XHRcdFx0c3VidHJhY3QgPSBleHRyYSA/XG5cdFx0XHRcdFx0Ym94TW9kZWxBZGp1c3RtZW50KFxuXHRcdFx0XHRcdFx0ZWxlbSxcblx0XHRcdFx0XHRcdGRpbWVuc2lvbixcblx0XHRcdFx0XHRcdGV4dHJhLFxuXHRcdFx0XHRcdFx0aXNCb3JkZXJCb3gsXG5cdFx0XHRcdFx0XHRzdHlsZXNcblx0XHRcdFx0XHQpIDpcblx0XHRcdFx0XHQwO1xuXG5cdFx0XHQvLyBBY2NvdW50IGZvciB1bnJlbGlhYmxlIGJvcmRlci1ib3ggZGltZW5zaW9ucyBieSBjb21wYXJpbmcgb2Zmc2V0KiB0byBjb21wdXRlZCBhbmRcblx0XHRcdC8vIGZha2luZyBhIGNvbnRlbnQtYm94IHRvIGdldCBib3JkZXIgYW5kIHBhZGRpbmcgKGdoLTM2OTkpXG5cdFx0XHRpZiAoIGlzQm9yZGVyQm94ICYmIHNjcm9sbGJveFNpemVCdWdneSApIHtcblx0XHRcdFx0c3VidHJhY3QgLT0gTWF0aC5jZWlsKFxuXHRcdFx0XHRcdGVsZW1bIFwib2Zmc2V0XCIgKyBkaW1lbnNpb25bIDAgXS50b1VwcGVyQ2FzZSgpICsgZGltZW5zaW9uLnNsaWNlKCAxICkgXSAtXG5cdFx0XHRcdFx0cGFyc2VGbG9hdCggc3R5bGVzWyBkaW1lbnNpb24gXSApIC1cblx0XHRcdFx0XHRib3hNb2RlbEFkanVzdG1lbnQoIGVsZW0sIGRpbWVuc2lvbiwgXCJib3JkZXJcIiwgZmFsc2UsIHN0eWxlcyApIC1cblx0XHRcdFx0XHQwLjVcblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udmVydCB0byBwaXhlbHMgaWYgdmFsdWUgYWRqdXN0bWVudCBpcyBuZWVkZWRcblx0XHRcdGlmICggc3VidHJhY3QgJiYgKCBtYXRjaGVzID0gcmNzc051bS5leGVjKCB2YWx1ZSApICkgJiZcblx0XHRcdFx0KCBtYXRjaGVzWyAzIF0gfHwgXCJweFwiICkgIT09IFwicHhcIiApIHtcblxuXHRcdFx0XHRlbGVtLnN0eWxlWyBkaW1lbnNpb24gXSA9IHZhbHVlO1xuXHRcdFx0XHR2YWx1ZSA9IGpRdWVyeS5jc3MoIGVsZW0sIGRpbWVuc2lvbiApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBzdWJ0cmFjdCApO1xuXHRcdH1cblx0fTtcbn0gKTtcblxualF1ZXJ5LmNzc0hvb2tzLm1hcmdpbkxlZnQgPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucmVsaWFibGVNYXJnaW5MZWZ0LFxuXHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdHJldHVybiAoIHBhcnNlRmxvYXQoIGN1ckNTUyggZWxlbSwgXCJtYXJnaW5MZWZ0XCIgKSApIHx8XG5cdFx0XHRcdGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCAtXG5cdFx0XHRcdFx0c3dhcCggZWxlbSwgeyBtYXJnaW5MZWZ0OiAwIH0sIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdDtcblx0XHRcdFx0XHR9IClcblx0XHRcdFx0KSArIFwicHhcIjtcblx0XHR9XG5cdH1cbik7XG5cbi8vIFRoZXNlIGhvb2tzIGFyZSB1c2VkIGJ5IGFuaW1hdGUgdG8gZXhwYW5kIHByb3BlcnRpZXNcbmpRdWVyeS5lYWNoKCB7XG5cdG1hcmdpbjogXCJcIixcblx0cGFkZGluZzogXCJcIixcblx0Ym9yZGVyOiBcIldpZHRoXCJcbn0sIGZ1bmN0aW9uKCBwcmVmaXgsIHN1ZmZpeCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcmVmaXggKyBzdWZmaXggXSA9IHtcblx0XHRleHBhbmQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdHZhciBpID0gMCxcblx0XHRcdFx0ZXhwYW5kZWQgPSB7fSxcblxuXHRcdFx0XHQvLyBBc3N1bWVzIGEgc2luZ2xlIG51bWJlciBpZiBub3QgYSBzdHJpbmdcblx0XHRcdFx0cGFydHMgPSB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgPyB2YWx1ZS5zcGxpdCggXCIgXCIgKSA6IFsgdmFsdWUgXTtcblxuXHRcdFx0Zm9yICggOyBpIDwgNDsgaSsrICkge1xuXHRcdFx0XHRleHBhbmRlZFsgcHJlZml4ICsgY3NzRXhwYW5kWyBpIF0gKyBzdWZmaXggXSA9XG5cdFx0XHRcdFx0cGFydHNbIGkgXSB8fCBwYXJ0c1sgaSAtIDIgXSB8fCBwYXJ0c1sgMCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXhwYW5kZWQ7XG5cdFx0fVxuXHR9O1xuXG5cdGlmICggcHJlZml4ICE9PSBcIm1hcmdpblwiICkge1xuXHRcdGpRdWVyeS5jc3NIb29rc1sgcHJlZml4ICsgc3VmZml4IF0uc2V0ID0gc2V0UG9zaXRpdmVOdW1iZXI7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRjc3M6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgc3R5bGVzLCBsZW4sXG5cdFx0XHRcdG1hcCA9IHt9LFxuXHRcdFx0XHRpID0gMDtcblxuXHRcdFx0aWYgKCBBcnJheS5pc0FycmF5KCBuYW1lICkgKSB7XG5cdFx0XHRcdHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApO1xuXHRcdFx0XHRsZW4gPSBuYW1lLmxlbmd0aDtcblxuXHRcdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRtYXBbIG5hbWVbIGkgXSBdID0galF1ZXJ5LmNzcyggZWxlbSwgbmFtZVsgaSBdLCBmYWxzZSwgc3R5bGVzICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gbWFwO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSwgdmFsdWUgKSA6XG5cdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIG5hbWUgKTtcblx0XHR9LCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fVxufSApO1xuXG5cbmZ1bmN0aW9uIFR3ZWVuKCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApIHtcblx0cmV0dXJuIG5ldyBUd2Vlbi5wcm90b3R5cGUuaW5pdCggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcgKTtcbn1cbmpRdWVyeS5Ud2VlbiA9IFR3ZWVuO1xuXG5Ud2Vlbi5wcm90b3R5cGUgPSB7XG5cdGNvbnN0cnVjdG9yOiBUd2Vlbixcblx0aW5pdDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nLCB1bml0ICkge1xuXHRcdHRoaXMuZWxlbSA9IGVsZW07XG5cdFx0dGhpcy5wcm9wID0gcHJvcDtcblx0XHR0aGlzLmVhc2luZyA9IGVhc2luZyB8fCBqUXVlcnkuZWFzaW5nLl9kZWZhdWx0O1xuXHRcdHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XG5cdFx0dGhpcy5zdGFydCA9IHRoaXMubm93ID0gdGhpcy5jdXIoKTtcblx0XHR0aGlzLmVuZCA9IGVuZDtcblx0XHR0aGlzLnVuaXQgPSB1bml0IHx8ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdID8gXCJcIiA6IFwicHhcIiApO1xuXHR9LFxuXHRjdXI6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBob29rcyA9IFR3ZWVuLnByb3BIb29rc1sgdGhpcy5wcm9wIF07XG5cblx0XHRyZXR1cm4gaG9va3MgJiYgaG9va3MuZ2V0ID9cblx0XHRcdGhvb2tzLmdldCggdGhpcyApIDpcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5nZXQoIHRoaXMgKTtcblx0fSxcblx0cnVuOiBmdW5jdGlvbiggcGVyY2VudCApIHtcblx0XHR2YXIgZWFzZWQsXG5cdFx0XHRob29rcyA9IFR3ZWVuLnByb3BIb29rc1sgdGhpcy5wcm9wIF07XG5cblx0XHRpZiAoIHRoaXMub3B0aW9ucy5kdXJhdGlvbiApIHtcblx0XHRcdHRoaXMucG9zID0gZWFzZWQgPSBqUXVlcnkuZWFzaW5nWyB0aGlzLmVhc2luZyBdKFxuXHRcdFx0XHRwZXJjZW50LCB0aGlzLm9wdGlvbnMuZHVyYXRpb24gKiBwZXJjZW50LCAwLCAxLCB0aGlzLm9wdGlvbnMuZHVyYXRpb25cblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMucG9zID0gZWFzZWQgPSBwZXJjZW50O1xuXHRcdH1cblx0XHR0aGlzLm5vdyA9ICggdGhpcy5lbmQgLSB0aGlzLnN0YXJ0ICkgKiBlYXNlZCArIHRoaXMuc3RhcnQ7XG5cblx0XHRpZiAoIHRoaXMub3B0aW9ucy5zdGVwICkge1xuXHRcdFx0dGhpcy5vcHRpb25zLnN0ZXAuY2FsbCggdGhpcy5lbGVtLCB0aGlzLm5vdywgdGhpcyApO1xuXHRcdH1cblxuXHRcdGlmICggaG9va3MgJiYgaG9va3Muc2V0ICkge1xuXHRcdFx0aG9va3Muc2V0KCB0aGlzICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5zZXQoIHRoaXMgKTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXM7XG5cdH1cbn07XG5cblR3ZWVuLnByb3RvdHlwZS5pbml0LnByb3RvdHlwZSA9IFR3ZWVuLnByb3RvdHlwZTtcblxuVHdlZW4ucHJvcEhvb2tzID0ge1xuXHRfZGVmYXVsdDoge1xuXHRcdGdldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdFx0dmFyIHJlc3VsdDtcblxuXHRcdFx0Ly8gVXNlIGEgcHJvcGVydHkgb24gdGhlIGVsZW1lbnQgZGlyZWN0bHkgd2hlbiBpdCBpcyBub3QgYSBET00gZWxlbWVudCxcblx0XHRcdC8vIG9yIHdoZW4gdGhlcmUgaXMgbm8gbWF0Y2hpbmcgc3R5bGUgcHJvcGVydHkgdGhhdCBleGlzdHMuXG5cdFx0XHRpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgIT09IDEgfHxcblx0XHRcdFx0dHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdICE9IG51bGwgJiYgdHdlZW4uZWxlbS5zdHlsZVsgdHdlZW4ucHJvcCBdID09IG51bGwgKSB7XG5cdFx0XHRcdHJldHVybiB0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF07XG5cdFx0XHR9XG5cblx0XHRcdC8vIFBhc3NpbmcgYW4gZW1wdHkgc3RyaW5nIGFzIGEgM3JkIHBhcmFtZXRlciB0byAuY3NzIHdpbGwgYXV0b21hdGljYWxseVxuXHRcdFx0Ly8gYXR0ZW1wdCBhIHBhcnNlRmxvYXQgYW5kIGZhbGxiYWNrIHRvIGEgc3RyaW5nIGlmIHRoZSBwYXJzZSBmYWlscy5cblx0XHRcdC8vIFNpbXBsZSB2YWx1ZXMgc3VjaCBhcyBcIjEwcHhcIiBhcmUgcGFyc2VkIHRvIEZsb2F0O1xuXHRcdFx0Ly8gY29tcGxleCB2YWx1ZXMgc3VjaCBhcyBcInJvdGF0ZSgxcmFkKVwiIGFyZSByZXR1cm5lZCBhcy1pcy5cblx0XHRcdHJlc3VsdCA9IGpRdWVyeS5jc3MoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIFwiXCIgKTtcblxuXHRcdFx0Ly8gRW1wdHkgc3RyaW5ncywgbnVsbCwgdW5kZWZpbmVkIGFuZCBcImF1dG9cIiBhcmUgY29udmVydGVkIHRvIDAuXG5cdFx0XHRyZXR1cm4gIXJlc3VsdCB8fCByZXN1bHQgPT09IFwiYXV0b1wiID8gMCA6IHJlc3VsdDtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXG5cdFx0XHQvLyBVc2Ugc3RlcCBob29rIGZvciBiYWNrIGNvbXBhdC5cblx0XHRcdC8vIFVzZSBjc3NIb29rIGlmIGl0cyB0aGVyZS5cblx0XHRcdC8vIFVzZSAuc3R5bGUgaWYgYXZhaWxhYmxlIGFuZCB1c2UgcGxhaW4gcHJvcGVydGllcyB3aGVyZSBhdmFpbGFibGUuXG5cdFx0XHRpZiAoIGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0gKSB7XG5cdFx0XHRcdGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0oIHR3ZWVuICk7XG5cdFx0XHR9IGVsc2UgaWYgKCB0d2Vlbi5lbGVtLm5vZGVUeXBlID09PSAxICYmIChcblx0XHRcdFx0XHRqUXVlcnkuY3NzSG9va3NbIHR3ZWVuLnByb3AgXSB8fFxuXHRcdFx0XHRcdHR3ZWVuLmVsZW0uc3R5bGVbIGZpbmFsUHJvcE5hbWUoIHR3ZWVuLnByb3AgKSBdICE9IG51bGwgKSApIHtcblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCB0d2Vlbi5lbGVtLCB0d2Vlbi5wcm9wLCB0d2Vlbi5ub3cgKyB0d2Vlbi51bml0ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59O1xuXG4vLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuLy8gUGFuaWMgYmFzZWQgYXBwcm9hY2ggdG8gc2V0dGluZyB0aGluZ3Mgb24gZGlzY29ubmVjdGVkIG5vZGVzXG5Ud2Vlbi5wcm9wSG9va3Muc2Nyb2xsVG9wID0gVHdlZW4ucHJvcEhvb2tzLnNjcm9sbExlZnQgPSB7XG5cdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAmJiB0d2Vlbi5lbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0fVxuXHR9XG59O1xuXG5qUXVlcnkuZWFzaW5nID0ge1xuXHRsaW5lYXI6IGZ1bmN0aW9uKCBwICkge1xuXHRcdHJldHVybiBwO1xuXHR9LFxuXHRzd2luZzogZnVuY3Rpb24oIHAgKSB7XG5cdFx0cmV0dXJuIDAuNSAtIE1hdGguY29zKCBwICogTWF0aC5QSSApIC8gMjtcblx0fSxcblx0X2RlZmF1bHQ6IFwic3dpbmdcIlxufTtcblxualF1ZXJ5LmZ4ID0gVHdlZW4ucHJvdG90eXBlLmluaXQ7XG5cbi8vIEJhY2sgY29tcGF0IDwxLjggZXh0ZW5zaW9uIHBvaW50XG5qUXVlcnkuZnguc3RlcCA9IHt9O1xuXG5cblxuXG52YXJcblx0ZnhOb3csIGluUHJvZ3Jlc3MsXG5cdHJmeHR5cGVzID0gL14oPzp0b2dnbGV8c2hvd3xoaWRlKSQvLFxuXHRycnVuID0gL3F1ZXVlSG9va3MkLztcblxuZnVuY3Rpb24gc2NoZWR1bGUoKSB7XG5cdGlmICggaW5Qcm9ncmVzcyApIHtcblx0XHRpZiAoIGRvY3VtZW50LmhpZGRlbiA9PT0gZmFsc2UgJiYgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSApIHtcblx0XHRcdHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoIHNjaGVkdWxlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHdpbmRvdy5zZXRUaW1lb3V0KCBzY2hlZHVsZSwgalF1ZXJ5LmZ4LmludGVydmFsICk7XG5cdFx0fVxuXG5cdFx0alF1ZXJ5LmZ4LnRpY2soKTtcblx0fVxufVxuXG4vLyBBbmltYXRpb25zIGNyZWF0ZWQgc3luY2hyb25vdXNseSB3aWxsIHJ1biBzeW5jaHJvbm91c2x5XG5mdW5jdGlvbiBjcmVhdGVGeE5vdygpIHtcblx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdGZ4Tm93ID0gdW5kZWZpbmVkO1xuXHR9ICk7XG5cdHJldHVybiAoIGZ4Tm93ID0gRGF0ZS5ub3coKSApO1xufVxuXG4vLyBHZW5lcmF0ZSBwYXJhbWV0ZXJzIHRvIGNyZWF0ZSBhIHN0YW5kYXJkIGFuaW1hdGlvblxuZnVuY3Rpb24gZ2VuRngoIHR5cGUsIGluY2x1ZGVXaWR0aCApIHtcblx0dmFyIHdoaWNoLFxuXHRcdGkgPSAwLFxuXHRcdGF0dHJzID0geyBoZWlnaHQ6IHR5cGUgfTtcblxuXHQvLyBJZiB3ZSBpbmNsdWRlIHdpZHRoLCBzdGVwIHZhbHVlIGlzIDEgdG8gZG8gYWxsIGNzc0V4cGFuZCB2YWx1ZXMsXG5cdC8vIG90aGVyd2lzZSBzdGVwIHZhbHVlIGlzIDIgdG8gc2tpcCBvdmVyIExlZnQgYW5kIFJpZ2h0XG5cdGluY2x1ZGVXaWR0aCA9IGluY2x1ZGVXaWR0aCA/IDEgOiAwO1xuXHRmb3IgKCA7IGkgPCA0OyBpICs9IDIgLSBpbmNsdWRlV2lkdGggKSB7XG5cdFx0d2hpY2ggPSBjc3NFeHBhbmRbIGkgXTtcblx0XHRhdHRyc1sgXCJtYXJnaW5cIiArIHdoaWNoIF0gPSBhdHRyc1sgXCJwYWRkaW5nXCIgKyB3aGljaCBdID0gdHlwZTtcblx0fVxuXG5cdGlmICggaW5jbHVkZVdpZHRoICkge1xuXHRcdGF0dHJzLm9wYWNpdHkgPSBhdHRycy53aWR0aCA9IHR5cGU7XG5cdH1cblxuXHRyZXR1cm4gYXR0cnM7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVR3ZWVuKCB2YWx1ZSwgcHJvcCwgYW5pbWF0aW9uICkge1xuXHR2YXIgdHdlZW4sXG5cdFx0Y29sbGVjdGlvbiA9ICggQW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gfHwgW10gKS5jb25jYXQoIEFuaW1hdGlvbi50d2VlbmVyc1sgXCIqXCIgXSApLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aDtcblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRpZiAoICggdHdlZW4gPSBjb2xsZWN0aW9uWyBpbmRleCBdLmNhbGwoIGFuaW1hdGlvbiwgcHJvcCwgdmFsdWUgKSApICkge1xuXG5cdFx0XHQvLyBXZSdyZSBkb25lIHdpdGggdGhpcyBwcm9wZXJ0eVxuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBkZWZhdWx0UHJlZmlsdGVyKCBlbGVtLCBwcm9wcywgb3B0cyApIHtcblx0dmFyIHByb3AsIHZhbHVlLCB0b2dnbGUsIGhvb2tzLCBvbGRmaXJlLCBwcm9wVHdlZW4sIHJlc3RvcmVEaXNwbGF5LCBkaXNwbGF5LFxuXHRcdGlzQm94ID0gXCJ3aWR0aFwiIGluIHByb3BzIHx8IFwiaGVpZ2h0XCIgaW4gcHJvcHMsXG5cdFx0YW5pbSA9IHRoaXMsXG5cdFx0b3JpZyA9IHt9LFxuXHRcdHN0eWxlID0gZWxlbS5zdHlsZSxcblx0XHRoaWRkZW4gPSBlbGVtLm5vZGVUeXBlICYmIGlzSGlkZGVuV2l0aGluVHJlZSggZWxlbSApLFxuXHRcdGRhdGFTaG93ID0gZGF0YVByaXYuZ2V0KCBlbGVtLCBcImZ4c2hvd1wiICk7XG5cblx0Ly8gUXVldWUtc2tpcHBpbmcgYW5pbWF0aW9ucyBoaWphY2sgdGhlIGZ4IGhvb2tzXG5cdGlmICggIW9wdHMucXVldWUgKSB7XG5cdFx0aG9va3MgPSBqUXVlcnkuX3F1ZXVlSG9va3MoIGVsZW0sIFwiZnhcIiApO1xuXHRcdGlmICggaG9va3MudW5xdWV1ZWQgPT0gbnVsbCApIHtcblx0XHRcdGhvb2tzLnVucXVldWVkID0gMDtcblx0XHRcdG9sZGZpcmUgPSBob29rcy5lbXB0eS5maXJlO1xuXHRcdFx0aG9va3MuZW1wdHkuZmlyZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICFob29rcy51bnF1ZXVlZCApIHtcblx0XHRcdFx0XHRvbGRmaXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHRcdGhvb2tzLnVucXVldWVkKys7XG5cblx0XHRhbmltLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8vIEVuc3VyZSB0aGUgY29tcGxldGUgaGFuZGxlciBpcyBjYWxsZWQgYmVmb3JlIHRoaXMgY29tcGxldGVzXG5cdFx0XHRhbmltLmFsd2F5cyggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGhvb2tzLnVucXVldWVkLS07XG5cdFx0XHRcdGlmICggIWpRdWVyeS5xdWV1ZSggZWxlbSwgXCJmeFwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRcdGhvb2tzLmVtcHR5LmZpcmUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSApO1xuXHRcdH0gKTtcblx0fVxuXG5cdC8vIERldGVjdCBzaG93L2hpZGUgYW5pbWF0aW9uc1xuXHRmb3IgKCBwcm9wIGluIHByb3BzICkge1xuXHRcdHZhbHVlID0gcHJvcHNbIHByb3AgXTtcblx0XHRpZiAoIHJmeHR5cGVzLnRlc3QoIHZhbHVlICkgKSB7XG5cdFx0XHRkZWxldGUgcHJvcHNbIHByb3AgXTtcblx0XHRcdHRvZ2dsZSA9IHRvZ2dsZSB8fCB2YWx1ZSA9PT0gXCJ0b2dnbGVcIjtcblx0XHRcdGlmICggdmFsdWUgPT09ICggaGlkZGVuID8gXCJoaWRlXCIgOiBcInNob3dcIiApICkge1xuXG5cdFx0XHRcdC8vIFByZXRlbmQgdG8gYmUgaGlkZGVuIGlmIHRoaXMgaXMgYSBcInNob3dcIiBhbmRcblx0XHRcdFx0Ly8gdGhlcmUgaXMgc3RpbGwgZGF0YSBmcm9tIGEgc3RvcHBlZCBzaG93L2hpZGVcblx0XHRcdFx0aWYgKCB2YWx1ZSA9PT0gXCJzaG93XCIgJiYgZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRcdGhpZGRlbiA9IHRydWU7XG5cblx0XHRcdFx0Ly8gSWdub3JlIGFsbCBvdGhlciBuby1vcCBzaG93L2hpZGUgZGF0YVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRvcmlnWyBwcm9wIF0gPSBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdIHx8IGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCApO1xuXHRcdH1cblx0fVxuXG5cdC8vIEJhaWwgb3V0IGlmIHRoaXMgaXMgYSBuby1vcCBsaWtlIC5oaWRlKCkuaGlkZSgpXG5cdHByb3BUd2VlbiA9ICFqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcHMgKTtcblx0aWYgKCAhcHJvcFR3ZWVuICYmIGpRdWVyeS5pc0VtcHR5T2JqZWN0KCBvcmlnICkgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0Ly8gUmVzdHJpY3QgXCJvdmVyZmxvd1wiIGFuZCBcImRpc3BsYXlcIiBzdHlsZXMgZHVyaW5nIGJveCBhbmltYXRpb25zXG5cdGlmICggaXNCb3ggJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblxuXHRcdC8vIFN1cHBvcnQ6IElFIDw9OSAtIDExLCBFZGdlIDEyIC0gMTVcblx0XHQvLyBSZWNvcmQgYWxsIDMgb3ZlcmZsb3cgYXR0cmlidXRlcyBiZWNhdXNlIElFIGRvZXMgbm90IGluZmVyIHRoZSBzaG9ydGhhbmRcblx0XHQvLyBmcm9tIGlkZW50aWNhbGx5LXZhbHVlZCBvdmVyZmxvd1ggYW5kIG92ZXJmbG93WSBhbmQgRWRnZSBqdXN0IG1pcnJvcnNcblx0XHQvLyB0aGUgb3ZlcmZsb3dYIHZhbHVlIHRoZXJlLlxuXHRcdG9wdHMub3ZlcmZsb3cgPSBbIHN0eWxlLm92ZXJmbG93LCBzdHlsZS5vdmVyZmxvd1gsIHN0eWxlLm92ZXJmbG93WSBdO1xuXG5cdFx0Ly8gSWRlbnRpZnkgYSBkaXNwbGF5IHR5cGUsIHByZWZlcnJpbmcgb2xkIHNob3cvaGlkZSBkYXRhIG92ZXIgdGhlIENTUyBjYXNjYWRlXG5cdFx0cmVzdG9yZURpc3BsYXkgPSBkYXRhU2hvdyAmJiBkYXRhU2hvdy5kaXNwbGF5O1xuXHRcdGlmICggcmVzdG9yZURpc3BsYXkgPT0gbnVsbCApIHtcblx0XHRcdHJlc3RvcmVEaXNwbGF5ID0gZGF0YVByaXYuZ2V0KCBlbGVtLCBcImRpc3BsYXlcIiApO1xuXHRcdH1cblx0XHRkaXNwbGF5ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKTtcblx0XHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiICkge1xuXHRcdFx0aWYgKCByZXN0b3JlRGlzcGxheSApIHtcblx0XHRcdFx0ZGlzcGxheSA9IHJlc3RvcmVEaXNwbGF5O1xuXHRcdFx0fSBlbHNlIHtcblxuXHRcdFx0XHQvLyBHZXQgbm9uZW1wdHkgdmFsdWUocykgYnkgdGVtcG9yYXJpbHkgZm9yY2luZyB2aXNpYmlsaXR5XG5cdFx0XHRcdHNob3dIaWRlKCBbIGVsZW0gXSwgdHJ1ZSApO1xuXHRcdFx0XHRyZXN0b3JlRGlzcGxheSA9IGVsZW0uc3R5bGUuZGlzcGxheSB8fCByZXN0b3JlRGlzcGxheTtcblx0XHRcdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICk7XG5cdFx0XHRcdHNob3dIaWRlKCBbIGVsZW0gXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEFuaW1hdGUgaW5saW5lIGVsZW1lbnRzIGFzIGlubGluZS1ibG9ja1xuXHRcdGlmICggZGlzcGxheSA9PT0gXCJpbmxpbmVcIiB8fCBkaXNwbGF5ID09PSBcImlubGluZS1ibG9ja1wiICYmIHJlc3RvcmVEaXNwbGF5ICE9IG51bGwgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5jc3MoIGVsZW0sIFwiZmxvYXRcIiApID09PSBcIm5vbmVcIiApIHtcblxuXHRcdFx0XHQvLyBSZXN0b3JlIHRoZSBvcmlnaW5hbCBkaXNwbGF5IHZhbHVlIGF0IHRoZSBlbmQgb2YgcHVyZSBzaG93L2hpZGUgYW5pbWF0aW9uc1xuXHRcdFx0XHRpZiAoICFwcm9wVHdlZW4gKSB7XG5cdFx0XHRcdFx0YW5pbS5kb25lKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdHN0eWxlLmRpc3BsYXkgPSByZXN0b3JlRGlzcGxheTtcblx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0aWYgKCByZXN0b3JlRGlzcGxheSA9PSBudWxsICkge1xuXHRcdFx0XHRcdFx0ZGlzcGxheSA9IHN0eWxlLmRpc3BsYXk7XG5cdFx0XHRcdFx0XHRyZXN0b3JlRGlzcGxheSA9IGRpc3BsYXkgPT09IFwibm9uZVwiID8gXCJcIiA6IGRpc3BsYXk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHN0eWxlLmRpc3BsYXkgPSBcImlubGluZS1ibG9ja1wiO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmICggb3B0cy5vdmVyZmxvdyApIHtcblx0XHRzdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCI7XG5cdFx0YW5pbS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXHRcdFx0c3R5bGUub3ZlcmZsb3cgPSBvcHRzLm92ZXJmbG93WyAwIF07XG5cdFx0XHRzdHlsZS5vdmVyZmxvd1ggPSBvcHRzLm92ZXJmbG93WyAxIF07XG5cdFx0XHRzdHlsZS5vdmVyZmxvd1kgPSBvcHRzLm92ZXJmbG93WyAyIF07XG5cdFx0fSApO1xuXHR9XG5cblx0Ly8gSW1wbGVtZW50IHNob3cvaGlkZSBhbmltYXRpb25zXG5cdHByb3BUd2VlbiA9IGZhbHNlO1xuXHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XG5cblx0XHQvLyBHZW5lcmFsIHNob3cvaGlkZSBzZXR1cCBmb3IgdGhpcyBlbGVtZW50IGFuaW1hdGlvblxuXHRcdGlmICggIXByb3BUd2VlbiApIHtcblx0XHRcdGlmICggZGF0YVNob3cgKSB7XG5cdFx0XHRcdGlmICggXCJoaWRkZW5cIiBpbiBkYXRhU2hvdyApIHtcblx0XHRcdFx0XHRoaWRkZW4gPSBkYXRhU2hvdy5oaWRkZW47XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRhdGFTaG93ID0gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBcImZ4c2hvd1wiLCB7IGRpc3BsYXk6IHJlc3RvcmVEaXNwbGF5IH0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3RvcmUgaGlkZGVuL3Zpc2libGUgZm9yIHRvZ2dsZSBzbyBgLnN0b3AoKS50b2dnbGUoKWAgXCJyZXZlcnNlc1wiXG5cdFx0XHRpZiAoIHRvZ2dsZSApIHtcblx0XHRcdFx0ZGF0YVNob3cuaGlkZGVuID0gIWhpZGRlbjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2hvdyBlbGVtZW50cyBiZWZvcmUgYW5pbWF0aW5nIHRoZW1cblx0XHRcdGlmICggaGlkZGVuICkge1xuXHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0sIHRydWUgKTtcblx0XHRcdH1cblxuXHRcdFx0LyogZXNsaW50LWRpc2FibGUgbm8tbG9vcC1mdW5jICovXG5cblx0XHRcdGFuaW0uZG9uZSggZnVuY3Rpb24oKSB7XG5cblx0XHRcdC8qIGVzbGludC1lbmFibGUgbm8tbG9vcC1mdW5jICovXG5cblx0XHRcdFx0Ly8gVGhlIGZpbmFsIHN0ZXAgb2YgYSBcImhpZGVcIiBhbmltYXRpb24gaXMgYWN0dWFsbHkgaGlkaW5nIHRoZSBlbGVtZW50XG5cdFx0XHRcdGlmICggIWhpZGRlbiApIHtcblx0XHRcdFx0XHRzaG93SGlkZSggWyBlbGVtIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGVsZW0sIFwiZnhzaG93XCIgKTtcblx0XHRcdFx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgb3JpZ1sgcHJvcCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHQvLyBQZXItcHJvcGVydHkgc2V0dXBcblx0XHRwcm9wVHdlZW4gPSBjcmVhdGVUd2VlbiggaGlkZGVuID8gZGF0YVNob3dbIHByb3AgXSA6IDAsIHByb3AsIGFuaW0gKTtcblx0XHRpZiAoICEoIHByb3AgaW4gZGF0YVNob3cgKSApIHtcblx0XHRcdGRhdGFTaG93WyBwcm9wIF0gPSBwcm9wVHdlZW4uc3RhcnQ7XG5cdFx0XHRpZiAoIGhpZGRlbiApIHtcblx0XHRcdFx0cHJvcFR3ZWVuLmVuZCA9IHByb3BUd2Vlbi5zdGFydDtcblx0XHRcdFx0cHJvcFR3ZWVuLnN0YXJ0ID0gMDtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gcHJvcEZpbHRlciggcHJvcHMsIHNwZWNpYWxFYXNpbmcgKSB7XG5cdHZhciBpbmRleCwgbmFtZSwgZWFzaW5nLCB2YWx1ZSwgaG9va3M7XG5cblx0Ly8gY2FtZWxDYXNlLCBzcGVjaWFsRWFzaW5nIGFuZCBleHBhbmQgY3NzSG9vayBwYXNzXG5cdGZvciAoIGluZGV4IGluIHByb3BzICkge1xuXHRcdG5hbWUgPSBjYW1lbENhc2UoIGluZGV4ICk7XG5cdFx0ZWFzaW5nID0gc3BlY2lhbEVhc2luZ1sgbmFtZSBdO1xuXHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF07XG5cdFx0aWYgKCBBcnJheS5pc0FycmF5KCB2YWx1ZSApICkge1xuXHRcdFx0ZWFzaW5nID0gdmFsdWVbIDEgXTtcblx0XHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgMCBdO1xuXHRcdH1cblxuXHRcdGlmICggaW5kZXggIT09IG5hbWUgKSB7XG5cdFx0XHRwcm9wc1sgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRkZWxldGUgcHJvcHNbIGluZGV4IF07XG5cdFx0fVxuXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXTtcblx0XHRpZiAoIGhvb2tzICYmIFwiZXhwYW5kXCIgaW4gaG9va3MgKSB7XG5cdFx0XHR2YWx1ZSA9IGhvb2tzLmV4cGFuZCggdmFsdWUgKTtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgbmFtZSBdO1xuXG5cdFx0XHQvLyBOb3QgcXVpdGUgJC5leHRlbmQsIHRoaXMgd29uJ3Qgb3ZlcndyaXRlIGV4aXN0aW5nIGtleXMuXG5cdFx0XHQvLyBSZXVzaW5nICdpbmRleCcgYmVjYXVzZSB3ZSBoYXZlIHRoZSBjb3JyZWN0IFwibmFtZVwiXG5cdFx0XHRmb3IgKCBpbmRleCBpbiB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhKCBpbmRleCBpbiBwcm9wcyApICkge1xuXHRcdFx0XHRcdHByb3BzWyBpbmRleCBdID0gdmFsdWVbIGluZGV4IF07XG5cdFx0XHRcdFx0c3BlY2lhbEVhc2luZ1sgaW5kZXggXSA9IGVhc2luZztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRzcGVjaWFsRWFzaW5nWyBuYW1lIF0gPSBlYXNpbmc7XG5cdFx0fVxuXHR9XG59XG5cbmZ1bmN0aW9uIEFuaW1hdGlvbiggZWxlbSwgcHJvcGVydGllcywgb3B0aW9ucyApIHtcblx0dmFyIHJlc3VsdCxcblx0XHRzdG9wcGVkLFxuXHRcdGluZGV4ID0gMCxcblx0XHRsZW5ndGggPSBBbmltYXRpb24ucHJlZmlsdGVycy5sZW5ndGgsXG5cdFx0ZGVmZXJyZWQgPSBqUXVlcnkuRGVmZXJyZWQoKS5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBEb24ndCBtYXRjaCBlbGVtIGluIHRoZSA6YW5pbWF0ZWQgc2VsZWN0b3Jcblx0XHRcdGRlbGV0ZSB0aWNrLmVsZW07XG5cdFx0fSApLFxuXHRcdHRpY2sgPSBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggc3RvcHBlZCApIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0dmFyIGN1cnJlbnRUaW1lID0gZnhOb3cgfHwgY3JlYXRlRnhOb3coKSxcblx0XHRcdFx0cmVtYWluaW5nID0gTWF0aC5tYXgoIDAsIGFuaW1hdGlvbi5zdGFydFRpbWUgKyBhbmltYXRpb24uZHVyYXRpb24gLSBjdXJyZW50VGltZSApLFxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zIG9ubHlcblx0XHRcdFx0Ly8gQXJjaGFpYyBjcmFzaCBidWcgd29uJ3QgYWxsb3cgdXMgdG8gdXNlIGAxIC0gKCAwLjUgfHwgMCApYCAoIzEyNDk3KVxuXHRcdFx0XHR0ZW1wID0gcmVtYWluaW5nIC8gYW5pbWF0aW9uLmR1cmF0aW9uIHx8IDAsXG5cdFx0XHRcdHBlcmNlbnQgPSAxIC0gdGVtcCxcblx0XHRcdFx0aW5kZXggPSAwLFxuXHRcdFx0XHRsZW5ndGggPSBhbmltYXRpb24udHdlZW5zLmxlbmd0aDtcblxuXHRcdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVuc1sgaW5kZXggXS5ydW4oIHBlcmNlbnQgKTtcblx0XHRcdH1cblxuXHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIHBlcmNlbnQsIHJlbWFpbmluZyBdICk7XG5cblx0XHRcdC8vIElmIHRoZXJlJ3MgbW9yZSB0byBkbywgeWllbGRcblx0XHRcdGlmICggcGVyY2VudCA8IDEgJiYgbGVuZ3RoICkge1xuXHRcdFx0XHRyZXR1cm4gcmVtYWluaW5nO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGlzIHdhcyBhbiBlbXB0eSBhbmltYXRpb24sIHN5bnRoZXNpemUgYSBmaW5hbCBwcm9ncmVzcyBub3RpZmljYXRpb25cblx0XHRcdGlmICggIWxlbmd0aCApIHtcblx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggZWxlbSwgWyBhbmltYXRpb24sIDEsIDAgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXNvbHZlIHRoZSBhbmltYXRpb24gYW5kIHJlcG9ydCBpdHMgY29uY2x1c2lvblxuXHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uIF0gKTtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdGFuaW1hdGlvbiA9IGRlZmVycmVkLnByb21pc2UoIHtcblx0XHRcdGVsZW06IGVsZW0sXG5cdFx0XHRwcm9wczogalF1ZXJ5LmV4dGVuZCgge30sIHByb3BlcnRpZXMgKSxcblx0XHRcdG9wdHM6IGpRdWVyeS5leHRlbmQoIHRydWUsIHtcblx0XHRcdFx0c3BlY2lhbEVhc2luZzoge30sXG5cdFx0XHRcdGVhc2luZzogalF1ZXJ5LmVhc2luZy5fZGVmYXVsdFxuXHRcdFx0fSwgb3B0aW9ucyApLFxuXHRcdFx0b3JpZ2luYWxQcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzLFxuXHRcdFx0b3JpZ2luYWxPcHRpb25zOiBvcHRpb25zLFxuXHRcdFx0c3RhcnRUaW1lOiBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLFxuXHRcdFx0ZHVyYXRpb246IG9wdGlvbnMuZHVyYXRpb24sXG5cdFx0XHR0d2VlbnM6IFtdLFxuXHRcdFx0Y3JlYXRlVHdlZW46IGZ1bmN0aW9uKCBwcm9wLCBlbmQgKSB7XG5cdFx0XHRcdHZhciB0d2VlbiA9IGpRdWVyeS5Ud2VlbiggZWxlbSwgYW5pbWF0aW9uLm9wdHMsIHByb3AsIGVuZCxcblx0XHRcdFx0XHRcdGFuaW1hdGlvbi5vcHRzLnNwZWNpYWxFYXNpbmdbIHByb3AgXSB8fCBhbmltYXRpb24ub3B0cy5lYXNpbmcgKTtcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVucy5wdXNoKCB0d2VlbiApO1xuXHRcdFx0XHRyZXR1cm4gdHdlZW47XG5cdFx0XHR9LFxuXHRcdFx0c3RvcDogZnVuY3Rpb24oIGdvdG9FbmQgKSB7XG5cdFx0XHRcdHZhciBpbmRleCA9IDAsXG5cblx0XHRcdFx0XHQvLyBJZiB3ZSBhcmUgZ29pbmcgdG8gdGhlIGVuZCwgd2Ugd2FudCB0byBydW4gYWxsIHRoZSB0d2VlbnNcblx0XHRcdFx0XHQvLyBvdGhlcndpc2Ugd2Ugc2tpcCB0aGlzIHBhcnRcblx0XHRcdFx0XHRsZW5ndGggPSBnb3RvRW5kID8gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGggOiAwO1xuXHRcdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdFx0c3RvcHBlZCA9IHRydWU7XG5cdFx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVuc1sgaW5kZXggXS5ydW4oIDEgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFJlc29sdmUgd2hlbiB3ZSBwbGF5ZWQgdGhlIGxhc3QgZnJhbWU7IG90aGVyd2lzZSwgcmVqZWN0XG5cdFx0XHRcdGlmICggZ290b0VuZCApIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7XG5cdFx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBnb3RvRW5kIF0gKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9XG5cdFx0fSApLFxuXHRcdHByb3BzID0gYW5pbWF0aW9uLnByb3BzO1xuXG5cdHByb3BGaWx0ZXIoIHByb3BzLCBhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nICk7XG5cblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRyZXN1bHQgPSBBbmltYXRpb24ucHJlZmlsdGVyc1sgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIGVsZW0sIHByb3BzLCBhbmltYXRpb24ub3B0cyApO1xuXHRcdGlmICggcmVzdWx0ICkge1xuXHRcdFx0aWYgKCBpc0Z1bmN0aW9uKCByZXN1bHQuc3RvcCApICkge1xuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIGFuaW1hdGlvbi5lbGVtLCBhbmltYXRpb24ub3B0cy5xdWV1ZSApLnN0b3AgPVxuXHRcdFx0XHRcdHJlc3VsdC5zdG9wLmJpbmQoIHJlc3VsdCApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHR9XG5cdH1cblxuXHRqUXVlcnkubWFwKCBwcm9wcywgY3JlYXRlVHdlZW4sIGFuaW1hdGlvbiApO1xuXG5cdGlmICggaXNGdW5jdGlvbiggYW5pbWF0aW9uLm9wdHMuc3RhcnQgKSApIHtcblx0XHRhbmltYXRpb24ub3B0cy5zdGFydC5jYWxsKCBlbGVtLCBhbmltYXRpb24gKTtcblx0fVxuXG5cdC8vIEF0dGFjaCBjYWxsYmFja3MgZnJvbSBvcHRpb25zXG5cdGFuaW1hdGlvblxuXHRcdC5wcm9ncmVzcyggYW5pbWF0aW9uLm9wdHMucHJvZ3Jlc3MgKVxuXHRcdC5kb25lKCBhbmltYXRpb24ub3B0cy5kb25lLCBhbmltYXRpb24ub3B0cy5jb21wbGV0ZSApXG5cdFx0LmZhaWwoIGFuaW1hdGlvbi5vcHRzLmZhaWwgKVxuXHRcdC5hbHdheXMoIGFuaW1hdGlvbi5vcHRzLmFsd2F5cyApO1xuXG5cdGpRdWVyeS5meC50aW1lcihcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aWNrLCB7XG5cdFx0XHRlbGVtOiBlbGVtLFxuXHRcdFx0YW5pbTogYW5pbWF0aW9uLFxuXHRcdFx0cXVldWU6IGFuaW1hdGlvbi5vcHRzLnF1ZXVlXG5cdFx0fSApXG5cdCk7XG5cblx0cmV0dXJuIGFuaW1hdGlvbjtcbn1cblxualF1ZXJ5LkFuaW1hdGlvbiA9IGpRdWVyeS5leHRlbmQoIEFuaW1hdGlvbiwge1xuXG5cdHR3ZWVuZXJzOiB7XG5cdFx0XCIqXCI6IFsgZnVuY3Rpb24oIHByb3AsIHZhbHVlICkge1xuXHRcdFx0dmFyIHR3ZWVuID0gdGhpcy5jcmVhdGVUd2VlbiggcHJvcCwgdmFsdWUgKTtcblx0XHRcdGFkanVzdENTUyggdHdlZW4uZWxlbSwgcHJvcCwgcmNzc051bS5leGVjKCB2YWx1ZSApLCB0d2VlbiApO1xuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH0gXVxuXHR9LFxuXG5cdHR3ZWVuZXI6IGZ1bmN0aW9uKCBwcm9wcywgY2FsbGJhY2sgKSB7XG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBwcm9wcyApICkge1xuXHRcdFx0Y2FsbGJhY2sgPSBwcm9wcztcblx0XHRcdHByb3BzID0gWyBcIipcIiBdO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwcm9wcyA9IHByb3BzLm1hdGNoKCBybm90aHRtbHdoaXRlICk7XG5cdFx0fVxuXG5cdFx0dmFyIHByb3AsXG5cdFx0XHRpbmRleCA9IDAsXG5cdFx0XHRsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cblx0XHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdFx0cHJvcCA9IHByb3BzWyBpbmRleCBdO1xuXHRcdFx0QW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gPSBBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSB8fCBbXTtcblx0XHRcdEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9LFxuXG5cdHByZWZpbHRlcnM6IFsgZGVmYXVsdFByZWZpbHRlciBdLFxuXG5cdHByZWZpbHRlcjogZnVuY3Rpb24oIGNhbGxiYWNrLCBwcmVwZW5kICkge1xuXHRcdGlmICggcHJlcGVuZCApIHtcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnVuc2hpZnQoIGNhbGxiYWNrICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnB1c2goIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9XG59ICk7XG5cbmpRdWVyeS5zcGVlZCA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBmbiApIHtcblx0dmFyIG9wdCA9IHNwZWVkICYmIHR5cGVvZiBzcGVlZCA9PT0gXCJvYmplY3RcIiA/IGpRdWVyeS5leHRlbmQoIHt9LCBzcGVlZCApIDoge1xuXHRcdGNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8XG5cdFx0XHRpc0Z1bmN0aW9uKCBzcGVlZCApICYmIHNwZWVkLFxuXHRcdGR1cmF0aW9uOiBzcGVlZCxcblx0XHRlYXNpbmc6IGZuICYmIGVhc2luZyB8fCBlYXNpbmcgJiYgIWlzRnVuY3Rpb24oIGVhc2luZyApICYmIGVhc2luZ1xuXHR9O1xuXG5cdC8vIEdvIHRvIHRoZSBlbmQgc3RhdGUgaWYgZnggYXJlIG9mZlxuXHRpZiAoIGpRdWVyeS5meC5vZmYgKSB7XG5cdFx0b3B0LmR1cmF0aW9uID0gMDtcblxuXHR9IGVsc2Uge1xuXHRcdGlmICggdHlwZW9mIG9wdC5kdXJhdGlvbiAhPT0gXCJudW1iZXJcIiApIHtcblx0XHRcdGlmICggb3B0LmR1cmF0aW9uIGluIGpRdWVyeS5meC5zcGVlZHMgKSB7XG5cdFx0XHRcdG9wdC5kdXJhdGlvbiA9IGpRdWVyeS5meC5zcGVlZHNbIG9wdC5kdXJhdGlvbiBdO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRvcHQuZHVyYXRpb24gPSBqUXVlcnkuZnguc3BlZWRzLl9kZWZhdWx0O1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIE5vcm1hbGl6ZSBvcHQucXVldWUgLSB0cnVlL3VuZGVmaW5lZC9udWxsIC0+IFwiZnhcIlxuXHRpZiAoIG9wdC5xdWV1ZSA9PSBudWxsIHx8IG9wdC5xdWV1ZSA9PT0gdHJ1ZSApIHtcblx0XHRvcHQucXVldWUgPSBcImZ4XCI7XG5cdH1cblxuXHQvLyBRdWV1ZWluZ1xuXHRvcHQub2xkID0gb3B0LmNvbXBsZXRlO1xuXG5cdG9wdC5jb21wbGV0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggaXNGdW5jdGlvbiggb3B0Lm9sZCApICkge1xuXHRcdFx0b3B0Lm9sZC5jYWxsKCB0aGlzICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBvcHQucXVldWUgKSB7XG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgb3B0LnF1ZXVlICk7XG5cdFx0fVxuXHR9O1xuXG5cdHJldHVybiBvcHQ7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cdGZhZGVUbzogZnVuY3Rpb24oIHNwZWVkLCB0bywgZWFzaW5nLCBjYWxsYmFjayApIHtcblxuXHRcdC8vIFNob3cgYW55IGhpZGRlbiBlbGVtZW50cyBhZnRlciBzZXR0aW5nIG9wYWNpdHkgdG8gMFxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggaXNIaWRkZW5XaXRoaW5UcmVlICkuY3NzKCBcIm9wYWNpdHlcIiwgMCApLnNob3coKVxuXG5cdFx0XHQvLyBBbmltYXRlIHRvIHRoZSB2YWx1ZSBzcGVjaWZpZWRcblx0XHRcdC5lbmQoKS5hbmltYXRlKCB7IG9wYWNpdHk6IHRvIH0sIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XG5cdH0sXG5cdGFuaW1hdGU6IGZ1bmN0aW9uKCBwcm9wLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHR2YXIgZW1wdHkgPSBqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcCApLFxuXHRcdFx0b3B0YWxsID0galF1ZXJ5LnNwZWVkKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApLFxuXHRcdFx0ZG9BbmltYXRpb24gPSBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBPcGVyYXRlIG9uIGEgY29weSBvZiBwcm9wIHNvIHBlci1wcm9wZXJ0eSBlYXNpbmcgd29uJ3QgYmUgbG9zdFxuXHRcdFx0XHR2YXIgYW5pbSA9IEFuaW1hdGlvbiggdGhpcywgalF1ZXJ5LmV4dGVuZCgge30sIHByb3AgKSwgb3B0YWxsICk7XG5cblx0XHRcdFx0Ly8gRW1wdHkgYW5pbWF0aW9ucywgb3IgZmluaXNoaW5nIHJlc29sdmVzIGltbWVkaWF0ZWx5XG5cdFx0XHRcdGlmICggZW1wdHkgfHwgZGF0YVByaXYuZ2V0KCB0aGlzLCBcImZpbmlzaFwiICkgKSB7XG5cdFx0XHRcdFx0YW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0XHRkb0FuaW1hdGlvbi5maW5pc2ggPSBkb0FuaW1hdGlvbjtcblxuXHRcdHJldHVybiBlbXB0eSB8fCBvcHRhbGwucXVldWUgPT09IGZhbHNlID9cblx0XHRcdHRoaXMuZWFjaCggZG9BbmltYXRpb24gKSA6XG5cdFx0XHR0aGlzLnF1ZXVlKCBvcHRhbGwucXVldWUsIGRvQW5pbWF0aW9uICk7XG5cdH0sXG5cdHN0b3A6IGZ1bmN0aW9uKCB0eXBlLCBjbGVhclF1ZXVlLCBnb3RvRW5kICkge1xuXHRcdHZhciBzdG9wUXVldWUgPSBmdW5jdGlvbiggaG9va3MgKSB7XG5cdFx0XHR2YXIgc3RvcCA9IGhvb2tzLnN0b3A7XG5cdFx0XHRkZWxldGUgaG9va3Muc3RvcDtcblx0XHRcdHN0b3AoIGdvdG9FbmQgKTtcblx0XHR9O1xuXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdGdvdG9FbmQgPSBjbGVhclF1ZXVlO1xuXHRcdFx0Y2xlYXJRdWV1ZSA9IHR5cGU7XG5cdFx0XHR0eXBlID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoIGNsZWFyUXVldWUgKSB7XG5cdFx0XHR0aGlzLnF1ZXVlKCB0eXBlIHx8IFwiZnhcIiwgW10gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBkZXF1ZXVlID0gdHJ1ZSxcblx0XHRcdFx0aW5kZXggPSB0eXBlICE9IG51bGwgJiYgdHlwZSArIFwicXVldWVIb29rc1wiLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRkYXRhID0gZGF0YVByaXYuZ2V0KCB0aGlzICk7XG5cblx0XHRcdGlmICggaW5kZXggKSB7XG5cdFx0XHRcdGlmICggZGF0YVsgaW5kZXggXSAmJiBkYXRhWyBpbmRleCBdLnN0b3AgKSB7XG5cdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGZvciAoIGluZGV4IGluIGRhdGEgKSB7XG5cdFx0XHRcdFx0aWYgKCBkYXRhWyBpbmRleCBdICYmIGRhdGFbIGluZGV4IF0uc3RvcCAmJiBycnVuLnRlc3QoIGluZGV4ICkgKSB7XG5cdFx0XHRcdFx0XHRzdG9wUXVldWUoIGRhdGFbIGluZGV4IF0gKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Zm9yICggaW5kZXggPSB0aW1lcnMubGVuZ3RoOyBpbmRleC0tOyApIHtcblx0XHRcdFx0aWYgKCB0aW1lcnNbIGluZGV4IF0uZWxlbSA9PT0gdGhpcyAmJlxuXHRcdFx0XHRcdCggdHlwZSA9PSBudWxsIHx8IHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApICkge1xuXG5cdFx0XHRcdFx0dGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggZ290b0VuZCApO1xuXHRcdFx0XHRcdGRlcXVldWUgPSBmYWxzZTtcblx0XHRcdFx0XHR0aW1lcnMuc3BsaWNlKCBpbmRleCwgMSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXJ0IHRoZSBuZXh0IGluIHRoZSBxdWV1ZSBpZiB0aGUgbGFzdCBzdGVwIHdhc24ndCBmb3JjZWQuXG5cdFx0XHQvLyBUaW1lcnMgY3VycmVudGx5IHdpbGwgY2FsbCB0aGVpciBjb21wbGV0ZSBjYWxsYmFja3MsIHdoaWNoXG5cdFx0XHQvLyB3aWxsIGRlcXVldWUgYnV0IG9ubHkgaWYgdGhleSB3ZXJlIGdvdG9FbmQuXG5cdFx0XHRpZiAoIGRlcXVldWUgfHwgIWdvdG9FbmQgKSB7XG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXHRmaW5pc2g6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdGlmICggdHlwZSAhPT0gZmFsc2UgKSB7XG5cdFx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGluZGV4LFxuXHRcdFx0XHRkYXRhID0gZGF0YVByaXYuZ2V0KCB0aGlzICksXG5cdFx0XHRcdHF1ZXVlID0gZGF0YVsgdHlwZSArIFwicXVldWVcIiBdLFxuXHRcdFx0XHRob29rcyA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlSG9va3NcIiBdLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRsZW5ndGggPSBxdWV1ZSA/IHF1ZXVlLmxlbmd0aCA6IDA7XG5cblx0XHRcdC8vIEVuYWJsZSBmaW5pc2hpbmcgZmxhZyBvbiBwcml2YXRlIGRhdGFcblx0XHRcdGRhdGEuZmluaXNoID0gdHJ1ZTtcblxuXHRcdFx0Ly8gRW1wdHkgdGhlIHF1ZXVlIGZpcnN0XG5cdFx0XHRqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIFtdICk7XG5cblx0XHRcdGlmICggaG9va3MgJiYgaG9va3Muc3RvcCApIHtcblx0XHRcdFx0aG9va3Muc3RvcC5jYWxsKCB0aGlzLCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIExvb2sgZm9yIGFueSBhY3RpdmUgYW5pbWF0aW9ucywgYW5kIGZpbmlzaCB0aGVtXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xuXHRcdFx0XHRpZiAoIHRpbWVyc1sgaW5kZXggXS5lbGVtID09PSB0aGlzICYmIHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApIHtcblx0XHRcdFx0XHR0aW1lcnNbIGluZGV4IF0uYW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBMb29rIGZvciBhbnkgYW5pbWF0aW9ucyBpbiB0aGUgb2xkIHF1ZXVlIGFuZCBmaW5pc2ggdGhlbVxuXHRcdFx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0aWYgKCBxdWV1ZVsgaW5kZXggXSAmJiBxdWV1ZVsgaW5kZXggXS5maW5pc2ggKSB7XG5cdFx0XHRcdFx0cXVldWVbIGluZGV4IF0uZmluaXNoLmNhbGwoIHRoaXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBUdXJuIG9mZiBmaW5pc2hpbmcgZmxhZ1xuXHRcdFx0ZGVsZXRlIGRhdGEuZmluaXNoO1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCggWyBcInRvZ2dsZVwiLCBcInNob3dcIiwgXCJoaWRlXCIgXSwgZnVuY3Rpb24oIF9pLCBuYW1lICkge1xuXHR2YXIgY3NzRm4gPSBqUXVlcnkuZm5bIG5hbWUgXTtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0cmV0dXJuIHNwZWVkID09IG51bGwgfHwgdHlwZW9mIHNwZWVkID09PSBcImJvb2xlYW5cIiA/XG5cdFx0XHRjc3NGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICkgOlxuXHRcdFx0dGhpcy5hbmltYXRlKCBnZW5GeCggbmFtZSwgdHJ1ZSApLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSApO1xuXG4vLyBHZW5lcmF0ZSBzaG9ydGN1dHMgZm9yIGN1c3RvbSBhbmltYXRpb25zXG5qUXVlcnkuZWFjaCgge1xuXHRzbGlkZURvd246IGdlbkZ4KCBcInNob3dcIiApLFxuXHRzbGlkZVVwOiBnZW5GeCggXCJoaWRlXCIgKSxcblx0c2xpZGVUb2dnbGU6IGdlbkZ4KCBcInRvZ2dsZVwiICksXG5cdGZhZGVJbjogeyBvcGFjaXR5OiBcInNob3dcIiB9LFxuXHRmYWRlT3V0OiB7IG9wYWNpdHk6IFwiaGlkZVwiIH0sXG5cdGZhZGVUb2dnbGU6IHsgb3BhY2l0eTogXCJ0b2dnbGVcIiB9XG59LCBmdW5jdGlvbiggbmFtZSwgcHJvcHMgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLmFuaW1hdGUoIHByb3BzLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSApO1xuXG5qUXVlcnkudGltZXJzID0gW107XG5qUXVlcnkuZngudGljayA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgdGltZXIsXG5cdFx0aSA9IDAsXG5cdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycztcblxuXHRmeE5vdyA9IERhdGUubm93KCk7XG5cblx0Zm9yICggOyBpIDwgdGltZXJzLmxlbmd0aDsgaSsrICkge1xuXHRcdHRpbWVyID0gdGltZXJzWyBpIF07XG5cblx0XHQvLyBSdW4gdGhlIHRpbWVyIGFuZCBzYWZlbHkgcmVtb3ZlIGl0IHdoZW4gZG9uZSAoYWxsb3dpbmcgZm9yIGV4dGVybmFsIHJlbW92YWwpXG5cdFx0aWYgKCAhdGltZXIoKSAmJiB0aW1lcnNbIGkgXSA9PT0gdGltZXIgKSB7XG5cdFx0XHR0aW1lcnMuc3BsaWNlKCBpLS0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHRpZiAoICF0aW1lcnMubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5meC5zdG9wKCk7XG5cdH1cblx0ZnhOb3cgPSB1bmRlZmluZWQ7XG59O1xuXG5qUXVlcnkuZngudGltZXIgPSBmdW5jdGlvbiggdGltZXIgKSB7XG5cdGpRdWVyeS50aW1lcnMucHVzaCggdGltZXIgKTtcblx0alF1ZXJ5LmZ4LnN0YXJ0KCk7XG59O1xuXG5qUXVlcnkuZnguaW50ZXJ2YWwgPSAxMztcbmpRdWVyeS5meC5zdGFydCA9IGZ1bmN0aW9uKCkge1xuXHRpZiAoIGluUHJvZ3Jlc3MgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aW5Qcm9ncmVzcyA9IHRydWU7XG5cdHNjaGVkdWxlKCk7XG59O1xuXG5qUXVlcnkuZnguc3RvcCA9IGZ1bmN0aW9uKCkge1xuXHRpblByb2dyZXNzID0gbnVsbDtcbn07XG5cbmpRdWVyeS5meC5zcGVlZHMgPSB7XG5cdHNsb3c6IDYwMCxcblx0ZmFzdDogMjAwLFxuXG5cdC8vIERlZmF1bHQgc3BlZWRcblx0X2RlZmF1bHQ6IDQwMFxufTtcblxuXG4vLyBCYXNlZCBvZmYgb2YgdGhlIHBsdWdpbiBieSBDbGludCBIZWxmZXJzLCB3aXRoIHBlcm1pc3Npb24uXG4vLyBodHRwczovL3dlYi5hcmNoaXZlLm9yZy93ZWIvMjAxMDAzMjQwMTQ3NDcvaHR0cDovL2JsaW5kc2lnbmFscy5jb20vaW5kZXgucGhwLzIwMDkvMDcvanF1ZXJ5LWRlbGF5L1xualF1ZXJ5LmZuLmRlbGF5ID0gZnVuY3Rpb24oIHRpbWUsIHR5cGUgKSB7XG5cdHRpbWUgPSBqUXVlcnkuZnggPyBqUXVlcnkuZnguc3BlZWRzWyB0aW1lIF0gfHwgdGltZSA6IHRpbWU7XG5cdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcblxuXHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSwgZnVuY3Rpb24oIG5leHQsIGhvb2tzICkge1xuXHRcdHZhciB0aW1lb3V0ID0gd2luZG93LnNldFRpbWVvdXQoIG5leHQsIHRpbWUgKTtcblx0XHRob29rcy5zdG9wID0gZnVuY3Rpb24oKSB7XG5cdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7XG5cdFx0fTtcblx0fSApO1xufTtcblxuXG4oIGZ1bmN0aW9uKCkge1xuXHR2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKSxcblx0XHRzZWxlY3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInNlbGVjdFwiICksXG5cdFx0b3B0ID0gc2VsZWN0LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9wdGlvblwiICkgKTtcblxuXHRpbnB1dC50eXBlID0gXCJjaGVja2JveFwiO1xuXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQgPD00LjMgb25seVxuXHQvLyBEZWZhdWx0IHZhbHVlIGZvciBhIGNoZWNrYm94IHNob3VsZCBiZSBcIm9uXCJcblx0c3VwcG9ydC5jaGVja09uID0gaW5wdXQudmFsdWUgIT09IFwiXCI7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIE11c3QgYWNjZXNzIHNlbGVjdGVkSW5kZXggdG8gbWFrZSBkZWZhdWx0IG9wdGlvbnMgc2VsZWN0XG5cdHN1cHBvcnQub3B0U2VsZWN0ZWQgPSBvcHQuc2VsZWN0ZWQ7XG5cblx0Ly8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG5cdC8vIEFuIGlucHV0IGxvc2VzIGl0cyB2YWx1ZSBhZnRlciBiZWNvbWluZyBhIHJhZGlvXG5cdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cdGlucHV0LnZhbHVlID0gXCJ0XCI7XG5cdGlucHV0LnR5cGUgPSBcInJhZGlvXCI7XG5cdHN1cHBvcnQucmFkaW9WYWx1ZSA9IGlucHV0LnZhbHVlID09PSBcInRcIjtcbn0gKSgpO1xuXG5cbnZhciBib29sSG9vayxcblx0YXR0ckhhbmRsZSA9IGpRdWVyeS5leHByLmF0dHJIYW5kbGU7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0YXR0cjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGpRdWVyeS5hdHRyLCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblxuXHRyZW1vdmVBdHRyOiBmdW5jdGlvbiggbmFtZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCB0aGlzLCBuYW1lICk7XG5cdFx0fSApO1xuXHR9XG59ICk7XG5cbmpRdWVyeS5leHRlbmQoIHtcblx0YXR0cjogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xuXHRcdHZhciByZXQsIGhvb2tzLFxuXHRcdFx0blR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0Ly8gRG9uJ3QgZ2V0L3NldCBhdHRyaWJ1dGVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xuXHRcdGlmICggblR5cGUgPT09IDMgfHwgblR5cGUgPT09IDggfHwgblR5cGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gRmFsbGJhY2sgdG8gcHJvcCB3aGVuIGF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcblx0XHRpZiAoIHR5cGVvZiBlbGVtLmdldEF0dHJpYnV0ZSA9PT0gXCJ1bmRlZmluZWRcIiApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucHJvcCggZWxlbSwgbmFtZSwgdmFsdWUgKTtcblx0XHR9XG5cblx0XHQvLyBBdHRyaWJ1dGUgaG9va3MgYXJlIGRldGVybWluZWQgYnkgdGhlIGxvd2VyY2FzZSB2ZXJzaW9uXG5cdFx0Ly8gR3JhYiBuZWNlc3NhcnkgaG9vayBpZiBvbmUgaXMgZGVmaW5lZFxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXHRcdFx0aG9va3MgPSBqUXVlcnkuYXR0ckhvb2tzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHQoIGpRdWVyeS5leHByLm1hdGNoLmJvb2wudGVzdCggbmFtZSApID8gYm9vbEhvb2sgOiB1bmRlZmluZWQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRpZiAoIHZhbHVlID09PSBudWxsICkge1xuXHRcdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJlxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCB2YWx1ZSArIFwiXCIgKTtcblx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHR9XG5cblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKCByZXQgPSBob29rcy5nZXQoIGVsZW0sIG5hbWUgKSApICE9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9XG5cblx0XHRyZXQgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHQvLyBOb24tZXhpc3RlbnQgYXR0cmlidXRlcyByZXR1cm4gbnVsbCwgd2Ugbm9ybWFsaXplIHRvIHVuZGVmaW5lZFxuXHRcdHJldHVybiByZXQgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHJldDtcblx0fSxcblxuXHRhdHRySG9va3M6IHtcblx0XHR0eXBlOiB7XG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhc3VwcG9ydC5yYWRpb1ZhbHVlICYmIHZhbHVlID09PSBcInJhZGlvXCIgJiZcblx0XHRcdFx0XHRub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgKSB7XG5cdFx0XHRcdFx0dmFyIHZhbCA9IGVsZW0udmFsdWU7XG5cdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCB2YWx1ZSApO1xuXHRcdFx0XHRcdGlmICggdmFsICkge1xuXHRcdFx0XHRcdFx0ZWxlbS52YWx1ZSA9IHZhbDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHR2YXIgbmFtZSxcblx0XHRcdGkgPSAwLFxuXG5cdFx0XHQvLyBBdHRyaWJ1dGUgbmFtZXMgY2FuIGNvbnRhaW4gbm9uLUhUTUwgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzXG5cdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zeW50YXguaHRtbCNhdHRyaWJ1dGVzLTJcblx0XHRcdGF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICk7XG5cblx0XHRpZiAoIGF0dHJOYW1lcyAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0d2hpbGUgKCAoIG5hbWUgPSBhdHRyTmFtZXNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBuYW1lICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59ICk7XG5cbi8vIEhvb2tzIGZvciBib29sZWFuIGF0dHJpYnV0ZXNcbmJvb2xIb29rID0ge1xuXHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgbmFtZSApIHtcblx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblxuXHRcdFx0Ly8gUmVtb3ZlIGJvb2xlYW4gYXR0cmlidXRlcyB3aGVuIHNldCB0byBmYWxzZVxuXHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIGVsZW0sIG5hbWUgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIG5hbWU7XG5cdH1cbn07XG5cbmpRdWVyeS5lYWNoKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnNvdXJjZS5tYXRjaCggL1xcdysvZyApLCBmdW5jdGlvbiggX2ksIG5hbWUgKSB7XG5cdHZhciBnZXR0ZXIgPSBhdHRySGFuZGxlWyBuYW1lIF0gfHwgalF1ZXJ5LmZpbmQuYXR0cjtcblxuXHRhdHRySGFuZGxlWyBuYW1lIF0gPSBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0dmFyIHJldCwgaGFuZGxlLFxuXHRcdFx0bG93ZXJjYXNlTmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblxuXHRcdGlmICggIWlzWE1MICkge1xuXG5cdFx0XHQvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wIGJ5IHRlbXBvcmFyaWx5IHJlbW92aW5nIHRoaXMgZnVuY3Rpb24gZnJvbSB0aGUgZ2V0dGVyXG5cdFx0XHRoYW5kbGUgPSBhdHRySGFuZGxlWyBsb3dlcmNhc2VOYW1lIF07XG5cdFx0XHRhdHRySGFuZGxlWyBsb3dlcmNhc2VOYW1lIF0gPSByZXQ7XG5cdFx0XHRyZXQgPSBnZXR0ZXIoIGVsZW0sIG5hbWUsIGlzWE1MICkgIT0gbnVsbCA/XG5cdFx0XHRcdGxvd2VyY2FzZU5hbWUgOlxuXHRcdFx0XHRudWxsO1xuXHRcdFx0YXR0ckhhbmRsZVsgbG93ZXJjYXNlTmFtZSBdID0gaGFuZGxlO1xuXHRcdH1cblx0XHRyZXR1cm4gcmV0O1xuXHR9O1xufSApO1xuXG5cblxuXG52YXIgcmZvY3VzYWJsZSA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksXG5cdHJjbGlja2FibGUgPSAvXig/OmF8YXJlYSkkL2k7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0cHJvcDogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGpRdWVyeS5wcm9wLCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblxuXHRyZW1vdmVQcm9wOiBmdW5jdGlvbiggbmFtZSApIHtcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGRlbGV0ZSB0aGlzWyBqUXVlcnkucHJvcEZpeFsgbmFtZSBdIHx8IG5hbWUgXTtcblx0XHR9ICk7XG5cdH1cbn0gKTtcblxualF1ZXJ5LmV4dGVuZCgge1xuXHRwcm9wOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgdmFsdWUgKSB7XG5cdFx0dmFyIHJldCwgaG9va3MsXG5cdFx0XHRuVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0XHQvLyBEb24ndCBnZXQvc2V0IHByb3BlcnRpZXMgb24gdGV4dCwgY29tbWVudCBhbmQgYXR0cmlidXRlIG5vZGVzXG5cdFx0aWYgKCBuVHlwZSA9PT0gMyB8fCBuVHlwZSA9PT0gOCB8fCBuVHlwZSA9PT0gMiApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRpZiAoIG5UeXBlICE9PSAxIHx8ICFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHtcblxuXHRcdFx0Ly8gRml4IG5hbWUgYW5kIGF0dGFjaCBob29rc1xuXHRcdFx0bmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTtcblx0XHRcdGhvb2tzID0galF1ZXJ5LnByb3BIb29rc1sgbmFtZSBdO1xuXHRcdH1cblxuXHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGlmICggaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJlxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiAoIGVsZW1bIG5hbWUgXSA9IHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmICggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkgKSAhPT0gbnVsbCApIHtcblx0XHRcdHJldHVybiByZXQ7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGVsZW1bIG5hbWUgXTtcblx0fSxcblxuXHRwcm9wSG9va3M6IHtcblx0XHR0YWJJbmRleDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgLSAxMSBvbmx5XG5cdFx0XHRcdC8vIGVsZW0udGFiSW5kZXggZG9lc24ndCBhbHdheXMgcmV0dXJuIHRoZVxuXHRcdFx0XHQvLyBjb3JyZWN0IHZhbHVlIHdoZW4gaXQgaGFzbid0IGJlZW4gZXhwbGljaXRseSBzZXRcblx0XHRcdFx0Ly8gaHR0cHM6Ly93ZWIuYXJjaGl2ZS5vcmcvd2ViLzIwMTQxMTE2MjMzMzQ3L2h0dHA6Ly9mbHVpZHByb2plY3Qub3JnL2Jsb2cvMjAwOC8wMS8wOS9nZXR0aW5nLXNldHRpbmctYW5kLXJlbW92aW5nLXRhYmluZGV4LXZhbHVlcy13aXRoLWphdmFzY3JpcHQvXG5cdFx0XHRcdC8vIFVzZSBwcm9wZXIgYXR0cmlidXRlIHJldHJpZXZhbCgjMTIwNzIpXG5cdFx0XHRcdHZhciB0YWJpbmRleCA9IGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIFwidGFiaW5kZXhcIiApO1xuXG5cdFx0XHRcdGlmICggdGFiaW5kZXggKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHBhcnNlSW50KCB0YWJpbmRleCwgMTAgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmIChcblx0XHRcdFx0XHRyZm9jdXNhYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSB8fFxuXHRcdFx0XHRcdHJjbGlja2FibGUudGVzdCggZWxlbS5ub2RlTmFtZSApICYmXG5cdFx0XHRcdFx0ZWxlbS5ocmVmXG5cdFx0XHRcdCkge1xuXHRcdFx0XHRcdHJldHVybiAwO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIC0xO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRwcm9wRml4OiB7XG5cdFx0XCJmb3JcIjogXCJodG1sRm9yXCIsXG5cdFx0XCJjbGFzc1wiOiBcImNsYXNzTmFtZVwiXG5cdH1cbn0gKTtcblxuLy8gU3VwcG9ydDogSUUgPD0xMSBvbmx5XG4vLyBBY2Nlc3NpbmcgdGhlIHNlbGVjdGVkSW5kZXggcHJvcGVydHlcbi8vIGZvcmNlcyB0aGUgYnJvd3NlciB0byByZXNwZWN0IHNldHRpbmcgc2VsZWN0ZWRcbi8vIG9uIHRoZSBvcHRpb25cbi8vIFRoZSBnZXR0ZXIgZW5zdXJlcyBhIGRlZmF1bHQgb3B0aW9uIGlzIHNlbGVjdGVkXG4vLyB3aGVuIGluIGFuIG9wdGdyb3VwXG4vLyBlc2xpbnQgcnVsZSBcIm5vLXVudXNlZC1leHByZXNzaW9uc1wiIGlzIGRpc2FibGVkIGZvciB0aGlzIGNvZGVcbi8vIHNpbmNlIGl0IGNvbnNpZGVycyBzdWNoIGFjY2Vzc2lvbnMgbm9vcFxuaWYgKCAhc3VwcG9ydC5vcHRTZWxlY3RlZCApIHtcblx0alF1ZXJ5LnByb3BIb29rcy5zZWxlY3RlZCA9IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHQvKiBlc2xpbnQgbm8tdW51c2VkLWV4cHJlc3Npb25zOiBcIm9mZlwiICovXG5cblx0XHRcdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XG5cdFx0XHRpZiAoIHBhcmVudCAmJiBwYXJlbnQucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdH1cblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdFx0LyogZXNsaW50IG5vLXVudXNlZC1leHByZXNzaW9uczogXCJvZmZcIiAqL1xuXG5cdFx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xuXHRcdFx0aWYgKCBwYXJlbnQgKSB7XG5cdFx0XHRcdHBhcmVudC5zZWxlY3RlZEluZGV4O1xuXG5cdFx0XHRcdGlmICggcGFyZW50LnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fTtcbn1cblxualF1ZXJ5LmVhY2goIFtcblx0XCJ0YWJJbmRleFwiLFxuXHRcInJlYWRPbmx5XCIsXG5cdFwibWF4TGVuZ3RoXCIsXG5cdFwiY2VsbFNwYWNpbmdcIixcblx0XCJjZWxsUGFkZGluZ1wiLFxuXHRcInJvd1NwYW5cIixcblx0XCJjb2xTcGFuXCIsXG5cdFwidXNlTWFwXCIsXG5cdFwiZnJhbWVCb3JkZXJcIixcblx0XCJjb250ZW50RWRpdGFibGVcIlxuXSwgZnVuY3Rpb24oKSB7XG5cdGpRdWVyeS5wcm9wRml4WyB0aGlzLnRvTG93ZXJDYXNlKCkgXSA9IHRoaXM7XG59ICk7XG5cblxuXG5cblx0Ly8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2UgYWNjb3JkaW5nIHRvIEhUTUwgc3BlY1xuXHQvLyBodHRwczovL2luZnJhLnNwZWMud2hhdHdnLm9yZy8jc3RyaXAtYW5kLWNvbGxhcHNlLWFzY2lpLXdoaXRlc3BhY2Vcblx0ZnVuY3Rpb24gc3RyaXBBbmRDb2xsYXBzZSggdmFsdWUgKSB7XG5cdFx0dmFyIHRva2VucyA9IHZhbHVlLm1hdGNoKCBybm90aHRtbHdoaXRlICkgfHwgW107XG5cdFx0cmV0dXJuIHRva2Vucy5qb2luKCBcIiBcIiApO1xuXHR9XG5cblxuZnVuY3Rpb24gZ2V0Q2xhc3MoIGVsZW0gKSB7XG5cdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSAmJiBlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHwgXCJcIjtcbn1cblxuZnVuY3Rpb24gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICkge1xuXHRpZiAoIEFycmF5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0cmV0dXJuIHZhbHVlO1xuXHR9XG5cdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiB2YWx1ZS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFtdO1xuXHR9XG5cdHJldHVybiBbXTtcbn1cblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRhZGRDbGFzczogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBjbGFzc2VzLCBlbGVtLCBjdXIsIGN1clZhbHVlLCBjbGF6eiwgaiwgZmluYWxWYWx1ZSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGogKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmFkZENsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCBnZXRDbGFzcyggdGhpcyApICkgKTtcblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRjbGFzc2VzID0gY2xhc3Nlc1RvQXJyYXkoIHZhbHVlICk7XG5cblx0XHRpZiAoIGNsYXNzZXMubGVuZ3RoICkge1xuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xuXHRcdFx0XHRjdXJWYWx1ZSA9IGdldENsYXNzKCBlbGVtICk7XG5cdFx0XHRcdGN1ciA9IGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBcIiBcIiArIHN0cmlwQW5kQ29sbGFwc2UoIGN1clZhbHVlICkgKyBcIiBcIiApO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA8IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1ciArPSBjbGF6eiArIFwiIFwiO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoIGN1ciApO1xuXHRcdFx0XHRcdGlmICggY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLCBmaW5hbFZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0cmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjdXJWYWx1ZSwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRpID0gMDtcblxuXHRcdGlmICggaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBqICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5yZW1vdmVDbGFzcyggdmFsdWUuY2FsbCggdGhpcywgaiwgZ2V0Q2xhc3MoIHRoaXMgKSApICk7XG5cdFx0XHR9ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCAhYXJndW1lbnRzLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiB0aGlzLmF0dHIoIFwiY2xhc3NcIiwgXCJcIiApO1xuXHRcdH1cblxuXHRcdGNsYXNzZXMgPSBjbGFzc2VzVG9BcnJheSggdmFsdWUgKTtcblxuXHRcdGlmICggY2xhc3Nlcy5sZW5ndGggKSB7XG5cdFx0XHR3aGlsZSAoICggZWxlbSA9IHRoaXNbIGkrKyBdICkgKSB7XG5cdFx0XHRcdGN1clZhbHVlID0gZ2V0Q2xhc3MoIGVsZW0gKTtcblxuXHRcdFx0XHQvLyBUaGlzIGV4cHJlc3Npb24gaXMgaGVyZSBmb3IgYmV0dGVyIGNvbXByZXNzaWJpbGl0eSAoc2VlIGFkZENsYXNzKVxuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggXCIgXCIgKyBzdHJpcEFuZENvbGxhcHNlKCBjdXJWYWx1ZSApICsgXCIgXCIgKTtcblxuXHRcdFx0XHRpZiAoIGN1ciApIHtcblx0XHRcdFx0XHRqID0gMDtcblx0XHRcdFx0XHR3aGlsZSAoICggY2xhenogPSBjbGFzc2VzWyBqKysgXSApICkge1xuXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgKmFsbCogaW5zdGFuY2VzXG5cdFx0XHRcdFx0XHR3aGlsZSAoIGN1ci5pbmRleE9mKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIgKSA+IC0xICkge1xuXHRcdFx0XHRcdFx0XHRjdXIgPSBjdXIucmVwbGFjZSggXCIgXCIgKyBjbGF6eiArIFwiIFwiLCBcIiBcIiApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXG5cdFx0XHRcdFx0ZmluYWxWYWx1ZSA9IHN0cmlwQW5kQ29sbGFwc2UoIGN1ciApO1xuXHRcdFx0XHRcdGlmICggY3VyVmFsdWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLCBmaW5hbFZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0dG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSwgc3RhdGVWYWwgKSB7XG5cdFx0dmFyIHR5cGUgPSB0eXBlb2YgdmFsdWUsXG5cdFx0XHRpc1ZhbGlkVmFsdWUgPSB0eXBlID09PSBcInN0cmluZ1wiIHx8IEFycmF5LmlzQXJyYXkoIHZhbHVlICk7XG5cblx0XHRpZiAoIHR5cGVvZiBzdGF0ZVZhbCA9PT0gXCJib29sZWFuXCIgJiYgaXNWYWxpZFZhbHVlICkge1xuXHRcdFx0cmV0dXJuIHN0YXRlVmFsID8gdGhpcy5hZGRDbGFzcyggdmFsdWUgKSA6IHRoaXMucmVtb3ZlQ2xhc3MoIHZhbHVlICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnRvZ2dsZUNsYXNzKFxuXHRcdFx0XHRcdHZhbHVlLmNhbGwoIHRoaXMsIGksIGdldENsYXNzKCB0aGlzICksIHN0YXRlVmFsICksXG5cdFx0XHRcdFx0c3RhdGVWYWxcblx0XHRcdFx0KTtcblx0XHRcdH0gKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBjbGFzc05hbWUsIGksIHNlbGYsIGNsYXNzTmFtZXM7XG5cblx0XHRcdGlmICggaXNWYWxpZFZhbHVlICkge1xuXG5cdFx0XHRcdC8vIFRvZ2dsZSBpbmRpdmlkdWFsIGNsYXNzIG5hbWVzXG5cdFx0XHRcdGkgPSAwO1xuXHRcdFx0XHRzZWxmID0galF1ZXJ5KCB0aGlzICk7XG5cdFx0XHRcdGNsYXNzTmFtZXMgPSBjbGFzc2VzVG9BcnJheSggdmFsdWUgKTtcblxuXHRcdFx0XHR3aGlsZSAoICggY2xhc3NOYW1lID0gY2xhc3NOYW1lc1sgaSsrIF0gKSApIHtcblxuXHRcdFx0XHRcdC8vIENoZWNrIGVhY2ggY2xhc3NOYW1lIGdpdmVuLCBzcGFjZSBzZXBhcmF0ZWQgbGlzdFxuXHRcdFx0XHRcdGlmICggc2VsZi5oYXNDbGFzcyggY2xhc3NOYW1lICkgKSB7XG5cdFx0XHRcdFx0XHRzZWxmLnJlbW92ZUNsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c2VsZi5hZGRDbGFzcyggY2xhc3NOYW1lICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdC8vIFRvZ2dsZSB3aG9sZSBjbGFzcyBuYW1lXG5cdFx0XHR9IGVsc2UgaWYgKCB2YWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHR5cGUgPT09IFwiYm9vbGVhblwiICkge1xuXHRcdFx0XHRjbGFzc05hbWUgPSBnZXRDbGFzcyggdGhpcyApO1xuXHRcdFx0XHRpZiAoIGNsYXNzTmFtZSApIHtcblxuXHRcdFx0XHRcdC8vIFN0b3JlIGNsYXNzTmFtZSBpZiBzZXRcblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiLCBjbGFzc05hbWUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIElmIHRoZSBlbGVtZW50IGhhcyBhIGNsYXNzIG5hbWUgb3IgaWYgd2UncmUgcGFzc2VkIGBmYWxzZWAsXG5cdFx0XHRcdC8vIHRoZW4gcmVtb3ZlIHRoZSB3aG9sZSBjbGFzc25hbWUgKGlmIHRoZXJlIHdhcyBvbmUsIHRoZSBhYm92ZSBzYXZlZCBpdCkuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBicmluZyBiYWNrIHdoYXRldmVyIHdhcyBwcmV2aW91c2x5IHNhdmVkIChpZiBhbnl0aGluZyksXG5cdFx0XHRcdC8vIGZhbGxpbmcgYmFjayB0byB0aGUgZW1wdHkgc3RyaW5nIGlmIG5vdGhpbmcgd2FzIHN0b3JlZC5cblx0XHRcdFx0aWYgKCB0aGlzLnNldEF0dHJpYnV0ZSApIHtcblx0XHRcdFx0XHR0aGlzLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lIHx8IHZhbHVlID09PSBmYWxzZSA/XG5cdFx0XHRcdFx0XHRcIlwiIDpcblx0XHRcdFx0XHRcdGRhdGFQcml2LmdldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIgKSB8fCBcIlwiXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0gKTtcblx0fSxcblxuXHRoYXNDbGFzczogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBjbGFzc05hbWUsIGVsZW0sXG5cdFx0XHRpID0gMDtcblxuXHRcdGNsYXNzTmFtZSA9IFwiIFwiICsgc2VsZWN0b3IgKyBcIiBcIjtcblx0XHR3aGlsZSAoICggZWxlbSA9IHRoaXNbIGkrKyBdICkgKSB7XG5cdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0KCBcIiBcIiArIHN0cmlwQW5kQ29sbGFwc2UoIGdldENsYXNzKCBlbGVtICkgKSArIFwiIFwiICkuaW5kZXhPZiggY2xhc3NOYW1lICkgPiAtMSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0gKTtcblxuXG5cblxudmFyIHJyZXR1cm4gPSAvXFxyL2c7XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0dmFsOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGhvb2tzLCByZXQsIHZhbHVlSXNGdW5jdGlvbixcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XG5cblx0XHRpZiAoICFhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgZWxlbS50eXBlIF0gfHxcblx0XHRcdFx0XHRqUXVlcnkudmFsSG9va3NbIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHRcdGlmICggaG9va3MgJiZcblx0XHRcdFx0XHRcImdldFwiIGluIGhvb2tzICYmXG5cdFx0XHRcdFx0KCByZXQgPSBob29rcy5nZXQoIGVsZW0sIFwidmFsdWVcIiApICkgIT09IHVuZGVmaW5lZFxuXHRcdFx0XHQpIHtcblx0XHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0ID0gZWxlbS52YWx1ZTtcblxuXHRcdFx0XHQvLyBIYW5kbGUgbW9zdCBjb21tb24gc3RyaW5nIGNhc2VzXG5cdFx0XHRcdGlmICggdHlwZW9mIHJldCA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0XHRyZXR1cm4gcmV0LnJlcGxhY2UoIHJyZXR1cm4sIFwiXCIgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEhhbmRsZSBjYXNlcyB3aGVyZSB2YWx1ZSBpcyBudWxsL3VuZGVmIG9yIG51bWJlclxuXHRcdFx0XHRyZXR1cm4gcmV0ID09IG51bGwgPyBcIlwiIDogcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFsdWVJc0Z1bmN0aW9uID0gaXNGdW5jdGlvbiggdmFsdWUgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0dmFyIHZhbDtcblxuXHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlICE9PSAxICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggdmFsdWVJc0Z1bmN0aW9uICkge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZS5jYWxsKCB0aGlzLCBpLCBqUXVlcnkoIHRoaXMgKS52YWwoKSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0dmFsID0gdmFsdWU7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRyZWF0IG51bGwvdW5kZWZpbmVkIGFzIFwiXCI7IGNvbnZlcnQgbnVtYmVycyB0byBzdHJpbmdcblx0XHRcdGlmICggdmFsID09IG51bGwgKSB7XG5cdFx0XHRcdHZhbCA9IFwiXCI7XG5cblx0XHRcdH0gZWxzZSBpZiAoIHR5cGVvZiB2YWwgPT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRcdHZhbCArPSBcIlwiO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBBcnJheS5pc0FycmF5KCB2YWwgKSApIHtcblx0XHRcdFx0dmFsID0galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlID09IG51bGwgPyBcIlwiIDogdmFsdWUgKyBcIlwiO1xuXHRcdFx0XHR9ICk7XG5cdFx0XHR9XG5cblx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyB0aGlzLnR5cGUgXSB8fCBqUXVlcnkudmFsSG9va3NbIHRoaXMubm9kZU5hbWUudG9Mb3dlckNhc2UoKSBdO1xuXG5cdFx0XHQvLyBJZiBzZXQgcmV0dXJucyB1bmRlZmluZWQsIGZhbGwgYmFjayB0byBub3JtYWwgc2V0dGluZ1xuXHRcdFx0aWYgKCAhaG9va3MgfHwgISggXCJzZXRcIiBpbiBob29rcyApIHx8IGhvb2tzLnNldCggdGhpcywgdmFsLCBcInZhbHVlXCIgKSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHR0aGlzLnZhbHVlID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0gKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cdHZhbEhvb2tzOiB7XG5cdFx0b3B0aW9uOiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xuXG5cdFx0XHRcdHZhciB2YWwgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInZhbHVlXCIgKTtcblx0XHRcdFx0cmV0dXJuIHZhbCAhPSBudWxsID9cblx0XHRcdFx0XHR2YWwgOlxuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD0xMCAtIDExIG9ubHlcblx0XHRcdFx0XHQvLyBvcHRpb24udGV4dCB0aHJvd3MgZXhjZXB0aW9ucyAoIzE0Njg2LCAjMTQ4NTgpXG5cdFx0XHRcdFx0Ly8gU3RyaXAgYW5kIGNvbGxhcHNlIHdoaXRlc3BhY2Vcblx0XHRcdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNzdHJpcC1hbmQtY29sbGFwc2Utd2hpdGVzcGFjZVxuXHRcdFx0XHRcdHN0cmlwQW5kQ29sbGFwc2UoIGpRdWVyeS50ZXh0KCBlbGVtICkgKTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdHNlbGVjdDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHZhbHVlLCBvcHRpb24sIGksXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHRpbmRleCA9IGVsZW0uc2VsZWN0ZWRJbmRleCxcblx0XHRcdFx0XHRvbmUgPSBlbGVtLnR5cGUgPT09IFwic2VsZWN0LW9uZVwiLFxuXHRcdFx0XHRcdHZhbHVlcyA9IG9uZSA/IG51bGwgOiBbXSxcblx0XHRcdFx0XHRtYXggPSBvbmUgPyBpbmRleCArIDEgOiBvcHRpb25zLmxlbmd0aDtcblxuXHRcdFx0XHRpZiAoIGluZGV4IDwgMCApIHtcblx0XHRcdFx0XHRpID0gbWF4O1xuXG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0aSA9IG9uZSA/IGluZGV4IDogMDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIExvb3AgdGhyb3VnaCBhbGwgdGhlIHNlbGVjdGVkIG9wdGlvbnNcblx0XHRcdFx0Zm9yICggOyBpIDwgbWF4OyBpKysgKSB7XG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xuXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD05IG9ubHlcblx0XHRcdFx0XHQvLyBJRTgtOSBkb2Vzbid0IHVwZGF0ZSBzZWxlY3RlZCBhZnRlciBmb3JtIHJlc2V0ICgjMjU1MSlcblx0XHRcdFx0XHRpZiAoICggb3B0aW9uLnNlbGVjdGVkIHx8IGkgPT09IGluZGV4ICkgJiZcblxuXHRcdFx0XHRcdFx0XHQvLyBEb24ndCByZXR1cm4gb3B0aW9ucyB0aGF0IGFyZSBkaXNhYmxlZCBvciBpbiBhIGRpc2FibGVkIG9wdGdyb3VwXG5cdFx0XHRcdFx0XHRcdCFvcHRpb24uZGlzYWJsZWQgJiZcblx0XHRcdFx0XHRcdFx0KCAhb3B0aW9uLnBhcmVudE5vZGUuZGlzYWJsZWQgfHxcblx0XHRcdFx0XHRcdFx0XHQhbm9kZU5hbWUoIG9wdGlvbi5wYXJlbnROb2RlLCBcIm9wdGdyb3VwXCIgKSApICkge1xuXG5cdFx0XHRcdFx0XHQvLyBHZXQgdGhlIHNwZWNpZmljIHZhbHVlIGZvciB0aGUgb3B0aW9uXG5cdFx0XHRcdFx0XHR2YWx1ZSA9IGpRdWVyeSggb3B0aW9uICkudmFsKCk7XG5cblx0XHRcdFx0XHRcdC8vIFdlIGRvbid0IG5lZWQgYW4gYXJyYXkgZm9yIG9uZSBzZWxlY3RzXG5cdFx0XHRcdFx0XHRpZiAoIG9uZSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBNdWx0aS1TZWxlY3RzIHJldHVybiBhbiBhcnJheVxuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH0sXG5cblx0XHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgb3B0aW9uU2V0LCBvcHRpb24sXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcblx0XHRcdFx0XHR2YWx1ZXMgPSBqUXVlcnkubWFrZUFycmF5KCB2YWx1ZSApLFxuXHRcdFx0XHRcdGkgPSBvcHRpb25zLmxlbmd0aDtcblxuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRvcHRpb24gPSBvcHRpb25zWyBpIF07XG5cblx0XHRcdFx0XHQvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25kLWFzc2lnbiAqL1xuXG5cdFx0XHRcdFx0aWYgKCBvcHRpb24uc2VsZWN0ZWQgPVxuXHRcdFx0XHRcdFx0alF1ZXJ5LmluQXJyYXkoIGpRdWVyeS52YWxIb29rcy5vcHRpb24uZ2V0KCBvcHRpb24gKSwgdmFsdWVzICkgPiAtMVxuXHRcdFx0XHRcdCkge1xuXHRcdFx0XHRcdFx0b3B0aW9uU2V0ID0gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvKiBlc2xpbnQtZW5hYmxlIG5vLWNvbmQtYXNzaWduICovXG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBGb3JjZSBicm93c2VycyB0byBiZWhhdmUgY29uc2lzdGVudGx5IHdoZW4gbm9uLW1hdGNoaW5nIHZhbHVlIGlzIHNldFxuXHRcdFx0XHRpZiAoICFvcHRpb25TZXQgKSB7XG5cdFx0XHRcdFx0ZWxlbS5zZWxlY3RlZEluZGV4ID0gLTE7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHZhbHVlcztcblx0XHRcdH1cblx0XHR9XG5cdH1cbn0gKTtcblxuLy8gUmFkaW9zIGFuZCBjaGVja2JveGVzIGdldHRlci9zZXR0ZXJcbmpRdWVyeS5lYWNoKCBbIFwicmFkaW9cIiwgXCJjaGVja2JveFwiIF0sIGZ1bmN0aW9uKCkge1xuXHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXSA9IHtcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSggdmFsdWUgKSApIHtcblx0XHRcdFx0cmV0dXJuICggZWxlbS5jaGVja2VkID0galF1ZXJ5LmluQXJyYXkoIGpRdWVyeSggZWxlbSApLnZhbCgpLCB2YWx1ZSApID4gLTEgKTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cdGlmICggIXN1cHBvcnQuY2hlY2tPbiApIHtcblx0XHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXS5nZXQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IG51bGwgPyBcIm9uXCIgOiBlbGVtLnZhbHVlO1xuXHRcdH07XG5cdH1cbn0gKTtcblxuXG5cblxuLy8gUmV0dXJuIGpRdWVyeSBmb3IgYXR0cmlidXRlcy1vbmx5IGluY2x1c2lvblxuXG5cbnN1cHBvcnQuZm9jdXNpbiA9IFwib25mb2N1c2luXCIgaW4gd2luZG93O1xuXG5cbnZhciByZm9jdXNNb3JwaCA9IC9eKD86Zm9jdXNpbmZvY3VzfGZvY3Vzb3V0Ymx1cikkLyxcblx0c3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgPSBmdW5jdGlvbiggZSApIHtcblx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHR9O1xuXG5qUXVlcnkuZXh0ZW5kKCBqUXVlcnkuZXZlbnQsIHtcblxuXHR0cmlnZ2VyOiBmdW5jdGlvbiggZXZlbnQsIGRhdGEsIGVsZW0sIG9ubHlIYW5kbGVycyApIHtcblxuXHRcdHZhciBpLCBjdXIsIHRtcCwgYnViYmxlVHlwZSwgb250eXBlLCBoYW5kbGUsIHNwZWNpYWwsIGxhc3RFbGVtZW50LFxuXHRcdFx0ZXZlbnRQYXRoID0gWyBlbGVtIHx8IGRvY3VtZW50IF0sXG5cdFx0XHR0eXBlID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcInR5cGVcIiApID8gZXZlbnQudHlwZSA6IGV2ZW50LFxuXHRcdFx0bmFtZXNwYWNlcyA9IGhhc093bi5jYWxsKCBldmVudCwgXCJuYW1lc3BhY2VcIiApID8gZXZlbnQubmFtZXNwYWNlLnNwbGl0KCBcIi5cIiApIDogW107XG5cblx0XHRjdXIgPSBsYXN0RWxlbWVudCA9IHRtcCA9IGVsZW0gPSBlbGVtIHx8IGRvY3VtZW50O1xuXG5cdFx0Ly8gRG9uJ3QgZG8gZXZlbnRzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBmb2N1cy9ibHVyIG1vcnBocyB0byBmb2N1c2luL291dDsgZW5zdXJlIHdlJ3JlIG5vdCBmaXJpbmcgdGhlbSByaWdodCBub3dcblx0XHRpZiAoIHJmb2N1c01vcnBoLnRlc3QoIHR5cGUgKyBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICkgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKCB0eXBlLmluZGV4T2YoIFwiLlwiICkgPiAtMSApIHtcblxuXHRcdFx0Ly8gTmFtZXNwYWNlZCB0cmlnZ2VyOyBjcmVhdGUgYSByZWdleHAgdG8gbWF0Y2ggZXZlbnQgdHlwZSBpbiBoYW5kbGUoKVxuXHRcdFx0bmFtZXNwYWNlcyA9IHR5cGUuc3BsaXQoIFwiLlwiICk7XG5cdFx0XHR0eXBlID0gbmFtZXNwYWNlcy5zaGlmdCgpO1xuXHRcdFx0bmFtZXNwYWNlcy5zb3J0KCk7XG5cdFx0fVxuXHRcdG9udHlwZSA9IHR5cGUuaW5kZXhPZiggXCI6XCIgKSA8IDAgJiYgXCJvblwiICsgdHlwZTtcblxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhIGpRdWVyeS5FdmVudCBvYmplY3QsIE9iamVjdCwgb3IganVzdCBhbiBldmVudCB0eXBlIHN0cmluZ1xuXHRcdGV2ZW50ID0gZXZlbnRbIGpRdWVyeS5leHBhbmRvIF0gP1xuXHRcdFx0ZXZlbnQgOlxuXHRcdFx0bmV3IGpRdWVyeS5FdmVudCggdHlwZSwgdHlwZW9mIGV2ZW50ID09PSBcIm9iamVjdFwiICYmIGV2ZW50ICk7XG5cblx0XHQvLyBUcmlnZ2VyIGJpdG1hc2s6ICYgMSBmb3IgbmF0aXZlIGhhbmRsZXJzOyAmIDIgZm9yIGpRdWVyeSAoYWx3YXlzIHRydWUpXG5cdFx0ZXZlbnQuaXNUcmlnZ2VyID0gb25seUhhbmRsZXJzID8gMiA6IDM7XG5cdFx0ZXZlbnQubmFtZXNwYWNlID0gbmFtZXNwYWNlcy5qb2luKCBcIi5cIiApO1xuXHRcdGV2ZW50LnJuYW1lc3BhY2UgPSBldmVudC5uYW1lc3BhY2UgP1xuXHRcdFx0bmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbiggXCJcXFxcLig/Oi4qXFxcXC58KVwiICkgKyBcIihcXFxcLnwkKVwiICkgOlxuXHRcdFx0bnVsbDtcblxuXHRcdC8vIENsZWFuIHVwIHRoZSBldmVudCBpbiBjYXNlIGl0IGlzIGJlaW5nIHJldXNlZFxuXHRcdGV2ZW50LnJlc3VsdCA9IHVuZGVmaW5lZDtcblx0XHRpZiAoICFldmVudC50YXJnZXQgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBlbGVtO1xuXHRcdH1cblxuXHRcdC8vIENsb25lIGFueSBpbmNvbWluZyBkYXRhIGFuZCBwcmVwZW5kIHRoZSBldmVudCwgY3JlYXRpbmcgdGhlIGhhbmRsZXIgYXJnIGxpc3Rcblx0XHRkYXRhID0gZGF0YSA9PSBudWxsID9cblx0XHRcdFsgZXZlbnQgXSA6XG5cdFx0XHRqUXVlcnkubWFrZUFycmF5KCBkYXRhLCBbIGV2ZW50IF0gKTtcblxuXHRcdC8vIEFsbG93IHNwZWNpYWwgZXZlbnRzIHRvIGRyYXcgb3V0c2lkZSB0aGUgbGluZXNcblx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgc3BlY2lhbC50cmlnZ2VyICYmIHNwZWNpYWwudHJpZ2dlci5hcHBseSggZWxlbSwgZGF0YSApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgZXZlbnQgcHJvcGFnYXRpb24gcGF0aCBpbiBhZHZhbmNlLCBwZXIgVzNDIGV2ZW50cyBzcGVjICgjOTk1MSlcblx0XHQvLyBCdWJibGUgdXAgdG8gZG9jdW1lbnQsIHRoZW4gdG8gd2luZG93OyB3YXRjaCBmb3IgYSBnbG9iYWwgb3duZXJEb2N1bWVudCB2YXIgKCM5NzI0KVxuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhc3BlY2lhbC5ub0J1YmJsZSAmJiAhaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0YnViYmxlVHlwZSA9IHNwZWNpYWwuZGVsZWdhdGVUeXBlIHx8IHR5cGU7XG5cdFx0XHRpZiAoICFyZm9jdXNNb3JwaC50ZXN0KCBidWJibGVUeXBlICsgdHlwZSApICkge1xuXHRcdFx0XHRjdXIgPSBjdXIucGFyZW50Tm9kZTtcblx0XHRcdH1cblx0XHRcdGZvciAoIDsgY3VyOyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIGN1ciApO1xuXHRcdFx0XHR0bXAgPSBjdXI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE9ubHkgYWRkIHdpbmRvdyBpZiB3ZSBnb3QgdG8gZG9jdW1lbnQgKGUuZy4sIG5vdCBwbGFpbiBvYmogb3IgZGV0YWNoZWQgRE9NKVxuXHRcdFx0aWYgKCB0bXAgPT09ICggZWxlbS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50ICkgKSB7XG5cdFx0XHRcdGV2ZW50UGF0aC5wdXNoKCB0bXAuZGVmYXVsdFZpZXcgfHwgdG1wLnBhcmVudFdpbmRvdyB8fCB3aW5kb3cgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBGaXJlIGhhbmRsZXJzIG9uIHRoZSBldmVudCBwYXRoXG5cdFx0aSA9IDA7XG5cdFx0d2hpbGUgKCAoIGN1ciA9IGV2ZW50UGF0aFsgaSsrIF0gKSAmJiAhZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblx0XHRcdGxhc3RFbGVtZW50ID0gY3VyO1xuXHRcdFx0ZXZlbnQudHlwZSA9IGkgPiAxID9cblx0XHRcdFx0YnViYmxlVHlwZSA6XG5cdFx0XHRcdHNwZWNpYWwuYmluZFR5cGUgfHwgdHlwZTtcblxuXHRcdFx0Ly8galF1ZXJ5IGhhbmRsZXJcblx0XHRcdGhhbmRsZSA9IChcblx0XHRcdFx0XHRkYXRhUHJpdi5nZXQoIGN1ciwgXCJldmVudHNcIiApIHx8IE9iamVjdC5jcmVhdGUoIG51bGwgKVxuXHRcdFx0XHQpWyBldmVudC50eXBlIF0gJiZcblx0XHRcdFx0ZGF0YVByaXYuZ2V0KCBjdXIsIFwiaGFuZGxlXCIgKTtcblx0XHRcdGlmICggaGFuZGxlICkge1xuXHRcdFx0XHRoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBOYXRpdmUgaGFuZGxlclxuXHRcdFx0aGFuZGxlID0gb250eXBlICYmIGN1clsgb250eXBlIF07XG5cdFx0XHRpZiAoIGhhbmRsZSAmJiBoYW5kbGUuYXBwbHkgJiYgYWNjZXB0RGF0YSggY3VyICkgKSB7XG5cdFx0XHRcdGV2ZW50LnJlc3VsdCA9IGhhbmRsZS5hcHBseSggY3VyLCBkYXRhICk7XG5cdFx0XHRcdGlmICggZXZlbnQucmVzdWx0ID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGV2ZW50LnR5cGUgPSB0eXBlO1xuXG5cdFx0Ly8gSWYgbm9ib2R5IHByZXZlbnRlZCB0aGUgZGVmYXVsdCBhY3Rpb24sIGRvIGl0IG5vd1xuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhZXZlbnQuaXNEZWZhdWx0UHJldmVudGVkKCkgKSB7XG5cblx0XHRcdGlmICggKCAhc3BlY2lhbC5fZGVmYXVsdCB8fFxuXHRcdFx0XHRzcGVjaWFsLl9kZWZhdWx0LmFwcGx5KCBldmVudFBhdGgucG9wKCksIGRhdGEgKSA9PT0gZmFsc2UgKSAmJlxuXHRcdFx0XHRhY2NlcHREYXRhKCBlbGVtICkgKSB7XG5cblx0XHRcdFx0Ly8gQ2FsbCBhIG5hdGl2ZSBET00gbWV0aG9kIG9uIHRoZSB0YXJnZXQgd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBldmVudC5cblx0XHRcdFx0Ly8gRG9uJ3QgZG8gZGVmYXVsdCBhY3Rpb25zIG9uIHdpbmRvdywgdGhhdCdzIHdoZXJlIGdsb2JhbCB2YXJpYWJsZXMgYmUgKCM2MTcwKVxuXHRcdFx0XHRpZiAoIG9udHlwZSAmJiBpc0Z1bmN0aW9uKCBlbGVtWyB0eXBlIF0gKSAmJiAhaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0XHRcdC8vIERvbid0IHJlLXRyaWdnZXIgYW4gb25GT08gZXZlbnQgd2hlbiB3ZSBjYWxsIGl0cyBGT08oKSBtZXRob2Rcblx0XHRcdFx0XHR0bXAgPSBlbGVtWyBvbnR5cGUgXTtcblxuXHRcdFx0XHRcdGlmICggdG1wICkge1xuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSBudWxsO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFByZXZlbnQgcmUtdHJpZ2dlcmluZyBvZiB0aGUgc2FtZSBldmVudCwgc2luY2Ugd2UgYWxyZWFkeSBidWJibGVkIGl0IGFib3ZlXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHR5cGU7XG5cblx0XHRcdFx0XHRpZiAoIGV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cdFx0XHRcdFx0XHRsYXN0RWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCB0eXBlLCBzdG9wUHJvcGFnYXRpb25DYWxsYmFjayApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGVsZW1bIHR5cGUgXSgpO1xuXG5cdFx0XHRcdFx0aWYgKCBldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXHRcdFx0XHRcdFx0bGFzdEVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgc3RvcFByb3BhZ2F0aW9uQ2FsbGJhY2sgKTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRcdFx0aWYgKCB0bXAgKSB7XG5cdFx0XHRcdFx0XHRlbGVtWyBvbnR5cGUgXSA9IHRtcDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xuXHR9LFxuXG5cdC8vIFBpZ2d5YmFjayBvbiBhIGRvbm9yIGV2ZW50IHRvIHNpbXVsYXRlIGEgZGlmZmVyZW50IG9uZVxuXHQvLyBVc2VkIG9ubHkgZm9yIGBmb2N1cyhpbiB8IG91dClgIGV2ZW50c1xuXHRzaW11bGF0ZTogZnVuY3Rpb24oIHR5cGUsIGVsZW0sIGV2ZW50ICkge1xuXHRcdHZhciBlID0galF1ZXJ5LmV4dGVuZChcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoKSxcblx0XHRcdGV2ZW50LFxuXHRcdFx0e1xuXHRcdFx0XHR0eXBlOiB0eXBlLFxuXHRcdFx0XHRpc1NpbXVsYXRlZDogdHJ1ZVxuXHRcdFx0fVxuXHRcdCk7XG5cblx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggZSwgbnVsbCwgZWxlbSApO1xuXHR9XG5cbn0gKTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIHRoaXMgKTtcblx0XHR9ICk7XG5cdH0sXG5cdHRyaWdnZXJIYW5kbGVyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgZWxlbSA9IHRoaXNbIDAgXTtcblx0XHRpZiAoIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmV2ZW50LnRyaWdnZXIoIHR5cGUsIGRhdGEsIGVsZW0sIHRydWUgKTtcblx0XHR9XG5cdH1cbn0gKTtcblxuXG4vLyBTdXBwb3J0OiBGaXJlZm94IDw9NDRcbi8vIEZpcmVmb3ggZG9lc24ndCBoYXZlIGZvY3VzKGluIHwgb3V0KSBldmVudHNcbi8vIFJlbGF0ZWQgdGlja2V0IC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9Njg3Nzg3XG4vL1xuLy8gU3VwcG9ydDogQ2hyb21lIDw9NDggLSA0OSwgU2FmYXJpIDw9OS4wIC0gOS4xXG4vLyBmb2N1cyhpbiB8IG91dCkgZXZlbnRzIGZpcmUgYWZ0ZXIgZm9jdXMgJiBibHVyIGV2ZW50cyxcbi8vIHdoaWNoIGlzIHNwZWMgdmlvbGF0aW9uIC0gaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtZm9jdXNldmVudC1ldmVudC1vcmRlclxuLy8gUmVsYXRlZCB0aWNrZXQgLSBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NDk4NTdcbmlmICggIXN1cHBvcnQuZm9jdXNpbiApIHtcblx0alF1ZXJ5LmVhY2goIHsgZm9jdXM6IFwiZm9jdXNpblwiLCBibHVyOiBcImZvY3Vzb3V0XCIgfSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblxuXHRcdC8vIEF0dGFjaCBhIHNpbmdsZSBjYXB0dXJpbmcgaGFuZGxlciBvbiB0aGUgZG9jdW1lbnQgd2hpbGUgc29tZW9uZSB3YW50cyBmb2N1c2luL2ZvY3Vzb3V0XG5cdFx0dmFyIGhhbmRsZXIgPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQuc2ltdWxhdGUoIGZpeCwgZXZlbnQudGFyZ2V0LCBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApICk7XG5cdFx0fTtcblxuXHRcdGpRdWVyeS5ldmVudC5zcGVjaWFsWyBmaXggXSA9IHtcblx0XHRcdHNldHVwOiBmdW5jdGlvbigpIHtcblxuXHRcdFx0XHQvLyBIYW5kbGU6IHJlZ3VsYXIgbm9kZXMgKHZpYSBgdGhpcy5vd25lckRvY3VtZW50YCksIHdpbmRvd1xuXHRcdFx0XHQvLyAodmlhIGB0aGlzLmRvY3VtZW50YCkgJiBkb2N1bWVudCAodmlhIGB0aGlzYCkuXG5cdFx0XHRcdHZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcy5kb2N1bWVudCB8fCB0aGlzLFxuXHRcdFx0XHRcdGF0dGFjaGVzID0gZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCApO1xuXG5cdFx0XHRcdGlmICggIWF0dGFjaGVzICkge1xuXHRcdFx0XHRcdGRvYy5hZGRFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCwgKCBhdHRhY2hlcyB8fCAwICkgKyAxICk7XG5cdFx0XHR9LFxuXHRcdFx0dGVhcmRvd246IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZG9jID0gdGhpcy5vd25lckRvY3VtZW50IHx8IHRoaXMuZG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0XHRhdHRhY2hlcyA9IGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXggKSAtIDE7XG5cblx0XHRcdFx0aWYgKCAhYXR0YWNoZXMgKSB7XG5cdFx0XHRcdFx0ZG9jLnJlbW92ZUV2ZW50TGlzdGVuZXIoIG9yaWcsIGhhbmRsZXIsIHRydWUgKTtcblx0XHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGRvYywgZml4ICk7XG5cblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4LCBhdHRhY2hlcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fSApO1xufVxudmFyIGxvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uO1xuXG52YXIgbm9uY2UgPSB7IGd1aWQ6IERhdGUubm93KCkgfTtcblxudmFyIHJxdWVyeSA9ICggL1xcPy8gKTtcblxuXG5cbi8vIENyb3NzLWJyb3dzZXIgeG1sIHBhcnNpbmdcbmpRdWVyeS5wYXJzZVhNTCA9IGZ1bmN0aW9uKCBkYXRhICkge1xuXHR2YXIgeG1sO1xuXHRpZiAoICFkYXRhIHx8IHR5cGVvZiBkYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cblx0Ly8gU3VwcG9ydDogSUUgOSAtIDExIG9ubHlcblx0Ly8gSUUgdGhyb3dzIG9uIHBhcnNlRnJvbVN0cmluZyB3aXRoIGludmFsaWQgaW5wdXQuXG5cdHRyeSB7XG5cdFx0eG1sID0gKCBuZXcgd2luZG93LkRPTVBhcnNlcigpICkucGFyc2VGcm9tU3RyaW5nKCBkYXRhLCBcInRleHQveG1sXCIgKTtcblx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0eG1sID0gdW5kZWZpbmVkO1xuXHR9XG5cblx0aWYgKCAheG1sIHx8IHhtbC5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJwYXJzZXJlcnJvclwiICkubGVuZ3RoICkge1xuXHRcdGpRdWVyeS5lcnJvciggXCJJbnZhbGlkIFhNTDogXCIgKyBkYXRhICk7XG5cdH1cblx0cmV0dXJuIHhtbDtcbn07XG5cblxudmFyXG5cdHJicmFja2V0ID0gL1xcW1xcXSQvLFxuXHRyQ1JMRiA9IC9cXHI/XFxuL2csXG5cdHJzdWJtaXR0ZXJUeXBlcyA9IC9eKD86c3VibWl0fGJ1dHRvbnxpbWFnZXxyZXNldHxmaWxlKSQvaSxcblx0cnN1Ym1pdHRhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO1xuXG5mdW5jdGlvbiBidWlsZFBhcmFtcyggcHJlZml4LCBvYmosIHRyYWRpdGlvbmFsLCBhZGQgKSB7XG5cdHZhciBuYW1lO1xuXG5cdGlmICggQXJyYXkuaXNBcnJheSggb2JqICkgKSB7XG5cblx0XHQvLyBTZXJpYWxpemUgYXJyYXkgaXRlbS5cblx0XHRqUXVlcnkuZWFjaCggb2JqLCBmdW5jdGlvbiggaSwgdiApIHtcblx0XHRcdGlmICggdHJhZGl0aW9uYWwgfHwgcmJyYWNrZXQudGVzdCggcHJlZml4ICkgKSB7XG5cblx0XHRcdFx0Ly8gVHJlYXQgZWFjaCBhcnJheSBpdGVtIGFzIGEgc2NhbGFyLlxuXHRcdFx0XHRhZGQoIHByZWZpeCwgdiApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXG5cdFx0XHRcdC8vIEl0ZW0gaXMgbm9uLXNjYWxhciAoYXJyYXkgb3Igb2JqZWN0KSwgZW5jb2RlIGl0cyBudW1lcmljIGluZGV4LlxuXHRcdFx0XHRidWlsZFBhcmFtcyhcblx0XHRcdFx0XHRwcmVmaXggKyBcIltcIiArICggdHlwZW9mIHYgPT09IFwib2JqZWN0XCIgJiYgdiAhPSBudWxsID8gaSA6IFwiXCIgKSArIFwiXVwiLFxuXHRcdFx0XHRcdHYsXG5cdFx0XHRcdFx0dHJhZGl0aW9uYWwsXG5cdFx0XHRcdFx0YWRkXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXG5cdH0gZWxzZSBpZiAoICF0cmFkaXRpb25hbCAmJiB0b1R5cGUoIG9iaiApID09PSBcIm9iamVjdFwiICkge1xuXG5cdFx0Ly8gU2VyaWFsaXplIG9iamVjdCBpdGVtLlxuXHRcdGZvciAoIG5hbWUgaW4gb2JqICkge1xuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCArIFwiW1wiICsgbmFtZSArIFwiXVwiLCBvYmpbIG5hbWUgXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xuXHRcdH1cblxuXHR9IGVsc2Uge1xuXG5cdFx0Ly8gU2VyaWFsaXplIHNjYWxhciBpdGVtLlxuXHRcdGFkZCggcHJlZml4LCBvYmogKTtcblx0fVxufVxuXG4vLyBTZXJpYWxpemUgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cyBvciBhIHNldCBvZlxuLy8ga2V5L3ZhbHVlcyBpbnRvIGEgcXVlcnkgc3RyaW5nXG5qUXVlcnkucGFyYW0gPSBmdW5jdGlvbiggYSwgdHJhZGl0aW9uYWwgKSB7XG5cdHZhciBwcmVmaXgsXG5cdFx0cyA9IFtdLFxuXHRcdGFkZCA9IGZ1bmN0aW9uKCBrZXksIHZhbHVlT3JGdW5jdGlvbiApIHtcblxuXHRcdFx0Ly8gSWYgdmFsdWUgaXMgYSBmdW5jdGlvbiwgaW52b2tlIGl0IGFuZCB1c2UgaXRzIHJldHVybiB2YWx1ZVxuXHRcdFx0dmFyIHZhbHVlID0gaXNGdW5jdGlvbiggdmFsdWVPckZ1bmN0aW9uICkgP1xuXHRcdFx0XHR2YWx1ZU9yRnVuY3Rpb24oKSA6XG5cdFx0XHRcdHZhbHVlT3JGdW5jdGlvbjtcblxuXHRcdFx0c1sgcy5sZW5ndGggXSA9IGVuY29kZVVSSUNvbXBvbmVudCgga2V5ICkgKyBcIj1cIiArXG5cdFx0XHRcdGVuY29kZVVSSUNvbXBvbmVudCggdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSApO1xuXHRcdH07XG5cblx0aWYgKCBhID09IG51bGwgKSB7XG5cdFx0cmV0dXJuIFwiXCI7XG5cdH1cblxuXHQvLyBJZiBhbiBhcnJheSB3YXMgcGFzc2VkIGluLCBhc3N1bWUgdGhhdCBpdCBpcyBhbiBhcnJheSBvZiBmb3JtIGVsZW1lbnRzLlxuXHRpZiAoIEFycmF5LmlzQXJyYXkoIGEgKSB8fCAoIGEuanF1ZXJ5ICYmICFqUXVlcnkuaXNQbGFpbk9iamVjdCggYSApICkgKSB7XG5cblx0XHQvLyBTZXJpYWxpemUgdGhlIGZvcm0gZWxlbWVudHNcblx0XHRqUXVlcnkuZWFjaCggYSwgZnVuY3Rpb24oKSB7XG5cdFx0XHRhZGQoIHRoaXMubmFtZSwgdGhpcy52YWx1ZSApO1xuXHRcdH0gKTtcblxuXHR9IGVsc2Uge1xuXG5cdFx0Ly8gSWYgdHJhZGl0aW9uYWwsIGVuY29kZSB0aGUgXCJvbGRcIiB3YXkgKHRoZSB3YXkgMS4zLjIgb3Igb2xkZXJcblx0XHQvLyBkaWQgaXQpLCBvdGhlcndpc2UgZW5jb2RlIHBhcmFtcyByZWN1cnNpdmVseS5cblx0XHRmb3IgKCBwcmVmaXggaW4gYSApIHtcblx0XHRcdGJ1aWxkUGFyYW1zKCBwcmVmaXgsIGFbIHByZWZpeCBdLCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSByZXN1bHRpbmcgc2VyaWFsaXphdGlvblxuXHRyZXR1cm4gcy5qb2luKCBcIiZcIiApO1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCgge1xuXHRzZXJpYWxpemU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBqUXVlcnkucGFyYW0oIHRoaXMuc2VyaWFsaXplQXJyYXkoKSApO1xuXHR9LFxuXHRzZXJpYWxpemVBcnJheTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMubWFwKCBmdW5jdGlvbigpIHtcblxuXHRcdFx0Ly8gQ2FuIGFkZCBwcm9wSG9vayBmb3IgXCJlbGVtZW50c1wiIHRvIGZpbHRlciBvciBhZGQgZm9ybSBlbGVtZW50c1xuXHRcdFx0dmFyIGVsZW1lbnRzID0galF1ZXJ5LnByb3AoIHRoaXMsIFwiZWxlbWVudHNcIiApO1xuXHRcdFx0cmV0dXJuIGVsZW1lbnRzID8galF1ZXJ5Lm1ha2VBcnJheSggZWxlbWVudHMgKSA6IHRoaXM7XG5cdFx0fSApXG5cdFx0LmZpbHRlciggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgdHlwZSA9IHRoaXMudHlwZTtcblxuXHRcdFx0Ly8gVXNlIC5pcyggXCI6ZGlzYWJsZWRcIiApIHNvIHRoYXQgZmllbGRzZXRbZGlzYWJsZWRdIHdvcmtzXG5cdFx0XHRyZXR1cm4gdGhpcy5uYW1lICYmICFqUXVlcnkoIHRoaXMgKS5pcyggXCI6ZGlzYWJsZWRcIiApICYmXG5cdFx0XHRcdHJzdWJtaXR0YWJsZS50ZXN0KCB0aGlzLm5vZGVOYW1lICkgJiYgIXJzdWJtaXR0ZXJUeXBlcy50ZXN0KCB0eXBlICkgJiZcblx0XHRcdFx0KCB0aGlzLmNoZWNrZWQgfHwgIXJjaGVja2FibGVUeXBlLnRlc3QoIHR5cGUgKSApO1xuXHRcdH0gKVxuXHRcdC5tYXAoIGZ1bmN0aW9uKCBfaSwgZWxlbSApIHtcblx0XHRcdHZhciB2YWwgPSBqUXVlcnkoIHRoaXMgKS52YWwoKTtcblxuXHRcdFx0aWYgKCB2YWwgPT0gbnVsbCApIHtcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggQXJyYXkuaXNBcnJheSggdmFsICkgKSB7XG5cdFx0XHRcdHJldHVybiBqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKCB2YWwgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHsgbmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsLnJlcGxhY2UoIHJDUkxGLCBcIlxcclxcblwiICkgfTtcblx0XHRcdFx0fSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4geyBuYW1lOiBlbGVtLm5hbWUsIHZhbHVlOiB2YWwucmVwbGFjZSggckNSTEYsIFwiXFxyXFxuXCIgKSB9O1xuXHRcdH0gKS5nZXQoKTtcblx0fVxufSApO1xuXG5cbnZhclxuXHRyMjAgPSAvJTIwL2csXG5cdHJoYXNoID0gLyMuKiQvLFxuXHRyYW50aUNhY2hlID0gLyhbPyZdKV89W14mXSovLFxuXHRyaGVhZGVycyA9IC9eKC4qPyk6WyBcXHRdKihbXlxcclxcbl0qKSQvbWcsXG5cblx0Ly8gIzc2NTMsICM4MTI1LCAjODE1MjogbG9jYWwgcHJvdG9jb2wgZGV0ZWN0aW9uXG5cdHJsb2NhbFByb3RvY29sID0gL14oPzphYm91dHxhcHB8YXBwLXN0b3JhZ2V8ListZXh0ZW5zaW9ufGZpbGV8cmVzfHdpZGdldCk6JC8sXG5cdHJub0NvbnRlbnQgPSAvXig/OkdFVHxIRUFEKSQvLFxuXHRycHJvdG9jb2wgPSAvXlxcL1xcLy8sXG5cblx0LyogUHJlZmlsdGVyc1xuXHQgKiAxKSBUaGV5IGFyZSB1c2VmdWwgdG8gaW50cm9kdWNlIGN1c3RvbSBkYXRhVHlwZXMgKHNlZSBhamF4L2pzb25wLmpzIGZvciBhbiBleGFtcGxlKVxuXHQgKiAyKSBUaGVzZSBhcmUgY2FsbGVkOlxuXHQgKiAgICAtIEJFRk9SRSBhc2tpbmcgZm9yIGEgdHJhbnNwb3J0XG5cdCAqICAgIC0gQUZURVIgcGFyYW0gc2VyaWFsaXphdGlvbiAocy5kYXRhIGlzIGEgc3RyaW5nIGlmIHMucHJvY2Vzc0RhdGEgaXMgdHJ1ZSlcblx0ICogMykga2V5IGlzIHRoZSBkYXRhVHlwZVxuXHQgKiA0KSB0aGUgY2F0Y2hhbGwgc3ltYm9sIFwiKlwiIGNhbiBiZSB1c2VkXG5cdCAqIDUpIGV4ZWN1dGlvbiB3aWxsIHN0YXJ0IHdpdGggdHJhbnNwb3J0IGRhdGFUeXBlIGFuZCBUSEVOIGNvbnRpbnVlIGRvd24gdG8gXCIqXCIgaWYgbmVlZGVkXG5cdCAqL1xuXHRwcmVmaWx0ZXJzID0ge30sXG5cblx0LyogVHJhbnNwb3J0cyBiaW5kaW5nc1xuXHQgKiAxKSBrZXkgaXMgdGhlIGRhdGFUeXBlXG5cdCAqIDIpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcblx0ICogMykgc2VsZWN0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gZ28gdG8gXCIqXCIgaWYgbmVlZGVkXG5cdCAqL1xuXHR0cmFuc3BvcnRzID0ge30sXG5cblx0Ly8gQXZvaWQgY29tbWVudC1wcm9sb2cgY2hhciBzZXF1ZW5jZSAoIzEwMDk4KTsgbXVzdCBhcHBlYXNlIGxpbnQgYW5kIGV2YWRlIGNvbXByZXNzaW9uXG5cdGFsbFR5cGVzID0gXCIqL1wiLmNvbmNhdCggXCIqXCIgKSxcblxuXHQvLyBBbmNob3IgdGFnIGZvciBwYXJzaW5nIHRoZSBkb2N1bWVudCBvcmlnaW5cblx0b3JpZ2luQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJhXCIgKTtcblx0b3JpZ2luQW5jaG9yLmhyZWYgPSBsb2NhdGlvbi5ocmVmO1xuXG4vLyBCYXNlIFwiY29uc3RydWN0b3JcIiBmb3IgalF1ZXJ5LmFqYXhQcmVmaWx0ZXIgYW5kIGpRdWVyeS5hamF4VHJhbnNwb3J0XG5mdW5jdGlvbiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSApIHtcblxuXHQvLyBkYXRhVHlwZUV4cHJlc3Npb24gaXMgb3B0aW9uYWwgYW5kIGRlZmF1bHRzIHRvIFwiKlwiXG5cdHJldHVybiBmdW5jdGlvbiggZGF0YVR5cGVFeHByZXNzaW9uLCBmdW5jICkge1xuXG5cdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVFeHByZXNzaW9uICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0ZnVuYyA9IGRhdGFUeXBlRXhwcmVzc2lvbjtcblx0XHRcdGRhdGFUeXBlRXhwcmVzc2lvbiA9IFwiKlwiO1xuXHRcdH1cblxuXHRcdHZhciBkYXRhVHlwZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0ZGF0YVR5cGVzID0gZGF0YVR5cGVFeHByZXNzaW9uLnRvTG93ZXJDYXNlKCkubWF0Y2goIHJub3RodG1sd2hpdGUgKSB8fCBbXTtcblxuXHRcdGlmICggaXNGdW5jdGlvbiggZnVuYyApICkge1xuXG5cdFx0XHQvLyBGb3IgZWFjaCBkYXRhVHlwZSBpbiB0aGUgZGF0YVR5cGVFeHByZXNzaW9uXG5cdFx0XHR3aGlsZSAoICggZGF0YVR5cGUgPSBkYXRhVHlwZXNbIGkrKyBdICkgKSB7XG5cblx0XHRcdFx0Ly8gUHJlcGVuZCBpZiByZXF1ZXN0ZWRcblx0XHRcdFx0aWYgKCBkYXRhVHlwZVsgMCBdID09PSBcIitcIiApIHtcblx0XHRcdFx0XHRkYXRhVHlwZSA9IGRhdGFUeXBlLnNsaWNlKCAxICkgfHwgXCIqXCI7XG5cdFx0XHRcdFx0KCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gPSBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10gKS51bnNoaWZ0KCBmdW5jICk7XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdCggc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdICkucHVzaCggZnVuYyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xufVxuXG4vLyBCYXNlIGluc3BlY3Rpb24gZnVuY3Rpb24gZm9yIHByZWZpbHRlcnMgYW5kIHRyYW5zcG9ydHNcbmZ1bmN0aW9uIGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBzdHJ1Y3R1cmUsIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKSB7XG5cblx0dmFyIGluc3BlY3RlZCA9IHt9LFxuXHRcdHNlZWtpbmdUcmFuc3BvcnQgPSAoIHN0cnVjdHVyZSA9PT0gdHJhbnNwb3J0cyApO1xuXG5cdGZ1bmN0aW9uIGluc3BlY3QoIGRhdGFUeXBlICkge1xuXHRcdHZhciBzZWxlY3RlZDtcblx0XHRpbnNwZWN0ZWRbIGRhdGFUeXBlIF0gPSB0cnVlO1xuXHRcdGpRdWVyeS5lYWNoKCBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10sIGZ1bmN0aW9uKCBfLCBwcmVmaWx0ZXJPckZhY3RvcnkgKSB7XG5cdFx0XHR2YXIgZGF0YVR5cGVPclRyYW5zcG9ydCA9IHByZWZpbHRlck9yRmFjdG9yeSggb3B0aW9ucywgb3JpZ2luYWxPcHRpb25zLCBqcVhIUiApO1xuXHRcdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVPclRyYW5zcG9ydCA9PT0gXCJzdHJpbmdcIiAmJlxuXHRcdFx0XHQhc2Vla2luZ1RyYW5zcG9ydCAmJiAhaW5zcGVjdGVkWyBkYXRhVHlwZU9yVHJhbnNwb3J0IF0gKSB7XG5cblx0XHRcdFx0b3B0aW9ucy5kYXRhVHlwZXMudW5zaGlmdCggZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0XHRpbnNwZWN0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH0gZWxzZSBpZiAoIHNlZWtpbmdUcmFuc3BvcnQgKSB7XG5cdFx0XHRcdHJldHVybiAhKCBzZWxlY3RlZCA9IGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdH1cblx0XHR9ICk7XG5cdFx0cmV0dXJuIHNlbGVjdGVkO1xuXHR9XG5cblx0cmV0dXJuIGluc3BlY3QoIG9wdGlvbnMuZGF0YVR5cGVzWyAwIF0gKSB8fCAhaW5zcGVjdGVkWyBcIipcIiBdICYmIGluc3BlY3QoIFwiKlwiICk7XG59XG5cbi8vIEEgc3BlY2lhbCBleHRlbmQgZm9yIGFqYXggb3B0aW9uc1xuLy8gdGhhdCB0YWtlcyBcImZsYXRcIiBvcHRpb25zIChub3QgdG8gYmUgZGVlcCBleHRlbmRlZClcbi8vIEZpeGVzICM5ODg3XG5mdW5jdGlvbiBhamF4RXh0ZW5kKCB0YXJnZXQsIHNyYyApIHtcblx0dmFyIGtleSwgZGVlcCxcblx0XHRmbGF0T3B0aW9ucyA9IGpRdWVyeS5hamF4U2V0dGluZ3MuZmxhdE9wdGlvbnMgfHwge307XG5cblx0Zm9yICgga2V5IGluIHNyYyApIHtcblx0XHRpZiAoIHNyY1sga2V5IF0gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdCggZmxhdE9wdGlvbnNbIGtleSBdID8gdGFyZ2V0IDogKCBkZWVwIHx8ICggZGVlcCA9IHt9ICkgKSApWyBrZXkgXSA9IHNyY1sga2V5IF07XG5cdFx0fVxuXHR9XG5cdGlmICggZGVlcCApIHtcblx0XHRqUXVlcnkuZXh0ZW5kKCB0cnVlLCB0YXJnZXQsIGRlZXAgKTtcblx0fVxuXG5cdHJldHVybiB0YXJnZXQ7XG59XG5cbi8qIEhhbmRsZXMgcmVzcG9uc2VzIHRvIGFuIGFqYXggcmVxdWVzdDpcbiAqIC0gZmluZHMgdGhlIHJpZ2h0IGRhdGFUeXBlIChtZWRpYXRlcyBiZXR3ZWVuIGNvbnRlbnQtdHlwZSBhbmQgZXhwZWN0ZWQgZGF0YVR5cGUpXG4gKiAtIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2VcbiAqL1xuZnVuY3Rpb24gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApIHtcblxuXHR2YXIgY3QsIHR5cGUsIGZpbmFsRGF0YVR5cGUsIGZpcnN0RGF0YVR5cGUsXG5cdFx0Y29udGVudHMgPSBzLmNvbnRlbnRzLFxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzO1xuXG5cdC8vIFJlbW92ZSBhdXRvIGRhdGFUeXBlIGFuZCBnZXQgY29udGVudC10eXBlIGluIHRoZSBwcm9jZXNzXG5cdHdoaWxlICggZGF0YVR5cGVzWyAwIF0gPT09IFwiKlwiICkge1xuXHRcdGRhdGFUeXBlcy5zaGlmdCgpO1xuXHRcdGlmICggY3QgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGN0ID0gcy5taW1lVHlwZSB8fCBqcVhIUi5nZXRSZXNwb25zZUhlYWRlciggXCJDb250ZW50LVR5cGVcIiApO1xuXHRcdH1cblx0fVxuXG5cdC8vIENoZWNrIGlmIHdlJ3JlIGRlYWxpbmcgd2l0aCBhIGtub3duIGNvbnRlbnQtdHlwZVxuXHRpZiAoIGN0ICkge1xuXHRcdGZvciAoIHR5cGUgaW4gY29udGVudHMgKSB7XG5cdFx0XHRpZiAoIGNvbnRlbnRzWyB0eXBlIF0gJiYgY29udGVudHNbIHR5cGUgXS50ZXN0KCBjdCApICkge1xuXHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdHlwZSApO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBDaGVjayB0byBzZWUgaWYgd2UgaGF2ZSBhIHJlc3BvbnNlIGZvciB0aGUgZXhwZWN0ZWQgZGF0YVR5cGVcblx0aWYgKCBkYXRhVHlwZXNbIDAgXSBpbiByZXNwb25zZXMgKSB7XG5cdFx0ZmluYWxEYXRhVHlwZSA9IGRhdGFUeXBlc1sgMCBdO1xuXHR9IGVsc2Uge1xuXG5cdFx0Ly8gVHJ5IGNvbnZlcnRpYmxlIGRhdGFUeXBlc1xuXHRcdGZvciAoIHR5cGUgaW4gcmVzcG9uc2VzICkge1xuXHRcdFx0aWYgKCAhZGF0YVR5cGVzWyAwIF0gfHwgcy5jb252ZXJ0ZXJzWyB0eXBlICsgXCIgXCIgKyBkYXRhVHlwZXNbIDAgXSBdICkge1xuXHRcdFx0XHRmaW5hbERhdGFUeXBlID0gdHlwZTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoICFmaXJzdERhdGFUeXBlICkge1xuXHRcdFx0XHRmaXJzdERhdGFUeXBlID0gdHlwZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBPciBqdXN0IHVzZSBmaXJzdCBvbmVcblx0XHRmaW5hbERhdGFUeXBlID0gZmluYWxEYXRhVHlwZSB8fCBmaXJzdERhdGFUeXBlO1xuXHR9XG5cblx0Ly8gSWYgd2UgZm91bmQgYSBkYXRhVHlwZVxuXHQvLyBXZSBhZGQgdGhlIGRhdGFUeXBlIHRvIHRoZSBsaXN0IGlmIG5lZWRlZFxuXHQvLyBhbmQgcmV0dXJuIHRoZSBjb3JyZXNwb25kaW5nIHJlc3BvbnNlXG5cdGlmICggZmluYWxEYXRhVHlwZSApIHtcblx0XHRpZiAoIGZpbmFsRGF0YVR5cGUgIT09IGRhdGFUeXBlc1sgMCBdICkge1xuXHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIGZpbmFsRGF0YVR5cGUgKTtcblx0XHR9XG5cdFx0cmV0dXJuIHJlc3BvbnNlc1sgZmluYWxEYXRhVHlwZSBdO1xuXHR9XG59XG5cbi8qIENoYWluIGNvbnZlcnNpb25zIGdpdmVuIHRoZSByZXF1ZXN0IGFuZCB0aGUgb3JpZ2luYWwgcmVzcG9uc2VcbiAqIEFsc28gc2V0cyB0aGUgcmVzcG9uc2VYWFggZmllbGRzIG9uIHRoZSBqcVhIUiBpbnN0YW5jZVxuICovXG5mdW5jdGlvbiBhamF4Q29udmVydCggcywgcmVzcG9uc2UsIGpxWEhSLCBpc1N1Y2Nlc3MgKSB7XG5cdHZhciBjb252MiwgY3VycmVudCwgY29udiwgdG1wLCBwcmV2LFxuXHRcdGNvbnZlcnRlcnMgPSB7fSxcblxuXHRcdC8vIFdvcmsgd2l0aCBhIGNvcHkgb2YgZGF0YVR5cGVzIGluIGNhc2Ugd2UgbmVlZCB0byBtb2RpZnkgaXQgZm9yIGNvbnZlcnNpb25cblx0XHRkYXRhVHlwZXMgPSBzLmRhdGFUeXBlcy5zbGljZSgpO1xuXG5cdC8vIENyZWF0ZSBjb252ZXJ0ZXJzIG1hcCB3aXRoIGxvd2VyY2FzZWQga2V5c1xuXHRpZiAoIGRhdGFUeXBlc1sgMSBdICkge1xuXHRcdGZvciAoIGNvbnYgaW4gcy5jb252ZXJ0ZXJzICkge1xuXHRcdFx0Y29udmVydGVyc1sgY29udi50b0xvd2VyQ2FzZSgpIF0gPSBzLmNvbnZlcnRlcnNbIGNvbnYgXTtcblx0XHR9XG5cdH1cblxuXHRjdXJyZW50ID0gZGF0YVR5cGVzLnNoaWZ0KCk7XG5cblx0Ly8gQ29udmVydCB0byBlYWNoIHNlcXVlbnRpYWwgZGF0YVR5cGVcblx0d2hpbGUgKCBjdXJyZW50ICkge1xuXG5cdFx0aWYgKCBzLnJlc3BvbnNlRmllbGRzWyBjdXJyZW50IF0gKSB7XG5cdFx0XHRqcVhIUlsgcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdIF0gPSByZXNwb25zZTtcblx0XHR9XG5cblx0XHQvLyBBcHBseSB0aGUgZGF0YUZpbHRlciBpZiBwcm92aWRlZFxuXHRcdGlmICggIXByZXYgJiYgaXNTdWNjZXNzICYmIHMuZGF0YUZpbHRlciApIHtcblx0XHRcdHJlc3BvbnNlID0gcy5kYXRhRmlsdGVyKCByZXNwb25zZSwgcy5kYXRhVHlwZSApO1xuXHRcdH1cblxuXHRcdHByZXYgPSBjdXJyZW50O1xuXHRcdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcblxuXHRcdGlmICggY3VycmVudCApIHtcblxuXHRcdFx0Ly8gVGhlcmUncyBvbmx5IHdvcmsgdG8gZG8gaWYgY3VycmVudCBkYXRhVHlwZSBpcyBub24tYXV0b1xuXHRcdFx0aWYgKCBjdXJyZW50ID09PSBcIipcIiApIHtcblxuXHRcdFx0XHRjdXJyZW50ID0gcHJldjtcblxuXHRcdFx0Ly8gQ29udmVydCByZXNwb25zZSBpZiBwcmV2IGRhdGFUeXBlIGlzIG5vbi1hdXRvIGFuZCBkaWZmZXJzIGZyb20gY3VycmVudFxuXHRcdFx0fSBlbHNlIGlmICggcHJldiAhPT0gXCIqXCIgJiYgcHJldiAhPT0gY3VycmVudCApIHtcblxuXHRcdFx0XHQvLyBTZWVrIGEgZGlyZWN0IGNvbnZlcnRlclxuXHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgY3VycmVudCBdIHx8IGNvbnZlcnRlcnNbIFwiKiBcIiArIGN1cnJlbnQgXTtcblxuXHRcdFx0XHQvLyBJZiBub25lIGZvdW5kLCBzZWVrIGEgcGFpclxuXHRcdFx0XHRpZiAoICFjb252ICkge1xuXHRcdFx0XHRcdGZvciAoIGNvbnYyIGluIGNvbnZlcnRlcnMgKSB7XG5cblx0XHRcdFx0XHRcdC8vIElmIGNvbnYyIG91dHB1dHMgY3VycmVudFxuXHRcdFx0XHRcdFx0dG1wID0gY29udjIuc3BsaXQoIFwiIFwiICk7XG5cdFx0XHRcdFx0XHRpZiAoIHRtcFsgMSBdID09PSBjdXJyZW50ICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIElmIHByZXYgY2FuIGJlIGNvbnZlcnRlZCB0byBhY2NlcHRlZCBpbnB1dFxuXHRcdFx0XHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgdG1wWyAwIF0gXSB8fFxuXHRcdFx0XHRcdFx0XHRcdGNvbnZlcnRlcnNbIFwiKiBcIiArIHRtcFsgMCBdIF07XG5cdFx0XHRcdFx0XHRcdGlmICggY29udiApIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIENvbmRlbnNlIGVxdWl2YWxlbmNlIGNvbnZlcnRlcnNcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGNvbnYgPT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgY29udjIgXTtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIE90aGVyd2lzZSwgaW5zZXJ0IHRoZSBpbnRlcm1lZGlhdGUgZGF0YVR5cGVcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBjb252ZXJ0ZXJzWyBjb252MiBdICE9PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y3VycmVudCA9IHRtcFsgMCBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIHRtcFsgMSBdICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXBwbHkgY29udmVydGVyIChpZiBub3QgYW4gZXF1aXZhbGVuY2UpXG5cdFx0XHRcdGlmICggY29udiAhPT0gdHJ1ZSApIHtcblxuXHRcdFx0XHRcdC8vIFVubGVzcyBlcnJvcnMgYXJlIGFsbG93ZWQgdG8gYnViYmxlLCBjYXRjaCBhbmQgcmV0dXJuIHRoZW1cblx0XHRcdFx0XHRpZiAoIGNvbnYgJiYgcy50aHJvd3MgKSB7XG5cdFx0XHRcdFx0XHRyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdHJlc3BvbnNlID0gY29udiggcmVzcG9uc2UgKTtcblx0XHRcdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0XHRcdHN0YXRlOiBcInBhcnNlcmVycm9yXCIsXG5cdFx0XHRcdFx0XHRcdFx0ZXJyb3I6IGNvbnYgPyBlIDogXCJObyBjb252ZXJzaW9uIGZyb20gXCIgKyBwcmV2ICsgXCIgdG8gXCIgKyBjdXJyZW50XG5cdFx0XHRcdFx0XHRcdH07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHsgc3RhdGU6IFwic3VjY2Vzc1wiLCBkYXRhOiByZXNwb25zZSB9O1xufVxuXG5qUXVlcnkuZXh0ZW5kKCB7XG5cblx0Ly8gQ291bnRlciBmb3IgaG9sZGluZyB0aGUgbnVtYmVyIG9mIGFjdGl2ZSBxdWVyaWVzXG5cdGFjdGl2ZTogMCxcblxuXHQvLyBMYXN0LU1vZGlmaWVkIGhlYWRlciBjYWNoZSBmb3IgbmV4dCByZXF1ZXN0XG5cdGxhc3RNb2RpZmllZDoge30sXG5cdGV0YWc6IHt9LFxuXG5cdGFqYXhTZXR0aW5nczoge1xuXHRcdHVybDogbG9jYXRpb24uaHJlZixcblx0XHR0eXBlOiBcIkdFVFwiLFxuXHRcdGlzTG9jYWw6IHJsb2NhbFByb3RvY29sLnRlc3QoIGxvY2F0aW9uLnByb3RvY29sICksXG5cdFx0Z2xvYmFsOiB0cnVlLFxuXHRcdHByb2Nlc3NEYXRhOiB0cnVlLFxuXHRcdGFzeW5jOiB0cnVlLFxuXHRcdGNvbnRlbnRUeXBlOiBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZDsgY2hhcnNldD1VVEYtOFwiLFxuXG5cdFx0Lypcblx0XHR0aW1lb3V0OiAwLFxuXHRcdGRhdGE6IG51bGwsXG5cdFx0ZGF0YVR5cGU6IG51bGwsXG5cdFx0dXNlcm5hbWU6IG51bGwsXG5cdFx0cGFzc3dvcmQ6IG51bGwsXG5cdFx0Y2FjaGU6IG51bGwsXG5cdFx0dGhyb3dzOiBmYWxzZSxcblx0XHR0cmFkaXRpb25hbDogZmFsc2UsXG5cdFx0aGVhZGVyczoge30sXG5cdFx0Ki9cblxuXHRcdGFjY2VwdHM6IHtcblx0XHRcdFwiKlwiOiBhbGxUeXBlcyxcblx0XHRcdHRleHQ6IFwidGV4dC9wbGFpblwiLFxuXHRcdFx0aHRtbDogXCJ0ZXh0L2h0bWxcIixcblx0XHRcdHhtbDogXCJhcHBsaWNhdGlvbi94bWwsIHRleHQveG1sXCIsXG5cdFx0XHRqc29uOiBcImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdFwiXG5cdFx0fSxcblxuXHRcdGNvbnRlbnRzOiB7XG5cdFx0XHR4bWw6IC9cXGJ4bWxcXGIvLFxuXHRcdFx0aHRtbDogL1xcYmh0bWwvLFxuXHRcdFx0anNvbjogL1xcYmpzb25cXGIvXG5cdFx0fSxcblxuXHRcdHJlc3BvbnNlRmllbGRzOiB7XG5cdFx0XHR4bWw6IFwicmVzcG9uc2VYTUxcIixcblx0XHRcdHRleHQ6IFwicmVzcG9uc2VUZXh0XCIsXG5cdFx0XHRqc29uOiBcInJlc3BvbnNlSlNPTlwiXG5cdFx0fSxcblxuXHRcdC8vIERhdGEgY29udmVydGVyc1xuXHRcdC8vIEtleXMgc2VwYXJhdGUgc291cmNlIChvciBjYXRjaGFsbCBcIipcIikgYW5kIGRlc3RpbmF0aW9uIHR5cGVzIHdpdGggYSBzaW5nbGUgc3BhY2Vcblx0XHRjb252ZXJ0ZXJzOiB7XG5cblx0XHRcdC8vIENvbnZlcnQgYW55dGhpbmcgdG8gdGV4dFxuXHRcdFx0XCIqIHRleHRcIjogU3RyaW5nLFxuXG5cdFx0XHQvLyBUZXh0IHRvIGh0bWwgKHRydWUgPSBubyB0cmFuc2Zvcm1hdGlvbilcblx0XHRcdFwidGV4dCBodG1sXCI6IHRydWUsXG5cblx0XHRcdC8vIEV2YWx1YXRlIHRleHQgYXMgYSBqc29uIGV4cHJlc3Npb25cblx0XHRcdFwidGV4dCBqc29uXCI6IEpTT04ucGFyc2UsXG5cblx0XHRcdC8vIFBhcnNlIHRleHQgYXMgeG1sXG5cdFx0XHRcInRleHQgeG1sXCI6IGpRdWVyeS5wYXJzZVhNTFxuXHRcdH0sXG5cblx0XHQvLyBGb3Igb3B0aW9ucyB0aGF0IHNob3VsZG4ndCBiZSBkZWVwIGV4dGVuZGVkOlxuXHRcdC8vIHlvdSBjYW4gYWRkIHlvdXIgb3duIGN1c3RvbSBvcHRpb25zIGhlcmUgaWZcblx0XHQvLyBhbmQgd2hlbiB5b3UgY3JlYXRlIG9uZSB0aGF0IHNob3VsZG4ndCBiZVxuXHRcdC8vIGRlZXAgZXh0ZW5kZWQgKHNlZSBhamF4RXh0ZW5kKVxuXHRcdGZsYXRPcHRpb25zOiB7XG5cdFx0XHR1cmw6IHRydWUsXG5cdFx0XHRjb250ZXh0OiB0cnVlXG5cdFx0fVxuXHR9LFxuXG5cdC8vIENyZWF0ZXMgYSBmdWxsIGZsZWRnZWQgc2V0dGluZ3Mgb2JqZWN0IGludG8gdGFyZ2V0XG5cdC8vIHdpdGggYm90aCBhamF4U2V0dGluZ3MgYW5kIHNldHRpbmdzIGZpZWxkcy5cblx0Ly8gSWYgdGFyZ2V0IGlzIG9taXR0ZWQsIHdyaXRlcyBpbnRvIGFqYXhTZXR0aW5ncy5cblx0YWpheFNldHVwOiBmdW5jdGlvbiggdGFyZ2V0LCBzZXR0aW5ncyApIHtcblx0XHRyZXR1cm4gc2V0dGluZ3MgP1xuXG5cdFx0XHQvLyBCdWlsZGluZyBhIHNldHRpbmdzIG9iamVjdFxuXHRcdFx0YWpheEV4dGVuZCggYWpheEV4dGVuZCggdGFyZ2V0LCBqUXVlcnkuYWpheFNldHRpbmdzICksIHNldHRpbmdzICkgOlxuXG5cdFx0XHQvLyBFeHRlbmRpbmcgYWpheFNldHRpbmdzXG5cdFx0XHRhamF4RXh0ZW5kKCBqUXVlcnkuYWpheFNldHRpbmdzLCB0YXJnZXQgKTtcblx0fSxcblxuXHRhamF4UHJlZmlsdGVyOiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMgKSxcblx0YWpheFRyYW5zcG9ydDogYWRkVG9QcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzICksXG5cblx0Ly8gTWFpbiBtZXRob2Rcblx0YWpheDogZnVuY3Rpb24oIHVybCwgb3B0aW9ucyApIHtcblxuXHRcdC8vIElmIHVybCBpcyBhbiBvYmplY3QsIHNpbXVsYXRlIHByZS0xLjUgc2lnbmF0dXJlXG5cdFx0aWYgKCB0eXBlb2YgdXJsID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0b3B0aW9ucyA9IHVybDtcblx0XHRcdHVybCA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBGb3JjZSBvcHRpb25zIHRvIGJlIGFuIG9iamVjdFxuXHRcdG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuXG5cdFx0dmFyIHRyYW5zcG9ydCxcblxuXHRcdFx0Ly8gVVJMIHdpdGhvdXQgYW50aS1jYWNoZSBwYXJhbVxuXHRcdFx0Y2FjaGVVUkwsXG5cblx0XHRcdC8vIFJlc3BvbnNlIGhlYWRlcnNcblx0XHRcdHJlc3BvbnNlSGVhZGVyc1N0cmluZyxcblx0XHRcdHJlc3BvbnNlSGVhZGVycyxcblxuXHRcdFx0Ly8gdGltZW91dCBoYW5kbGVcblx0XHRcdHRpbWVvdXRUaW1lcixcblxuXHRcdFx0Ly8gVXJsIGNsZWFudXAgdmFyXG5cdFx0XHR1cmxBbmNob3IsXG5cblx0XHRcdC8vIFJlcXVlc3Qgc3RhdGUgKGJlY29tZXMgZmFsc2UgdXBvbiBzZW5kIGFuZCB0cnVlIHVwb24gY29tcGxldGlvbilcblx0XHRcdGNvbXBsZXRlZCxcblxuXHRcdFx0Ly8gVG8ga25vdyBpZiBnbG9iYWwgZXZlbnRzIGFyZSB0byBiZSBkaXNwYXRjaGVkXG5cdFx0XHRmaXJlR2xvYmFscyxcblxuXHRcdFx0Ly8gTG9vcCB2YXJpYWJsZVxuXHRcdFx0aSxcblxuXHRcdFx0Ly8gdW5jYWNoZWQgcGFydCBvZiB0aGUgdXJsXG5cdFx0XHR1bmNhY2hlZCxcblxuXHRcdFx0Ly8gQ3JlYXRlIHRoZSBmaW5hbCBvcHRpb25zIG9iamVjdFxuXHRcdFx0cyA9IGpRdWVyeS5hamF4U2V0dXAoIHt9LCBvcHRpb25zICksXG5cblx0XHRcdC8vIENhbGxiYWNrcyBjb250ZXh0XG5cdFx0XHRjYWxsYmFja0NvbnRleHQgPSBzLmNvbnRleHQgfHwgcyxcblxuXHRcdFx0Ly8gQ29udGV4dCBmb3IgZ2xvYmFsIGV2ZW50cyBpcyBjYWxsYmFja0NvbnRleHQgaWYgaXQgaXMgYSBET00gbm9kZSBvciBqUXVlcnkgY29sbGVjdGlvblxuXHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0ID0gcy5jb250ZXh0ICYmXG5cdFx0XHRcdCggY2FsbGJhY2tDb250ZXh0Lm5vZGVUeXBlIHx8IGNhbGxiYWNrQ29udGV4dC5qcXVlcnkgKSA/XG5cdFx0XHRcdFx0alF1ZXJ5KCBjYWxsYmFja0NvbnRleHQgKSA6XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LFxuXG5cdFx0XHQvLyBEZWZlcnJlZHNcblx0XHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCksXG5cdFx0XHRjb21wbGV0ZURlZmVycmVkID0galF1ZXJ5LkNhbGxiYWNrcyggXCJvbmNlIG1lbW9yeVwiICksXG5cblx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRzdGF0dXNDb2RlID0gcy5zdGF0dXNDb2RlIHx8IHt9LFxuXG5cdFx0XHQvLyBIZWFkZXJzICh0aGV5IGFyZSBzZW50IGFsbCBhdCBvbmNlKVxuXHRcdFx0cmVxdWVzdEhlYWRlcnMgPSB7fSxcblx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXMgPSB7fSxcblxuXHRcdFx0Ly8gRGVmYXVsdCBhYm9ydCBtZXNzYWdlXG5cdFx0XHRzdHJBYm9ydCA9IFwiY2FuY2VsZWRcIixcblxuXHRcdFx0Ly8gRmFrZSB4aHJcblx0XHRcdGpxWEhSID0ge1xuXHRcdFx0XHRyZWFkeVN0YXRlOiAwLFxuXG5cdFx0XHRcdC8vIEJ1aWxkcyBoZWFkZXJzIGhhc2h0YWJsZSBpZiBuZWVkZWRcblx0XHRcdFx0Z2V0UmVzcG9uc2VIZWFkZXI6IGZ1bmN0aW9uKCBrZXkgKSB7XG5cdFx0XHRcdFx0dmFyIG1hdGNoO1xuXHRcdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRcdFx0aWYgKCAhcmVzcG9uc2VIZWFkZXJzICkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnMgPSB7fTtcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG1hdGNoID0gcmhlYWRlcnMuZXhlYyggcmVzcG9uc2VIZWFkZXJzU3RyaW5nICkgKSApIHtcblx0XHRcdFx0XHRcdFx0XHRyZXNwb25zZUhlYWRlcnNbIG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKSArIFwiIFwiIF0gPVxuXHRcdFx0XHRcdFx0XHRcdFx0KCByZXNwb25zZUhlYWRlcnNbIG1hdGNoWyAxIF0udG9Mb3dlckNhc2UoKSArIFwiIFwiIF0gfHwgW10gKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuY29uY2F0KCBtYXRjaFsgMiBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdG1hdGNoID0gcmVzcG9uc2VIZWFkZXJzWyBrZXkudG9Mb3dlckNhc2UoKSArIFwiIFwiIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiBtYXRjaCA9PSBudWxsID8gbnVsbCA6IG1hdGNoLmpvaW4oIFwiLCBcIiApO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIFJhdyBzdHJpbmdcblx0XHRcdFx0Z2V0QWxsUmVzcG9uc2VIZWFkZXJzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gY29tcGxldGVkID8gcmVzcG9uc2VIZWFkZXJzU3RyaW5nIDogbnVsbDtcblx0XHRcdFx0fSxcblxuXHRcdFx0XHQvLyBDYWNoZXMgdGhlIGhlYWRlclxuXHRcdFx0XHRzZXRSZXF1ZXN0SGVhZGVyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0XHRcdFx0aWYgKCBjb21wbGV0ZWQgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRcdG5hbWUgPSByZXF1ZXN0SGVhZGVyc05hbWVzWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSA9XG5cdFx0XHRcdFx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXNbIG5hbWUudG9Mb3dlckNhc2UoKSBdIHx8IG5hbWU7XG5cdFx0XHRcdFx0XHRyZXF1ZXN0SGVhZGVyc1sgbmFtZSBdID0gdmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIE92ZXJyaWRlcyByZXNwb25zZSBjb250ZW50LXR5cGUgaGVhZGVyXG5cdFx0XHRcdG92ZXJyaWRlTWltZVR5cGU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdFx0XHRcdGlmICggY29tcGxldGVkID09IG51bGwgKSB7XG5cdFx0XHRcdFx0XHRzLm1pbWVUeXBlID0gdHlwZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdFx0c3RhdHVzQ29kZTogZnVuY3Rpb24oIG1hcCApIHtcblx0XHRcdFx0XHR2YXIgY29kZTtcblx0XHRcdFx0XHRpZiAoIG1hcCApIHtcblx0XHRcdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEV4ZWN1dGUgdGhlIGFwcHJvcHJpYXRlIGNhbGxiYWNrc1xuXHRcdFx0XHRcdFx0XHRqcVhIUi5hbHdheXMoIG1hcFsganFYSFIuc3RhdHVzIF0gKTtcblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gTGF6eS1hZGQgdGhlIG5ldyBjYWxsYmFja3MgaW4gYSB3YXkgdGhhdCBwcmVzZXJ2ZXMgb2xkIG9uZXNcblx0XHRcdFx0XHRcdFx0Zm9yICggY29kZSBpbiBtYXAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c3RhdHVzQ29kZVsgY29kZSBdID0gWyBzdGF0dXNDb2RlWyBjb2RlIF0sIG1hcFsgY29kZSBdIF07XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gQ2FuY2VsIHRoZSByZXF1ZXN0XG5cdFx0XHRcdGFib3J0OiBmdW5jdGlvbiggc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHR2YXIgZmluYWxUZXh0ID0gc3RhdHVzVGV4dCB8fCBzdHJBYm9ydDtcblx0XHRcdFx0XHRpZiAoIHRyYW5zcG9ydCApIHtcblx0XHRcdFx0XHRcdHRyYW5zcG9ydC5hYm9ydCggZmluYWxUZXh0ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRvbmUoIDAsIGZpbmFsVGV4dCApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0Ly8gQXR0YWNoIGRlZmVycmVkc1xuXHRcdGRlZmVycmVkLnByb21pc2UoIGpxWEhSICk7XG5cblx0XHQvLyBBZGQgcHJvdG9jb2wgaWYgbm90IHByb3ZpZGVkIChwcmVmaWx0ZXJzIG1pZ2h0IGV4cGVjdCBpdClcblx0XHQvLyBIYW5kbGUgZmFsc3kgdXJsIGluIHRoZSBzZXR0aW5ncyBvYmplY3QgKCMxMDA5MzogY29uc2lzdGVuY3kgd2l0aCBvbGQgc2lnbmF0dXJlKVxuXHRcdC8vIFdlIGFsc28gdXNlIHRoZSB1cmwgcGFyYW1ldGVyIGlmIGF2YWlsYWJsZVxuXHRcdHMudXJsID0gKCAoIHVybCB8fCBzLnVybCB8fCBsb2NhdGlvbi5ocmVmICkgKyBcIlwiIClcblx0XHRcdC5yZXBsYWNlKCBycHJvdG9jb2wsIGxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICk7XG5cblx0XHQvLyBBbGlhcyBtZXRob2Qgb3B0aW9uIHRvIHR5cGUgYXMgcGVyIHRpY2tldCAjMTIwMDRcblx0XHRzLnR5cGUgPSBvcHRpb25zLm1ldGhvZCB8fCBvcHRpb25zLnR5cGUgfHwgcy5tZXRob2QgfHwgcy50eXBlO1xuXG5cdFx0Ly8gRXh0cmFjdCBkYXRhVHlwZXMgbGlzdFxuXHRcdHMuZGF0YVR5cGVzID0gKCBzLmRhdGFUeXBlIHx8IFwiKlwiICkudG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdGh0bWx3aGl0ZSApIHx8IFsgXCJcIiBdO1xuXG5cdFx0Ly8gQSBjcm9zcy1kb21haW4gcmVxdWVzdCBpcyBpbiBvcmRlciB3aGVuIHRoZSBvcmlnaW4gZG9lc24ndCBtYXRjaCB0aGUgY3VycmVudCBvcmlnaW4uXG5cdFx0aWYgKCBzLmNyb3NzRG9tYWluID09IG51bGwgKSB7XG5cdFx0XHR1cmxBbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImFcIiApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTggLSAxMSwgRWRnZSAxMiAtIDE1XG5cdFx0XHQvLyBJRSB0aHJvd3MgZXhjZXB0aW9uIG9uIGFjY2Vzc2luZyB0aGUgaHJlZiBwcm9wZXJ0eSBpZiB1cmwgaXMgbWFsZm9ybWVkLFxuXHRcdFx0Ly8gZS5nLiBodHRwOi8vZXhhbXBsZS5jb206ODB4L1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0dXJsQW5jaG9yLmhyZWYgPSBzLnVybDtcblxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTggLSAxMSBvbmx5XG5cdFx0XHRcdC8vIEFuY2hvcidzIGhvc3QgcHJvcGVydHkgaXNuJ3QgY29ycmVjdGx5IHNldCB3aGVuIHMudXJsIGlzIHJlbGF0aXZlXG5cdFx0XHRcdHVybEFuY2hvci5ocmVmID0gdXJsQW5jaG9yLmhyZWY7XG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSBvcmlnaW5BbmNob3IucHJvdG9jb2wgKyBcIi8vXCIgKyBvcmlnaW5BbmNob3IuaG9zdCAhPT1cblx0XHRcdFx0XHR1cmxBbmNob3IucHJvdG9jb2wgKyBcIi8vXCIgKyB1cmxBbmNob3IuaG9zdDtcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXG5cdFx0XHRcdC8vIElmIHRoZXJlIGlzIGFuIGVycm9yIHBhcnNpbmcgdGhlIFVSTCwgYXNzdW1lIGl0IGlzIGNyb3NzRG9tYWluLFxuXHRcdFx0XHQvLyBpdCBjYW4gYmUgcmVqZWN0ZWQgYnkgdGhlIHRyYW5zcG9ydCBpZiBpdCBpcyBpbnZhbGlkXG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgZGF0YSBpZiBub3QgYWxyZWFkeSBhIHN0cmluZ1xuXHRcdGlmICggcy5kYXRhICYmIHMucHJvY2Vzc0RhdGEgJiYgdHlwZW9mIHMuZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHMuZGF0YSA9IGpRdWVyeS5wYXJhbSggcy5kYXRhLCBzLnRyYWRpdGlvbmFsICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcHJlZmlsdGVyc1xuXHRcdGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBwcmVmaWx0ZXJzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xuXG5cdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYSBwcmVmaWx0ZXIsIHN0b3AgdGhlcmVcblx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdHJldHVybiBqcVhIUjtcblx0XHR9XG5cblx0XHQvLyBXZSBjYW4gZmlyZSBnbG9iYWwgZXZlbnRzIGFzIG9mIG5vdyBpZiBhc2tlZCB0b1xuXHRcdC8vIERvbid0IGZpcmUgZXZlbnRzIGlmIGpRdWVyeS5ldmVudCBpcyB1bmRlZmluZWQgaW4gYW4gQU1ELXVzYWdlIHNjZW5hcmlvICgjMTUxMTgpXG5cdFx0ZmlyZUdsb2JhbHMgPSBqUXVlcnkuZXZlbnQgJiYgcy5nbG9iYWw7XG5cblx0XHQvLyBXYXRjaCBmb3IgYSBuZXcgc2V0IG9mIHJlcXVlc3RzXG5cdFx0aWYgKCBmaXJlR2xvYmFscyAmJiBqUXVlcnkuYWN0aXZlKysgPT09IDAgKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggXCJhamF4U3RhcnRcIiApO1xuXHRcdH1cblxuXHRcdC8vIFVwcGVyY2FzZSB0aGUgdHlwZVxuXHRcdHMudHlwZSA9IHMudHlwZS50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0Ly8gRGV0ZXJtaW5lIGlmIHJlcXVlc3QgaGFzIGNvbnRlbnRcblx0XHRzLmhhc0NvbnRlbnQgPSAhcm5vQ29udGVudC50ZXN0KCBzLnR5cGUgKTtcblxuXHRcdC8vIFNhdmUgdGhlIFVSTCBpbiBjYXNlIHdlJ3JlIHRveWluZyB3aXRoIHRoZSBJZi1Nb2RpZmllZC1TaW5jZVxuXHRcdC8vIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciBsYXRlciBvblxuXHRcdC8vIFJlbW92ZSBoYXNoIHRvIHNpbXBsaWZ5IHVybCBtYW5pcHVsYXRpb25cblx0XHRjYWNoZVVSTCA9IHMudXJsLnJlcGxhY2UoIHJoYXNoLCBcIlwiICk7XG5cblx0XHQvLyBNb3JlIG9wdGlvbnMgaGFuZGxpbmcgZm9yIHJlcXVlc3RzIHdpdGggbm8gY29udGVudFxuXHRcdGlmICggIXMuaGFzQ29udGVudCApIHtcblxuXHRcdFx0Ly8gUmVtZW1iZXIgdGhlIGhhc2ggc28gd2UgY2FuIHB1dCBpdCBiYWNrXG5cdFx0XHR1bmNhY2hlZCA9IHMudXJsLnNsaWNlKCBjYWNoZVVSTC5sZW5ndGggKTtcblxuXHRcdFx0Ly8gSWYgZGF0YSBpcyBhdmFpbGFibGUgYW5kIHNob3VsZCBiZSBwcm9jZXNzZWQsIGFwcGVuZCBkYXRhIHRvIHVybFxuXHRcdFx0aWYgKCBzLmRhdGEgJiYgKCBzLnByb2Nlc3NEYXRhIHx8IHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgKSApIHtcblx0XHRcdFx0Y2FjaGVVUkwgKz0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuZGF0YTtcblxuXHRcdFx0XHQvLyAjOTY4MjogcmVtb3ZlIGRhdGEgc28gdGhhdCBpdCdzIG5vdCB1c2VkIGluIGFuIGV2ZW50dWFsIHJldHJ5XG5cdFx0XHRcdGRlbGV0ZSBzLmRhdGE7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBvciB1cGRhdGUgYW50aS1jYWNoZSBwYXJhbSBpZiBuZWVkZWRcblx0XHRcdGlmICggcy5jYWNoZSA9PT0gZmFsc2UgKSB7XG5cdFx0XHRcdGNhY2hlVVJMID0gY2FjaGVVUkwucmVwbGFjZSggcmFudGlDYWNoZSwgXCIkMVwiICk7XG5cdFx0XHRcdHVuY2FjaGVkID0gKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIFwiXz1cIiArICggbm9uY2UuZ3VpZCsrICkgK1xuXHRcdFx0XHRcdHVuY2FjaGVkO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBQdXQgaGFzaCBhbmQgYW50aS1jYWNoZSBvbiB0aGUgVVJMIHRoYXQgd2lsbCBiZSByZXF1ZXN0ZWQgKGdoLTE3MzIpXG5cdFx0XHRzLnVybCA9IGNhY2hlVVJMICsgdW5jYWNoZWQ7XG5cblx0XHQvLyBDaGFuZ2UgJyUyMCcgdG8gJysnIGlmIHRoaXMgaXMgZW5jb2RlZCBmb3JtIGJvZHkgY29udGVudCAoZ2gtMjY1OClcblx0XHR9IGVsc2UgaWYgKCBzLmRhdGEgJiYgcy5wcm9jZXNzRGF0YSAmJlxuXHRcdFx0KCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKS5pbmRleE9mKCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiICkgPT09IDAgKSB7XG5cdFx0XHRzLmRhdGEgPSBzLmRhdGEucmVwbGFjZSggcjIwLCBcIitcIiApO1xuXHRcdH1cblxuXHRcdC8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuXG5cdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XG5cdFx0XHRpZiAoIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKSB7XG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTW9kaWZpZWQtU2luY2VcIiwgalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApIHtcblx0XHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJJZi1Ob25lLU1hdGNoXCIsIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBjb3JyZWN0IGhlYWRlciwgaWYgZGF0YSBpcyBiZWluZyBzZW50XG5cdFx0aWYgKCBzLmRhdGEgJiYgcy5oYXNDb250ZW50ICYmIHMuY29udGVudFR5cGUgIT09IGZhbHNlIHx8IG9wdGlvbnMuY29udGVudFR5cGUgKSB7XG5cdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIkNvbnRlbnQtVHlwZVwiLCBzLmNvbnRlbnRUeXBlICk7XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBBY2NlcHRzIGhlYWRlciBmb3IgdGhlIHNlcnZlciwgZGVwZW5kaW5nIG9uIHRoZSBkYXRhVHlwZVxuXHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoXG5cdFx0XHRcIkFjY2VwdFwiLFxuXHRcdFx0cy5kYXRhVHlwZXNbIDAgXSAmJiBzLmFjY2VwdHNbIHMuZGF0YVR5cGVzWyAwIF0gXSA/XG5cdFx0XHRcdHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbIDAgXSBdICtcblx0XHRcdFx0XHQoIHMuZGF0YVR5cGVzWyAwIF0gIT09IFwiKlwiID8gXCIsIFwiICsgYWxsVHlwZXMgKyBcIjsgcT0wLjAxXCIgOiBcIlwiICkgOlxuXHRcdFx0XHRzLmFjY2VwdHNbIFwiKlwiIF1cblx0XHQpO1xuXG5cdFx0Ly8gQ2hlY2sgZm9yIGhlYWRlcnMgb3B0aW9uXG5cdFx0Zm9yICggaSBpbiBzLmhlYWRlcnMgKSB7XG5cdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBpLCBzLmhlYWRlcnNbIGkgXSApO1xuXHRcdH1cblxuXHRcdC8vIEFsbG93IGN1c3RvbSBoZWFkZXJzL21pbWV0eXBlcyBhbmQgZWFybHkgYWJvcnRcblx0XHRpZiAoIHMuYmVmb3JlU2VuZCAmJlxuXHRcdFx0KCBzLmJlZm9yZVNlbmQuY2FsbCggY2FsbGJhY2tDb250ZXh0LCBqcVhIUiwgcyApID09PSBmYWxzZSB8fCBjb21wbGV0ZWQgKSApIHtcblxuXHRcdFx0Ly8gQWJvcnQgaWYgbm90IGRvbmUgYWxyZWFkeSBhbmQgcmV0dXJuXG5cdFx0XHRyZXR1cm4ganFYSFIuYWJvcnQoKTtcblx0XHR9XG5cblx0XHQvLyBBYm9ydGluZyBpcyBubyBsb25nZXIgYSBjYW5jZWxsYXRpb25cblx0XHRzdHJBYm9ydCA9IFwiYWJvcnRcIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tzIG9uIGRlZmVycmVkc1xuXHRcdGNvbXBsZXRlRGVmZXJyZWQuYWRkKCBzLmNvbXBsZXRlICk7XG5cdFx0anFYSFIuZG9uZSggcy5zdWNjZXNzICk7XG5cdFx0anFYSFIuZmFpbCggcy5lcnJvciApO1xuXG5cdFx0Ly8gR2V0IHRyYW5zcG9ydFxuXHRcdHRyYW5zcG9ydCA9IGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xuXG5cdFx0Ly8gSWYgbm8gdHJhbnNwb3J0LCB3ZSBhdXRvLWFib3J0XG5cdFx0aWYgKCAhdHJhbnNwb3J0ICkge1xuXHRcdFx0ZG9uZSggLTEsIFwiTm8gVHJhbnNwb3J0XCIgKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IDE7XG5cblx0XHRcdC8vIFNlbmQgZ2xvYmFsIGV2ZW50XG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggXCJhamF4U2VuZFwiLCBbIGpxWEhSLCBzIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYWpheFNlbmQsIHN0b3AgdGhlcmVcblx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRyZXR1cm4ganFYSFI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFRpbWVvdXRcblx0XHRcdGlmICggcy5hc3luYyAmJiBzLnRpbWVvdXQgPiAwICkge1xuXHRcdFx0XHR0aW1lb3V0VGltZXIgPSB3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0anFYSFIuYWJvcnQoIFwidGltZW91dFwiICk7XG5cdFx0XHRcdH0sIHMudGltZW91dCApO1xuXHRcdFx0fVxuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb21wbGV0ZWQgPSBmYWxzZTtcblx0XHRcdFx0dHJhbnNwb3J0LnNlbmQoIHJlcXVlc3RIZWFkZXJzLCBkb25lICk7XG5cdFx0XHR9IGNhdGNoICggZSApIHtcblxuXHRcdFx0XHQvLyBSZXRocm93IHBvc3QtY29tcGxldGlvbiBleGNlcHRpb25zXG5cdFx0XHRcdGlmICggY29tcGxldGVkICkge1xuXHRcdFx0XHRcdHRocm93IGU7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBQcm9wYWdhdGUgb3RoZXJzIGFzIHJlc3VsdHNcblx0XHRcdFx0ZG9uZSggLTEsIGUgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWxsYmFjayBmb3Igd2hlbiBldmVyeXRoaW5nIGlzIGRvbmVcblx0XHRmdW5jdGlvbiBkb25lKCBzdGF0dXMsIG5hdGl2ZVN0YXR1c1RleHQsIHJlc3BvbnNlcywgaGVhZGVycyApIHtcblx0XHRcdHZhciBpc1N1Y2Nlc3MsIHN1Y2Nlc3MsIGVycm9yLCByZXNwb25zZSwgbW9kaWZpZWQsXG5cdFx0XHRcdHN0YXR1c1RleHQgPSBuYXRpdmVTdGF0dXNUZXh0O1xuXG5cdFx0XHQvLyBJZ25vcmUgcmVwZWF0IGludm9jYXRpb25zXG5cdFx0XHRpZiAoIGNvbXBsZXRlZCApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRjb21wbGV0ZWQgPSB0cnVlO1xuXG5cdFx0XHQvLyBDbGVhciB0aW1lb3V0IGlmIGl0IGV4aXN0c1xuXHRcdFx0aWYgKCB0aW1lb3V0VGltZXIgKSB7XG5cdFx0XHRcdHdpbmRvdy5jbGVhclRpbWVvdXQoIHRpbWVvdXRUaW1lciApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBEZXJlZmVyZW5jZSB0cmFuc3BvcnQgZm9yIGVhcmx5IGdhcmJhZ2UgY29sbGVjdGlvblxuXHRcdFx0Ly8gKG5vIG1hdHRlciBob3cgbG9uZyB0aGUganFYSFIgb2JqZWN0IHdpbGwgYmUgdXNlZClcblx0XHRcdHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcblxuXHRcdFx0Ly8gQ2FjaGUgcmVzcG9uc2UgaGVhZGVyc1xuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nID0gaGVhZGVycyB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTZXQgcmVhZHlTdGF0ZVxuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IHN0YXR1cyA+IDAgPyA0IDogMDtcblxuXHRcdFx0Ly8gRGV0ZXJtaW5lIGlmIHN1Y2Nlc3NmdWxcblx0XHRcdGlzU3VjY2VzcyA9IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwIHx8IHN0YXR1cyA9PT0gMzA0O1xuXG5cdFx0XHQvLyBHZXQgcmVzcG9uc2UgZGF0YVxuXHRcdFx0aWYgKCByZXNwb25zZXMgKSB7XG5cdFx0XHRcdHJlc3BvbnNlID0gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBVc2UgYSBub29wIGNvbnZlcnRlciBmb3IgbWlzc2luZyBzY3JpcHRcblx0XHRcdGlmICggIWlzU3VjY2VzcyAmJiBqUXVlcnkuaW5BcnJheSggXCJzY3JpcHRcIiwgcy5kYXRhVHlwZXMgKSA+IC0xICkge1xuXHRcdFx0XHRzLmNvbnZlcnRlcnNbIFwidGV4dCBzY3JpcHRcIiBdID0gZnVuY3Rpb24oKSB7fTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29udmVydCBubyBtYXR0ZXIgd2hhdCAodGhhdCB3YXkgcmVzcG9uc2VYWFggZmllbGRzIGFyZSBhbHdheXMgc2V0KVxuXHRcdFx0cmVzcG9uc2UgPSBhamF4Q29udmVydCggcywgcmVzcG9uc2UsIGpxWEhSLCBpc1N1Y2Nlc3MgKTtcblxuXHRcdFx0Ly8gSWYgc3VjY2Vzc2Z1bCwgaGFuZGxlIHR5cGUgY2hhaW5pbmdcblx0XHRcdGlmICggaXNTdWNjZXNzICkge1xuXG5cdFx0XHRcdC8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuXG5cdFx0XHRcdGlmICggcy5pZk1vZGlmaWVkICkge1xuXHRcdFx0XHRcdG1vZGlmaWVkID0ganFYSFIuZ2V0UmVzcG9uc2VIZWFkZXIoIFwiTGFzdC1Nb2RpZmllZFwiICk7XG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlciggXCJldGFnXCIgKTtcblx0XHRcdFx0XHRpZiAoIG1vZGlmaWVkICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBpZiBubyBjb250ZW50XG5cdFx0XHRcdGlmICggc3RhdHVzID09PSAyMDQgfHwgcy50eXBlID09PSBcIkhFQURcIiApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJub2NvbnRlbnRcIjtcblxuXHRcdFx0XHQvLyBpZiBub3QgbW9kaWZpZWRcblx0XHRcdFx0fSBlbHNlIGlmICggc3RhdHVzID09PSAzMDQgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm90bW9kaWZpZWRcIjtcblxuXHRcdFx0XHQvLyBJZiB3ZSBoYXZlIGRhdGEsIGxldCdzIGNvbnZlcnQgaXRcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gcmVzcG9uc2Uuc3RhdGU7XG5cdFx0XHRcdFx0c3VjY2VzcyA9IHJlc3BvbnNlLmRhdGE7XG5cdFx0XHRcdFx0ZXJyb3IgPSByZXNwb25zZS5lcnJvcjtcblx0XHRcdFx0XHRpc1N1Y2Nlc3MgPSAhZXJyb3I7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0Ly8gRXh0cmFjdCBlcnJvciBmcm9tIHN0YXR1c1RleHQgYW5kIG5vcm1hbGl6ZSBmb3Igbm9uLWFib3J0c1xuXHRcdFx0XHRlcnJvciA9IHN0YXR1c1RleHQ7XG5cdFx0XHRcdGlmICggc3RhdHVzIHx8ICFzdGF0dXNUZXh0ICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcImVycm9yXCI7XG5cdFx0XHRcdFx0aWYgKCBzdGF0dXMgPCAwICkge1xuXHRcdFx0XHRcdFx0c3RhdHVzID0gMDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8gU2V0IGRhdGEgZm9yIHRoZSBmYWtlIHhociBvYmplY3Rcblx0XHRcdGpxWEhSLnN0YXR1cyA9IHN0YXR1cztcblx0XHRcdGpxWEhSLnN0YXR1c1RleHQgPSAoIG5hdGl2ZVN0YXR1c1RleHQgfHwgc3RhdHVzVGV4dCApICsgXCJcIjtcblxuXHRcdFx0Ly8gU3VjY2Vzcy9FcnJvclxuXHRcdFx0aWYgKCBpc1N1Y2Nlc3MgKSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsgc3VjY2Vzcywgc3RhdHVzVGV4dCwganFYSFIgXSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZGVmZXJyZWQucmVqZWN0V2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIGpxWEhSLCBzdGF0dXNUZXh0LCBlcnJvciBdICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRqcVhIUi5zdGF0dXNDb2RlKCBzdGF0dXNDb2RlICk7XG5cdFx0XHRzdGF0dXNDb2RlID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xuXHRcdFx0XHRnbG9iYWxFdmVudENvbnRleHQudHJpZ2dlciggaXNTdWNjZXNzID8gXCJhamF4U3VjY2Vzc1wiIDogXCJhamF4RXJyb3JcIixcblx0XHRcdFx0XHRbIGpxWEhSLCBzLCBpc1N1Y2Nlc3MgPyBzdWNjZXNzIDogZXJyb3IgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb21wbGV0ZVxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZC5maXJlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIGpxWEhSLCBzdGF0dXNUZXh0IF0gKTtcblxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIFwiYWpheENvbXBsZXRlXCIsIFsganFYSFIsIHMgXSApO1xuXG5cdFx0XHRcdC8vIEhhbmRsZSB0aGUgZ2xvYmFsIEFKQVggY291bnRlclxuXHRcdFx0XHRpZiAoICEoIC0talF1ZXJ5LmFjdGl2ZSApICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCBcImFqYXhTdG9wXCIgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBqcVhIUjtcblx0fSxcblxuXHRnZXRKU09OOiBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCBkYXRhLCBjYWxsYmFjaywgXCJqc29uXCIgKTtcblx0fSxcblxuXHRnZXRTY3JpcHQ6IGZ1bmN0aW9uKCB1cmwsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIHVuZGVmaW5lZCwgY2FsbGJhY2ssIFwic2NyaXB0XCIgKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCggWyBcImdldFwiLCBcInBvc3RcIiBdLCBmdW5jdGlvbiggX2ksIG1ldGhvZCApIHtcblx0alF1ZXJ5WyBtZXRob2QgXSA9IGZ1bmN0aW9uKCB1cmwsIGRhdGEsIGNhbGxiYWNrLCB0eXBlICkge1xuXG5cdFx0Ly8gU2hpZnQgYXJndW1lbnRzIGlmIGRhdGEgYXJndW1lbnQgd2FzIG9taXR0ZWRcblx0XHRpZiAoIGlzRnVuY3Rpb24oIGRhdGEgKSApIHtcblx0XHRcdHR5cGUgPSB0eXBlIHx8IGNhbGxiYWNrO1xuXHRcdFx0Y2FsbGJhY2sgPSBkYXRhO1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHQvLyBUaGUgdXJsIGNhbiBiZSBhbiBvcHRpb25zIG9iamVjdCAod2hpY2ggdGhlbiBtdXN0IGhhdmUgLnVybClcblx0XHRyZXR1cm4galF1ZXJ5LmFqYXgoIGpRdWVyeS5leHRlbmQoIHtcblx0XHRcdHVybDogdXJsLFxuXHRcdFx0dHlwZTogbWV0aG9kLFxuXHRcdFx0ZGF0YVR5cGU6IHR5cGUsXG5cdFx0XHRkYXRhOiBkYXRhLFxuXHRcdFx0c3VjY2VzczogY2FsbGJhY2tcblx0XHR9LCBqUXVlcnkuaXNQbGFpbk9iamVjdCggdXJsICkgJiYgdXJsICkgKTtcblx0fTtcbn0gKTtcblxualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIGZ1bmN0aW9uKCBzICkge1xuXHR2YXIgaTtcblx0Zm9yICggaSBpbiBzLmhlYWRlcnMgKSB7XG5cdFx0aWYgKCBpLnRvTG93ZXJDYXNlKCkgPT09IFwiY29udGVudC10eXBlXCIgKSB7XG5cdFx0XHRzLmNvbnRlbnRUeXBlID0gcy5oZWFkZXJzWyBpIF0gfHwgXCJcIjtcblx0XHR9XG5cdH1cbn0gKTtcblxuXG5qUXVlcnkuX2V2YWxVcmwgPSBmdW5jdGlvbiggdXJsLCBvcHRpb25zLCBkb2MgKSB7XG5cdHJldHVybiBqUXVlcnkuYWpheCgge1xuXHRcdHVybDogdXJsLFxuXG5cdFx0Ly8gTWFrZSB0aGlzIGV4cGxpY2l0LCBzaW5jZSB1c2VyIGNhbiBvdmVycmlkZSB0aGlzIHRocm91Z2ggYWpheFNldHVwICgjMTEyNjQpXG5cdFx0dHlwZTogXCJHRVRcIixcblx0XHRkYXRhVHlwZTogXCJzY3JpcHRcIixcblx0XHRjYWNoZTogdHJ1ZSxcblx0XHRhc3luYzogZmFsc2UsXG5cdFx0Z2xvYmFsOiBmYWxzZSxcblxuXHRcdC8vIE9ubHkgZXZhbHVhdGUgdGhlIHJlc3BvbnNlIGlmIGl0IGlzIHN1Y2Nlc3NmdWwgKGdoLTQxMjYpXG5cdFx0Ly8gZGF0YUZpbHRlciBpcyBub3QgaW52b2tlZCBmb3IgZmFpbHVyZSByZXNwb25zZXMsIHNvIHVzaW5nIGl0IGluc3RlYWRcblx0XHQvLyBvZiB0aGUgZGVmYXVsdCBjb252ZXJ0ZXIgaXMga2x1ZGd5IGJ1dCBpdCB3b3Jrcy5cblx0XHRjb252ZXJ0ZXJzOiB7XG5cdFx0XHRcInRleHQgc2NyaXB0XCI6IGZ1bmN0aW9uKCkge31cblx0XHR9LFxuXHRcdGRhdGFGaWx0ZXI6IGZ1bmN0aW9uKCByZXNwb25zZSApIHtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCByZXNwb25zZSwgb3B0aW9ucywgZG9jICk7XG5cdFx0fVxuXHR9ICk7XG59O1xuXG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblx0d3JhcEFsbDogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0dmFyIHdyYXA7XG5cblx0XHRpZiAoIHRoaXNbIDAgXSApIHtcblx0XHRcdGlmICggaXNGdW5jdGlvbiggaHRtbCApICkge1xuXHRcdFx0XHRodG1sID0gaHRtbC5jYWxsKCB0aGlzWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVGhlIGVsZW1lbnRzIHRvIHdyYXAgdGhlIHRhcmdldCBhcm91bmRcblx0XHRcdHdyYXAgPSBqUXVlcnkoIGh0bWwsIHRoaXNbIDAgXS5vd25lckRvY3VtZW50ICkuZXEoIDAgKS5jbG9uZSggdHJ1ZSApO1xuXG5cdFx0XHRpZiAoIHRoaXNbIDAgXS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR3cmFwLmluc2VydEJlZm9yZSggdGhpc1sgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHdyYXAubWFwKCBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGVsZW0gPSB0aGlzO1xuXG5cdFx0XHRcdHdoaWxlICggZWxlbS5maXJzdEVsZW1lbnRDaGlsZCApIHtcblx0XHRcdFx0XHRlbGVtID0gZWxlbS5maXJzdEVsZW1lbnRDaGlsZDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBlbGVtO1xuXHRcdFx0fSApLmFwcGVuZCggdGhpcyApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHdyYXBJbm5lcjogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcElubmVyKCBodG1sLmNhbGwoIHRoaXMsIGkgKSApO1xuXHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHNlbGYgPSBqUXVlcnkoIHRoaXMgKSxcblx0XHRcdFx0Y29udGVudHMgPSBzZWxmLmNvbnRlbnRzKCk7XG5cblx0XHRcdGlmICggY29udGVudHMubGVuZ3RoICkge1xuXHRcdFx0XHRjb250ZW50cy53cmFwQWxsKCBodG1sICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHNlbGYuYXBwZW5kKCBodG1sICk7XG5cdFx0XHR9XG5cdFx0fSApO1xuXHR9LFxuXG5cdHdyYXA6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciBodG1sSXNGdW5jdGlvbiA9IGlzRnVuY3Rpb24oIGh0bWwgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaHRtbElzRnVuY3Rpb24gPyBodG1sLmNhbGwoIHRoaXMsIGkgKSA6IGh0bWwgKTtcblx0XHR9ICk7XG5cdH0sXG5cblx0dW53cmFwOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dGhpcy5wYXJlbnQoIHNlbGVjdG9yICkubm90KCBcImJvZHlcIiApLmVhY2goIGZ1bmN0aW9uKCkge1xuXHRcdFx0alF1ZXJ5KCB0aGlzICkucmVwbGFjZVdpdGgoIHRoaXMuY2hpbGROb2RlcyApO1xuXHRcdH0gKTtcblx0XHRyZXR1cm4gdGhpcztcblx0fVxufSApO1xuXG5cbmpRdWVyeS5leHByLnBzZXVkb3MuaGlkZGVuID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiAhalF1ZXJ5LmV4cHIucHNldWRvcy52aXNpYmxlKCBlbGVtICk7XG59O1xualF1ZXJ5LmV4cHIucHNldWRvcy52aXNpYmxlID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiAhISggZWxlbS5vZmZzZXRXaWR0aCB8fCBlbGVtLm9mZnNldEhlaWdodCB8fCBlbGVtLmdldENsaWVudFJlY3RzKCkubGVuZ3RoICk7XG59O1xuXG5cblxuXG5qUXVlcnkuYWpheFNldHRpbmdzLnhociA9IGZ1bmN0aW9uKCkge1xuXHR0cnkge1xuXHRcdHJldHVybiBuZXcgd2luZG93LlhNTEh0dHBSZXF1ZXN0KCk7XG5cdH0gY2F0Y2ggKCBlICkge31cbn07XG5cbnZhciB4aHJTdWNjZXNzU3RhdHVzID0ge1xuXG5cdFx0Ly8gRmlsZSBwcm90b2NvbCBhbHdheXMgeWllbGRzIHN0YXR1cyBjb2RlIDAsIGFzc3VtZSAyMDBcblx0XHQwOiAyMDAsXG5cblx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdC8vICMxNDUwOiBzb21ldGltZXMgSUUgcmV0dXJucyAxMjIzIHdoZW4gaXQgc2hvdWxkIGJlIDIwNFxuXHRcdDEyMjM6IDIwNFxuXHR9LFxuXHR4aHJTdXBwb3J0ZWQgPSBqUXVlcnkuYWpheFNldHRpbmdzLnhocigpO1xuXG5zdXBwb3J0LmNvcnMgPSAhIXhoclN1cHBvcnRlZCAmJiAoIFwid2l0aENyZWRlbnRpYWxzXCIgaW4geGhyU3VwcG9ydGVkICk7XG5zdXBwb3J0LmFqYXggPSB4aHJTdXBwb3J0ZWQgPSAhIXhoclN1cHBvcnRlZDtcblxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoIGZ1bmN0aW9uKCBvcHRpb25zICkge1xuXHR2YXIgY2FsbGJhY2ssIGVycm9yQ2FsbGJhY2s7XG5cblx0Ly8gQ3Jvc3MgZG9tYWluIG9ubHkgYWxsb3dlZCBpZiBzdXBwb3J0ZWQgdGhyb3VnaCBYTUxIdHRwUmVxdWVzdFxuXHRpZiAoIHN1cHBvcnQuY29ycyB8fCB4aHJTdXBwb3J0ZWQgJiYgIW9wdGlvbnMuY3Jvc3NEb21haW4gKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBoZWFkZXJzLCBjb21wbGV0ZSApIHtcblx0XHRcdFx0dmFyIGksXG5cdFx0XHRcdFx0eGhyID0gb3B0aW9ucy54aHIoKTtcblxuXHRcdFx0XHR4aHIub3Blbihcblx0XHRcdFx0XHRvcHRpb25zLnR5cGUsXG5cdFx0XHRcdFx0b3B0aW9ucy51cmwsXG5cdFx0XHRcdFx0b3B0aW9ucy5hc3luYyxcblx0XHRcdFx0XHRvcHRpb25zLnVzZXJuYW1lLFxuXHRcdFx0XHRcdG9wdGlvbnMucGFzc3dvcmRcblx0XHRcdFx0KTtcblxuXHRcdFx0XHQvLyBBcHBseSBjdXN0b20gZmllbGRzIGlmIHByb3ZpZGVkXG5cdFx0XHRcdGlmICggb3B0aW9ucy54aHJGaWVsZHMgKSB7XG5cdFx0XHRcdFx0Zm9yICggaSBpbiBvcHRpb25zLnhockZpZWxkcyApIHtcblx0XHRcdFx0XHRcdHhoclsgaSBdID0gb3B0aW9ucy54aHJGaWVsZHNbIGkgXTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBPdmVycmlkZSBtaW1lIHR5cGUgaWYgbmVlZGVkXG5cdFx0XHRcdGlmICggb3B0aW9ucy5taW1lVHlwZSAmJiB4aHIub3ZlcnJpZGVNaW1lVHlwZSApIHtcblx0XHRcdFx0XHR4aHIub3ZlcnJpZGVNaW1lVHlwZSggb3B0aW9ucy5taW1lVHlwZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gWC1SZXF1ZXN0ZWQtV2l0aCBoZWFkZXJcblx0XHRcdFx0Ly8gRm9yIGNyb3NzLWRvbWFpbiByZXF1ZXN0cywgc2VlaW5nIGFzIGNvbmRpdGlvbnMgZm9yIGEgcHJlZmxpZ2h0IGFyZVxuXHRcdFx0XHQvLyBha2luIHRvIGEgamlnc2F3IHB1enpsZSwgd2Ugc2ltcGx5IG5ldmVyIHNldCBpdCB0byBiZSBzdXJlLlxuXHRcdFx0XHQvLyAoaXQgY2FuIGFsd2F5cyBiZSBzZXQgb24gYSBwZXItcmVxdWVzdCBiYXNpcyBvciBldmVuIHVzaW5nIGFqYXhTZXR1cClcblx0XHRcdFx0Ly8gRm9yIHNhbWUtZG9tYWluIHJlcXVlc3RzLCB3b24ndCBjaGFuZ2UgaGVhZGVyIGlmIGFscmVhZHkgcHJvdmlkZWQuXG5cdFx0XHRcdGlmICggIW9wdGlvbnMuY3Jvc3NEb21haW4gJiYgIWhlYWRlcnNbIFwiWC1SZXF1ZXN0ZWQtV2l0aFwiIF0gKSB7XG5cdFx0XHRcdFx0aGVhZGVyc1sgXCJYLVJlcXVlc3RlZC1XaXRoXCIgXSA9IFwiWE1MSHR0cFJlcXVlc3RcIjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIFNldCBoZWFkZXJzXG5cdFx0XHRcdGZvciAoIGkgaW4gaGVhZGVycyApIHtcblx0XHRcdFx0XHR4aHIuc2V0UmVxdWVzdEhlYWRlciggaSwgaGVhZGVyc1sgaSBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBDYWxsYmFja1xuXHRcdFx0XHRjYWxsYmFjayA9IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdFx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdGNhbGxiYWNrID0gZXJyb3JDYWxsYmFjayA9IHhoci5vbmxvYWQgPVxuXHRcdFx0XHRcdFx0XHRcdHhoci5vbmVycm9yID0geGhyLm9uYWJvcnQgPSB4aHIub250aW1lb3V0ID1cblx0XHRcdFx0XHRcdFx0XHRcdHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xuXG5cdFx0XHRcdFx0XHRcdGlmICggdHlwZSA9PT0gXCJhYm9ydFwiICkge1xuXHRcdFx0XHRcdFx0XHRcdHhoci5hYm9ydCgpO1xuXHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCB0eXBlID09PSBcImVycm9yXCIgKSB7XG5cblx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdFx0XHRcdFx0XHRcdC8vIE9uIGEgbWFudWFsIG5hdGl2ZSBhYm9ydCwgSUU5IHRocm93c1xuXHRcdFx0XHRcdFx0XHRcdC8vIGVycm9ycyBvbiBhbnkgcHJvcGVydHkgYWNjZXNzIHRoYXQgaXMgbm90IHJlYWR5U3RhdGVcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHR5cGVvZiB4aHIuc3RhdHVzICE9PSBcIm51bWJlclwiICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIDAsIFwiZXJyb3JcIiApO1xuXHRcdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjb21wbGV0ZShcblxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBGaWxlOiBwcm90b2NvbCBhbHdheXMgeWllbGRzIHN0YXR1cyAwOyBzZWUgIzg2MDUsICMxNDIwN1xuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dFxuXHRcdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHJTdWNjZXNzU3RhdHVzWyB4aHIuc3RhdHVzIF0gfHwgeGhyLnN0YXR1cyxcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXNUZXh0LFxuXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8PTkgb25seVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSUU5IGhhcyBubyBYSFIyIGJ1dCB0aHJvd3Mgb24gYmluYXJ5ICh0cmFjLTExNDI2KVxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gRm9yIFhIUjIgbm9uLXRleHQsIGxldCB0aGUgY2FsbGVyIGhhbmRsZSBpdCAoZ2gtMjQ5OClcblx0XHRcdFx0XHRcdFx0XHRcdCggeGhyLnJlc3BvbnNlVHlwZSB8fCBcInRleHRcIiApICE9PSBcInRleHRcIiAgfHxcblx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiB4aHIucmVzcG9uc2VUZXh0ICE9PSBcInN0cmluZ1wiID9cblx0XHRcdFx0XHRcdFx0XHRcdFx0eyBiaW5hcnk6IHhoci5yZXNwb25zZSB9IDpcblx0XHRcdFx0XHRcdFx0XHRcdFx0eyB0ZXh0OiB4aHIucmVzcG9uc2VUZXh0IH0sXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKClcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fTtcblxuXHRcdFx0XHQvLyBMaXN0ZW4gdG8gZXZlbnRzXG5cdFx0XHRcdHhoci5vbmxvYWQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHRlcnJvckNhbGxiYWNrID0geGhyLm9uZXJyb3IgPSB4aHIub250aW1lb3V0ID0gY2FsbGJhY2soIFwiZXJyb3JcIiApO1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDkgb25seVxuXHRcdFx0XHQvLyBVc2Ugb25yZWFkeXN0YXRlY2hhbmdlIHRvIHJlcGxhY2Ugb25hYm9ydFxuXHRcdFx0XHQvLyB0byBoYW5kbGUgdW5jYXVnaHQgYWJvcnRzXG5cdFx0XHRcdGlmICggeGhyLm9uYWJvcnQgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHR4aHIub25hYm9ydCA9IGVycm9yQ2FsbGJhY2s7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0eGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xuXG5cdFx0XHRcdFx0XHQvLyBDaGVjayByZWFkeVN0YXRlIGJlZm9yZSB0aW1lb3V0IGFzIGl0IGNoYW5nZXNcblx0XHRcdFx0XHRcdGlmICggeGhyLnJlYWR5U3RhdGUgPT09IDQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gQWxsb3cgb25lcnJvciB0byBiZSBjYWxsZWQgZmlyc3QsXG5cdFx0XHRcdFx0XHRcdC8vIGJ1dCB0aGF0IHdpbGwgbm90IGhhbmRsZSBhIG5hdGl2ZSBhYm9ydFxuXHRcdFx0XHRcdFx0XHQvLyBBbHNvLCBzYXZlIGVycm9yQ2FsbGJhY2sgdG8gYSB2YXJpYWJsZVxuXHRcdFx0XHRcdFx0XHQvLyBhcyB4aHIub25lcnJvciBjYW5ub3QgYmUgYWNjZXNzZWRcblx0XHRcdFx0XHRcdFx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRlcnJvckNhbGxiYWNrKCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9ICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIENyZWF0ZSB0aGUgYWJvcnQgY2FsbGJhY2tcblx0XHRcdFx0Y2FsbGJhY2sgPSBjYWxsYmFjayggXCJhYm9ydFwiICk7XG5cblx0XHRcdFx0dHJ5IHtcblxuXHRcdFx0XHRcdC8vIERvIHNlbmQgdGhlIHJlcXVlc3QgKHRoaXMgbWF5IHJhaXNlIGFuIGV4Y2VwdGlvbilcblx0XHRcdFx0XHR4aHIuc2VuZCggb3B0aW9ucy5oYXNDb250ZW50ICYmIG9wdGlvbnMuZGF0YSB8fCBudWxsICk7XG5cdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXG5cdFx0XHRcdFx0Ly8gIzE0NjgzOiBPbmx5IHJldGhyb3cgaWYgdGhpcyBoYXNuJ3QgYmVlbiBub3RpZmllZCBhcyBhbiBlcnJvciB5ZXRcblx0XHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xuXHRcdFx0XHRcdFx0dGhyb3cgZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cblx0XHRcdGFib3J0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufSApO1xuXG5cblxuXG4vLyBQcmV2ZW50IGF1dG8tZXhlY3V0aW9uIG9mIHNjcmlwdHMgd2hlbiBubyBleHBsaWNpdCBkYXRhVHlwZSB3YXMgcHJvdmlkZWQgKFNlZSBnaC0yNDMyKVxualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIGZ1bmN0aW9uKCBzICkge1xuXHRpZiAoIHMuY3Jvc3NEb21haW4gKSB7XG5cdFx0cy5jb250ZW50cy5zY3JpcHQgPSBmYWxzZTtcblx0fVxufSApO1xuXG4vLyBJbnN0YWxsIHNjcmlwdCBkYXRhVHlwZVxualF1ZXJ5LmFqYXhTZXR1cCgge1xuXHRhY2NlcHRzOiB7XG5cdFx0c2NyaXB0OiBcInRleHQvamF2YXNjcmlwdCwgYXBwbGljYXRpb24vamF2YXNjcmlwdCwgXCIgK1xuXHRcdFx0XCJhcHBsaWNhdGlvbi9lY21hc2NyaXB0LCBhcHBsaWNhdGlvbi94LWVjbWFzY3JpcHRcIlxuXHR9LFxuXHRjb250ZW50czoge1xuXHRcdHNjcmlwdDogL1xcYig/OmphdmF8ZWNtYSlzY3JpcHRcXGIvXG5cdH0sXG5cdGNvbnZlcnRlcnM6IHtcblx0XHRcInRleHQgc2NyaXB0XCI6IGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIHRleHQgKTtcblx0XHRcdHJldHVybiB0ZXh0O1xuXHRcdH1cblx0fVxufSApO1xuXG4vLyBIYW5kbGUgY2FjaGUncyBzcGVjaWFsIGNhc2UgYW5kIGNyb3NzRG9tYWluXG5qUXVlcnkuYWpheFByZWZpbHRlciggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XG5cdGlmICggcy5jYWNoZSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdHMuY2FjaGUgPSBmYWxzZTtcblx0fVxuXHRpZiAoIHMuY3Jvc3NEb21haW4gKSB7XG5cdFx0cy50eXBlID0gXCJHRVRcIjtcblx0fVxufSApO1xuXG4vLyBCaW5kIHNjcmlwdCB0YWcgaGFjayB0cmFuc3BvcnRcbmpRdWVyeS5hamF4VHJhbnNwb3J0KCBcInNjcmlwdFwiLCBmdW5jdGlvbiggcyApIHtcblxuXHQvLyBUaGlzIHRyYW5zcG9ydCBvbmx5IGRlYWxzIHdpdGggY3Jvc3MgZG9tYWluIG9yIGZvcmNlZC1ieS1hdHRycyByZXF1ZXN0c1xuXHRpZiAoIHMuY3Jvc3NEb21haW4gfHwgcy5zY3JpcHRBdHRycyApIHtcblx0XHR2YXIgc2NyaXB0LCBjYWxsYmFjaztcblx0XHRyZXR1cm4ge1xuXHRcdFx0c2VuZDogZnVuY3Rpb24oIF8sIGNvbXBsZXRlICkge1xuXHRcdFx0XHRzY3JpcHQgPSBqUXVlcnkoIFwiPHNjcmlwdD5cIiApXG5cdFx0XHRcdFx0LmF0dHIoIHMuc2NyaXB0QXR0cnMgfHwge30gKVxuXHRcdFx0XHRcdC5wcm9wKCB7IGNoYXJzZXQ6IHMuc2NyaXB0Q2hhcnNldCwgc3JjOiBzLnVybCB9IClcblx0XHRcdFx0XHQub24oIFwibG9hZCBlcnJvclwiLCBjYWxsYmFjayA9IGZ1bmN0aW9uKCBldnQgKSB7XG5cdFx0XHRcdFx0XHRzY3JpcHQucmVtb3ZlKCk7XG5cdFx0XHRcdFx0XHRjYWxsYmFjayA9IG51bGw7XG5cdFx0XHRcdFx0XHRpZiAoIGV2dCApIHtcblx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIGV2dC50eXBlID09PSBcImVycm9yXCIgPyA0MDQgOiAyMDAsIGV2dC50eXBlICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSApO1xuXG5cdFx0XHRcdC8vIFVzZSBuYXRpdmUgRE9NIG1hbmlwdWxhdGlvbiB0byBhdm9pZCBvdXIgZG9tTWFuaXAgQUpBWCB0cmlja2VyeVxuXHRcdFx0XHRkb2N1bWVudC5oZWFkLmFwcGVuZENoaWxkKCBzY3JpcHRbIDAgXSApO1xuXHRcdFx0fSxcblx0XHRcdGFib3J0OiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufSApO1xuXG5cblxuXG52YXIgb2xkQ2FsbGJhY2tzID0gW10sXG5cdHJqc29ucCA9IC8oPSlcXD8oPz0mfCQpfFxcP1xcPy87XG5cbi8vIERlZmF1bHQganNvbnAgc2V0dGluZ3NcbmpRdWVyeS5hamF4U2V0dXAoIHtcblx0anNvbnA6IFwiY2FsbGJhY2tcIixcblx0anNvbnBDYWxsYmFjazogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGNhbGxiYWNrID0gb2xkQ2FsbGJhY2tzLnBvcCgpIHx8ICggalF1ZXJ5LmV4cGFuZG8gKyBcIl9cIiArICggbm9uY2UuZ3VpZCsrICkgKTtcblx0XHR0aGlzWyBjYWxsYmFjayBdID0gdHJ1ZTtcblx0XHRyZXR1cm4gY2FsbGJhY2s7XG5cdH1cbn0gKTtcblxuLy8gRGV0ZWN0LCBub3JtYWxpemUgb3B0aW9ucyBhbmQgaW5zdGFsbCBjYWxsYmFja3MgZm9yIGpzb25wIHJlcXVlc3RzXG5qUXVlcnkuYWpheFByZWZpbHRlciggXCJqc29uIGpzb25wXCIsIGZ1bmN0aW9uKCBzLCBvcmlnaW5hbFNldHRpbmdzLCBqcVhIUiApIHtcblxuXHR2YXIgY2FsbGJhY2tOYW1lLCBvdmVyd3JpdHRlbiwgcmVzcG9uc2VDb250YWluZXIsXG5cdFx0anNvblByb3AgPSBzLmpzb25wICE9PSBmYWxzZSAmJiAoIHJqc29ucC50ZXN0KCBzLnVybCApID9cblx0XHRcdFwidXJsXCIgOlxuXHRcdFx0dHlwZW9mIHMuZGF0YSA9PT0gXCJzdHJpbmdcIiAmJlxuXHRcdFx0XHQoIHMuY29udGVudFR5cGUgfHwgXCJcIiApXG5cdFx0XHRcdFx0LmluZGV4T2YoIFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXCIgKSA9PT0gMCAmJlxuXHRcdFx0XHRyanNvbnAudGVzdCggcy5kYXRhICkgJiYgXCJkYXRhXCJcblx0XHQpO1xuXG5cdC8vIEhhbmRsZSBpZmYgdGhlIGV4cGVjdGVkIGRhdGEgdHlwZSBpcyBcImpzb25wXCIgb3Igd2UgaGF2ZSBhIHBhcmFtZXRlciB0byBzZXRcblx0aWYgKCBqc29uUHJvcCB8fCBzLmRhdGFUeXBlc1sgMCBdID09PSBcImpzb25wXCIgKSB7XG5cblx0XHQvLyBHZXQgY2FsbGJhY2sgbmFtZSwgcmVtZW1iZXJpbmcgcHJlZXhpc3RpbmcgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGl0XG5cdFx0Y2FsbGJhY2tOYW1lID0gcy5qc29ucENhbGxiYWNrID0gaXNGdW5jdGlvbiggcy5qc29ucENhbGxiYWNrICkgP1xuXHRcdFx0cy5qc29ucENhbGxiYWNrKCkgOlxuXHRcdFx0cy5qc29ucENhbGxiYWNrO1xuXG5cdFx0Ly8gSW5zZXJ0IGNhbGxiYWNrIGludG8gdXJsIG9yIGZvcm0gZGF0YVxuXHRcdGlmICgganNvblByb3AgKSB7XG5cdFx0XHRzWyBqc29uUHJvcCBdID0gc1sganNvblByb3AgXS5yZXBsYWNlKCByanNvbnAsIFwiJDFcIiArIGNhbGxiYWNrTmFtZSApO1xuXHRcdH0gZWxzZSBpZiAoIHMuanNvbnAgIT09IGZhbHNlICkge1xuXHRcdFx0cy51cmwgKz0gKCBycXVlcnkudGVzdCggcy51cmwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuanNvbnAgKyBcIj1cIiArIGNhbGxiYWNrTmFtZTtcblx0XHR9XG5cblx0XHQvLyBVc2UgZGF0YSBjb252ZXJ0ZXIgdG8gcmV0cmlldmUganNvbiBhZnRlciBzY3JpcHQgZXhlY3V0aW9uXG5cdFx0cy5jb252ZXJ0ZXJzWyBcInNjcmlwdCBqc29uXCIgXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCAhcmVzcG9uc2VDb250YWluZXIgKSB7XG5cdFx0XHRcdGpRdWVyeS5lcnJvciggY2FsbGJhY2tOYW1lICsgXCIgd2FzIG5vdCBjYWxsZWRcIiApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJlc3BvbnNlQ29udGFpbmVyWyAwIF07XG5cdFx0fTtcblxuXHRcdC8vIEZvcmNlIGpzb24gZGF0YVR5cGVcblx0XHRzLmRhdGFUeXBlc1sgMCBdID0gXCJqc29uXCI7XG5cblx0XHQvLyBJbnN0YWxsIGNhbGxiYWNrXG5cdFx0b3ZlcndyaXR0ZW4gPSB3aW5kb3dbIGNhbGxiYWNrTmFtZSBdO1xuXHRcdHdpbmRvd1sgY2FsbGJhY2tOYW1lIF0gPSBmdW5jdGlvbigpIHtcblx0XHRcdHJlc3BvbnNlQ29udGFpbmVyID0gYXJndW1lbnRzO1xuXHRcdH07XG5cblx0XHQvLyBDbGVhbi11cCBmdW5jdGlvbiAoZmlyZXMgYWZ0ZXIgY29udmVydGVycylcblx0XHRqcVhIUi5hbHdheXMoIGZ1bmN0aW9uKCkge1xuXG5cdFx0XHQvLyBJZiBwcmV2aW91cyB2YWx1ZSBkaWRuJ3QgZXhpc3QgLSByZW1vdmUgaXRcblx0XHRcdGlmICggb3ZlcndyaXR0ZW4gPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0alF1ZXJ5KCB3aW5kb3cgKS5yZW1vdmVQcm9wKCBjYWxsYmFja05hbWUgKTtcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIHJlc3RvcmUgcHJlZXhpc3RpbmcgdmFsdWVcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHdpbmRvd1sgY2FsbGJhY2tOYW1lIF0gPSBvdmVyd3JpdHRlbjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU2F2ZSBiYWNrIGFzIGZyZWVcblx0XHRcdGlmICggc1sgY2FsbGJhY2tOYW1lIF0gKSB7XG5cblx0XHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgcmUtdXNpbmcgdGhlIG9wdGlvbnMgZG9lc24ndCBzY3JldyB0aGluZ3MgYXJvdW5kXG5cdFx0XHRcdHMuanNvbnBDYWxsYmFjayA9IG9yaWdpbmFsU2V0dGluZ3MuanNvbnBDYWxsYmFjaztcblxuXHRcdFx0XHQvLyBTYXZlIHRoZSBjYWxsYmFjayBuYW1lIGZvciBmdXR1cmUgdXNlXG5cdFx0XHRcdG9sZENhbGxiYWNrcy5wdXNoKCBjYWxsYmFja05hbWUgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FsbCBpZiBpdCB3YXMgYSBmdW5jdGlvbiBhbmQgd2UgaGF2ZSBhIHJlc3BvbnNlXG5cdFx0XHRpZiAoIHJlc3BvbnNlQ29udGFpbmVyICYmIGlzRnVuY3Rpb24oIG92ZXJ3cml0dGVuICkgKSB7XG5cdFx0XHRcdG92ZXJ3cml0dGVuKCByZXNwb25zZUNvbnRhaW5lclsgMCBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHJlc3BvbnNlQ29udGFpbmVyID0gb3ZlcndyaXR0ZW4gPSB1bmRlZmluZWQ7XG5cdFx0fSApO1xuXG5cdFx0Ly8gRGVsZWdhdGUgdG8gc2NyaXB0XG5cdFx0cmV0dXJuIFwic2NyaXB0XCI7XG5cdH1cbn0gKTtcblxuXG5cblxuLy8gU3VwcG9ydDogU2FmYXJpIDggb25seVxuLy8gSW4gU2FmYXJpIDggZG9jdW1lbnRzIGNyZWF0ZWQgdmlhIGRvY3VtZW50LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1bWVudFxuLy8gY29sbGFwc2Ugc2libGluZyBmb3JtczogdGhlIHNlY29uZCBvbmUgYmVjb21lcyBhIGNoaWxkIG9mIHRoZSBmaXJzdCBvbmUuXG4vLyBCZWNhdXNlIG9mIHRoYXQsIHRoaXMgc2VjdXJpdHkgbWVhc3VyZSBoYXMgdG8gYmUgZGlzYWJsZWQgaW4gU2FmYXJpIDguXG4vLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM3MzM3XG5zdXBwb3J0LmNyZWF0ZUhUTUxEb2N1bWVudCA9ICggZnVuY3Rpb24oKSB7XG5cdHZhciBib2R5ID0gZG9jdW1lbnQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCBcIlwiICkuYm9keTtcblx0Ym9keS5pbm5lckhUTUwgPSBcIjxmb3JtPjwvZm9ybT48Zm9ybT48L2Zvcm0+XCI7XG5cdHJldHVybiBib2R5LmNoaWxkTm9kZXMubGVuZ3RoID09PSAyO1xufSApKCk7XG5cblxuLy8gQXJndW1lbnQgXCJkYXRhXCIgc2hvdWxkIGJlIHN0cmluZyBvZiBodG1sXG4vLyBjb250ZXh0IChvcHRpb25hbCk6IElmIHNwZWNpZmllZCwgdGhlIGZyYWdtZW50IHdpbGwgYmUgY3JlYXRlZCBpbiB0aGlzIGNvbnRleHQsXG4vLyBkZWZhdWx0cyB0byBkb2N1bWVudFxuLy8ga2VlcFNjcmlwdHMgKG9wdGlvbmFsKTogSWYgdHJ1ZSwgd2lsbCBpbmNsdWRlIHNjcmlwdHMgcGFzc2VkIGluIHRoZSBodG1sIHN0cmluZ1xualF1ZXJ5LnBhcnNlSFRNTCA9IGZ1bmN0aW9uKCBkYXRhLCBjb250ZXh0LCBrZWVwU2NyaXB0cyApIHtcblx0aWYgKCB0eXBlb2YgZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRyZXR1cm4gW107XG5cdH1cblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0a2VlcFNjcmlwdHMgPSBjb250ZXh0O1xuXHRcdGNvbnRleHQgPSBmYWxzZTtcblx0fVxuXG5cdHZhciBiYXNlLCBwYXJzZWQsIHNjcmlwdHM7XG5cblx0aWYgKCAhY29udGV4dCApIHtcblxuXHRcdC8vIFN0b3Agc2NyaXB0cyBvciBpbmxpbmUgZXZlbnQgaGFuZGxlcnMgZnJvbSBiZWluZyBleGVjdXRlZCBpbW1lZGlhdGVseVxuXHRcdC8vIGJ5IHVzaW5nIGRvY3VtZW50LmltcGxlbWVudGF0aW9uXG5cdFx0aWYgKCBzdXBwb3J0LmNyZWF0ZUhUTUxEb2N1bWVudCApIHtcblx0XHRcdGNvbnRleHQgPSBkb2N1bWVudC5pbXBsZW1lbnRhdGlvbi5jcmVhdGVIVE1MRG9jdW1lbnQoIFwiXCIgKTtcblxuXHRcdFx0Ly8gU2V0IHRoZSBiYXNlIGhyZWYgZm9yIHRoZSBjcmVhdGVkIGRvY3VtZW50XG5cdFx0XHQvLyBzbyBhbnkgcGFyc2VkIGVsZW1lbnRzIHdpdGggVVJMc1xuXHRcdFx0Ly8gYXJlIGJhc2VkIG9uIHRoZSBkb2N1bWVudCdzIFVSTCAoZ2gtMjk2NSlcblx0XHRcdGJhc2UgPSBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoIFwiYmFzZVwiICk7XG5cdFx0XHRiYXNlLmhyZWYgPSBkb2N1bWVudC5sb2NhdGlvbi5ocmVmO1xuXHRcdFx0Y29udGV4dC5oZWFkLmFwcGVuZENoaWxkKCBiYXNlICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnRleHQgPSBkb2N1bWVudDtcblx0XHR9XG5cdH1cblxuXHRwYXJzZWQgPSByc2luZ2xlVGFnLmV4ZWMoIGRhdGEgKTtcblx0c2NyaXB0cyA9ICFrZWVwU2NyaXB0cyAmJiBbXTtcblxuXHQvLyBTaW5nbGUgdGFnXG5cdGlmICggcGFyc2VkICkge1xuXHRcdHJldHVybiBbIGNvbnRleHQuY3JlYXRlRWxlbWVudCggcGFyc2VkWyAxIF0gKSBdO1xuXHR9XG5cblx0cGFyc2VkID0gYnVpbGRGcmFnbWVudCggWyBkYXRhIF0sIGNvbnRleHQsIHNjcmlwdHMgKTtcblxuXHRpZiAoIHNjcmlwdHMgJiYgc2NyaXB0cy5sZW5ndGggKSB7XG5cdFx0alF1ZXJ5KCBzY3JpcHRzICkucmVtb3ZlKCk7XG5cdH1cblxuXHRyZXR1cm4galF1ZXJ5Lm1lcmdlKCBbXSwgcGFyc2VkLmNoaWxkTm9kZXMgKTtcbn07XG5cblxuLyoqXG4gKiBMb2FkIGEgdXJsIGludG8gYSBwYWdlXG4gKi9cbmpRdWVyeS5mbi5sb2FkID0gZnVuY3Rpb24oIHVybCwgcGFyYW1zLCBjYWxsYmFjayApIHtcblx0dmFyIHNlbGVjdG9yLCB0eXBlLCByZXNwb25zZSxcblx0XHRzZWxmID0gdGhpcyxcblx0XHRvZmYgPSB1cmwuaW5kZXhPZiggXCIgXCIgKTtcblxuXHRpZiAoIG9mZiA+IC0xICkge1xuXHRcdHNlbGVjdG9yID0gc3RyaXBBbmRDb2xsYXBzZSggdXJsLnNsaWNlKCBvZmYgKSApO1xuXHRcdHVybCA9IHVybC5zbGljZSggMCwgb2ZmICk7XG5cdH1cblxuXHQvLyBJZiBpdCdzIGEgZnVuY3Rpb25cblx0aWYgKCBpc0Z1bmN0aW9uKCBwYXJhbXMgKSApIHtcblxuXHRcdC8vIFdlIGFzc3VtZSB0aGF0IGl0J3MgdGhlIGNhbGxiYWNrXG5cdFx0Y2FsbGJhY2sgPSBwYXJhbXM7XG5cdFx0cGFyYW1zID0gdW5kZWZpbmVkO1xuXG5cdC8vIE90aGVyd2lzZSwgYnVpbGQgYSBwYXJhbSBzdHJpbmdcblx0fSBlbHNlIGlmICggcGFyYW1zICYmIHR5cGVvZiBwYXJhbXMgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0dHlwZSA9IFwiUE9TVFwiO1xuXHR9XG5cblx0Ly8gSWYgd2UgaGF2ZSBlbGVtZW50cyB0byBtb2RpZnksIG1ha2UgdGhlIHJlcXVlc3Rcblx0aWYgKCBzZWxmLmxlbmd0aCA+IDAgKSB7XG5cdFx0alF1ZXJ5LmFqYXgoIHtcblx0XHRcdHVybDogdXJsLFxuXG5cdFx0XHQvLyBJZiBcInR5cGVcIiB2YXJpYWJsZSBpcyB1bmRlZmluZWQsIHRoZW4gXCJHRVRcIiBtZXRob2Qgd2lsbCBiZSB1c2VkLlxuXHRcdFx0Ly8gTWFrZSB2YWx1ZSBvZiB0aGlzIGZpZWxkIGV4cGxpY2l0IHNpbmNlXG5cdFx0XHQvLyB1c2VyIGNhbiBvdmVycmlkZSBpdCB0aHJvdWdoIGFqYXhTZXR1cCBtZXRob2Rcblx0XHRcdHR5cGU6IHR5cGUgfHwgXCJHRVRcIixcblx0XHRcdGRhdGFUeXBlOiBcImh0bWxcIixcblx0XHRcdGRhdGE6IHBhcmFtc1xuXHRcdH0gKS5kb25lKCBmdW5jdGlvbiggcmVzcG9uc2VUZXh0ICkge1xuXG5cdFx0XHQvLyBTYXZlIHJlc3BvbnNlIGZvciB1c2UgaW4gY29tcGxldGUgY2FsbGJhY2tcblx0XHRcdHJlc3BvbnNlID0gYXJndW1lbnRzO1xuXG5cdFx0XHRzZWxmLmh0bWwoIHNlbGVjdG9yID9cblxuXHRcdFx0XHQvLyBJZiBhIHNlbGVjdG9yIHdhcyBzcGVjaWZpZWQsIGxvY2F0ZSB0aGUgcmlnaHQgZWxlbWVudHMgaW4gYSBkdW1teSBkaXZcblx0XHRcdFx0Ly8gRXhjbHVkZSBzY3JpcHRzIHRvIGF2b2lkIElFICdQZXJtaXNzaW9uIERlbmllZCcgZXJyb3JzXG5cdFx0XHRcdGpRdWVyeSggXCI8ZGl2PlwiICkuYXBwZW5kKCBqUXVlcnkucGFyc2VIVE1MKCByZXNwb25zZVRleHQgKSApLmZpbmQoIHNlbGVjdG9yICkgOlxuXG5cdFx0XHRcdC8vIE90aGVyd2lzZSB1c2UgdGhlIGZ1bGwgcmVzdWx0XG5cdFx0XHRcdHJlc3BvbnNlVGV4dCApO1xuXG5cdFx0Ly8gSWYgdGhlIHJlcXVlc3Qgc3VjY2VlZHMsIHRoaXMgZnVuY3Rpb24gZ2V0cyBcImRhdGFcIiwgXCJzdGF0dXNcIiwgXCJqcVhIUlwiXG5cdFx0Ly8gYnV0IHRoZXkgYXJlIGlnbm9yZWQgYmVjYXVzZSByZXNwb25zZSB3YXMgc2V0IGFib3ZlLlxuXHRcdC8vIElmIGl0IGZhaWxzLCB0aGlzIGZ1bmN0aW9uIGdldHMgXCJqcVhIUlwiLCBcInN0YXR1c1wiLCBcImVycm9yXCJcblx0XHR9ICkuYWx3YXlzKCBjYWxsYmFjayAmJiBmdW5jdGlvbigganFYSFIsIHN0YXR1cyApIHtcblx0XHRcdHNlbGYuZWFjaCggZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGNhbGxiYWNrLmFwcGx5KCB0aGlzLCByZXNwb25zZSB8fCBbIGpxWEhSLnJlc3BvbnNlVGV4dCwgc3RhdHVzLCBqcVhIUiBdICk7XG5cdFx0XHR9ICk7XG5cdFx0fSApO1xuXHR9XG5cblx0cmV0dXJuIHRoaXM7XG59O1xuXG5cblxuXG5qUXVlcnkuZXhwci5wc2V1ZG9zLmFuaW1hdGVkID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiBqUXVlcnkuZ3JlcCggalF1ZXJ5LnRpbWVycywgZnVuY3Rpb24oIGZuICkge1xuXHRcdHJldHVybiBlbGVtID09PSBmbi5lbGVtO1xuXHR9ICkubGVuZ3RoO1xufTtcblxuXG5cblxualF1ZXJ5Lm9mZnNldCA9IHtcblx0c2V0T2Zmc2V0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgaSApIHtcblx0XHR2YXIgY3VyUG9zaXRpb24sIGN1ckxlZnQsIGN1ckNTU1RvcCwgY3VyVG9wLCBjdXJPZmZzZXQsIGN1ckNTU0xlZnQsIGNhbGN1bGF0ZVBvc2l0aW9uLFxuXHRcdFx0cG9zaXRpb24gPSBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSxcblx0XHRcdGN1ckVsZW0gPSBqUXVlcnkoIGVsZW0gKSxcblx0XHRcdHByb3BzID0ge307XG5cblx0XHQvLyBTZXQgcG9zaXRpb24gZmlyc3QsIGluLWNhc2UgdG9wL2xlZnQgYXJlIHNldCBldmVuIG9uIHN0YXRpYyBlbGVtXG5cdFx0aWYgKCBwb3NpdGlvbiA9PT0gXCJzdGF0aWNcIiApIHtcblx0XHRcdGVsZW0uc3R5bGUucG9zaXRpb24gPSBcInJlbGF0aXZlXCI7XG5cdFx0fVxuXG5cdFx0Y3VyT2Zmc2V0ID0gY3VyRWxlbS5vZmZzZXQoKTtcblx0XHRjdXJDU1NUb3AgPSBqUXVlcnkuY3NzKCBlbGVtLCBcInRvcFwiICk7XG5cdFx0Y3VyQ1NTTGVmdCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwibGVmdFwiICk7XG5cdFx0Y2FsY3VsYXRlUG9zaXRpb24gPSAoIHBvc2l0aW9uID09PSBcImFic29sdXRlXCIgfHwgcG9zaXRpb24gPT09IFwiZml4ZWRcIiApICYmXG5cdFx0XHQoIGN1ckNTU1RvcCArIGN1ckNTU0xlZnQgKS5pbmRleE9mKCBcImF1dG9cIiApID4gLTE7XG5cblx0XHQvLyBOZWVkIHRvIGJlIGFibGUgdG8gY2FsY3VsYXRlIHBvc2l0aW9uIGlmIGVpdGhlclxuXHRcdC8vIHRvcCBvciBsZWZ0IGlzIGF1dG8gYW5kIHBvc2l0aW9uIGlzIGVpdGhlciBhYnNvbHV0ZSBvciBmaXhlZFxuXHRcdGlmICggY2FsY3VsYXRlUG9zaXRpb24gKSB7XG5cdFx0XHRjdXJQb3NpdGlvbiA9IGN1ckVsZW0ucG9zaXRpb24oKTtcblx0XHRcdGN1clRvcCA9IGN1clBvc2l0aW9uLnRvcDtcblx0XHRcdGN1ckxlZnQgPSBjdXJQb3NpdGlvbi5sZWZ0O1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1clRvcCA9IHBhcnNlRmxvYXQoIGN1ckNTU1RvcCApIHx8IDA7XG5cdFx0XHRjdXJMZWZ0ID0gcGFyc2VGbG9hdCggY3VyQ1NTTGVmdCApIHx8IDA7XG5cdFx0fVxuXG5cdFx0aWYgKCBpc0Z1bmN0aW9uKCBvcHRpb25zICkgKSB7XG5cblx0XHRcdC8vIFVzZSBqUXVlcnkuZXh0ZW5kIGhlcmUgdG8gYWxsb3cgbW9kaWZpY2F0aW9uIG9mIGNvb3JkaW5hdGVzIGFyZ3VtZW50IChnaC0xODQ4KVxuXHRcdFx0b3B0aW9ucyA9IG9wdGlvbnMuY2FsbCggZWxlbSwgaSwgalF1ZXJ5LmV4dGVuZCgge30sIGN1ck9mZnNldCApICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBvcHRpb25zLnRvcCAhPSBudWxsICkge1xuXHRcdFx0cHJvcHMudG9wID0gKCBvcHRpb25zLnRvcCAtIGN1ck9mZnNldC50b3AgKSArIGN1clRvcDtcblx0XHR9XG5cdFx0aWYgKCBvcHRpb25zLmxlZnQgIT0gbnVsbCApIHtcblx0XHRcdHByb3BzLmxlZnQgPSAoIG9wdGlvbnMubGVmdCAtIGN1ck9mZnNldC5sZWZ0ICkgKyBjdXJMZWZ0O1xuXHRcdH1cblxuXHRcdGlmICggXCJ1c2luZ1wiIGluIG9wdGlvbnMgKSB7XG5cdFx0XHRvcHRpb25zLnVzaW5nLmNhbGwoIGVsZW0sIHByb3BzICk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0aWYgKCB0eXBlb2YgcHJvcHMudG9wID09PSBcIm51bWJlclwiICkge1xuXHRcdFx0XHRwcm9wcy50b3AgKz0gXCJweFwiO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCB0eXBlb2YgcHJvcHMubGVmdCA9PT0gXCJudW1iZXJcIiApIHtcblx0XHRcdFx0cHJvcHMubGVmdCArPSBcInB4XCI7XG5cdFx0XHR9XG5cdFx0XHRjdXJFbGVtLmNzcyggcHJvcHMgKTtcblx0XHR9XG5cdH1cbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoIHtcblxuXHQvLyBvZmZzZXQoKSByZWxhdGVzIGFuIGVsZW1lbnQncyBib3JkZXIgYm94IHRvIHRoZSBkb2N1bWVudCBvcmlnaW5cblx0b2Zmc2V0OiBmdW5jdGlvbiggb3B0aW9ucyApIHtcblxuXHRcdC8vIFByZXNlcnZlIGNoYWluaW5nIGZvciBzZXR0ZXJcblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gb3B0aW9ucyA9PT0gdW5kZWZpbmVkID9cblx0XHRcdFx0dGhpcyA6XG5cdFx0XHRcdHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5Lm9mZnNldC5zZXRPZmZzZXQoIHRoaXMsIG9wdGlvbnMsIGkgKTtcblx0XHRcdFx0fSApO1xuXHRcdH1cblxuXHRcdHZhciByZWN0LCB3aW4sXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdO1xuXG5cdFx0aWYgKCAhZWxlbSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBSZXR1cm4gemVyb3MgZm9yIGRpc2Nvbm5lY3RlZCBhbmQgaGlkZGVuIChkaXNwbGF5OiBub25lKSBlbGVtZW50cyAoZ2gtMjMxMClcblx0XHQvLyBTdXBwb3J0OiBJRSA8PTExIG9ubHlcblx0XHQvLyBSdW5uaW5nIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBvbiBhXG5cdFx0Ly8gZGlzY29ubmVjdGVkIG5vZGUgaW4gSUUgdGhyb3dzIGFuIGVycm9yXG5cdFx0aWYgKCAhZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCApIHtcblx0XHRcdHJldHVybiB7IHRvcDogMCwgbGVmdDogMCB9O1xuXHRcdH1cblxuXHRcdC8vIEdldCBkb2N1bWVudC1yZWxhdGl2ZSBwb3NpdGlvbiBieSBhZGRpbmcgdmlld3BvcnQgc2Nyb2xsIHRvIHZpZXdwb3J0LXJlbGF0aXZlIGdCQ1Jcblx0XHRyZWN0ID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0XHR3aW4gPSBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXc7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogcmVjdC50b3AgKyB3aW4ucGFnZVlPZmZzZXQsXG5cdFx0XHRsZWZ0OiByZWN0LmxlZnQgKyB3aW4ucGFnZVhPZmZzZXRcblx0XHR9O1xuXHR9LFxuXG5cdC8vIHBvc2l0aW9uKCkgcmVsYXRlcyBhbiBlbGVtZW50J3MgbWFyZ2luIGJveCB0byBpdHMgb2Zmc2V0IHBhcmVudCdzIHBhZGRpbmcgYm94XG5cdC8vIFRoaXMgY29ycmVzcG9uZHMgdG8gdGhlIGJlaGF2aW9yIG9mIENTUyBhYnNvbHV0ZSBwb3NpdGlvbmluZ1xuXHRwb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCAhdGhpc1sgMCBdICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHZhciBvZmZzZXRQYXJlbnQsIG9mZnNldCwgZG9jLFxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXSxcblx0XHRcdHBhcmVudE9mZnNldCA9IHsgdG9wOiAwLCBsZWZ0OiAwIH07XG5cblx0XHQvLyBwb3NpdGlvbjpmaXhlZCBlbGVtZW50cyBhcmUgb2Zmc2V0IGZyb20gdGhlIHZpZXdwb3J0LCB3aGljaCBpdHNlbGYgYWx3YXlzIGhhcyB6ZXJvIG9mZnNldFxuXHRcdGlmICggalF1ZXJ5LmNzcyggZWxlbSwgXCJwb3NpdGlvblwiICkgPT09IFwiZml4ZWRcIiApIHtcblxuXHRcdFx0Ly8gQXNzdW1lIHBvc2l0aW9uOmZpeGVkIGltcGxpZXMgYXZhaWxhYmlsaXR5IG9mIGdldEJvdW5kaW5nQ2xpZW50UmVjdFxuXHRcdFx0b2Zmc2V0ID0gZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRvZmZzZXQgPSB0aGlzLm9mZnNldCgpO1xuXG5cdFx0XHQvLyBBY2NvdW50IGZvciB0aGUgKnJlYWwqIG9mZnNldCBwYXJlbnQsIHdoaWNoIGNhbiBiZSB0aGUgZG9jdW1lbnQgb3IgaXRzIHJvb3QgZWxlbWVudFxuXHRcdFx0Ly8gd2hlbiBhIHN0YXRpY2FsbHkgcG9zaXRpb25lZCBlbGVtZW50IGlzIGlkZW50aWZpZWRcblx0XHRcdGRvYyA9IGVsZW0ub3duZXJEb2N1bWVudDtcblx0XHRcdG9mZnNldFBhcmVudCA9IGVsZW0ub2Zmc2V0UGFyZW50IHx8IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG5cdFx0XHR3aGlsZSAoIG9mZnNldFBhcmVudCAmJlxuXHRcdFx0XHQoIG9mZnNldFBhcmVudCA9PT0gZG9jLmJvZHkgfHwgb2Zmc2V0UGFyZW50ID09PSBkb2MuZG9jdW1lbnRFbGVtZW50ICkgJiZcblx0XHRcdFx0alF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcInBvc2l0aW9uXCIgKSA9PT0gXCJzdGF0aWNcIiApIHtcblxuXHRcdFx0XHRvZmZzZXRQYXJlbnQgPSBvZmZzZXRQYXJlbnQucGFyZW50Tm9kZTtcblx0XHRcdH1cblx0XHRcdGlmICggb2Zmc2V0UGFyZW50ICYmIG9mZnNldFBhcmVudCAhPT0gZWxlbSAmJiBvZmZzZXRQYXJlbnQubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHRcdFx0Ly8gSW5jb3Jwb3JhdGUgYm9yZGVycyBpbnRvIGl0cyBvZmZzZXQsIHNpbmNlIHRoZXkgYXJlIG91dHNpZGUgaXRzIGNvbnRlbnQgb3JpZ2luXG5cdFx0XHRcdHBhcmVudE9mZnNldCA9IGpRdWVyeSggb2Zmc2V0UGFyZW50ICkub2Zmc2V0KCk7XG5cdFx0XHRcdHBhcmVudE9mZnNldC50b3AgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcImJvcmRlclRvcFdpZHRoXCIsIHRydWUgKTtcblx0XHRcdFx0cGFyZW50T2Zmc2V0LmxlZnQgKz0galF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcImJvcmRlckxlZnRXaWR0aFwiLCB0cnVlICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU3VidHJhY3QgcGFyZW50IG9mZnNldHMgYW5kIGVsZW1lbnQgbWFyZ2luc1xuXHRcdHJldHVybiB7XG5cdFx0XHR0b3A6IG9mZnNldC50b3AgLSBwYXJlbnRPZmZzZXQudG9wIC0galF1ZXJ5LmNzcyggZWxlbSwgXCJtYXJnaW5Ub3BcIiwgdHJ1ZSApLFxuXHRcdFx0bGVmdDogb2Zmc2V0LmxlZnQgLSBwYXJlbnRPZmZzZXQubGVmdCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luTGVmdFwiLCB0cnVlIClcblx0XHR9O1xuXHR9LFxuXG5cdC8vIFRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuIGRvY3VtZW50RWxlbWVudCBpbiB0aGUgZm9sbG93aW5nIGNhc2VzOlxuXHQvLyAxKSBGb3IgdGhlIGVsZW1lbnQgaW5zaWRlIHRoZSBpZnJhbWUgd2l0aG91dCBvZmZzZXRQYXJlbnQsIHRoaXMgbWV0aG9kIHdpbGwgcmV0dXJuXG5cdC8vICAgIGRvY3VtZW50RWxlbWVudCBvZiB0aGUgcGFyZW50IHdpbmRvd1xuXHQvLyAyKSBGb3IgdGhlIGhpZGRlbiBvciBkZXRhY2hlZCBlbGVtZW50XG5cdC8vIDMpIEZvciBib2R5IG9yIGh0bWwgZWxlbWVudCwgaS5lLiBpbiBjYXNlIG9mIHRoZSBodG1sIG5vZGUgLSBpdCB3aWxsIHJldHVybiBpdHNlbGZcblx0Ly9cblx0Ly8gYnV0IHRob3NlIGV4Y2VwdGlvbnMgd2VyZSBuZXZlciBwcmVzZW50ZWQgYXMgYSByZWFsIGxpZmUgdXNlLWNhc2VzXG5cdC8vIGFuZCBtaWdodCBiZSBjb25zaWRlcmVkIGFzIG1vcmUgcHJlZmVyYWJsZSByZXN1bHRzLlxuXHQvL1xuXHQvLyBUaGlzIGxvZ2ljLCBob3dldmVyLCBpcyBub3QgZ3VhcmFudGVlZCBhbmQgY2FuIGNoYW5nZSBhdCBhbnkgcG9pbnQgaW4gdGhlIGZ1dHVyZVxuXHRvZmZzZXRQYXJlbnQ6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgb2Zmc2V0UGFyZW50ID0gdGhpcy5vZmZzZXRQYXJlbnQ7XG5cblx0XHRcdHdoaWxlICggb2Zmc2V0UGFyZW50ICYmIGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudCwgXCJwb3NpdGlvblwiICkgPT09IFwic3RhdGljXCIgKSB7XG5cdFx0XHRcdG9mZnNldFBhcmVudCA9IG9mZnNldFBhcmVudC5vZmZzZXRQYXJlbnQ7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBvZmZzZXRQYXJlbnQgfHwgZG9jdW1lbnRFbGVtZW50O1xuXHRcdH0gKTtcblx0fVxufSApO1xuXG4vLyBDcmVhdGUgc2Nyb2xsTGVmdCBhbmQgc2Nyb2xsVG9wIG1ldGhvZHNcbmpRdWVyeS5lYWNoKCB7IHNjcm9sbExlZnQ6IFwicGFnZVhPZmZzZXRcIiwgc2Nyb2xsVG9wOiBcInBhZ2VZT2Zmc2V0XCIgfSwgZnVuY3Rpb24oIG1ldGhvZCwgcHJvcCApIHtcblx0dmFyIHRvcCA9IFwicGFnZVlPZmZzZXRcIiA9PT0gcHJvcDtcblxuXHRqUXVlcnkuZm5bIG1ldGhvZCBdID0gZnVuY3Rpb24oIHZhbCApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgbWV0aG9kLCB2YWwgKSB7XG5cblx0XHRcdC8vIENvYWxlc2NlIGRvY3VtZW50cyBhbmQgd2luZG93c1xuXHRcdFx0dmFyIHdpbjtcblx0XHRcdGlmICggaXNXaW5kb3coIGVsZW0gKSApIHtcblx0XHRcdFx0d2luID0gZWxlbTtcblx0XHRcdH0gZWxzZSBpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdHdpbiA9IGVsZW0uZGVmYXVsdFZpZXc7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggdmFsID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiB3aW4gPyB3aW5bIHByb3AgXSA6IGVsZW1bIG1ldGhvZCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHdpbiApIHtcblx0XHRcdFx0d2luLnNjcm9sbFRvKFxuXHRcdFx0XHRcdCF0b3AgPyB2YWwgOiB3aW4ucGFnZVhPZmZzZXQsXG5cdFx0XHRcdFx0dG9wID8gdmFsIDogd2luLnBhZ2VZT2Zmc2V0XG5cdFx0XHRcdCk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1bIG1ldGhvZCBdID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0sIG1ldGhvZCwgdmFsLCBhcmd1bWVudHMubGVuZ3RoICk7XG5cdH07XG59ICk7XG5cbi8vIFN1cHBvcnQ6IFNhZmFyaSA8PTcgLSA5LjEsIENocm9tZSA8PTM3IC0gNDlcbi8vIEFkZCB0aGUgdG9wL2xlZnQgY3NzSG9va3MgdXNpbmcgalF1ZXJ5LmZuLnBvc2l0aW9uXG4vLyBXZWJraXQgYnVnOiBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MjkwODRcbi8vIEJsaW5rIGJ1ZzogaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9NTg5MzQ3XG4vLyBnZXRDb21wdXRlZFN0eWxlIHJldHVybnMgcGVyY2VudCB3aGVuIHNwZWNpZmllZCBmb3IgdG9wL2xlZnQvYm90dG9tL3JpZ2h0O1xuLy8gcmF0aGVyIHRoYW4gbWFrZSB0aGUgY3NzIG1vZHVsZSBkZXBlbmQgb24gdGhlIG9mZnNldCBtb2R1bGUsIGp1c3QgY2hlY2sgZm9yIGl0IGhlcmVcbmpRdWVyeS5lYWNoKCBbIFwidG9wXCIsIFwibGVmdFwiIF0sIGZ1bmN0aW9uKCBfaSwgcHJvcCApIHtcblx0alF1ZXJ5LmNzc0hvb2tzWyBwcm9wIF0gPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucGl4ZWxQb3NpdGlvbixcblx0XHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xuXHRcdFx0XHRjb21wdXRlZCA9IGN1ckNTUyggZWxlbSwgcHJvcCApO1xuXG5cdFx0XHRcdC8vIElmIGN1ckNTUyByZXR1cm5zIHBlcmNlbnRhZ2UsIGZhbGxiYWNrIHRvIG9mZnNldFxuXHRcdFx0XHRyZXR1cm4gcm51bW5vbnB4LnRlc3QoIGNvbXB1dGVkICkgP1xuXHRcdFx0XHRcdGpRdWVyeSggZWxlbSApLnBvc2l0aW9uKClbIHByb3AgXSArIFwicHhcIiA6XG5cdFx0XHRcdFx0Y29tcHV0ZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHQpO1xufSApO1xuXG5cbi8vIENyZWF0ZSBpbm5lckhlaWdodCwgaW5uZXJXaWR0aCwgaGVpZ2h0LCB3aWR0aCwgb3V0ZXJIZWlnaHQgYW5kIG91dGVyV2lkdGggbWV0aG9kc1xualF1ZXJ5LmVhY2goIHsgSGVpZ2h0OiBcImhlaWdodFwiLCBXaWR0aDogXCJ3aWR0aFwiIH0sIGZ1bmN0aW9uKCBuYW1lLCB0eXBlICkge1xuXHRqUXVlcnkuZWFjaCggeyBwYWRkaW5nOiBcImlubmVyXCIgKyBuYW1lLCBjb250ZW50OiB0eXBlLCBcIlwiOiBcIm91dGVyXCIgKyBuYW1lIH0sXG5cdFx0ZnVuY3Rpb24oIGRlZmF1bHRFeHRyYSwgZnVuY05hbWUgKSB7XG5cblx0XHQvLyBNYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGhcblx0XHRqUXVlcnkuZm5bIGZ1bmNOYW1lIF0gPSBmdW5jdGlvbiggbWFyZ2luLCB2YWx1ZSApIHtcblx0XHRcdHZhciBjaGFpbmFibGUgPSBhcmd1bWVudHMubGVuZ3RoICYmICggZGVmYXVsdEV4dHJhIHx8IHR5cGVvZiBtYXJnaW4gIT09IFwiYm9vbGVhblwiICksXG5cdFx0XHRcdGV4dHJhID0gZGVmYXVsdEV4dHJhIHx8ICggbWFyZ2luID09PSB0cnVlIHx8IHZhbHVlID09PSB0cnVlID8gXCJtYXJnaW5cIiA6IFwiYm9yZGVyXCIgKTtcblxuXHRcdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIHR5cGUsIHZhbHVlICkge1xuXHRcdFx0XHR2YXIgZG9jO1xuXG5cdFx0XHRcdGlmICggaXNXaW5kb3coIGVsZW0gKSApIHtcblxuXHRcdFx0XHRcdC8vICQoIHdpbmRvdyApLm91dGVyV2lkdGgvSGVpZ2h0IHJldHVybiB3L2ggaW5jbHVkaW5nIHNjcm9sbGJhcnMgKGdoLTE3MjkpXG5cdFx0XHRcdFx0cmV0dXJuIGZ1bmNOYW1lLmluZGV4T2YoIFwib3V0ZXJcIiApID09PSAwID9cblx0XHRcdFx0XHRcdGVsZW1bIFwiaW5uZXJcIiArIG5hbWUgXSA6XG5cdFx0XHRcdFx0XHRlbGVtLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFsgXCJjbGllbnRcIiArIG5hbWUgXTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEdldCBkb2N1bWVudCB3aWR0aCBvciBoZWlnaHRcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHRcdGRvYyA9IGVsZW0uZG9jdW1lbnRFbGVtZW50O1xuXG5cdFx0XHRcdFx0Ly8gRWl0aGVyIHNjcm9sbFtXaWR0aC9IZWlnaHRdIG9yIG9mZnNldFtXaWR0aC9IZWlnaHRdIG9yIGNsaWVudFtXaWR0aC9IZWlnaHRdLFxuXHRcdFx0XHRcdC8vIHdoaWNoZXZlciBpcyBncmVhdGVzdFxuXHRcdFx0XHRcdHJldHVybiBNYXRoLm1heChcblx0XHRcdFx0XHRcdGVsZW0uYm9keVsgXCJzY3JvbGxcIiArIG5hbWUgXSwgZG9jWyBcInNjcm9sbFwiICsgbmFtZSBdLFxuXHRcdFx0XHRcdFx0ZWxlbS5ib2R5WyBcIm9mZnNldFwiICsgbmFtZSBdLCBkb2NbIFwib2Zmc2V0XCIgKyBuYW1lIF0sXG5cdFx0XHRcdFx0XHRkb2NbIFwiY2xpZW50XCIgKyBuYW1lIF1cblx0XHRcdFx0XHQpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWQgP1xuXG5cdFx0XHRcdFx0Ly8gR2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudCwgcmVxdWVzdGluZyBidXQgbm90IGZvcmNpbmcgcGFyc2VGbG9hdFxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIHR5cGUsIGV4dHJhICkgOlxuXG5cdFx0XHRcdFx0Ly8gU2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudFxuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgdHlwZSwgdmFsdWUsIGV4dHJhICk7XG5cdFx0XHR9LCB0eXBlLCBjaGFpbmFibGUgPyBtYXJnaW4gOiB1bmRlZmluZWQsIGNoYWluYWJsZSApO1xuXHRcdH07XG5cdH0gKTtcbn0gKTtcblxuXG5qUXVlcnkuZWFjaCggW1xuXHRcImFqYXhTdGFydFwiLFxuXHRcImFqYXhTdG9wXCIsXG5cdFwiYWpheENvbXBsZXRlXCIsXG5cdFwiYWpheEVycm9yXCIsXG5cdFwiYWpheFN1Y2Nlc3NcIixcblx0XCJhamF4U2VuZFwiXG5dLCBmdW5jdGlvbiggX2ksIHR5cGUgKSB7XG5cdGpRdWVyeS5mblsgdHlwZSBdID0gZnVuY3Rpb24oIGZuICkge1xuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlLCBmbiApO1xuXHR9O1xufSApO1xuXG5cblxuXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XG5cblx0YmluZDogZnVuY3Rpb24oIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIG51bGwsIGRhdGEsIGZuICk7XG5cdH0sXG5cdHVuYmluZDogZnVuY3Rpb24oIHR5cGVzLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYoIHR5cGVzLCBudWxsLCBmbiApO1xuXHR9LFxuXG5cdGRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApO1xuXHR9LFxuXHR1bmRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBmbiApIHtcblxuXHRcdC8vICggbmFtZXNwYWNlICkgb3IgKCBzZWxlY3RvciwgdHlwZXMgWywgZm5dIClcblx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/XG5cdFx0XHR0aGlzLm9mZiggc2VsZWN0b3IsIFwiKipcIiApIDpcblx0XHRcdHRoaXMub2ZmKCB0eXBlcywgc2VsZWN0b3IgfHwgXCIqKlwiLCBmbiApO1xuXHR9LFxuXG5cdGhvdmVyOiBmdW5jdGlvbiggZm5PdmVyLCBmbk91dCApIHtcblx0XHRyZXR1cm4gdGhpcy5tb3VzZWVudGVyKCBmbk92ZXIgKS5tb3VzZWxlYXZlKCBmbk91dCB8fCBmbk92ZXIgKTtcblx0fVxufSApO1xuXG5qUXVlcnkuZWFjaCggKCBcImJsdXIgZm9jdXMgZm9jdXNpbiBmb2N1c291dCByZXNpemUgc2Nyb2xsIGNsaWNrIGRibGNsaWNrIFwiICtcblx0XCJtb3VzZWRvd24gbW91c2V1cCBtb3VzZW1vdmUgbW91c2VvdmVyIG1vdXNlb3V0IG1vdXNlZW50ZXIgbW91c2VsZWF2ZSBcIiArXG5cdFwiY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBjb250ZXh0bWVudVwiICkuc3BsaXQoIFwiIFwiICksXG5cdGZ1bmN0aW9uKCBfaSwgbmFtZSApIHtcblxuXHRcdC8vIEhhbmRsZSBldmVudCBiaW5kaW5nXG5cdFx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggZGF0YSwgZm4gKSB7XG5cdFx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDAgP1xuXHRcdFx0XHR0aGlzLm9uKCBuYW1lLCBudWxsLCBkYXRhLCBmbiApIDpcblx0XHRcdFx0dGhpcy50cmlnZ2VyKCBuYW1lICk7XG5cdFx0fTtcblx0fSApO1xuXG5cblxuXG4vLyBTdXBwb3J0OiBBbmRyb2lkIDw9NC4wIG9ubHlcbi8vIE1ha2Ugc3VyZSB3ZSB0cmltIEJPTSBhbmQgTkJTUFxudmFyIHJ0cmltID0gL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nO1xuXG4vLyBCaW5kIGEgZnVuY3Rpb24gdG8gYSBjb250ZXh0LCBvcHRpb25hbGx5IHBhcnRpYWxseSBhcHBseWluZyBhbnlcbi8vIGFyZ3VtZW50cy5cbi8vIGpRdWVyeS5wcm94eSBpcyBkZXByZWNhdGVkIHRvIHByb21vdGUgc3RhbmRhcmRzIChzcGVjaWZpY2FsbHkgRnVuY3Rpb24jYmluZClcbi8vIEhvd2V2ZXIsIGl0IGlzIG5vdCBzbGF0ZWQgZm9yIHJlbW92YWwgYW55IHRpbWUgc29vblxualF1ZXJ5LnByb3h5ID0gZnVuY3Rpb24oIGZuLCBjb250ZXh0ICkge1xuXHR2YXIgdG1wLCBhcmdzLCBwcm94eTtcblxuXHRpZiAoIHR5cGVvZiBjb250ZXh0ID09PSBcInN0cmluZ1wiICkge1xuXHRcdHRtcCA9IGZuWyBjb250ZXh0IF07XG5cdFx0Y29udGV4dCA9IGZuO1xuXHRcdGZuID0gdG1wO1xuXHR9XG5cblx0Ly8gUXVpY2sgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRhcmdldCBpcyBjYWxsYWJsZSwgaW4gdGhlIHNwZWNcblx0Ly8gdGhpcyB0aHJvd3MgYSBUeXBlRXJyb3IsIGJ1dCB3ZSB3aWxsIGp1c3QgcmV0dXJuIHVuZGVmaW5lZC5cblx0aWYgKCAhaXNGdW5jdGlvbiggZm4gKSApIHtcblx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHR9XG5cblx0Ly8gU2ltdWxhdGVkIGJpbmRcblx0YXJncyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMiApO1xuXHRwcm94eSA9IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBmbi5hcHBseSggY29udGV4dCB8fCB0aGlzLCBhcmdzLmNvbmNhdCggc2xpY2UuY2FsbCggYXJndW1lbnRzICkgKSApO1xuXHR9O1xuXG5cdC8vIFNldCB0aGUgZ3VpZCBvZiB1bmlxdWUgaGFuZGxlciB0byB0aGUgc2FtZSBvZiBvcmlnaW5hbCBoYW5kbGVyLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZFxuXHRwcm94eS5ndWlkID0gZm4uZ3VpZCA9IGZuLmd1aWQgfHwgalF1ZXJ5Lmd1aWQrKztcblxuXHRyZXR1cm4gcHJveHk7XG59O1xuXG5qUXVlcnkuaG9sZFJlYWR5ID0gZnVuY3Rpb24oIGhvbGQgKSB7XG5cdGlmICggaG9sZCApIHtcblx0XHRqUXVlcnkucmVhZHlXYWl0Kys7XG5cdH0gZWxzZSB7XG5cdFx0alF1ZXJ5LnJlYWR5KCB0cnVlICk7XG5cdH1cbn07XG5qUXVlcnkuaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5qUXVlcnkucGFyc2VKU09OID0gSlNPTi5wYXJzZTtcbmpRdWVyeS5ub2RlTmFtZSA9IG5vZGVOYW1lO1xualF1ZXJ5LmlzRnVuY3Rpb24gPSBpc0Z1bmN0aW9uO1xualF1ZXJ5LmlzV2luZG93ID0gaXNXaW5kb3c7XG5qUXVlcnkuY2FtZWxDYXNlID0gY2FtZWxDYXNlO1xualF1ZXJ5LnR5cGUgPSB0b1R5cGU7XG5cbmpRdWVyeS5ub3cgPSBEYXRlLm5vdztcblxualF1ZXJ5LmlzTnVtZXJpYyA9IGZ1bmN0aW9uKCBvYmogKSB7XG5cblx0Ly8gQXMgb2YgalF1ZXJ5IDMuMCwgaXNOdW1lcmljIGlzIGxpbWl0ZWQgdG9cblx0Ly8gc3RyaW5ncyBhbmQgbnVtYmVycyAocHJpbWl0aXZlcyBvciBvYmplY3RzKVxuXHQvLyB0aGF0IGNhbiBiZSBjb2VyY2VkIHRvIGZpbml0ZSBudW1iZXJzIChnaC0yNjYyKVxuXHR2YXIgdHlwZSA9IGpRdWVyeS50eXBlKCBvYmogKTtcblx0cmV0dXJuICggdHlwZSA9PT0gXCJudW1iZXJcIiB8fCB0eXBlID09PSBcInN0cmluZ1wiICkgJiZcblxuXHRcdC8vIHBhcnNlRmxvYXQgTmFOcyBudW1lcmljLWNhc3QgZmFsc2UgcG9zaXRpdmVzIChcIlwiKVxuXHRcdC8vIC4uLmJ1dCBtaXNpbnRlcnByZXRzIGxlYWRpbmctbnVtYmVyIHN0cmluZ3MsIHBhcnRpY3VsYXJseSBoZXggbGl0ZXJhbHMgKFwiMHguLi5cIilcblx0XHQvLyBzdWJ0cmFjdGlvbiBmb3JjZXMgaW5maW5pdGllcyB0byBOYU5cblx0XHQhaXNOYU4oIG9iaiAtIHBhcnNlRmxvYXQoIG9iaiApICk7XG59O1xuXG5qUXVlcnkudHJpbSA9IGZ1bmN0aW9uKCB0ZXh0ICkge1xuXHRyZXR1cm4gdGV4dCA9PSBudWxsID9cblx0XHRcIlwiIDpcblx0XHQoIHRleHQgKyBcIlwiICkucmVwbGFjZSggcnRyaW0sIFwiXCIgKTtcbn07XG5cblxuXG4vLyBSZWdpc3RlciBhcyBhIG5hbWVkIEFNRCBtb2R1bGUsIHNpbmNlIGpRdWVyeSBjYW4gYmUgY29uY2F0ZW5hdGVkIHdpdGggb3RoZXJcbi8vIGZpbGVzIHRoYXQgbWF5IHVzZSBkZWZpbmUsIGJ1dCBub3QgdmlhIGEgcHJvcGVyIGNvbmNhdGVuYXRpb24gc2NyaXB0IHRoYXRcbi8vIHVuZGVyc3RhbmRzIGFub255bW91cyBBTUQgbW9kdWxlcy4gQSBuYW1lZCBBTUQgaXMgc2FmZXN0IGFuZCBtb3N0IHJvYnVzdFxuLy8gd2F5IHRvIHJlZ2lzdGVyLiBMb3dlcmNhc2UganF1ZXJ5IGlzIHVzZWQgYmVjYXVzZSBBTUQgbW9kdWxlIG5hbWVzIGFyZVxuLy8gZGVyaXZlZCBmcm9tIGZpbGUgbmFtZXMsIGFuZCBqUXVlcnkgaXMgbm9ybWFsbHkgZGVsaXZlcmVkIGluIGEgbG93ZXJjYXNlXG4vLyBmaWxlIG5hbWUuIERvIHRoaXMgYWZ0ZXIgY3JlYXRpbmcgdGhlIGdsb2JhbCBzbyB0aGF0IGlmIGFuIEFNRCBtb2R1bGUgd2FudHNcbi8vIHRvIGNhbGwgbm9Db25mbGljdCB0byBoaWRlIHRoaXMgdmVyc2lvbiBvZiBqUXVlcnksIGl0IHdpbGwgd29yay5cblxuLy8gTm90ZSB0aGF0IGZvciBtYXhpbXVtIHBvcnRhYmlsaXR5LCBsaWJyYXJpZXMgdGhhdCBhcmUgbm90IGpRdWVyeSBzaG91bGRcbi8vIGRlY2xhcmUgdGhlbXNlbHZlcyBhcyBhbm9ueW1vdXMgbW9kdWxlcywgYW5kIGF2b2lkIHNldHRpbmcgYSBnbG9iYWwgaWYgYW5cbi8vIEFNRCBsb2FkZXIgaXMgcHJlc2VudC4galF1ZXJ5IGlzIGEgc3BlY2lhbCBjYXNlLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiwgc2VlXG4vLyBodHRwczovL2dpdGh1Yi5jb20vanJidXJrZS9yZXF1aXJlanMvd2lraS9VcGRhdGluZy1leGlzdGluZy1saWJyYXJpZXMjd2lraS1hbm9uXG5cbmlmICggdHlwZW9mIGRlZmluZSA9PT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQgKSB7XG5cdGRlZmluZSggXCJqcXVlcnlcIiwgW10sIGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBqUXVlcnk7XG5cdH0gKTtcbn1cblxuXG5cblxudmFyXG5cblx0Ly8gTWFwIG92ZXIgalF1ZXJ5IGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF9qUXVlcnkgPSB3aW5kb3cualF1ZXJ5LFxuXG5cdC8vIE1hcCBvdmVyIHRoZSAkIGluIGNhc2Ugb2Ygb3ZlcndyaXRlXG5cdF8kID0gd2luZG93LiQ7XG5cbmpRdWVyeS5ub0NvbmZsaWN0ID0gZnVuY3Rpb24oIGRlZXAgKSB7XG5cdGlmICggd2luZG93LiQgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cuJCA9IF8kO1xuXHR9XG5cblx0aWYgKCBkZWVwICYmIHdpbmRvdy5qUXVlcnkgPT09IGpRdWVyeSApIHtcblx0XHR3aW5kb3cualF1ZXJ5ID0gX2pRdWVyeTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnk7XG59O1xuXG4vLyBFeHBvc2UgalF1ZXJ5IGFuZCAkIGlkZW50aWZpZXJzLCBldmVuIGluIEFNRFxuLy8gKCM3MTAyI2NvbW1lbnQ6MTAsIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvNTU3KVxuLy8gYW5kIENvbW1vbkpTIGZvciBicm93c2VyIGVtdWxhdG9ycyAoIzEzNTY2KVxuaWYgKCB0eXBlb2Ygbm9HbG9iYWwgPT09IFwidW5kZWZpbmVkXCIgKSB7XG5cdHdpbmRvdy5qUXVlcnkgPSB3aW5kb3cuJCA9IGpRdWVyeTtcbn1cblxuXG5cblxucmV0dXJuIGpRdWVyeTtcbn0gKTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgRGF0YVZpZXcgPSBnZXROYXRpdmUocm9vdCwgJ0RhdGFWaWV3Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gRGF0YVZpZXc7XG4iLCJ2YXIgaGFzaENsZWFyID0gcmVxdWlyZSgnLi9faGFzaENsZWFyJyksXG4gICAgaGFzaERlbGV0ZSA9IHJlcXVpcmUoJy4vX2hhc2hEZWxldGUnKSxcbiAgICBoYXNoR2V0ID0gcmVxdWlyZSgnLi9faGFzaEdldCcpLFxuICAgIGhhc2hIYXMgPSByZXF1aXJlKCcuL19oYXNoSGFzJyksXG4gICAgaGFzaFNldCA9IHJlcXVpcmUoJy4vX2hhc2hTZXQnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgaGFzaCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gKi9cbmZ1bmN0aW9uIEhhc2goZW50cmllcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICB0aGlzLmNsZWFyKCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgfVxufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgSGFzaGAuXG5IYXNoLnByb3RvdHlwZS5jbGVhciA9IGhhc2hDbGVhcjtcbkhhc2gucHJvdG90eXBlWydkZWxldGUnXSA9IGhhc2hEZWxldGU7XG5IYXNoLnByb3RvdHlwZS5nZXQgPSBoYXNoR2V0O1xuSGFzaC5wcm90b3R5cGUuaGFzID0gaGFzaEhhcztcbkhhc2gucHJvdG90eXBlLnNldCA9IGhhc2hTZXQ7XG5cbm1vZHVsZS5leHBvcnRzID0gSGFzaDtcbiIsInZhciBiYXNlQ3JlYXRlID0gcmVxdWlyZSgnLi9fYmFzZUNyZWF0ZScpLFxuICAgIGJhc2VMb2Rhc2ggPSByZXF1aXJlKCcuL19iYXNlTG9kYXNoJyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHRoZSBtYXhpbXVtIGxlbmd0aCBhbmQgaW5kZXggb2YgYW4gYXJyYXkuICovXG52YXIgTUFYX0FSUkFZX0xFTkdUSCA9IDQyOTQ5NjcyOTU7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGxhenkgd3JhcHBlciBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgbGF6eSBldmFsdWF0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gKi9cbmZ1bmN0aW9uIExhenlXcmFwcGVyKHZhbHVlKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IFtdO1xuICB0aGlzLl9fZGlyX18gPSAxO1xuICB0aGlzLl9fZmlsdGVyZWRfXyA9IGZhbHNlO1xuICB0aGlzLl9faXRlcmF0ZWVzX18gPSBbXTtcbiAgdGhpcy5fX3Rha2VDb3VudF9fID0gTUFYX0FSUkFZX0xFTkdUSDtcbiAgdGhpcy5fX3ZpZXdzX18gPSBbXTtcbn1cblxuLy8gRW5zdXJlIGBMYXp5V3JhcHBlcmAgaXMgYW4gaW5zdGFuY2Ugb2YgYGJhc2VMb2Rhc2hgLlxuTGF6eVdyYXBwZXIucHJvdG90eXBlID0gYmFzZUNyZWF0ZShiYXNlTG9kYXNoLnByb3RvdHlwZSk7XG5MYXp5V3JhcHBlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBMYXp5V3JhcHBlcjtcblxubW9kdWxlLmV4cG9ydHMgPSBMYXp5V3JhcHBlcjtcbiIsInZhciBsaXN0Q2FjaGVDbGVhciA9IHJlcXVpcmUoJy4vX2xpc3RDYWNoZUNsZWFyJyksXG4gICAgbGlzdENhY2hlRGVsZXRlID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlRGVsZXRlJyksXG4gICAgbGlzdENhY2hlR2V0ID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlR2V0JyksXG4gICAgbGlzdENhY2hlSGFzID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlSGFzJyksXG4gICAgbGlzdENhY2hlU2V0ID0gcmVxdWlyZSgnLi9fbGlzdENhY2hlU2V0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBsaXN0IGNhY2hlIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gTGlzdENhY2hlKGVudHJpZXMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBlbnRyaWVzID09IG51bGwgPyAwIDogZW50cmllcy5sZW5ndGg7XG5cbiAgdGhpcy5jbGVhcigpO1xuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBlbnRyeSA9IGVudHJpZXNbaW5kZXhdO1xuICAgIHRoaXMuc2V0KGVudHJ5WzBdLCBlbnRyeVsxXSk7XG4gIH1cbn1cblxuLy8gQWRkIG1ldGhvZHMgdG8gYExpc3RDYWNoZWAuXG5MaXN0Q2FjaGUucHJvdG90eXBlLmNsZWFyID0gbGlzdENhY2hlQ2xlYXI7XG5MaXN0Q2FjaGUucHJvdG90eXBlWydkZWxldGUnXSA9IGxpc3RDYWNoZURlbGV0ZTtcbkxpc3RDYWNoZS5wcm90b3R5cGUuZ2V0ID0gbGlzdENhY2hlR2V0O1xuTGlzdENhY2hlLnByb3RvdHlwZS5oYXMgPSBsaXN0Q2FjaGVIYXM7XG5MaXN0Q2FjaGUucHJvdG90eXBlLnNldCA9IGxpc3RDYWNoZVNldDtcblxubW9kdWxlLmV4cG9ydHMgPSBMaXN0Q2FjaGU7XG4iLCJ2YXIgYmFzZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX2Jhc2VDcmVhdGUnKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi9fYmFzZUxvZGFzaCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGNvbnN0cnVjdG9yIGZvciBjcmVhdGluZyBgbG9kYXNoYCB3cmFwcGVyIG9iamVjdHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtjaGFpbkFsbF0gRW5hYmxlIGV4cGxpY2l0IG1ldGhvZCBjaGFpbiBzZXF1ZW5jZXMuXG4gKi9cbmZ1bmN0aW9uIExvZGFzaFdyYXBwZXIodmFsdWUsIGNoYWluQWxsKSB7XG4gIHRoaXMuX193cmFwcGVkX18gPSB2YWx1ZTtcbiAgdGhpcy5fX2FjdGlvbnNfXyA9IFtdO1xuICB0aGlzLl9fY2hhaW5fXyA9ICEhY2hhaW5BbGw7XG4gIHRoaXMuX19pbmRleF9fID0gMDtcbiAgdGhpcy5fX3ZhbHVlc19fID0gdW5kZWZpbmVkO1xufVxuXG5Mb2Rhc2hXcmFwcGVyLnByb3RvdHlwZSA9IGJhc2VDcmVhdGUoYmFzZUxvZGFzaC5wcm90b3R5cGUpO1xuTG9kYXNoV3JhcHBlci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBMb2Rhc2hXcmFwcGVyO1xuXG5tb2R1bGUuZXhwb3J0cyA9IExvZGFzaFdyYXBwZXI7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyksXG4gICAgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xudmFyIE1hcCA9IGdldE5hdGl2ZShyb290LCAnTWFwJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gTWFwO1xuIiwidmFyIG1hcENhY2hlQ2xlYXIgPSByZXF1aXJlKCcuL19tYXBDYWNoZUNsZWFyJyksXG4gICAgbWFwQ2FjaGVEZWxldGUgPSByZXF1aXJlKCcuL19tYXBDYWNoZURlbGV0ZScpLFxuICAgIG1hcENhY2hlR2V0ID0gcmVxdWlyZSgnLi9fbWFwQ2FjaGVHZXQnKSxcbiAgICBtYXBDYWNoZUhhcyA9IHJlcXVpcmUoJy4vX21hcENhY2hlSGFzJyksXG4gICAgbWFwQ2FjaGVTZXQgPSByZXF1aXJlKCcuL19tYXBDYWNoZVNldCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBtYXAgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIGtleS12YWx1ZSBwYWlycy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0FycmF5fSBbZW50cmllc10gVGhlIGtleS12YWx1ZSBwYWlycyB0byBjYWNoZS5cbiAqL1xuZnVuY3Rpb24gTWFwQ2FjaGUoZW50cmllcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGVudHJpZXMgPT0gbnVsbCA/IDAgOiBlbnRyaWVzLmxlbmd0aDtcblxuICB0aGlzLmNsZWFyKCk7XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGVudHJ5ID0gZW50cmllc1tpbmRleF07XG4gICAgdGhpcy5zZXQoZW50cnlbMF0sIGVudHJ5WzFdKTtcbiAgfVxufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgTWFwQ2FjaGVgLlxuTWFwQ2FjaGUucHJvdG90eXBlLmNsZWFyID0gbWFwQ2FjaGVDbGVhcjtcbk1hcENhY2hlLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBtYXBDYWNoZURlbGV0ZTtcbk1hcENhY2hlLnByb3RvdHlwZS5nZXQgPSBtYXBDYWNoZUdldDtcbk1hcENhY2hlLnByb3RvdHlwZS5oYXMgPSBtYXBDYWNoZUhhcztcbk1hcENhY2hlLnByb3RvdHlwZS5zZXQgPSBtYXBDYWNoZVNldDtcblxubW9kdWxlLmV4cG9ydHMgPSBNYXBDYWNoZTtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgUHJvbWlzZSA9IGdldE5hdGl2ZShyb290LCAnUHJvbWlzZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IFByb21pc2U7XG4iLCJ2YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnLi9fZ2V0TmF0aXZlJyksXG4gICAgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgdGhhdCBhcmUgdmVyaWZpZWQgdG8gYmUgbmF0aXZlLiAqL1xudmFyIFNldCA9IGdldE5hdGl2ZShyb290LCAnU2V0Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0gU2V0O1xuIiwidmFyIE1hcENhY2hlID0gcmVxdWlyZSgnLi9fTWFwQ2FjaGUnKSxcbiAgICBzZXRDYWNoZUFkZCA9IHJlcXVpcmUoJy4vX3NldENhY2hlQWRkJyksXG4gICAgc2V0Q2FjaGVIYXMgPSByZXF1aXJlKCcuL19zZXRDYWNoZUhhcycpO1xuXG4vKipcbiAqXG4gKiBDcmVhdGVzIGFuIGFycmF5IGNhY2hlIG9iamVjdCB0byBzdG9yZSB1bmlxdWUgdmFsdWVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY2FjaGUuXG4gKi9cbmZ1bmN0aW9uIFNldENhY2hlKHZhbHVlcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHZhbHVlcyA9PSBudWxsID8gMCA6IHZhbHVlcy5sZW5ndGg7XG5cbiAgdGhpcy5fX2RhdGFfXyA9IG5ldyBNYXBDYWNoZTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB0aGlzLmFkZCh2YWx1ZXNbaW5kZXhdKTtcbiAgfVxufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgU2V0Q2FjaGVgLlxuU2V0Q2FjaGUucHJvdG90eXBlLmFkZCA9IFNldENhY2hlLnByb3RvdHlwZS5wdXNoID0gc2V0Q2FjaGVBZGQ7XG5TZXRDYWNoZS5wcm90b3R5cGUuaGFzID0gc2V0Q2FjaGVIYXM7XG5cbm1vZHVsZS5leHBvcnRzID0gU2V0Q2FjaGU7XG4iLCJ2YXIgTGlzdENhY2hlID0gcmVxdWlyZSgnLi9fTGlzdENhY2hlJyksXG4gICAgc3RhY2tDbGVhciA9IHJlcXVpcmUoJy4vX3N0YWNrQ2xlYXInKSxcbiAgICBzdGFja0RlbGV0ZSA9IHJlcXVpcmUoJy4vX3N0YWNrRGVsZXRlJyksXG4gICAgc3RhY2tHZXQgPSByZXF1aXJlKCcuL19zdGFja0dldCcpLFxuICAgIHN0YWNrSGFzID0gcmVxdWlyZSgnLi9fc3RhY2tIYXMnKSxcbiAgICBzdGFja1NldCA9IHJlcXVpcmUoJy4vX3N0YWNrU2V0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHN0YWNrIGNhY2hlIG9iamVjdCB0byBzdG9yZSBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtBcnJheX0gW2VudHJpZXNdIFRoZSBrZXktdmFsdWUgcGFpcnMgdG8gY2FjaGUuXG4gKi9cbmZ1bmN0aW9uIFN0YWNrKGVudHJpZXMpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZShlbnRyaWVzKTtcbiAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xufVxuXG4vLyBBZGQgbWV0aG9kcyB0byBgU3RhY2tgLlxuU3RhY2sucHJvdG90eXBlLmNsZWFyID0gc3RhY2tDbGVhcjtcblN0YWNrLnByb3RvdHlwZVsnZGVsZXRlJ10gPSBzdGFja0RlbGV0ZTtcblN0YWNrLnByb3RvdHlwZS5nZXQgPSBzdGFja0dldDtcblN0YWNrLnByb3RvdHlwZS5oYXMgPSBzdGFja0hhcztcblN0YWNrLnByb3RvdHlwZS5zZXQgPSBzdGFja1NldDtcblxubW9kdWxlLmV4cG9ydHMgPSBTdGFjaztcbiIsInZhciByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBTeW1ib2wgPSByb290LlN5bWJvbDtcblxubW9kdWxlLmV4cG9ydHMgPSBTeW1ib2w7XG4iLCJ2YXIgcm9vdCA9IHJlcXVpcmUoJy4vX3Jvb3QnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgVWludDhBcnJheSA9IHJvb3QuVWludDhBcnJheTtcblxubW9kdWxlLmV4cG9ydHMgPSBVaW50OEFycmF5O1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIHRoYXQgYXJlIHZlcmlmaWVkIHRvIGJlIG5hdGl2ZS4gKi9cbnZhciBXZWFrTWFwID0gZ2V0TmF0aXZlKHJvb3QsICdXZWFrTWFwJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gV2Vha01hcDtcbiIsIi8qKlxuICogQSBmYXN0ZXIgYWx0ZXJuYXRpdmUgdG8gYEZ1bmN0aW9uI2FwcGx5YCwgdGhpcyBmdW5jdGlvbiBpbnZva2VzIGBmdW5jYFxuICogd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgIGFuZCB0aGUgYXJndW1lbnRzIG9mIGBhcmdzYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gaW52b2tlLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBhcmdzIFRoZSBhcmd1bWVudHMgdG8gaW52b2tlIGBmdW5jYCB3aXRoLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc3VsdCBvZiBgZnVuY2AuXG4gKi9cbmZ1bmN0aW9uIGFwcGx5KGZ1bmMsIHRoaXNBcmcsIGFyZ3MpIHtcbiAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgIGNhc2UgMDogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnKTtcbiAgICBjYXNlIDE6IHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgYXJnc1swXSk7XG4gICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgIGNhc2UgMzogcmV0dXJuIGZ1bmMuY2FsbCh0aGlzQXJnLCBhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdKTtcbiAgfVxuICByZXR1cm4gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcHBseTtcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlQWdncmVnYXRvcmAgZm9yIGFycmF5cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gKiBAcGFyYW0ge09iamVjdH0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgYWdncmVnYXRlZCBvYmplY3QuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlBZ2dyZWdhdG9yKGFycmF5LCBzZXR0ZXIsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgIHNldHRlcihhY2N1bXVsYXRvciwgdmFsdWUsIGl0ZXJhdGVlKHZhbHVlKSwgYXJyYXkpO1xuICB9XG4gIHJldHVybiBhY2N1bXVsYXRvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUFnZ3JlZ2F0b3I7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgXy5mb3JFYWNoYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlFYWNoKGFycmF5LCBpdGVyYXRlZSkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGl0ZXJhdGVlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSA9PT0gZmFsc2UpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlFYWNoO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uZmlsdGVyYCBmb3IgYXJyYXlzIHdpdGhvdXQgc3VwcG9ydCBmb3JcbiAqIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheV0gVGhlIGFycmF5IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmlsdGVyZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGFycmF5RmlsdGVyKGFycmF5LCBwcmVkaWNhdGUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc0luZGV4ID0gMCxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJlc3VsdFtyZXNJbmRleCsrXSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFycmF5RmlsdGVyO1xuIiwidmFyIGJhc2VJbmRleE9mID0gcmVxdWlyZSgnLi9fYmFzZUluZGV4T2YnKTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uaW5jbHVkZXNgIGZvciBhcnJheXMgd2l0aG91dCBzdXBwb3J0IGZvclxuICogc3BlY2lmeWluZyBhbiBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gW2FycmF5XSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0gdGFyZ2V0IFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB0YXJnZXRgIGlzIGZvdW5kLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5SW5jbHVkZXMoYXJyYXksIHZhbHVlKSB7XG4gIHZhciBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aDtcbiAgcmV0dXJuICEhbGVuZ3RoICYmIGJhc2VJbmRleE9mKGFycmF5LCB2YWx1ZSwgMCkgPiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUluY2x1ZGVzO1xuIiwiLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGFycmF5SW5jbHVkZXNgIGV4Y2VwdCB0aGF0IGl0IGFjY2VwdHMgYSBjb21wYXJhdG9yLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB0YXJnZXQgVGhlIHZhbHVlIHRvIHNlYXJjaCBmb3IuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJhdG9yIFRoZSBjb21wYXJhdG9yIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHRhcmdldGAgaXMgZm91bmQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlJbmNsdWRlc1dpdGgoYXJyYXksIHZhbHVlLCBjb21wYXJhdG9yKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoY29tcGFyYXRvcih2YWx1ZSwgYXJyYXlbaW5kZXhdKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheUluY2x1ZGVzV2l0aDtcbiIsInZhciBiYXNlVGltZXMgPSByZXF1aXJlKCcuL19iYXNlVGltZXMnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNCdWZmZXIgPSByZXF1aXJlKCcuL2lzQnVmZmVyJyksXG4gICAgaXNJbmRleCA9IHJlcXVpcmUoJy4vX2lzSW5kZXgnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgdGhlIGFycmF5LWxpa2UgYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGluaGVyaXRlZCBTcGVjaWZ5IHJldHVybmluZyBpbmhlcml0ZWQgcHJvcGVydHkgbmFtZXMuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICovXG5mdW5jdGlvbiBhcnJheUxpa2VLZXlzKHZhbHVlLCBpbmhlcml0ZWQpIHtcbiAgdmFyIGlzQXJyID0gaXNBcnJheSh2YWx1ZSksXG4gICAgICBpc0FyZyA9ICFpc0FyciAmJiBpc0FyZ3VtZW50cyh2YWx1ZSksXG4gICAgICBpc0J1ZmYgPSAhaXNBcnIgJiYgIWlzQXJnICYmIGlzQnVmZmVyKHZhbHVlKSxcbiAgICAgIGlzVHlwZSA9ICFpc0FyciAmJiAhaXNBcmcgJiYgIWlzQnVmZiAmJiBpc1R5cGVkQXJyYXkodmFsdWUpLFxuICAgICAgc2tpcEluZGV4ZXMgPSBpc0FyciB8fCBpc0FyZyB8fCBpc0J1ZmYgfHwgaXNUeXBlLFxuICAgICAgcmVzdWx0ID0gc2tpcEluZGV4ZXMgPyBiYXNlVGltZXModmFsdWUubGVuZ3RoLCBTdHJpbmcpIDogW10sXG4gICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgIGlmICgoaW5oZXJpdGVkIHx8IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIGtleSkpICYmXG4gICAgICAgICEoc2tpcEluZGV4ZXMgJiYgKFxuICAgICAgICAgICAvLyBTYWZhcmkgOSBoYXMgZW51bWVyYWJsZSBgYXJndW1lbnRzLmxlbmd0aGAgaW4gc3RyaWN0IG1vZGUuXG4gICAgICAgICAgIGtleSA9PSAnbGVuZ3RoJyB8fFxuICAgICAgICAgICAvLyBOb2RlLmpzIDAuMTAgaGFzIGVudW1lcmFibGUgbm9uLWluZGV4IHByb3BlcnRpZXMgb24gYnVmZmVycy5cbiAgICAgICAgICAgKGlzQnVmZiAmJiAoa2V5ID09ICdvZmZzZXQnIHx8IGtleSA9PSAncGFyZW50JykpIHx8XG4gICAgICAgICAgIC8vIFBoYW50b21KUyAyIGhhcyBlbnVtZXJhYmxlIG5vbi1pbmRleCBwcm9wZXJ0aWVzIG9uIHR5cGVkIGFycmF5cy5cbiAgICAgICAgICAgKGlzVHlwZSAmJiAoa2V5ID09ICdidWZmZXInIHx8IGtleSA9PSAnYnl0ZUxlbmd0aCcgfHwga2V5ID09ICdieXRlT2Zmc2V0JykpIHx8XG4gICAgICAgICAgIC8vIFNraXAgaW5kZXggcHJvcGVydGllcy5cbiAgICAgICAgICAgaXNJbmRleChrZXksIGxlbmd0aClcbiAgICAgICAgKSkpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlMaWtlS2V5cztcbiIsIi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLm1hcGAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlXG4gKiBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBhcnJheU1hcChhcnJheSwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheSA9PSBudWxsID8gMCA6IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICByZXN1bHRbaW5kZXhdID0gaXRlcmF0ZWUoYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlNYXA7XG4iLCIvKipcbiAqIEFwcGVuZHMgdGhlIGVsZW1lbnRzIG9mIGB2YWx1ZXNgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBtb2RpZnkuXG4gKiBAcGFyYW0ge0FycmF5fSB2YWx1ZXMgVGhlIHZhbHVlcyB0byBhcHBlbmQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGFycmF5YC5cbiAqL1xuZnVuY3Rpb24gYXJyYXlQdXNoKGFycmF5LCB2YWx1ZXMpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgb2Zmc2V0ID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgYXJyYXlbb2Zmc2V0ICsgaW5kZXhdID0gdmFsdWVzW2luZGV4XTtcbiAgfVxuICByZXR1cm4gYXJyYXk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXJyYXlQdXNoO1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uc29tZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlXG4gKiBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJyYXldIFRoZSBhcnJheSB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbnkgZWxlbWVudCBwYXNzZXMgdGhlIHByZWRpY2F0ZSBjaGVjayxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGFycmF5U29tZShhcnJheSwgcHJlZGljYXRlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAocHJlZGljYXRlKGFycmF5W2luZGV4XSwgaW5kZXgsIGFycmF5KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBhcnJheVNvbWU7XG4iLCJ2YXIgYmFzZUFzc2lnblZhbHVlID0gcmVxdWlyZSgnLi9fYmFzZUFzc2lnblZhbHVlJyksXG4gICAgZXEgPSByZXF1aXJlKCcuL2VxJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQXNzaWducyBgdmFsdWVgIHRvIGBrZXlgIG9mIGBvYmplY3RgIGlmIHRoZSBleGlzdGluZyB2YWx1ZSBpcyBub3QgZXF1aXZhbGVudFxuICogdXNpbmcgW2BTYW1lVmFsdWVaZXJvYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtc2FtZXZhbHVlemVybylcbiAqIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gYXNzaWduLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gYXNzaWduLlxuICovXG5mdW5jdGlvbiBhc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgdmFyIG9ialZhbHVlID0gb2JqZWN0W2tleV07XG4gIGlmICghKGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCBrZXkpICYmIGVxKG9ialZhbHVlLCB2YWx1ZSkpIHx8XG4gICAgICAodmFsdWUgPT09IHVuZGVmaW5lZCAmJiAhKGtleSBpbiBvYmplY3QpKSkge1xuICAgIGJhc2VBc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgdmFsdWUpO1xuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzaWduVmFsdWU7XG4iLCJ2YXIgZXEgPSByZXF1aXJlKCcuL2VxJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGBrZXlgIGlzIGZvdW5kIGluIGBhcnJheWAgb2Yga2V5LXZhbHVlIHBhaXJzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7Kn0ga2V5IFRoZSBrZXkgdG8gc2VhcmNoIGZvci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIGluZGV4IG9mIHRoZSBtYXRjaGVkIHZhbHVlLCBlbHNlIGAtMWAuXG4gKi9cbmZ1bmN0aW9uIGFzc29jSW5kZXhPZihhcnJheSwga2V5KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIGlmIChlcShhcnJheVtsZW5ndGhdWzBdLCBrZXkpKSB7XG4gICAgICByZXR1cm4gbGVuZ3RoO1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzb2NJbmRleE9mO1xuIiwidmFyIGJhc2VFYWNoID0gcmVxdWlyZSgnLi9fYmFzZUVhY2gnKTtcblxuLyoqXG4gKiBBZ2dyZWdhdGVzIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCBvbiBgYWNjdW11bGF0b3JgIHdpdGgga2V5cyB0cmFuc2Zvcm1lZFxuICogYnkgYGl0ZXJhdGVlYCBhbmQgdmFsdWVzIHNldCBieSBgc2V0dGVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYGFjY3VtdWxhdG9yYCB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgaXRlcmF0ZWUgdG8gdHJhbnNmb3JtIGtleXMuXG4gKiBAcGFyYW0ge09iamVjdH0gYWNjdW11bGF0b3IgVGhlIGluaXRpYWwgYWdncmVnYXRlZCBvYmplY3QuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGFjY3VtdWxhdG9yYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUFnZ3JlZ2F0b3IoY29sbGVjdGlvbiwgc2V0dGVyLCBpdGVyYXRlZSwgYWNjdW11bGF0b3IpIHtcbiAgYmFzZUVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24odmFsdWUsIGtleSwgY29sbGVjdGlvbikge1xuICAgIHNldHRlcihhY2N1bXVsYXRvciwgdmFsdWUsIGl0ZXJhdGVlKHZhbHVlKSwgY29sbGVjdGlvbik7XG4gIH0pO1xuICByZXR1cm4gYWNjdW11bGF0b3I7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUFnZ3JlZ2F0b3I7XG4iLCJ2YXIgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19kZWZpbmVQcm9wZXJ0eScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBhc3NpZ25WYWx1ZWAgYW5kIGBhc3NpZ25NZXJnZVZhbHVlYCB3aXRob3V0XG4gKiB2YWx1ZSBjaGVja3MuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBtb2RpZnkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGFzc2lnbi5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGFzc2lnbi5cbiAqL1xuZnVuY3Rpb24gYmFzZUFzc2lnblZhbHVlKG9iamVjdCwga2V5LCB2YWx1ZSkge1xuICBpZiAoa2V5ID09ICdfX3Byb3RvX18nICYmIGRlZmluZVByb3BlcnR5KSB7XG4gICAgZGVmaW5lUHJvcGVydHkob2JqZWN0LCBrZXksIHtcbiAgICAgICdjb25maWd1cmFibGUnOiB0cnVlLFxuICAgICAgJ2VudW1lcmFibGUnOiB0cnVlLFxuICAgICAgJ3ZhbHVlJzogdmFsdWUsXG4gICAgICAnd3JpdGFibGUnOiB0cnVlXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VBc3NpZ25WYWx1ZTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0Q3JlYXRlID0gT2JqZWN0LmNyZWF0ZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5jcmVhdGVgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYXNzaWduaW5nXG4gKiBwcm9wZXJ0aWVzIHRvIHRoZSBjcmVhdGVkIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHByb3RvIFRoZSBvYmplY3QgdG8gaW5oZXJpdCBmcm9tLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IG9iamVjdC5cbiAqL1xudmFyIGJhc2VDcmVhdGUgPSAoZnVuY3Rpb24oKSB7XG4gIGZ1bmN0aW9uIG9iamVjdCgpIHt9XG4gIHJldHVybiBmdW5jdGlvbihwcm90bykge1xuICAgIGlmICghaXNPYmplY3QocHJvdG8pKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICAgIGlmIChvYmplY3RDcmVhdGUpIHtcbiAgICAgIHJldHVybiBvYmplY3RDcmVhdGUocHJvdG8pO1xuICAgIH1cbiAgICBvYmplY3QucHJvdG90eXBlID0gcHJvdG87XG4gICAgdmFyIHJlc3VsdCA9IG5ldyBvYmplY3Q7XG4gICAgb2JqZWN0LnByb3RvdHlwZSA9IHVuZGVmaW5lZDtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufSgpKTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlQ3JlYXRlO1xuIiwidmFyIFNldENhY2hlID0gcmVxdWlyZSgnLi9fU2V0Q2FjaGUnKSxcbiAgICBhcnJheUluY2x1ZGVzID0gcmVxdWlyZSgnLi9fYXJyYXlJbmNsdWRlcycpLFxuICAgIGFycmF5SW5jbHVkZXNXaXRoID0gcmVxdWlyZSgnLi9fYXJyYXlJbmNsdWRlc1dpdGgnKSxcbiAgICBhcnJheU1hcCA9IHJlcXVpcmUoJy4vX2FycmF5TWFwJyksXG4gICAgYmFzZVVuYXJ5ID0gcmVxdWlyZSgnLi9fYmFzZVVuYXJ5JyksXG4gICAgY2FjaGVIYXMgPSByZXF1aXJlKCcuL19jYWNoZUhhcycpO1xuXG4vKiogVXNlZCBhcyB0aGUgc2l6ZSB0byBlbmFibGUgbGFyZ2UgYXJyYXkgb3B0aW1pemF0aW9ucy4gKi9cbnZhciBMQVJHRV9BUlJBWV9TSVpFID0gMjAwO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIG1ldGhvZHMgbGlrZSBgXy5kaWZmZXJlbmNlYCB3aXRob3V0IHN1cHBvcnRcbiAqIGZvciBleGNsdWRpbmcgbXVsdGlwbGUgYXJyYXlzIG9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtBcnJheX0gdmFsdWVzIFRoZSB2YWx1ZXMgdG8gZXhjbHVkZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gYmFzZURpZmZlcmVuY2UoYXJyYXksIHZhbHVlcywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXMsXG4gICAgICBpc0NvbW1vbiA9IHRydWUsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXN1bHQgPSBbXSxcbiAgICAgIHZhbHVlc0xlbmd0aCA9IHZhbHVlcy5sZW5ndGg7XG5cbiAgaWYgKCFsZW5ndGgpIHtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGlmIChpdGVyYXRlZSkge1xuICAgIHZhbHVlcyA9IGFycmF5TWFwKHZhbHVlcywgYmFzZVVuYXJ5KGl0ZXJhdGVlKSk7XG4gIH1cbiAgaWYgKGNvbXBhcmF0b3IpIHtcbiAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXNXaXRoO1xuICAgIGlzQ29tbW9uID0gZmFsc2U7XG4gIH1cbiAgZWxzZSBpZiAodmFsdWVzLmxlbmd0aCA+PSBMQVJHRV9BUlJBWV9TSVpFKSB7XG4gICAgaW5jbHVkZXMgPSBjYWNoZUhhcztcbiAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgIHZhbHVlcyA9IG5ldyBTZXRDYWNoZSh2YWx1ZXMpO1xuICB9XG4gIG91dGVyOlxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XSxcbiAgICAgICAgY29tcHV0ZWQgPSBpdGVyYXRlZSA9PSBudWxsID8gdmFsdWUgOiBpdGVyYXRlZSh2YWx1ZSk7XG5cbiAgICB2YWx1ZSA9IChjb21wYXJhdG9yIHx8IHZhbHVlICE9PSAwKSA/IHZhbHVlIDogMDtcbiAgICBpZiAoaXNDb21tb24gJiYgY29tcHV0ZWQgPT09IGNvbXB1dGVkKSB7XG4gICAgICB2YXIgdmFsdWVzSW5kZXggPSB2YWx1ZXNMZW5ndGg7XG4gICAgICB3aGlsZSAodmFsdWVzSW5kZXgtLSkge1xuICAgICAgICBpZiAodmFsdWVzW3ZhbHVlc0luZGV4XSA9PT0gY29tcHV0ZWQpIHtcbiAgICAgICAgICBjb250aW51ZSBvdXRlcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgIH1cbiAgICBlbHNlIGlmICghaW5jbHVkZXModmFsdWVzLCBjb21wdXRlZCwgY29tcGFyYXRvcikpIHtcbiAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRGlmZmVyZW5jZTtcbiIsInZhciBiYXNlRm9yT3duID0gcmVxdWlyZSgnLi9fYmFzZUZvck93bicpLFxuICAgIGNyZWF0ZUJhc2VFYWNoID0gcmVxdWlyZSgnLi9fY3JlYXRlQmFzZUVhY2gnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mb3JFYWNoYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl8T2JqZWN0fSBSZXR1cm5zIGBjb2xsZWN0aW9uYC5cbiAqL1xudmFyIGJhc2VFYWNoID0gY3JlYXRlQmFzZUVhY2goYmFzZUZvck93bik7XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUVhY2g7XG4iLCJ2YXIgYmFzZUVhY2ggPSByZXF1aXJlKCcuL19iYXNlRWFjaCcpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmZpbHRlcmAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlRmlsdGVyKGNvbGxlY3Rpb24sIHByZWRpY2F0ZSkge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbikge1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSkge1xuICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZpbHRlcjtcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZmluZEluZGV4YCBhbmQgYF8uZmluZExhc3RJbmRleGAgd2l0aG91dFxuICogc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlRmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCwgZnJvbVJpZ2h0KSB7XG4gIHZhciBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBpbmRleCA9IGZyb21JbmRleCArIChmcm9tUmlnaHQgPyAxIDogLTEpO1xuXG4gIHdoaWxlICgoZnJvbVJpZ2h0ID8gaW5kZXgtLSA6ICsraW5kZXggPCBsZW5ndGgpKSB7XG4gICAgaWYgKHByZWRpY2F0ZShhcnJheVtpbmRleF0sIGluZGV4LCBhcnJheSkpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGaW5kSW5kZXg7XG4iLCJ2YXIgYXJyYXlQdXNoID0gcmVxdWlyZSgnLi9fYXJyYXlQdXNoJyksXG4gICAgaXNGbGF0dGVuYWJsZSA9IHJlcXVpcmUoJy4vX2lzRmxhdHRlbmFibGUnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mbGF0dGVuYCB3aXRoIHN1cHBvcnQgZm9yIHJlc3RyaWN0aW5nIGZsYXR0ZW5pbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICogQHBhcmFtIHtudW1iZXJ9IGRlcHRoIFRoZSBtYXhpbXVtIHJlY3Vyc2lvbiBkZXB0aC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3ByZWRpY2F0ZT1pc0ZsYXR0ZW5hYmxlXSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbaXNTdHJpY3RdIFJlc3RyaWN0IHRvIHZhbHVlcyB0aGF0IHBhc3MgYHByZWRpY2F0ZWAgY2hlY2tzLlxuICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdD1bXV0gVGhlIGluaXRpYWwgcmVzdWx0IHZhbHVlLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlRmxhdHRlbihhcnJheSwgZGVwdGgsIHByZWRpY2F0ZSwgaXNTdHJpY3QsIHJlc3VsdCkge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IGFycmF5Lmxlbmd0aDtcblxuICBwcmVkaWNhdGUgfHwgKHByZWRpY2F0ZSA9IGlzRmxhdHRlbmFibGUpO1xuICByZXN1bHQgfHwgKHJlc3VsdCA9IFtdKTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAoZGVwdGggPiAwICYmIHByZWRpY2F0ZSh2YWx1ZSkpIHtcbiAgICAgIGlmIChkZXB0aCA+IDEpIHtcbiAgICAgICAgLy8gUmVjdXJzaXZlbHkgZmxhdHRlbiBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICAgICAgYmFzZUZsYXR0ZW4odmFsdWUsIGRlcHRoIC0gMSwgcHJlZGljYXRlLCBpc1N0cmljdCwgcmVzdWx0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFycmF5UHVzaChyZXN1bHQsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFpc1N0cmljdCkge1xuICAgICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUZsYXR0ZW47XG4iLCJ2YXIgY3JlYXRlQmFzZUZvciA9IHJlcXVpcmUoJy4vX2NyZWF0ZUJhc2VGb3InKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgYmFzZUZvck93bmAgd2hpY2ggaXRlcmF0ZXMgb3ZlciBgb2JqZWN0YFxuICogcHJvcGVydGllcyByZXR1cm5lZCBieSBga2V5c0Z1bmNgIGFuZCBpbnZva2VzIGBpdGVyYXRlZWAgZm9yIGVhY2ggcHJvcGVydHkuXG4gKiBJdGVyYXRlZSBmdW5jdGlvbnMgbWF5IGV4aXQgaXRlcmF0aW9uIGVhcmx5IGJ5IGV4cGxpY2l0bHkgcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VGb3I7XG4iLCJ2YXIgYmFzZUZvciA9IHJlcXVpcmUoJy4vX2Jhc2VGb3InKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBgb2JqZWN0YC5cbiAqL1xuZnVuY3Rpb24gYmFzZUZvck93bihvYmplY3QsIGl0ZXJhdGVlKSB7XG4gIHJldHVybiBvYmplY3QgJiYgYmFzZUZvcihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9yT3duO1xuIiwidmFyIGNhc3RQYXRoID0gcmVxdWlyZSgnLi9fY2FzdFBhdGgnKSxcbiAgICB0b0tleSA9IHJlcXVpcmUoJy4vX3RvS2V5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZ2V0YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZmF1bHQgdmFsdWVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHJlc29sdmVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBiYXNlR2V0KG9iamVjdCwgcGF0aCkge1xuICBwYXRoID0gY2FzdFBhdGgocGF0aCwgb2JqZWN0KTtcblxuICB2YXIgaW5kZXggPSAwLFxuICAgICAgbGVuZ3RoID0gcGF0aC5sZW5ndGg7XG5cbiAgd2hpbGUgKG9iamVjdCAhPSBudWxsICYmIGluZGV4IDwgbGVuZ3RoKSB7XG4gICAgb2JqZWN0ID0gb2JqZWN0W3RvS2V5KHBhdGhbaW5kZXgrK10pXTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICYmIGluZGV4ID09IGxlbmd0aCkgPyBvYmplY3QgOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUdldDtcbiIsInZhciBhcnJheVB1c2ggPSByZXF1aXJlKCcuL19hcnJheVB1c2gnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGdldEFsbEtleXNgIGFuZCBgZ2V0QWxsS2V5c0luYCB3aGljaCB1c2VzXG4gKiBga2V5c0Z1bmNgIGFuZCBgc3ltYm9sc0Z1bmNgIHRvIGdldCB0aGUgZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmRcbiAqIHN5bWJvbHMgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGtleXNGdW5jIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgb2YgYG9iamVjdGAuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzeW1ib2xzRnVuYyBUaGUgZnVuY3Rpb24gdG8gZ2V0IHRoZSBzeW1ib2xzIG9mIGBvYmplY3RgLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAqL1xuZnVuY3Rpb24gYmFzZUdldEFsbEtleXMob2JqZWN0LCBrZXlzRnVuYywgc3ltYm9sc0Z1bmMpIHtcbiAgdmFyIHJlc3VsdCA9IGtleXNGdW5jKG9iamVjdCk7XG4gIHJldHVybiBpc0FycmF5KG9iamVjdCkgPyByZXN1bHQgOiBhcnJheVB1c2gocmVzdWx0LCBzeW1ib2xzRnVuYyhvYmplY3QpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlR2V0QWxsS2V5cztcbiIsInZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19TeW1ib2wnKSxcbiAgICBnZXRSYXdUYWcgPSByZXF1aXJlKCcuL19nZXRSYXdUYWcnKSxcbiAgICBvYmplY3RUb1N0cmluZyA9IHJlcXVpcmUoJy4vX29iamVjdFRvU3RyaW5nJyk7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBudWxsVGFnID0gJ1tvYmplY3QgTnVsbF0nLFxuICAgIHVuZGVmaW5lZFRhZyA9ICdbb2JqZWN0IFVuZGVmaW5lZF0nO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBzeW1Ub1N0cmluZ1RhZyA9IFN5bWJvbCA/IFN5bWJvbC50b1N0cmluZ1RhZyA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgZ2V0VGFnYCB3aXRob3V0IGZhbGxiYWNrcyBmb3IgYnVnZ3kgZW52aXJvbm1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuXG4gKi9cbmZ1bmN0aW9uIGJhc2VHZXRUYWcodmFsdWUpIHtcbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZFRhZyA6IG51bGxUYWc7XG4gIH1cbiAgcmV0dXJuIChzeW1Ub1N0cmluZ1RhZyAmJiBzeW1Ub1N0cmluZ1RhZyBpbiBPYmplY3QodmFsdWUpKVxuICAgID8gZ2V0UmF3VGFnKHZhbHVlKVxuICAgIDogb2JqZWN0VG9TdHJpbmcodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VHZXRUYWc7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmhhc0luYCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IGtleSBUaGUga2V5IHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBiYXNlSGFzSW4ob2JqZWN0LCBrZXkpIHtcbiAgcmV0dXJuIG9iamVjdCAhPSBudWxsICYmIGtleSBpbiBPYmplY3Qob2JqZWN0KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSGFzSW47XG4iLCJ2YXIgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vX2Jhc2VGaW5kSW5kZXgnKSxcbiAgICBiYXNlSXNOYU4gPSByZXF1aXJlKCcuL19iYXNlSXNOYU4nKSxcbiAgICBzdHJpY3RJbmRleE9mID0gcmVxdWlyZSgnLi9fc3RyaWN0SW5kZXhPZicpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmluZGV4T2ZgIHdpdGhvdXQgYGZyb21JbmRleGAgYm91bmRzIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHBhcmFtIHtudW1iZXJ9IGZyb21JbmRleCBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCB2YWx1ZSwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBiYXNlSW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICByZXR1cm4gdmFsdWUgPT09IHZhbHVlXG4gICAgPyBzdHJpY3RJbmRleE9mKGFycmF5LCB2YWx1ZSwgZnJvbUluZGV4KVxuICAgIDogYmFzZUZpbmRJbmRleChhcnJheSwgYmFzZUlzTmFOLCBmcm9tSW5kZXgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJbmRleE9mO1xuIiwidmFyIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJztcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0FyZ3VtZW50c2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYGFyZ3VtZW50c2Agb2JqZWN0LFxuICovXG5mdW5jdGlvbiBiYXNlSXNBcmd1bWVudHModmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgYmFzZUdldFRhZyh2YWx1ZSkgPT0gYXJnc1RhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNBcmd1bWVudHM7XG4iLCJ2YXIgYmFzZUlzRXF1YWxEZWVwID0gcmVxdWlyZSgnLi9fYmFzZUlzRXF1YWxEZWVwJyksXG4gICAgaXNPYmplY3RMaWtlID0gcmVxdWlyZSgnLi9pc09iamVjdExpa2UnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc0VxdWFsYCB3aGljaCBzdXBwb3J0cyBwYXJ0aWFsIGNvbXBhcmlzb25zXG4gKiBhbmQgdHJhY2tzIHRyYXZlcnNlZCBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb21wYXJlLlxuICogQHBhcmFtIHsqfSBvdGhlciBUaGUgb3RoZXIgdmFsdWUgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy5cbiAqICAxIC0gVW5vcmRlcmVkIGNvbXBhcmlzb25cbiAqICAyIC0gUGFydGlhbCBjb21wYXJpc29uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY3VzdG9taXplcl0gVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbc3RhY2tdIFRyYWNrcyB0cmF2ZXJzZWQgYHZhbHVlYCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzRXF1YWwodmFsdWUsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBzdGFjaykge1xuICBpZiAodmFsdWUgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwgfHwgb3RoZXIgPT0gbnVsbCB8fCAoIWlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgIWlzT2JqZWN0TGlrZShvdGhlcikpKSB7XG4gICAgcmV0dXJuIHZhbHVlICE9PSB2YWx1ZSAmJiBvdGhlciAhPT0gb3RoZXI7XG4gIH1cbiAgcmV0dXJuIGJhc2VJc0VxdWFsRGVlcCh2YWx1ZSwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGJhc2VJc0VxdWFsLCBzdGFjayk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzRXF1YWw7XG4iLCJ2YXIgU3RhY2sgPSByZXF1aXJlKCcuL19TdGFjaycpLFxuICAgIGVxdWFsQXJyYXlzID0gcmVxdWlyZSgnLi9fZXF1YWxBcnJheXMnKSxcbiAgICBlcXVhbEJ5VGFnID0gcmVxdWlyZSgnLi9fZXF1YWxCeVRhZycpLFxuICAgIGVxdWFsT2JqZWN0cyA9IHJlcXVpcmUoJy4vX2VxdWFsT2JqZWN0cycpLFxuICAgIGdldFRhZyA9IHJlcXVpcmUoJy4vX2dldFRhZycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0J1ZmZlciA9IHJlcXVpcmUoJy4vaXNCdWZmZXInKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciB2YWx1ZSBjb21wYXJpc29ucy4gKi9cbnZhciBDT01QQVJFX1BBUlRJQUxfRkxBRyA9IDE7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcmdzVGFnID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXG4gICAgYXJyYXlUYWcgPSAnW29iamVjdCBBcnJheV0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxgIGZvciBhcnJheXMgYW5kIG9iamVjdHMgd2hpY2ggcGVyZm9ybXNcbiAqIGRlZXAgY29tcGFyaXNvbnMgYW5kIHRyYWNrcyB0cmF2ZXJzZWQgb2JqZWN0cyBlbmFibGluZyBvYmplY3RzIHdpdGggY2lyY3VsYXJcbiAqIHJlZmVyZW5jZXMgdG8gYmUgY29tcGFyZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IFtzdGFja10gVHJhY2tzIHRyYXZlcnNlZCBgb2JqZWN0YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBvYmplY3RzIGFyZSBlcXVpdmFsZW50LCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc0VxdWFsRGVlcChvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBvYmpJc0FyciA9IGlzQXJyYXkob2JqZWN0KSxcbiAgICAgIG90aElzQXJyID0gaXNBcnJheShvdGhlciksXG4gICAgICBvYmpUYWcgPSBvYmpJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG9iamVjdCksXG4gICAgICBvdGhUYWcgPSBvdGhJc0FyciA/IGFycmF5VGFnIDogZ2V0VGFnKG90aGVyKTtcblxuICBvYmpUYWcgPSBvYmpUYWcgPT0gYXJnc1RhZyA/IG9iamVjdFRhZyA6IG9ialRhZztcbiAgb3RoVGFnID0gb3RoVGFnID09IGFyZ3NUYWcgPyBvYmplY3RUYWcgOiBvdGhUYWc7XG5cbiAgdmFyIG9iaklzT2JqID0gb2JqVGFnID09IG9iamVjdFRhZyxcbiAgICAgIG90aElzT2JqID0gb3RoVGFnID09IG9iamVjdFRhZyxcbiAgICAgIGlzU2FtZVRhZyA9IG9ialRhZyA9PSBvdGhUYWc7XG5cbiAgaWYgKGlzU2FtZVRhZyAmJiBpc0J1ZmZlcihvYmplY3QpKSB7XG4gICAgaWYgKCFpc0J1ZmZlcihvdGhlcikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgb2JqSXNBcnIgPSB0cnVlO1xuICAgIG9iaklzT2JqID0gZmFsc2U7XG4gIH1cbiAgaWYgKGlzU2FtZVRhZyAmJiAhb2JqSXNPYmopIHtcbiAgICBzdGFjayB8fCAoc3RhY2sgPSBuZXcgU3RhY2spO1xuICAgIHJldHVybiAob2JqSXNBcnIgfHwgaXNUeXBlZEFycmF5KG9iamVjdCkpXG4gICAgICA/IGVxdWFsQXJyYXlzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spXG4gICAgICA6IGVxdWFsQnlUYWcob2JqZWN0LCBvdGhlciwgb2JqVGFnLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbiAgfVxuICBpZiAoIShiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcpKSB7XG4gICAgdmFyIG9iaklzV3JhcHBlZCA9IG9iaklzT2JqICYmIGhhc093blByb3BlcnR5LmNhbGwob2JqZWN0LCAnX193cmFwcGVkX18nKSxcbiAgICAgICAgb3RoSXNXcmFwcGVkID0gb3RoSXNPYmogJiYgaGFzT3duUHJvcGVydHkuY2FsbChvdGhlciwgJ19fd3JhcHBlZF9fJyk7XG5cbiAgICBpZiAob2JqSXNXcmFwcGVkIHx8IG90aElzV3JhcHBlZCkge1xuICAgICAgdmFyIG9ialVud3JhcHBlZCA9IG9iaklzV3JhcHBlZCA/IG9iamVjdC52YWx1ZSgpIDogb2JqZWN0LFxuICAgICAgICAgIG90aFVud3JhcHBlZCA9IG90aElzV3JhcHBlZCA/IG90aGVyLnZhbHVlKCkgOiBvdGhlcjtcblxuICAgICAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgICAgIHJldHVybiBlcXVhbEZ1bmMob2JqVW53cmFwcGVkLCBvdGhVbndyYXBwZWQsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKTtcbiAgICB9XG4gIH1cbiAgaWYgKCFpc1NhbWVUYWcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgc3RhY2sgfHwgKHN0YWNrID0gbmV3IFN0YWNrKTtcbiAgcmV0dXJuIGVxdWFsT2JqZWN0cyhvYmplY3QsIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNFcXVhbERlZXA7XG4iLCJ2YXIgU3RhY2sgPSByZXF1aXJlKCcuL19TdGFjaycpLFxuICAgIGJhc2VJc0VxdWFsID0gcmVxdWlyZSgnLi9fYmFzZUlzRXF1YWwnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTWF0Y2hgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaXRlcmF0ZWUgc2hvcnRoYW5kcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3Qgb2YgcHJvcGVydHkgdmFsdWVzIHRvIG1hdGNoLlxuICogQHBhcmFtIHtBcnJheX0gbWF0Y2hEYXRhIFRoZSBwcm9wZXJ0eSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyB0byBtYXRjaC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBvYmplY3RgIGlzIGEgbWF0Y2gsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzTWF0Y2gob2JqZWN0LCBzb3VyY2UsIG1hdGNoRGF0YSwgY3VzdG9taXplcikge1xuICB2YXIgaW5kZXggPSBtYXRjaERhdGEubGVuZ3RoLFxuICAgICAgbGVuZ3RoID0gaW5kZXgsXG4gICAgICBub0N1c3RvbWl6ZXIgPSAhY3VzdG9taXplcjtcblxuICBpZiAob2JqZWN0ID09IG51bGwpIHtcbiAgICByZXR1cm4gIWxlbmd0aDtcbiAgfVxuICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07XG4gICAgaWYgKChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSlcbiAgICAgICAgICA/IGRhdGFbMV0gIT09IG9iamVjdFtkYXRhWzBdXVxuICAgICAgICAgIDogIShkYXRhWzBdIGluIG9iamVjdClcbiAgICAgICAgKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgZGF0YSA9IG1hdGNoRGF0YVtpbmRleF07XG4gICAgdmFyIGtleSA9IGRhdGFbMF0sXG4gICAgICAgIG9ialZhbHVlID0gb2JqZWN0W2tleV0sXG4gICAgICAgIHNyY1ZhbHVlID0gZGF0YVsxXTtcblxuICAgIGlmIChub0N1c3RvbWl6ZXIgJiYgZGF0YVsyXSkge1xuICAgICAgaWYgKG9ialZhbHVlID09PSB1bmRlZmluZWQgJiYgIShrZXkgaW4gb2JqZWN0KSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBzdGFjayA9IG5ldyBTdGFjaztcbiAgICAgIGlmIChjdXN0b21pemVyKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBjdXN0b21pemVyKG9ialZhbHVlLCBzcmNWYWx1ZSwga2V5LCBvYmplY3QsIHNvdXJjZSwgc3RhY2spO1xuICAgICAgfVxuICAgICAgaWYgKCEocmVzdWx0ID09PSB1bmRlZmluZWRcbiAgICAgICAgICAgID8gYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcsIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICAgICAgOiByZXN1bHRcbiAgICAgICAgICApKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzTWF0Y2g7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmFOYCB3aXRob3V0IHN1cHBvcnQgZm9yIG51bWJlciBvYmplY3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGBOYU5gLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc05hTih2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgIT09IHZhbHVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VJc05hTjtcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNNYXNrZWQgPSByZXF1aXJlKCcuL19pc01hc2tlZCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpLFxuICAgIHRvU291cmNlID0gcmVxdWlyZSgnLi9fdG9Tb3VyY2UnKTtcblxuLyoqXG4gKiBVc2VkIHRvIG1hdGNoIGBSZWdFeHBgXG4gKiBbc3ludGF4IGNoYXJhY3RlcnNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXBhdHRlcm5zKS5cbiAqL1xudmFyIHJlUmVnRXhwQ2hhciA9IC9bXFxcXF4kLiorPygpW1xcXXt9fF0vZztcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGhvc3QgY29uc3RydWN0b3JzIChTYWZhcmkpLiAqL1xudmFyIHJlSXNIb3N0Q3RvciA9IC9eXFxbb2JqZWN0IC4rP0NvbnN0cnVjdG9yXFxdJC87XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBmdW5jUHJvdG8gPSBGdW5jdGlvbi5wcm90b3R5cGUsXG4gICAgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byByZXNvbHZlIHRoZSBkZWNvbXBpbGVkIHNvdXJjZSBvZiBmdW5jdGlvbnMuICovXG52YXIgZnVuY1RvU3RyaW5nID0gZnVuY1Byb3RvLnRvU3RyaW5nO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKiogVXNlZCB0byBkZXRlY3QgaWYgYSBtZXRob2QgaXMgbmF0aXZlLiAqL1xudmFyIHJlSXNOYXRpdmUgPSBSZWdFeHAoJ14nICtcbiAgZnVuY1RvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UocmVSZWdFeHBDaGFyLCAnXFxcXCQmJylcbiAgLnJlcGxhY2UoL2hhc093blByb3BlcnR5fChmdW5jdGlvbikuKj8oPz1cXFxcXFwoKXwgZm9yIC4rPyg/PVxcXFxcXF0pL2csICckMS4qPycpICsgJyQnXG4pO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmlzTmF0aXZlYCB3aXRob3V0IGJhZCBzaGltIGNoZWNrcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbixcbiAqICBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJc05hdGl2ZSh2YWx1ZSkge1xuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSB8fCBpc01hc2tlZCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHBhdHRlcm4gPSBpc0Z1bmN0aW9uKHZhbHVlKSA/IHJlSXNOYXRpdmUgOiByZUlzSG9zdEN0b3I7XG4gIHJldHVybiBwYXR0ZXJuLnRlc3QodG9Tb3VyY2UodmFsdWUpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSXNOYXRpdmU7XG4iLCJ2YXIgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICBpc0xlbmd0aCA9IHJlcXVpcmUoJy4vaXNMZW5ndGgnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYXJnc1RhZyA9ICdbb2JqZWN0IEFyZ3VtZW50c10nLFxuICAgIGFycmF5VGFnID0gJ1tvYmplY3QgQXJyYXldJyxcbiAgICBib29sVGFnID0gJ1tvYmplY3QgQm9vbGVhbl0nLFxuICAgIGRhdGVUYWcgPSAnW29iamVjdCBEYXRlXScsXG4gICAgZXJyb3JUYWcgPSAnW29iamVjdCBFcnJvcl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIG1hcFRhZyA9ICdbb2JqZWN0IE1hcF0nLFxuICAgIG51bWJlclRhZyA9ICdbb2JqZWN0IE51bWJlcl0nLFxuICAgIG9iamVjdFRhZyA9ICdbb2JqZWN0IE9iamVjdF0nLFxuICAgIHJlZ2V4cFRhZyA9ICdbb2JqZWN0IFJlZ0V4cF0nLFxuICAgIHNldFRhZyA9ICdbb2JqZWN0IFNldF0nLFxuICAgIHN0cmluZ1RhZyA9ICdbb2JqZWN0IFN0cmluZ10nLFxuICAgIHdlYWtNYXBUYWcgPSAnW29iamVjdCBXZWFrTWFwXSc7XG5cbnZhciBhcnJheUJ1ZmZlclRhZyA9ICdbb2JqZWN0IEFycmF5QnVmZmVyXScsXG4gICAgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nLFxuICAgIGZsb2F0MzJUYWcgPSAnW29iamVjdCBGbG9hdDMyQXJyYXldJyxcbiAgICBmbG9hdDY0VGFnID0gJ1tvYmplY3QgRmxvYXQ2NEFycmF5XScsXG4gICAgaW50OFRhZyA9ICdbb2JqZWN0IEludDhBcnJheV0nLFxuICAgIGludDE2VGFnID0gJ1tvYmplY3QgSW50MTZBcnJheV0nLFxuICAgIGludDMyVGFnID0gJ1tvYmplY3QgSW50MzJBcnJheV0nLFxuICAgIHVpbnQ4VGFnID0gJ1tvYmplY3QgVWludDhBcnJheV0nLFxuICAgIHVpbnQ4Q2xhbXBlZFRhZyA9ICdbb2JqZWN0IFVpbnQ4Q2xhbXBlZEFycmF5XScsXG4gICAgdWludDE2VGFnID0gJ1tvYmplY3QgVWludDE2QXJyYXldJyxcbiAgICB1aW50MzJUYWcgPSAnW29iamVjdCBVaW50MzJBcnJheV0nO1xuXG4vKiogVXNlZCB0byBpZGVudGlmeSBgdG9TdHJpbmdUYWdgIHZhbHVlcyBvZiB0eXBlZCBhcnJheXMuICovXG52YXIgdHlwZWRBcnJheVRhZ3MgPSB7fTtcbnR5cGVkQXJyYXlUYWdzW2Zsb2F0MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbZmxvYXQ2NFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50OFRhZ10gPSB0eXBlZEFycmF5VGFnc1tpbnQxNlRhZ10gPVxudHlwZWRBcnJheVRhZ3NbaW50MzJUYWddID0gdHlwZWRBcnJheVRhZ3NbdWludDhUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQ4Q2xhbXBlZFRhZ10gPSB0eXBlZEFycmF5VGFnc1t1aW50MTZUYWddID1cbnR5cGVkQXJyYXlUYWdzW3VpbnQzMlRhZ10gPSB0cnVlO1xudHlwZWRBcnJheVRhZ3NbYXJnc1RhZ10gPSB0eXBlZEFycmF5VGFnc1thcnJheVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbYXJyYXlCdWZmZXJUYWddID0gdHlwZWRBcnJheVRhZ3NbYm9vbFRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZGF0YVZpZXdUYWddID0gdHlwZWRBcnJheVRhZ3NbZGF0ZVRhZ10gPVxudHlwZWRBcnJheVRhZ3NbZXJyb3JUYWddID0gdHlwZWRBcnJheVRhZ3NbZnVuY1RhZ10gPVxudHlwZWRBcnJheVRhZ3NbbWFwVGFnXSA9IHR5cGVkQXJyYXlUYWdzW251bWJlclRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbb2JqZWN0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3JlZ2V4cFRhZ10gPVxudHlwZWRBcnJheVRhZ3Nbc2V0VGFnXSA9IHR5cGVkQXJyYXlUYWdzW3N0cmluZ1RhZ10gPVxudHlwZWRBcnJheVRhZ3Nbd2Vha01hcFRhZ10gPSBmYWxzZTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5pc1R5cGVkQXJyYXlgIHdpdGhvdXQgTm9kZS5qcyBvcHRpbWl6YXRpb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdHlwZWQgYXJyYXksIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUlzVHlwZWRBcnJheSh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3RMaWtlKHZhbHVlKSAmJlxuICAgIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgISF0eXBlZEFycmF5VGFnc1tiYXNlR2V0VGFnKHZhbHVlKV07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUlzVHlwZWRBcnJheTtcbiIsInZhciBiYXNlTWF0Y2hlcyA9IHJlcXVpcmUoJy4vX2Jhc2VNYXRjaGVzJyksXG4gICAgYmFzZU1hdGNoZXNQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2Jhc2VNYXRjaGVzUHJvcGVydHknKSxcbiAgICBpZGVudGl0eSA9IHJlcXVpcmUoJy4vaWRlbnRpdHknKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgcHJvcGVydHkgPSByZXF1aXJlKCcuL3Byb3BlcnR5Jyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uaXRlcmF0ZWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IFt2YWx1ZT1fLmlkZW50aXR5XSBUaGUgdmFsdWUgdG8gY29udmVydCB0byBhbiBpdGVyYXRlZS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgaXRlcmF0ZWUuXG4gKi9cbmZ1bmN0aW9uIGJhc2VJdGVyYXRlZSh2YWx1ZSkge1xuICAvLyBEb24ndCBzdG9yZSB0aGUgYHR5cGVvZmAgcmVzdWx0IGluIGEgdmFyaWFibGUgdG8gYXZvaWQgYSBKSVQgYnVnIGluIFNhZmFyaSA5LlxuICAvLyBTZWUgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE1NjAzNCBmb3IgbW9yZSBkZXRhaWxzLlxuICBpZiAodHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gaWRlbnRpdHk7XG4gIH1cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jykge1xuICAgIHJldHVybiBpc0FycmF5KHZhbHVlKVxuICAgICAgPyBiYXNlTWF0Y2hlc1Byb3BlcnR5KHZhbHVlWzBdLCB2YWx1ZVsxXSlcbiAgICAgIDogYmFzZU1hdGNoZXModmFsdWUpO1xuICB9XG4gIHJldHVybiBwcm9wZXJ0eSh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUl0ZXJhdGVlO1xuIiwidmFyIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKSxcbiAgICBuYXRpdmVLZXlzID0gcmVxdWlyZSgnLi9fbmF0aXZlS2V5cycpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmtleXNgIHdoaWNoIGRvZXNuJ3QgdHJlYXQgc3BhcnNlIGFycmF5cyBhcyBkZW5zZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqL1xuZnVuY3Rpb24gYmFzZUtleXMob2JqZWN0KSB7XG4gIGlmICghaXNQcm90b3R5cGUob2JqZWN0KSkge1xuICAgIHJldHVybiBuYXRpdmVLZXlzKG9iamVjdCk7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3IgKHZhciBrZXkgaW4gT2JqZWN0KG9iamVjdCkpIHtcbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIGtleSkgJiYga2V5ICE9ICdjb25zdHJ1Y3RvcicpIHtcbiAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUtleXM7XG4iLCIvKipcbiAqIFRoZSBmdW5jdGlvbiB3aG9zZSBwcm90b3R5cGUgY2hhaW4gc2VxdWVuY2Ugd3JhcHBlcnMgaW5oZXJpdCBmcm9tLlxuICpcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIGJhc2VMb2Rhc2goKSB7XG4gIC8vIE5vIG9wZXJhdGlvbiBwZXJmb3JtZWQuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZUxvZGFzaDtcbiIsInZhciBiYXNlRWFjaCA9IHJlcXVpcmUoJy4vX2Jhc2VFYWNoJyksXG4gICAgaXNBcnJheUxpa2UgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ubWFwYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBtYXBwZWQgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGJhc2VNYXAoY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSBpc0FycmF5TGlrZShjb2xsZWN0aW9uKSA/IEFycmF5KGNvbGxlY3Rpb24ubGVuZ3RoKSA6IFtdO1xuXG4gIGJhc2VFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uKHZhbHVlLCBrZXksIGNvbGxlY3Rpb24pIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSBpdGVyYXRlZSh2YWx1ZSwga2V5LCBjb2xsZWN0aW9uKTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZU1hcDtcbiIsInZhciBiYXNlSXNNYXRjaCA9IHJlcXVpcmUoJy4vX2Jhc2VJc01hdGNoJyksXG4gICAgZ2V0TWF0Y2hEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWF0Y2hEYXRhJyksXG4gICAgbWF0Y2hlc1N0cmljdENvbXBhcmFibGUgPSByZXF1aXJlKCcuL19tYXRjaGVzU3RyaWN0Q29tcGFyYWJsZScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNgIHdoaWNoIGRvZXNuJ3QgY2xvbmUgYHNvdXJjZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzb3VyY2UgVGhlIG9iamVjdCBvZiBwcm9wZXJ0eSB2YWx1ZXMgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlTWF0Y2hlcyhzb3VyY2UpIHtcbiAgdmFyIG1hdGNoRGF0YSA9IGdldE1hdGNoRGF0YShzb3VyY2UpO1xuICBpZiAobWF0Y2hEYXRhLmxlbmd0aCA9PSAxICYmIG1hdGNoRGF0YVswXVsyXSkge1xuICAgIHJldHVybiBtYXRjaGVzU3RyaWN0Q29tcGFyYWJsZShtYXRjaERhdGFbMF1bMF0sIG1hdGNoRGF0YVswXVsxXSk7XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT09IHNvdXJjZSB8fCBiYXNlSXNNYXRjaChvYmplY3QsIHNvdXJjZSwgbWF0Y2hEYXRhKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlTWF0Y2hlcztcbiIsInZhciBiYXNlSXNFcXVhbCA9IHJlcXVpcmUoJy4vX2Jhc2VJc0VxdWFsJyksXG4gICAgZ2V0ID0gcmVxdWlyZSgnLi9nZXQnKSxcbiAgICBoYXNJbiA9IHJlcXVpcmUoJy4vaGFzSW4nKSxcbiAgICBpc0tleSA9IHJlcXVpcmUoJy4vX2lzS2V5JyksXG4gICAgaXNTdHJpY3RDb21wYXJhYmxlID0gcmVxdWlyZSgnLi9faXNTdHJpY3RDb21wYXJhYmxlJyksXG4gICAgbWF0Y2hlc1N0cmljdENvbXBhcmFibGUgPSByZXF1aXJlKCcuL19tYXRjaGVzU3RyaWN0Q29tcGFyYWJsZScpLFxuICAgIHRvS2V5ID0gcmVxdWlyZSgnLi9fdG9LZXknKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLm1hdGNoZXNQcm9wZXJ0eWAgd2hpY2ggZG9lc24ndCBjbG9uZSBgc3JjVmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHBhcmFtIHsqfSBzcmNWYWx1ZSBUaGUgdmFsdWUgdG8gbWF0Y2guXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBzcGVjIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlTWF0Y2hlc1Byb3BlcnR5KHBhdGgsIHNyY1ZhbHVlKSB7XG4gIGlmIChpc0tleShwYXRoKSAmJiBpc1N0cmljdENvbXBhcmFibGUoc3JjVmFsdWUpKSB7XG4gICAgcmV0dXJuIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKHRvS2V5KHBhdGgpLCBzcmNWYWx1ZSk7XG4gIH1cbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHZhciBvYmpWYWx1ZSA9IGdldChvYmplY3QsIHBhdGgpO1xuICAgIHJldHVybiAob2JqVmFsdWUgPT09IHVuZGVmaW5lZCAmJiBvYmpWYWx1ZSA9PT0gc3JjVmFsdWUpXG4gICAgICA/IGhhc0luKG9iamVjdCwgcGF0aClcbiAgICAgIDogYmFzZUlzRXF1YWwoc3JjVmFsdWUsIG9ialZhbHVlLCBDT01QQVJFX1BBUlRJQUxfRkxBRyB8IENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcpO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VNYXRjaGVzUHJvcGVydHk7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VQcm9wZXJ0eTtcbiIsInZhciBiYXNlR2V0ID0gcmVxdWlyZSgnLi9fYmFzZUdldCcpO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVByb3BlcnR5YCB3aGljaCBzdXBwb3J0cyBkZWVwIHBhdGhzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fHN0cmluZ30gcGF0aCBUaGUgcGF0aCBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eURlZXAocGF0aCkge1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgcmV0dXJuIGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlUHJvcGVydHlEZWVwO1xuIiwidmFyIGlkZW50aXR5ID0gcmVxdWlyZSgnLi9pZGVudGl0eScpLFxuICAgIG92ZXJSZXN0ID0gcmVxdWlyZSgnLi9fb3ZlclJlc3QnKSxcbiAgICBzZXRUb1N0cmluZyA9IHJlcXVpcmUoJy4vX3NldFRvU3RyaW5nJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucmVzdGAgd2hpY2ggZG9lc24ndCB2YWxpZGF0ZSBvciBjb2VyY2UgYXJndW1lbnRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBhcHBseSBhIHJlc3QgcGFyYW1ldGVyIHRvLlxuICogQHBhcmFtIHtudW1iZXJ9IFtzdGFydD1mdW5jLmxlbmd0aC0xXSBUaGUgc3RhcnQgcG9zaXRpb24gb2YgdGhlIHJlc3QgcGFyYW1ldGVyLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VSZXN0KGZ1bmMsIHN0YXJ0KSB7XG4gIHJldHVybiBzZXRUb1N0cmluZyhvdmVyUmVzdChmdW5jLCBzdGFydCwgaWRlbnRpdHkpLCBmdW5jICsgJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VSZXN0O1xuIiwidmFyIGlkZW50aXR5ID0gcmVxdWlyZSgnLi9pZGVudGl0eScpLFxuICAgIG1ldGFNYXAgPSByZXF1aXJlKCcuL19tZXRhTWFwJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYHNldERhdGFgIHdpdGhvdXQgc3VwcG9ydCBmb3IgaG90IGxvb3Agc2hvcnRpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBiYXNlU2V0RGF0YSA9ICFtZXRhTWFwID8gaWRlbnRpdHkgOiBmdW5jdGlvbihmdW5jLCBkYXRhKSB7XG4gIG1ldGFNYXAuc2V0KGZ1bmMsIGRhdGEpO1xuICByZXR1cm4gZnVuYztcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVNldERhdGE7XG4iLCJ2YXIgY29uc3RhbnQgPSByZXF1aXJlKCcuL2NvbnN0YW50JyksXG4gICAgZGVmaW5lUHJvcGVydHkgPSByZXF1aXJlKCcuL19kZWZpbmVQcm9wZXJ0eScpLFxuICAgIGlkZW50aXR5ID0gcmVxdWlyZSgnLi9pZGVudGl0eScpO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBzZXRUb1N0cmluZ2Agd2l0aG91dCBzdXBwb3J0IGZvciBob3QgbG9vcCBzaG9ydGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gc3RyaW5nIFRoZSBgdG9TdHJpbmdgIHJlc3VsdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBiYXNlU2V0VG9TdHJpbmcgPSAhZGVmaW5lUHJvcGVydHkgPyBpZGVudGl0eSA6IGZ1bmN0aW9uKGZ1bmMsIHN0cmluZykge1xuICByZXR1cm4gZGVmaW5lUHJvcGVydHkoZnVuYywgJ3RvU3RyaW5nJywge1xuICAgICdjb25maWd1cmFibGUnOiB0cnVlLFxuICAgICdlbnVtZXJhYmxlJzogZmFsc2UsXG4gICAgJ3ZhbHVlJzogY29uc3RhbnQoc3RyaW5nKSxcbiAgICAnd3JpdGFibGUnOiB0cnVlXG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlU2V0VG9TdHJpbmc7XG4iLCIvKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRpbWVzYCB3aXRob3V0IHN1cHBvcnQgZm9yIGl0ZXJhdGVlIHNob3J0aGFuZHNcbiAqIG9yIG1heCBhcnJheSBsZW5ndGggY2hlY2tzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge251bWJlcn0gbiBUaGUgbnVtYmVyIG9mIHRpbWVzIHRvIGludm9rZSBgaXRlcmF0ZWVgLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcmVzdWx0cy5cbiAqL1xuZnVuY3Rpb24gYmFzZVRpbWVzKG4sIGl0ZXJhdGVlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobik7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBuKSB7XG4gICAgcmVzdWx0W2luZGV4XSA9IGl0ZXJhdGVlKGluZGV4KTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUaW1lcztcbiIsInZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19TeW1ib2wnKSxcbiAgICBhcnJheU1hcCA9IHJlcXVpcmUoJy4vX2FycmF5TWFwJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzU3ltYm9sID0gcmVxdWlyZSgnLi9pc1N5bWJvbCcpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBJTkZJTklUWSA9IDEgLyAwO1xuXG4vKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbnZhciBzeW1ib2xQcm90byA9IFN5bWJvbCA/IFN5bWJvbC5wcm90b3R5cGUgOiB1bmRlZmluZWQsXG4gICAgc3ltYm9sVG9TdHJpbmcgPSBzeW1ib2xQcm90byA/IHN5bWJvbFByb3RvLnRvU3RyaW5nIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnRvU3RyaW5nYCB3aGljaCBkb2Vzbid0IGNvbnZlcnQgbnVsbGlzaFxuICogdmFsdWVzIHRvIGVtcHR5IHN0cmluZ3MuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIGJhc2VUb1N0cmluZyh2YWx1ZSkge1xuICAvLyBFeGl0IGVhcmx5IGZvciBzdHJpbmdzIHRvIGF2b2lkIGEgcGVyZm9ybWFuY2UgaGl0IGluIHNvbWUgZW52aXJvbm1lbnRzLlxuICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIC8vIFJlY3Vyc2l2ZWx5IGNvbnZlcnQgdmFsdWVzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgcmV0dXJuIGFycmF5TWFwKHZhbHVlLCBiYXNlVG9TdHJpbmcpICsgJyc7XG4gIH1cbiAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgIHJldHVybiBzeW1ib2xUb1N0cmluZyA/IHN5bWJvbFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7XG4gIH1cbiAgdmFyIHJlc3VsdCA9ICh2YWx1ZSArICcnKTtcbiAgcmV0dXJuIChyZXN1bHQgPT0gJzAnICYmICgxIC8gdmFsdWUpID09IC1JTkZJTklUWSkgPyAnLTAnIDogcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VUb1N0cmluZztcbiIsIi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8udW5hcnlgIHdpdGhvdXQgc3VwcG9ydCBmb3Igc3RvcmluZyBtZXRhZGF0YS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gY2FwIGFyZ3VtZW50cyBmb3IuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VVbmFyeShmdW5jKSB7XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiBmdW5jKHZhbHVlKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlVW5hcnk7XG4iLCJ2YXIgU2V0Q2FjaGUgPSByZXF1aXJlKCcuL19TZXRDYWNoZScpLFxuICAgIGFycmF5SW5jbHVkZXMgPSByZXF1aXJlKCcuL19hcnJheUluY2x1ZGVzJyksXG4gICAgYXJyYXlJbmNsdWRlc1dpdGggPSByZXF1aXJlKCcuL19hcnJheUluY2x1ZGVzV2l0aCcpLFxuICAgIGNhY2hlSGFzID0gcmVxdWlyZSgnLi9fY2FjaGVIYXMnKSxcbiAgICBjcmVhdGVTZXQgPSByZXF1aXJlKCcuL19jcmVhdGVTZXQnKSxcbiAgICBzZXRUb0FycmF5ID0gcmVxdWlyZSgnLi9fc2V0VG9BcnJheScpO1xuXG4vKiogVXNlZCBhcyB0aGUgc2l6ZSB0byBlbmFibGUgbGFyZ2UgYXJyYXkgb3B0aW1pemF0aW9ucy4gKi9cbnZhciBMQVJHRV9BUlJBWV9TSVpFID0gMjAwO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnVuaXFCeWAgd2l0aG91dCBzdXBwb3J0IGZvciBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZV0gVGhlIGl0ZXJhdGVlIGludm9rZWQgcGVyIGVsZW1lbnQuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyYXRvcl0gVGhlIGNvbXBhcmF0b3IgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGR1cGxpY2F0ZSBmcmVlIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlVW5pcShhcnJheSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBpbmNsdWRlcyA9IGFycmF5SW5jbHVkZXMsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBpc0NvbW1vbiA9IHRydWUsXG4gICAgICByZXN1bHQgPSBbXSxcbiAgICAgIHNlZW4gPSByZXN1bHQ7XG5cbiAgaWYgKGNvbXBhcmF0b3IpIHtcbiAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgIGluY2x1ZGVzID0gYXJyYXlJbmNsdWRlc1dpdGg7XG4gIH1cbiAgZWxzZSBpZiAobGVuZ3RoID49IExBUkdFX0FSUkFZX1NJWkUpIHtcbiAgICB2YXIgc2V0ID0gaXRlcmF0ZWUgPyBudWxsIDogY3JlYXRlU2V0KGFycmF5KTtcbiAgICBpZiAoc2V0KSB7XG4gICAgICByZXR1cm4gc2V0VG9BcnJheShzZXQpO1xuICAgIH1cbiAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICAgIGluY2x1ZGVzID0gY2FjaGVIYXM7XG4gICAgc2VlbiA9IG5ldyBTZXRDYWNoZTtcbiAgfVxuICBlbHNlIHtcbiAgICBzZWVuID0gaXRlcmF0ZWUgPyBbXSA6IHJlc3VsdDtcbiAgfVxuICBvdXRlcjpcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSkgOiB2YWx1ZTtcblxuICAgIHZhbHVlID0gKGNvbXBhcmF0b3IgfHwgdmFsdWUgIT09IDApID8gdmFsdWUgOiAwO1xuICAgIGlmIChpc0NvbW1vbiAmJiBjb21wdXRlZCA9PT0gY29tcHV0ZWQpIHtcbiAgICAgIHZhciBzZWVuSW5kZXggPSBzZWVuLmxlbmd0aDtcbiAgICAgIHdoaWxlIChzZWVuSW5kZXgtLSkge1xuICAgICAgICBpZiAoc2VlbltzZWVuSW5kZXhdID09PSBjb21wdXRlZCkge1xuICAgICAgICAgIGNvbnRpbnVlIG91dGVyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoaXRlcmF0ZWUpIHtcbiAgICAgICAgc2Vlbi5wdXNoKGNvbXB1dGVkKTtcbiAgICAgIH1cbiAgICAgIHJlc3VsdC5wdXNoKHZhbHVlKTtcbiAgICB9XG4gICAgZWxzZSBpZiAoIWluY2x1ZGVzKHNlZW4sIGNvbXB1dGVkLCBjb21wYXJhdG9yKSkge1xuICAgICAgaWYgKHNlZW4gIT09IHJlc3VsdCkge1xuICAgICAgICBzZWVuLnB1c2goY29tcHV0ZWQpO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VVbmlxO1xuIiwidmFyIGFycmF5TWFwID0gcmVxdWlyZSgnLi9fYXJyYXlNYXAnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy52YWx1ZXNgIGFuZCBgXy52YWx1ZXNJbmAgd2hpY2ggY3JlYXRlcyBhblxuICogYXJyYXkgb2YgYG9iamVjdGAgcHJvcGVydHkgdmFsdWVzIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHByb3BlcnR5IG5hbWVzXG4gKiBvZiBgcHJvcHNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgbmFtZXMgdG8gZ2V0IHZhbHVlcyBmb3IuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSB2YWx1ZXMuXG4gKi9cbmZ1bmN0aW9uIGJhc2VWYWx1ZXMob2JqZWN0LCBwcm9wcykge1xuICByZXR1cm4gYXJyYXlNYXAocHJvcHMsIGZ1bmN0aW9uKGtleSkge1xuICAgIHJldHVybiBvYmplY3Rba2V5XTtcbiAgfSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVZhbHVlcztcbiIsInZhciBiYXNlRGlmZmVyZW5jZSA9IHJlcXVpcmUoJy4vX2Jhc2VEaWZmZXJlbmNlJyksXG4gICAgYmFzZUZsYXR0ZW4gPSByZXF1aXJlKCcuL19iYXNlRmxhdHRlbicpLFxuICAgIGJhc2VVbmlxID0gcmVxdWlyZSgnLi9fYmFzZVVuaXEnKTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBtZXRob2RzIGxpa2UgYF8ueG9yYCwgd2l0aG91dCBzdXBwb3J0IGZvclxuICogaXRlcmF0ZWUgc2hvcnRoYW5kcywgdGhhdCBhY2NlcHRzIGFuIGFycmF5IG9mIGFycmF5cyB0byBpbnNwZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheXMgVGhlIGFycmF5cyB0byBpbnNwZWN0LlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlXSBUaGUgaXRlcmF0ZWUgaW52b2tlZCBwZXIgZWxlbWVudC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJhdG9yXSBUaGUgY29tcGFyYXRvciBpbnZva2VkIHBlciBlbGVtZW50LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBiYXNlWG9yKGFycmF5cywgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5cy5sZW5ndGg7XG4gIGlmIChsZW5ndGggPCAyKSB7XG4gICAgcmV0dXJuIGxlbmd0aCA/IGJhc2VVbmlxKGFycmF5c1swXSkgOiBbXTtcbiAgfVxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IEFycmF5KGxlbmd0aCk7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgYXJyYXkgPSBhcnJheXNbaW5kZXhdLFxuICAgICAgICBvdGhJbmRleCA9IC0xO1xuXG4gICAgd2hpbGUgKCsrb3RoSW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGlmIChvdGhJbmRleCAhPSBpbmRleCkge1xuICAgICAgICByZXN1bHRbaW5kZXhdID0gYmFzZURpZmZlcmVuY2UocmVzdWx0W2luZGV4XSB8fCBhcnJheSwgYXJyYXlzW290aEluZGV4XSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gYmFzZVVuaXEoYmFzZUZsYXR0ZW4ocmVzdWx0LCAxKSwgaXRlcmF0ZWUsIGNvbXBhcmF0b3IpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJhc2VYb3I7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBhIGBjYWNoZWAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IGNhY2hlIFRoZSBjYWNoZSB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBjYWNoZUhhcyhjYWNoZSwga2V5KSB7XG4gIHJldHVybiBjYWNoZS5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjYWNoZUhhcztcbiIsInZhciBpZGVudGl0eSA9IHJlcXVpcmUoJy4vaWRlbnRpdHknKTtcblxuLyoqXG4gKiBDYXN0cyBgdmFsdWVgIHRvIGBpZGVudGl0eWAgaWYgaXQncyBub3QgYSBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBjYXN0IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjYXN0RnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnZnVuY3Rpb24nID8gdmFsdWUgOiBpZGVudGl0eTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjYXN0RnVuY3Rpb247XG4iLCJ2YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzS2V5ID0gcmVxdWlyZSgnLi9faXNLZXknKSxcbiAgICBzdHJpbmdUb1BhdGggPSByZXF1aXJlKCcuL19zdHJpbmdUb1BhdGgnKSxcbiAgICB0b1N0cmluZyA9IHJlcXVpcmUoJy4vdG9TdHJpbmcnKTtcblxuLyoqXG4gKiBDYXN0cyBgdmFsdWVgIHRvIGEgcGF0aCBhcnJheSBpZiBpdCdzIG5vdCBvbmUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge09iamVjdH0gW29iamVjdF0gVGhlIG9iamVjdCB0byBxdWVyeSBrZXlzIG9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBjYXN0IHByb3BlcnR5IHBhdGggYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGNhc3RQYXRoKHZhbHVlLCBvYmplY3QpIHtcbiAgaWYgKGlzQXJyYXkodmFsdWUpKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIHJldHVybiBpc0tleSh2YWx1ZSwgb2JqZWN0KSA/IFt2YWx1ZV0gOiBzdHJpbmdUb1BhdGgodG9TdHJpbmcodmFsdWUpKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjYXN0UGF0aDtcbiIsIi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IHRoYXQgaXMgdGhlIGNvbXBvc2l0aW9uIG9mIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cyxcbiAqIHBsYWNlaG9sZGVycywgYW5kIHByb3ZpZGVkIGFyZ3VtZW50cyBpbnRvIGEgc2luZ2xlIGFycmF5IG9mIGFyZ3VtZW50cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkLlxuICogQHBhcmFtIHtBcnJheX0gaG9sZGVycyBUaGUgYHBhcnRpYWxzYCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHBhcmFtcyB7Ym9vbGVhbn0gW2lzQ3VycmllZF0gU3BlY2lmeSBjb21wb3NpbmcgZm9yIGEgY3VycmllZCBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbXBvc2VkIGFyZ3VtZW50cy5cbiAqL1xuZnVuY3Rpb24gY29tcG9zZUFyZ3MoYXJncywgcGFydGlhbHMsIGhvbGRlcnMsIGlzQ3VycmllZCkge1xuICB2YXIgYXJnc0luZGV4ID0gLTEsXG4gICAgICBhcmdzTGVuZ3RoID0gYXJncy5sZW5ndGgsXG4gICAgICBob2xkZXJzTGVuZ3RoID0gaG9sZGVycy5sZW5ndGgsXG4gICAgICBsZWZ0SW5kZXggPSAtMSxcbiAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICByYW5nZUxlbmd0aCA9IG5hdGl2ZU1heChhcmdzTGVuZ3RoIC0gaG9sZGVyc0xlbmd0aCwgMCksXG4gICAgICByZXN1bHQgPSBBcnJheShsZWZ0TGVuZ3RoICsgcmFuZ2VMZW5ndGgpLFxuICAgICAgaXNVbmN1cnJpZWQgPSAhaXNDdXJyaWVkO1xuXG4gIHdoaWxlICgrK2xlZnRJbmRleCA8IGxlZnRMZW5ndGgpIHtcbiAgICByZXN1bHRbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gIH1cbiAgd2hpbGUgKCsrYXJnc0luZGV4IDwgaG9sZGVyc0xlbmd0aCkge1xuICAgIGlmIChpc1VuY3VycmllZCB8fCBhcmdzSW5kZXggPCBhcmdzTGVuZ3RoKSB7XG4gICAgICByZXN1bHRbaG9sZGVyc1thcmdzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4XTtcbiAgICB9XG4gIH1cbiAgd2hpbGUgKHJhbmdlTGVuZ3RoLS0pIHtcbiAgICByZXN1bHRbbGVmdEluZGV4KytdID0gYXJnc1thcmdzSW5kZXgrK107XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb21wb3NlQXJncztcbiIsIi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heDtcblxuLyoqXG4gKiBUaGlzIGZ1bmN0aW9uIGlzIGxpa2UgYGNvbXBvc2VBcmdzYCBleGNlcHQgdGhhdCB0aGUgYXJndW1lbnRzIGNvbXBvc2l0aW9uXG4gKiBpcyB0YWlsb3JlZCBmb3IgYF8ucGFydGlhbFJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJncyBUaGUgcHJvdmlkZWQgYXJndW1lbnRzLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBob2xkZXJzIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW1zIHtib29sZWFufSBbaXNDdXJyaWVkXSBTcGVjaWZ5IGNvbXBvc2luZyBmb3IgYSBjdXJyaWVkIGZ1bmN0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgYXJyYXkgb2YgY29tcG9zZWQgYXJndW1lbnRzLlxuICovXG5mdW5jdGlvbiBjb21wb3NlQXJnc1JpZ2h0KGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpIHtcbiAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgYXJnc0xlbmd0aCA9IGFyZ3MubGVuZ3RoLFxuICAgICAgaG9sZGVyc0luZGV4ID0gLTEsXG4gICAgICBob2xkZXJzTGVuZ3RoID0gaG9sZGVycy5sZW5ndGgsXG4gICAgICByaWdodEluZGV4ID0gLTEsXG4gICAgICByaWdodExlbmd0aCA9IHBhcnRpYWxzLmxlbmd0aCxcbiAgICAgIHJhbmdlTGVuZ3RoID0gbmF0aXZlTWF4KGFyZ3NMZW5ndGggLSBob2xkZXJzTGVuZ3RoLCAwKSxcbiAgICAgIHJlc3VsdCA9IEFycmF5KHJhbmdlTGVuZ3RoICsgcmlnaHRMZW5ndGgpLFxuICAgICAgaXNVbmN1cnJpZWQgPSAhaXNDdXJyaWVkO1xuXG4gIHdoaWxlICgrK2FyZ3NJbmRleCA8IHJhbmdlTGVuZ3RoKSB7XG4gICAgcmVzdWx0W2FyZ3NJbmRleF0gPSBhcmdzW2FyZ3NJbmRleF07XG4gIH1cbiAgdmFyIG9mZnNldCA9IGFyZ3NJbmRleDtcbiAgd2hpbGUgKCsrcmlnaHRJbmRleCA8IHJpZ2h0TGVuZ3RoKSB7XG4gICAgcmVzdWx0W29mZnNldCArIHJpZ2h0SW5kZXhdID0gcGFydGlhbHNbcmlnaHRJbmRleF07XG4gIH1cbiAgd2hpbGUgKCsraG9sZGVyc0luZGV4IDwgaG9sZGVyc0xlbmd0aCkge1xuICAgIGlmIChpc1VuY3VycmllZCB8fCBhcmdzSW5kZXggPCBhcmdzTGVuZ3RoKSB7XG4gICAgICByZXN1bHRbb2Zmc2V0ICsgaG9sZGVyc1tob2xkZXJzSW5kZXhdXSA9IGFyZ3NbYXJnc0luZGV4KytdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbXBvc2VBcmdzUmlnaHQ7XG4iLCIvKipcbiAqIENvcGllcyB0aGUgdmFsdWVzIG9mIGBzb3VyY2VgIHRvIGBhcnJheWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZSBUaGUgYXJyYXkgdG8gY29weSB2YWx1ZXMgZnJvbS5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcnJheT1bXV0gVGhlIGFycmF5IHRvIGNvcHkgdmFsdWVzIHRvLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIGBhcnJheWAuXG4gKi9cbmZ1bmN0aW9uIGNvcHlBcnJheShzb3VyY2UsIGFycmF5KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gc291cmNlLmxlbmd0aDtcblxuICBhcnJheSB8fCAoYXJyYXkgPSBBcnJheShsZW5ndGgpKTtcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtpbmRleF0gPSBzb3VyY2VbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5QXJyYXk7XG4iLCJ2YXIgYXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19hc3NpZ25WYWx1ZScpLFxuICAgIGJhc2VBc3NpZ25WYWx1ZSA9IHJlcXVpcmUoJy4vX2Jhc2VBc3NpZ25WYWx1ZScpO1xuXG4vKipcbiAqIENvcGllcyBwcm9wZXJ0aWVzIG9mIGBzb3VyY2VgIHRvIGBvYmplY3RgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gc291cmNlIFRoZSBvYmplY3QgdG8gY29weSBwcm9wZXJ0aWVzIGZyb20uXG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wcyBUaGUgcHJvcGVydHkgaWRlbnRpZmllcnMgdG8gY29weS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0PXt9XSBUaGUgb2JqZWN0IHRvIGNvcHkgcHJvcGVydGllcyB0by5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjdXN0b21pemVyXSBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvcGllZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBjb3B5T2JqZWN0KHNvdXJjZSwgcHJvcHMsIG9iamVjdCwgY3VzdG9taXplcikge1xuICB2YXIgaXNOZXcgPSAhb2JqZWN0O1xuICBvYmplY3QgfHwgKG9iamVjdCA9IHt9KTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XG5cbiAgICB2YXIgbmV3VmFsdWUgPSBjdXN0b21pemVyXG4gICAgICA/IGN1c3RvbWl6ZXIob2JqZWN0W2tleV0sIHNvdXJjZVtrZXldLCBrZXksIG9iamVjdCwgc291cmNlKVxuICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICBpZiAobmV3VmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgbmV3VmFsdWUgPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gICAgaWYgKGlzTmV3KSB7XG4gICAgICBiYXNlQXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXNzaWduVmFsdWUob2JqZWN0LCBrZXksIG5ld1ZhbHVlKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG9iamVjdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3B5T2JqZWN0O1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvdmVycmVhY2hpbmcgY29yZS1qcyBzaGltcy4gKi9cbnZhciBjb3JlSnNEYXRhID0gcm9vdFsnX19jb3JlLWpzX3NoYXJlZF9fJ107XG5cbm1vZHVsZS5leHBvcnRzID0gY29yZUpzRGF0YTtcbiIsIi8qKlxuICogR2V0cyB0aGUgbnVtYmVyIG9mIGBwbGFjZWhvbGRlcmAgb2NjdXJyZW5jZXMgaW4gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0geyp9IHBsYWNlaG9sZGVyIFRoZSBwbGFjZWhvbGRlciB0byBzZWFyY2ggZm9yLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgcGxhY2Vob2xkZXIgY291bnQuXG4gKi9cbmZ1bmN0aW9uIGNvdW50SG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IDA7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgaWYgKGFycmF5W2xlbmd0aF0gPT09IHBsYWNlaG9sZGVyKSB7XG4gICAgICArK3Jlc3VsdDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjb3VudEhvbGRlcnM7XG4iLCJ2YXIgYXJyYXlBZ2dyZWdhdG9yID0gcmVxdWlyZSgnLi9fYXJyYXlBZ2dyZWdhdG9yJyksXG4gICAgYmFzZUFnZ3JlZ2F0b3IgPSByZXF1aXJlKCcuL19iYXNlQWdncmVnYXRvcicpLFxuICAgIGJhc2VJdGVyYXRlZSA9IHJlcXVpcmUoJy4vX2Jhc2VJdGVyYXRlZScpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5ncm91cEJ5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gc2V0dGVyIFRoZSBmdW5jdGlvbiB0byBzZXQgYWNjdW11bGF0b3IgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2luaXRpYWxpemVyXSBUaGUgYWNjdW11bGF0b3Igb2JqZWN0IGluaXRpYWxpemVyLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWdncmVnYXRvciBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlQWdncmVnYXRvcihzZXR0ZXIsIGluaXRpYWxpemVyKSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICAgIHZhciBmdW5jID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IGFycmF5QWdncmVnYXRvciA6IGJhc2VBZ2dyZWdhdG9yLFxuICAgICAgICBhY2N1bXVsYXRvciA9IGluaXRpYWxpemVyID8gaW5pdGlhbGl6ZXIoKSA6IHt9O1xuXG4gICAgcmV0dXJuIGZ1bmMoY29sbGVjdGlvbiwgc2V0dGVyLCBiYXNlSXRlcmF0ZWUoaXRlcmF0ZWUsIDIpLCBhY2N1bXVsYXRvcik7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQWdncmVnYXRvcjtcbiIsInZhciBiYXNlUmVzdCA9IHJlcXVpcmUoJy4vX2Jhc2VSZXN0JyksXG4gICAgaXNJdGVyYXRlZUNhbGwgPSByZXF1aXJlKCcuL19pc0l0ZXJhdGVlQ2FsbCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiBsaWtlIGBfLmFzc2lnbmAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFzc2lnbmVyIFRoZSBmdW5jdGlvbiB0byBhc3NpZ24gdmFsdWVzLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYXNzaWduZXIgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUFzc2lnbmVyKGFzc2lnbmVyKSB7XG4gIHJldHVybiBiYXNlUmVzdChmdW5jdGlvbihvYmplY3QsIHNvdXJjZXMpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgbGVuZ3RoID0gc291cmNlcy5sZW5ndGgsXG4gICAgICAgIGN1c3RvbWl6ZXIgPSBsZW5ndGggPiAxID8gc291cmNlc1tsZW5ndGggLSAxXSA6IHVuZGVmaW5lZCxcbiAgICAgICAgZ3VhcmQgPSBsZW5ndGggPiAyID8gc291cmNlc1syXSA6IHVuZGVmaW5lZDtcblxuICAgIGN1c3RvbWl6ZXIgPSAoYXNzaWduZXIubGVuZ3RoID4gMyAmJiB0eXBlb2YgY3VzdG9taXplciA9PSAnZnVuY3Rpb24nKVxuICAgICAgPyAobGVuZ3RoLS0sIGN1c3RvbWl6ZXIpXG4gICAgICA6IHVuZGVmaW5lZDtcblxuICAgIGlmIChndWFyZCAmJiBpc0l0ZXJhdGVlQ2FsbChzb3VyY2VzWzBdLCBzb3VyY2VzWzFdLCBndWFyZCkpIHtcbiAgICAgIGN1c3RvbWl6ZXIgPSBsZW5ndGggPCAzID8gdW5kZWZpbmVkIDogY3VzdG9taXplcjtcbiAgICAgIGxlbmd0aCA9IDE7XG4gICAgfVxuICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICB2YXIgc291cmNlID0gc291cmNlc1tpbmRleF07XG4gICAgICBpZiAoc291cmNlKSB7XG4gICAgICAgIGFzc2lnbmVyKG9iamVjdCwgc291cmNlLCBpbmRleCwgY3VzdG9taXplcik7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmplY3Q7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUFzc2lnbmVyO1xuIiwidmFyIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgYmFzZUVhY2hgIG9yIGBiYXNlRWFjaFJpZ2h0YCBmdW5jdGlvbi5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZWFjaEZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGl0ZXJhdGUgb3ZlciBhIGNvbGxlY3Rpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VFYWNoKGVhY2hGdW5jLCBmcm9tUmlnaHQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbGxlY3Rpb24sIGl0ZXJhdGVlKSB7XG4gICAgaWYgKGNvbGxlY3Rpb24gPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGNvbGxlY3Rpb247XG4gICAgfVxuICAgIGlmICghaXNBcnJheUxpa2UoY29sbGVjdGlvbikpIHtcbiAgICAgIHJldHVybiBlYWNoRnVuYyhjb2xsZWN0aW9uLCBpdGVyYXRlZSk7XG4gICAgfVxuICAgIHZhciBsZW5ndGggPSBjb2xsZWN0aW9uLmxlbmd0aCxcbiAgICAgICAgaW5kZXggPSBmcm9tUmlnaHQgPyBsZW5ndGggOiAtMSxcbiAgICAgICAgaXRlcmFibGUgPSBPYmplY3QoY29sbGVjdGlvbik7XG5cbiAgICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2luZGV4XSwgaW5kZXgsIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb2xsZWN0aW9uO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUJhc2VFYWNoO1xuIiwiLyoqXG4gKiBDcmVhdGVzIGEgYmFzZSBmdW5jdGlvbiBmb3IgbWV0aG9kcyBsaWtlIGBfLmZvckluYCBhbmQgYF8uZm9yT3duYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBiYXNlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVCYXNlRm9yKGZyb21SaWdodCkge1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0LCBpdGVyYXRlZSwga2V5c0Z1bmMpIHtcbiAgICB2YXIgaW5kZXggPSAtMSxcbiAgICAgICAgaXRlcmFibGUgPSBPYmplY3Qob2JqZWN0KSxcbiAgICAgICAgcHJvcHMgPSBrZXlzRnVuYyhvYmplY3QpLFxuICAgICAgICBsZW5ndGggPSBwcm9wcy5sZW5ndGg7XG5cbiAgICB3aGlsZSAobGVuZ3RoLS0pIHtcbiAgICAgIHZhciBrZXkgPSBwcm9wc1tmcm9tUmlnaHQgPyBsZW5ndGggOiArK2luZGV4XTtcbiAgICAgIGlmIChpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKSA9PT0gZmFsc2UpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmplY3Q7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQmFzZUZvcjtcbiIsInZhciBjcmVhdGVDdG9yID0gcmVxdWlyZSgnLi9fY3JlYXRlQ3RvcicpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xudmFyIFdSQVBfQklORF9GTEFHID0gMTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gaW52b2tlIGl0IHdpdGggdGhlIG9wdGlvbmFsIGB0aGlzYFxuICogYmluZGluZyBvZiBgdGhpc0FyZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJpbmQoZnVuYywgYml0bWFzaywgdGhpc0FyZykge1xuICB2YXIgaXNCaW5kID0gYml0bWFzayAmIFdSQVBfQklORF9GTEFHLFxuICAgICAgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICB2YXIgZm4gPSAodGhpcyAmJiB0aGlzICE9PSByb290ICYmIHRoaXMgaW5zdGFuY2VvZiB3cmFwcGVyKSA/IEN0b3IgOiBmdW5jO1xuICAgIHJldHVybiBmbi5hcHBseShpc0JpbmQgPyB0aGlzQXJnIDogdGhpcywgYXJndW1lbnRzKTtcbiAgfVxuICByZXR1cm4gd3JhcHBlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVCaW5kO1xuIiwidmFyIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL19iYXNlQ3JlYXRlJyksXG4gICAgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcHJvZHVjZXMgYW4gaW5zdGFuY2Ugb2YgYEN0b3JgIHJlZ2FyZGxlc3Mgb2ZcbiAqIHdoZXRoZXIgaXQgd2FzIGludm9rZWQgYXMgcGFydCBvZiBhIGBuZXdgIGV4cHJlc3Npb24gb3IgYnkgYGNhbGxgIG9yIGBhcHBseWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IEN0b3IgVGhlIGNvbnN0cnVjdG9yIHRvIHdyYXAuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdG9yKEN0b3IpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIC8vIFVzZSBhIGBzd2l0Y2hgIHN0YXRlbWVudCB0byB3b3JrIHdpdGggY2xhc3MgY29uc3RydWN0b3JzLiBTZWVcbiAgICAvLyBodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1lY21hc2NyaXB0LWZ1bmN0aW9uLW9iamVjdHMtY2FsbC10aGlzYXJndW1lbnQtYXJndW1lbnRzbGlzdFxuICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHM7XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gbmV3IEN0b3I7XG4gICAgICBjYXNlIDE6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdKTtcbiAgICAgIGNhc2UgMjogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0pO1xuICAgICAgY2FzZSAzOiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICBjYXNlIDQ6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdKTtcbiAgICAgIGNhc2UgNTogcmV0dXJuIG5ldyBDdG9yKGFyZ3NbMF0sIGFyZ3NbMV0sIGFyZ3NbMl0sIGFyZ3NbM10sIGFyZ3NbNF0pO1xuICAgICAgY2FzZSA2OiByZXR1cm4gbmV3IEN0b3IoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSwgYXJnc1s1XSk7XG4gICAgICBjYXNlIDc6IHJldHVybiBuZXcgQ3RvcihhcmdzWzBdLCBhcmdzWzFdLCBhcmdzWzJdLCBhcmdzWzNdLCBhcmdzWzRdLCBhcmdzWzVdLCBhcmdzWzZdKTtcbiAgICB9XG4gICAgdmFyIHRoaXNCaW5kaW5nID0gYmFzZUNyZWF0ZShDdG9yLnByb3RvdHlwZSksXG4gICAgICAgIHJlc3VsdCA9IEN0b3IuYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuXG4gICAgLy8gTWltaWMgdGhlIGNvbnN0cnVjdG9yJ3MgYHJldHVybmAgYmVoYXZpb3IuXG4gICAgLy8gU2VlIGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDEzLjIuMiBmb3IgbW9yZSBkZXRhaWxzLlxuICAgIHJldHVybiBpc09iamVjdChyZXN1bHQpID8gcmVzdWx0IDogdGhpc0JpbmRpbmc7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlQ3RvcjtcbiIsInZhciBhcHBseSA9IHJlcXVpcmUoJy4vX2FwcGx5JyksXG4gICAgY3JlYXRlQ3RvciA9IHJlcXVpcmUoJy4vX2NyZWF0ZUN0b3InKSxcbiAgICBjcmVhdGVIeWJyaWQgPSByZXF1aXJlKCcuL19jcmVhdGVIeWJyaWQnKSxcbiAgICBjcmVhdGVSZWN1cnJ5ID0gcmVxdWlyZSgnLi9fY3JlYXRlUmVjdXJyeScpLFxuICAgIGdldEhvbGRlciA9IHJlcXVpcmUoJy4vX2dldEhvbGRlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi9fcmVwbGFjZUhvbGRlcnMnKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHdyYXBzIGBmdW5jYCB0byBlbmFibGUgY3VycnlpbmcuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHdyYXAuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBjcmVhdGVXcmFwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtudW1iZXJ9IGFyaXR5IFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDdXJyeShmdW5jLCBiaXRtYXNrLCBhcml0eSkge1xuICB2YXIgQ3RvciA9IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgIGluZGV4ID0gbGVuZ3RoLFxuICAgICAgICBwbGFjZWhvbGRlciA9IGdldEhvbGRlcih3cmFwcGVyKTtcblxuICAgIHdoaWxlIChpbmRleC0tKSB7XG4gICAgICBhcmdzW2luZGV4XSA9IGFyZ3VtZW50c1tpbmRleF07XG4gICAgfVxuICAgIHZhciBob2xkZXJzID0gKGxlbmd0aCA8IDMgJiYgYXJnc1swXSAhPT0gcGxhY2Vob2xkZXIgJiYgYXJnc1tsZW5ndGggLSAxXSAhPT0gcGxhY2Vob2xkZXIpXG4gICAgICA/IFtdXG4gICAgICA6IHJlcGxhY2VIb2xkZXJzKGFyZ3MsIHBsYWNlaG9sZGVyKTtcblxuICAgIGxlbmd0aCAtPSBob2xkZXJzLmxlbmd0aDtcbiAgICBpZiAobGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgIHJldHVybiBjcmVhdGVSZWN1cnJ5KFxuICAgICAgICBmdW5jLCBiaXRtYXNrLCBjcmVhdGVIeWJyaWQsIHdyYXBwZXIucGxhY2Vob2xkZXIsIHVuZGVmaW5lZCxcbiAgICAgICAgYXJncywgaG9sZGVycywgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGFyaXR5IC0gbGVuZ3RoKTtcbiAgICB9XG4gICAgdmFyIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcbiAgICByZXR1cm4gYXBwbHkoZm4sIHRoaXMsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUN1cnJ5O1xuIiwidmFyIGJhc2VJdGVyYXRlZSA9IHJlcXVpcmUoJy4vX2Jhc2VJdGVyYXRlZScpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuL2tleXMnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgYF8uZmluZGAgb3IgYF8uZmluZExhc3RgIGZ1bmN0aW9uLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmaW5kSW5kZXhGdW5jIFRoZSBmdW5jdGlvbiB0byBmaW5kIHRoZSBjb2xsZWN0aW9uIGluZGV4LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZmluZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlRmluZChmaW5kSW5kZXhGdW5jKSB7XG4gIHJldHVybiBmdW5jdGlvbihjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICAgIHZhciBpdGVyYWJsZSA9IE9iamVjdChjb2xsZWN0aW9uKTtcbiAgICBpZiAoIWlzQXJyYXlMaWtlKGNvbGxlY3Rpb24pKSB7XG4gICAgICB2YXIgaXRlcmF0ZWUgPSBiYXNlSXRlcmF0ZWUocHJlZGljYXRlLCAzKTtcbiAgICAgIGNvbGxlY3Rpb24gPSBrZXlzKGNvbGxlY3Rpb24pO1xuICAgICAgcHJlZGljYXRlID0gZnVuY3Rpb24oa2V5KSB7IHJldHVybiBpdGVyYXRlZShpdGVyYWJsZVtrZXldLCBrZXksIGl0ZXJhYmxlKTsgfTtcbiAgICB9XG4gICAgdmFyIGluZGV4ID0gZmluZEluZGV4RnVuYyhjb2xsZWN0aW9uLCBwcmVkaWNhdGUsIGZyb21JbmRleCk7XG4gICAgcmV0dXJuIGluZGV4ID4gLTEgPyBpdGVyYWJsZVtpdGVyYXRlZSA/IGNvbGxlY3Rpb25baW5kZXhdIDogaW5kZXhdIDogdW5kZWZpbmVkO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUZpbmQ7XG4iLCJ2YXIgY29tcG9zZUFyZ3MgPSByZXF1aXJlKCcuL19jb21wb3NlQXJncycpLFxuICAgIGNvbXBvc2VBcmdzUmlnaHQgPSByZXF1aXJlKCcuL19jb21wb3NlQXJnc1JpZ2h0JyksXG4gICAgY291bnRIb2xkZXJzID0gcmVxdWlyZSgnLi9fY291bnRIb2xkZXJzJyksXG4gICAgY3JlYXRlQ3RvciA9IHJlcXVpcmUoJy4vX2NyZWF0ZUN0b3InKSxcbiAgICBjcmVhdGVSZWN1cnJ5ID0gcmVxdWlyZSgnLi9fY3JlYXRlUmVjdXJyeScpLFxuICAgIGdldEhvbGRlciA9IHJlcXVpcmUoJy4vX2dldEhvbGRlcicpLFxuICAgIHJlb3JkZXIgPSByZXF1aXJlKCcuL19yZW9yZGVyJyksXG4gICAgcmVwbGFjZUhvbGRlcnMgPSByZXF1aXJlKCcuL19yZXBsYWNlSG9sZGVycycpLFxuICAgIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xudmFyIFdSQVBfQklORF9GTEFHID0gMSxcbiAgICBXUkFQX0JJTkRfS0VZX0ZMQUcgPSAyLFxuICAgIFdSQVBfQ1VSUllfRkxBRyA9IDgsXG4gICAgV1JBUF9DVVJSWV9SSUdIVF9GTEFHID0gMTYsXG4gICAgV1JBUF9BUllfRkxBRyA9IDEyOCxcbiAgICBXUkFQX0ZMSVBfRkxBRyA9IDUxMjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCB3cmFwcyBgZnVuY2AgdG8gaW52b2tlIGl0IHdpdGggb3B0aW9uYWwgYHRoaXNgXG4gKiBiaW5kaW5nIG9mIGB0aGlzQXJnYCwgcGFydGlhbCBhcHBsaWNhdGlvbiwgYW5kIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufHN0cmluZ30gZnVuYyBUaGUgZnVuY3Rpb24gb3IgbWV0aG9kIG5hbWUgdG8gd3JhcC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAqICB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNSaWdodF0gVGhlIGFyZ3VtZW50cyB0byBhcHBlbmQgdG8gdGhvc2UgcHJvdmlkZWRcbiAqICB0byB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNSaWdodF0gVGhlIGBwYXJ0aWFsc1JpZ2h0YCBwbGFjZWhvbGRlciBpbmRleGVzLlxuICogQHBhcmFtIHtBcnJheX0gW2FyZ1Bvc10gVGhlIGFyZ3VtZW50IHBvc2l0aW9ucyBvZiB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcnldIFRoZSBhcml0eSBjYXAgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtudW1iZXJ9IFthcml0eV0gVGhlIGFyaXR5IG9mIGBmdW5jYC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUh5YnJpZChmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBwYXJ0aWFscywgaG9sZGVycywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgdmFyIGlzQXJ5ID0gYml0bWFzayAmIFdSQVBfQVJZX0ZMQUcsXG4gICAgICBpc0JpbmQgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcsXG4gICAgICBpc0JpbmRLZXkgPSBiaXRtYXNrICYgV1JBUF9CSU5EX0tFWV9GTEFHLFxuICAgICAgaXNDdXJyaWVkID0gYml0bWFzayAmIChXUkFQX0NVUlJZX0ZMQUcgfCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcpLFxuICAgICAgaXNGbGlwID0gYml0bWFzayAmIFdSQVBfRkxJUF9GTEFHLFxuICAgICAgQ3RvciA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGNyZWF0ZUN0b3IoZnVuYyk7XG5cbiAgZnVuY3Rpb24gd3JhcHBlcigpIHtcbiAgICB2YXIgbGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgYXJncyA9IEFycmF5KGxlbmd0aCksXG4gICAgICAgIGluZGV4ID0gbGVuZ3RoO1xuXG4gICAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICAgIGFyZ3NbaW5kZXhdID0gYXJndW1lbnRzW2luZGV4XTtcbiAgICB9XG4gICAgaWYgKGlzQ3VycmllZCkge1xuICAgICAgdmFyIHBsYWNlaG9sZGVyID0gZ2V0SG9sZGVyKHdyYXBwZXIpLFxuICAgICAgICAgIGhvbGRlcnNDb3VudCA9IGNvdW50SG9sZGVycyhhcmdzLCBwbGFjZWhvbGRlcik7XG4gICAgfVxuICAgIGlmIChwYXJ0aWFscykge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzKGFyZ3MsIHBhcnRpYWxzLCBob2xkZXJzLCBpc0N1cnJpZWQpO1xuICAgIH1cbiAgICBpZiAocGFydGlhbHNSaWdodCkge1xuICAgICAgYXJncyA9IGNvbXBvc2VBcmdzUmlnaHQoYXJncywgcGFydGlhbHNSaWdodCwgaG9sZGVyc1JpZ2h0LCBpc0N1cnJpZWQpO1xuICAgIH1cbiAgICBsZW5ndGggLT0gaG9sZGVyc0NvdW50O1xuICAgIGlmIChpc0N1cnJpZWQgJiYgbGVuZ3RoIDwgYXJpdHkpIHtcbiAgICAgIHZhciBuZXdIb2xkZXJzID0gcmVwbGFjZUhvbGRlcnMoYXJncywgcGxhY2Vob2xkZXIpO1xuICAgICAgcmV0dXJuIGNyZWF0ZVJlY3VycnkoXG4gICAgICAgIGZ1bmMsIGJpdG1hc2ssIGNyZWF0ZUh5YnJpZCwgd3JhcHBlci5wbGFjZWhvbGRlciwgdGhpc0FyZyxcbiAgICAgICAgYXJncywgbmV3SG9sZGVycywgYXJnUG9zLCBhcnksIGFyaXR5IC0gbGVuZ3RoXG4gICAgICApO1xuICAgIH1cbiAgICB2YXIgdGhpc0JpbmRpbmcgPSBpc0JpbmQgPyB0aGlzQXJnIDogdGhpcyxcbiAgICAgICAgZm4gPSBpc0JpbmRLZXkgPyB0aGlzQmluZGluZ1tmdW5jXSA6IGZ1bmM7XG5cbiAgICBsZW5ndGggPSBhcmdzLmxlbmd0aDtcbiAgICBpZiAoYXJnUG9zKSB7XG4gICAgICBhcmdzID0gcmVvcmRlcihhcmdzLCBhcmdQb3MpO1xuICAgIH0gZWxzZSBpZiAoaXNGbGlwICYmIGxlbmd0aCA+IDEpIHtcbiAgICAgIGFyZ3MucmV2ZXJzZSgpO1xuICAgIH1cbiAgICBpZiAoaXNBcnkgJiYgYXJ5IDwgbGVuZ3RoKSB7XG4gICAgICBhcmdzLmxlbmd0aCA9IGFyeTtcbiAgICB9XG4gICAgaWYgKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikge1xuICAgICAgZm4gPSBDdG9yIHx8IGNyZWF0ZUN0b3IoZm4pO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpc0JpbmRpbmcsIGFyZ3MpO1xuICB9XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUh5YnJpZDtcbiIsInZhciBhcHBseSA9IHJlcXVpcmUoJy4vX2FwcGx5JyksXG4gICAgY3JlYXRlQ3RvciA9IHJlcXVpcmUoJy4vX2NyZWF0ZUN0b3InKSxcbiAgICByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbnZhciBXUkFQX0JJTkRfRkxBRyA9IDE7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGludm9rZSBpdCB3aXRoIHRoZSBgdGhpc2AgYmluZGluZ1xuICogb2YgYHRoaXNBcmdgIGFuZCBgcGFydGlhbHNgIHByZXBlbmRlZCB0byB0aGUgYXJndW1lbnRzIGl0IHJlY2VpdmVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7Kn0gdGhpc0FyZyBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gcGFydGlhbHMgVGhlIGFyZ3VtZW50cyB0byBwcmVwZW5kIHRvIHRob3NlIHByb3ZpZGVkIHRvXG4gKiAgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHdyYXBwZWQgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBhcnRpYWwoZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMpIHtcbiAgdmFyIGlzQmluZCA9IGJpdG1hc2sgJiBXUkFQX0JJTkRfRkxBRyxcbiAgICAgIEN0b3IgPSBjcmVhdGVDdG9yKGZ1bmMpO1xuXG4gIGZ1bmN0aW9uIHdyYXBwZXIoKSB7XG4gICAgdmFyIGFyZ3NJbmRleCA9IC0xLFxuICAgICAgICBhcmdzTGVuZ3RoID0gYXJndW1lbnRzLmxlbmd0aCxcbiAgICAgICAgbGVmdEluZGV4ID0gLTEsXG4gICAgICAgIGxlZnRMZW5ndGggPSBwYXJ0aWFscy5sZW5ndGgsXG4gICAgICAgIGFyZ3MgPSBBcnJheShsZWZ0TGVuZ3RoICsgYXJnc0xlbmd0aCksXG4gICAgICAgIGZuID0gKHRoaXMgJiYgdGhpcyAhPT0gcm9vdCAmJiB0aGlzIGluc3RhbmNlb2Ygd3JhcHBlcikgPyBDdG9yIDogZnVuYztcblxuICAgIHdoaWxlICgrK2xlZnRJbmRleCA8IGxlZnRMZW5ndGgpIHtcbiAgICAgIGFyZ3NbbGVmdEluZGV4XSA9IHBhcnRpYWxzW2xlZnRJbmRleF07XG4gICAgfVxuICAgIHdoaWxlIChhcmdzTGVuZ3RoLS0pIHtcbiAgICAgIGFyZ3NbbGVmdEluZGV4KytdID0gYXJndW1lbnRzWysrYXJnc0luZGV4XTtcbiAgICB9XG4gICAgcmV0dXJuIGFwcGx5KGZuLCBpc0JpbmQgPyB0aGlzQXJnIDogdGhpcywgYXJncyk7XG4gIH1cbiAgcmV0dXJuIHdyYXBwZXI7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlUGFydGlhbDtcbiIsInZhciBpc0xhemlhYmxlID0gcmVxdWlyZSgnLi9faXNMYXppYWJsZScpLFxuICAgIHNldERhdGEgPSByZXF1aXJlKCcuL19zZXREYXRhJyksXG4gICAgc2V0V3JhcFRvU3RyaW5nID0gcmVxdWlyZSgnLi9fc2V0V3JhcFRvU3RyaW5nJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIGZ1bmN0aW9uIG1ldGFkYXRhLiAqL1xudmFyIFdSQVBfQklORF9GTEFHID0gMSxcbiAgICBXUkFQX0JJTkRfS0VZX0ZMQUcgPSAyLFxuICAgIFdSQVBfQ1VSUllfQk9VTkRfRkxBRyA9IDQsXG4gICAgV1JBUF9DVVJSWV9GTEFHID0gOCxcbiAgICBXUkFQX1BBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHID0gNjQ7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYGZ1bmNgIHRvIGNvbnRpbnVlIGN1cnJ5aW5nLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHdyYXBGdW5jIFRoZSBmdW5jdGlvbiB0byBjcmVhdGUgdGhlIGBmdW5jYCB3cmFwcGVyLlxuICogQHBhcmFtIHsqfSBwbGFjZWhvbGRlciBUaGUgcGxhY2Vob2xkZXIgdmFsdWUuXG4gKiBAcGFyYW0geyp9IFt0aGlzQXJnXSBUaGUgYHRoaXNgIGJpbmRpbmcgb2YgYGZ1bmNgLlxuICogQHBhcmFtIHtBcnJheX0gW3BhcnRpYWxzXSBUaGUgYXJndW1lbnRzIHRvIHByZXBlbmQgdG8gdGhvc2UgcHJvdmlkZWQgdG9cbiAqICB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBcnJheX0gW2hvbGRlcnNdIFRoZSBgcGFydGlhbHNgIHBsYWNlaG9sZGVyIGluZGV4ZXMuXG4gKiBAcGFyYW0ge0FycmF5fSBbYXJnUG9zXSBUaGUgYXJndW1lbnQgcG9zaXRpb25zIG9mIHRoZSBuZXcgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyeV0gVGhlIGFyaXR5IGNhcCBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge251bWJlcn0gW2FyaXR5XSBUaGUgYXJpdHkgb2YgYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgd3JhcHBlZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUmVjdXJyeShmdW5jLCBiaXRtYXNrLCB3cmFwRnVuYywgcGxhY2Vob2xkZXIsIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgdmFyIGlzQ3VycnkgPSBiaXRtYXNrICYgV1JBUF9DVVJSWV9GTEFHLFxuICAgICAgbmV3SG9sZGVycyA9IGlzQ3VycnkgPyBob2xkZXJzIDogdW5kZWZpbmVkLFxuICAgICAgbmV3SG9sZGVyc1JpZ2h0ID0gaXNDdXJyeSA/IHVuZGVmaW5lZCA6IGhvbGRlcnMsXG4gICAgICBuZXdQYXJ0aWFscyA9IGlzQ3VycnkgPyBwYXJ0aWFscyA6IHVuZGVmaW5lZCxcbiAgICAgIG5ld1BhcnRpYWxzUmlnaHQgPSBpc0N1cnJ5ID8gdW5kZWZpbmVkIDogcGFydGlhbHM7XG5cbiAgYml0bWFzayB8PSAoaXNDdXJyeSA/IFdSQVBfUEFSVElBTF9GTEFHIDogV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcpO1xuICBiaXRtYXNrICY9IH4oaXNDdXJyeSA/IFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHIDogV1JBUF9QQVJUSUFMX0ZMQUcpO1xuXG4gIGlmICghKGJpdG1hc2sgJiBXUkFQX0NVUlJZX0JPVU5EX0ZMQUcpKSB7XG4gICAgYml0bWFzayAmPSB+KFdSQVBfQklORF9GTEFHIHwgV1JBUF9CSU5EX0tFWV9GTEFHKTtcbiAgfVxuICB2YXIgbmV3RGF0YSA9IFtcbiAgICBmdW5jLCBiaXRtYXNrLCB0aGlzQXJnLCBuZXdQYXJ0aWFscywgbmV3SG9sZGVycywgbmV3UGFydGlhbHNSaWdodCxcbiAgICBuZXdIb2xkZXJzUmlnaHQsIGFyZ1BvcywgYXJ5LCBhcml0eVxuICBdO1xuXG4gIHZhciByZXN1bHQgPSB3cmFwRnVuYy5hcHBseSh1bmRlZmluZWQsIG5ld0RhdGEpO1xuICBpZiAoaXNMYXppYWJsZShmdW5jKSkge1xuICAgIHNldERhdGEocmVzdWx0LCBuZXdEYXRhKTtcbiAgfVxuICByZXN1bHQucGxhY2Vob2xkZXIgPSBwbGFjZWhvbGRlcjtcbiAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhyZXN1bHQsIGZ1bmMsIGJpdG1hc2spO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZVJlY3Vycnk7XG4iLCJ2YXIgU2V0ID0gcmVxdWlyZSgnLi9fU2V0JyksXG4gICAgbm9vcCA9IHJlcXVpcmUoJy4vbm9vcCcpLFxuICAgIHNldFRvQXJyYXkgPSByZXF1aXJlKCcuL19zZXRUb0FycmF5Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIElORklOSVRZID0gMSAvIDA7XG5cbi8qKlxuICogQ3JlYXRlcyBhIHNldCBvYmplY3Qgb2YgYHZhbHVlc2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFkZCB0byB0aGUgc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgbmV3IHNldC5cbiAqL1xudmFyIGNyZWF0ZVNldCA9ICEoU2V0ICYmICgxIC8gc2V0VG9BcnJheShuZXcgU2V0KFssLTBdKSlbMV0pID09IElORklOSVRZKSA/IG5vb3AgOiBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgcmV0dXJuIG5ldyBTZXQodmFsdWVzKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlU2V0O1xuIiwidmFyIGJhc2VTZXREYXRhID0gcmVxdWlyZSgnLi9fYmFzZVNldERhdGEnKSxcbiAgICBjcmVhdGVCaW5kID0gcmVxdWlyZSgnLi9fY3JlYXRlQmluZCcpLFxuICAgIGNyZWF0ZUN1cnJ5ID0gcmVxdWlyZSgnLi9fY3JlYXRlQ3VycnknKSxcbiAgICBjcmVhdGVIeWJyaWQgPSByZXF1aXJlKCcuL19jcmVhdGVIeWJyaWQnKSxcbiAgICBjcmVhdGVQYXJ0aWFsID0gcmVxdWlyZSgnLi9fY3JlYXRlUGFydGlhbCcpLFxuICAgIGdldERhdGEgPSByZXF1aXJlKCcuL19nZXREYXRhJyksXG4gICAgbWVyZ2VEYXRhID0gcmVxdWlyZSgnLi9fbWVyZ2VEYXRhJyksXG4gICAgc2V0RGF0YSA9IHJlcXVpcmUoJy4vX3NldERhdGEnKSxcbiAgICBzZXRXcmFwVG9TdHJpbmcgPSByZXF1aXJlKCcuL19zZXRXcmFwVG9TdHJpbmcnKSxcbiAgICB0b0ludGVnZXIgPSByZXF1aXJlKCcuL3RvSW50ZWdlcicpO1xuXG4vKiogRXJyb3IgbWVzc2FnZSBjb25zdGFudHMuICovXG52YXIgRlVOQ19FUlJPUl9URVhUID0gJ0V4cGVjdGVkIGEgZnVuY3Rpb24nO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIGJpdG1hc2tzIGZvciBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbnZhciBXUkFQX0JJTkRfRkxBRyA9IDEsXG4gICAgV1JBUF9CSU5EX0tFWV9GTEFHID0gMixcbiAgICBXUkFQX0NVUlJZX0ZMQUcgPSA4LFxuICAgIFdSQVBfQ1VSUllfUklHSFRfRkxBRyA9IDE2LFxuICAgIFdSQVBfUEFSVElBTF9GTEFHID0gMzIsXG4gICAgV1JBUF9QQVJUSUFMX1JJR0hUX0ZMQUcgPSA2NDtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGVpdGhlciBjdXJyaWVzIG9yIGludm9rZXMgYGZ1bmNgIHdpdGggb3B0aW9uYWxcbiAqIGB0aGlzYCBiaW5kaW5nIGFuZCBwYXJ0aWFsbHkgYXBwbGllZCBhcmd1bWVudHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb258c3RyaW5nfSBmdW5jIFRoZSBmdW5jdGlvbiBvciBtZXRob2QgbmFtZSB0byB3cmFwLlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuXG4gKiAgICAxIC0gYF8uYmluZGBcbiAqICAgIDIgLSBgXy5iaW5kS2V5YFxuICogICAgNCAtIGBfLmN1cnJ5YCBvciBgXy5jdXJyeVJpZ2h0YCBvZiBhIGJvdW5kIGZ1bmN0aW9uXG4gKiAgICA4IC0gYF8uY3VycnlgXG4gKiAgIDE2IC0gYF8uY3VycnlSaWdodGBcbiAqICAgMzIgLSBgXy5wYXJ0aWFsYFxuICogICA2NCAtIGBfLnBhcnRpYWxSaWdodGBcbiAqICAxMjggLSBgXy5yZWFyZ2BcbiAqICAyNTYgLSBgXy5hcnlgXG4gKiAgNTEyIC0gYF8uZmxpcGBcbiAqIEBwYXJhbSB7Kn0gW3RoaXNBcmddIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0ge0FycmF5fSBbcGFydGlhbHNdIFRoZSBhcmd1bWVudHMgdG8gYmUgcGFydGlhbGx5IGFwcGxpZWQuXG4gKiBAcGFyYW0ge0FycmF5fSBbaG9sZGVyc10gVGhlIGBwYXJ0aWFsc2AgcGxhY2Vob2xkZXIgaW5kZXhlcy5cbiAqIEBwYXJhbSB7QXJyYXl9IFthcmdQb3NdIFRoZSBhcmd1bWVudCBwb3NpdGlvbnMgb2YgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJ5XSBUaGUgYXJpdHkgY2FwIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJpdHldIFRoZSBhcml0eSBvZiBgZnVuY2AuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyB3cmFwcGVkIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVXcmFwKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzLCBhcmdQb3MsIGFyeSwgYXJpdHkpIHtcbiAgdmFyIGlzQmluZEtleSA9IGJpdG1hc2sgJiBXUkFQX0JJTkRfS0VZX0ZMQUc7XG4gIGlmICghaXNCaW5kS2V5ICYmIHR5cGVvZiBmdW5jICE9ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgVHlwZUVycm9yKEZVTkNfRVJST1JfVEVYVCk7XG4gIH1cbiAgdmFyIGxlbmd0aCA9IHBhcnRpYWxzID8gcGFydGlhbHMubGVuZ3RoIDogMDtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBiaXRtYXNrICY9IH4oV1JBUF9QQVJUSUFMX0ZMQUcgfCBXUkFQX1BBUlRJQUxfUklHSFRfRkxBRyk7XG4gICAgcGFydGlhbHMgPSBob2xkZXJzID0gdW5kZWZpbmVkO1xuICB9XG4gIGFyeSA9IGFyeSA9PT0gdW5kZWZpbmVkID8gYXJ5IDogbmF0aXZlTWF4KHRvSW50ZWdlcihhcnkpLCAwKTtcbiAgYXJpdHkgPSBhcml0eSA9PT0gdW5kZWZpbmVkID8gYXJpdHkgOiB0b0ludGVnZXIoYXJpdHkpO1xuICBsZW5ndGggLT0gaG9sZGVycyA/IGhvbGRlcnMubGVuZ3RoIDogMDtcblxuICBpZiAoYml0bWFzayAmIFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHKSB7XG4gICAgdmFyIHBhcnRpYWxzUmlnaHQgPSBwYXJ0aWFscyxcbiAgICAgICAgaG9sZGVyc1JpZ2h0ID0gaG9sZGVycztcblxuICAgIHBhcnRpYWxzID0gaG9sZGVycyA9IHVuZGVmaW5lZDtcbiAgfVxuICB2YXIgZGF0YSA9IGlzQmluZEtleSA/IHVuZGVmaW5lZCA6IGdldERhdGEoZnVuYyk7XG5cbiAgdmFyIG5ld0RhdGEgPSBbXG4gICAgZnVuYywgYml0bWFzaywgdGhpc0FyZywgcGFydGlhbHMsIGhvbGRlcnMsIHBhcnRpYWxzUmlnaHQsIGhvbGRlcnNSaWdodCxcbiAgICBhcmdQb3MsIGFyeSwgYXJpdHlcbiAgXTtcblxuICBpZiAoZGF0YSkge1xuICAgIG1lcmdlRGF0YShuZXdEYXRhLCBkYXRhKTtcbiAgfVxuICBmdW5jID0gbmV3RGF0YVswXTtcbiAgYml0bWFzayA9IG5ld0RhdGFbMV07XG4gIHRoaXNBcmcgPSBuZXdEYXRhWzJdO1xuICBwYXJ0aWFscyA9IG5ld0RhdGFbM107XG4gIGhvbGRlcnMgPSBuZXdEYXRhWzRdO1xuICBhcml0eSA9IG5ld0RhdGFbOV0gPSBuZXdEYXRhWzldID09PSB1bmRlZmluZWRcbiAgICA/IChpc0JpbmRLZXkgPyAwIDogZnVuYy5sZW5ndGgpXG4gICAgOiBuYXRpdmVNYXgobmV3RGF0YVs5XSAtIGxlbmd0aCwgMCk7XG5cbiAgaWYgKCFhcml0eSAmJiBiaXRtYXNrICYgKFdSQVBfQ1VSUllfRkxBRyB8IFdSQVBfQ1VSUllfUklHSFRfRkxBRykpIHtcbiAgICBiaXRtYXNrICY9IH4oV1JBUF9DVVJSWV9GTEFHIHwgV1JBUF9DVVJSWV9SSUdIVF9GTEFHKTtcbiAgfVxuICBpZiAoIWJpdG1hc2sgfHwgYml0bWFzayA9PSBXUkFQX0JJTkRfRkxBRykge1xuICAgIHZhciByZXN1bHQgPSBjcmVhdGVCaW5kKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcpO1xuICB9IGVsc2UgaWYgKGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9GTEFHIHx8IGJpdG1hc2sgPT0gV1JBUF9DVVJSWV9SSUdIVF9GTEFHKSB7XG4gICAgcmVzdWx0ID0gY3JlYXRlQ3VycnkoZnVuYywgYml0bWFzaywgYXJpdHkpO1xuICB9IGVsc2UgaWYgKChiaXRtYXNrID09IFdSQVBfUEFSVElBTF9GTEFHIHx8IGJpdG1hc2sgPT0gKFdSQVBfQklORF9GTEFHIHwgV1JBUF9QQVJUSUFMX0ZMQUcpKSAmJiAhaG9sZGVycy5sZW5ndGgpIHtcbiAgICByZXN1bHQgPSBjcmVhdGVQYXJ0aWFsKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzKTtcbiAgfSBlbHNlIHtcbiAgICByZXN1bHQgPSBjcmVhdGVIeWJyaWQuYXBwbHkodW5kZWZpbmVkLCBuZXdEYXRhKTtcbiAgfVxuICB2YXIgc2V0dGVyID0gZGF0YSA/IGJhc2VTZXREYXRhIDogc2V0RGF0YTtcbiAgcmV0dXJuIHNldFdyYXBUb1N0cmluZyhzZXR0ZXIocmVzdWx0LCBuZXdEYXRhKSwgZnVuYywgYml0bWFzayk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlV3JhcDtcbiIsInZhciBnZXROYXRpdmUgPSByZXF1aXJlKCcuL19nZXROYXRpdmUnKTtcblxudmFyIGRlZmluZVByb3BlcnR5ID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIHZhciBmdW5jID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2RlZmluZVByb3BlcnR5Jyk7XG4gICAgZnVuYyh7fSwgJycsIHt9KTtcbiAgICByZXR1cm4gZnVuYztcbiAgfSBjYXRjaCAoZSkge31cbn0oKSk7XG5cbm1vZHVsZS5leHBvcnRzID0gZGVmaW5lUHJvcGVydHk7XG4iLCJ2YXIgU2V0Q2FjaGUgPSByZXF1aXJlKCcuL19TZXRDYWNoZScpLFxuICAgIGFycmF5U29tZSA9IHJlcXVpcmUoJy4vX2FycmF5U29tZScpLFxuICAgIGNhY2hlSGFzID0gcmVxdWlyZSgnLi9fY2FjaGVIYXMnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgYXJyYXlzIHdpdGggc3VwcG9ydCBmb3JcbiAqIHBhcnRpYWwgZGVlcCBjb21wYXJpc29ucy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge0FycmF5fSBvdGhlciBUaGUgb3RoZXIgYXJyYXkgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYGFycmF5YCBhbmQgYG90aGVyYCBvYmplY3RzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBhcnJheXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxBcnJheXMoYXJyYXksIG90aGVyLCBiaXRtYXNrLCBjdXN0b21pemVyLCBlcXVhbEZ1bmMsIHN0YWNrKSB7XG4gIHZhciBpc1BhcnRpYWwgPSBiaXRtYXNrICYgQ09NUEFSRV9QQVJUSUFMX0ZMQUcsXG4gICAgICBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBvdGhMZW5ndGggPSBvdGhlci5sZW5ndGg7XG5cbiAgaWYgKGFyckxlbmd0aCAhPSBvdGhMZW5ndGggJiYgIShpc1BhcnRpYWwgJiYgb3RoTGVuZ3RoID4gYXJyTGVuZ3RoKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBDaGVjayB0aGF0IGN5Y2xpYyB2YWx1ZXMgYXJlIGVxdWFsLlxuICB2YXIgYXJyU3RhY2tlZCA9IHN0YWNrLmdldChhcnJheSk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKGFyclN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBhcnJTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gYXJyYXk7XG4gIH1cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICByZXN1bHQgPSB0cnVlLFxuICAgICAgc2VlbiA9IChiaXRtYXNrICYgQ09NUEFSRV9VTk9SREVSRURfRkxBRykgPyBuZXcgU2V0Q2FjaGUgOiB1bmRlZmluZWQ7XG5cbiAgc3RhY2suc2V0KGFycmF5LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgYXJyYXkpO1xuXG4gIC8vIElnbm9yZSBub24taW5kZXggcHJvcGVydGllcy5cbiAgd2hpbGUgKCsraW5kZXggPCBhcnJMZW5ndGgpIHtcbiAgICB2YXIgYXJyVmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIG90aFZhbHVlID0gb3RoZXJbaW5kZXhdO1xuXG4gICAgaWYgKGN1c3RvbWl6ZXIpIHtcbiAgICAgIHZhciBjb21wYXJlZCA9IGlzUGFydGlhbFxuICAgICAgICA/IGN1c3RvbWl6ZXIob3RoVmFsdWUsIGFyclZhbHVlLCBpbmRleCwgb3RoZXIsIGFycmF5LCBzdGFjaylcbiAgICAgICAgOiBjdXN0b21pemVyKGFyclZhbHVlLCBvdGhWYWx1ZSwgaW5kZXgsIGFycmF5LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICBpZiAoY29tcGFyZWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKGNvbXBhcmVkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBhcnJheXMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoc2Vlbikge1xuICAgICAgaWYgKCFhcnJheVNvbWUob3RoZXIsIGZ1bmN0aW9uKG90aFZhbHVlLCBvdGhJbmRleCkge1xuICAgICAgICAgICAgaWYgKCFjYWNoZUhhcyhzZWVuLCBvdGhJbmRleCkgJiZcbiAgICAgICAgICAgICAgICAoYXJyVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHNlZW4ucHVzaChvdGhJbmRleCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkpIHtcbiAgICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIShcbiAgICAgICAgICBhcnJWYWx1ZSA9PT0gb3RoVmFsdWUgfHxcbiAgICAgICAgICAgIGVxdWFsRnVuYyhhcnJWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKVxuICAgICAgICApKSB7XG4gICAgICByZXN1bHQgPSBmYWxzZTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuICBzdGFja1snZGVsZXRlJ10oYXJyYXkpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsQXJyYXlzO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpLFxuICAgIFVpbnQ4QXJyYXkgPSByZXF1aXJlKCcuL19VaW50OEFycmF5JyksXG4gICAgZXEgPSByZXF1aXJlKCcuL2VxJyksXG4gICAgZXF1YWxBcnJheXMgPSByZXF1aXJlKCcuL19lcXVhbEFycmF5cycpLFxuICAgIG1hcFRvQXJyYXkgPSByZXF1aXJlKCcuL19tYXBUb0FycmF5JyksXG4gICAgc2V0VG9BcnJheSA9IHJlcXVpcmUoJy4vX3NldFRvQXJyYXknKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgdmFsdWUgY29tcGFyaXNvbnMuICovXG52YXIgQ09NUEFSRV9QQVJUSUFMX0ZMQUcgPSAxLFxuICAgIENPTVBBUkVfVU5PUkRFUkVEX0ZMQUcgPSAyO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgYm9vbFRhZyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcbiAgICBkYXRlVGFnID0gJ1tvYmplY3QgRGF0ZV0nLFxuICAgIGVycm9yVGFnID0gJ1tvYmplY3QgRXJyb3JdJyxcbiAgICBtYXBUYWcgPSAnW29iamVjdCBNYXBdJyxcbiAgICBudW1iZXJUYWcgPSAnW29iamVjdCBOdW1iZXJdJyxcbiAgICByZWdleHBUYWcgPSAnW29iamVjdCBSZWdFeHBdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICBzdHJpbmdUYWcgPSAnW29iamVjdCBTdHJpbmddJyxcbiAgICBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxudmFyIGFycmF5QnVmZmVyVGFnID0gJ1tvYmplY3QgQXJyYXlCdWZmZXJdJyxcbiAgICBkYXRhVmlld1RhZyA9ICdbb2JqZWN0IERhdGFWaWV3XSc7XG5cbi8qKiBVc2VkIHRvIGNvbnZlcnQgc3ltYm9scyB0byBwcmltaXRpdmVzIGFuZCBzdHJpbmdzLiAqL1xudmFyIHN5bWJvbFByb3RvID0gU3ltYm9sID8gU3ltYm9sLnByb3RvdHlwZSA6IHVuZGVmaW5lZCxcbiAgICBzeW1ib2xWYWx1ZU9mID0gc3ltYm9sUHJvdG8gPyBzeW1ib2xQcm90by52YWx1ZU9mIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZUlzRXF1YWxEZWVwYCBmb3IgY29tcGFyaW5nIG9iamVjdHMgb2ZcbiAqIHRoZSBzYW1lIGB0b1N0cmluZ1RhZ2AuXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gb25seSBzdXBwb3J0cyBjb21wYXJpbmcgdmFsdWVzIHdpdGggdGFncyBvZlxuICogYEJvb2xlYW5gLCBgRGF0ZWAsIGBFcnJvcmAsIGBOdW1iZXJgLCBgUmVnRXhwYCwgb3IgYFN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBjb21wYXJlLlxuICogQHBhcmFtIHtPYmplY3R9IG90aGVyIFRoZSBvdGhlciBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YWcgVGhlIGB0b1N0cmluZ1RhZ2Agb2YgdGhlIG9iamVjdHMgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGJhc2VJc0VxdWFsYCBmb3IgbW9yZSBkZXRhaWxzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY3VzdG9taXplciBUaGUgZnVuY3Rpb24gdG8gY3VzdG9taXplIGNvbXBhcmlzb25zLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gZXF1YWxGdW5jIFRoZSBmdW5jdGlvbiB0byBkZXRlcm1pbmUgZXF1aXZhbGVudHMgb2YgdmFsdWVzLlxuICogQHBhcmFtIHtPYmplY3R9IHN0YWNrIFRyYWNrcyB0cmF2ZXJzZWQgYG9iamVjdGAgYW5kIGBvdGhlcmAgb2JqZWN0cy5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgb2JqZWN0cyBhcmUgZXF1aXZhbGVudCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBlcXVhbEJ5VGFnKG9iamVjdCwgb3RoZXIsIHRhZywgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjaykge1xuICBzd2l0Y2ggKHRhZykge1xuICAgIGNhc2UgZGF0YVZpZXdUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgKG9iamVjdC5ieXRlT2Zmc2V0ICE9IG90aGVyLmJ5dGVPZmZzZXQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIG9iamVjdCA9IG9iamVjdC5idWZmZXI7XG4gICAgICBvdGhlciA9IG90aGVyLmJ1ZmZlcjtcblxuICAgIGNhc2UgYXJyYXlCdWZmZXJUYWc6XG4gICAgICBpZiAoKG9iamVjdC5ieXRlTGVuZ3RoICE9IG90aGVyLmJ5dGVMZW5ndGgpIHx8XG4gICAgICAgICAgIWVxdWFsRnVuYyhuZXcgVWludDhBcnJheShvYmplY3QpLCBuZXcgVWludDhBcnJheShvdGhlcikpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuXG4gICAgY2FzZSBib29sVGFnOlxuICAgIGNhc2UgZGF0ZVRhZzpcbiAgICBjYXNlIG51bWJlclRhZzpcbiAgICAgIC8vIENvZXJjZSBib29sZWFucyB0byBgMWAgb3IgYDBgIGFuZCBkYXRlcyB0byBtaWxsaXNlY29uZHMuXG4gICAgICAvLyBJbnZhbGlkIGRhdGVzIGFyZSBjb2VyY2VkIHRvIGBOYU5gLlxuICAgICAgcmV0dXJuIGVxKCtvYmplY3QsICtvdGhlcik7XG5cbiAgICBjYXNlIGVycm9yVGFnOlxuICAgICAgcmV0dXJuIG9iamVjdC5uYW1lID09IG90aGVyLm5hbWUgJiYgb2JqZWN0Lm1lc3NhZ2UgPT0gb3RoZXIubWVzc2FnZTtcblxuICAgIGNhc2UgcmVnZXhwVGFnOlxuICAgIGNhc2Ugc3RyaW5nVGFnOlxuICAgICAgLy8gQ29lcmNlIHJlZ2V4ZXMgdG8gc3RyaW5ncyBhbmQgdHJlYXQgc3RyaW5ncywgcHJpbWl0aXZlcyBhbmQgb2JqZWN0cyxcbiAgICAgIC8vIGFzIGVxdWFsLiBTZWUgaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXJlZ2V4cC5wcm90b3R5cGUudG9zdHJpbmdcbiAgICAgIC8vIGZvciBtb3JlIGRldGFpbHMuXG4gICAgICByZXR1cm4gb2JqZWN0ID09IChvdGhlciArICcnKTtcblxuICAgIGNhc2UgbWFwVGFnOlxuICAgICAgdmFyIGNvbnZlcnQgPSBtYXBUb0FycmF5O1xuXG4gICAgY2FzZSBzZXRUYWc6XG4gICAgICB2YXIgaXNQYXJ0aWFsID0gYml0bWFzayAmIENPTVBBUkVfUEFSVElBTF9GTEFHO1xuICAgICAgY29udmVydCB8fCAoY29udmVydCA9IHNldFRvQXJyYXkpO1xuXG4gICAgICBpZiAob2JqZWN0LnNpemUgIT0gb3RoZXIuc2l6ZSAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEFzc3VtZSBjeWNsaWMgdmFsdWVzIGFyZSBlcXVhbC5cbiAgICAgIHZhciBzdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gICAgICBpZiAoc3RhY2tlZCkge1xuICAgICAgICByZXR1cm4gc3RhY2tlZCA9PSBvdGhlcjtcbiAgICAgIH1cbiAgICAgIGJpdG1hc2sgfD0gQ09NUEFSRV9VTk9SREVSRURfRkxBRztcblxuICAgICAgLy8gUmVjdXJzaXZlbHkgY29tcGFyZSBvYmplY3RzIChzdXNjZXB0aWJsZSB0byBjYWxsIHN0YWNrIGxpbWl0cykuXG4gICAgICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gICAgICB2YXIgcmVzdWx0ID0gZXF1YWxBcnJheXMoY29udmVydChvYmplY3QpLCBjb252ZXJ0KG90aGVyKSwgYml0bWFzaywgY3VzdG9taXplciwgZXF1YWxGdW5jLCBzdGFjayk7XG4gICAgICBzdGFja1snZGVsZXRlJ10ob2JqZWN0KTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICBjYXNlIHN5bWJvbFRhZzpcbiAgICAgIGlmIChzeW1ib2xWYWx1ZU9mKSB7XG4gICAgICAgIHJldHVybiBzeW1ib2xWYWx1ZU9mLmNhbGwob2JqZWN0KSA9PSBzeW1ib2xWYWx1ZU9mLmNhbGwob3RoZXIpO1xuICAgICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlcXVhbEJ5VGFnO1xuIiwidmFyIGdldEFsbEtleXMgPSByZXF1aXJlKCcuL19nZXRBbGxLZXlzJyk7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgYml0bWFza3MgZm9yIHZhbHVlIGNvbXBhcmlzb25zLiAqL1xudmFyIENPTVBBUkVfUEFSVElBTF9GTEFHID0gMTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VJc0VxdWFsRGVlcGAgZm9yIG9iamVjdHMgd2l0aCBzdXBwb3J0IGZvclxuICogcGFydGlhbCBkZWVwIGNvbXBhcmlzb25zLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvdGhlciBUaGUgb3RoZXIgb2JqZWN0IHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0ge251bWJlcn0gYml0bWFzayBUaGUgYml0bWFzayBmbGFncy4gU2VlIGBiYXNlSXNFcXVhbGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGN1c3RvbWl6ZXIgVGhlIGZ1bmN0aW9uIHRvIGN1c3RvbWl6ZSBjb21wYXJpc29ucy5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGVxdWFsRnVuYyBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIGVxdWl2YWxlbnRzIG9mIHZhbHVlcy5cbiAqIEBwYXJhbSB7T2JqZWN0fSBzdGFjayBUcmFja3MgdHJhdmVyc2VkIGBvYmplY3RgIGFuZCBgb3RoZXJgIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIG9iamVjdHMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gZXF1YWxPYmplY3RzKG9iamVjdCwgb3RoZXIsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIGVxdWFsRnVuYywgc3RhY2spIHtcbiAgdmFyIGlzUGFydGlhbCA9IGJpdG1hc2sgJiBDT01QQVJFX1BBUlRJQUxfRkxBRyxcbiAgICAgIG9ialByb3BzID0gZ2V0QWxsS2V5cyhvYmplY3QpLFxuICAgICAgb2JqTGVuZ3RoID0gb2JqUHJvcHMubGVuZ3RoLFxuICAgICAgb3RoUHJvcHMgPSBnZXRBbGxLZXlzKG90aGVyKSxcbiAgICAgIG90aExlbmd0aCA9IG90aFByb3BzLmxlbmd0aDtcblxuICBpZiAob2JqTGVuZ3RoICE9IG90aExlbmd0aCAmJiAhaXNQYXJ0aWFsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHZhciBpbmRleCA9IG9iakxlbmd0aDtcbiAgd2hpbGUgKGluZGV4LS0pIHtcbiAgICB2YXIga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIGlmICghKGlzUGFydGlhbCA/IGtleSBpbiBvdGhlciA6IGhhc093blByb3BlcnR5LmNhbGwob3RoZXIsIGtleSkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIC8vIENoZWNrIHRoYXQgY3ljbGljIHZhbHVlcyBhcmUgZXF1YWwuXG4gIHZhciBvYmpTdGFja2VkID0gc3RhY2suZ2V0KG9iamVjdCk7XG4gIHZhciBvdGhTdGFja2VkID0gc3RhY2suZ2V0KG90aGVyKTtcbiAgaWYgKG9ialN0YWNrZWQgJiYgb3RoU3RhY2tlZCkge1xuICAgIHJldHVybiBvYmpTdGFja2VkID09IG90aGVyICYmIG90aFN0YWNrZWQgPT0gb2JqZWN0O1xuICB9XG4gIHZhciByZXN1bHQgPSB0cnVlO1xuICBzdGFjay5zZXQob2JqZWN0LCBvdGhlcik7XG4gIHN0YWNrLnNldChvdGhlciwgb2JqZWN0KTtcblxuICB2YXIgc2tpcEN0b3IgPSBpc1BhcnRpYWw7XG4gIHdoaWxlICgrK2luZGV4IDwgb2JqTGVuZ3RoKSB7XG4gICAga2V5ID0gb2JqUHJvcHNbaW5kZXhdO1xuICAgIHZhciBvYmpWYWx1ZSA9IG9iamVjdFtrZXldLFxuICAgICAgICBvdGhWYWx1ZSA9IG90aGVyW2tleV07XG5cbiAgICBpZiAoY3VzdG9taXplcikge1xuICAgICAgdmFyIGNvbXBhcmVkID0gaXNQYXJ0aWFsXG4gICAgICAgID8gY3VzdG9taXplcihvdGhWYWx1ZSwgb2JqVmFsdWUsIGtleSwgb3RoZXIsIG9iamVjdCwgc3RhY2spXG4gICAgICAgIDogY3VzdG9taXplcihvYmpWYWx1ZSwgb3RoVmFsdWUsIGtleSwgb2JqZWN0LCBvdGhlciwgc3RhY2spO1xuICAgIH1cbiAgICAvLyBSZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgKHN1c2NlcHRpYmxlIHRvIGNhbGwgc3RhY2sgbGltaXRzKS5cbiAgICBpZiAoIShjb21wYXJlZCA9PT0gdW5kZWZpbmVkXG4gICAgICAgICAgPyAob2JqVmFsdWUgPT09IG90aFZhbHVlIHx8IGVxdWFsRnVuYyhvYmpWYWx1ZSwgb3RoVmFsdWUsIGJpdG1hc2ssIGN1c3RvbWl6ZXIsIHN0YWNrKSlcbiAgICAgICAgICA6IGNvbXBhcmVkXG4gICAgICAgICkpIHtcbiAgICAgIHJlc3VsdCA9IGZhbHNlO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHNraXBDdG9yIHx8IChza2lwQ3RvciA9IGtleSA9PSAnY29uc3RydWN0b3InKTtcbiAgfVxuICBpZiAocmVzdWx0ICYmICFza2lwQ3Rvcikge1xuICAgIHZhciBvYmpDdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxuICAgICAgICBvdGhDdG9yID0gb3RoZXIuY29uc3RydWN0b3I7XG5cbiAgICAvLyBOb24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbC5cbiAgICBpZiAob2JqQ3RvciAhPSBvdGhDdG9yICYmXG4gICAgICAgICgnY29uc3RydWN0b3InIGluIG9iamVjdCAmJiAnY29uc3RydWN0b3InIGluIG90aGVyKSAmJlxuICAgICAgICAhKHR5cGVvZiBvYmpDdG9yID09ICdmdW5jdGlvbicgJiYgb2JqQ3RvciBpbnN0YW5jZW9mIG9iakN0b3IgJiZcbiAgICAgICAgICB0eXBlb2Ygb3RoQ3RvciA9PSAnZnVuY3Rpb24nICYmIG90aEN0b3IgaW5zdGFuY2VvZiBvdGhDdG9yKSkge1xuICAgICAgcmVzdWx0ID0gZmFsc2U7XG4gICAgfVxuICB9XG4gIHN0YWNrWydkZWxldGUnXShvYmplY3QpO1xuICBzdGFja1snZGVsZXRlJ10ob3RoZXIpO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGVxdWFsT2JqZWN0cztcbiIsIi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZUdsb2JhbCA9IHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgZ2xvYmFsICYmIGdsb2JhbC5PYmplY3QgPT09IE9iamVjdCAmJiBnbG9iYWw7XG5cbm1vZHVsZS5leHBvcnRzID0gZnJlZUdsb2JhbDtcbiIsInZhciBiYXNlR2V0QWxsS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRBbGxLZXlzJyksXG4gICAgZ2V0U3ltYm9scyA9IHJlcXVpcmUoJy4vX2dldFN5bWJvbHMnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyBhbmQgc3ltYm9scy5cbiAqL1xuZnVuY3Rpb24gZ2V0QWxsS2V5cyhvYmplY3QpIHtcbiAgcmV0dXJuIGJhc2VHZXRBbGxLZXlzKG9iamVjdCwga2V5cywgZ2V0U3ltYm9scyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0QWxsS2V5cztcbiIsInZhciBtZXRhTWFwID0gcmVxdWlyZSgnLi9fbWV0YU1hcCcpLFxuICAgIG5vb3AgPSByZXF1aXJlKCcuL25vb3AnKTtcblxuLyoqXG4gKiBHZXRzIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIG1ldGFkYXRhIGZvciBgZnVuY2AuXG4gKi9cbnZhciBnZXREYXRhID0gIW1ldGFNYXAgPyBub29wIDogZnVuY3Rpb24oZnVuYykge1xuICByZXR1cm4gbWV0YU1hcC5nZXQoZnVuYyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGdldERhdGE7XG4iLCJ2YXIgcmVhbE5hbWVzID0gcmVxdWlyZSgnLi9fcmVhbE5hbWVzJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogR2V0cyB0aGUgbmFtZSBvZiBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHF1ZXJ5LlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZnVuY3Rpb24gbmFtZS5cbiAqL1xuZnVuY3Rpb24gZ2V0RnVuY05hbWUoZnVuYykge1xuICB2YXIgcmVzdWx0ID0gKGZ1bmMubmFtZSArICcnKSxcbiAgICAgIGFycmF5ID0gcmVhbE5hbWVzW3Jlc3VsdF0sXG4gICAgICBsZW5ndGggPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlYWxOYW1lcywgcmVzdWx0KSA/IGFycmF5Lmxlbmd0aCA6IDA7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgdmFyIGRhdGEgPSBhcnJheVtsZW5ndGhdLFxuICAgICAgICBvdGhlckZ1bmMgPSBkYXRhLmZ1bmM7XG4gICAgaWYgKG90aGVyRnVuYyA9PSBudWxsIHx8IG90aGVyRnVuYyA9PSBmdW5jKSB7XG4gICAgICByZXR1cm4gZGF0YS5uYW1lO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldEZ1bmNOYW1lO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSBhcmd1bWVudCBwbGFjZWhvbGRlciB2YWx1ZSBmb3IgYGZ1bmNgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBpbnNwZWN0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIHBsYWNlaG9sZGVyIHZhbHVlLlxuICovXG5mdW5jdGlvbiBnZXRIb2xkZXIoZnVuYykge1xuICB2YXIgb2JqZWN0ID0gZnVuYztcbiAgcmV0dXJuIG9iamVjdC5wbGFjZWhvbGRlcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRIb2xkZXI7XG4iLCJ2YXIgaXNLZXlhYmxlID0gcmVxdWlyZSgnLi9faXNLZXlhYmxlJyk7XG5cbi8qKlxuICogR2V0cyB0aGUgZGF0YSBmb3IgYG1hcGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIHJlZmVyZW5jZSBrZXkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgbWFwIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIGdldE1hcERhdGEobWFwLCBrZXkpIHtcbiAgdmFyIGRhdGEgPSBtYXAuX19kYXRhX187XG4gIHJldHVybiBpc0tleWFibGUoa2V5KVxuICAgID8gZGF0YVt0eXBlb2Yga2V5ID09ICdzdHJpbmcnID8gJ3N0cmluZycgOiAnaGFzaCddXG4gICAgOiBkYXRhLm1hcDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXRNYXBEYXRhO1xuIiwidmFyIGlzU3RyaWN0Q29tcGFyYWJsZSA9IHJlcXVpcmUoJy4vX2lzU3RyaWN0Q29tcGFyYWJsZScpLFxuICAgIGtleXMgPSByZXF1aXJlKCcuL2tleXMnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBwcm9wZXJ0eSBuYW1lcywgdmFsdWVzLCBhbmQgY29tcGFyZSBmbGFncyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBtYXRjaCBkYXRhIG9mIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBnZXRNYXRjaERhdGEob2JqZWN0KSB7XG4gIHZhciByZXN1bHQgPSBrZXlzKG9iamVjdCksXG4gICAgICBsZW5ndGggPSByZXN1bHQubGVuZ3RoO1xuXG4gIHdoaWxlIChsZW5ndGgtLSkge1xuICAgIHZhciBrZXkgPSByZXN1bHRbbGVuZ3RoXSxcbiAgICAgICAgdmFsdWUgPSBvYmplY3Rba2V5XTtcblxuICAgIHJlc3VsdFtsZW5ndGhdID0gW2tleSwgdmFsdWUsIGlzU3RyaWN0Q29tcGFyYWJsZSh2YWx1ZSldO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0TWF0Y2hEYXRhO1xuIiwidmFyIGJhc2VJc05hdGl2ZSA9IHJlcXVpcmUoJy4vX2Jhc2VJc05hdGl2ZScpLFxuICAgIGdldFZhbHVlID0gcmVxdWlyZSgnLi9fZ2V0VmFsdWUnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqL1xuZnVuY3Rpb24gZ2V0TmF0aXZlKG9iamVjdCwga2V5KSB7XG4gIHZhciB2YWx1ZSA9IGdldFZhbHVlKG9iamVjdCwga2V5KTtcbiAgcmV0dXJuIGJhc2VJc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBnZXROYXRpdmU7XG4iLCJ2YXIgb3ZlckFyZyA9IHJlcXVpcmUoJy4vX292ZXJBcmcnKTtcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgZ2V0UHJvdG90eXBlID0gb3ZlckFyZyhPYmplY3QuZ2V0UHJvdG90eXBlT2YsIE9iamVjdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UHJvdG90eXBlO1xuIiwidmFyIFN5bWJvbCA9IHJlcXVpcmUoJy4vX1N5bWJvbCcpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgbmF0aXZlT2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgc3ltVG9TdHJpbmdUYWcgPSBTeW1ib2wgPyBTeW1ib2wudG9TdHJpbmdUYWcgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBiYXNlR2V0VGFnYCB3aGljaCBpZ25vcmVzIGBTeW1ib2wudG9TdHJpbmdUYWdgIHZhbHVlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSByYXcgYHRvU3RyaW5nVGFnYC5cbiAqL1xuZnVuY3Rpb24gZ2V0UmF3VGFnKHZhbHVlKSB7XG4gIHZhciBpc093biA9IGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsIHN5bVRvU3RyaW5nVGFnKSxcbiAgICAgIHRhZyA9IHZhbHVlW3N5bVRvU3RyaW5nVGFnXTtcblxuICB0cnkge1xuICAgIHZhbHVlW3N5bVRvU3RyaW5nVGFnXSA9IHVuZGVmaW5lZDtcbiAgICB2YXIgdW5tYXNrZWQgPSB0cnVlO1xuICB9IGNhdGNoIChlKSB7fVxuXG4gIHZhciByZXN1bHQgPSBuYXRpdmVPYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKTtcbiAgaWYgKHVubWFza2VkKSB7XG4gICAgaWYgKGlzT3duKSB7XG4gICAgICB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ10gPSB0YWc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSB2YWx1ZVtzeW1Ub1N0cmluZ1RhZ107XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0UmF3VGFnO1xuIiwidmFyIGFycmF5RmlsdGVyID0gcmVxdWlyZSgnLi9fYXJyYXlGaWx0ZXInKSxcbiAgICBzdHViQXJyYXkgPSByZXF1aXJlKCcuL3N0dWJBcnJheScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBwcm9wZXJ0eUlzRW51bWVyYWJsZSA9IG9iamVjdFByb3RvLnByb3BlcnR5SXNFbnVtZXJhYmxlO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlR2V0U3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHM7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3ltYm9scyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBzeW1ib2xzLlxuICovXG52YXIgZ2V0U3ltYm9scyA9ICFuYXRpdmVHZXRTeW1ib2xzID8gc3R1YkFycmF5IDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuICBvYmplY3QgPSBPYmplY3Qob2JqZWN0KTtcbiAgcmV0dXJuIGFycmF5RmlsdGVyKG5hdGl2ZUdldFN5bWJvbHMob2JqZWN0KSwgZnVuY3Rpb24oc3ltYm9sKSB7XG4gICAgcmV0dXJuIHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwob2JqZWN0LCBzeW1ib2wpO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0U3ltYm9scztcbiIsInZhciBEYXRhVmlldyA9IHJlcXVpcmUoJy4vX0RhdGFWaWV3JyksXG4gICAgTWFwID0gcmVxdWlyZSgnLi9fTWFwJyksXG4gICAgUHJvbWlzZSA9IHJlcXVpcmUoJy4vX1Byb21pc2UnKSxcbiAgICBTZXQgPSByZXF1aXJlKCcuL19TZXQnKSxcbiAgICBXZWFrTWFwID0gcmVxdWlyZSgnLi9fV2Vha01hcCcpLFxuICAgIGJhc2VHZXRUYWcgPSByZXF1aXJlKCcuL19iYXNlR2V0VGFnJyksXG4gICAgdG9Tb3VyY2UgPSByZXF1aXJlKCcuL190b1NvdXJjZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgb2JqZWN0VGFnID0gJ1tvYmplY3QgT2JqZWN0XScsXG4gICAgcHJvbWlzZVRhZyA9ICdbb2JqZWN0IFByb21pc2VdJyxcbiAgICBzZXRUYWcgPSAnW29iamVjdCBTZXRdJyxcbiAgICB3ZWFrTWFwVGFnID0gJ1tvYmplY3QgV2Vha01hcF0nO1xuXG52YXIgZGF0YVZpZXdUYWcgPSAnW29iamVjdCBEYXRhVmlld10nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgbWFwcywgc2V0cywgYW5kIHdlYWttYXBzLiAqL1xudmFyIGRhdGFWaWV3Q3RvclN0cmluZyA9IHRvU291cmNlKERhdGFWaWV3KSxcbiAgICBtYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoTWFwKSxcbiAgICBwcm9taXNlQ3RvclN0cmluZyA9IHRvU291cmNlKFByb21pc2UpLFxuICAgIHNldEN0b3JTdHJpbmcgPSB0b1NvdXJjZShTZXQpLFxuICAgIHdlYWtNYXBDdG9yU3RyaW5nID0gdG9Tb3VyY2UoV2Vha01hcCk7XG5cbi8qKlxuICogR2V0cyB0aGUgYHRvU3RyaW5nVGFnYCBvZiBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGB0b1N0cmluZ1RhZ2AuXG4gKi9cbnZhciBnZXRUYWcgPSBiYXNlR2V0VGFnO1xuXG4vLyBGYWxsYmFjayBmb3IgZGF0YSB2aWV3cywgbWFwcywgc2V0cywgYW5kIHdlYWsgbWFwcyBpbiBJRSAxMSBhbmQgcHJvbWlzZXMgaW4gTm9kZS5qcyA8IDYuXG5pZiAoKERhdGFWaWV3ICYmIGdldFRhZyhuZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDEpKSkgIT0gZGF0YVZpZXdUYWcpIHx8XG4gICAgKE1hcCAmJiBnZXRUYWcobmV3IE1hcCkgIT0gbWFwVGFnKSB8fFxuICAgIChQcm9taXNlICYmIGdldFRhZyhQcm9taXNlLnJlc29sdmUoKSkgIT0gcHJvbWlzZVRhZykgfHxcbiAgICAoU2V0ICYmIGdldFRhZyhuZXcgU2V0KSAhPSBzZXRUYWcpIHx8XG4gICAgKFdlYWtNYXAgJiYgZ2V0VGFnKG5ldyBXZWFrTWFwKSAhPSB3ZWFrTWFwVGFnKSkge1xuICBnZXRUYWcgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciByZXN1bHQgPSBiYXNlR2V0VGFnKHZhbHVlKSxcbiAgICAgICAgQ3RvciA9IHJlc3VsdCA9PSBvYmplY3RUYWcgPyB2YWx1ZS5jb25zdHJ1Y3RvciA6IHVuZGVmaW5lZCxcbiAgICAgICAgY3RvclN0cmluZyA9IEN0b3IgPyB0b1NvdXJjZShDdG9yKSA6ICcnO1xuXG4gICAgaWYgKGN0b3JTdHJpbmcpIHtcbiAgICAgIHN3aXRjaCAoY3RvclN0cmluZykge1xuICAgICAgICBjYXNlIGRhdGFWaWV3Q3RvclN0cmluZzogcmV0dXJuIGRhdGFWaWV3VGFnO1xuICAgICAgICBjYXNlIG1hcEN0b3JTdHJpbmc6IHJldHVybiBtYXBUYWc7XG4gICAgICAgIGNhc2UgcHJvbWlzZUN0b3JTdHJpbmc6IHJldHVybiBwcm9taXNlVGFnO1xuICAgICAgICBjYXNlIHNldEN0b3JTdHJpbmc6IHJldHVybiBzZXRUYWc7XG4gICAgICAgIGNhc2Ugd2Vha01hcEN0b3JTdHJpbmc6IHJldHVybiB3ZWFrTWFwVGFnO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFRhZztcbiIsIi8qKlxuICogR2V0cyB0aGUgdmFsdWUgYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcHJvcGVydHkgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIGdldFZhbHVlKG9iamVjdCwga2V5KSB7XG4gIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldFZhbHVlO1xuIiwiLyoqIFVzZWQgdG8gbWF0Y2ggd3JhcCBkZXRhaWwgY29tbWVudHMuICovXG52YXIgcmVXcmFwRGV0YWlscyA9IC9cXHtcXG5cXC9cXCogXFxbd3JhcHBlZCB3aXRoICguKylcXF0gXFwqLyxcbiAgICByZVNwbGl0RGV0YWlscyA9IC8sPyAmIC87XG5cbi8qKlxuICogRXh0cmFjdHMgd3JhcHBlciBkZXRhaWxzIGZyb20gdGhlIGBzb3VyY2VgIGJvZHkgY29tbWVudC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSBUaGUgc291cmNlIHRvIGluc3BlY3QuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHdyYXBwZXIgZGV0YWlscy5cbiAqL1xuZnVuY3Rpb24gZ2V0V3JhcERldGFpbHMoc291cmNlKSB7XG4gIHZhciBtYXRjaCA9IHNvdXJjZS5tYXRjaChyZVdyYXBEZXRhaWxzKTtcbiAgcmV0dXJuIG1hdGNoID8gbWF0Y2hbMV0uc3BsaXQocmVTcGxpdERldGFpbHMpIDogW107XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZ2V0V3JhcERldGFpbHM7XG4iLCJ2YXIgY2FzdFBhdGggPSByZXF1aXJlKCcuL19jYXN0UGF0aCcpLFxuICAgIGlzQXJndW1lbnRzID0gcmVxdWlyZSgnLi9pc0FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9faXNJbmRleCcpLFxuICAgIGlzTGVuZ3RoID0gcmVxdWlyZSgnLi9pc0xlbmd0aCcpLFxuICAgIHRvS2V5ID0gcmVxdWlyZSgnLi9fdG9LZXknKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHBhdGhgIGV4aXN0cyBvbiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggdG8gY2hlY2suXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYXNGdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjayBwcm9wZXJ0aWVzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaGFzUGF0aChvYmplY3QsIHBhdGgsIGhhc0Z1bmMpIHtcbiAgcGF0aCA9IGNhc3RQYXRoKHBhdGgsIG9iamVjdCk7XG5cbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBwYXRoLmxlbmd0aCxcbiAgICAgIHJlc3VsdCA9IGZhbHNlO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIGtleSA9IHRvS2V5KHBhdGhbaW5kZXhdKTtcbiAgICBpZiAoIShyZXN1bHQgPSBvYmplY3QgIT0gbnVsbCAmJiBoYXNGdW5jKG9iamVjdCwga2V5KSkpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBvYmplY3QgPSBvYmplY3Rba2V5XTtcbiAgfVxuICBpZiAocmVzdWx0IHx8ICsraW5kZXggIT0gbGVuZ3RoKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICBsZW5ndGggPSBvYmplY3QgPT0gbnVsbCA/IDAgOiBvYmplY3QubGVuZ3RoO1xuICByZXR1cm4gISFsZW5ndGggJiYgaXNMZW5ndGgobGVuZ3RoKSAmJiBpc0luZGV4KGtleSwgbGVuZ3RoKSAmJlxuICAgIChpc0FycmF5KG9iamVjdCkgfHwgaXNBcmd1bWVudHMob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzUGF0aDtcbiIsInZhciBuYXRpdmVDcmVhdGUgPSByZXF1aXJlKCcuL19uYXRpdmVDcmVhdGUnKTtcblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBoYXNoLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBjbGVhclxuICogQG1lbWJlck9mIEhhc2hcbiAqL1xuZnVuY3Rpb24gaGFzaENsZWFyKCkge1xuICB0aGlzLl9fZGF0YV9fID0gbmF0aXZlQ3JlYXRlID8gbmF0aXZlQ3JlYXRlKG51bGwpIDoge307XG4gIHRoaXMuc2l6ZSA9IDA7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzaENsZWFyO1xuIiwiLyoqXG4gKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgaGFzaC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgZGVsZXRlXG4gKiBAbWVtYmVyT2YgSGFzaFxuICogQHBhcmFtIHtPYmplY3R9IGhhc2ggVGhlIGhhc2ggdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byByZW1vdmUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgdGhlIGVudHJ5IHdhcyByZW1vdmVkLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGhhc2hEZWxldGUoa2V5KSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLmhhcyhrZXkpICYmIGRlbGV0ZSB0aGlzLl9fZGF0YV9fW2tleV07XG4gIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBoYXNoRGVsZXRlO1xuIiwidmFyIG5hdGl2ZUNyZWF0ZSA9IHJlcXVpcmUoJy4vX25hdGl2ZUNyZWF0ZScpO1xuXG4vKiogVXNlZCB0byBzdGFuZC1pbiBmb3IgYHVuZGVmaW5lZGAgaGFzaCB2YWx1ZXMuICovXG52YXIgSEFTSF9VTkRFRklORUQgPSAnX19sb2Rhc2hfaGFzaF91bmRlZmluZWRfXyc7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogR2V0cyB0aGUgaGFzaCB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIEhhc2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGVudHJ5IHZhbHVlLlxuICovXG5mdW5jdGlvbiBoYXNoR2V0KGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gIGlmIChuYXRpdmVDcmVhdGUpIHtcbiAgICB2YXIgcmVzdWx0ID0gZGF0YVtrZXldO1xuICAgIHJldHVybiByZXN1bHQgPT09IEhBU0hfVU5ERUZJTkVEID8gdW5kZWZpbmVkIDogcmVzdWx0O1xuICB9XG4gIHJldHVybiBoYXNPd25Qcm9wZXJ0eS5jYWxsKGRhdGEsIGtleSkgPyBkYXRhW2tleV0gOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzaEdldDtcbiIsInZhciBuYXRpdmVDcmVhdGUgPSByZXF1aXJlKCcuL19uYXRpdmVDcmVhdGUnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gY2hlY2sgb2JqZWN0cyBmb3Igb3duIHByb3BlcnRpZXMuICovXG52YXIgaGFzT3duUHJvcGVydHkgPSBvYmplY3RQcm90by5oYXNPd25Qcm9wZXJ0eTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBoYXNoIHZhbHVlIGZvciBga2V5YCBleGlzdHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGhhc1xuICogQG1lbWJlck9mIEhhc2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBoYXNoSGFzKGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX187XG4gIHJldHVybiBuYXRpdmVDcmVhdGUgPyAoZGF0YVtrZXldICE9PSB1bmRlZmluZWQpIDogaGFzT3duUHJvcGVydHkuY2FsbChkYXRhLCBrZXkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hIYXM7XG4iLCJ2YXIgbmF0aXZlQ3JlYXRlID0gcmVxdWlyZSgnLi9fbmF0aXZlQ3JlYXRlJyk7XG5cbi8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi9cbnZhciBIQVNIX1VOREVGSU5FRCA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJztcblxuLyoqXG4gKiBTZXRzIHRoZSBoYXNoIGBrZXlgIHRvIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIHNldFxuICogQG1lbWJlck9mIEhhc2hcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgaGFzaCBpbnN0YW5jZS5cbiAqL1xuZnVuY3Rpb24gaGFzaFNldChrZXksIHZhbHVlKSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXztcbiAgdGhpcy5zaXplICs9IHRoaXMuaGFzKGtleSkgPyAwIDogMTtcbiAgZGF0YVtrZXldID0gKG5hdGl2ZUNyZWF0ZSAmJiB2YWx1ZSA9PT0gdW5kZWZpbmVkKSA/IEhBU0hfVU5ERUZJTkVEIDogdmFsdWU7XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGhhc2hTZXQ7XG4iLCIvKiogVXNlZCB0byBtYXRjaCB3cmFwIGRldGFpbCBjb21tZW50cy4gKi9cbnZhciByZVdyYXBDb21tZW50ID0gL1xceyg/OlxcblxcL1xcKiBcXFt3cmFwcGVkIHdpdGggLitcXF0gXFwqXFwvKT9cXG4/LztcblxuLyoqXG4gKiBJbnNlcnRzIHdyYXBwZXIgYGRldGFpbHNgIGluIGEgY29tbWVudCBhdCB0aGUgdG9wIG9mIHRoZSBgc291cmNlYCBib2R5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIFRoZSBzb3VyY2UgdG8gbW9kaWZ5LlxuICogQHJldHVybnMge0FycmF5fSBkZXRhaWxzIFRoZSBkZXRhaWxzIHRvIGluc2VydC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIG1vZGlmaWVkIHNvdXJjZS5cbiAqL1xuZnVuY3Rpb24gaW5zZXJ0V3JhcERldGFpbHMoc291cmNlLCBkZXRhaWxzKSB7XG4gIHZhciBsZW5ndGggPSBkZXRhaWxzLmxlbmd0aDtcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICByZXR1cm4gc291cmNlO1xuICB9XG4gIHZhciBsYXN0SW5kZXggPSBsZW5ndGggLSAxO1xuICBkZXRhaWxzW2xhc3RJbmRleF0gPSAobGVuZ3RoID4gMSA/ICcmICcgOiAnJykgKyBkZXRhaWxzW2xhc3RJbmRleF07XG4gIGRldGFpbHMgPSBkZXRhaWxzLmpvaW4obGVuZ3RoID4gMiA/ICcsICcgOiAnICcpO1xuICByZXR1cm4gc291cmNlLnJlcGxhY2UocmVXcmFwQ29tbWVudCwgJ3tcXG4vKiBbd3JhcHBlZCB3aXRoICcgKyBkZXRhaWxzICsgJ10gKi9cXG4nKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpbnNlcnRXcmFwRGV0YWlscztcbiIsInZhciBTeW1ib2wgPSByZXF1aXJlKCcuL19TeW1ib2wnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5Jyk7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHNwcmVhZGFibGVTeW1ib2wgPSBTeW1ib2wgPyBTeW1ib2wuaXNDb25jYXRTcHJlYWRhYmxlIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgZmxhdHRlbmFibGUgYGFyZ3VtZW50c2Agb2JqZWN0IG9yIGFycmF5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGZsYXR0ZW5hYmxlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzRmxhdHRlbmFibGUodmFsdWUpIHtcbiAgcmV0dXJuIGlzQXJyYXkodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSB8fFxuICAgICEhKHNwcmVhZGFibGVTeW1ib2wgJiYgdmFsdWUgJiYgdmFsdWVbc3ByZWFkYWJsZVN5bWJvbF0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRmxhdHRlbmFibGU7XG4iLCIvKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IHVuc2lnbmVkIGludGVnZXIgdmFsdWVzLiAqL1xudmFyIHJlSXNVaW50ID0gL14oPzowfFsxLTldXFxkKikkLztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgaW5kZXguXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHBhcmFtIHtudW1iZXJ9IFtsZW5ndGg9TUFYX1NBRkVfSU5URUdFUl0gVGhlIHVwcGVyIGJvdW5kcyBvZiBhIHZhbGlkIGluZGV4LlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBpbmRleCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0luZGV4KHZhbHVlLCBsZW5ndGgpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGxlbmd0aCA9IGxlbmd0aCA9PSBudWxsID8gTUFYX1NBRkVfSU5URUdFUiA6IGxlbmd0aDtcblxuICByZXR1cm4gISFsZW5ndGggJiZcbiAgICAodHlwZSA9PSAnbnVtYmVyJyB8fFxuICAgICAgKHR5cGUgIT0gJ3N5bWJvbCcgJiYgcmVJc1VpbnQudGVzdCh2YWx1ZSkpKSAmJlxuICAgICAgICAodmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJbmRleDtcbiIsInZhciBlcSA9IHJlcXVpcmUoJy4vZXEnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9faXNJbmRleCcpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHBvdGVudGlhbCBpdGVyYXRlZSB2YWx1ZSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Kn0gaW5kZXggVGhlIHBvdGVudGlhbCBpdGVyYXRlZSBpbmRleCBvciBrZXkgYXJndW1lbnQuXG4gKiBAcGFyYW0geyp9IG9iamVjdCBUaGUgcG90ZW50aWFsIGl0ZXJhdGVlIG9iamVjdCBhcmd1bWVudC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgYXJndW1lbnRzIGFyZSBmcm9tIGFuIGl0ZXJhdGVlIGNhbGwsXG4gKiAgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0l0ZXJhdGVlQ2FsbCh2YWx1ZSwgaW5kZXgsIG9iamVjdCkge1xuICBpZiAoIWlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHR5cGUgPSB0eXBlb2YgaW5kZXg7XG4gIGlmICh0eXBlID09ICdudW1iZXInXG4gICAgICAgID8gKGlzQXJyYXlMaWtlKG9iamVjdCkgJiYgaXNJbmRleChpbmRleCwgb2JqZWN0Lmxlbmd0aCkpXG4gICAgICAgIDogKHR5cGUgPT0gJ3N0cmluZycgJiYgaW5kZXggaW4gb2JqZWN0KVxuICAgICAgKSB7XG4gICAgcmV0dXJuIGVxKG9iamVjdFtpbmRleF0sIHZhbHVlKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNJdGVyYXRlZUNhbGw7XG4iLCJ2YXIgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzU3ltYm9sID0gcmVxdWlyZSgnLi9pc1N5bWJvbCcpO1xuXG4vKiogVXNlZCB0byBtYXRjaCBwcm9wZXJ0eSBuYW1lcyB3aXRoaW4gcHJvcGVydHkgcGF0aHMuICovXG52YXIgcmVJc0RlZXBQcm9wID0gL1xcLnxcXFsoPzpbXltcXF1dKnwoW1wiJ10pKD86KD8hXFwxKVteXFxcXF18XFxcXC4pKj9cXDEpXFxdLyxcbiAgICByZUlzUGxhaW5Qcm9wID0gL15cXHcqJC87XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBwcm9wZXJ0eSBuYW1lIGFuZCBub3QgYSBwcm9wZXJ0eSBwYXRoLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEBwYXJhbSB7T2JqZWN0fSBbb2JqZWN0XSBUaGUgb2JqZWN0IHRvIHF1ZXJ5IGtleXMgb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3BlcnR5IG5hbWUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNLZXkodmFsdWUsIG9iamVjdCkge1xuICBpZiAoaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIGlmICh0eXBlID09ICdudW1iZXInIHx8IHR5cGUgPT0gJ3N5bWJvbCcgfHwgdHlwZSA9PSAnYm9vbGVhbicgfHxcbiAgICAgIHZhbHVlID09IG51bGwgfHwgaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgcmV0dXJuIHJlSXNQbGFpblByb3AudGVzdCh2YWx1ZSkgfHwgIXJlSXNEZWVwUHJvcC50ZXN0KHZhbHVlKSB8fFxuICAgIChvYmplY3QgIT0gbnVsbCAmJiB2YWx1ZSBpbiBPYmplY3Qob2JqZWN0KSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNLZXk7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHN1aXRhYmxlIGZvciB1c2UgYXMgdW5pcXVlIG9iamVjdCBrZXkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgc3VpdGFibGUsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNLZXlhYmxlKHZhbHVlKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gKHR5cGUgPT0gJ3N0cmluZycgfHwgdHlwZSA9PSAnbnVtYmVyJyB8fCB0eXBlID09ICdzeW1ib2wnIHx8IHR5cGUgPT0gJ2Jvb2xlYW4nKVxuICAgID8gKHZhbHVlICE9PSAnX19wcm90b19fJylcbiAgICA6ICh2YWx1ZSA9PT0gbnVsbCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNLZXlhYmxlO1xuIiwidmFyIExhenlXcmFwcGVyID0gcmVxdWlyZSgnLi9fTGF6eVdyYXBwZXInKSxcbiAgICBnZXREYXRhID0gcmVxdWlyZSgnLi9fZ2V0RGF0YScpLFxuICAgIGdldEZ1bmNOYW1lID0gcmVxdWlyZSgnLi9fZ2V0RnVuY05hbWUnKSxcbiAgICBsb2Rhc2ggPSByZXF1aXJlKCcuL3dyYXBwZXJMb2Rhc2gnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYGZ1bmNgIGhhcyBhIGxhenkgY291bnRlcnBhcnQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBmdW5jYCBoYXMgYSBsYXp5IGNvdW50ZXJwYXJ0LFxuICogIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNMYXppYWJsZShmdW5jKSB7XG4gIHZhciBmdW5jTmFtZSA9IGdldEZ1bmNOYW1lKGZ1bmMpLFxuICAgICAgb3RoZXIgPSBsb2Rhc2hbZnVuY05hbWVdO1xuXG4gIGlmICh0eXBlb2Ygb3RoZXIgIT0gJ2Z1bmN0aW9uJyB8fCAhKGZ1bmNOYW1lIGluIExhenlXcmFwcGVyLnByb3RvdHlwZSkpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGZ1bmMgPT09IG90aGVyKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgdmFyIGRhdGEgPSBnZXREYXRhKG90aGVyKTtcbiAgcmV0dXJuICEhZGF0YSAmJiBmdW5jID09PSBkYXRhWzBdO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTGF6aWFibGU7XG4iLCJ2YXIgY29yZUpzRGF0YSA9IHJlcXVpcmUoJy4vX2NvcmVKc0RhdGEnKTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IG1ldGhvZHMgbWFzcXVlcmFkaW5nIGFzIG5hdGl2ZS4gKi9cbnZhciBtYXNrU3JjS2V5ID0gKGZ1bmN0aW9uKCkge1xuICB2YXIgdWlkID0gL1teLl0rJC8uZXhlYyhjb3JlSnNEYXRhICYmIGNvcmVKc0RhdGEua2V5cyAmJiBjb3JlSnNEYXRhLmtleXMuSUVfUFJPVE8gfHwgJycpO1xuICByZXR1cm4gdWlkID8gKCdTeW1ib2woc3JjKV8xLicgKyB1aWQpIDogJyc7XG59KCkpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgZnVuY2AgaGFzIGl0cyBzb3VyY2UgbWFza2VkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgZnVuY2AgaXMgbWFza2VkLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzTWFza2VkKGZ1bmMpIHtcbiAgcmV0dXJuICEhbWFza1NyY0tleSAmJiAobWFza1NyY0tleSBpbiBmdW5jKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc01hc2tlZDtcbiIsIi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGEgcHJvdG90eXBlIG9iamVjdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHByb3RvdHlwZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc1Byb3RvdHlwZSh2YWx1ZSkge1xuICB2YXIgQ3RvciA9IHZhbHVlICYmIHZhbHVlLmNvbnN0cnVjdG9yLFxuICAgICAgcHJvdG8gPSAodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSkgfHwgb2JqZWN0UHJvdG87XG5cbiAgcmV0dXJuIHZhbHVlID09PSBwcm90bztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc1Byb3RvdHlwZTtcbiIsInZhciBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBzdWl0YWJsZSBmb3Igc3RyaWN0IGVxdWFsaXR5IGNvbXBhcmlzb25zLCBpLmUuIGA9PT1gLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlmIHN1aXRhYmxlIGZvciBzdHJpY3RcbiAqICBlcXVhbGl0eSBjb21wYXJpc29ucywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc1N0cmljdENvbXBhcmFibGUodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSAmJiAhaXNPYmplY3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzU3RyaWN0Q29tcGFyYWJsZTtcbiIsIi8qKlxuICogUmVtb3ZlcyBhbGwga2V5LXZhbHVlIGVudHJpZXMgZnJvbSB0aGUgbGlzdCBjYWNoZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlQ2xlYXIoKSB7XG4gIHRoaXMuX19kYXRhX18gPSBbXTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVDbGVhcjtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIGFycmF5UHJvdG8gPSBBcnJheS5wcm90b3R5cGU7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHNwbGljZSA9IGFycmF5UHJvdG8uc3BsaWNlO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBsaXN0IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBkZWxldGVcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gcmVtb3ZlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSBlbnRyeSB3YXMgcmVtb3ZlZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIGluZGV4ID0gYXNzb2NJbmRleE9mKGRhdGEsIGtleSk7XG5cbiAgaWYgKGluZGV4IDwgMCkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB2YXIgbGFzdEluZGV4ID0gZGF0YS5sZW5ndGggLSAxO1xuICBpZiAoaW5kZXggPT0gbGFzdEluZGV4KSB7XG4gICAgZGF0YS5wb3AoKTtcbiAgfSBlbHNlIHtcbiAgICBzcGxpY2UuY2FsbChkYXRhLCBpbmRleCwgMSk7XG4gIH1cbiAgLS10aGlzLnNpemU7XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZURlbGV0ZTtcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSBsaXN0IGNhY2hlIHZhbHVlIGZvciBga2V5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgZ2V0XG4gKiBAbWVtYmVyT2YgTGlzdENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbGlzdENhY2hlR2V0KGtleSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIHJldHVybiBpbmRleCA8IDAgPyB1bmRlZmluZWQgOiBkYXRhW2luZGV4XVsxXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBsaXN0Q2FjaGVHZXQ7XG4iLCJ2YXIgYXNzb2NJbmRleE9mID0gcmVxdWlyZSgnLi9fYXNzb2NJbmRleE9mJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGEgbGlzdCBjYWNoZSB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBMaXN0Q2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVIYXMoa2V5KSB7XG4gIHJldHVybiBhc3NvY0luZGV4T2YodGhpcy5fX2RhdGFfXywga2V5KSA+IC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZUhhcztcbiIsInZhciBhc3NvY0luZGV4T2YgPSByZXF1aXJlKCcuL19hc3NvY0luZGV4T2YnKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBsaXN0IGNhY2hlIGBrZXlgIHRvIGB2YWx1ZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIHNldFxuICogQG1lbWJlck9mIExpc3RDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBsaXN0IGNhY2hlIGluc3RhbmNlLlxuICovXG5mdW5jdGlvbiBsaXN0Q2FjaGVTZXQoa2V5LCB2YWx1ZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuX19kYXRhX18sXG4gICAgICBpbmRleCA9IGFzc29jSW5kZXhPZihkYXRhLCBrZXkpO1xuXG4gIGlmIChpbmRleCA8IDApIHtcbiAgICArK3RoaXMuc2l6ZTtcbiAgICBkYXRhLnB1c2goW2tleSwgdmFsdWVdKTtcbiAgfSBlbHNlIHtcbiAgICBkYXRhW2luZGV4XVsxXSA9IHZhbHVlO1xuICB9XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGxpc3RDYWNoZVNldDtcbiIsInZhciBIYXNoID0gcmVxdWlyZSgnLi9fSGFzaCcpLFxuICAgIExpc3RDYWNoZSA9IHJlcXVpcmUoJy4vX0xpc3RDYWNoZScpLFxuICAgIE1hcCA9IHJlcXVpcmUoJy4vX01hcCcpO1xuXG4vKipcbiAqIFJlbW92ZXMgYWxsIGtleS12YWx1ZSBlbnRyaWVzIGZyb20gdGhlIG1hcC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUNsZWFyKCkge1xuICB0aGlzLnNpemUgPSAwO1xuICB0aGlzLl9fZGF0YV9fID0ge1xuICAgICdoYXNoJzogbmV3IEhhc2gsXG4gICAgJ21hcCc6IG5ldyAoTWFwIHx8IExpc3RDYWNoZSksXG4gICAgJ3N0cmluZyc6IG5ldyBIYXNoXG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVDbGVhcjtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFJlbW92ZXMgYGtleWAgYW5kIGl0cyB2YWx1ZSBmcm9tIHRoZSBtYXAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVEZWxldGUoa2V5KSB7XG4gIHZhciByZXN1bHQgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSlbJ2RlbGV0ZSddKGtleSk7XG4gIHRoaXMuc2l6ZSAtPSByZXN1bHQgPyAxIDogMDtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZURlbGV0ZTtcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIEdldHMgdGhlIG1hcCB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIE1hcENhY2hlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gbWFwQ2FjaGVHZXQoa2V5KSB7XG4gIHJldHVybiBnZXRNYXBEYXRhKHRoaXMsIGtleSkuZ2V0KGtleSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVHZXQ7XG4iLCJ2YXIgZ2V0TWFwRGF0YSA9IHJlcXVpcmUoJy4vX2dldE1hcERhdGEnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYSBtYXAgdmFsdWUgZm9yIGBrZXlgIGV4aXN0cy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgaGFzXG4gKiBAbWVtYmVyT2YgTWFwQ2FjaGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgZW50cnkgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYW4gZW50cnkgZm9yIGBrZXlgIGV4aXN0cywgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBtYXBDYWNoZUhhcyhrZXkpIHtcbiAgcmV0dXJuIGdldE1hcERhdGEodGhpcywga2V5KS5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBtYXBDYWNoZUhhcztcbiIsInZhciBnZXRNYXBEYXRhID0gcmVxdWlyZSgnLi9fZ2V0TWFwRGF0YScpO1xuXG4vKipcbiAqIFNldHMgdGhlIG1hcCBga2V5YCB0byBgdmFsdWVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBzZXRcbiAqIEBtZW1iZXJPZiBNYXBDYWNoZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBtYXAgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIG1hcENhY2hlU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSBnZXRNYXBEYXRhKHRoaXMsIGtleSksXG4gICAgICBzaXplID0gZGF0YS5zaXplO1xuXG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgKz0gZGF0YS5zaXplID09IHNpemUgPyAwIDogMTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWFwQ2FjaGVTZXQ7XG4iLCIvKipcbiAqIENvbnZlcnRzIGBtYXBgIHRvIGl0cyBrZXktdmFsdWUgcGFpcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBtYXAgVGhlIG1hcCB0byBjb252ZXJ0LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBrZXktdmFsdWUgcGFpcnMuXG4gKi9cbmZ1bmN0aW9uIG1hcFRvQXJyYXkobWFwKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkobWFwLnNpemUpO1xuXG4gIG1hcC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAgICByZXN1bHRbKytpbmRleF0gPSBba2V5LCB2YWx1ZV07XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcFRvQXJyYXk7XG4iLCIvKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgbWF0Y2hlc1Byb3BlcnR5YCBmb3Igc291cmNlIHZhbHVlcyBzdWl0YWJsZVxuICogZm9yIHN0cmljdCBlcXVhbGl0eSBjb21wYXJpc29ucywgaS5lLiBgPT09YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcGFyYW0geyp9IHNyY1ZhbHVlIFRoZSB2YWx1ZSB0byBtYXRjaC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IHNwZWMgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIG1hdGNoZXNTdHJpY3RDb21wYXJhYmxlKGtleSwgc3JjVmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGlmIChvYmplY3QgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0W2tleV0gPT09IHNyY1ZhbHVlICYmXG4gICAgICAoc3JjVmFsdWUgIT09IHVuZGVmaW5lZCB8fCAoa2V5IGluIE9iamVjdChvYmplY3QpKSk7XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWF0Y2hlc1N0cmljdENvbXBhcmFibGU7XG4iLCJ2YXIgbWVtb2l6ZSA9IHJlcXVpcmUoJy4vbWVtb2l6ZScpO1xuXG4vKiogVXNlZCBhcyB0aGUgbWF4aW11bSBtZW1vaXplIGNhY2hlIHNpemUuICovXG52YXIgTUFYX01FTU9JWkVfU0laRSA9IDUwMDtcblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8ubWVtb2l6ZWAgd2hpY2ggY2xlYXJzIHRoZSBtZW1vaXplZCBmdW5jdGlvbidzXG4gKiBjYWNoZSB3aGVuIGl0IGV4Y2VlZHMgYE1BWF9NRU1PSVpFX1NJWkVgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBoYXZlIGl0cyBvdXRwdXQgbWVtb2l6ZWQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBtZW1vaXplZCBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gbWVtb2l6ZUNhcHBlZChmdW5jKSB7XG4gIHZhciByZXN1bHQgPSBtZW1vaXplKGZ1bmMsIGZ1bmN0aW9uKGtleSkge1xuICAgIGlmIChjYWNoZS5zaXplID09PSBNQVhfTUVNT0laRV9TSVpFKSB7XG4gICAgICBjYWNoZS5jbGVhcigpO1xuICAgIH1cbiAgICByZXR1cm4ga2V5O1xuICB9KTtcblxuICB2YXIgY2FjaGUgPSByZXN1bHQuY2FjaGU7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbWVtb2l6ZUNhcHBlZDtcbiIsInZhciBjb21wb3NlQXJncyA9IHJlcXVpcmUoJy4vX2NvbXBvc2VBcmdzJyksXG4gICAgY29tcG9zZUFyZ3NSaWdodCA9IHJlcXVpcmUoJy4vX2NvbXBvc2VBcmdzUmlnaHQnKSxcbiAgICByZXBsYWNlSG9sZGVycyA9IHJlcXVpcmUoJy4vX3JlcGxhY2VIb2xkZXJzJyk7XG5cbi8qKiBVc2VkIGFzIHRoZSBpbnRlcm5hbCBhcmd1bWVudCBwbGFjZWhvbGRlci4gKi9cbnZhciBQTEFDRUhPTERFUiA9ICdfX2xvZGFzaF9wbGFjZWhvbGRlcl9fJztcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgV1JBUF9CSU5EX0ZMQUcgPSAxLFxuICAgIFdSQVBfQklORF9LRVlfRkxBRyA9IDIsXG4gICAgV1JBUF9DVVJSWV9CT1VORF9GTEFHID0gNCxcbiAgICBXUkFQX0NVUlJZX0ZMQUcgPSA4LFxuICAgIFdSQVBfQVJZX0ZMQUcgPSAxMjgsXG4gICAgV1JBUF9SRUFSR19GTEFHID0gMjU2O1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKlxuICogTWVyZ2VzIHRoZSBmdW5jdGlvbiBtZXRhZGF0YSBvZiBgc291cmNlYCBpbnRvIGBkYXRhYC5cbiAqXG4gKiBNZXJnaW5nIG1ldGFkYXRhIHJlZHVjZXMgdGhlIG51bWJlciBvZiB3cmFwcGVycyB1c2VkIHRvIGludm9rZSBhIGZ1bmN0aW9uLlxuICogVGhpcyBpcyBwb3NzaWJsZSBiZWNhdXNlIG1ldGhvZHMgbGlrZSBgXy5iaW5kYCwgYF8uY3VycnlgLCBhbmQgYF8ucGFydGlhbGBcbiAqIG1heSBiZSBhcHBsaWVkIHJlZ2FyZGxlc3Mgb2YgZXhlY3V0aW9uIG9yZGVyLiBNZXRob2RzIGxpa2UgYF8uYXJ5YCBhbmRcbiAqIGBfLnJlYXJnYCBtb2RpZnkgZnVuY3Rpb24gYXJndW1lbnRzLCBtYWtpbmcgdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgYXJlXG4gKiBleGVjdXRlZCBpbXBvcnRhbnQsIHByZXZlbnRpbmcgdGhlIG1lcmdpbmcgb2YgbWV0YWRhdGEuIEhvd2V2ZXIsIHdlIG1ha2VcbiAqIGFuIGV4Y2VwdGlvbiBmb3IgYSBzYWZlIGNvbWJpbmVkIGNhc2Ugd2hlcmUgY3VycmllZCBmdW5jdGlvbnMgaGF2ZSBgXy5hcnlgXG4gKiBhbmQgb3IgYF8ucmVhcmdgIGFwcGxpZWQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgVGhlIGRlc3RpbmF0aW9uIG1ldGFkYXRhLlxuICogQHBhcmFtIHtBcnJheX0gc291cmNlIFRoZSBzb3VyY2UgbWV0YWRhdGEuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYGRhdGFgLlxuICovXG5mdW5jdGlvbiBtZXJnZURhdGEoZGF0YSwgc291cmNlKSB7XG4gIHZhciBiaXRtYXNrID0gZGF0YVsxXSxcbiAgICAgIHNyY0JpdG1hc2sgPSBzb3VyY2VbMV0sXG4gICAgICBuZXdCaXRtYXNrID0gYml0bWFzayB8IHNyY0JpdG1hc2ssXG4gICAgICBpc0NvbW1vbiA9IG5ld0JpdG1hc2sgPCAoV1JBUF9CSU5EX0ZMQUcgfCBXUkFQX0JJTkRfS0VZX0ZMQUcgfCBXUkFQX0FSWV9GTEFHKTtcblxuICB2YXIgaXNDb21ibyA9XG4gICAgKChzcmNCaXRtYXNrID09IFdSQVBfQVJZX0ZMQUcpICYmIChiaXRtYXNrID09IFdSQVBfQ1VSUllfRkxBRykpIHx8XG4gICAgKChzcmNCaXRtYXNrID09IFdSQVBfQVJZX0ZMQUcpICYmIChiaXRtYXNrID09IFdSQVBfUkVBUkdfRkxBRykgJiYgKGRhdGFbN10ubGVuZ3RoIDw9IHNvdXJjZVs4XSkpIHx8XG4gICAgKChzcmNCaXRtYXNrID09IChXUkFQX0FSWV9GTEFHIHwgV1JBUF9SRUFSR19GTEFHKSkgJiYgKHNvdXJjZVs3XS5sZW5ndGggPD0gc291cmNlWzhdKSAmJiAoYml0bWFzayA9PSBXUkFQX0NVUlJZX0ZMQUcpKTtcblxuICAvLyBFeGl0IGVhcmx5IGlmIG1ldGFkYXRhIGNhbid0IGJlIG1lcmdlZC5cbiAgaWYgKCEoaXNDb21tb24gfHwgaXNDb21ibykpIHtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGB0aGlzQXJnYCBpZiBhdmFpbGFibGUuXG4gIGlmIChzcmNCaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcpIHtcbiAgICBkYXRhWzJdID0gc291cmNlWzJdO1xuICAgIC8vIFNldCB3aGVuIGN1cnJ5aW5nIGEgYm91bmQgZnVuY3Rpb24uXG4gICAgbmV3Qml0bWFzayB8PSBiaXRtYXNrICYgV1JBUF9CSU5EX0ZMQUcgPyAwIDogV1JBUF9DVVJSWV9CT1VORF9GTEFHO1xuICB9XG4gIC8vIENvbXBvc2UgcGFydGlhbCBhcmd1bWVudHMuXG4gIHZhciB2YWx1ZSA9IHNvdXJjZVszXTtcbiAgaWYgKHZhbHVlKSB7XG4gICAgdmFyIHBhcnRpYWxzID0gZGF0YVszXTtcbiAgICBkYXRhWzNdID0gcGFydGlhbHMgPyBjb21wb3NlQXJncyhwYXJ0aWFscywgdmFsdWUsIHNvdXJjZVs0XSkgOiB2YWx1ZTtcbiAgICBkYXRhWzRdID0gcGFydGlhbHMgPyByZXBsYWNlSG9sZGVycyhkYXRhWzNdLCBQTEFDRUhPTERFUikgOiBzb3VyY2VbNF07XG4gIH1cbiAgLy8gQ29tcG9zZSBwYXJ0aWFsIHJpZ2h0IGFyZ3VtZW50cy5cbiAgdmFsdWUgPSBzb3VyY2VbNV07XG4gIGlmICh2YWx1ZSkge1xuICAgIHBhcnRpYWxzID0gZGF0YVs1XTtcbiAgICBkYXRhWzVdID0gcGFydGlhbHMgPyBjb21wb3NlQXJnc1JpZ2h0KHBhcnRpYWxzLCB2YWx1ZSwgc291cmNlWzZdKSA6IHZhbHVlO1xuICAgIGRhdGFbNl0gPSBwYXJ0aWFscyA/IHJlcGxhY2VIb2xkZXJzKGRhdGFbNV0sIFBMQUNFSE9MREVSKSA6IHNvdXJjZVs2XTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcmdQb3NgIGlmIGF2YWlsYWJsZS5cbiAgdmFsdWUgPSBzb3VyY2VbN107XG4gIGlmICh2YWx1ZSkge1xuICAgIGRhdGFbN10gPSB2YWx1ZTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBhcnlgIGlmIGl0J3Mgc21hbGxlci5cbiAgaWYgKHNyY0JpdG1hc2sgJiBXUkFQX0FSWV9GTEFHKSB7XG4gICAgZGF0YVs4XSA9IGRhdGFbOF0gPT0gbnVsbCA/IHNvdXJjZVs4XSA6IG5hdGl2ZU1pbihkYXRhWzhdLCBzb3VyY2VbOF0pO1xuICB9XG4gIC8vIFVzZSBzb3VyY2UgYGFyaXR5YCBpZiBvbmUgaXMgbm90IHByb3ZpZGVkLlxuICBpZiAoZGF0YVs5XSA9PSBudWxsKSB7XG4gICAgZGF0YVs5XSA9IHNvdXJjZVs5XTtcbiAgfVxuICAvLyBVc2Ugc291cmNlIGBmdW5jYCBhbmQgbWVyZ2UgYml0bWFza3MuXG4gIGRhdGFbMF0gPSBzb3VyY2VbMF07XG4gIGRhdGFbMV0gPSBuZXdCaXRtYXNrO1xuXG4gIHJldHVybiBkYXRhO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1lcmdlRGF0YTtcbiIsInZhciBXZWFrTWFwID0gcmVxdWlyZSgnLi9fV2Vha01hcCcpO1xuXG4vKiogVXNlZCB0byBzdG9yZSBmdW5jdGlvbiBtZXRhZGF0YS4gKi9cbnZhciBtZXRhTWFwID0gV2Vha01hcCAmJiBuZXcgV2Vha01hcDtcblxubW9kdWxlLmV4cG9ydHMgPSBtZXRhTWFwO1xuIiwidmFyIGdldE5hdGl2ZSA9IHJlcXVpcmUoJy4vX2dldE5hdGl2ZScpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB0aGF0IGFyZSB2ZXJpZmllZCB0byBiZSBuYXRpdmUuICovXG52YXIgbmF0aXZlQ3JlYXRlID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2NyZWF0ZScpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5hdGl2ZUNyZWF0ZTtcbiIsInZhciBvdmVyQXJnID0gcmVxdWlyZSgnLi9fb3ZlckFyZycpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IG92ZXJBcmcoT2JqZWN0LmtleXMsIE9iamVjdCk7XG5cbm1vZHVsZS5leHBvcnRzID0gbmF0aXZlS2V5cztcbiIsInZhciBmcmVlR2xvYmFsID0gcmVxdWlyZSgnLi9fZnJlZUdsb2JhbCcpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xudmFyIGZyZWVFeHBvcnRzID0gdHlwZW9mIGV4cG9ydHMgPT0gJ29iamVjdCcgJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG52YXIgZnJlZU1vZHVsZSA9IGZyZWVFeHBvcnRzICYmIHR5cGVvZiBtb2R1bGUgPT0gJ29iamVjdCcgJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgbW9kdWxlO1xuXG4vKiogRGV0ZWN0IHRoZSBwb3B1bGFyIENvbW1vbkpTIGV4dGVuc2lvbiBgbW9kdWxlLmV4cG9ydHNgLiAqL1xudmFyIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHM7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgcHJvY2Vzc2AgZnJvbSBOb2RlLmpzLiAqL1xudmFyIGZyZWVQcm9jZXNzID0gbW9kdWxlRXhwb3J0cyAmJiBmcmVlR2xvYmFsLnByb2Nlc3M7XG5cbi8qKiBVc2VkIHRvIGFjY2VzcyBmYXN0ZXIgTm9kZS5qcyBoZWxwZXJzLiAqL1xudmFyIG5vZGVVdGlsID0gKGZ1bmN0aW9uKCkge1xuICB0cnkge1xuICAgIC8vIFVzZSBgdXRpbC50eXBlc2AgZm9yIE5vZGUuanMgMTArLlxuICAgIHZhciB0eXBlcyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5yZXF1aXJlICYmIGZyZWVNb2R1bGUucmVxdWlyZSgndXRpbCcpLnR5cGVzO1xuXG4gICAgaWYgKHR5cGVzKSB7XG4gICAgICByZXR1cm4gdHlwZXM7XG4gICAgfVxuXG4gICAgLy8gTGVnYWN5IGBwcm9jZXNzLmJpbmRpbmcoJ3V0aWwnKWAgZm9yIE5vZGUuanMgPCAxMC5cbiAgICByZXR1cm4gZnJlZVByb2Nlc3MgJiYgZnJlZVByb2Nlc3MuYmluZGluZyAmJiBmcmVlUHJvY2Vzcy5iaW5kaW5nKCd1dGlsJyk7XG4gIH0gY2F0Y2ggKGUpIHt9XG59KCkpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IG5vZGVVdGlsO1xuIiwiLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlXG4gKiBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG5hdGl2ZU9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyB1c2luZyBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICovXG5mdW5jdGlvbiBvYmplY3RUb1N0cmluZyh2YWx1ZSkge1xuICByZXR1cm4gbmF0aXZlT2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gb2JqZWN0VG9TdHJpbmc7XG4iLCIvKipcbiAqIENyZWF0ZXMgYSB1bmFyeSBmdW5jdGlvbiB0aGF0IGludm9rZXMgYGZ1bmNgIHdpdGggaXRzIGFyZ3VtZW50IHRyYW5zZm9ybWVkLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byB3cmFwLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNmb3JtIFRoZSBhcmd1bWVudCB0cmFuc2Zvcm0uXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gb3ZlckFyZyhmdW5jLCB0cmFuc2Zvcm0pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGFyZykge1xuICAgIHJldHVybiBmdW5jKHRyYW5zZm9ybShhcmcpKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBvdmVyQXJnO1xuIiwidmFyIGFwcGx5ID0gcmVxdWlyZSgnLi9fYXBwbHknKTtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU1heCA9IE1hdGgubWF4O1xuXG4vKipcbiAqIEEgc3BlY2lhbGl6ZWQgdmVyc2lvbiBvZiBgYmFzZVJlc3RgIHdoaWNoIHRyYW5zZm9ybXMgdGhlIHJlc3QgYXJyYXkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2Zvcm0gVGhlIHJlc3QgYXJyYXkgdHJhbnNmb3JtLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIG92ZXJSZXN0KGZ1bmMsIHN0YXJ0LCB0cmFuc2Zvcm0pIHtcbiAgc3RhcnQgPSBuYXRpdmVNYXgoc3RhcnQgPT09IHVuZGVmaW5lZCA/IChmdW5jLmxlbmd0aCAtIDEpIDogc3RhcnQsIDApO1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3MgPSBhcmd1bWVudHMsXG4gICAgICAgIGluZGV4ID0gLTEsXG4gICAgICAgIGxlbmd0aCA9IG5hdGl2ZU1heChhcmdzLmxlbmd0aCAtIHN0YXJ0LCAwKSxcbiAgICAgICAgYXJyYXkgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIGFycmF5W2luZGV4XSA9IGFyZ3Nbc3RhcnQgKyBpbmRleF07XG4gICAgfVxuICAgIGluZGV4ID0gLTE7XG4gICAgdmFyIG90aGVyQXJncyA9IEFycmF5KHN0YXJ0ICsgMSk7XG4gICAgd2hpbGUgKCsraW5kZXggPCBzdGFydCkge1xuICAgICAgb3RoZXJBcmdzW2luZGV4XSA9IGFyZ3NbaW5kZXhdO1xuICAgIH1cbiAgICBvdGhlckFyZ3Nbc3RhcnRdID0gdHJhbnNmb3JtKGFycmF5KTtcbiAgICByZXR1cm4gYXBwbHkoZnVuYywgdGhpcywgb3RoZXJBcmdzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBvdmVyUmVzdDtcbiIsIi8qKiBVc2VkIHRvIGxvb2t1cCB1bm1pbmlmaWVkIGZ1bmN0aW9uIG5hbWVzLiAqL1xudmFyIHJlYWxOYW1lcyA9IHt9O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHJlYWxOYW1lcztcbiIsInZhciBjb3B5QXJyYXkgPSByZXF1aXJlKCcuL19jb3B5QXJyYXknKSxcbiAgICBpc0luZGV4ID0gcmVxdWlyZSgnLi9faXNJbmRleCcpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWluID0gTWF0aC5taW47XG5cbi8qKlxuICogUmVvcmRlciBgYXJyYXlgIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGluZGV4ZXMgd2hlcmUgdGhlIGVsZW1lbnQgYXRcbiAqIHRoZSBmaXJzdCBpbmRleCBpcyBhc3NpZ25lZCBhcyB0aGUgZmlyc3QgZWxlbWVudCwgdGhlIGVsZW1lbnQgYXRcbiAqIHRoZSBzZWNvbmQgaW5kZXggaXMgYXNzaWduZWQgYXMgdGhlIHNlY29uZCBlbGVtZW50LCBhbmQgc28gb24uXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byByZW9yZGVyLlxuICogQHBhcmFtIHtBcnJheX0gaW5kZXhlcyBUaGUgYXJyYW5nZWQgYXJyYXkgaW5kZXhlcy5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiByZW9yZGVyKGFycmF5LCBpbmRleGVzKSB7XG4gIHZhciBhcnJMZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICBsZW5ndGggPSBuYXRpdmVNaW4oaW5kZXhlcy5sZW5ndGgsIGFyckxlbmd0aCksXG4gICAgICBvbGRBcnJheSA9IGNvcHlBcnJheShhcnJheSk7XG5cbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgdmFyIGluZGV4ID0gaW5kZXhlc1tsZW5ndGhdO1xuICAgIGFycmF5W2xlbmd0aF0gPSBpc0luZGV4KGluZGV4LCBhcnJMZW5ndGgpID8gb2xkQXJyYXlbaW5kZXhdIDogdW5kZWZpbmVkO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZW9yZGVyO1xuIiwiLyoqIFVzZWQgYXMgdGhlIGludGVybmFsIGFyZ3VtZW50IHBsYWNlaG9sZGVyLiAqL1xudmFyIFBMQUNFSE9MREVSID0gJ19fbG9kYXNoX3BsYWNlaG9sZGVyX18nO1xuXG4vKipcbiAqIFJlcGxhY2VzIGFsbCBgcGxhY2Vob2xkZXJgIGVsZW1lbnRzIGluIGBhcnJheWAgd2l0aCBhbiBpbnRlcm5hbCBwbGFjZWhvbGRlclxuICogYW5kIHJldHVybnMgYW4gYXJyYXkgb2YgdGhlaXIgaW5kZXhlcy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7Kn0gcGxhY2Vob2xkZXIgVGhlIHBsYWNlaG9sZGVyIHRvIHJlcGxhY2UuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBhcnJheSBvZiBwbGFjZWhvbGRlciBpbmRleGVzLlxuICovXG5mdW5jdGlvbiByZXBsYWNlSG9sZGVycyhhcnJheSwgcGxhY2Vob2xkZXIpIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGgsXG4gICAgICByZXNJbmRleCA9IDAsXG4gICAgICByZXN1bHQgPSBbXTtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHZhciB2YWx1ZSA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAodmFsdWUgPT09IHBsYWNlaG9sZGVyIHx8IHZhbHVlID09PSBQTEFDRUhPTERFUikge1xuICAgICAgYXJyYXlbaW5kZXhdID0gUExBQ0VIT0xERVI7XG4gICAgICByZXN1bHRbcmVzSW5kZXgrK10gPSBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXBsYWNlSG9sZGVycztcbiIsInZhciBmcmVlR2xvYmFsID0gcmVxdWlyZSgnLi9fZnJlZUdsb2JhbCcpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqL1xudmFyIGZyZWVTZWxmID0gdHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgc2VsZiAmJiBzZWxmLk9iamVjdCA9PT0gT2JqZWN0ICYmIHNlbGY7XG5cbi8qKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LiAqL1xudmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8IGZyZWVTZWxmIHx8IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cbm1vZHVsZS5leHBvcnRzID0gcm9vdDtcbiIsIi8qKiBVc2VkIHRvIHN0YW5kLWluIGZvciBgdW5kZWZpbmVkYCBoYXNoIHZhbHVlcy4gKi9cbnZhciBIQVNIX1VOREVGSU5FRCA9ICdfX2xvZGFzaF9oYXNoX3VuZGVmaW5lZF9fJztcblxuLyoqXG4gKiBBZGRzIGB2YWx1ZWAgdG8gdGhlIGFycmF5IGNhY2hlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBhZGRcbiAqIEBtZW1iZXJPZiBTZXRDYWNoZVxuICogQGFsaWFzIHB1c2hcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNhY2hlLlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIHNldENhY2hlQWRkKHZhbHVlKSB7XG4gIHRoaXMuX19kYXRhX18uc2V0KHZhbHVlLCBIQVNIX1VOREVGSU5FRCk7XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldENhY2hlQWRkO1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBpbiB0aGUgYXJyYXkgY2FjaGUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGhhc1xuICogQG1lbWJlck9mIFNldENhY2hlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZWFyY2ggZm9yLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBmb3VuZCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBzZXRDYWNoZUhhcyh2YWx1ZSkge1xuICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXModmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldENhY2hlSGFzO1xuIiwidmFyIGJhc2VTZXREYXRhID0gcmVxdWlyZSgnLi9fYmFzZVNldERhdGEnKSxcbiAgICBzaG9ydE91dCA9IHJlcXVpcmUoJy4vX3Nob3J0T3V0Jyk7XG5cbi8qKlxuICogU2V0cyBtZXRhZGF0YSBmb3IgYGZ1bmNgLlxuICpcbiAqICoqTm90ZToqKiBJZiB0aGlzIGZ1bmN0aW9uIGJlY29tZXMgaG90LCBpLmUuIGlzIGludm9rZWQgYSBsb3QgaW4gYSBzaG9ydFxuICogcGVyaW9kIG9mIHRpbWUsIGl0IHdpbGwgdHJpcCBpdHMgYnJlYWtlciBhbmQgdHJhbnNpdGlvbiB0byBhbiBpZGVudGl0eVxuICogZnVuY3Rpb24gdG8gYXZvaWQgZ2FyYmFnZSBjb2xsZWN0aW9uIHBhdXNlcyBpbiBWOC4gU2VlXG4gKiBbVjggaXNzdWUgMjA3MF0oaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjA3MClcbiAqIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFzc29jaWF0ZSBtZXRhZGF0YSB3aXRoLlxuICogQHBhcmFtIHsqfSBkYXRhIFRoZSBtZXRhZGF0YS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyBgZnVuY2AuXG4gKi9cbnZhciBzZXREYXRhID0gc2hvcnRPdXQoYmFzZVNldERhdGEpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNldERhdGE7XG4iLCIvKipcbiAqIENvbnZlcnRzIGBzZXRgIHRvIGFuIGFycmF5IG9mIGl0cyB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBzZXQgVGhlIHNldCB0byBjb252ZXJ0LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSB2YWx1ZXMuXG4gKi9cbmZ1bmN0aW9uIHNldFRvQXJyYXkoc2V0KSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgcmVzdWx0ID0gQXJyYXkoc2V0LnNpemUpO1xuXG4gIHNldC5mb3JFYWNoKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgcmVzdWx0WysraW5kZXhdID0gdmFsdWU7XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldFRvQXJyYXk7XG4iLCJ2YXIgYmFzZVNldFRvU3RyaW5nID0gcmVxdWlyZSgnLi9fYmFzZVNldFRvU3RyaW5nJyksXG4gICAgc2hvcnRPdXQgPSByZXF1aXJlKCcuL19zaG9ydE91dCcpO1xuXG4vKipcbiAqIFNldHMgdGhlIGB0b1N0cmluZ2AgbWV0aG9kIG9mIGBmdW5jYCB0byByZXR1cm4gYHN0cmluZ2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IHN0cmluZyBUaGUgYHRvU3RyaW5nYCByZXN1bHQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYGZ1bmNgLlxuICovXG52YXIgc2V0VG9TdHJpbmcgPSBzaG9ydE91dChiYXNlU2V0VG9TdHJpbmcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHNldFRvU3RyaW5nO1xuIiwidmFyIGdldFdyYXBEZXRhaWxzID0gcmVxdWlyZSgnLi9fZ2V0V3JhcERldGFpbHMnKSxcbiAgICBpbnNlcnRXcmFwRGV0YWlscyA9IHJlcXVpcmUoJy4vX2luc2VydFdyYXBEZXRhaWxzJyksXG4gICAgc2V0VG9TdHJpbmcgPSByZXF1aXJlKCcuL19zZXRUb1N0cmluZycpLFxuICAgIHVwZGF0ZVdyYXBEZXRhaWxzID0gcmVxdWlyZSgnLi9fdXBkYXRlV3JhcERldGFpbHMnKTtcblxuLyoqXG4gKiBTZXRzIHRoZSBgdG9TdHJpbmdgIG1ldGhvZCBvZiBgd3JhcHBlcmAgdG8gbWltaWMgdGhlIHNvdXJjZSBvZiBgcmVmZXJlbmNlYFxuICogd2l0aCB3cmFwcGVyIGRldGFpbHMgaW4gYSBjb21tZW50IGF0IHRoZSB0b3Agb2YgdGhlIHNvdXJjZSBib2R5LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB3cmFwcGVyIFRoZSBmdW5jdGlvbiB0byBtb2RpZnkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSByZWZlcmVuY2UgVGhlIHJlZmVyZW5jZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBiaXRtYXNrIFRoZSBiaXRtYXNrIGZsYWdzLiBTZWUgYGNyZWF0ZVdyYXBgIGZvciBtb3JlIGRldGFpbHMuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgYHdyYXBwZXJgLlxuICovXG5mdW5jdGlvbiBzZXRXcmFwVG9TdHJpbmcod3JhcHBlciwgcmVmZXJlbmNlLCBiaXRtYXNrKSB7XG4gIHZhciBzb3VyY2UgPSAocmVmZXJlbmNlICsgJycpO1xuICByZXR1cm4gc2V0VG9TdHJpbmcod3JhcHBlciwgaW5zZXJ0V3JhcERldGFpbHMoc291cmNlLCB1cGRhdGVXcmFwRGV0YWlscyhnZXRXcmFwRGV0YWlscyhzb3VyY2UpLCBiaXRtYXNrKSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHNldFdyYXBUb1N0cmluZztcbiIsIi8qKiBVc2VkIHRvIGRldGVjdCBob3QgZnVuY3Rpb25zIGJ5IG51bWJlciBvZiBjYWxscyB3aXRoaW4gYSBzcGFuIG9mIG1pbGxpc2Vjb25kcy4gKi9cbnZhciBIT1RfQ09VTlQgPSA4MDAsXG4gICAgSE9UX1NQQU4gPSAxNjtcblxuLyogQnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZU5vdyA9IERhdGUubm93O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0J2xsIHNob3J0IG91dCBhbmQgaW52b2tlIGBpZGVudGl0eWAgaW5zdGVhZFxuICogb2YgYGZ1bmNgIHdoZW4gaXQncyBjYWxsZWQgYEhPVF9DT1VOVGAgb3IgbW9yZSB0aW1lcyBpbiBgSE9UX1NQQU5gXG4gKiBtaWxsaXNlY29uZHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIHJlc3RyaWN0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgc2hvcnRhYmxlIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBzaG9ydE91dChmdW5jKSB7XG4gIHZhciBjb3VudCA9IDAsXG4gICAgICBsYXN0Q2FsbGVkID0gMDtcblxuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHN0YW1wID0gbmF0aXZlTm93KCksXG4gICAgICAgIHJlbWFpbmluZyA9IEhPVF9TUEFOIC0gKHN0YW1wIC0gbGFzdENhbGxlZCk7XG5cbiAgICBsYXN0Q2FsbGVkID0gc3RhbXA7XG4gICAgaWYgKHJlbWFpbmluZyA+IDApIHtcbiAgICAgIGlmICgrK2NvdW50ID49IEhPVF9DT1VOVCkge1xuICAgICAgICByZXR1cm4gYXJndW1lbnRzWzBdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb3VudCA9IDA7XG4gICAgfVxuICAgIHJldHVybiBmdW5jLmFwcGx5KHVuZGVmaW5lZCwgYXJndW1lbnRzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaG9ydE91dDtcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKTtcblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBrZXktdmFsdWUgZW50cmllcyBmcm9tIHRoZSBzdGFjay5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgY2xlYXJcbiAqIEBtZW1iZXJPZiBTdGFja1xuICovXG5mdW5jdGlvbiBzdGFja0NsZWFyKCkge1xuICB0aGlzLl9fZGF0YV9fID0gbmV3IExpc3RDYWNoZTtcbiAgdGhpcy5zaXplID0gMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0NsZWFyO1xuIiwiLyoqXG4gKiBSZW1vdmVzIGBrZXlgIGFuZCBpdHMgdmFsdWUgZnJvbSB0aGUgc3RhY2suXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGRlbGV0ZVxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIHJlbW92ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgZW50cnkgd2FzIHJlbW92ZWQsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gc3RhY2tEZWxldGUoa2V5KSB7XG4gIHZhciBkYXRhID0gdGhpcy5fX2RhdGFfXyxcbiAgICAgIHJlc3VsdCA9IGRhdGFbJ2RlbGV0ZSddKGtleSk7XG5cbiAgdGhpcy5zaXplID0gZGF0YS5zaXplO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrRGVsZXRlO1xuIiwiLyoqXG4gKiBHZXRzIHRoZSBzdGFjayB2YWx1ZSBmb3IgYGtleWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIGdldFxuICogQG1lbWJlck9mIFN0YWNrXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHZhbHVlIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBlbnRyeSB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gc3RhY2tHZXQoa2V5KSB7XG4gIHJldHVybiB0aGlzLl9fZGF0YV9fLmdldChrZXkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrR2V0O1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYSBzdGFjayB2YWx1ZSBmb3IgYGtleWAgZXhpc3RzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAbmFtZSBoYXNcbiAqIEBtZW1iZXJPZiBTdGFja1xuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBlbnRyeSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBhbiBlbnRyeSBmb3IgYGtleWAgZXhpc3RzLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrSGFzKGtleSkge1xuICByZXR1cm4gdGhpcy5fX2RhdGFfXy5oYXMoa2V5KTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdGFja0hhcztcbiIsInZhciBMaXN0Q2FjaGUgPSByZXF1aXJlKCcuL19MaXN0Q2FjaGUnKSxcbiAgICBNYXAgPSByZXF1aXJlKCcuL19NYXAnKSxcbiAgICBNYXBDYWNoZSA9IHJlcXVpcmUoJy4vX01hcENhY2hlJyk7XG5cbi8qKiBVc2VkIGFzIHRoZSBzaXplIHRvIGVuYWJsZSBsYXJnZSBhcnJheSBvcHRpbWl6YXRpb25zLiAqL1xudmFyIExBUkdFX0FSUkFZX1NJWkUgPSAyMDA7XG5cbi8qKlxuICogU2V0cyB0aGUgc3RhY2sgYGtleWAgdG8gYHZhbHVlYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQG5hbWUgc2V0XG4gKiBAbWVtYmVyT2YgU3RhY2tcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgc3RhY2sgY2FjaGUgaW5zdGFuY2UuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrU2V0KGtleSwgdmFsdWUpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLl9fZGF0YV9fO1xuICBpZiAoZGF0YSBpbnN0YW5jZW9mIExpc3RDYWNoZSkge1xuICAgIHZhciBwYWlycyA9IGRhdGEuX19kYXRhX187XG4gICAgaWYgKCFNYXAgfHwgKHBhaXJzLmxlbmd0aCA8IExBUkdFX0FSUkFZX1NJWkUgLSAxKSkge1xuICAgICAgcGFpcnMucHVzaChba2V5LCB2YWx1ZV0pO1xuICAgICAgdGhpcy5zaXplID0gKytkYXRhLnNpemU7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG4gICAgZGF0YSA9IHRoaXMuX19kYXRhX18gPSBuZXcgTWFwQ2FjaGUocGFpcnMpO1xuICB9XG4gIGRhdGEuc2V0KGtleSwgdmFsdWUpO1xuICB0aGlzLnNpemUgPSBkYXRhLnNpemU7XG4gIHJldHVybiB0aGlzO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0YWNrU2V0O1xuIiwiLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYF8uaW5kZXhPZmAgd2hpY2ggcGVyZm9ybXMgc3RyaWN0IGVxdWFsaXR5XG4gKiBjb21wYXJpc29ucyBvZiB2YWx1ZXMsIGkuZS4gYD09PWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBpbnNwZWN0LlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gc3RyaWN0SW5kZXhPZihhcnJheSwgdmFsdWUsIGZyb21JbmRleCkge1xuICB2YXIgaW5kZXggPSBmcm9tSW5kZXggLSAxLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgaWYgKGFycmF5W2luZGV4XSA9PT0gdmFsdWUpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIC0xO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHN0cmljdEluZGV4T2Y7XG4iLCJ2YXIgbWVtb2l6ZUNhcHBlZCA9IHJlcXVpcmUoJy4vX21lbW9pemVDYXBwZWQnKTtcblxuLyoqIFVzZWQgdG8gbWF0Y2ggcHJvcGVydHkgbmFtZXMgd2l0aGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlUHJvcE5hbWUgPSAvW14uW1xcXV0rfFxcWyg/OigtP1xcZCsoPzpcXC5cXGQrKT8pfChbXCInXSkoKD86KD8hXFwyKVteXFxcXF18XFxcXC4pKj8pXFwyKVxcXXwoPz0oPzpcXC58XFxbXFxdKSg/OlxcLnxcXFtcXF18JCkpL2c7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIGJhY2tzbGFzaGVzIGluIHByb3BlcnR5IHBhdGhzLiAqL1xudmFyIHJlRXNjYXBlQ2hhciA9IC9cXFxcKFxcXFwpPy9nO1xuXG4vKipcbiAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIGEgcHJvcGVydHkgcGF0aCBhcnJheS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IHN0cmluZyBUaGUgc3RyaW5nIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIHByb3BlcnR5IHBhdGggYXJyYXkuXG4gKi9cbnZhciBzdHJpbmdUb1BhdGggPSBtZW1vaXplQ2FwcGVkKGZ1bmN0aW9uKHN0cmluZykge1xuICB2YXIgcmVzdWx0ID0gW107XG4gIGlmIChzdHJpbmcuY2hhckNvZGVBdCgwKSA9PT0gNDYgLyogLiAqLykge1xuICAgIHJlc3VsdC5wdXNoKCcnKTtcbiAgfVxuICBzdHJpbmcucmVwbGFjZShyZVByb3BOYW1lLCBmdW5jdGlvbihtYXRjaCwgbnVtYmVyLCBxdW90ZSwgc3ViU3RyaW5nKSB7XG4gICAgcmVzdWx0LnB1c2gocXVvdGUgPyBzdWJTdHJpbmcucmVwbGFjZShyZUVzY2FwZUNoYXIsICckMScpIDogKG51bWJlciB8fCBtYXRjaCkpO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHN0cmluZ1RvUGF0aDtcbiIsInZhciBpc1N5bWJvbCA9IHJlcXVpcmUoJy4vaXNTeW1ib2wnKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG52YXIgSU5GSU5JVFkgPSAxIC8gMDtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIGtleSBpZiBpdCdzIG5vdCBhIHN0cmluZyBvciBzeW1ib2wuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGluc3BlY3QuXG4gKiBAcmV0dXJucyB7c3RyaW5nfHN5bWJvbH0gUmV0dXJucyB0aGUga2V5LlxuICovXG5mdW5jdGlvbiB0b0tleSh2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IGlzU3ltYm9sKHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICB2YXIgcmVzdWx0ID0gKHZhbHVlICsgJycpO1xuICByZXR1cm4gKHJlc3VsdCA9PSAnMCcgJiYgKDEgLyB2YWx1ZSkgPT0gLUlORklOSVRZKSA/ICctMCcgOiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdG9LZXk7XG4iLCIvKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1Byb3RvID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byByZXNvbHZlIHRoZSBkZWNvbXBpbGVkIHNvdXJjZSBvZiBmdW5jdGlvbnMuICovXG52YXIgZnVuY1RvU3RyaW5nID0gZnVuY1Byb3RvLnRvU3RyaW5nO1xuXG4vKipcbiAqIENvbnZlcnRzIGBmdW5jYCB0byBpdHMgc291cmNlIGNvZGUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzb3VyY2UgY29kZS5cbiAqL1xuZnVuY3Rpb24gdG9Tb3VyY2UoZnVuYykge1xuICBpZiAoZnVuYyAhPSBudWxsKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBmdW5jVG9TdHJpbmcuY2FsbChmdW5jKTtcbiAgICB9IGNhdGNoIChlKSB7fVxuICAgIHRyeSB7XG4gICAgICByZXR1cm4gKGZ1bmMgKyAnJyk7XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfVxuICByZXR1cm4gJyc7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdG9Tb3VyY2U7XG4iLCJ2YXIgYXJyYXlFYWNoID0gcmVxdWlyZSgnLi9fYXJyYXlFYWNoJyksXG4gICAgYXJyYXlJbmNsdWRlcyA9IHJlcXVpcmUoJy4vX2FycmF5SW5jbHVkZXMnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgV1JBUF9CSU5EX0ZMQUcgPSAxLFxuICAgIFdSQVBfQklORF9LRVlfRkxBRyA9IDIsXG4gICAgV1JBUF9DVVJSWV9GTEFHID0gOCxcbiAgICBXUkFQX0NVUlJZX1JJR0hUX0ZMQUcgPSAxNixcbiAgICBXUkFQX1BBUlRJQUxfRkxBRyA9IDMyLFxuICAgIFdSQVBfUEFSVElBTF9SSUdIVF9GTEFHID0gNjQsXG4gICAgV1JBUF9BUllfRkxBRyA9IDEyOCxcbiAgICBXUkFQX1JFQVJHX0ZMQUcgPSAyNTYsXG4gICAgV1JBUF9GTElQX0ZMQUcgPSA1MTI7XG5cbi8qKiBVc2VkIHRvIGFzc29jaWF0ZSB3cmFwIG1ldGhvZHMgd2l0aCB0aGVpciBiaXQgZmxhZ3MuICovXG52YXIgd3JhcEZsYWdzID0gW1xuICBbJ2FyeScsIFdSQVBfQVJZX0ZMQUddLFxuICBbJ2JpbmQnLCBXUkFQX0JJTkRfRkxBR10sXG4gIFsnYmluZEtleScsIFdSQVBfQklORF9LRVlfRkxBR10sXG4gIFsnY3VycnknLCBXUkFQX0NVUlJZX0ZMQUddLFxuICBbJ2N1cnJ5UmlnaHQnLCBXUkFQX0NVUlJZX1JJR0hUX0ZMQUddLFxuICBbJ2ZsaXAnLCBXUkFQX0ZMSVBfRkxBR10sXG4gIFsncGFydGlhbCcsIFdSQVBfUEFSVElBTF9GTEFHXSxcbiAgWydwYXJ0aWFsUmlnaHQnLCBXUkFQX1BBUlRJQUxfUklHSFRfRkxBR10sXG4gIFsncmVhcmcnLCBXUkFQX1JFQVJHX0ZMQUddXG5dO1xuXG4vKipcbiAqIFVwZGF0ZXMgd3JhcHBlciBgZGV0YWlsc2AgYmFzZWQgb24gYGJpdG1hc2tgIGZsYWdzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcmV0dXJucyB7QXJyYXl9IGRldGFpbHMgVGhlIGRldGFpbHMgdG8gbW9kaWZ5LlxuICogQHBhcmFtIHtudW1iZXJ9IGJpdG1hc2sgVGhlIGJpdG1hc2sgZmxhZ3MuIFNlZSBgY3JlYXRlV3JhcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgZGV0YWlsc2AuXG4gKi9cbmZ1bmN0aW9uIHVwZGF0ZVdyYXBEZXRhaWxzKGRldGFpbHMsIGJpdG1hc2spIHtcbiAgYXJyYXlFYWNoKHdyYXBGbGFncywgZnVuY3Rpb24ocGFpcikge1xuICAgIHZhciB2YWx1ZSA9ICdfLicgKyBwYWlyWzBdO1xuICAgIGlmICgoYml0bWFzayAmIHBhaXJbMV0pICYmICFhcnJheUluY2x1ZGVzKGRldGFpbHMsIHZhbHVlKSkge1xuICAgICAgZGV0YWlscy5wdXNoKHZhbHVlKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gZGV0YWlscy5zb3J0KCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gdXBkYXRlV3JhcERldGFpbHM7XG4iLCJ2YXIgTGF6eVdyYXBwZXIgPSByZXF1aXJlKCcuL19MYXp5V3JhcHBlcicpLFxuICAgIExvZGFzaFdyYXBwZXIgPSByZXF1aXJlKCcuL19Mb2Rhc2hXcmFwcGVyJyksXG4gICAgY29weUFycmF5ID0gcmVxdWlyZSgnLi9fY29weUFycmF5Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGNsb25lIG9mIGB3cmFwcGVyYC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IHdyYXBwZXIgVGhlIHdyYXBwZXIgdG8gY2xvbmUuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjbG9uZWQgd3JhcHBlci5cbiAqL1xuZnVuY3Rpb24gd3JhcHBlckNsb25lKHdyYXBwZXIpIHtcbiAgaWYgKHdyYXBwZXIgaW5zdGFuY2VvZiBMYXp5V3JhcHBlcikge1xuICAgIHJldHVybiB3cmFwcGVyLmNsb25lKCk7XG4gIH1cbiAgdmFyIHJlc3VsdCA9IG5ldyBMb2Rhc2hXcmFwcGVyKHdyYXBwZXIuX193cmFwcGVkX18sIHdyYXBwZXIuX19jaGFpbl9fKTtcbiAgcmVzdWx0Ll9fYWN0aW9uc19fID0gY29weUFycmF5KHdyYXBwZXIuX19hY3Rpb25zX18pO1xuICByZXN1bHQuX19pbmRleF9fICA9IHdyYXBwZXIuX19pbmRleF9fO1xuICByZXN1bHQuX192YWx1ZXNfXyA9IHdyYXBwZXIuX192YWx1ZXNfXztcbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB3cmFwcGVyQ2xvbmU7XG4iLCJ2YXIgYXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19hc3NpZ25WYWx1ZScpLFxuICAgIGNvcHlPYmplY3QgPSByZXF1aXJlKCcuL19jb3B5T2JqZWN0JyksXG4gICAgY3JlYXRlQXNzaWduZXIgPSByZXF1aXJlKCcuL19jcmVhdGVBc3NpZ25lcicpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQXNzaWducyBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyBvZiBzb3VyY2Ugb2JqZWN0cyB0byB0aGVcbiAqIGRlc3RpbmF0aW9uIG9iamVjdC4gU291cmNlIG9iamVjdHMgYXJlIGFwcGxpZWQgZnJvbSBsZWZ0IHRvIHJpZ2h0LlxuICogU3Vic2VxdWVudCBzb3VyY2VzIG92ZXJ3cml0ZSBwcm9wZXJ0eSBhc3NpZ25tZW50cyBvZiBwcmV2aW91cyBzb3VyY2VzLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIG1ldGhvZCBtdXRhdGVzIGBvYmplY3RgIGFuZCBpcyBsb29zZWx5IGJhc2VkIG9uXG4gKiBbYE9iamVjdC5hc3NpZ25gXShodHRwczovL21kbi5pby9PYmplY3QvYXNzaWduKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMTAuMFxuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgZGVzdGluYXRpb24gb2JqZWN0LlxuICogQHBhcmFtIHsuLi5PYmplY3R9IFtzb3VyY2VzXSBUaGUgc291cmNlIG9iamVjdHMuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICogQHNlZSBfLmFzc2lnbkluXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqIH1cbiAqXG4gKiBmdW5jdGlvbiBCYXIoKSB7XG4gKiAgIHRoaXMuYyA9IDM7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5iID0gMjtcbiAqIEJhci5wcm90b3R5cGUuZCA9IDQ7XG4gKlxuICogXy5hc3NpZ24oeyAnYSc6IDAgfSwgbmV3IEZvbywgbmV3IEJhcik7XG4gKiAvLyA9PiB7ICdhJzogMSwgJ2MnOiAzIH1cbiAqL1xudmFyIGFzc2lnbiA9IGNyZWF0ZUFzc2lnbmVyKGZ1bmN0aW9uKG9iamVjdCwgc291cmNlKSB7XG4gIGlmIChpc1Byb3RvdHlwZShzb3VyY2UpIHx8IGlzQXJyYXlMaWtlKHNvdXJjZSkpIHtcbiAgICBjb3B5T2JqZWN0KHNvdXJjZSwga2V5cyhzb3VyY2UpLCBvYmplY3QpO1xuICAgIHJldHVybjtcbiAgfVxuICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICBhc3NpZ25WYWx1ZShvYmplY3QsIGtleSwgc291cmNlW2tleV0pO1xuICAgIH1cbiAgfVxufSk7XG5cbm1vZHVsZS5leHBvcnRzID0gYXNzaWduO1xuIiwidmFyIGJhc2VSZXN0ID0gcmVxdWlyZSgnLi9fYmFzZVJlc3QnKSxcbiAgICBjcmVhdGVXcmFwID0gcmVxdWlyZSgnLi9fY3JlYXRlV3JhcCcpLFxuICAgIGdldEhvbGRlciA9IHJlcXVpcmUoJy4vX2dldEhvbGRlcicpLFxuICAgIHJlcGxhY2VIb2xkZXJzID0gcmVxdWlyZSgnLi9fcmVwbGFjZUhvbGRlcnMnKTtcblxuLyoqIFVzZWQgdG8gY29tcG9zZSBiaXRtYXNrcyBmb3IgZnVuY3Rpb24gbWV0YWRhdGEuICovXG52YXIgV1JBUF9CSU5EX0ZMQUcgPSAxLFxuICAgIFdSQVBfUEFSVElBTF9GTEFHID0gMzI7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgYHRoaXNBcmdgXG4gKiBhbmQgYHBhcnRpYWxzYCBwcmVwZW5kZWQgdG8gdGhlIGFyZ3VtZW50cyBpdCByZWNlaXZlcy5cbiAqXG4gKiBUaGUgYF8uYmluZC5wbGFjZWhvbGRlcmAgdmFsdWUsIHdoaWNoIGRlZmF1bHRzIHRvIGBfYCBpbiBtb25vbGl0aGljIGJ1aWxkcyxcbiAqIG1heSBiZSB1c2VkIGFzIGEgcGxhY2Vob2xkZXIgZm9yIHBhcnRpYWxseSBhcHBsaWVkIGFyZ3VtZW50cy5cbiAqXG4gKiAqKk5vdGU6KiogVW5saWtlIG5hdGl2ZSBgRnVuY3Rpb24jYmluZGAsIHRoaXMgbWV0aG9kIGRvZXNuJ3Qgc2V0IHRoZSBcImxlbmd0aFwiXG4gKiBwcm9wZXJ0eSBvZiBib3VuZCBmdW5jdGlvbnMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IEZ1bmN0aW9uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBiaW5kLlxuICogQHBhcmFtIHsqfSB0aGlzQXJnIFRoZSBgdGhpc2AgYmluZGluZyBvZiBgZnVuY2AuXG4gKiBAcGFyYW0gey4uLip9IFtwYXJ0aWFsc10gVGhlIGFyZ3VtZW50cyB0byBiZSBwYXJ0aWFsbHkgYXBwbGllZC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJvdW5kIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBncmVldChncmVldGluZywgcHVuY3R1YXRpb24pIHtcbiAqICAgcmV0dXJuIGdyZWV0aW5nICsgJyAnICsgdGhpcy51c2VyICsgcHVuY3R1YXRpb247XG4gKiB9XG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiB2YXIgYm91bmQgPSBfLmJpbmQoZ3JlZXQsIG9iamVjdCwgJ2hpJyk7XG4gKiBib3VuZCgnIScpO1xuICogLy8gPT4gJ2hpIGZyZWQhJ1xuICpcbiAqIC8vIEJvdW5kIHdpdGggcGxhY2Vob2xkZXJzLlxuICogdmFyIGJvdW5kID0gXy5iaW5kKGdyZWV0LCBvYmplY3QsIF8sICchJyk7XG4gKiBib3VuZCgnaGknKTtcbiAqIC8vID0+ICdoaSBmcmVkISdcbiAqL1xudmFyIGJpbmQgPSBiYXNlUmVzdChmdW5jdGlvbihmdW5jLCB0aGlzQXJnLCBwYXJ0aWFscykge1xuICB2YXIgYml0bWFzayA9IFdSQVBfQklORF9GTEFHO1xuICBpZiAocGFydGlhbHMubGVuZ3RoKSB7XG4gICAgdmFyIGhvbGRlcnMgPSByZXBsYWNlSG9sZGVycyhwYXJ0aWFscywgZ2V0SG9sZGVyKGJpbmQpKTtcbiAgICBiaXRtYXNrIHw9IFdSQVBfUEFSVElBTF9GTEFHO1xuICB9XG4gIHJldHVybiBjcmVhdGVXcmFwKGZ1bmMsIGJpdG1hc2ssIHRoaXNBcmcsIHBhcnRpYWxzLCBob2xkZXJzKTtcbn0pO1xuXG4vLyBBc3NpZ24gZGVmYXVsdCBwbGFjZWhvbGRlcnMuXG5iaW5kLnBsYWNlaG9sZGVyID0ge307XG5cbm1vZHVsZS5leHBvcnRzID0gYmluZDtcbiIsIi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBgdmFsdWVgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMi40LjBcbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byByZXR1cm4gZnJvbSB0aGUgbmV3IGZ1bmN0aW9uLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgY29uc3RhbnQgZnVuY3Rpb24uXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3RzID0gXy50aW1lcygyLCBfLmNvbnN0YW50KHsgJ2EnOiAxIH0pKTtcbiAqXG4gKiBjb25zb2xlLmxvZyhvYmplY3RzKTtcbiAqIC8vID0+IFt7ICdhJzogMSB9LCB7ICdhJzogMSB9XVxuICpcbiAqIGNvbnNvbGUubG9nKG9iamVjdHNbMF0gPT09IG9iamVjdHNbMV0pO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBjb25zdGFudCh2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNvbnN0YW50O1xuIiwidmFyIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpLFxuICAgIG5vdyA9IHJlcXVpcmUoJy4vbm93JyksXG4gICAgdG9OdW1iZXIgPSByZXF1aXJlKCcuL3RvTnVtYmVyJyk7XG5cbi8qKiBFcnJvciBtZXNzYWdlIGNvbnN0YW50cy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qIEJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzIGZvciB0aG9zZSB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgb3RoZXIgYGxvZGFzaGAgbWV0aG9kcy4gKi9cbnZhciBuYXRpdmVNYXggPSBNYXRoLm1heCxcbiAgICBuYXRpdmVNaW4gPSBNYXRoLm1pbjtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVib3VuY2VkIGZ1bmN0aW9uIHRoYXQgZGVsYXlzIGludm9raW5nIGBmdW5jYCB1bnRpbCBhZnRlciBgd2FpdGBcbiAqIG1pbGxpc2Vjb25kcyBoYXZlIGVsYXBzZWQgc2luY2UgdGhlIGxhc3QgdGltZSB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uIHdhc1xuICogaW52b2tlZC4gVGhlIGRlYm91bmNlZCBmdW5jdGlvbiBjb21lcyB3aXRoIGEgYGNhbmNlbGAgbWV0aG9kIHRvIGNhbmNlbFxuICogZGVsYXllZCBgZnVuY2AgaW52b2NhdGlvbnMgYW5kIGEgYGZsdXNoYCBtZXRob2QgdG8gaW1tZWRpYXRlbHkgaW52b2tlIHRoZW0uXG4gKiBQcm92aWRlIGBvcHRpb25zYCB0byBpbmRpY2F0ZSB3aGV0aGVyIGBmdW5jYCBzaG91bGQgYmUgaW52b2tlZCBvbiB0aGVcbiAqIGxlYWRpbmcgYW5kL29yIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIGB3YWl0YCB0aW1lb3V0LiBUaGUgYGZ1bmNgIGlzIGludm9rZWRcbiAqIHdpdGggdGhlIGxhc3QgYXJndW1lbnRzIHByb3ZpZGVkIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24uIFN1YnNlcXVlbnRcbiAqIGNhbGxzIHRvIHRoZSBkZWJvdW5jZWQgZnVuY3Rpb24gcmV0dXJuIHRoZSByZXN1bHQgb2YgdGhlIGxhc3QgYGZ1bmNgXG4gKiBpbnZvY2F0aW9uLlxuICpcbiAqICoqTm90ZToqKiBJZiBgbGVhZGluZ2AgYW5kIGB0cmFpbGluZ2Agb3B0aW9ucyBhcmUgYHRydWVgLCBgZnVuY2AgaXNcbiAqIGludm9rZWQgb24gdGhlIHRyYWlsaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQgb25seSBpZiB0aGUgZGVib3VuY2VkIGZ1bmN0aW9uXG4gKiBpcyBpbnZva2VkIG1vcmUgdGhhbiBvbmNlIGR1cmluZyB0aGUgYHdhaXRgIHRpbWVvdXQuXG4gKlxuICogSWYgYHdhaXRgIGlzIGAwYCBhbmQgYGxlYWRpbmdgIGlzIGBmYWxzZWAsIGBmdW5jYCBpbnZvY2F0aW9uIGlzIGRlZmVycmVkXG4gKiB1bnRpbCB0byB0aGUgbmV4dCB0aWNrLCBzaW1pbGFyIHRvIGBzZXRUaW1lb3V0YCB3aXRoIGEgdGltZW91dCBvZiBgMGAuXG4gKlxuICogU2VlIFtEYXZpZCBDb3JiYWNobydzIGFydGljbGVdKGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vZGVib3VuY2luZy10aHJvdHRsaW5nLWV4cGxhaW5lZC1leGFtcGxlcy8pXG4gKiBmb3IgZGV0YWlscyBvdmVyIHRoZSBkaWZmZXJlbmNlcyBiZXR3ZWVuIGBfLmRlYm91bmNlYCBhbmQgYF8udGhyb3R0bGVgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBGdW5jdGlvblxuICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyBUaGUgZnVuY3Rpb24gdG8gZGVib3VuY2UuXG4gKiBAcGFyYW0ge251bWJlcn0gW3dhaXQ9MF0gVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgdG8gZGVsYXkuXG4gKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnM9e31dIFRoZSBvcHRpb25zIG9iamVjdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMubGVhZGluZz1mYWxzZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSBsZWFkaW5nIGVkZ2Ugb2YgdGhlIHRpbWVvdXQuXG4gKiBAcGFyYW0ge251bWJlcn0gW29wdGlvbnMubWF4V2FpdF1cbiAqICBUaGUgbWF4aW11bSB0aW1lIGBmdW5jYCBpcyBhbGxvd2VkIHRvIGJlIGRlbGF5ZWQgYmVmb3JlIGl0J3MgaW52b2tlZC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMudHJhaWxpbmc9dHJ1ZV1cbiAqICBTcGVjaWZ5IGludm9raW5nIG9uIHRoZSB0cmFpbGluZyBlZGdlIG9mIHRoZSB0aW1lb3V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgZGVib3VuY2VkIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBBdm9pZCBjb3N0bHkgY2FsY3VsYXRpb25zIHdoaWxlIHRoZSB3aW5kb3cgc2l6ZSBpcyBpbiBmbHV4LlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3Jlc2l6ZScsIF8uZGVib3VuY2UoY2FsY3VsYXRlTGF5b3V0LCAxNTApKTtcbiAqXG4gKiAvLyBJbnZva2UgYHNlbmRNYWlsYCB3aGVuIGNsaWNrZWQsIGRlYm91bmNpbmcgc3Vic2VxdWVudCBjYWxscy5cbiAqIGpRdWVyeShlbGVtZW50KS5vbignY2xpY2snLCBfLmRlYm91bmNlKHNlbmRNYWlsLCAzMDAsIHtcbiAqICAgJ2xlYWRpbmcnOiB0cnVlLFxuICogICAndHJhaWxpbmcnOiBmYWxzZVxuICogfSkpO1xuICpcbiAqIC8vIEVuc3VyZSBgYmF0Y2hMb2dgIGlzIGludm9rZWQgb25jZSBhZnRlciAxIHNlY29uZCBvZiBkZWJvdW5jZWQgY2FsbHMuXG4gKiB2YXIgZGVib3VuY2VkID0gXy5kZWJvdW5jZShiYXRjaExvZywgMjUwLCB7ICdtYXhXYWl0JzogMTAwMCB9KTtcbiAqIHZhciBzb3VyY2UgPSBuZXcgRXZlbnRTb3VyY2UoJy9zdHJlYW0nKTtcbiAqIGpRdWVyeShzb3VyY2UpLm9uKCdtZXNzYWdlJywgZGVib3VuY2VkKTtcbiAqXG4gKiAvLyBDYW5jZWwgdGhlIHRyYWlsaW5nIGRlYm91bmNlZCBpbnZvY2F0aW9uLlxuICogalF1ZXJ5KHdpbmRvdykub24oJ3BvcHN0YXRlJywgZGVib3VuY2VkLmNhbmNlbCk7XG4gKi9cbmZ1bmN0aW9uIGRlYm91bmNlKGZ1bmMsIHdhaXQsIG9wdGlvbnMpIHtcbiAgdmFyIGxhc3RBcmdzLFxuICAgICAgbGFzdFRoaXMsXG4gICAgICBtYXhXYWl0LFxuICAgICAgcmVzdWx0LFxuICAgICAgdGltZXJJZCxcbiAgICAgIGxhc3RDYWxsVGltZSxcbiAgICAgIGxhc3RJbnZva2VUaW1lID0gMCxcbiAgICAgIGxlYWRpbmcgPSBmYWxzZSxcbiAgICAgIG1heGluZyA9IGZhbHNlLFxuICAgICAgdHJhaWxpbmcgPSB0cnVlO1xuXG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgdGhyb3cgbmV3IFR5cGVFcnJvcihGVU5DX0VSUk9SX1RFWFQpO1xuICB9XG4gIHdhaXQgPSB0b051bWJlcih3YWl0KSB8fCAwO1xuICBpZiAoaXNPYmplY3Qob3B0aW9ucykpIHtcbiAgICBsZWFkaW5nID0gISFvcHRpb25zLmxlYWRpbmc7XG4gICAgbWF4aW5nID0gJ21heFdhaXQnIGluIG9wdGlvbnM7XG4gICAgbWF4V2FpdCA9IG1heGluZyA/IG5hdGl2ZU1heCh0b051bWJlcihvcHRpb25zLm1heFdhaXQpIHx8IDAsIHdhaXQpIDogbWF4V2FpdDtcbiAgICB0cmFpbGluZyA9ICd0cmFpbGluZycgaW4gb3B0aW9ucyA/ICEhb3B0aW9ucy50cmFpbGluZyA6IHRyYWlsaW5nO1xuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlRnVuYyh0aW1lKSB7XG4gICAgdmFyIGFyZ3MgPSBsYXN0QXJncyxcbiAgICAgICAgdGhpc0FyZyA9IGxhc3RUaGlzO1xuXG4gICAgbGFzdEFyZ3MgPSBsYXN0VGhpcyA9IHVuZGVmaW5lZDtcbiAgICBsYXN0SW52b2tlVGltZSA9IHRpbWU7XG4gICAgcmVzdWx0ID0gZnVuYy5hcHBseSh0aGlzQXJnLCBhcmdzKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgZnVuY3Rpb24gbGVhZGluZ0VkZ2UodGltZSkge1xuICAgIC8vIFJlc2V0IGFueSBgbWF4V2FpdGAgdGltZXIuXG4gICAgbGFzdEludm9rZVRpbWUgPSB0aW1lO1xuICAgIC8vIFN0YXJ0IHRoZSB0aW1lciBmb3IgdGhlIHRyYWlsaW5nIGVkZ2UuXG4gICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCB3YWl0KTtcbiAgICAvLyBJbnZva2UgdGhlIGxlYWRpbmcgZWRnZS5cbiAgICByZXR1cm4gbGVhZGluZyA/IGludm9rZUZ1bmModGltZSkgOiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiByZW1haW5pbmdXYWl0KHRpbWUpIHtcbiAgICB2YXIgdGltZVNpbmNlTGFzdENhbGwgPSB0aW1lIC0gbGFzdENhbGxUaW1lLFxuICAgICAgICB0aW1lU2luY2VMYXN0SW52b2tlID0gdGltZSAtIGxhc3RJbnZva2VUaW1lLFxuICAgICAgICB0aW1lV2FpdGluZyA9IHdhaXQgLSB0aW1lU2luY2VMYXN0Q2FsbDtcblxuICAgIHJldHVybiBtYXhpbmdcbiAgICAgID8gbmF0aXZlTWluKHRpbWVXYWl0aW5nLCBtYXhXYWl0IC0gdGltZVNpbmNlTGFzdEludm9rZSlcbiAgICAgIDogdGltZVdhaXRpbmc7XG4gIH1cblxuICBmdW5jdGlvbiBzaG91bGRJbnZva2UodGltZSkge1xuICAgIHZhciB0aW1lU2luY2VMYXN0Q2FsbCA9IHRpbWUgLSBsYXN0Q2FsbFRpbWUsXG4gICAgICAgIHRpbWVTaW5jZUxhc3RJbnZva2UgPSB0aW1lIC0gbGFzdEludm9rZVRpbWU7XG5cbiAgICAvLyBFaXRoZXIgdGhpcyBpcyB0aGUgZmlyc3QgY2FsbCwgYWN0aXZpdHkgaGFzIHN0b3BwZWQgYW5kIHdlJ3JlIGF0IHRoZVxuICAgIC8vIHRyYWlsaW5nIGVkZ2UsIHRoZSBzeXN0ZW0gdGltZSBoYXMgZ29uZSBiYWNrd2FyZHMgYW5kIHdlJ3JlIHRyZWF0aW5nXG4gICAgLy8gaXQgYXMgdGhlIHRyYWlsaW5nIGVkZ2UsIG9yIHdlJ3ZlIGhpdCB0aGUgYG1heFdhaXRgIGxpbWl0LlxuICAgIHJldHVybiAobGFzdENhbGxUaW1lID09PSB1bmRlZmluZWQgfHwgKHRpbWVTaW5jZUxhc3RDYWxsID49IHdhaXQpIHx8XG4gICAgICAodGltZVNpbmNlTGFzdENhbGwgPCAwKSB8fCAobWF4aW5nICYmIHRpbWVTaW5jZUxhc3RJbnZva2UgPj0gbWF4V2FpdCkpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGltZXJFeHBpcmVkKCkge1xuICAgIHZhciB0aW1lID0gbm93KCk7XG4gICAgaWYgKHNob3VsZEludm9rZSh0aW1lKSkge1xuICAgICAgcmV0dXJuIHRyYWlsaW5nRWRnZSh0aW1lKTtcbiAgICB9XG4gICAgLy8gUmVzdGFydCB0aGUgdGltZXIuXG4gICAgdGltZXJJZCA9IHNldFRpbWVvdXQodGltZXJFeHBpcmVkLCByZW1haW5pbmdXYWl0KHRpbWUpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYWlsaW5nRWRnZSh0aW1lKSB7XG4gICAgdGltZXJJZCA9IHVuZGVmaW5lZDtcblxuICAgIC8vIE9ubHkgaW52b2tlIGlmIHdlIGhhdmUgYGxhc3RBcmdzYCB3aGljaCBtZWFucyBgZnVuY2AgaGFzIGJlZW5cbiAgICAvLyBkZWJvdW5jZWQgYXQgbGVhc3Qgb25jZS5cbiAgICBpZiAodHJhaWxpbmcgJiYgbGFzdEFyZ3MpIHtcbiAgICAgIHJldHVybiBpbnZva2VGdW5jKHRpbWUpO1xuICAgIH1cbiAgICBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBmdW5jdGlvbiBjYW5jZWwoKSB7XG4gICAgaWYgKHRpbWVySWQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgIH1cbiAgICBsYXN0SW52b2tlVGltZSA9IDA7XG4gICAgbGFzdEFyZ3MgPSBsYXN0Q2FsbFRpbWUgPSBsYXN0VGhpcyA9IHRpbWVySWQgPSB1bmRlZmluZWQ7XG4gIH1cblxuICBmdW5jdGlvbiBmbHVzaCgpIHtcbiAgICByZXR1cm4gdGltZXJJZCA9PT0gdW5kZWZpbmVkID8gcmVzdWx0IDogdHJhaWxpbmdFZGdlKG5vdygpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGRlYm91bmNlZCgpIHtcbiAgICB2YXIgdGltZSA9IG5vdygpLFxuICAgICAgICBpc0ludm9raW5nID0gc2hvdWxkSW52b2tlKHRpbWUpO1xuXG4gICAgbGFzdEFyZ3MgPSBhcmd1bWVudHM7XG4gICAgbGFzdFRoaXMgPSB0aGlzO1xuICAgIGxhc3RDYWxsVGltZSA9IHRpbWU7XG5cbiAgICBpZiAoaXNJbnZva2luZykge1xuICAgICAgaWYgKHRpbWVySWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gbGVhZGluZ0VkZ2UobGFzdENhbGxUaW1lKTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXhpbmcpIHtcbiAgICAgICAgLy8gSGFuZGxlIGludm9jYXRpb25zIGluIGEgdGlnaHQgbG9vcC5cbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuICAgICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgICAgICByZXR1cm4gaW52b2tlRnVuYyhsYXN0Q2FsbFRpbWUpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodGltZXJJZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aW1lcklkID0gc2V0VGltZW91dCh0aW1lckV4cGlyZWQsIHdhaXQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG4gIGRlYm91bmNlZC5jYW5jZWwgPSBjYW5jZWw7XG4gIGRlYm91bmNlZC5mbHVzaCA9IGZsdXNoO1xuICByZXR1cm4gZGVib3VuY2VkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRlYm91bmNlO1xuIiwiLyoqXG4gKiBQZXJmb3JtcyBhXG4gKiBbYFNhbWVWYWx1ZVplcm9gXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi83LjAvI3NlYy1zYW1ldmFsdWV6ZXJvKVxuICogY29tcGFyaXNvbiBiZXR3ZWVuIHR3byB2YWx1ZXMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlIGVxdWl2YWxlbnQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbXBhcmUuXG4gKiBAcGFyYW0geyp9IG90aGVyIFRoZSBvdGhlciB2YWx1ZSB0byBjb21wYXJlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIHRoZSB2YWx1ZXMgYXJlIGVxdWl2YWxlbnQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ2EnOiAxIH07XG4gKiB2YXIgb3RoZXIgPSB7ICdhJzogMSB9O1xuICpcbiAqIF8uZXEob2JqZWN0LCBvYmplY3QpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEob2JqZWN0LCBvdGhlcik7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoJ2EnLCAnYScpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uZXEoJ2EnLCBPYmplY3QoJ2EnKSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uZXEoTmFOLCBOYU4pO1xuICogLy8gPT4gdHJ1ZVxuICovXG5mdW5jdGlvbiBlcSh2YWx1ZSwgb3RoZXIpIHtcbiAgcmV0dXJuIHZhbHVlID09PSBvdGhlciB8fCAodmFsdWUgIT09IHZhbHVlICYmIG90aGVyICE9PSBvdGhlcik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZXE7XG4iLCJ2YXIgYXJyYXlGaWx0ZXIgPSByZXF1aXJlKCcuL19hcnJheUZpbHRlcicpLFxuICAgIGJhc2VGaWx0ZXIgPSByZXF1aXJlKCcuL19iYXNlRmlsdGVyJyksXG4gICAgYmFzZUl0ZXJhdGVlID0gcmVxdWlyZSgnLi9fYmFzZUl0ZXJhdGVlJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpO1xuXG4vKipcbiAqIEl0ZXJhdGVzIG92ZXIgZWxlbWVudHMgb2YgYGNvbGxlY3Rpb25gLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgYWxsIGVsZW1lbnRzXG4gKiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRocmVlXG4gKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAqXG4gKiAqKk5vdGU6KiogVW5saWtlIGBfLnJlbW92ZWAsIHRoaXMgbWV0aG9kIHJldHVybnMgYSBuZXcgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGZpbHRlcmVkIGFycmF5LlxuICogQHNlZSBfLnJlamVjdFxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgdXNlcnMgPSBbXG4gKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICdhZ2UnOiA0MCwgJ2FjdGl2ZSc6IGZhbHNlIH1cbiAqIF07XG4gKlxuICogXy5maWx0ZXIodXNlcnMsIGZ1bmN0aW9uKG8pIHsgcmV0dXJuICFvLmFjdGl2ZTsgfSk7XG4gKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICpcbiAqIC8vIFRoZSBgXy5tYXRjaGVzYCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gKiBfLmZpbHRlcih1c2VycywgeyAnYWdlJzogMzYsICdhY3RpdmUnOiB0cnVlIH0pO1xuICogLy8gPT4gb2JqZWN0cyBmb3IgWydiYXJuZXknXVxuICpcbiAqIC8vIFRoZSBgXy5tYXRjaGVzUHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAqIF8uZmlsdGVyKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gKiAvLyA9PiBvYmplY3RzIGZvciBbJ2ZyZWQnXVxuICpcbiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maWx0ZXIodXNlcnMsICdhY3RpdmUnKTtcbiAqIC8vID0+IG9iamVjdHMgZm9yIFsnYmFybmV5J11cbiAqXG4gKiAvLyBDb21iaW5pbmcgc2V2ZXJhbCBwcmVkaWNhdGVzIHVzaW5nIGBfLm92ZXJFdmVyeWAgb3IgYF8ub3ZlclNvbWVgLlxuICogXy5maWx0ZXIodXNlcnMsIF8ub3ZlclNvbWUoW3sgJ2FnZSc6IDM2IH0sIFsnYWdlJywgNDBdXSkpO1xuICogLy8gPT4gb2JqZWN0cyBmb3IgWydmcmVkJywgJ2Jhcm5leSddXG4gKi9cbmZ1bmN0aW9uIGZpbHRlcihjb2xsZWN0aW9uLCBwcmVkaWNhdGUpIHtcbiAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlGaWx0ZXIgOiBiYXNlRmlsdGVyO1xuICByZXR1cm4gZnVuYyhjb2xsZWN0aW9uLCBiYXNlSXRlcmF0ZWUocHJlZGljYXRlLCAzKSk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZmlsdGVyO1xuIiwidmFyIGNyZWF0ZUZpbmQgPSByZXF1aXJlKCcuL19jcmVhdGVGaW5kJyksXG4gICAgZmluZEluZGV4ID0gcmVxdWlyZSgnLi9maW5kSW5kZXgnKTtcblxuLyoqXG4gKiBJdGVyYXRlcyBvdmVyIGVsZW1lbnRzIG9mIGBjb2xsZWN0aW9uYCwgcmV0dXJuaW5nIHRoZSBmaXJzdCBlbGVtZW50XG4gKiBgcHJlZGljYXRlYCByZXR1cm5zIHRydXRoeSBmb3IuIFRoZSBwcmVkaWNhdGUgaXMgaW52b2tlZCB3aXRoIHRocmVlXG4gKiBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaW5zcGVjdC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZnJvbUluZGV4PTBdIFRoZSBpbmRleCB0byBzZWFyY2ggZnJvbS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBtYXRjaGVkIGVsZW1lbnQsIGVsc2UgYHVuZGVmaW5lZGAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknLCAgJ2FnZSc6IDM2LCAnYWN0aXZlJzogdHJ1ZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWdlJzogNDAsICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ3BlYmJsZXMnLCAnYWdlJzogMSwgICdhY3RpdmUnOiB0cnVlIH1cbiAqIF07XG4gKlxuICogXy5maW5kKHVzZXJzLCBmdW5jdGlvbihvKSB7IHJldHVybiBvLmFnZSA8IDQwOyB9KTtcbiAqIC8vID0+IG9iamVjdCBmb3IgJ2Jhcm5leSdcbiAqXG4gKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kKHVzZXJzLCB7ICdhZ2UnOiAxLCAnYWN0aXZlJzogdHJ1ZSB9KTtcbiAqIC8vID0+IG9iamVjdCBmb3IgJ3BlYmJsZXMnXG4gKlxuICogLy8gVGhlIGBfLm1hdGNoZXNQcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kKHVzZXJzLCBbJ2FjdGl2ZScsIGZhbHNlXSk7XG4gKiAvLyA9PiBvYmplY3QgZm9yICdmcmVkJ1xuICpcbiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kKHVzZXJzLCAnYWN0aXZlJyk7XG4gKiAvLyA9PiBvYmplY3QgZm9yICdiYXJuZXknXG4gKi9cbnZhciBmaW5kID0gY3JlYXRlRmluZChmaW5kSW5kZXgpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmQ7XG4iLCJ2YXIgYmFzZUZpbmRJbmRleCA9IHJlcXVpcmUoJy4vX2Jhc2VGaW5kSW5kZXgnKSxcbiAgICBiYXNlSXRlcmF0ZWUgPSByZXF1aXJlKCcuL19iYXNlSXRlcmF0ZWUnKSxcbiAgICB0b0ludGVnZXIgPSByZXF1aXJlKCcuL3RvSW50ZWdlcicpO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5maW5kYCBleGNlcHQgdGhhdCBpdCByZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZmlyc3RcbiAqIGVsZW1lbnQgYHByZWRpY2F0ZWAgcmV0dXJucyB0cnV0aHkgZm9yIGluc3RlYWQgb2YgdGhlIGVsZW1lbnQgaXRzZWxmLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMS4xLjBcbiAqIEBjYXRlZ29yeSBBcnJheVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW2Zyb21JbmRleD0wXSBUaGUgaW5kZXggdG8gc2VhcmNoIGZyb20uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgZm91bmQgZWxlbWVudCwgZWxzZSBgLTFgLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgdXNlcnMgPSBbXG4gKiAgIHsgJ3VzZXInOiAnYmFybmV5JywgICdhY3RpdmUnOiBmYWxzZSB9LFxuICogICB7ICd1c2VyJzogJ2ZyZWQnLCAgICAnYWN0aXZlJzogZmFsc2UgfSxcbiAqICAgeyAndXNlcic6ICdwZWJibGVzJywgJ2FjdGl2ZSc6IHRydWUgfVxuICogXTtcbiAqXG4gKiBfLmZpbmRJbmRleCh1c2VycywgZnVuY3Rpb24obykgeyByZXR1cm4gby51c2VyID09ICdiYXJuZXknOyB9KTtcbiAqIC8vID0+IDBcbiAqXG4gKiAvLyBUaGUgYF8ubWF0Y2hlc2AgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kSW5kZXgodXNlcnMsIHsgJ3VzZXInOiAnZnJlZCcsICdhY3RpdmUnOiBmYWxzZSB9KTtcbiAqIC8vID0+IDFcbiAqXG4gKiAvLyBUaGUgYF8ubWF0Y2hlc1Byb3BlcnR5YCBpdGVyYXRlZSBzaG9ydGhhbmQuXG4gKiBfLmZpbmRJbmRleCh1c2VycywgWydhY3RpdmUnLCBmYWxzZV0pO1xuICogLy8gPT4gMFxuICpcbiAqIC8vIFRoZSBgXy5wcm9wZXJ0eWAgaXRlcmF0ZWUgc2hvcnRoYW5kLlxuICogXy5maW5kSW5kZXgodXNlcnMsICdhY3RpdmUnKTtcbiAqIC8vID0+IDJcbiAqL1xuZnVuY3Rpb24gZmluZEluZGV4KGFycmF5LCBwcmVkaWNhdGUsIGZyb21JbmRleCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkgPT0gbnVsbCA/IDAgOiBhcnJheS5sZW5ndGg7XG4gIGlmICghbGVuZ3RoKSB7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIHZhciBpbmRleCA9IGZyb21JbmRleCA9PSBudWxsID8gMCA6IHRvSW50ZWdlcihmcm9tSW5kZXgpO1xuICBpZiAoaW5kZXggPCAwKSB7XG4gICAgaW5kZXggPSBuYXRpdmVNYXgobGVuZ3RoICsgaW5kZXgsIDApO1xuICB9XG4gIHJldHVybiBiYXNlRmluZEluZGV4KGFycmF5LCBiYXNlSXRlcmF0ZWUocHJlZGljYXRlLCAzKSwgaW5kZXgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZpbmRJbmRleDtcbiIsInZhciBiYXNlRmxhdHRlbiA9IHJlcXVpcmUoJy4vX2Jhc2VGbGF0dGVuJyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIElORklOSVRZID0gMSAvIDA7XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgZmxhdHRlbnMgYGFycmF5YC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDMuMC4wXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBmbGF0dGVuLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmZsYXR0ZW5EZWVwKFsxLCBbMiwgWzMsIFs0XV0sIDVdXSk7XG4gKiAvLyA9PiBbMSwgMiwgMywgNCwgNV1cbiAqL1xuZnVuY3Rpb24gZmxhdHRlbkRlZXAoYXJyYXkpIHtcbiAgdmFyIGxlbmd0aCA9IGFycmF5ID09IG51bGwgPyAwIDogYXJyYXkubGVuZ3RoO1xuICByZXR1cm4gbGVuZ3RoID8gYmFzZUZsYXR0ZW4oYXJyYXksIElORklOSVRZKSA6IFtdO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZsYXR0ZW5EZWVwO1xuIiwidmFyIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vX2FycmF5RWFjaCcpLFxuICAgIGJhc2VFYWNoID0gcmVxdWlyZSgnLi9fYmFzZUVhY2gnKSxcbiAgICBjYXN0RnVuY3Rpb24gPSByZXF1aXJlKCcuL19jYXN0RnVuY3Rpb24nKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5Jyk7XG5cbi8qKlxuICogSXRlcmF0ZXMgb3ZlciBlbGVtZW50cyBvZiBgY29sbGVjdGlvbmAgYW5kIGludm9rZXMgYGl0ZXJhdGVlYCBmb3IgZWFjaCBlbGVtZW50LlxuICogVGhlIGl0ZXJhdGVlIGlzIGludm9rZWQgd2l0aCB0aHJlZSBhcmd1bWVudHM6ICh2YWx1ZSwgaW5kZXh8a2V5LCBjb2xsZWN0aW9uKS5cbiAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAqXG4gKiAqKk5vdGU6KiogQXMgd2l0aCBvdGhlciBcIkNvbGxlY3Rpb25zXCIgbWV0aG9kcywgb2JqZWN0cyB3aXRoIGEgXCJsZW5ndGhcIlxuICogcHJvcGVydHkgYXJlIGl0ZXJhdGVkIGxpa2UgYXJyYXlzLiBUbyBhdm9pZCB0aGlzIGJlaGF2aW9yIHVzZSBgXy5mb3JJbmBcbiAqIG9yIGBfLmZvck93bmAgZm9yIG9iamVjdCBpdGVyYXRpb24uXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGFsaWFzIGVhY2hcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdH0gY29sbGVjdGlvbiBUaGUgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWU9Xy5pZGVudGl0eV0gVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEByZXR1cm5zIHtBcnJheXxPYmplY3R9IFJldHVybnMgYGNvbGxlY3Rpb25gLlxuICogQHNlZSBfLmZvckVhY2hSaWdodFxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmZvckVhY2goWzEsIDJdLCBmdW5jdGlvbih2YWx1ZSkge1xuICogICBjb25zb2xlLmxvZyh2YWx1ZSk7XG4gKiB9KTtcbiAqIC8vID0+IExvZ3MgYDFgIHRoZW4gYDJgLlxuICpcbiAqIF8uZm9yRWFjaCh7ICdhJzogMSwgJ2InOiAyIH0sIGZ1bmN0aW9uKHZhbHVlLCBrZXkpIHtcbiAqICAgY29uc29sZS5sb2coa2V5KTtcbiAqIH0pO1xuICogLy8gPT4gTG9ncyAnYScgdGhlbiAnYicgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZCkuXG4gKi9cbmZ1bmN0aW9uIGZvckVhY2goY29sbGVjdGlvbiwgaXRlcmF0ZWUpIHtcbiAgdmFyIGZ1bmMgPSBpc0FycmF5KGNvbGxlY3Rpb24pID8gYXJyYXlFYWNoIDogYmFzZUVhY2g7XG4gIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGNhc3RGdW5jdGlvbihpdGVyYXRlZSkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGZvckVhY2g7XG4iLCJ2YXIgYmFzZUdldCA9IHJlcXVpcmUoJy4vX2Jhc2VHZXQnKTtcblxuLyoqXG4gKiBHZXRzIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYG9iamVjdGAuIElmIHRoZSByZXNvbHZlZCB2YWx1ZSBpc1xuICogYHVuZGVmaW5lZGAsIHRoZSBgZGVmYXVsdFZhbHVlYCBpcyByZXR1cm5lZCBpbiBpdHMgcGxhY2UuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAzLjcuMFxuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtBcnJheXxzdHJpbmd9IHBhdGggVGhlIHBhdGggb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEBwYXJhbSB7Kn0gW2RlZmF1bHRWYWx1ZV0gVGhlIHZhbHVlIHJldHVybmVkIGZvciBgdW5kZWZpbmVkYCByZXNvbHZlZCB2YWx1ZXMuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgcmVzb2x2ZWQgdmFsdWUuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICdhJzogW3sgJ2InOiB7ICdjJzogMyB9IH1dIH07XG4gKlxuICogXy5nZXQob2JqZWN0LCAnYVswXS5iLmMnKTtcbiAqIC8vID0+IDNcbiAqXG4gKiBfLmdldChvYmplY3QsIFsnYScsICcwJywgJ2InLCAnYyddKTtcbiAqIC8vID0+IDNcbiAqXG4gKiBfLmdldChvYmplY3QsICdhLmIuYycsICdkZWZhdWx0Jyk7XG4gKiAvLyA9PiAnZGVmYXVsdCdcbiAqL1xuZnVuY3Rpb24gZ2V0KG9iamVjdCwgcGF0aCwgZGVmYXVsdFZhbHVlKSB7XG4gIHZhciByZXN1bHQgPSBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IGJhc2VHZXQob2JqZWN0LCBwYXRoKTtcbiAgcmV0dXJuIHJlc3VsdCA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdFZhbHVlIDogcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldDtcbiIsInZhciBiYXNlSGFzSW4gPSByZXF1aXJlKCcuL19iYXNlSGFzSW4nKSxcbiAgICBoYXNQYXRoID0gcmVxdWlyZSgnLi9faGFzUGF0aCcpO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgcGF0aGAgaXMgYSBkaXJlY3Qgb3IgaW5oZXJpdGVkIHByb3BlcnR5IG9mIGBvYmplY3RgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGBwYXRoYCBleGlzdHMsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IF8uY3JlYXRlKHsgJ2EnOiBfLmNyZWF0ZSh7ICdiJzogMiB9KSB9KTtcbiAqXG4gKiBfLmhhc0luKG9iamVjdCwgJ2EnKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmhhc0luKG9iamVjdCwgJ2EuYicpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaGFzSW4ob2JqZWN0LCBbJ2EnLCAnYiddKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmhhc0luKG9iamVjdCwgJ2InKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGhhc0luKG9iamVjdCwgcGF0aCkge1xuICByZXR1cm4gb2JqZWN0ICE9IG51bGwgJiYgaGFzUGF0aChvYmplY3QsIHBhdGgsIGJhc2VIYXNJbik7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaGFzSW47XG4iLCIvKipcbiAqIFRoaXMgbWV0aG9kIHJldHVybnMgdGhlIGZpcnN0IGFyZ3VtZW50IGl0IHJlY2VpdmVzLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBzaW5jZSAwLjEuMFxuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcGFyYW0geyp9IHZhbHVlIEFueSB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIGB2YWx1ZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBvYmplY3QgPSB7ICdhJzogMSB9O1xuICpcbiAqIGNvbnNvbGUubG9nKF8uaWRlbnRpdHkob2JqZWN0KSA9PT0gb2JqZWN0KTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaWRlbnRpdHkodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlkZW50aXR5O1xuIiwidmFyIGJhc2VJc0FyZ3VtZW50cyA9IHJlcXVpcmUoJy4vX2Jhc2VJc0FyZ3VtZW50cycpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIHByb3BlcnR5SXNFbnVtZXJhYmxlID0gb2JqZWN0UHJvdG8ucHJvcGVydHlJc0VudW1lcmFibGU7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGFuIGBhcmd1bWVudHNgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsXG4gKiAgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0FyZ3VtZW50cyA9IGJhc2VJc0FyZ3VtZW50cyhmdW5jdGlvbigpIHsgcmV0dXJuIGFyZ3VtZW50czsgfSgpKSA/IGJhc2VJc0FyZ3VtZW50cyA6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGhhc093blByb3BlcnR5LmNhbGwodmFsdWUsICdjYWxsZWUnKSAmJlxuICAgICFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJyk7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJndW1lbnRzO1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGFuIGBBcnJheWAgb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheShkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KCdhYmMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5KF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG52YXIgaXNBcnJheSA9IEFycmF5LmlzQXJyYXk7XG5cbm1vZHVsZS5leHBvcnRzID0gaXNBcnJheTtcbiIsInZhciBpc0Z1bmN0aW9uID0gcmVxdWlyZSgnLi9pc0Z1bmN0aW9uJyksXG4gICAgaXNMZW5ndGggPSByZXF1aXJlKCcuL2lzTGVuZ3RoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFycmF5LWxpa2UgaWYgaXQnc1xuICogbm90IGEgZnVuY3Rpb24gYW5kIGhhcyBhIGB2YWx1ZS5sZW5ndGhgIHRoYXQncyBhbiBpbnRlZ2VyIGdyZWF0ZXIgdGhhbiBvclxuICogZXF1YWwgdG8gYDBgIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYE51bWJlci5NQVhfU0FGRV9JTlRFR0VSYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoJ2FiYycpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgIWlzRnVuY3Rpb24odmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJyYXlMaWtlO1xuIiwidmFyIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpLFxuICAgIGlzT2JqZWN0TGlrZSA9IHJlcXVpcmUoJy4vaXNPYmplY3RMaWtlJyk7XG5cbi8qKlxuICogVGhpcyBtZXRob2QgaXMgbGlrZSBgXy5pc0FycmF5TGlrZWAgZXhjZXB0IHRoYXQgaXQgYWxzbyBjaGVja3MgaWYgYHZhbHVlYFxuICogaXMgYW4gb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIGFycmF5LWxpa2Ugb2JqZWN0LFxuICogIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5TGlrZU9iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2VPYmplY3QoZG9jdW1lbnQuYm9keS5jaGlsZHJlbik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZU9iamVjdCgnYWJjJyk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNBcnJheUxpa2VPYmplY3QoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlT2JqZWN0KHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FycmF5TGlrZU9iamVjdDtcbiIsInZhciByb290ID0gcmVxdWlyZSgnLi9fcm9vdCcpLFxuICAgIHN0dWJGYWxzZSA9IHJlcXVpcmUoJy4vc3R1YkZhbHNlJyk7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZXhwb3J0c2AuICovXG52YXIgZnJlZUV4cG9ydHMgPSB0eXBlb2YgZXhwb3J0cyA9PSAnb2JqZWN0JyAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbnZhciBmcmVlTW9kdWxlID0gZnJlZUV4cG9ydHMgJiYgdHlwZW9mIG1vZHVsZSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSAmJiBtb2R1bGU7XG5cbi8qKiBEZXRlY3QgdGhlIHBvcHVsYXIgQ29tbW9uSlMgZXh0ZW5zaW9uIGBtb2R1bGUuZXhwb3J0c2AuICovXG52YXIgbW9kdWxlRXhwb3J0cyA9IGZyZWVNb2R1bGUgJiYgZnJlZU1vZHVsZS5leHBvcnRzID09PSBmcmVlRXhwb3J0cztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgQnVmZmVyID0gbW9kdWxlRXhwb3J0cyA/IHJvb3QuQnVmZmVyIDogdW5kZWZpbmVkO1xuXG4vKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlSXNCdWZmZXIgPSBCdWZmZXIgPyBCdWZmZXIuaXNCdWZmZXIgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBidWZmZXIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjMuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBidWZmZXIsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0J1ZmZlcihuZXcgQnVmZmVyKDIpKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQnVmZmVyKG5ldyBVaW50OEFycmF5KDIpKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbnZhciBpc0J1ZmZlciA9IG5hdGl2ZUlzQnVmZmVyIHx8IHN0dWJGYWxzZTtcblxubW9kdWxlLmV4cG9ydHMgPSBpc0J1ZmZlcjtcbiIsInZhciBiYXNlS2V5cyA9IHJlcXVpcmUoJy4vX2Jhc2VLZXlzJyksXG4gICAgZ2V0VGFnID0gcmVxdWlyZSgnLi9fZ2V0VGFnJyksXG4gICAgaXNBcmd1bWVudHMgPSByZXF1aXJlKCcuL2lzQXJndW1lbnRzJyksXG4gICAgaXNBcnJheSA9IHJlcXVpcmUoJy4vaXNBcnJheScpLFxuICAgIGlzQXJyYXlMaWtlID0gcmVxdWlyZSgnLi9pc0FycmF5TGlrZScpLFxuICAgIGlzQnVmZmVyID0gcmVxdWlyZSgnLi9pc0J1ZmZlcicpLFxuICAgIGlzUHJvdG90eXBlID0gcmVxdWlyZSgnLi9faXNQcm90b3R5cGUnKSxcbiAgICBpc1R5cGVkQXJyYXkgPSByZXF1aXJlKCcuL2lzVHlwZWRBcnJheScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgbWFwVGFnID0gJ1tvYmplY3QgTWFwXScsXG4gICAgc2V0VGFnID0gJ1tvYmplY3QgU2V0XSc7XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYW4gZW1wdHkgb2JqZWN0LCBjb2xsZWN0aW9uLCBtYXAsIG9yIHNldC5cbiAqXG4gKiBPYmplY3RzIGFyZSBjb25zaWRlcmVkIGVtcHR5IGlmIHRoZXkgaGF2ZSBubyBvd24gZW51bWVyYWJsZSBzdHJpbmcga2V5ZWRcbiAqIHByb3BlcnRpZXMuXG4gKlxuICogQXJyYXktbGlrZSB2YWx1ZXMgc3VjaCBhcyBgYXJndW1lbnRzYCBvYmplY3RzLCBhcnJheXMsIGJ1ZmZlcnMsIHN0cmluZ3MsIG9yXG4gKiBqUXVlcnktbGlrZSBjb2xsZWN0aW9ucyBhcmUgY29uc2lkZXJlZCBlbXB0eSBpZiB0aGV5IGhhdmUgYSBgbGVuZ3RoYCBvZiBgMGAuXG4gKiBTaW1pbGFybHksIG1hcHMgYW5kIHNldHMgYXJlIGNvbnNpZGVyZWQgZW1wdHkgaWYgdGhleSBoYXZlIGEgYHNpemVgIG9mIGAwYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBlbXB0eSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzRW1wdHkobnVsbCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0VtcHR5KHRydWUpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNFbXB0eSgxKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRW1wdHkoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0VtcHR5KHsgJ2EnOiAxIH0pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNFbXB0eSh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChpc0FycmF5TGlrZSh2YWx1ZSkgJiZcbiAgICAgIChpc0FycmF5KHZhbHVlKSB8fCB0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycgfHwgdHlwZW9mIHZhbHVlLnNwbGljZSA9PSAnZnVuY3Rpb24nIHx8XG4gICAgICAgIGlzQnVmZmVyKHZhbHVlKSB8fCBpc1R5cGVkQXJyYXkodmFsdWUpIHx8IGlzQXJndW1lbnRzKHZhbHVlKSkpIHtcbiAgICByZXR1cm4gIXZhbHVlLmxlbmd0aDtcbiAgfVxuICB2YXIgdGFnID0gZ2V0VGFnKHZhbHVlKTtcbiAgaWYgKHRhZyA9PSBtYXBUYWcgfHwgdGFnID09IHNldFRhZykge1xuICAgIHJldHVybiAhdmFsdWUuc2l6ZTtcbiAgfVxuICBpZiAoaXNQcm90b3R5cGUodmFsdWUpKSB7XG4gICAgcmV0dXJuICFiYXNlS2V5cyh2YWx1ZSkubGVuZ3RoO1xuICB9XG4gIGZvciAodmFyIGtleSBpbiB2YWx1ZSkge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCBrZXkpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzRW1wdHk7XG4iLCJ2YXIgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICBpc09iamVjdCA9IHJlcXVpcmUoJy4vaXNPYmplY3QnKTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFzeW5jVGFnID0gJ1tvYmplY3QgQXN5bmNGdW5jdGlvbl0nLFxuICAgIGZ1bmNUYWcgPSAnW29iamVjdCBGdW5jdGlvbl0nLFxuICAgIGdlblRhZyA9ICdbb2JqZWN0IEdlbmVyYXRvckZ1bmN0aW9uXScsXG4gICAgcHJveHlUYWcgPSAnW29iamVjdCBQcm94eV0nO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNGdW5jdGlvbihfKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICBpZiAoIWlzT2JqZWN0KHZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3JcbiAgLy8gaW4gU2FmYXJpIDkgd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXlzIGFuZCBvdGhlciBjb25zdHJ1Y3RvcnMuXG4gIHZhciB0YWcgPSBiYXNlR2V0VGFnKHZhbHVlKTtcbiAgcmV0dXJuIHRhZyA9PSBmdW5jVGFnIHx8IHRhZyA9PSBnZW5UYWcgfHwgdGFnID09IGFzeW5jVGFnIHx8IHRhZyA9PSBwcm94eVRhZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0Z1bmN0aW9uO1xuIiwiLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBhcnJheS1saWtlIGxlbmd0aC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBtZXRob2QgaXMgbG9vc2VseSBiYXNlZCBvblxuICogW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRvbGVuZ3RoKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzTGVuZ3RoKDMpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNMZW5ndGgoTnVtYmVyLk1JTl9WQUxVRSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNMZW5ndGgoSW5maW5pdHkpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzTGVuZ3RoKCczJyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmXG4gICAgdmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8PSBNQVhfU0FGRV9JTlRFR0VSO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzTGVuZ3RoO1xuIiwiLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGVcbiAqIFtsYW5ndWFnZSB0eXBlXShodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtZWNtYXNjcmlwdC1sYW5ndWFnZS10eXBlcylcbiAqIG9mIGBPYmplY3RgLiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBvYmplY3QsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdCh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoXy5ub29wKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgdmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmICh0eXBlID09ICdvYmplY3QnIHx8IHR5cGUgPT0gJ2Z1bmN0aW9uJyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNPYmplY3Q7XG4iLCIvKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLiBBIHZhbHVlIGlzIG9iamVjdC1saWtlIGlmIGl0J3Mgbm90IGBudWxsYFxuICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdExpa2U7XG4iLCJ2YXIgYmFzZUdldFRhZyA9IHJlcXVpcmUoJy4vX2Jhc2VHZXRUYWcnKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTeW1ib2xgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBzeW1ib2wsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fFxuICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIGJhc2VHZXRUYWcodmFsdWUpID09IHN5bWJvbFRhZyk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gaXNTeW1ib2w7XG4iLCJ2YXIgYmFzZUlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4vX2Jhc2VJc1R5cGVkQXJyYXknKSxcbiAgICBiYXNlVW5hcnkgPSByZXF1aXJlKCcuL19iYXNlVW5hcnknKSxcbiAgICBub2RlVXRpbCA9IHJlcXVpcmUoJy4vX25vZGVVdGlsJyk7XG5cbi8qIE5vZGUuanMgaGVscGVyIHJlZmVyZW5jZXMuICovXG52YXIgbm9kZUlzVHlwZWRBcnJheSA9IG5vZGVVdGlsICYmIG5vZGVVdGlsLmlzVHlwZWRBcnJheTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgdHlwZWQgYXJyYXkuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAzLjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB0eXBlZCBhcnJheSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzVHlwZWRBcnJheShuZXcgVWludDhBcnJheSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1R5cGVkQXJyYXkoW10pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzVHlwZWRBcnJheSA9IG5vZGVJc1R5cGVkQXJyYXkgPyBiYXNlVW5hcnkobm9kZUlzVHlwZWRBcnJheSkgOiBiYXNlSXNUeXBlZEFycmF5O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVHlwZWRBcnJheTtcbiIsInZhciBiYXNlQXNzaWduVmFsdWUgPSByZXF1aXJlKCcuL19iYXNlQXNzaWduVmFsdWUnKSxcbiAgICBjcmVhdGVBZ2dyZWdhdG9yID0gcmVxdWlyZSgnLi9fY3JlYXRlQWdncmVnYXRvcicpO1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gb2JqZWN0IGNvbXBvc2VkIG9mIGtleXMgZ2VuZXJhdGVkIGZyb20gdGhlIHJlc3VsdHMgb2YgcnVubmluZ1xuICogZWFjaCBlbGVtZW50IG9mIGBjb2xsZWN0aW9uYCB0aHJ1IGBpdGVyYXRlZWAuIFRoZSBjb3JyZXNwb25kaW5nIHZhbHVlIG9mXG4gKiBlYWNoIGtleSBpcyB0aGUgbGFzdCBlbGVtZW50IHJlc3BvbnNpYmxlIGZvciBnZW5lcmF0aW5nIHRoZSBrZXkuIFRoZVxuICogaXRlcmF0ZWUgaXMgaW52b2tlZCB3aXRoIG9uZSBhcmd1bWVudDogKHZhbHVlKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxPYmplY3R9IGNvbGxlY3Rpb24gVGhlIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBpdGVyYXRlZSB0byB0cmFuc2Zvcm0ga2V5cy5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIGNvbXBvc2VkIGFnZ3JlZ2F0ZSBvYmplY3QuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBhcnJheSA9IFtcbiAqICAgeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sXG4gKiAgIHsgJ2Rpcic6ICdyaWdodCcsICdjb2RlJzogMTAwIH1cbiAqIF07XG4gKlxuICogXy5rZXlCeShhcnJheSwgZnVuY3Rpb24obykge1xuICogICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShvLmNvZGUpO1xuICogfSk7XG4gKiAvLyA9PiB7ICdhJzogeyAnZGlyJzogJ2xlZnQnLCAnY29kZSc6IDk3IH0sICdkJzogeyAnZGlyJzogJ3JpZ2h0JywgJ2NvZGUnOiAxMDAgfSB9XG4gKlxuICogXy5rZXlCeShhcnJheSwgJ2RpcicpO1xuICogLy8gPT4geyAnbGVmdCc6IHsgJ2Rpcic6ICdsZWZ0JywgJ2NvZGUnOiA5NyB9LCAncmlnaHQnOiB7ICdkaXInOiAncmlnaHQnLCAnY29kZSc6IDEwMCB9IH1cbiAqL1xudmFyIGtleUJ5ID0gY3JlYXRlQWdncmVnYXRvcihmdW5jdGlvbihyZXN1bHQsIHZhbHVlLCBrZXkpIHtcbiAgYmFzZUFzc2lnblZhbHVlKHJlc3VsdCwga2V5LCB2YWx1ZSk7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSBrZXlCeTtcbiIsInZhciBhcnJheUxpa2VLZXlzID0gcmVxdWlyZSgnLi9fYXJyYXlMaWtlS2V5cycpLFxuICAgIGJhc2VLZXlzID0gcmVxdWlyZSgnLi9fYmFzZUtleXMnKSxcbiAgICBpc0FycmF5TGlrZSA9IHJlcXVpcmUoJy4vaXNBcnJheUxpa2UnKTtcblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLW9iamVjdC5rZXlzKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IG5hbWVzLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmtleXMobmV3IEZvbyk7XG4gKiAvLyA9PiBbJ2EnLCAnYiddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKlxuICogXy5rZXlzKCdoaScpO1xuICogLy8gPT4gWycwJywgJzEnXVxuICovXG5mdW5jdGlvbiBrZXlzKG9iamVjdCkge1xuICByZXR1cm4gaXNBcnJheUxpa2Uob2JqZWN0KSA/IGFycmF5TGlrZUtleXMob2JqZWN0KSA6IGJhc2VLZXlzKG9iamVjdCk7XG59XG5cbm1vZHVsZS5leHBvcnRzID0ga2V5cztcbiIsInZhciBhcnJheU1hcCA9IHJlcXVpcmUoJy4vX2FycmF5TWFwJyksXG4gICAgYmFzZUl0ZXJhdGVlID0gcmVxdWlyZSgnLi9fYmFzZUl0ZXJhdGVlJyksXG4gICAgYmFzZU1hcCA9IHJlcXVpcmUoJy4vX2Jhc2VNYXAnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB2YWx1ZXMgYnkgcnVubmluZyBlYWNoIGVsZW1lbnQgaW4gYGNvbGxlY3Rpb25gIHRocnVcbiAqIGBpdGVyYXRlZWAuIFRoZSBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggdGhyZWUgYXJndW1lbnRzOlxuICogKHZhbHVlLCBpbmRleHxrZXksIGNvbGxlY3Rpb24pLlxuICpcbiAqIE1hbnkgbG9kYXNoIG1ldGhvZHMgYXJlIGd1YXJkZWQgdG8gd29yayBhcyBpdGVyYXRlZXMgZm9yIG1ldGhvZHMgbGlrZVxuICogYF8uZXZlcnlgLCBgXy5maWx0ZXJgLCBgXy5tYXBgLCBgXy5tYXBWYWx1ZXNgLCBgXy5yZWplY3RgLCBhbmQgYF8uc29tZWAuXG4gKlxuICogVGhlIGd1YXJkZWQgbWV0aG9kcyBhcmU6XG4gKiBgYXJ5YCwgYGNodW5rYCwgYGN1cnJ5YCwgYGN1cnJ5UmlnaHRgLCBgZHJvcGAsIGBkcm9wUmlnaHRgLCBgZXZlcnlgLFxuICogYGZpbGxgLCBgaW52ZXJ0YCwgYHBhcnNlSW50YCwgYHJhbmRvbWAsIGByYW5nZWAsIGByYW5nZVJpZ2h0YCwgYHJlcGVhdGAsXG4gKiBgc2FtcGxlU2l6ZWAsIGBzbGljZWAsIGBzb21lYCwgYHNvcnRCeWAsIGBzcGxpdGAsIGB0YWtlYCwgYHRha2VSaWdodGAsXG4gKiBgdGVtcGxhdGVgLCBgdHJpbWAsIGB0cmltRW5kYCwgYHRyaW1TdGFydGAsIGFuZCBgd29yZHNgXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uIFRoZSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgbWFwcGVkIGFycmF5LlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICogICByZXR1cm4gbiAqIG47XG4gKiB9XG4gKlxuICogXy5tYXAoWzQsIDhdLCBzcXVhcmUpO1xuICogLy8gPT4gWzE2LCA2NF1cbiAqXG4gKiBfLm1hcCh7ICdhJzogNCwgJ2InOiA4IH0sIHNxdWFyZSk7XG4gKiAvLyA9PiBbMTYsIDY0XSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIHZhciB1c2VycyA9IFtcbiAqICAgeyAndXNlcic6ICdiYXJuZXknIH0sXG4gKiAgIHsgJ3VzZXInOiAnZnJlZCcgfVxuICogXTtcbiAqXG4gKiAvLyBUaGUgYF8ucHJvcGVydHlgIGl0ZXJhdGVlIHNob3J0aGFuZC5cbiAqIF8ubWFwKHVzZXJzLCAndXNlcicpO1xuICogLy8gPT4gWydiYXJuZXknLCAnZnJlZCddXG4gKi9cbmZ1bmN0aW9uIG1hcChjb2xsZWN0aW9uLCBpdGVyYXRlZSkge1xuICB2YXIgZnVuYyA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyBhcnJheU1hcCA6IGJhc2VNYXA7XG4gIHJldHVybiBmdW5jKGNvbGxlY3Rpb24sIGJhc2VJdGVyYXRlZShpdGVyYXRlZSwgMykpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IG1hcDtcbiIsInZhciBNYXBDYWNoZSA9IHJlcXVpcmUoJy4vX01hcENhY2hlJyk7XG5cbi8qKiBFcnJvciBtZXNzYWdlIGNvbnN0YW50cy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgbWVtb2l6ZXMgdGhlIHJlc3VsdCBvZiBgZnVuY2AuIElmIGByZXNvbHZlcmAgaXNcbiAqIHByb3ZpZGVkLCBpdCBkZXRlcm1pbmVzIHRoZSBjYWNoZSBrZXkgZm9yIHN0b3JpbmcgdGhlIHJlc3VsdCBiYXNlZCBvbiB0aGVcbiAqIGFyZ3VtZW50cyBwcm92aWRlZCB0byB0aGUgbWVtb2l6ZWQgZnVuY3Rpb24uIEJ5IGRlZmF1bHQsIHRoZSBmaXJzdCBhcmd1bWVudFxuICogcHJvdmlkZWQgdG8gdGhlIG1lbW9pemVkIGZ1bmN0aW9uIGlzIHVzZWQgYXMgdGhlIG1hcCBjYWNoZSBrZXkuIFRoZSBgZnVuY2BcbiAqIGlzIGludm9rZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIG1lbW9pemVkIGZ1bmN0aW9uLlxuICpcbiAqICoqTm90ZToqKiBUaGUgY2FjaGUgaXMgZXhwb3NlZCBhcyB0aGUgYGNhY2hlYCBwcm9wZXJ0eSBvbiB0aGUgbWVtb2l6ZWRcbiAqIGZ1bmN0aW9uLiBJdHMgY3JlYXRpb24gbWF5IGJlIGN1c3RvbWl6ZWQgYnkgcmVwbGFjaW5nIHRoZSBgXy5tZW1vaXplLkNhY2hlYFxuICogY29uc3RydWN0b3Igd2l0aCBvbmUgd2hvc2UgaW5zdGFuY2VzIGltcGxlbWVudCB0aGVcbiAqIFtgTWFwYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNy4wLyNzZWMtcHJvcGVydGllcy1vZi10aGUtbWFwLXByb3RvdHlwZS1vYmplY3QpXG4gKiBtZXRob2QgaW50ZXJmYWNlIG9mIGBjbGVhcmAsIGBkZWxldGVgLCBgZ2V0YCwgYGhhc2AsIGFuZCBgc2V0YC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGhhdmUgaXRzIG91dHB1dCBtZW1vaXplZC5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtyZXNvbHZlcl0gVGhlIGZ1bmN0aW9uIHRvIHJlc29sdmUgdGhlIGNhY2hlIGtleS5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IG1lbW9pemVkIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgb2JqZWN0ID0geyAnYSc6IDEsICdiJzogMiB9O1xuICogdmFyIG90aGVyID0geyAnYyc6IDMsICdkJzogNCB9O1xuICpcbiAqIHZhciB2YWx1ZXMgPSBfLm1lbW9pemUoXy52YWx1ZXMpO1xuICogdmFsdWVzKG9iamVjdCk7XG4gKiAvLyA9PiBbMSwgMl1cbiAqXG4gKiB2YWx1ZXMob3RoZXIpO1xuICogLy8gPT4gWzMsIDRdXG4gKlxuICogb2JqZWN0LmEgPSAyO1xuICogdmFsdWVzKG9iamVjdCk7XG4gKiAvLyA9PiBbMSwgMl1cbiAqXG4gKiAvLyBNb2RpZnkgdGhlIHJlc3VsdCBjYWNoZS5cbiAqIHZhbHVlcy5jYWNoZS5zZXQob2JqZWN0LCBbJ2EnLCAnYiddKTtcbiAqIHZhbHVlcyhvYmplY3QpO1xuICogLy8gPT4gWydhJywgJ2InXVxuICpcbiAqIC8vIFJlcGxhY2UgYF8ubWVtb2l6ZS5DYWNoZWAuXG4gKiBfLm1lbW9pemUuQ2FjaGUgPSBXZWFrTWFwO1xuICovXG5mdW5jdGlvbiBtZW1vaXplKGZ1bmMsIHJlc29sdmVyKSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nIHx8IChyZXNvbHZlciAhPSBudWxsICYmIHR5cGVvZiByZXNvbHZlciAhPSAnZnVuY3Rpb24nKSkge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICB2YXIgbWVtb2l6ZWQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgYXJncyA9IGFyZ3VtZW50cyxcbiAgICAgICAga2V5ID0gcmVzb2x2ZXIgPyByZXNvbHZlci5hcHBseSh0aGlzLCBhcmdzKSA6IGFyZ3NbMF0sXG4gICAgICAgIGNhY2hlID0gbWVtb2l6ZWQuY2FjaGU7XG5cbiAgICBpZiAoY2FjaGUuaGFzKGtleSkpIHtcbiAgICAgIHJldHVybiBjYWNoZS5nZXQoa2V5KTtcbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IGZ1bmMuYXBwbHkodGhpcywgYXJncyk7XG4gICAgbWVtb2l6ZWQuY2FjaGUgPSBjYWNoZS5zZXQoa2V5LCByZXN1bHQpIHx8IGNhY2hlO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH07XG4gIG1lbW9pemVkLmNhY2hlID0gbmV3IChtZW1vaXplLkNhY2hlIHx8IE1hcENhY2hlKTtcbiAgcmV0dXJuIG1lbW9pemVkO1xufVxuXG4vLyBFeHBvc2UgYE1hcENhY2hlYC5cbm1lbW9pemUuQ2FjaGUgPSBNYXBDYWNoZTtcblxubW9kdWxlLmV4cG9ydHMgPSBtZW1vaXplO1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIGB1bmRlZmluZWRgLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgMi4zLjBcbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udGltZXMoMiwgXy5ub29wKTtcbiAqIC8vID0+IFt1bmRlZmluZWQsIHVuZGVmaW5lZF1cbiAqL1xuZnVuY3Rpb24gbm9vcCgpIHtcbiAgLy8gTm8gb3BlcmF0aW9uIHBlcmZvcm1lZC5cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBub29wO1xuIiwidmFyIHJvb3QgPSByZXF1aXJlKCcuL19yb290Jyk7XG5cbi8qKlxuICogR2V0cyB0aGUgdGltZXN0YW1wIG9mIHRoZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIHRoYXQgaGF2ZSBlbGFwc2VkIHNpbmNlXG4gKiB0aGUgVW5peCBlcG9jaCAoMSBKYW51YXJ5IDE5NzAgMDA6MDA6MDAgVVRDKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDIuNC4wXG4gKiBAY2F0ZWdvcnkgRGF0ZVxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgdGltZXN0YW1wLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmRlZmVyKGZ1bmN0aW9uKHN0YW1wKSB7XG4gKiAgIGNvbnNvbGUubG9nKF8ubm93KCkgLSBzdGFtcCk7XG4gKiB9LCBfLm5vdygpKTtcbiAqIC8vID0+IExvZ3MgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgaXQgdG9vayBmb3IgdGhlIGRlZmVycmVkIGludm9jYXRpb24uXG4gKi9cbnZhciBub3cgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHJvb3QuRGF0ZS5ub3coKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0gbm93O1xuIiwidmFyIGJhc2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vX2Jhc2VQcm9wZXJ0eScpLFxuICAgIGJhc2VQcm9wZXJ0eURlZXAgPSByZXF1aXJlKCcuL19iYXNlUHJvcGVydHlEZWVwJyksXG4gICAgaXNLZXkgPSByZXF1aXJlKCcuL19pc0tleScpLFxuICAgIHRvS2V5ID0gcmVxdWlyZSgnLi9fdG9LZXknKTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSB2YWx1ZSBhdCBgcGF0aGAgb2YgYSBnaXZlbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAyLjQuMFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEBwYXJhbSB7QXJyYXl8c3RyaW5nfSBwYXRoIFRoZSBwYXRoIG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBhY2Nlc3NvciBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdHMgPSBbXG4gKiAgIHsgJ2EnOiB7ICdiJzogMiB9IH0sXG4gKiAgIHsgJ2EnOiB7ICdiJzogMSB9IH1cbiAqIF07XG4gKlxuICogXy5tYXAob2JqZWN0cywgXy5wcm9wZXJ0eSgnYS5iJykpO1xuICogLy8gPT4gWzIsIDFdXG4gKlxuICogXy5tYXAoXy5zb3J0Qnkob2JqZWN0cywgXy5wcm9wZXJ0eShbJ2EnLCAnYiddKSksICdhLmInKTtcbiAqIC8vID0+IFsxLCAyXVxuICovXG5mdW5jdGlvbiBwcm9wZXJ0eShwYXRoKSB7XG4gIHJldHVybiBpc0tleShwYXRoKSA/IGJhc2VQcm9wZXJ0eSh0b0tleShwYXRoKSkgOiBiYXNlUHJvcGVydHlEZWVwKHBhdGgpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHByb3BlcnR5O1xuIiwiLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIGEgbmV3IGVtcHR5IGFycmF5LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4xMy4wXG4gKiBAY2F0ZWdvcnkgVXRpbFxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZW1wdHkgYXJyYXkuXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBhcnJheXMgPSBfLnRpbWVzKDIsIF8uc3R1YkFycmF5KTtcbiAqXG4gKiBjb25zb2xlLmxvZyhhcnJheXMpO1xuICogLy8gPT4gW1tdLCBbXV1cbiAqXG4gKiBjb25zb2xlLmxvZyhhcnJheXNbMF0gPT09IGFycmF5c1sxXSk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBzdHViQXJyYXkoKSB7XG4gIHJldHVybiBbXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzdHViQXJyYXk7XG4iLCIvKipcbiAqIFRoaXMgbWV0aG9kIHJldHVybnMgYGZhbHNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMTMuMFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udGltZXMoMiwgXy5zdHViRmFsc2UpO1xuICogLy8gPT4gW2ZhbHNlLCBmYWxzZV1cbiAqL1xuZnVuY3Rpb24gc3R1YkZhbHNlKCkge1xuICByZXR1cm4gZmFsc2U7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gc3R1YkZhbHNlO1xuIiwidmFyIHRvTnVtYmVyID0gcmVxdWlyZSgnLi90b051bWJlcicpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBJTkZJTklUWSA9IDEgLyAwLFxuICAgIE1BWF9JTlRFR0VSID0gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDg7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIGZpbml0ZSBudW1iZXIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjEyLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjb252ZXJ0LlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgY29udmVydGVkIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b0Zpbml0ZSgzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b0Zpbml0ZShOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9GaW5pdGUoSW5maW5pdHkpO1xuICogLy8gPT4gMS43OTc2OTMxMzQ4NjIzMTU3ZSszMDhcbiAqXG4gKiBfLnRvRmluaXRlKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b0Zpbml0ZSh2YWx1ZSkge1xuICBpZiAoIXZhbHVlKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiAwO1xuICB9XG4gIHZhbHVlID0gdG9OdW1iZXIodmFsdWUpO1xuICBpZiAodmFsdWUgPT09IElORklOSVRZIHx8IHZhbHVlID09PSAtSU5GSU5JVFkpIHtcbiAgICB2YXIgc2lnbiA9ICh2YWx1ZSA8IDAgPyAtMSA6IDEpO1xuICAgIHJldHVybiBzaWduICogTUFYX0lOVEVHRVI7XG4gIH1cbiAgcmV0dXJuIHZhbHVlID09PSB2YWx1ZSA/IHZhbHVlIDogMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b0Zpbml0ZTtcbiIsInZhciB0b0Zpbml0ZSA9IHJlcXVpcmUoJy4vdG9GaW5pdGUnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGFuIGludGVnZXIuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGxvb3NlbHkgYmFzZWQgb25cbiAqIFtgVG9JbnRlZ2VyYF0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzcuMC8jc2VjLXRvaW50ZWdlcikuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW50ZWdlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b0ludGVnZXIoMy4yKTtcbiAqIC8vID0+IDNcbiAqXG4gKiBfLnRvSW50ZWdlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDBcbiAqXG4gKiBfLnRvSW50ZWdlcihJbmZpbml0eSk7XG4gKiAvLyA9PiAxLjc5NzY5MzEzNDg2MjMxNTdlKzMwOFxuICpcbiAqIF8udG9JbnRlZ2VyKCczLjInKTtcbiAqIC8vID0+IDNcbiAqL1xuZnVuY3Rpb24gdG9JbnRlZ2VyKHZhbHVlKSB7XG4gIHZhciByZXN1bHQgPSB0b0Zpbml0ZSh2YWx1ZSksXG4gICAgICByZW1haW5kZXIgPSByZXN1bHQgJSAxO1xuXG4gIHJldHVybiByZXN1bHQgPT09IHJlc3VsdCA/IChyZW1haW5kZXIgPyByZXN1bHQgLSByZW1haW5kZXIgOiByZXN1bHQpIDogMDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b0ludGVnZXI7XG4iLCJ2YXIgaXNPYmplY3QgPSByZXF1aXJlKCcuL2lzT2JqZWN0JyksXG4gICAgaXNTeW1ib2wgPSByZXF1aXJlKCcuL2lzU3ltYm9sJyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIE5BTiA9IDAgLyAwO1xuXG4vKiogVXNlZCB0byBtYXRjaCBsZWFkaW5nIGFuZCB0cmFpbGluZyB3aGl0ZXNwYWNlLiAqL1xudmFyIHJlVHJpbSA9IC9eXFxzK3xcXHMrJC9nO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgYmFkIHNpZ25lZCBoZXhhZGVjaW1hbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCYWRIZXggPSAvXlstK10weFswLTlhLWZdKyQvaTtcblxuLyoqIFVzZWQgdG8gZGV0ZWN0IGJpbmFyeSBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNCaW5hcnkgPSAvXjBiWzAxXSskL2k7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBvY3RhbCBzdHJpbmcgdmFsdWVzLiAqL1xudmFyIHJlSXNPY3RhbCA9IC9eMG9bMC03XSskL2k7XG5cbi8qKiBCdWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcyB3aXRob3V0IGEgZGVwZW5kZW5jeSBvbiBgcm9vdGAuICovXG52YXIgZnJlZVBhcnNlSW50ID0gcGFyc2VJbnQ7XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIG51bWJlci5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgdGhlIG51bWJlci5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b051bWJlcigzLjIpO1xuICogLy8gPT4gMy4yXG4gKlxuICogXy50b051bWJlcihOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IDVlLTMyNFxuICpcbiAqIF8udG9OdW1iZXIoSW5maW5pdHkpO1xuICogLy8gPT4gSW5maW5pdHlcbiAqXG4gKiBfLnRvTnVtYmVyKCczLjInKTtcbiAqIC8vID0+IDMuMlxuICovXG5mdW5jdGlvbiB0b051bWJlcih2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlID09ICdudW1iZXInKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gTkFOO1xuICB9XG4gIGlmIChpc09iamVjdCh2YWx1ZSkpIHtcbiAgICB2YXIgb3RoZXIgPSB0eXBlb2YgdmFsdWUudmFsdWVPZiA9PSAnZnVuY3Rpb24nID8gdmFsdWUudmFsdWVPZigpIDogdmFsdWU7XG4gICAgdmFsdWUgPSBpc09iamVjdChvdGhlcikgPyAob3RoZXIgKyAnJykgOiBvdGhlcjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlICE9ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlID09PSAwID8gdmFsdWUgOiArdmFsdWU7XG4gIH1cbiAgdmFsdWUgPSB2YWx1ZS5yZXBsYWNlKHJlVHJpbSwgJycpO1xuICB2YXIgaXNCaW5hcnkgPSByZUlzQmluYXJ5LnRlc3QodmFsdWUpO1xuICByZXR1cm4gKGlzQmluYXJ5IHx8IHJlSXNPY3RhbC50ZXN0KHZhbHVlKSlcbiAgICA/IGZyZWVQYXJzZUludCh2YWx1ZS5zbGljZSgyKSwgaXNCaW5hcnkgPyAyIDogOClcbiAgICA6IChyZUlzQmFkSGV4LnRlc3QodmFsdWUpID8gTkFOIDogK3ZhbHVlKTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0b051bWJlcjtcbiIsInZhciBiYXNlVG9TdHJpbmcgPSByZXF1aXJlKCcuL19iYXNlVG9TdHJpbmcnKTtcblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWQgZm9yIGBudWxsYFxuICogYW5kIGB1bmRlZmluZWRgIHZhbHVlcy4gVGhlIHNpZ24gb2YgYC0wYCBpcyBwcmVzZXJ2ZWQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgc3RyaW5nLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRvU3RyaW5nKG51bGwpO1xuICogLy8gPT4gJydcbiAqXG4gKiBfLnRvU3RyaW5nKC0wKTtcbiAqIC8vID0+ICctMCdcbiAqXG4gKiBfLnRvU3RyaW5nKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiAnMSwyLDMnXG4gKi9cbmZ1bmN0aW9uIHRvU3RyaW5nKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSA9PSBudWxsID8gJycgOiBiYXNlVG9TdHJpbmcodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRvU3RyaW5nO1xuIiwidmFyIGFycmF5RWFjaCA9IHJlcXVpcmUoJy4vX2FycmF5RWFjaCcpLFxuICAgIGJhc2VDcmVhdGUgPSByZXF1aXJlKCcuL19iYXNlQ3JlYXRlJyksXG4gICAgYmFzZUZvck93biA9IHJlcXVpcmUoJy4vX2Jhc2VGb3JPd24nKSxcbiAgICBiYXNlSXRlcmF0ZWUgPSByZXF1aXJlKCcuL19iYXNlSXRlcmF0ZWUnKSxcbiAgICBnZXRQcm90b3R5cGUgPSByZXF1aXJlKCcuL19nZXRQcm90b3R5cGUnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnLi9pc0FycmF5JyksXG4gICAgaXNCdWZmZXIgPSByZXF1aXJlKCcuL2lzQnVmZmVyJyksXG4gICAgaXNGdW5jdGlvbiA9IHJlcXVpcmUoJy4vaXNGdW5jdGlvbicpLFxuICAgIGlzT2JqZWN0ID0gcmVxdWlyZSgnLi9pc09iamVjdCcpLFxuICAgIGlzVHlwZWRBcnJheSA9IHJlcXVpcmUoJy4vaXNUeXBlZEFycmF5Jyk7XG5cbi8qKlxuICogQW4gYWx0ZXJuYXRpdmUgdG8gYF8ucmVkdWNlYDsgdGhpcyBtZXRob2QgdHJhbnNmb3JtcyBgb2JqZWN0YCB0byBhIG5ld1xuICogYGFjY3VtdWxhdG9yYCBvYmplY3Qgd2hpY2ggaXMgdGhlIHJlc3VsdCBvZiBydW5uaW5nIGVhY2ggb2YgaXRzIG93blxuICogZW51bWVyYWJsZSBzdHJpbmcga2V5ZWQgcHJvcGVydGllcyB0aHJ1IGBpdGVyYXRlZWAsIHdpdGggZWFjaCBpbnZvY2F0aW9uXG4gKiBwb3RlbnRpYWxseSBtdXRhdGluZyB0aGUgYGFjY3VtdWxhdG9yYCBvYmplY3QuIElmIGBhY2N1bXVsYXRvcmAgaXMgbm90XG4gKiBwcm92aWRlZCwgYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWUgYFtbUHJvdG90eXBlXV1gIHdpbGwgYmUgdXNlZC4gVGhlXG4gKiBpdGVyYXRlZSBpcyBpbnZva2VkIHdpdGggZm91ciBhcmd1bWVudHM6IChhY2N1bXVsYXRvciwgdmFsdWUsIGtleSwgb2JqZWN0KS5cbiAqIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDEuMy4wXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2l0ZXJhdGVlPV8uaWRlbnRpdHldIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcGFyYW0geyp9IFthY2N1bXVsYXRvcl0gVGhlIGN1c3RvbSBhY2N1bXVsYXRvciB2YWx1ZS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZS5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50cmFuc2Zvcm0oWzIsIDMsIDRdLCBmdW5jdGlvbihyZXN1bHQsIG4pIHtcbiAqICAgcmVzdWx0LnB1c2gobiAqPSBuKTtcbiAqICAgcmV0dXJuIG4gJSAyID09IDA7XG4gKiB9LCBbXSk7XG4gKiAvLyA9PiBbNCwgOV1cbiAqXG4gKiBfLnRyYW5zZm9ybSh7ICdhJzogMSwgJ2InOiAyLCAnYyc6IDEgfSwgZnVuY3Rpb24ocmVzdWx0LCB2YWx1ZSwga2V5KSB7XG4gKiAgIChyZXN1bHRbdmFsdWVdIHx8IChyZXN1bHRbdmFsdWVdID0gW10pKS5wdXNoKGtleSk7XG4gKiB9LCB7fSk7XG4gKiAvLyA9PiB7ICcxJzogWydhJywgJ2MnXSwgJzInOiBbJ2InXSB9XG4gKi9cbmZ1bmN0aW9uIHRyYW5zZm9ybShvYmplY3QsIGl0ZXJhdGVlLCBhY2N1bXVsYXRvcikge1xuICB2YXIgaXNBcnIgPSBpc0FycmF5KG9iamVjdCksXG4gICAgICBpc0Fyckxpa2UgPSBpc0FyciB8fCBpc0J1ZmZlcihvYmplY3QpIHx8IGlzVHlwZWRBcnJheShvYmplY3QpO1xuXG4gIGl0ZXJhdGVlID0gYmFzZUl0ZXJhdGVlKGl0ZXJhdGVlLCA0KTtcbiAgaWYgKGFjY3VtdWxhdG9yID09IG51bGwpIHtcbiAgICB2YXIgQ3RvciA9IG9iamVjdCAmJiBvYmplY3QuY29uc3RydWN0b3I7XG4gICAgaWYgKGlzQXJyTGlrZSkge1xuICAgICAgYWNjdW11bGF0b3IgPSBpc0FyciA/IG5ldyBDdG9yIDogW107XG4gICAgfVxuICAgIGVsc2UgaWYgKGlzT2JqZWN0KG9iamVjdCkpIHtcbiAgICAgIGFjY3VtdWxhdG9yID0gaXNGdW5jdGlvbihDdG9yKSA/IGJhc2VDcmVhdGUoZ2V0UHJvdG90eXBlKG9iamVjdCkpIDoge307XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgYWNjdW11bGF0b3IgPSB7fTtcbiAgICB9XG4gIH1cbiAgKGlzQXJyTGlrZSA/IGFycmF5RWFjaCA6IGJhc2VGb3JPd24pKG9iamVjdCwgZnVuY3Rpb24odmFsdWUsIGluZGV4LCBvYmplY3QpIHtcbiAgICByZXR1cm4gaXRlcmF0ZWUoYWNjdW11bGF0b3IsIHZhbHVlLCBpbmRleCwgb2JqZWN0KTtcbiAgfSk7XG4gIHJldHVybiBhY2N1bXVsYXRvcjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB0cmFuc2Zvcm07XG4iLCJ2YXIgYmFzZVZhbHVlcyA9IHJlcXVpcmUoJy4vX2Jhc2VWYWx1ZXMnKSxcbiAgICBrZXlzID0gcmVxdWlyZSgnLi9rZXlzJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB0aGUgb3duIGVudW1lcmFibGUgc3RyaW5nIGtleWVkIHByb3BlcnR5IHZhbHVlcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAc2luY2UgMC4xLjBcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgT2JqZWN0XG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIGFycmF5IG9mIHByb3BlcnR5IHZhbHVlcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy52YWx1ZXMobmV3IEZvbyk7XG4gKiAvLyA9PiBbMSwgMl0gKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqXG4gKiBfLnZhbHVlcygnaGknKTtcbiAqIC8vID0+IFsnaCcsICdpJ11cbiAqL1xuZnVuY3Rpb24gdmFsdWVzKG9iamVjdCkge1xuICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyBbXSA6IGJhc2VWYWx1ZXMob2JqZWN0LCBrZXlzKG9iamVjdCkpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHZhbHVlcztcbiIsInZhciBMYXp5V3JhcHBlciA9IHJlcXVpcmUoJy4vX0xhenlXcmFwcGVyJyksXG4gICAgTG9kYXNoV3JhcHBlciA9IHJlcXVpcmUoJy4vX0xvZGFzaFdyYXBwZXInKSxcbiAgICBiYXNlTG9kYXNoID0gcmVxdWlyZSgnLi9fYmFzZUxvZGFzaCcpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCcuL2lzQXJyYXknKSxcbiAgICBpc09iamVjdExpa2UgPSByZXF1aXJlKCcuL2lzT2JqZWN0TGlrZScpLFxuICAgIHdyYXBwZXJDbG9uZSA9IHJlcXVpcmUoJy4vX3dyYXBwZXJDbG9uZScpO1xuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgbG9kYXNoYCBvYmplY3Qgd2hpY2ggd3JhcHMgYHZhbHVlYCB0byBlbmFibGUgaW1wbGljaXQgbWV0aG9kXG4gKiBjaGFpbiBzZXF1ZW5jZXMuIE1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIGFuZCByZXR1cm4gYXJyYXlzLCBjb2xsZWN0aW9ucyxcbiAqIGFuZCBmdW5jdGlvbnMgY2FuIGJlIGNoYWluZWQgdG9nZXRoZXIuIE1ldGhvZHMgdGhhdCByZXRyaWV2ZSBhIHNpbmdsZSB2YWx1ZVxuICogb3IgbWF5IHJldHVybiBhIHByaW1pdGl2ZSB2YWx1ZSB3aWxsIGF1dG9tYXRpY2FsbHkgZW5kIHRoZSBjaGFpbiBzZXF1ZW5jZVxuICogYW5kIHJldHVybiB0aGUgdW53cmFwcGVkIHZhbHVlLiBPdGhlcndpc2UsIHRoZSB2YWx1ZSBtdXN0IGJlIHVud3JhcHBlZFxuICogd2l0aCBgXyN2YWx1ZWAuXG4gKlxuICogRXhwbGljaXQgY2hhaW4gc2VxdWVuY2VzLCB3aGljaCBtdXN0IGJlIHVud3JhcHBlZCB3aXRoIGBfI3ZhbHVlYCwgbWF5IGJlXG4gKiBlbmFibGVkIHVzaW5nIGBfLmNoYWluYC5cbiAqXG4gKiBUaGUgZXhlY3V0aW9uIG9mIGNoYWluZWQgbWV0aG9kcyBpcyBsYXp5LCB0aGF0IGlzLCBpdCdzIGRlZmVycmVkIHVudGlsXG4gKiBgXyN2YWx1ZWAgaXMgaW1wbGljaXRseSBvciBleHBsaWNpdGx5IGNhbGxlZC5cbiAqXG4gKiBMYXp5IGV2YWx1YXRpb24gYWxsb3dzIHNldmVyYWwgbWV0aG9kcyB0byBzdXBwb3J0IHNob3J0Y3V0IGZ1c2lvbi5cbiAqIFNob3J0Y3V0IGZ1c2lvbiBpcyBhbiBvcHRpbWl6YXRpb24gdG8gbWVyZ2UgaXRlcmF0ZWUgY2FsbHM7IHRoaXMgYXZvaWRzXG4gKiB0aGUgY3JlYXRpb24gb2YgaW50ZXJtZWRpYXRlIGFycmF5cyBhbmQgY2FuIGdyZWF0bHkgcmVkdWNlIHRoZSBudW1iZXIgb2ZcbiAqIGl0ZXJhdGVlIGV4ZWN1dGlvbnMuIFNlY3Rpb25zIG9mIGEgY2hhaW4gc2VxdWVuY2UgcXVhbGlmeSBmb3Igc2hvcnRjdXRcbiAqIGZ1c2lvbiBpZiB0aGUgc2VjdGlvbiBpcyBhcHBsaWVkIHRvIGFuIGFycmF5IGFuZCBpdGVyYXRlZXMgYWNjZXB0IG9ubHlcbiAqIG9uZSBhcmd1bWVudC4gVGhlIGhldXJpc3RpYyBmb3Igd2hldGhlciBhIHNlY3Rpb24gcXVhbGlmaWVzIGZvciBzaG9ydGN1dFxuICogZnVzaW9uIGlzIHN1YmplY3QgdG8gY2hhbmdlLlxuICpcbiAqIENoYWluaW5nIGlzIHN1cHBvcnRlZCBpbiBjdXN0b20gYnVpbGRzIGFzIGxvbmcgYXMgdGhlIGBfI3ZhbHVlYCBtZXRob2QgaXNcbiAqIGRpcmVjdGx5IG9yIGluZGlyZWN0bHkgaW5jbHVkZWQgaW4gdGhlIGJ1aWxkLlxuICpcbiAqIEluIGFkZGl0aW9uIHRvIGxvZGFzaCBtZXRob2RzLCB3cmFwcGVycyBoYXZlIGBBcnJheWAgYW5kIGBTdHJpbmdgIG1ldGhvZHMuXG4gKlxuICogVGhlIHdyYXBwZXIgYEFycmF5YCBtZXRob2RzIGFyZTpcbiAqIGBjb25jYXRgLCBgam9pbmAsIGBwb3BgLCBgcHVzaGAsIGBzaGlmdGAsIGBzb3J0YCwgYHNwbGljZWAsIGFuZCBgdW5zaGlmdGBcbiAqXG4gKiBUaGUgd3JhcHBlciBgU3RyaW5nYCBtZXRob2RzIGFyZTpcbiAqIGByZXBsYWNlYCBhbmQgYHNwbGl0YFxuICpcbiAqIFRoZSB3cmFwcGVyIG1ldGhvZHMgdGhhdCBzdXBwb3J0IHNob3J0Y3V0IGZ1c2lvbiBhcmU6XG4gKiBgYXRgLCBgY29tcGFjdGAsIGBkcm9wYCwgYGRyb3BSaWdodGAsIGBkcm9wV2hpbGVgLCBgZmlsdGVyYCwgYGZpbmRgLFxuICogYGZpbmRMYXN0YCwgYGhlYWRgLCBgaW5pdGlhbGAsIGBsYXN0YCwgYG1hcGAsIGByZWplY3RgLCBgcmV2ZXJzZWAsIGBzbGljZWAsXG4gKiBgdGFpbGAsIGB0YWtlYCwgYHRha2VSaWdodGAsIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBhbmQgYHRvQXJyYXlgXG4gKlxuICogVGhlIGNoYWluYWJsZSB3cmFwcGVyIG1ldGhvZHMgYXJlOlxuICogYGFmdGVyYCwgYGFyeWAsIGBhc3NpZ25gLCBgYXNzaWduSW5gLCBgYXNzaWduSW5XaXRoYCwgYGFzc2lnbldpdGhgLCBgYXRgLFxuICogYGJlZm9yZWAsIGBiaW5kYCwgYGJpbmRBbGxgLCBgYmluZEtleWAsIGBjYXN0QXJyYXlgLCBgY2hhaW5gLCBgY2h1bmtgLFxuICogYGNvbW1pdGAsIGBjb21wYWN0YCwgYGNvbmNhdGAsIGBjb25mb3Jtc2AsIGBjb25zdGFudGAsIGBjb3VudEJ5YCwgYGNyZWF0ZWAsXG4gKiBgY3VycnlgLCBgZGVib3VuY2VgLCBgZGVmYXVsdHNgLCBgZGVmYXVsdHNEZWVwYCwgYGRlZmVyYCwgYGRlbGF5YCxcbiAqIGBkaWZmZXJlbmNlYCwgYGRpZmZlcmVuY2VCeWAsIGBkaWZmZXJlbmNlV2l0aGAsIGBkcm9wYCwgYGRyb3BSaWdodGAsXG4gKiBgZHJvcFJpZ2h0V2hpbGVgLCBgZHJvcFdoaWxlYCwgYGV4dGVuZGAsIGBleHRlbmRXaXRoYCwgYGZpbGxgLCBgZmlsdGVyYCxcbiAqIGBmbGF0TWFwYCwgYGZsYXRNYXBEZWVwYCwgYGZsYXRNYXBEZXB0aGAsIGBmbGF0dGVuYCwgYGZsYXR0ZW5EZWVwYCxcbiAqIGBmbGF0dGVuRGVwdGhgLCBgZmxpcGAsIGBmbG93YCwgYGZsb3dSaWdodGAsIGBmcm9tUGFpcnNgLCBgZnVuY3Rpb25zYCxcbiAqIGBmdW5jdGlvbnNJbmAsIGBncm91cEJ5YCwgYGluaXRpYWxgLCBgaW50ZXJzZWN0aW9uYCwgYGludGVyc2VjdGlvbkJ5YCxcbiAqIGBpbnRlcnNlY3Rpb25XaXRoYCwgYGludmVydGAsIGBpbnZlcnRCeWAsIGBpbnZva2VNYXBgLCBgaXRlcmF0ZWVgLCBga2V5QnlgLFxuICogYGtleXNgLCBga2V5c0luYCwgYG1hcGAsIGBtYXBLZXlzYCwgYG1hcFZhbHVlc2AsIGBtYXRjaGVzYCwgYG1hdGNoZXNQcm9wZXJ0eWAsXG4gKiBgbWVtb2l6ZWAsIGBtZXJnZWAsIGBtZXJnZVdpdGhgLCBgbWV0aG9kYCwgYG1ldGhvZE9mYCwgYG1peGluYCwgYG5lZ2F0ZWAsXG4gKiBgbnRoQXJnYCwgYG9taXRgLCBgb21pdEJ5YCwgYG9uY2VgLCBgb3JkZXJCeWAsIGBvdmVyYCwgYG92ZXJBcmdzYCxcbiAqIGBvdmVyRXZlcnlgLCBgb3ZlclNvbWVgLCBgcGFydGlhbGAsIGBwYXJ0aWFsUmlnaHRgLCBgcGFydGl0aW9uYCwgYHBpY2tgLFxuICogYHBpY2tCeWAsIGBwbGFudGAsIGBwcm9wZXJ0eWAsIGBwcm9wZXJ0eU9mYCwgYHB1bGxgLCBgcHVsbEFsbGAsIGBwdWxsQWxsQnlgLFxuICogYHB1bGxBbGxXaXRoYCwgYHB1bGxBdGAsIGBwdXNoYCwgYHJhbmdlYCwgYHJhbmdlUmlnaHRgLCBgcmVhcmdgLCBgcmVqZWN0YCxcbiAqIGByZW1vdmVgLCBgcmVzdGAsIGByZXZlcnNlYCwgYHNhbXBsZVNpemVgLCBgc2V0YCwgYHNldFdpdGhgLCBgc2h1ZmZsZWAsXG4gKiBgc2xpY2VgLCBgc29ydGAsIGBzb3J0QnlgLCBgc3BsaWNlYCwgYHNwcmVhZGAsIGB0YWlsYCwgYHRha2VgLCBgdGFrZVJpZ2h0YCxcbiAqIGB0YWtlUmlnaHRXaGlsZWAsIGB0YWtlV2hpbGVgLCBgdGFwYCwgYHRocm90dGxlYCwgYHRocnVgLCBgdG9BcnJheWAsXG4gKiBgdG9QYWlyc2AsIGB0b1BhaXJzSW5gLCBgdG9QYXRoYCwgYHRvUGxhaW5PYmplY3RgLCBgdHJhbnNmb3JtYCwgYHVuYXJ5YCxcbiAqIGB1bmlvbmAsIGB1bmlvbkJ5YCwgYHVuaW9uV2l0aGAsIGB1bmlxYCwgYHVuaXFCeWAsIGB1bmlxV2l0aGAsIGB1bnNldGAsXG4gKiBgdW5zaGlmdGAsIGB1bnppcGAsIGB1bnppcFdpdGhgLCBgdXBkYXRlYCwgYHVwZGF0ZVdpdGhgLCBgdmFsdWVzYCxcbiAqIGB2YWx1ZXNJbmAsIGB3aXRob3V0YCwgYHdyYXBgLCBgeG9yYCwgYHhvckJ5YCwgYHhvcldpdGhgLCBgemlwYCxcbiAqIGB6aXBPYmplY3RgLCBgemlwT2JqZWN0RGVlcGAsIGFuZCBgemlwV2l0aGBcbiAqXG4gKiBUaGUgd3JhcHBlciBtZXRob2RzIHRoYXQgYXJlICoqbm90KiogY2hhaW5hYmxlIGJ5IGRlZmF1bHQgYXJlOlxuICogYGFkZGAsIGBhdHRlbXB0YCwgYGNhbWVsQ2FzZWAsIGBjYXBpdGFsaXplYCwgYGNlaWxgLCBgY2xhbXBgLCBgY2xvbmVgLFxuICogYGNsb25lRGVlcGAsIGBjbG9uZURlZXBXaXRoYCwgYGNsb25lV2l0aGAsIGBjb25mb3Jtc1RvYCwgYGRlYnVycmAsXG4gKiBgZGVmYXVsdFRvYCwgYGRpdmlkZWAsIGBlYWNoYCwgYGVhY2hSaWdodGAsIGBlbmRzV2l0aGAsIGBlcWAsIGBlc2NhcGVgLFxuICogYGVzY2FwZVJlZ0V4cGAsIGBldmVyeWAsIGBmaW5kYCwgYGZpbmRJbmRleGAsIGBmaW5kS2V5YCwgYGZpbmRMYXN0YCxcbiAqIGBmaW5kTGFzdEluZGV4YCwgYGZpbmRMYXN0S2V5YCwgYGZpcnN0YCwgYGZsb29yYCwgYGZvckVhY2hgLCBgZm9yRWFjaFJpZ2h0YCxcbiAqIGBmb3JJbmAsIGBmb3JJblJpZ2h0YCwgYGZvck93bmAsIGBmb3JPd25SaWdodGAsIGBnZXRgLCBgZ3RgLCBgZ3RlYCwgYGhhc2AsXG4gKiBgaGFzSW5gLCBgaGVhZGAsIGBpZGVudGl0eWAsIGBpbmNsdWRlc2AsIGBpbmRleE9mYCwgYGluUmFuZ2VgLCBgaW52b2tlYCxcbiAqIGBpc0FyZ3VtZW50c2AsIGBpc0FycmF5YCwgYGlzQXJyYXlCdWZmZXJgLCBgaXNBcnJheUxpa2VgLCBgaXNBcnJheUxpa2VPYmplY3RgLFxuICogYGlzQm9vbGVhbmAsIGBpc0J1ZmZlcmAsIGBpc0RhdGVgLCBgaXNFbGVtZW50YCwgYGlzRW1wdHlgLCBgaXNFcXVhbGAsXG4gKiBgaXNFcXVhbFdpdGhgLCBgaXNFcnJvcmAsIGBpc0Zpbml0ZWAsIGBpc0Z1bmN0aW9uYCwgYGlzSW50ZWdlcmAsIGBpc0xlbmd0aGAsXG4gKiBgaXNNYXBgLCBgaXNNYXRjaGAsIGBpc01hdGNoV2l0aGAsIGBpc05hTmAsIGBpc05hdGl2ZWAsIGBpc05pbGAsIGBpc051bGxgLFxuICogYGlzTnVtYmVyYCwgYGlzT2JqZWN0YCwgYGlzT2JqZWN0TGlrZWAsIGBpc1BsYWluT2JqZWN0YCwgYGlzUmVnRXhwYCxcbiAqIGBpc1NhZmVJbnRlZ2VyYCwgYGlzU2V0YCwgYGlzU3RyaW5nYCwgYGlzVW5kZWZpbmVkYCwgYGlzVHlwZWRBcnJheWAsXG4gKiBgaXNXZWFrTWFwYCwgYGlzV2Vha1NldGAsIGBqb2luYCwgYGtlYmFiQ2FzZWAsIGBsYXN0YCwgYGxhc3RJbmRleE9mYCxcbiAqIGBsb3dlckNhc2VgLCBgbG93ZXJGaXJzdGAsIGBsdGAsIGBsdGVgLCBgbWF4YCwgYG1heEJ5YCwgYG1lYW5gLCBgbWVhbkJ5YCxcbiAqIGBtaW5gLCBgbWluQnlgLCBgbXVsdGlwbHlgLCBgbm9Db25mbGljdGAsIGBub29wYCwgYG5vd2AsIGBudGhgLCBgcGFkYCxcbiAqIGBwYWRFbmRgLCBgcGFkU3RhcnRgLCBgcGFyc2VJbnRgLCBgcG9wYCwgYHJhbmRvbWAsIGByZWR1Y2VgLCBgcmVkdWNlUmlnaHRgLFxuICogYHJlcGVhdGAsIGByZXN1bHRgLCBgcm91bmRgLCBgcnVuSW5Db250ZXh0YCwgYHNhbXBsZWAsIGBzaGlmdGAsIGBzaXplYCxcbiAqIGBzbmFrZUNhc2VgLCBgc29tZWAsIGBzb3J0ZWRJbmRleGAsIGBzb3J0ZWRJbmRleEJ5YCwgYHNvcnRlZExhc3RJbmRleGAsXG4gKiBgc29ydGVkTGFzdEluZGV4QnlgLCBgc3RhcnRDYXNlYCwgYHN0YXJ0c1dpdGhgLCBgc3R1YkFycmF5YCwgYHN0dWJGYWxzZWAsXG4gKiBgc3R1Yk9iamVjdGAsIGBzdHViU3RyaW5nYCwgYHN0dWJUcnVlYCwgYHN1YnRyYWN0YCwgYHN1bWAsIGBzdW1CeWAsXG4gKiBgdGVtcGxhdGVgLCBgdGltZXNgLCBgdG9GaW5pdGVgLCBgdG9JbnRlZ2VyYCwgYHRvSlNPTmAsIGB0b0xlbmd0aGAsXG4gKiBgdG9Mb3dlcmAsIGB0b051bWJlcmAsIGB0b1NhZmVJbnRlZ2VyYCwgYHRvU3RyaW5nYCwgYHRvVXBwZXJgLCBgdHJpbWAsXG4gKiBgdHJpbUVuZGAsIGB0cmltU3RhcnRgLCBgdHJ1bmNhdGVgLCBgdW5lc2NhcGVgLCBgdW5pcXVlSWRgLCBgdXBwZXJDYXNlYCxcbiAqIGB1cHBlckZpcnN0YCwgYHZhbHVlYCwgYW5kIGB3b3Jkc2BcbiAqXG4gKiBAbmFtZSBfXG4gKiBAY29uc3RydWN0b3JcbiAqIEBjYXRlZ29yeSBTZXFcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHdyYXAgaW4gYSBgbG9kYXNoYCBpbnN0YW5jZS5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgdGhlIG5ldyBgbG9kYXNoYCB3cmFwcGVyIGluc3RhbmNlLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBzcXVhcmUobikge1xuICogICByZXR1cm4gbiAqIG47XG4gKiB9XG4gKlxuICogdmFyIHdyYXBwZWQgPSBfKFsxLCAyLCAzXSk7XG4gKlxuICogLy8gUmV0dXJucyBhbiB1bndyYXBwZWQgdmFsdWUuXG4gKiB3cmFwcGVkLnJlZHVjZShfLmFkZCk7XG4gKiAvLyA9PiA2XG4gKlxuICogLy8gUmV0dXJucyBhIHdyYXBwZWQgdmFsdWUuXG4gKiB2YXIgc3F1YXJlcyA9IHdyYXBwZWQubWFwKHNxdWFyZSk7XG4gKlxuICogXy5pc0FycmF5KHNxdWFyZXMpO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzQXJyYXkoc3F1YXJlcy52YWx1ZSgpKTtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gbG9kYXNoKHZhbHVlKSB7XG4gIGlmIChpc09iamVjdExpa2UodmFsdWUpICYmICFpc0FycmF5KHZhbHVlKSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgTGF6eVdyYXBwZXIpKSB7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgTG9kYXNoV3JhcHBlcikge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ19fd3JhcHBlZF9fJykpIHtcbiAgICAgIHJldHVybiB3cmFwcGVyQ2xvbmUodmFsdWUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbmV3IExvZGFzaFdyYXBwZXIodmFsdWUpO1xufVxuXG4vLyBFbnN1cmUgd3JhcHBlcnMgYXJlIGluc3RhbmNlcyBvZiBgYmFzZUxvZGFzaGAuXG5sb2Rhc2gucHJvdG90eXBlID0gYmFzZUxvZGFzaC5wcm90b3R5cGU7XG5sb2Rhc2gucHJvdG90eXBlLmNvbnN0cnVjdG9yID0gbG9kYXNoO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGxvZGFzaDtcbiIsInZhciBhcnJheUZpbHRlciA9IHJlcXVpcmUoJy4vX2FycmF5RmlsdGVyJyksXG4gICAgYmFzZVJlc3QgPSByZXF1aXJlKCcuL19iYXNlUmVzdCcpLFxuICAgIGJhc2VYb3IgPSByZXF1aXJlKCcuL19iYXNlWG9yJyksXG4gICAgaXNBcnJheUxpa2VPYmplY3QgPSByZXF1aXJlKCcuL2lzQXJyYXlMaWtlT2JqZWN0Jyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzIHRoYXQgaXMgdGhlXG4gKiBbc3ltbWV0cmljIGRpZmZlcmVuY2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1N5bW1ldHJpY19kaWZmZXJlbmNlKVxuICogb2YgdGhlIGdpdmVuIGFycmF5cy4gVGhlIG9yZGVyIG9mIHJlc3VsdCB2YWx1ZXMgaXMgZGV0ZXJtaW5lZCBieSB0aGUgb3JkZXJcbiAqIHRoZXkgb2NjdXIgaW4gdGhlIGFycmF5cy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDIuNC4wXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGZpbHRlcmVkIHZhbHVlcy5cbiAqIEBzZWUgXy5kaWZmZXJlbmNlLCBfLndpdGhvdXRcbiAqIEBleGFtcGxlXG4gKlxuICogXy54b3IoWzIsIDFdLCBbMiwgM10pO1xuICogLy8gPT4gWzEsIDNdXG4gKi9cbnZhciB4b3IgPSBiYXNlUmVzdChmdW5jdGlvbihhcnJheXMpIHtcbiAgcmV0dXJuIGJhc2VYb3IoYXJyYXlGaWx0ZXIoYXJyYXlzLCBpc0FycmF5TGlrZU9iamVjdCkpO1xufSk7XG5cbm1vZHVsZS5leHBvcnRzID0geG9yO1xuIiwiLyoqXG4gKiBGbGF0dGVuIGFycmF5LCBvbmUgbGV2ZWwgZGVlcC5cbiAqXG4gKiBAcGFyYW0ge0FycmF5PD8+fSBhcnJcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTw/Pn1cbiAqL1xuZnVuY3Rpb24gZmxhdHRlbihhcnIpIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBwbHkoW10sIGFycik7XG59XG5cbnZhciBuYXRpdmVUb1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG52YXIgbmF0aXZlSGFzT3duUHJvcGVydHkgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuZnVuY3Rpb24gaXNVbmRlZmluZWQob2JqKSB7XG4gIHJldHVybiBvYmogPT09IHVuZGVmaW5lZDtcbn1cbmZ1bmN0aW9uIGlzRGVmaW5lZChvYmopIHtcbiAgcmV0dXJuIG9iaiAhPT0gdW5kZWZpbmVkO1xufVxuZnVuY3Rpb24gaXNOaWwob2JqKSB7XG4gIHJldHVybiBvYmogPT0gbnVsbDtcbn1cbmZ1bmN0aW9uIGlzQXJyYXkob2JqKSB7XG4gIHJldHVybiBuYXRpdmVUb1N0cmluZy5jYWxsKG9iaikgPT09ICdbb2JqZWN0IEFycmF5XSc7XG59XG5mdW5jdGlvbiBpc09iamVjdChvYmopIHtcbiAgcmV0dXJuIG5hdGl2ZVRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgT2JqZWN0XSc7XG59XG5mdW5jdGlvbiBpc051bWJlcihvYmopIHtcbiAgcmV0dXJuIG5hdGl2ZVRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgTnVtYmVyXSc7XG59XG5mdW5jdGlvbiBpc0Z1bmN0aW9uKG9iaikge1xuICB2YXIgdGFnID0gbmF0aXZlVG9TdHJpbmcuY2FsbChvYmopO1xuICByZXR1cm4gdGFnID09PSAnW29iamVjdCBGdW5jdGlvbl0nIHx8IHRhZyA9PT0gJ1tvYmplY3QgQXN5bmNGdW5jdGlvbl0nIHx8IHRhZyA9PT0gJ1tvYmplY3QgR2VuZXJhdG9yRnVuY3Rpb25dJyB8fCB0YWcgPT09ICdbb2JqZWN0IEFzeW5jR2VuZXJhdG9yRnVuY3Rpb25dJyB8fCB0YWcgPT09ICdbb2JqZWN0IFByb3h5XSc7XG59XG5mdW5jdGlvbiBpc1N0cmluZyhvYmopIHtcbiAgcmV0dXJuIG5hdGl2ZVRvU3RyaW5nLmNhbGwob2JqKSA9PT0gJ1tvYmplY3QgU3RyaW5nXSc7XG59XG4vKipcbiAqIEVuc3VyZSBjb2xsZWN0aW9uIGlzIGFuIGFycmF5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAqL1xuXG5mdW5jdGlvbiBlbnN1cmVBcnJheShvYmopIHtcbiAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcignbXVzdCBzdXBwbHkgYXJyYXknKTtcbn1cbi8qKlxuICogUmV0dXJuIHRydWUsIGlmIHRhcmdldCBvd25zIGEgcHJvcGVydHkgd2l0aCB0aGUgZ2l2ZW4ga2V5LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7U3RyaW5nfSBrZXlcbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmZ1bmN0aW9uIGhhcyh0YXJnZXQsIGtleSkge1xuICByZXR1cm4gbmF0aXZlSGFzT3duUHJvcGVydHkuY2FsbCh0YXJnZXQsIGtleSk7XG59XG5cbi8qKlxuICogRmluZCBlbGVtZW50IGluIGNvbGxlY3Rpb24uXG4gKlxuICogQHBhcmFtICB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uXG4gKiBAcGFyYW0gIHtGdW5jdGlvbnxPYmplY3R9IG1hdGNoZXJcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9XG4gKi9cblxuZnVuY3Rpb24gZmluZChjb2xsZWN0aW9uLCBtYXRjaGVyKSB7XG4gIG1hdGNoZXIgPSB0b01hdGNoZXIobWF0Y2hlcik7XG4gIHZhciBtYXRjaDtcbiAgZm9yRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICBpZiAobWF0Y2hlcih2YWwsIGtleSkpIHtcbiAgICAgIG1hdGNoID0gdmFsO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBtYXRjaDtcbn1cbi8qKlxuICogRmluZCBlbGVtZW50IGluZGV4IGluIGNvbGxlY3Rpb24uXG4gKlxuICogQHBhcmFtICB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gbWF0Y2hlclxuICpcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuXG5mdW5jdGlvbiBmaW5kSW5kZXgoY29sbGVjdGlvbiwgbWF0Y2hlcikge1xuICBtYXRjaGVyID0gdG9NYXRjaGVyKG1hdGNoZXIpO1xuICB2YXIgaWR4ID0gaXNBcnJheShjb2xsZWN0aW9uKSA/IC0xIDogdW5kZWZpbmVkO1xuICBmb3JFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWwsIGtleSkge1xuICAgIGlmIChtYXRjaGVyKHZhbCwga2V5KSkge1xuICAgICAgaWR4ID0ga2V5O1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBpZHg7XG59XG4vKipcbiAqIEZpbmQgZWxlbWVudCBpbiBjb2xsZWN0aW9uLlxuICpcbiAqIEBwYXJhbSAge0FycmF5fE9iamVjdH0gY29sbGVjdGlvblxuICogQHBhcmFtICB7RnVuY3Rpb259IG1hdGNoZXJcbiAqXG4gKiBAcmV0dXJuIHtBcnJheX0gcmVzdWx0XG4gKi9cblxuZnVuY3Rpb24gZmlsdGVyKGNvbGxlY3Rpb24sIG1hdGNoZXIpIHtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3JFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWwsIGtleSkge1xuICAgIGlmIChtYXRjaGVyKHZhbCwga2V5KSkge1xuICAgICAgcmVzdWx0LnB1c2godmFsKTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuLyoqXG4gKiBJdGVyYXRlIG92ZXIgY29sbGVjdGlvbjsgcmV0dXJuaW5nIHNvbWV0aGluZ1xuICogKG5vbi11bmRlZmluZWQpIHdpbGwgc3RvcCBpdGVyYXRpb24uXG4gKlxuICogQHBhcmFtICB7QXJyYXl8T2JqZWN0fSBjb2xsZWN0aW9uXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gaXRlcmF0b3JcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHJldHVybiByZXN1bHQgdGhhdCBzdG9wcGVkIHRoZSBpdGVyYXRpb25cbiAqL1xuXG5mdW5jdGlvbiBmb3JFYWNoKGNvbGxlY3Rpb24sIGl0ZXJhdG9yKSB7XG4gIHZhciB2YWwsIHJlc3VsdDtcblxuICBpZiAoaXNVbmRlZmluZWQoY29sbGVjdGlvbikpIHtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgY29udmVydEtleSA9IGlzQXJyYXkoY29sbGVjdGlvbikgPyB0b051bSA6IGlkZW50aXR5O1xuXG4gIGZvciAodmFyIGtleSBpbiBjb2xsZWN0aW9uKSB7XG4gICAgaWYgKGhhcyhjb2xsZWN0aW9uLCBrZXkpKSB7XG4gICAgICB2YWwgPSBjb2xsZWN0aW9uW2tleV07XG4gICAgICByZXN1bHQgPSBpdGVyYXRvcih2YWwsIGNvbnZlcnRLZXkoa2V5KSk7XG5cbiAgICAgIGlmIChyZXN1bHQgPT09IGZhbHNlKSB7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4vKipcbiAqIFJldHVybiBjb2xsZWN0aW9uIHdpdGhvdXQgZWxlbWVudC5cbiAqXG4gKiBAcGFyYW0gIHtBcnJheX0gYXJyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gbWF0Y2hlclxuICpcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5cbmZ1bmN0aW9uIHdpdGhvdXQoYXJyLCBtYXRjaGVyKSB7XG4gIGlmIChpc1VuZGVmaW5lZChhcnIpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgZW5zdXJlQXJyYXkoYXJyKTtcbiAgbWF0Y2hlciA9IHRvTWF0Y2hlcihtYXRjaGVyKTtcbiAgcmV0dXJuIGFyci5maWx0ZXIoZnVuY3Rpb24gKGVsLCBpZHgpIHtcbiAgICByZXR1cm4gIW1hdGNoZXIoZWwsIGlkeCk7XG4gIH0pO1xufVxuLyoqXG4gKiBSZWR1Y2UgY29sbGVjdGlvbiwgcmV0dXJuaW5nIGEgc2luZ2xlIHJlc3VsdC5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R8QXJyYXl9IGNvbGxlY3Rpb25cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBpdGVyYXRvclxuICogQHBhcmFtICB7QW55fSByZXN1bHRcbiAqXG4gKiBAcmV0dXJuIHtBbnl9IHJlc3VsdCByZXR1cm5lZCBmcm9tIGxhc3QgaXRlcmF0b3JcbiAqL1xuXG5mdW5jdGlvbiByZWR1Y2UoY29sbGVjdGlvbiwgaXRlcmF0b3IsIHJlc3VsdCkge1xuICBmb3JFYWNoKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWx1ZSwgaWR4KSB7XG4gICAgcmVzdWx0ID0gaXRlcmF0b3IocmVzdWx0LCB2YWx1ZSwgaWR4KTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG4vKipcbiAqIFJldHVybiB0cnVlIGlmIGV2ZXJ5IGVsZW1lbnQgaW4gdGhlIGNvbGxlY3Rpb25cbiAqIG1hdGNoZXMgdGhlIGNyaXRlcmlhLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheX0gY29sbGVjdGlvblxuICogQHBhcmFtICB7RnVuY3Rpb259IG1hdGNoZXJcbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmZ1bmN0aW9uIGV2ZXJ5KGNvbGxlY3Rpb24sIG1hdGNoZXIpIHtcbiAgcmV0dXJuICEhcmVkdWNlKGNvbGxlY3Rpb24sIGZ1bmN0aW9uIChtYXRjaGVzLCB2YWwsIGtleSkge1xuICAgIHJldHVybiBtYXRjaGVzICYmIG1hdGNoZXIodmFsLCBrZXkpO1xuICB9LCB0cnVlKTtcbn1cbi8qKlxuICogUmV0dXJuIHRydWUgaWYgc29tZSBlbGVtZW50cyBpbiB0aGUgY29sbGVjdGlvblxuICogbWF0Y2ggdGhlIGNyaXRlcmlhLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheX0gY29sbGVjdGlvblxuICogQHBhcmFtICB7RnVuY3Rpb259IG1hdGNoZXJcbiAqXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICovXG5cbmZ1bmN0aW9uIHNvbWUoY29sbGVjdGlvbiwgbWF0Y2hlcikge1xuICByZXR1cm4gISFmaW5kKGNvbGxlY3Rpb24sIG1hdGNoZXIpO1xufVxuLyoqXG4gKiBUcmFuc2Zvcm0gYSBjb2xsZWN0aW9uIGludG8gYW5vdGhlciBjb2xsZWN0aW9uXG4gKiBieSBwaXBpbmcgZWFjaCBtZW1iZXIgdGhyb3VnaCB0aGUgZ2l2ZW4gZm4uXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fEFycmF5fSAgIGNvbGxlY3Rpb25cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmblxuICpcbiAqIEByZXR1cm4ge0FycmF5fSB0cmFuc2Zvcm1lZCBjb2xsZWN0aW9uXG4gKi9cblxuZnVuY3Rpb24gbWFwKGNvbGxlY3Rpb24sIGZuKSB7XG4gIHZhciByZXN1bHQgPSBbXTtcbiAgZm9yRWFjaChjb2xsZWN0aW9uLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICByZXN1bHQucHVzaChmbih2YWwsIGtleSkpO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogR2V0IHRoZSBjb2xsZWN0aW9ucyBrZXlzLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheX0gY29sbGVjdGlvblxuICpcbiAqIEByZXR1cm4ge0FycmF5fVxuICovXG5cbmZ1bmN0aW9uIGtleXMoY29sbGVjdGlvbikge1xuICByZXR1cm4gY29sbGVjdGlvbiAmJiBPYmplY3Qua2V5cyhjb2xsZWN0aW9uKSB8fCBbXTtcbn1cbi8qKlxuICogU2hvcnRoYW5kIGZvciBga2V5cyhvKS5sZW5ndGhgLlxuICpcbiAqIEBwYXJhbSAge09iamVjdHxBcnJheX0gY29sbGVjdGlvblxuICpcbiAqIEByZXR1cm4ge051bWJlcn1cbiAqL1xuXG5mdW5jdGlvbiBzaXplKGNvbGxlY3Rpb24pIHtcbiAgcmV0dXJuIGtleXMoY29sbGVjdGlvbikubGVuZ3RoO1xufVxuLyoqXG4gKiBHZXQgdGhlIHZhbHVlcyBpbiB0aGUgY29sbGVjdGlvbi5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R8QXJyYXl9IGNvbGxlY3Rpb25cbiAqXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqL1xuXG5mdW5jdGlvbiB2YWx1ZXMoY29sbGVjdGlvbikge1xuICByZXR1cm4gbWFwKGNvbGxlY3Rpb24sIGZ1bmN0aW9uICh2YWwpIHtcbiAgICByZXR1cm4gdmFsO1xuICB9KTtcbn1cbi8qKlxuICogR3JvdXAgY29sbGVjdGlvbiBtZW1iZXJzIGJ5IGF0dHJpYnV0ZS5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R8QXJyYXl9IGNvbGxlY3Rpb25cbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBleHRyYWN0b3JcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IG1hcCB3aXRoIHsgYXR0clZhbHVlID0+IFsgYSwgYiwgYyBdIH1cbiAqL1xuXG5mdW5jdGlvbiBncm91cEJ5KGNvbGxlY3Rpb24sIGV4dHJhY3Rvcikge1xuICB2YXIgZ3JvdXBlZCA9IGFyZ3VtZW50cy5sZW5ndGggPiAyICYmIGFyZ3VtZW50c1syXSAhPT0gdW5kZWZpbmVkID8gYXJndW1lbnRzWzJdIDoge307XG4gIGV4dHJhY3RvciA9IHRvRXh0cmFjdG9yKGV4dHJhY3Rvcik7XG4gIGZvckVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24gKHZhbCkge1xuICAgIHZhciBkaXNjcmltaW5hdG9yID0gZXh0cmFjdG9yKHZhbCkgfHwgJ18nO1xuICAgIHZhciBncm91cCA9IGdyb3VwZWRbZGlzY3JpbWluYXRvcl07XG5cbiAgICBpZiAoIWdyb3VwKSB7XG4gICAgICBncm91cCA9IGdyb3VwZWRbZGlzY3JpbWluYXRvcl0gPSBbXTtcbiAgICB9XG5cbiAgICBncm91cC5wdXNoKHZhbCk7XG4gIH0pO1xuICByZXR1cm4gZ3JvdXBlZDtcbn1cbmZ1bmN0aW9uIHVuaXF1ZUJ5KGV4dHJhY3Rvcikge1xuICBleHRyYWN0b3IgPSB0b0V4dHJhY3RvcihleHRyYWN0b3IpO1xuICB2YXIgZ3JvdXBlZCA9IHt9O1xuXG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBjb2xsZWN0aW9ucyA9IG5ldyBBcnJheShfbGVuID4gMSA/IF9sZW4gLSAxIDogMCksIF9rZXkgPSAxOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgY29sbGVjdGlvbnNbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICB9XG5cbiAgZm9yRWFjaChjb2xsZWN0aW9ucywgZnVuY3Rpb24gKGMpIHtcbiAgICByZXR1cm4gZ3JvdXBCeShjLCBleHRyYWN0b3IsIGdyb3VwZWQpO1xuICB9KTtcbiAgdmFyIHJlc3VsdCA9IG1hcChncm91cGVkLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICByZXR1cm4gdmFsWzBdO1xuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbnZhciB1bmlvbkJ5ID0gdW5pcXVlQnk7XG4vKipcbiAqIFNvcnQgY29sbGVjdGlvbiBieSBjcml0ZXJpYS5cbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R8QXJyYXl9IGNvbGxlY3Rpb25cbiAqIEBwYXJhbSAge1N0cmluZ3xGdW5jdGlvbn0gZXh0cmFjdG9yXG4gKlxuICogQHJldHVybiB7QXJyYXl9XG4gKi9cblxuZnVuY3Rpb24gc29ydEJ5KGNvbGxlY3Rpb24sIGV4dHJhY3Rvcikge1xuICBleHRyYWN0b3IgPSB0b0V4dHJhY3RvcihleHRyYWN0b3IpO1xuICB2YXIgc29ydGVkID0gW107XG4gIGZvckVhY2goY29sbGVjdGlvbiwgZnVuY3Rpb24gKHZhbHVlLCBrZXkpIHtcbiAgICB2YXIgZGlzYyA9IGV4dHJhY3Rvcih2YWx1ZSwga2V5KTtcbiAgICB2YXIgZW50cnkgPSB7XG4gICAgICBkOiBkaXNjLFxuICAgICAgdjogdmFsdWVcbiAgICB9O1xuXG4gICAgZm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgc29ydGVkLmxlbmd0aDsgaWR4KyspIHtcbiAgICAgIHZhciBkID0gc29ydGVkW2lkeF0uZDtcblxuICAgICAgaWYgKGRpc2MgPCBkKSB7XG4gICAgICAgIHNvcnRlZC5zcGxpY2UoaWR4LCAwLCBlbnRyeSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9IC8vIG5vdCBpbnNlcnRlZCwgYXBwZW5kICghKVxuXG5cbiAgICBzb3J0ZWQucHVzaChlbnRyeSk7XG4gIH0pO1xuICByZXR1cm4gbWFwKHNvcnRlZCwgZnVuY3Rpb24gKGUpIHtcbiAgICByZXR1cm4gZS52O1xuICB9KTtcbn1cbi8qKlxuICogQ3JlYXRlIGFuIG9iamVjdCBwYXR0ZXJuIG1hdGNoZXIuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBjb25zdCBtYXRjaGVyID0gbWF0Y2hQYXR0ZXJuKHsgaWQ6IDEgfSk7XG4gKlxuICogdmFyIGVsZW1lbnQgPSBmaW5kKGVsZW1lbnRzLCBtYXRjaGVyKTtcbiAqXG4gKiBAcGFyYW0gIHtPYmplY3R9IHBhdHRlcm5cbiAqXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn0gbWF0Y2hlckZuXG4gKi9cblxuZnVuY3Rpb24gbWF0Y2hQYXR0ZXJuKHBhdHRlcm4pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChlbCkge1xuICAgIHJldHVybiBldmVyeShwYXR0ZXJuLCBmdW5jdGlvbiAodmFsLCBrZXkpIHtcbiAgICAgIHJldHVybiBlbFtrZXldID09PSB2YWw7XG4gICAgfSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHRvRXh0cmFjdG9yKGV4dHJhY3Rvcikge1xuICByZXR1cm4gaXNGdW5jdGlvbihleHRyYWN0b3IpID8gZXh0cmFjdG9yIDogZnVuY3Rpb24gKGUpIHtcbiAgICByZXR1cm4gZVtleHRyYWN0b3JdO1xuICB9O1xufVxuXG5mdW5jdGlvbiB0b01hdGNoZXIobWF0Y2hlcikge1xuICByZXR1cm4gaXNGdW5jdGlvbihtYXRjaGVyKSA/IG1hdGNoZXIgOiBmdW5jdGlvbiAoZSkge1xuICAgIHJldHVybiBlID09PSBtYXRjaGVyO1xuICB9O1xufVxuXG5mdW5jdGlvbiBpZGVudGl0eShhcmcpIHtcbiAgcmV0dXJuIGFyZztcbn1cblxuZnVuY3Rpb24gdG9OdW0oYXJnKSB7XG4gIHJldHVybiBOdW1iZXIoYXJnKTtcbn1cblxuLyoqXG4gKiBEZWJvdW5jZSBmbiwgY2FsbGluZyBpdCBvbmx5IG9uY2UgaWZcbiAqIHRoZSBnaXZlbiB0aW1lIGVsYXBzZWQgYmV0d2VlbiBjYWxscy5cbiAqXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gZm5cbiAqIEBwYXJhbSAge051bWJlcn0gdGltZW91dFxuICpcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBkZWJvdW5jZWQgZnVuY3Rpb25cbiAqL1xuZnVuY3Rpb24gZGVib3VuY2UoZm4sIHRpbWVvdXQpIHtcbiAgdmFyIHRpbWVyO1xuICB2YXIgbGFzdEFyZ3M7XG4gIHZhciBsYXN0VGhpcztcbiAgdmFyIGxhc3ROb3c7XG5cbiAgZnVuY3Rpb24gZmlyZSgpIHtcbiAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcbiAgICB2YXIgc2NoZWR1bGVkRGlmZiA9IGxhc3ROb3cgKyB0aW1lb3V0IC0gbm93O1xuXG4gICAgaWYgKHNjaGVkdWxlZERpZmYgPiAwKSB7XG4gICAgICByZXR1cm4gc2NoZWR1bGUoc2NoZWR1bGVkRGlmZik7XG4gICAgfVxuXG4gICAgZm4uYXBwbHkobGFzdFRoaXMsIGxhc3RBcmdzKTtcbiAgICB0aW1lciA9IGxhc3ROb3cgPSBsYXN0QXJncyA9IGxhc3RUaGlzID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NoZWR1bGUodGltZW91dCkge1xuICAgIHRpbWVyID0gc2V0VGltZW91dChmaXJlLCB0aW1lb3V0KTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgbGFzdE5vdyA9IERhdGUubm93KCk7XG5cbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IG5ldyBBcnJheShfbGVuKSwgX2tleSA9IDA7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGFyZ3NbX2tleV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgfVxuXG4gICAgbGFzdEFyZ3MgPSBhcmdzO1xuICAgIGxhc3RUaGlzID0gdGhpczsgLy8gZW5zdXJlIGFuIGV4ZWN1dGlvbiBpcyBzY2hlZHVsZWRcblxuICAgIGlmICghdGltZXIpIHtcbiAgICAgIHNjaGVkdWxlKHRpbWVvdXQpO1xuICAgIH1cbiAgfTtcbn1cbi8qKlxuICogVGhyb3R0bGUgZm4sIGNhbGxpbmcgYXQgbW9zdCBvbmNlXG4gKiBpbiB0aGUgZ2l2ZW4gaW50ZXJ2YWwuXG4gKlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0gIHtOdW1iZXJ9IGludGVydmFsXG4gKlxuICogQHJldHVybiB7RnVuY3Rpb259IHRocm90dGxlZCBmdW5jdGlvblxuICovXG5cbmZ1bmN0aW9uIHRocm90dGxlKGZuLCBpbnRlcnZhbCkge1xuICB2YXIgdGhyb3R0bGluZyA9IGZhbHNlO1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aHJvdHRsaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm4uYXBwbHkodm9pZCAwLCBhcmd1bWVudHMpO1xuICAgIHRocm90dGxpbmcgPSB0cnVlO1xuICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgdGhyb3R0bGluZyA9IGZhbHNlO1xuICAgIH0sIGludGVydmFsKTtcbiAgfTtcbn1cbi8qKlxuICogQmluZCBmdW5jdGlvbiBhZ2FpbnN0IHRhcmdldCA8dGhpcz4uXG4gKlxuICogQHBhcmFtICB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0gIHtPYmplY3R9ICAgdGFyZ2V0XG4gKlxuICogQHJldHVybiB7RnVuY3Rpb259IGJvdW5kIGZ1bmN0aW9uXG4gKi9cblxuZnVuY3Rpb24gYmluZChmbiwgdGFyZ2V0KSB7XG4gIHJldHVybiBmbi5iaW5kKHRhcmdldCk7XG59XG5cbmZ1bmN0aW9uIF9leHRlbmRzKCkge1xuICBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkge1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuXG4gICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XG4gICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7XG4gICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0YXJnZXQ7XG4gIH07XG5cbiAgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbi8qKlxuICogQ29udmVuaWVuY2Ugd3JhcHBlciBmb3IgYE9iamVjdC5hc3NpZ25gLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7Li4uT2JqZWN0fSBvdGhlcnNcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSB0YXJnZXRcbiAqL1xuXG5mdW5jdGlvbiBhc3NpZ24odGFyZ2V0KSB7XG4gIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBvdGhlcnMgPSBuZXcgQXJyYXkoX2xlbiA+IDEgPyBfbGVuIC0gMSA6IDApLCBfa2V5ID0gMTsgX2tleSA8IF9sZW47IF9rZXkrKykge1xuICAgIG90aGVyc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gIH1cblxuICByZXR1cm4gX2V4dGVuZHMuYXBwbHkodm9pZCAwLCBbdGFyZ2V0XS5jb25jYXQob3RoZXJzKSk7XG59XG4vKipcbiAqIFBpY2sgZ2l2ZW4gcHJvcGVydGllcyBmcm9tIHRoZSB0YXJnZXQgb2JqZWN0LlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSB7QXJyYXl9IHByb3BlcnRpZXNcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRhcmdldFxuICovXG5cbmZ1bmN0aW9uIHBpY2sodGFyZ2V0LCBwcm9wZXJ0aWVzKSB7XG4gIHZhciByZXN1bHQgPSB7fTtcbiAgdmFyIG9iaiA9IE9iamVjdCh0YXJnZXQpO1xuICBmb3JFYWNoKHByb3BlcnRpZXMsIGZ1bmN0aW9uIChwcm9wKSB7XG4gICAgaWYgKHByb3AgaW4gb2JqKSB7XG4gICAgICByZXN1bHRbcHJvcF0gPSB0YXJnZXRbcHJvcF07XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogUGljayBhbGwgdGFyZ2V0IHByb3BlcnRpZXMsIGV4Y2x1ZGluZyB0aGUgZ2l2ZW4gb25lcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0ge0FycmF5fSBwcm9wZXJ0aWVzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB0YXJnZXRcbiAqL1xuXG5mdW5jdGlvbiBvbWl0KHRhcmdldCwgcHJvcGVydGllcykge1xuICB2YXIgcmVzdWx0ID0ge307XG4gIHZhciBvYmogPSBPYmplY3QodGFyZ2V0KTtcbiAgZm9yRWFjaChvYmosIGZ1bmN0aW9uIChwcm9wLCBrZXkpIHtcbiAgICBpZiAocHJvcGVydGllcy5pbmRleE9mKGtleSkgPT09IC0xKSB7XG4gICAgICByZXN1bHRba2V5XSA9IHByb3A7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn1cbi8qKlxuICogUmVjdXJzaXZlbHkgbWVyZ2UgYC4uLnNvdXJjZXNgIGludG8gZ2l2ZW4gdGFyZ2V0LlxuICpcbiAqIERvZXMgc3VwcG9ydCBtZXJnaW5nIG9iamVjdHM7IGRvZXMgbm90IHN1cHBvcnQgbWVyZ2luZyBhcnJheXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IHRhcmdldFxuICogQHBhcmFtIHsuLi5PYmplY3R9IHNvdXJjZXNcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSB0YXJnZXRcbiAqL1xuXG5mdW5jdGlvbiBtZXJnZSh0YXJnZXQpIHtcbiAgZm9yICh2YXIgX2xlbjIgPSBhcmd1bWVudHMubGVuZ3RoLCBzb3VyY2VzID0gbmV3IEFycmF5KF9sZW4yID4gMSA/IF9sZW4yIC0gMSA6IDApLCBfa2V5MiA9IDE7IF9rZXkyIDwgX2xlbjI7IF9rZXkyKyspIHtcbiAgICBzb3VyY2VzW19rZXkyIC0gMV0gPSBhcmd1bWVudHNbX2tleTJdO1xuICB9XG5cbiAgaWYgKCFzb3VyY2VzLmxlbmd0aCkge1xuICAgIHJldHVybiB0YXJnZXQ7XG4gIH1cblxuICBmb3JFYWNoKHNvdXJjZXMsIGZ1bmN0aW9uIChzb3VyY2UpIHtcbiAgICAvLyBza2lwIG5vbi1vYmogc291cmNlcywgaS5lLiBudWxsXG4gICAgaWYgKCFzb3VyY2UgfHwgIWlzT2JqZWN0KHNvdXJjZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBmb3JFYWNoKHNvdXJjZSwgZnVuY3Rpb24gKHNvdXJjZVZhbCwga2V5KSB7XG4gICAgICBpZiAoa2V5ID09PSAnX19wcm90b19fJykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHZhciB0YXJnZXRWYWwgPSB0YXJnZXRba2V5XTtcblxuICAgICAgaWYgKGlzT2JqZWN0KHNvdXJjZVZhbCkpIHtcbiAgICAgICAgaWYgKCFpc09iamVjdCh0YXJnZXRWYWwpKSB7XG4gICAgICAgICAgLy8gb3ZlcnJpZGUgdGFyZ2V0W2tleV0gd2l0aCBvYmplY3RcbiAgICAgICAgICB0YXJnZXRWYWwgPSB7fTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRhcmdldFtrZXldID0gbWVyZ2UodGFyZ2V0VmFsLCBzb3VyY2VWYWwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2VWYWw7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xuICByZXR1cm4gdGFyZ2V0O1xufVxuXG5leHBvcnQgeyBmbGF0dGVuLCBmaW5kLCBmaW5kSW5kZXgsIGZpbHRlciwgZm9yRWFjaCwgd2l0aG91dCwgcmVkdWNlLCBldmVyeSwgc29tZSwgbWFwLCBrZXlzLCBzaXplLCB2YWx1ZXMsIGdyb3VwQnksIHVuaXF1ZUJ5LCB1bmlvbkJ5LCBzb3J0QnksIG1hdGNoUGF0dGVybiwgZGVib3VuY2UsIHRocm90dGxlLCBiaW5kLCBpc1VuZGVmaW5lZCwgaXNEZWZpbmVkLCBpc05pbCwgaXNBcnJheSwgaXNPYmplY3QsIGlzTnVtYmVyLCBpc0Z1bmN0aW9uLCBpc1N0cmluZywgZW5zdXJlQXJyYXksIGhhcywgYXNzaWduLCBwaWNrLCBvbWl0LCBtZXJnZSB9O1xuIiwiLyoqXG4gKiBTZXQgYXR0cmlidXRlIGBuYW1lYCB0byBgdmFsYCwgb3IgZ2V0IGF0dHIgYG5hbWVgLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0ge1N0cmluZ30gW3ZhbF1cbiAqIEBhcGkgcHVibGljXG4gKi9cbmZ1bmN0aW9uIGF0dHIoZWwsIG5hbWUsIHZhbCkge1xuICAvLyBnZXRcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT0gMikge1xuICAgIHJldHVybiBlbC5nZXRBdHRyaWJ1dGUobmFtZSk7XG4gIH1cblxuICAvLyByZW1vdmVcbiAgaWYgKHZhbCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBlbC5yZW1vdmVBdHRyaWJ1dGUobmFtZSk7XG4gIH1cblxuICAvLyBzZXRcbiAgZWwuc2V0QXR0cmlidXRlKG5hbWUsIHZhbCk7XG5cbiAgcmV0dXJuIGVsO1xufVxuXG52YXIgaW5kZXhPZiA9IFtdLmluZGV4T2Y7XG5cbnZhciBpbmRleG9mID0gZnVuY3Rpb24oYXJyLCBvYmope1xuICBpZiAoaW5kZXhPZikgcmV0dXJuIGFyci5pbmRleE9mKG9iaik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgaWYgKGFycltpXSA9PT0gb2JqKSByZXR1cm4gaTtcbiAgfVxuICByZXR1cm4gLTE7XG59O1xuXG4vKipcbiAqIFRha2VuIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2NvbXBvbmVudC9jbGFzc2VzXG4gKlxuICogV2l0aG91dCB0aGUgY29tcG9uZW50IGJpdHMuXG4gKi9cblxuLyoqXG4gKiBXaGl0ZXNwYWNlIHJlZ2V4cC5cbiAqL1xuXG52YXIgcmUgPSAvXFxzKy87XG5cbi8qKlxuICogdG9TdHJpbmcgcmVmZXJlbmNlLlxuICovXG5cbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKlxuICogV3JhcCBgZWxgIGluIGEgYENsYXNzTGlzdGAuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBjbGFzc2VzKGVsKSB7XG4gIHJldHVybiBuZXcgQ2xhc3NMaXN0KGVsKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIGEgbmV3IENsYXNzTGlzdCBmb3IgYGVsYC5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBDbGFzc0xpc3QoZWwpIHtcbiAgaWYgKCFlbCB8fCAhZWwubm9kZVR5cGUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgRE9NIGVsZW1lbnQgcmVmZXJlbmNlIGlzIHJlcXVpcmVkJyk7XG4gIH1cbiAgdGhpcy5lbCA9IGVsO1xuICB0aGlzLmxpc3QgPSBlbC5jbGFzc0xpc3Q7XG59XG5cbi8qKlxuICogQWRkIGNsYXNzIGBuYW1lYCBpZiBub3QgYWxyZWFkeSBwcmVzZW50LlxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gKiBAcmV0dXJuIHtDbGFzc0xpc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkNsYXNzTGlzdC5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgLy8gY2xhc3NMaXN0XG4gIGlmICh0aGlzLmxpc3QpIHtcbiAgICB0aGlzLmxpc3QuYWRkKG5hbWUpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZmFsbGJhY2tcbiAgdmFyIGFyciA9IHRoaXMuYXJyYXkoKTtcbiAgdmFyIGkgPSBpbmRleG9mKGFyciwgbmFtZSk7XG4gIGlmICghfmkpIGFyci5wdXNoKG5hbWUpO1xuICB0aGlzLmVsLmNsYXNzTmFtZSA9IGFyci5qb2luKCcgJyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZW1vdmUgY2xhc3MgYG5hbWVgIHdoZW4gcHJlc2VudCwgb3JcbiAqIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gcmVtb3ZlXG4gKiBhbnkgd2hpY2ggbWF0Y2guXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBuYW1lXG4gKiBAcmV0dXJuIHtDbGFzc0xpc3R9XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbkNsYXNzTGlzdC5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgaWYgKCdbb2JqZWN0IFJlZ0V4cF0nID09IHRvU3RyaW5nLmNhbGwobmFtZSkpIHtcbiAgICByZXR1cm4gdGhpcy5yZW1vdmVNYXRjaGluZyhuYW1lKTtcbiAgfVxuXG4gIC8vIGNsYXNzTGlzdFxuICBpZiAodGhpcy5saXN0KSB7XG4gICAgdGhpcy5saXN0LnJlbW92ZShuYW1lKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8vIGZhbGxiYWNrXG4gIHZhciBhcnIgPSB0aGlzLmFycmF5KCk7XG4gIHZhciBpID0gaW5kZXhvZihhcnIsIG5hbWUpO1xuICBpZiAofmkpIGFyci5zcGxpY2UoaSwgMSk7XG4gIHRoaXMuZWwuY2xhc3NOYW1lID0gYXJyLmpvaW4oJyAnKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBhbGwgY2xhc3NlcyBtYXRjaGluZyBgcmVgLlxuICpcbiAqIEBwYXJhbSB7UmVnRXhwfSByZVxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxuICogQGFwaSBwcml2YXRlXG4gKi9cblxuQ2xhc3NMaXN0LnByb3RvdHlwZS5yZW1vdmVNYXRjaGluZyA9IGZ1bmN0aW9uIChyZSkge1xuICB2YXIgYXJyID0gdGhpcy5hcnJheSgpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgIGlmIChyZS50ZXN0KGFycltpXSkpIHtcbiAgICAgIHRoaXMucmVtb3ZlKGFycltpXSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBUb2dnbGUgY2xhc3MgYG5hbWVgLCBjYW4gZm9yY2Ugc3RhdGUgdmlhIGBmb3JjZWAuXG4gKlxuICogRm9yIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBjbGFzc0xpc3QsIGJ1dCBkbyBub3Qgc3VwcG9ydCBgZm9yY2VgIHlldCxcbiAqIHRoZSBtaXN0YWtlIHdpbGwgYmUgZGV0ZWN0ZWQgYW5kIGNvcnJlY3RlZC5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtCb29sZWFufSBmb3JjZVxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5DbGFzc0xpc3QucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uIChuYW1lLCBmb3JjZSkge1xuICAvLyBjbGFzc0xpc3RcbiAgaWYgKHRoaXMubGlzdCkge1xuICAgIGlmICgndW5kZWZpbmVkJyAhPT0gdHlwZW9mIGZvcmNlKSB7XG4gICAgICBpZiAoZm9yY2UgIT09IHRoaXMubGlzdC50b2dnbGUobmFtZSwgZm9yY2UpKSB7XG4gICAgICAgIHRoaXMubGlzdC50b2dnbGUobmFtZSk7IC8vIHRvZ2dsZSBhZ2FpbiB0byBjb3JyZWN0XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubGlzdC50b2dnbGUobmFtZSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLy8gZmFsbGJhY2tcbiAgaWYgKCd1bmRlZmluZWQnICE9PSB0eXBlb2YgZm9yY2UpIHtcbiAgICBpZiAoIWZvcmNlKSB7XG4gICAgICB0aGlzLnJlbW92ZShuYW1lKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hZGQobmFtZSk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmICh0aGlzLmhhcyhuYW1lKSkge1xuICAgICAgdGhpcy5yZW1vdmUobmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYWRkKG5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gYW4gYXJyYXkgb2YgY2xhc3Nlcy5cbiAqXG4gKiBAcmV0dXJuIHtBcnJheX1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuQ2xhc3NMaXN0LnByb3RvdHlwZS5hcnJheSA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIGNsYXNzTmFtZSA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpIHx8ICcnO1xuICB2YXIgc3RyID0gY2xhc3NOYW1lLnJlcGxhY2UoL15cXHMrfFxccyskL2csICcnKTtcbiAgdmFyIGFyciA9IHN0ci5zcGxpdChyZSk7XG4gIGlmICgnJyA9PT0gYXJyWzBdKSBhcnIuc2hpZnQoKTtcbiAgcmV0dXJuIGFycjtcbn07XG5cbi8qKlxuICogQ2hlY2sgaWYgY2xhc3MgYG5hbWVgIGlzIHByZXNlbnQuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcbiAqIEByZXR1cm4ge0NsYXNzTGlzdH1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxuQ2xhc3NMaXN0LnByb3RvdHlwZS5oYXMgPSBDbGFzc0xpc3QucHJvdG90eXBlLmNvbnRhaW5zID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgcmV0dXJuIHRoaXMubGlzdCA/IHRoaXMubGlzdC5jb250YWlucyhuYW1lKSA6ICEhfmluZGV4b2YodGhpcy5hcnJheSgpLCBuYW1lKTtcbn07XG5cbi8qKlxuICogUmVtb3ZlIGFsbCBjaGlsZHJlbiBmcm9tIHRoZSBnaXZlbiBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBjbGVhcihlbCkge1xuXG4gIHZhciBjO1xuXG4gIHdoaWxlIChlbC5jaGlsZE5vZGVzLmxlbmd0aCkge1xuICAgIGMgPSBlbC5jaGlsZE5vZGVzWzBdO1xuICAgIGVsLnJlbW92ZUNoaWxkKGMpO1xuICB9XG5cbiAgcmV0dXJuIGVsO1xufVxuXG52YXIgcHJvdG8gPSB0eXBlb2YgRWxlbWVudCAhPT0gJ3VuZGVmaW5lZCcgPyBFbGVtZW50LnByb3RvdHlwZSA6IHt9O1xudmFyIHZlbmRvciA9IHByb3RvLm1hdGNoZXNcbiAgfHwgcHJvdG8ubWF0Y2hlc1NlbGVjdG9yXG4gIHx8IHByb3RvLndlYmtpdE1hdGNoZXNTZWxlY3RvclxuICB8fCBwcm90by5tb3pNYXRjaGVzU2VsZWN0b3JcbiAgfHwgcHJvdG8ubXNNYXRjaGVzU2VsZWN0b3JcbiAgfHwgcHJvdG8ub01hdGNoZXNTZWxlY3RvcjtcblxudmFyIG1hdGNoZXNTZWxlY3RvciA9IG1hdGNoO1xuXG4vKipcbiAqIE1hdGNoIGBlbGAgdG8gYHNlbGVjdG9yYC5cbiAqXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGVsXG4gKiBAcGFyYW0ge1N0cmluZ30gc2VsZWN0b3JcbiAqIEByZXR1cm4ge0Jvb2xlYW59XG4gKiBAYXBpIHB1YmxpY1xuICovXG5cbmZ1bmN0aW9uIG1hdGNoKGVsLCBzZWxlY3Rvcikge1xuICBpZiAoIWVsIHx8IGVsLm5vZGVUeXBlICE9PSAxKSByZXR1cm4gZmFsc2U7XG4gIGlmICh2ZW5kb3IpIHJldHVybiB2ZW5kb3IuY2FsbChlbCwgc2VsZWN0b3IpO1xuICB2YXIgbm9kZXMgPSBlbC5wYXJlbnROb2RlLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKG5vZGVzW2ldID09IGVsKSByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogQ2xvc2VzdFxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxlY3RvclxuICogQHBhcmFtIHtCb29sZWFufSBjaGVja1lvdXJTZWxmIChvcHRpb25hbClcbiAqL1xuZnVuY3Rpb24gY2xvc2VzdCAoZWxlbWVudCwgc2VsZWN0b3IsIGNoZWNrWW91clNlbGYpIHtcbiAgdmFyIGN1cnJlbnRFbGVtID0gY2hlY2tZb3VyU2VsZiA/IGVsZW1lbnQgOiBlbGVtZW50LnBhcmVudE5vZGU7XG5cbiAgd2hpbGUgKGN1cnJlbnRFbGVtICYmIGN1cnJlbnRFbGVtLm5vZGVUeXBlICE9PSBkb2N1bWVudC5ET0NVTUVOVF9OT0RFICYmIGN1cnJlbnRFbGVtLm5vZGVUeXBlICE9PSBkb2N1bWVudC5ET0NVTUVOVF9GUkFHTUVOVF9OT0RFKSB7XG5cbiAgICBpZiAobWF0Y2hlc1NlbGVjdG9yKGN1cnJlbnRFbGVtLCBzZWxlY3RvcikpIHtcbiAgICAgIHJldHVybiBjdXJyZW50RWxlbTtcbiAgICB9XG5cbiAgICBjdXJyZW50RWxlbSA9IGN1cnJlbnRFbGVtLnBhcmVudE5vZGU7XG4gIH1cblxuICByZXR1cm4gbWF0Y2hlc1NlbGVjdG9yKGN1cnJlbnRFbGVtLCBzZWxlY3RvcikgPyBjdXJyZW50RWxlbSA6IG51bGw7XG59XG5cbnZhciBiaW5kID0gd2luZG93LmFkZEV2ZW50TGlzdGVuZXIgPyAnYWRkRXZlbnRMaXN0ZW5lcicgOiAnYXR0YWNoRXZlbnQnLFxuICAgIHVuYmluZCA9IHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyID8gJ3JlbW92ZUV2ZW50TGlzdGVuZXInIDogJ2RldGFjaEV2ZW50JyxcbiAgICBwcmVmaXggPSBiaW5kICE9PSAnYWRkRXZlbnRMaXN0ZW5lcicgPyAnb24nIDogJyc7XG5cbi8qKlxuICogQmluZCBgZWxgIGV2ZW50IGB0eXBlYCB0byBgZm5gLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtCb29sZWFufSBjYXB0dXJlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxudmFyIGJpbmRfMSA9IGZ1bmN0aW9uKGVsLCB0eXBlLCBmbiwgY2FwdHVyZSl7XG4gIGVsW2JpbmRdKHByZWZpeCArIHR5cGUsIGZuLCBjYXB0dXJlIHx8IGZhbHNlKTtcbiAgcmV0dXJuIGZuO1xufTtcblxuLyoqXG4gKiBVbmJpbmQgYGVsYCBldmVudCBgdHlwZWAncyBjYWxsYmFjayBgZm5gLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtCb29sZWFufSBjYXB0dXJlXG4gKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAqIEBhcGkgcHVibGljXG4gKi9cblxudmFyIHVuYmluZF8xID0gZnVuY3Rpb24oZWwsIHR5cGUsIGZuLCBjYXB0dXJlKXtcbiAgZWxbdW5iaW5kXShwcmVmaXggKyB0eXBlLCBmbiwgY2FwdHVyZSB8fCBmYWxzZSk7XG4gIHJldHVybiBmbjtcbn07XG5cbnZhciBjb21wb25lbnRFdmVudCA9IHtcblx0YmluZDogYmluZF8xLFxuXHR1bmJpbmQ6IHVuYmluZF8xXG59O1xuXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKi9cblxuLyoqXG4gKiBEZWxlZ2F0ZSBldmVudCBgdHlwZWAgdG8gYHNlbGVjdG9yYFxuICogYW5kIGludm9rZSBgZm4oZSlgLiBBIGNhbGxiYWNrIGZ1bmN0aW9uXG4gKiBpcyByZXR1cm5lZCB3aGljaCBtYXkgYmUgcGFzc2VkIHRvIGAudW5iaW5kKClgLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSBzZWxlY3RvclxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGNhcHR1cmVcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG4vLyBTb21lIGV2ZW50cyBkb24ndCBidWJibGUsIHNvIHdlIHdhbnQgdG8gYmluZCB0byB0aGUgY2FwdHVyZSBwaGFzZSBpbnN0ZWFkXG4vLyB3aGVuIGRlbGVnYXRpbmcuXG52YXIgZm9yY2VDYXB0dXJlRXZlbnRzID0gWydmb2N1cycsICdibHVyJ107XG5cbmZ1bmN0aW9uIGJpbmQkMShlbCwgc2VsZWN0b3IsIHR5cGUsIGZuLCBjYXB0dXJlKSB7XG4gIGlmIChmb3JjZUNhcHR1cmVFdmVudHMuaW5kZXhPZih0eXBlKSAhPT0gLTEpIHtcbiAgICBjYXB0dXJlID0gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBjb21wb25lbnRFdmVudC5iaW5kKGVsLCB0eXBlLCBmdW5jdGlvbiAoZSkge1xuICAgIHZhciB0YXJnZXQgPSBlLnRhcmdldCB8fCBlLnNyY0VsZW1lbnQ7XG4gICAgZS5kZWxlZ2F0ZVRhcmdldCA9IGNsb3Nlc3QodGFyZ2V0LCBzZWxlY3RvciwgdHJ1ZSwgZWwpO1xuICAgIGlmIChlLmRlbGVnYXRlVGFyZ2V0KSB7XG4gICAgICBmbi5jYWxsKGVsLCBlKTtcbiAgICB9XG4gIH0sIGNhcHR1cmUpO1xufVxuXG4vKipcbiAqIFVuYmluZCBldmVudCBgdHlwZWAncyBjYWxsYmFjayBgZm5gLlxuICpcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcbiAqIEBwYXJhbSB7U3RyaW5nfSB0eXBlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICogQHBhcmFtIHtCb29sZWFufSBjYXB0dXJlXG4gKiBAYXBpIHB1YmxpY1xuICovXG5mdW5jdGlvbiB1bmJpbmQkMShlbCwgdHlwZSwgZm4sIGNhcHR1cmUpIHtcbiAgaWYgKGZvcmNlQ2FwdHVyZUV2ZW50cy5pbmRleE9mKHR5cGUpICE9PSAtMSkge1xuICAgIGNhcHR1cmUgPSB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGNvbXBvbmVudEV2ZW50LnVuYmluZChlbCwgdHlwZSwgZm4sIGNhcHR1cmUpO1xufVxuXG52YXIgZGVsZWdhdGUgPSB7XG4gIGJpbmQ6IGJpbmQkMSxcbiAgdW5iaW5kOiB1bmJpbmQkMVxufTtcblxuLyoqXG4gKiBFeHBvc2UgYHBhcnNlYC5cbiAqL1xuXG52YXIgZG9taWZ5ID0gcGFyc2U7XG5cbi8qKlxuICogVGVzdHMgZm9yIGJyb3dzZXIgc3VwcG9ydC5cbiAqL1xuXG52YXIgaW5uZXJIVE1MQnVnID0gZmFsc2U7XG52YXIgYnVnVGVzdERpdjtcbmlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gIGJ1Z1Rlc3REaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgLy8gU2V0dXBcbiAgYnVnVGVzdERpdi5pbm5lckhUTUwgPSAnICA8bGluay8+PHRhYmxlPjwvdGFibGU+PGEgaHJlZj1cIi9hXCI+YTwvYT48aW5wdXQgdHlwZT1cImNoZWNrYm94XCIvPic7XG4gIC8vIE1ha2Ugc3VyZSB0aGF0IGxpbmsgZWxlbWVudHMgZ2V0IHNlcmlhbGl6ZWQgY29ycmVjdGx5IGJ5IGlubmVySFRNTFxuICAvLyBUaGlzIHJlcXVpcmVzIGEgd3JhcHBlciBlbGVtZW50IGluIElFXG4gIGlubmVySFRNTEJ1ZyA9ICFidWdUZXN0RGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdsaW5rJykubGVuZ3RoO1xuICBidWdUZXN0RGl2ID0gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFdyYXAgbWFwIGZyb20ganF1ZXJ5LlxuICovXG5cbnZhciBtYXAgPSB7XG4gIGxlZ2VuZDogWzEsICc8ZmllbGRzZXQ+JywgJzwvZmllbGRzZXQ+J10sXG4gIHRyOiBbMiwgJzx0YWJsZT48dGJvZHk+JywgJzwvdGJvZHk+PC90YWJsZT4nXSxcbiAgY29sOiBbMiwgJzx0YWJsZT48dGJvZHk+PC90Ym9keT48Y29sZ3JvdXA+JywgJzwvY29sZ3JvdXA+PC90YWJsZT4nXSxcbiAgLy8gZm9yIHNjcmlwdC9saW5rL3N0eWxlIHRhZ3MgdG8gd29yayBpbiBJRTYtOCwgeW91IGhhdmUgdG8gd3JhcFxuICAvLyBpbiBhIGRpdiB3aXRoIGEgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyIGluIGZyb250LCBoYSFcbiAgX2RlZmF1bHQ6IGlubmVySFRNTEJ1ZyA/IFsxLCAnWDxkaXY+JywgJzwvZGl2PiddIDogWzAsICcnLCAnJ11cbn07XG5cbm1hcC50ZCA9XG5tYXAudGggPSBbMywgJzx0YWJsZT48dGJvZHk+PHRyPicsICc8L3RyPjwvdGJvZHk+PC90YWJsZT4nXTtcblxubWFwLm9wdGlvbiA9XG5tYXAub3B0Z3JvdXAgPSBbMSwgJzxzZWxlY3QgbXVsdGlwbGU9XCJtdWx0aXBsZVwiPicsICc8L3NlbGVjdD4nXTtcblxubWFwLnRoZWFkID1cbm1hcC50Ym9keSA9XG5tYXAuY29sZ3JvdXAgPVxubWFwLmNhcHRpb24gPVxubWFwLnRmb290ID0gWzEsICc8dGFibGU+JywgJzwvdGFibGU+J107XG5cbm1hcC5wb2x5bGluZSA9XG5tYXAuZWxsaXBzZSA9XG5tYXAucG9seWdvbiA9XG5tYXAuY2lyY2xlID1cbm1hcC50ZXh0ID1cbm1hcC5saW5lID1cbm1hcC5wYXRoID1cbm1hcC5yZWN0ID1cbm1hcC5nID0gWzEsICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB2ZXJzaW9uPVwiMS4xXCI+JywnPC9zdmc+J107XG5cbi8qKlxuICogUGFyc2UgYGh0bWxgIGFuZCByZXR1cm4gYSBET00gTm9kZSBpbnN0YW5jZSwgd2hpY2ggY291bGQgYmUgYSBUZXh0Tm9kZSxcbiAqIEhUTUwgRE9NIE5vZGUgb2Ygc29tZSBraW5kICg8ZGl2PiBmb3IgZXhhbXBsZSksIG9yIGEgRG9jdW1lbnRGcmFnbWVudFxuICogaW5zdGFuY2UsIGRlcGVuZGluZyBvbiB0aGUgY29udGVudHMgb2YgdGhlIGBodG1sYCBzdHJpbmcuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IGh0bWwgLSBIVE1MIHN0cmluZyB0byBcImRvbWlmeVwiXG4gKiBAcGFyYW0ge0RvY3VtZW50fSBkb2MgLSBUaGUgYGRvY3VtZW50YCBpbnN0YW5jZSB0byBjcmVhdGUgdGhlIE5vZGUgZm9yXG4gKiBAcmV0dXJuIHtET01Ob2RlfSB0aGUgVGV4dE5vZGUsIERPTSBOb2RlLCBvciBEb2N1bWVudEZyYWdtZW50IGluc3RhbmNlXG4gKiBAYXBpIHByaXZhdGVcbiAqL1xuXG5mdW5jdGlvbiBwYXJzZShodG1sLCBkb2MpIHtcbiAgaWYgKCdzdHJpbmcnICE9IHR5cGVvZiBodG1sKSB0aHJvdyBuZXcgVHlwZUVycm9yKCdTdHJpbmcgZXhwZWN0ZWQnKTtcblxuICAvLyBkZWZhdWx0IHRvIHRoZSBnbG9iYWwgYGRvY3VtZW50YCBvYmplY3RcbiAgaWYgKCFkb2MpIGRvYyA9IGRvY3VtZW50O1xuXG4gIC8vIHRhZyBuYW1lXG4gIHZhciBtID0gLzwoW1xcdzpdKykvLmV4ZWMoaHRtbCk7XG4gIGlmICghbSkgcmV0dXJuIGRvYy5jcmVhdGVUZXh0Tm9kZShodG1sKTtcblxuICBodG1sID0gaHRtbC5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJyk7IC8vIFJlbW92ZSBsZWFkaW5nL3RyYWlsaW5nIHdoaXRlc3BhY2VcblxuICB2YXIgdGFnID0gbVsxXTtcblxuICAvLyBib2R5IHN1cHBvcnRcbiAgaWYgKHRhZyA9PSAnYm9keScpIHtcbiAgICB2YXIgZWwgPSBkb2MuY3JlYXRlRWxlbWVudCgnaHRtbCcpO1xuICAgIGVsLmlubmVySFRNTCA9IGh0bWw7XG4gICAgcmV0dXJuIGVsLnJlbW92ZUNoaWxkKGVsLmxhc3RDaGlsZCk7XG4gIH1cblxuICAvLyB3cmFwIG1hcFxuICB2YXIgd3JhcCA9IG1hcFt0YWddIHx8IG1hcC5fZGVmYXVsdDtcbiAgdmFyIGRlcHRoID0gd3JhcFswXTtcbiAgdmFyIHByZWZpeCA9IHdyYXBbMV07XG4gIHZhciBzdWZmaXggPSB3cmFwWzJdO1xuICB2YXIgZWwgPSBkb2MuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIGVsLmlubmVySFRNTCA9IHByZWZpeCArIGh0bWwgKyBzdWZmaXg7XG4gIHdoaWxlIChkZXB0aC0tKSBlbCA9IGVsLmxhc3RDaGlsZDtcblxuICAvLyBvbmUgZWxlbWVudFxuICBpZiAoZWwuZmlyc3RDaGlsZCA9PSBlbC5sYXN0Q2hpbGQpIHtcbiAgICByZXR1cm4gZWwucmVtb3ZlQ2hpbGQoZWwuZmlyc3RDaGlsZCk7XG4gIH1cblxuICAvLyBzZXZlcmFsIGVsZW1lbnRzXG4gIHZhciBmcmFnbWVudCA9IGRvYy5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG4gIHdoaWxlIChlbC5maXJzdENoaWxkKSB7XG4gICAgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoZWwucmVtb3ZlQ2hpbGQoZWwuZmlyc3RDaGlsZCkpO1xuICB9XG5cbiAgcmV0dXJuIGZyYWdtZW50O1xufVxuXG5mdW5jdGlvbiBxdWVyeShzZWxlY3RvciwgZWwpIHtcbiAgZWwgPSBlbCB8fCBkb2N1bWVudDtcblxuICByZXR1cm4gZWwucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG59XG5cbmZ1bmN0aW9uIGFsbChzZWxlY3RvciwgZWwpIHtcbiAgZWwgPSBlbCB8fCBkb2N1bWVudDtcblxuICByZXR1cm4gZWwucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShlbCkge1xuICBlbC5wYXJlbnROb2RlICYmIGVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoZWwpO1xufVxuXG5leHBvcnQgeyBhdHRyLCBjbGFzc2VzLCBjbGVhciwgY2xvc2VzdCwgZGVsZWdhdGUsIGRvbWlmeSwgY29tcG9uZW50RXZlbnQgYXMgZXZlbnQsIG1hdGNoZXNTZWxlY3RvciBhcyBtYXRjaGVzLCBxdWVyeSwgYWxsIGFzIHF1ZXJ5QWxsLCByZW1vdmUgfTtcbiIsIlwidXNlIHN0cmljdFwiO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gdm9pZCAwO1xuXG4vLyAgICAgIFxuLy8gQW4gZXZlbnQgaGFuZGxlciBjYW4gdGFrZSBhbiBvcHRpb25hbCBldmVudCBhcmd1bWVudFxuLy8gYW5kIHNob3VsZCBub3QgcmV0dXJuIGEgdmFsdWVcbi8vIEFuIGFycmF5IG9mIGFsbCBjdXJyZW50bHkgcmVnaXN0ZXJlZCBldmVudCBoYW5kbGVycyBmb3IgYSB0eXBlXG4vLyBBIG1hcCBvZiBldmVudCB0eXBlcyBhbmQgdGhlaXIgY29ycmVzcG9uZGluZyBldmVudCBoYW5kbGVycy5cblxuLyoqIE1pdHQ6IFRpbnkgKH4yMDBiKSBmdW5jdGlvbmFsIGV2ZW50IGVtaXR0ZXIgLyBwdWJzdWIuXG4gKiAgQG5hbWUgbWl0dFxuICogIEByZXR1cm5zIHtNaXR0fVxuICovXG5mdW5jdGlvbiBtaXR0KGFsbCkge1xuICBhbGwgPSBhbGwgfHwgT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgcmV0dXJuIHtcbiAgICAvKipcbiAgICAgKiBSZWdpc3RlciBhbiBldmVudCBoYW5kbGVyIGZvciB0aGUgZ2l2ZW4gdHlwZS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSAge1N0cmluZ30gdHlwZVx0VHlwZSBvZiBldmVudCB0byBsaXN0ZW4gZm9yLCBvciBgXCIqXCJgIGZvciBhbGwgZXZlbnRzXG4gICAgICogQHBhcmFtICB7RnVuY3Rpb259IGhhbmRsZXIgRnVuY3Rpb24gdG8gY2FsbCBpbiByZXNwb25zZSB0byBnaXZlbiBldmVudFxuICAgICAqIEBtZW1iZXJPZiBtaXR0XG4gICAgICovXG4gICAgb246IGZ1bmN0aW9uIG9uKHR5cGUsIGhhbmRsZXIpIHtcbiAgICAgIChhbGxbdHlwZV0gfHwgKGFsbFt0eXBlXSA9IFtdKSkucHVzaChoYW5kbGVyKTtcbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogUmVtb3ZlIGFuIGV2ZW50IGhhbmRsZXIgZm9yIHRoZSBnaXZlbiB0eXBlLlxuICAgICAqXG4gICAgICogQHBhcmFtICB7U3RyaW5nfSB0eXBlXHRUeXBlIG9mIGV2ZW50IHRvIHVucmVnaXN0ZXIgYGhhbmRsZXJgIGZyb20sIG9yIGBcIipcImBcbiAgICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gaGFuZGxlciBIYW5kbGVyIGZ1bmN0aW9uIHRvIHJlbW92ZVxuICAgICAqIEBtZW1iZXJPZiBtaXR0XG4gICAgICovXG4gICAgb2ZmOiBmdW5jdGlvbiBvZmYodHlwZSwgaGFuZGxlcikge1xuICAgICAgaWYgKGFsbFt0eXBlXSkge1xuICAgICAgICBhbGxbdHlwZV0uc3BsaWNlKGFsbFt0eXBlXS5pbmRleE9mKGhhbmRsZXIpID4+PiAwLCAxKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgLyoqXG4gICAgICogSW52b2tlIGFsbCBoYW5kbGVycyBmb3IgdGhlIGdpdmVuIHR5cGUuXG4gICAgICogSWYgcHJlc2VudCwgYFwiKlwiYCBoYW5kbGVycyBhcmUgaW52b2tlZCBhZnRlciB0eXBlLW1hdGNoZWQgaGFuZGxlcnMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmluZ30gdHlwZSAgVGhlIGV2ZW50IHR5cGUgdG8gaW52b2tlXG4gICAgICogQHBhcmFtIHtBbnl9IFtldnRdICBBbnkgdmFsdWUgKG9iamVjdCBpcyByZWNvbW1lbmRlZCBhbmQgcG93ZXJmdWwpLCBwYXNzZWQgdG8gZWFjaCBoYW5kbGVyXG4gICAgICogQG1lbWJlck9mIG1pdHRcbiAgICAgKi9cbiAgICBlbWl0OiBmdW5jdGlvbiBlbWl0KHR5cGUsIGV2dCkge1xuICAgICAgKGFsbFt0eXBlXSB8fCBbXSkuc2xpY2UoKS5tYXAoZnVuY3Rpb24gKGhhbmRsZXIpIHtcbiAgICAgICAgaGFuZGxlcihldnQpO1xuICAgICAgfSk7XG4gICAgICAoYWxsWycqJ10gfHwgW10pLnNsaWNlKCkubWFwKGZ1bmN0aW9uIChoYW5kbGVyKSB7XG4gICAgICAgIGhhbmRsZXIodHlwZSwgZXZ0KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcbn1cblxudmFyIF9kZWZhdWx0ID0gbWl0dDtcbmV4cG9ydHMuZGVmYXVsdCA9IF9kZWZhdWx0O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZGF0YTphcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7YmFzZTY0LGV5SjJaWEp6YVc5dUlqb3pMQ0p6YjNWeVkyVnpJanBiWFN3aWJtRnRaWE1pT2x0ZExDSnRZWEJ3YVc1bmN5STZJaUo5IiwiaW1wb3J0IHsgZm9yRWFjaCwgYXNzaWduLCBmaW5kLCBmaWx0ZXIsIGlzU3RyaW5nLCBtYXAgfSBmcm9tICdtaW4tZGFzaCc7XG5pbXBvcnQgeyBQYXJzZXIgfSBmcm9tICdzYXhlbic7XG5pbXBvcnQgeyBjb2VyY2VUeXBlLCBwYXJzZU5hbWVOUywgaXNTaW1wbGVUeXBlLCBNb2RkbGUgfSBmcm9tICdtb2RkbGUnO1xuXG5mdW5jdGlvbiBoYXNMb3dlckNhc2VBbGlhcyhwa2cpIHtcbiAgcmV0dXJuIHBrZy54bWwgJiYgcGtnLnhtbC50YWdBbGlhcyA9PT0gJ2xvd2VyQ2FzZSc7XG59XG5cbnZhciBERUZBVUxUX05TX01BUCA9IHtcbiAgJ3hzaSc6ICdodHRwOi8vd3d3LnczLm9yZy8yMDAxL1hNTFNjaGVtYS1pbnN0YW5jZScsXG4gICd4bWwnOiAnaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJ1xufTtcblxudmFyIFhTSV9UWVBFID0gJ3hzaTp0eXBlJztcblxuZnVuY3Rpb24gc2VyaWFsaXplRm9ybWF0KGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQueG1sICYmIGVsZW1lbnQueG1sLnNlcmlhbGl6ZTtcbn1cblxuZnVuY3Rpb24gc2VyaWFsaXplQXNUeXBlKGVsZW1lbnQpIHtcbiAgcmV0dXJuIHNlcmlhbGl6ZUZvcm1hdChlbGVtZW50KSA9PT0gWFNJX1RZUEU7XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZUFzUHJvcGVydHkoZWxlbWVudCkge1xuICByZXR1cm4gc2VyaWFsaXplRm9ybWF0KGVsZW1lbnQpID09PSAncHJvcGVydHknO1xufVxuXG5mdW5jdGlvbiBjYXBpdGFsaXplKHN0cikge1xuICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnNsaWNlKDEpO1xufVxuXG5mdW5jdGlvbiBhbGlhc1RvTmFtZShhbGlhc05zLCBwa2cpIHtcblxuICBpZiAoIWhhc0xvd2VyQ2FzZUFsaWFzKHBrZykpIHtcbiAgICByZXR1cm4gYWxpYXNOcy5uYW1lO1xuICB9XG5cbiAgcmV0dXJuIGFsaWFzTnMucHJlZml4ICsgJzonICsgY2FwaXRhbGl6ZShhbGlhc05zLmxvY2FsTmFtZSk7XG59XG5cbmZ1bmN0aW9uIHByZWZpeGVkVG9OYW1lKG5hbWVOcywgcGtnKSB7XG5cbiAgdmFyIG5hbWUgPSBuYW1lTnMubmFtZSxcbiAgICAgIGxvY2FsTmFtZSA9IG5hbWVOcy5sb2NhbE5hbWU7XG5cbiAgdmFyIHR5cGVQcmVmaXggPSBwa2cueG1sICYmIHBrZy54bWwudHlwZVByZWZpeDtcblxuICBpZiAodHlwZVByZWZpeCAmJiBsb2NhbE5hbWUuaW5kZXhPZih0eXBlUHJlZml4KSA9PT0gMCkge1xuICAgIHJldHVybiBuYW1lTnMucHJlZml4ICsgJzonICsgbG9jYWxOYW1lLnNsaWNlKHR5cGVQcmVmaXgubGVuZ3RoKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBub3JtYWxpemVYc2lUeXBlTmFtZShuYW1lLCBtb2RlbCkge1xuXG4gIHZhciBuYW1lTnMgPSBwYXJzZU5hbWVOUyhuYW1lKTtcbiAgdmFyIHBrZyA9IG1vZGVsLmdldFBhY2thZ2UobmFtZU5zLnByZWZpeCk7XG5cbiAgcmV0dXJuIHByZWZpeGVkVG9OYW1lKG5hbWVOcywgcGtnKTtcbn1cblxuZnVuY3Rpb24gZXJyb3IobWVzc2FnZSkge1xuICByZXR1cm4gbmV3IEVycm9yKG1lc3NhZ2UpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgbW9kZGxlIGRlc2NyaXB0b3IgZm9yIGEgZ2l2ZW4gaW5zdGFuY2Ugb3IgdHlwZS5cbiAqXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50fEZ1bmN0aW9ufSBlbGVtZW50XG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB0aGUgbW9kZGxlIGRlc2NyaXB0b3JcbiAqL1xuZnVuY3Rpb24gZ2V0TW9kZGxlRGVzY3JpcHRvcihlbGVtZW50KSB7XG4gIHJldHVybiBlbGVtZW50LiRkZXNjcmlwdG9yO1xufVxuXG5cbi8qKlxuICogQSBwYXJzZSBjb250ZXh0LlxuICpcbiAqIEBjbGFzc1xuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0ge0VsZW1lbnRIYW5kbGVyfSBvcHRpb25zLnJvb3RIYW5kbGVyIHRoZSByb290IGhhbmRsZXIgZm9yIHBhcnNpbmcgYSBkb2N1bWVudFxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5sYXg9ZmFsc2VdIHdoZXRoZXIgb3Igbm90IHRvIGlnbm9yZSBpbnZhbGlkIGVsZW1lbnRzXG4gKi9cbmZ1bmN0aW9uIENvbnRleHQob3B0aW9ucykge1xuXG4gIC8qKlxuICAgKiBAcHJvcGVydHkge0VsZW1lbnRIYW5kbGVyfSByb290SGFuZGxlclxuICAgKi9cblxuICAvKipcbiAgICogQHByb3BlcnR5IHtCb29sZWFufSBsYXhcbiAgICovXG5cbiAgYXNzaWduKHRoaXMsIG9wdGlvbnMpO1xuXG4gIHRoaXMuZWxlbWVudHNCeUlkID0ge307XG4gIHRoaXMucmVmZXJlbmNlcyA9IFtdO1xuICB0aGlzLndhcm5pbmdzID0gW107XG5cbiAgLyoqXG4gICAqIEFkZCBhbiB1bnJlc29sdmVkIHJlZmVyZW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IHJlZmVyZW5jZVxuICAgKi9cbiAgdGhpcy5hZGRSZWZlcmVuY2UgPSBmdW5jdGlvbihyZWZlcmVuY2UpIHtcbiAgICB0aGlzLnJlZmVyZW5jZXMucHVzaChyZWZlcmVuY2UpO1xuICB9O1xuXG4gIC8qKlxuICAgKiBBZGQgYSBwcm9jZXNzZWQgZWxlbWVudC5cbiAgICpcbiAgICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBlbGVtZW50XG4gICAqL1xuICB0aGlzLmFkZEVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgICBpZiAoIWVsZW1lbnQpIHtcbiAgICAgIHRocm93IGVycm9yKCdleHBlY3RlZCBlbGVtZW50Jyk7XG4gICAgfVxuXG4gICAgdmFyIGVsZW1lbnRzQnlJZCA9IHRoaXMuZWxlbWVudHNCeUlkO1xuXG4gICAgdmFyIGRlc2NyaXB0b3IgPSBnZXRNb2RkbGVEZXNjcmlwdG9yKGVsZW1lbnQpO1xuXG4gICAgdmFyIGlkUHJvcGVydHkgPSBkZXNjcmlwdG9yLmlkUHJvcGVydHksXG4gICAgICAgIGlkO1xuXG4gICAgaWYgKGlkUHJvcGVydHkpIHtcbiAgICAgIGlkID0gZWxlbWVudC5nZXQoaWRQcm9wZXJ0eS5uYW1lKTtcblxuICAgICAgaWYgKGlkKSB7XG4gICAgICAgIC8vIGZvciBRTmFtZSB2YWxpZGF0aW9uIGFzIHBlciBodHRwOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLyNOVC1OYW1lQ2hhclxuICAgICAgICBpZiAoIS9eKFthLXpdW1xcdy0uXSo6KT9bYS16X11bXFx3LS5dKiQvaS50ZXN0KGlkKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignaWxsZWdhbCBJRCA8JyArIGlkICsgJz4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChlbGVtZW50c0J5SWRbaWRdKSB7XG4gICAgICAgICAgdGhyb3cgZXJyb3IoJ2R1cGxpY2F0ZSBJRCA8JyArIGlkICsgJz4nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVsZW1lbnRzQnlJZFtpZF0gPSBlbGVtZW50O1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogQWRkIGFuIGltcG9ydCB3YXJuaW5nLlxuICAgKlxuICAgKiBAcGFyYW0ge09iamVjdH0gd2FybmluZ1xuICAgKiBAcGFyYW0ge1N0cmluZ30gd2FybmluZy5tZXNzYWdlXG4gICAqIEBwYXJhbSB7RXJyb3J9IFt3YXJuaW5nLmVycm9yXVxuICAgKi9cbiAgdGhpcy5hZGRXYXJuaW5nID0gZnVuY3Rpb24od2FybmluZykge1xuICAgIHRoaXMud2FybmluZ3MucHVzaCh3YXJuaW5nKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gQmFzZUhhbmRsZXIoKSB7fVxuXG5CYXNlSGFuZGxlci5wcm90b3R5cGUuaGFuZGxlRW5kID0gZnVuY3Rpb24oKSB7fTtcbkJhc2VIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVUZXh0ID0gZnVuY3Rpb24oKSB7fTtcbkJhc2VIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVOb2RlID0gZnVuY3Rpb24oKSB7fTtcblxuXG4vKipcbiAqIEEgc2ltcGxlIHBhc3MgdGhyb3VnaCBoYW5kbGVyIHRoYXQgZG9lcyBub3RoaW5nIGV4Y2VwdCBmb3JcbiAqIGlnbm9yaW5nIGFsbCBpbnB1dCBpdCByZWNlaXZlcy5cbiAqXG4gKiBUaGlzIGlzIHVzZWQgdG8gaWdub3JlIHVua25vd24gZWxlbWVudHMgYW5kXG4gKiBhdHRyaWJ1dGVzLlxuICovXG5mdW5jdGlvbiBOb29wSGFuZGxlcigpIHsgfVxuXG5Ob29wSGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VIYW5kbGVyLnByb3RvdHlwZSk7XG5cbk5vb3BIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVOb2RlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gQm9keUhhbmRsZXIoKSB7fVxuXG5Cb2R5SGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VIYW5kbGVyLnByb3RvdHlwZSk7XG5cbkJvZHlIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVUZXh0ID0gZnVuY3Rpb24odGV4dCkge1xuICB0aGlzLmJvZHkgPSAodGhpcy5ib2R5IHx8ICcnKSArIHRleHQ7XG59O1xuXG5mdW5jdGlvbiBSZWZlcmVuY2VIYW5kbGVyKHByb3BlcnR5LCBjb250ZXh0KSB7XG4gIHRoaXMucHJvcGVydHkgPSBwcm9wZXJ0eTtcbiAgdGhpcy5jb250ZXh0ID0gY29udGV4dDtcbn1cblxuUmVmZXJlbmNlSGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJvZHlIYW5kbGVyLnByb3RvdHlwZSk7XG5cblJlZmVyZW5jZUhhbmRsZXIucHJvdG90eXBlLmhhbmRsZU5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgaWYgKHRoaXMuZWxlbWVudCkge1xuICAgIHRocm93IGVycm9yKCdleHBlY3RlZCBubyBzdWIgbm9kZXMnKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLmVsZW1lbnQgPSB0aGlzLmNyZWF0ZVJlZmVyZW5jZShub2RlKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuUmVmZXJlbmNlSGFuZGxlci5wcm90b3R5cGUuaGFuZGxlRW5kID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuZWxlbWVudC5pZCA9IHRoaXMuYm9keTtcbn07XG5cblJlZmVyZW5jZUhhbmRsZXIucHJvdG90eXBlLmNyZWF0ZVJlZmVyZW5jZSA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgcmV0dXJuIHtcbiAgICBwcm9wZXJ0eTogdGhpcy5wcm9wZXJ0eS5ucy5uYW1lLFxuICAgIGlkOiAnJ1xuICB9O1xufTtcblxuZnVuY3Rpb24gVmFsdWVIYW5kbGVyKHByb3BlcnR5RGVzYywgZWxlbWVudCkge1xuICB0aGlzLmVsZW1lbnQgPSBlbGVtZW50O1xuICB0aGlzLnByb3BlcnR5RGVzYyA9IHByb3BlcnR5RGVzYztcbn1cblxuVmFsdWVIYW5kbGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoQm9keUhhbmRsZXIucHJvdG90eXBlKTtcblxuVmFsdWVIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVFbmQgPSBmdW5jdGlvbigpIHtcblxuICB2YXIgdmFsdWUgPSB0aGlzLmJvZHkgfHwgJycsXG4gICAgICBlbGVtZW50ID0gdGhpcy5lbGVtZW50LFxuICAgICAgcHJvcGVydHlEZXNjID0gdGhpcy5wcm9wZXJ0eURlc2M7XG5cbiAgdmFsdWUgPSBjb2VyY2VUeXBlKHByb3BlcnR5RGVzYy50eXBlLCB2YWx1ZSk7XG5cbiAgaWYgKHByb3BlcnR5RGVzYy5pc01hbnkpIHtcbiAgICBlbGVtZW50LmdldChwcm9wZXJ0eURlc2MubmFtZSkucHVzaCh2YWx1ZSk7XG4gIH0gZWxzZSB7XG4gICAgZWxlbWVudC5zZXQocHJvcGVydHlEZXNjLm5hbWUsIHZhbHVlKTtcbiAgfVxufTtcblxuXG5mdW5jdGlvbiBCYXNlRWxlbWVudEhhbmRsZXIoKSB7fVxuXG5CYXNlRWxlbWVudEhhbmRsZXIucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShCb2R5SGFuZGxlci5wcm90b3R5cGUpO1xuXG5CYXNlRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmhhbmRsZU5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gIHZhciBwYXJzZXIgPSB0aGlzLFxuICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblxuICBpZiAoIWVsZW1lbnQpIHtcbiAgICBlbGVtZW50ID0gdGhpcy5lbGVtZW50ID0gdGhpcy5jcmVhdGVFbGVtZW50KG5vZGUpO1xuXG4gICAgdGhpcy5jb250ZXh0LmFkZEVsZW1lbnQoZWxlbWVudCk7XG4gIH0gZWxzZSB7XG4gICAgcGFyc2VyID0gdGhpcy5oYW5kbGVDaGlsZChub2RlKTtcbiAgfVxuXG4gIHJldHVybiBwYXJzZXI7XG59O1xuXG4vKipcbiAqIEBjbGFzcyBSZWFkZXIuRWxlbWVudEhhbmRsZXJcbiAqXG4gKi9cbmZ1bmN0aW9uIEVsZW1lbnRIYW5kbGVyKG1vZGVsLCB0eXBlTmFtZSwgY29udGV4dCkge1xuICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gIHRoaXMudHlwZSA9IG1vZGVsLmdldFR5cGUodHlwZU5hbWUpO1xuICB0aGlzLmNvbnRleHQgPSBjb250ZXh0O1xufVxuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VFbGVtZW50SGFuZGxlci5wcm90b3R5cGUpO1xuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUuYWRkUmVmZXJlbmNlID0gZnVuY3Rpb24ocmVmZXJlbmNlKSB7XG4gIHRoaXMuY29udGV4dC5hZGRSZWZlcmVuY2UocmVmZXJlbmNlKTtcbn07XG5cbkVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVUZXh0ID0gZnVuY3Rpb24odGV4dCkge1xuXG4gIHZhciBlbGVtZW50ID0gdGhpcy5lbGVtZW50LFxuICAgICAgZGVzY3JpcHRvciA9IGdldE1vZGRsZURlc2NyaXB0b3IoZWxlbWVudCksXG4gICAgICBib2R5UHJvcGVydHkgPSBkZXNjcmlwdG9yLmJvZHlQcm9wZXJ0eTtcblxuICBpZiAoIWJvZHlQcm9wZXJ0eSkge1xuICAgIHRocm93IGVycm9yKCd1bmV4cGVjdGVkIGJvZHkgdGV4dCA8JyArIHRleHQgKyAnPicpO1xuICB9XG5cbiAgQm9keUhhbmRsZXIucHJvdG90eXBlLmhhbmRsZVRleHQuY2FsbCh0aGlzLCB0ZXh0KTtcbn07XG5cbkVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVFbmQgPSBmdW5jdGlvbigpIHtcblxuICB2YXIgdmFsdWUgPSB0aGlzLmJvZHksXG4gICAgICBlbGVtZW50ID0gdGhpcy5lbGVtZW50LFxuICAgICAgZGVzY3JpcHRvciA9IGdldE1vZGRsZURlc2NyaXB0b3IoZWxlbWVudCksXG4gICAgICBib2R5UHJvcGVydHkgPSBkZXNjcmlwdG9yLmJvZHlQcm9wZXJ0eTtcblxuICBpZiAoYm9keVByb3BlcnR5ICYmIHZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICB2YWx1ZSA9IGNvZXJjZVR5cGUoYm9keVByb3BlcnR5LnR5cGUsIHZhbHVlKTtcbiAgICBlbGVtZW50LnNldChib2R5UHJvcGVydHkubmFtZSwgdmFsdWUpO1xuICB9XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgbW9kZWwgZnJvbSB0aGUgZ2l2ZW4gbm9kZS5cbiAqXG4gKiBAcGFyYW0gIHtFbGVtZW50fSBub2RlIHRoZSB4bWwgbm9kZVxuICovXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUuY3JlYXRlRWxlbWVudCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgdmFyIGF0dHJpYnV0ZXMgPSBub2RlLmF0dHJpYnV0ZXMsXG4gICAgICBUeXBlID0gdGhpcy50eXBlLFxuICAgICAgZGVzY3JpcHRvciA9IGdldE1vZGRsZURlc2NyaXB0b3IoVHlwZSksXG4gICAgICBjb250ZXh0ID0gdGhpcy5jb250ZXh0LFxuICAgICAgaW5zdGFuY2UgPSBuZXcgVHlwZSh7fSksXG4gICAgICBtb2RlbCA9IHRoaXMubW9kZWwsXG4gICAgICBwcm9wTmFtZU5zO1xuXG4gIGZvckVhY2goYXR0cmlidXRlcywgZnVuY3Rpb24odmFsdWUsIG5hbWUpIHtcblxuICAgIHZhciBwcm9wID0gZGVzY3JpcHRvci5wcm9wZXJ0aWVzQnlOYW1lW25hbWVdLFxuICAgICAgICB2YWx1ZXM7XG5cbiAgICBpZiAocHJvcCAmJiBwcm9wLmlzUmVmZXJlbmNlKSB7XG5cbiAgICAgIGlmICghcHJvcC5pc01hbnkpIHtcbiAgICAgICAgY29udGV4dC5hZGRSZWZlcmVuY2Uoe1xuICAgICAgICAgIGVsZW1lbnQ6IGluc3RhbmNlLFxuICAgICAgICAgIHByb3BlcnR5OiBwcm9wLm5zLm5hbWUsXG4gICAgICAgICAgaWQ6IHZhbHVlXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gSURSRUZTOiBwYXJzZSByZWZlcmVuY2VzIGFzIHdoaXRlc3BhY2Utc2VwYXJhdGVkIGxpc3RcbiAgICAgICAgdmFsdWVzID0gdmFsdWUuc3BsaXQoJyAnKTtcblxuICAgICAgICBmb3JFYWNoKHZhbHVlcywgZnVuY3Rpb24odikge1xuICAgICAgICAgIGNvbnRleHQuYWRkUmVmZXJlbmNlKHtcbiAgICAgICAgICAgIGVsZW1lbnQ6IGluc3RhbmNlLFxuICAgICAgICAgICAgcHJvcGVydHk6IHByb3AubnMubmFtZSxcbiAgICAgICAgICAgIGlkOiB2XG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChwcm9wKSB7XG4gICAgICAgIHZhbHVlID0gY29lcmNlVHlwZShwcm9wLnR5cGUsIHZhbHVlKTtcbiAgICAgIH0gZWxzZVxuICAgICAgaWYgKG5hbWUgIT09ICd4bWxucycpIHtcbiAgICAgICAgcHJvcE5hbWVOcyA9IHBhcnNlTmFtZU5TKG5hbWUsIGRlc2NyaXB0b3IubnMucHJlZml4KTtcblxuICAgICAgICAvLyBjaGVjayB3aGV0aGVyIGF0dHJpYnV0ZSBpcyBkZWZpbmVkIGluIGEgd2VsbC1rbm93biBuYW1lc3BhY2VcbiAgICAgICAgLy8gaWYgdGhhdCBpcyB0aGUgY2FzZSB3ZSBlbWl0IGEgd2FybmluZyB0byBpbmRpY2F0ZSBwb3RlbnRpYWwgbWlzdXNlXG4gICAgICAgIGlmIChtb2RlbC5nZXRQYWNrYWdlKHByb3BOYW1lTnMucHJlZml4KSkge1xuXG4gICAgICAgICAgY29udGV4dC5hZGRXYXJuaW5nKHtcbiAgICAgICAgICAgIG1lc3NhZ2U6ICd1bmtub3duIGF0dHJpYnV0ZSA8JyArIG5hbWUgKyAnPicsXG4gICAgICAgICAgICBlbGVtZW50OiBpbnN0YW5jZSxcbiAgICAgICAgICAgIHByb3BlcnR5OiBuYW1lLFxuICAgICAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaW5zdGFuY2Uuc2V0KG5hbWUsIHZhbHVlKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBpbnN0YW5jZTtcbn07XG5cbkVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5nZXRQcm9wZXJ0eUZvck5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgdmFyIG5hbWUgPSBub2RlLm5hbWU7XG4gIHZhciBuYW1lTnMgPSBwYXJzZU5hbWVOUyhuYW1lKTtcblxuICB2YXIgdHlwZSA9IHRoaXMudHlwZSxcbiAgICAgIG1vZGVsID0gdGhpcy5tb2RlbCxcbiAgICAgIGRlc2NyaXB0b3IgPSBnZXRNb2RkbGVEZXNjcmlwdG9yKHR5cGUpO1xuXG4gIHZhciBwcm9wZXJ0eU5hbWUgPSBuYW1lTnMubmFtZSxcbiAgICAgIHByb3BlcnR5ID0gZGVzY3JpcHRvci5wcm9wZXJ0aWVzQnlOYW1lW3Byb3BlcnR5TmFtZV0sXG4gICAgICBlbGVtZW50VHlwZU5hbWUsXG4gICAgICBlbGVtZW50VHlwZTtcblxuICAvLyBzZWFyY2ggZm9yIHByb3BlcnRpZXMgYnkgbmFtZSBmaXJzdFxuXG4gIGlmIChwcm9wZXJ0eSAmJiAhcHJvcGVydHkuaXNBdHRyKSB7XG5cbiAgICBpZiAoc2VyaWFsaXplQXNUeXBlKHByb3BlcnR5KSkge1xuICAgICAgZWxlbWVudFR5cGVOYW1lID0gbm9kZS5hdHRyaWJ1dGVzW1hTSV9UWVBFXTtcblxuICAgICAgLy8geHNpIHR5cGUgaXMgb3B0aW9uYWwsIGlmIGl0IGRvZXMgbm90IGV4aXN0cyB0aGVcbiAgICAgIC8vIGRlZmF1bHQgdHlwZSBpcyBhc3N1bWVkXG4gICAgICBpZiAoZWxlbWVudFR5cGVOYW1lKSB7XG5cbiAgICAgICAgLy8gdGFrZSBwb3NzaWJsZSB0eXBlIHByZWZpeGVzIGZyb20gWE1MXG4gICAgICAgIC8vIGludG8gYWNjb3VudCwgaS5lLjogeHNpOnR5cGU9XCJ0e0FjdHVhbFR5cGV9XCJcbiAgICAgICAgZWxlbWVudFR5cGVOYW1lID0gbm9ybWFsaXplWHNpVHlwZU5hbWUoZWxlbWVudFR5cGVOYW1lLCBtb2RlbCk7XG5cbiAgICAgICAgZWxlbWVudFR5cGUgPSBtb2RlbC5nZXRUeXBlKGVsZW1lbnRUeXBlTmFtZSk7XG5cbiAgICAgICAgcmV0dXJuIGFzc2lnbih7fSwgcHJvcGVydHksIHtcbiAgICAgICAgICBlZmZlY3RpdmVUeXBlOiBnZXRNb2RkbGVEZXNjcmlwdG9yKGVsZW1lbnRUeXBlKS5uYW1lXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHNlYXJjaCBmb3IgcHJvcGVydGllcyBieSBuYW1lIGZpcnN0XG4gICAgcmV0dXJuIHByb3BlcnR5O1xuICB9XG5cbiAgdmFyIHBrZyA9IG1vZGVsLmdldFBhY2thZ2UobmFtZU5zLnByZWZpeCk7XG5cbiAgaWYgKHBrZykge1xuICAgIGVsZW1lbnRUeXBlTmFtZSA9IGFsaWFzVG9OYW1lKG5hbWVOcywgcGtnKTtcbiAgICBlbGVtZW50VHlwZSA9IG1vZGVsLmdldFR5cGUoZWxlbWVudFR5cGVOYW1lKTtcblxuICAgIC8vIHNlYXJjaCBmb3IgY29sbGVjdGlvbiBtZW1iZXJzIGxhdGVyXG4gICAgcHJvcGVydHkgPSBmaW5kKGRlc2NyaXB0b3IucHJvcGVydGllcywgZnVuY3Rpb24ocCkge1xuICAgICAgcmV0dXJuICFwLmlzVmlydHVhbCAmJiAhcC5pc1JlZmVyZW5jZSAmJiAhcC5pc0F0dHJpYnV0ZSAmJiBlbGVtZW50VHlwZS5oYXNUeXBlKHAudHlwZSk7XG4gICAgfSk7XG5cbiAgICBpZiAocHJvcGVydHkpIHtcbiAgICAgIHJldHVybiBhc3NpZ24oe30sIHByb3BlcnR5LCB7XG4gICAgICAgIGVmZmVjdGl2ZVR5cGU6IGdldE1vZGRsZURlc2NyaXB0b3IoZWxlbWVudFR5cGUpLm5hbWVcbiAgICAgIH0pO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBwYXJzZSB1bmtub3duIGVsZW1lbnQgKG1heWJlIGV4dGVuc2lvbilcbiAgICBwcm9wZXJ0eSA9IGZpbmQoZGVzY3JpcHRvci5wcm9wZXJ0aWVzLCBmdW5jdGlvbihwKSB7XG4gICAgICByZXR1cm4gIXAuaXNSZWZlcmVuY2UgJiYgIXAuaXNBdHRyaWJ1dGUgJiYgcC50eXBlID09PSAnRWxlbWVudCc7XG4gICAgfSk7XG5cbiAgICBpZiAocHJvcGVydHkpIHtcbiAgICAgIHJldHVybiBwcm9wZXJ0eTtcbiAgICB9XG4gIH1cblxuICB0aHJvdyBlcnJvcigndW5yZWNvZ25pemVkIGVsZW1lbnQgPCcgKyBuYW1lTnMubmFtZSArICc+Jyk7XG59O1xuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuICdFbGVtZW50RGVzY3JpcHRvclsnICsgZ2V0TW9kZGxlRGVzY3JpcHRvcih0aGlzLnR5cGUpLm5hbWUgKyAnXSc7XG59O1xuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUudmFsdWVIYW5kbGVyID0gZnVuY3Rpb24ocHJvcGVydHlEZXNjLCBlbGVtZW50KSB7XG4gIHJldHVybiBuZXcgVmFsdWVIYW5kbGVyKHByb3BlcnR5RGVzYywgZWxlbWVudCk7XG59O1xuXG5FbGVtZW50SGFuZGxlci5wcm90b3R5cGUucmVmZXJlbmNlSGFuZGxlciA9IGZ1bmN0aW9uKHByb3BlcnR5RGVzYykge1xuICByZXR1cm4gbmV3IFJlZmVyZW5jZUhhbmRsZXIocHJvcGVydHlEZXNjLCB0aGlzLmNvbnRleHQpO1xufTtcblxuRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmhhbmRsZXIgPSBmdW5jdGlvbih0eXBlKSB7XG4gIGlmICh0eXBlID09PSAnRWxlbWVudCcpIHtcbiAgICByZXR1cm4gbmV3IEdlbmVyaWNFbGVtZW50SGFuZGxlcih0aGlzLm1vZGVsLCB0eXBlLCB0aGlzLmNvbnRleHQpO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBuZXcgRWxlbWVudEhhbmRsZXIodGhpcy5tb2RlbCwgdHlwZSwgdGhpcy5jb250ZXh0KTtcbiAgfVxufTtcblxuLyoqXG4gKiBIYW5kbGUgdGhlIGNoaWxkIGVsZW1lbnQgcGFyc2luZ1xuICpcbiAqIEBwYXJhbSAge0VsZW1lbnR9IG5vZGUgdGhlIHhtbCBub2RlXG4gKi9cbkVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVDaGlsZCA9IGZ1bmN0aW9uKG5vZGUpIHtcbiAgdmFyIHByb3BlcnR5RGVzYywgdHlwZSwgZWxlbWVudCwgY2hpbGRIYW5kbGVyO1xuXG4gIHByb3BlcnR5RGVzYyA9IHRoaXMuZ2V0UHJvcGVydHlGb3JOb2RlKG5vZGUpO1xuICBlbGVtZW50ID0gdGhpcy5lbGVtZW50O1xuXG4gIHR5cGUgPSBwcm9wZXJ0eURlc2MuZWZmZWN0aXZlVHlwZSB8fCBwcm9wZXJ0eURlc2MudHlwZTtcblxuICBpZiAoaXNTaW1wbGVUeXBlKHR5cGUpKSB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWVIYW5kbGVyKHByb3BlcnR5RGVzYywgZWxlbWVudCk7XG4gIH1cblxuICBpZiAocHJvcGVydHlEZXNjLmlzUmVmZXJlbmNlKSB7XG4gICAgY2hpbGRIYW5kbGVyID0gdGhpcy5yZWZlcmVuY2VIYW5kbGVyKHByb3BlcnR5RGVzYykuaGFuZGxlTm9kZShub2RlKTtcbiAgfSBlbHNlIHtcbiAgICBjaGlsZEhhbmRsZXIgPSB0aGlzLmhhbmRsZXIodHlwZSkuaGFuZGxlTm9kZShub2RlKTtcbiAgfVxuXG4gIHZhciBuZXdFbGVtZW50ID0gY2hpbGRIYW5kbGVyLmVsZW1lbnQ7XG5cbiAgLy8gY2hpbGQgaGFuZGxlcyBtYXkgZGVjaWRlIHRvIHNraXAgZWxlbWVudHNcbiAgLy8gYnkgbm90IHJldHVybmluZyBhbnl0aGluZ1xuICBpZiAobmV3RWxlbWVudCAhPT0gdW5kZWZpbmVkKSB7XG5cbiAgICBpZiAocHJvcGVydHlEZXNjLmlzTWFueSkge1xuICAgICAgZWxlbWVudC5nZXQocHJvcGVydHlEZXNjLm5hbWUpLnB1c2gobmV3RWxlbWVudCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQuc2V0KHByb3BlcnR5RGVzYy5uYW1lLCBuZXdFbGVtZW50KTtcbiAgICB9XG5cbiAgICBpZiAocHJvcGVydHlEZXNjLmlzUmVmZXJlbmNlKSB7XG4gICAgICBhc3NpZ24obmV3RWxlbWVudCwge1xuICAgICAgICBlbGVtZW50OiBlbGVtZW50XG4gICAgICB9KTtcblxuICAgICAgdGhpcy5jb250ZXh0LmFkZFJlZmVyZW5jZShuZXdFbGVtZW50KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gZXN0YWJsaXNoIGNoaWxkIC0+IHBhcmVudCByZWxhdGlvbnNoaXBcbiAgICAgIG5ld0VsZW1lbnQuJHBhcmVudCA9IGVsZW1lbnQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNoaWxkSGFuZGxlcjtcbn07XG5cbi8qKlxuICogQW4gZWxlbWVudCBoYW5kbGVyIHRoYXQgcGVyZm9ybXMgc3BlY2lhbCB2YWxpZGF0aW9uXG4gKiB0byBlbnN1cmUgdGhlIG5vZGUgaXQgZ2V0cyBpbml0aWFsaXplZCB3aXRoIG1hdGNoZXNcbiAqIHRoZSBoYW5kbGVycyB0eXBlIChuYW1lc3BhY2Ugd2lzZSkuXG4gKlxuICogQHBhcmFtIHtNb2RkbGV9IG1vZGVsXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZU5hbWVcbiAqIEBwYXJhbSB7Q29udGV4dH0gY29udGV4dFxuICovXG5mdW5jdGlvbiBSb290RWxlbWVudEhhbmRsZXIobW9kZWwsIHR5cGVOYW1lLCBjb250ZXh0KSB7XG4gIEVsZW1lbnRIYW5kbGVyLmNhbGwodGhpcywgbW9kZWwsIHR5cGVOYW1lLCBjb250ZXh0KTtcbn1cblxuUm9vdEVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoRWxlbWVudEhhbmRsZXIucHJvdG90eXBlKTtcblxuUm9vdEVsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5jcmVhdGVFbGVtZW50ID0gZnVuY3Rpb24obm9kZSkge1xuXG4gIHZhciBuYW1lID0gbm9kZS5uYW1lLFxuICAgICAgbmFtZU5zID0gcGFyc2VOYW1lTlMobmFtZSksXG4gICAgICBtb2RlbCA9IHRoaXMubW9kZWwsXG4gICAgICB0eXBlID0gdGhpcy50eXBlLFxuICAgICAgcGtnID0gbW9kZWwuZ2V0UGFja2FnZShuYW1lTnMucHJlZml4KSxcbiAgICAgIHR5cGVOYW1lID0gcGtnICYmIGFsaWFzVG9OYW1lKG5hbWVOcywgcGtnKSB8fCBuYW1lO1xuXG4gIC8vIHZlcmlmeSB0aGUgY29ycmVjdCBuYW1lc3BhY2UgaWYgd2UgcGFyc2VcbiAgLy8gdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIGhhbmRsZXIgdHJlZVxuICAvL1xuICAvLyB0aGlzIGVuc3VyZXMgd2UgZG9uJ3QgbWlzdGFrZW5seSBpbXBvcnQgd3JvbmcgbmFtZXNwYWNlIGVsZW1lbnRzXG4gIGlmICghdHlwZS5oYXNUeXBlKHR5cGVOYW1lKSkge1xuICAgIHRocm93IGVycm9yKCd1bmV4cGVjdGVkIGVsZW1lbnQgPCcgKyBub2RlLm9yaWdpbmFsTmFtZSArICc+Jyk7XG4gIH1cblxuICByZXR1cm4gRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmNyZWF0ZUVsZW1lbnQuY2FsbCh0aGlzLCBub2RlKTtcbn07XG5cblxuZnVuY3Rpb24gR2VuZXJpY0VsZW1lbnRIYW5kbGVyKG1vZGVsLCB0eXBlTmFtZSwgY29udGV4dCkge1xuICB0aGlzLm1vZGVsID0gbW9kZWw7XG4gIHRoaXMuY29udGV4dCA9IGNvbnRleHQ7XG59XG5cbkdlbmVyaWNFbGVtZW50SGFuZGxlci5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKEJhc2VFbGVtZW50SGFuZGxlci5wcm90b3R5cGUpO1xuXG5HZW5lcmljRWxlbWVudEhhbmRsZXIucHJvdG90eXBlLmNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgdmFyIG5hbWUgPSBub2RlLm5hbWUsXG4gICAgICBucyA9IHBhcnNlTmFtZU5TKG5hbWUpLFxuICAgICAgcHJlZml4ID0gbnMucHJlZml4LFxuICAgICAgdXJpID0gbm9kZS5uc1twcmVmaXggKyAnJHVyaSddLFxuICAgICAgYXR0cmlidXRlcyA9IG5vZGUuYXR0cmlidXRlcztcblxuICByZXR1cm4gdGhpcy5tb2RlbC5jcmVhdGVBbnkobmFtZSwgdXJpLCBhdHRyaWJ1dGVzKTtcbn07XG5cbkdlbmVyaWNFbGVtZW50SGFuZGxlci5wcm90b3R5cGUuaGFuZGxlQ2hpbGQgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgdmFyIGhhbmRsZXIgPSBuZXcgR2VuZXJpY0VsZW1lbnRIYW5kbGVyKHRoaXMubW9kZWwsICdFbGVtZW50JywgdGhpcy5jb250ZXh0KS5oYW5kbGVOb2RlKG5vZGUpLFxuICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblxuICB2YXIgbmV3RWxlbWVudCA9IGhhbmRsZXIuZWxlbWVudCxcbiAgICAgIGNoaWxkcmVuO1xuXG4gIGlmIChuZXdFbGVtZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICBjaGlsZHJlbiA9IGVsZW1lbnQuJGNoaWxkcmVuID0gZWxlbWVudC4kY2hpbGRyZW4gfHwgW107XG4gICAgY2hpbGRyZW4ucHVzaChuZXdFbGVtZW50KTtcblxuICAgIC8vIGVzdGFibGlzaCBjaGlsZCAtPiBwYXJlbnQgcmVsYXRpb25zaGlwXG4gICAgbmV3RWxlbWVudC4kcGFyZW50ID0gZWxlbWVudDtcbiAgfVxuXG4gIHJldHVybiBoYW5kbGVyO1xufTtcblxuR2VuZXJpY0VsZW1lbnRIYW5kbGVyLnByb3RvdHlwZS5oYW5kbGVFbmQgPSBmdW5jdGlvbigpIHtcbiAgaWYgKHRoaXMuYm9keSkge1xuICAgIHRoaXMuZWxlbWVudC4kYm9keSA9IHRoaXMuYm9keTtcbiAgfVxufTtcblxuLyoqXG4gKiBBIHJlYWRlciBmb3IgYSBtZXRhLW1vZGVsXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7TW9kZWx9IG9wdGlvbnMubW9kZWwgdXNlZCB0byByZWFkIHhtbCBmaWxlc1xuICogQHBhcmFtIHtCb29sZWFufSBvcHRpb25zLmxheCB3aGV0aGVyIHRvIG1ha2UgcGFyc2UgZXJyb3JzIHdhcm5pbmdzXG4gKi9cbmZ1bmN0aW9uIFJlYWRlcihvcHRpb25zKSB7XG5cbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBNb2RkbGUpIHtcbiAgICBvcHRpb25zID0ge1xuICAgICAgbW9kZWw6IG9wdGlvbnNcbiAgICB9O1xuICB9XG5cbiAgYXNzaWduKHRoaXMsIHsgbGF4OiBmYWxzZSB9LCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBUaGUgZnJvbVhNTCByZXN1bHQuXG4gKlxuICogQHR5cGVkZWYge09iamVjdH0gUGFyc2VSZXN1bHRcbiAqXG4gKiBAcHJvcGVydHkge01vZGRsZUVsZW1lbnR9IHJvb3RFbGVtZW50XG4gKiBAcHJvcGVydHkge0FycmF5PE9iamVjdD59IHJlZmVyZW5jZXNcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8RXJyb3I+fSB3YXJuaW5nc1xuICogQHByb3BlcnR5IHtPYmplY3R9IGVsZW1lbnRzQnlJZCAtIGEgbWFwcGluZyBjb250YWluaW5nIGVhY2ggSUQgLT4gTW9kZGxlRWxlbWVudFxuICovXG5cbi8qKlxuICogVGhlIGZyb21YTUwgcmVzdWx0LlxuICpcbiAqIEB0eXBlZGVmIHtFcnJvcn0gUGFyc2VFcnJvclxuICpcbiAqIEBwcm9wZXJ0eSB7QXJyYXk8RXJyb3I+fSB3YXJuaW5nc1xuICovXG5cbi8qKlxuICogUGFyc2UgdGhlIGdpdmVuIFhNTCBpbnRvIGEgbW9kZGxlIGRvY3VtZW50IHRyZWUuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IHhtbFxuICogQHBhcmFtIHtFbGVtZW50SGFuZGxlcnxPYmplY3R9IG9wdGlvbnMgb3Igcm9vdEhhbmRsZXJcbiAqXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxQYXJzZVJlc3VsdCwgUGFyc2VFcnJvcj59XG4gKi9cblJlYWRlci5wcm90b3R5cGUuZnJvbVhNTCA9IGZ1bmN0aW9uKHhtbCwgb3B0aW9ucywgZG9uZSkge1xuXG4gIHZhciByb290SGFuZGxlciA9IG9wdGlvbnMucm9vdEhhbmRsZXI7XG5cbiAgaWYgKG9wdGlvbnMgaW5zdGFuY2VvZiBFbGVtZW50SGFuZGxlcikge1xuICAgIC8vIHJvb3QgaGFuZGxlciBwYXNzZWQgdmlhICh4bWwsIHsgcm9vdEhhbmRsZXI6IEVsZW1lbnRIYW5kbGVyIH0sIC4uLilcbiAgICByb290SGFuZGxlciA9IG9wdGlvbnM7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9IGVsc2Uge1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIHJvb3RIYW5kbGVyIHBhc3NlZCB2aWEgKHhtbCwgJ3NvbWVTdHJpbmcnLCAuLi4pXG4gICAgICByb290SGFuZGxlciA9IHRoaXMuaGFuZGxlcihvcHRpb25zKTtcbiAgICAgIG9wdGlvbnMgPSB7fTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiByb290SGFuZGxlciA9PT0gJ3N0cmluZycpIHtcbiAgICAgIC8vIHJvb3RIYW5kbGVyIHBhc3NlZCB2aWEgKHhtbCwgeyByb290SGFuZGxlcjogJ3NvbWVTdHJpbmcnIH0sIC4uLilcbiAgICAgIHJvb3RIYW5kbGVyID0gdGhpcy5oYW5kbGVyKHJvb3RIYW5kbGVyKTtcbiAgICB9XG4gIH1cblxuICB2YXIgbW9kZWwgPSB0aGlzLm1vZGVsLFxuICAgICAgbGF4ID0gdGhpcy5sYXg7XG5cbiAgdmFyIGNvbnRleHQgPSBuZXcgQ29udGV4dChhc3NpZ24oe30sIG9wdGlvbnMsIHsgcm9vdEhhbmRsZXI6IHJvb3RIYW5kbGVyIH0pKSxcbiAgICAgIHBhcnNlciA9IG5ldyBQYXJzZXIoeyBwcm94eTogdHJ1ZSB9KSxcbiAgICAgIHN0YWNrID0gY3JlYXRlU3RhY2soKTtcblxuICByb290SGFuZGxlci5jb250ZXh0ID0gY29udGV4dDtcblxuICAvLyBwdXNoIHJvb3QgaGFuZGxlclxuICBzdGFjay5wdXNoKHJvb3RIYW5kbGVyKTtcblxuXG4gIC8qKlxuICAgKiBIYW5kbGUgZXJyb3IuXG4gICAqXG4gICAqIEBwYXJhbSAge0Vycm9yfSBlcnJcbiAgICogQHBhcmFtICB7RnVuY3Rpb259IGdldENvbnRleHRcbiAgICogQHBhcmFtICB7Ym9vbGVhbn0gbGF4XG4gICAqXG4gICAqIEByZXR1cm4ge2Jvb2xlYW59IHRydWUgaWYgaGFuZGxlZFxuICAgKi9cbiAgZnVuY3Rpb24gaGFuZGxlRXJyb3IoZXJyLCBnZXRDb250ZXh0LCBsYXgpIHtcblxuICAgIHZhciBjdHggPSBnZXRDb250ZXh0KCk7XG5cbiAgICB2YXIgbGluZSA9IGN0eC5saW5lLFxuICAgICAgICBjb2x1bW4gPSBjdHguY29sdW1uLFxuICAgICAgICBkYXRhID0gY3R4LmRhdGE7XG5cbiAgICAvLyB3ZSByZWNlaXZlIHRoZSBmdWxsIGNvbnRleHQgZGF0YSBoZXJlLFxuICAgIC8vIGZvciBlbGVtZW50cyB0cmltIGRvd24gdGhlIGluZm9ybWF0aW9uXG4gICAgLy8gdG8gdGhlIHRhZyBuYW1lLCBvbmx5XG4gICAgaWYgKGRhdGEuY2hhckF0KDApID09PSAnPCcgJiYgZGF0YS5pbmRleE9mKCcgJykgIT09IC0xKSB7XG4gICAgICBkYXRhID0gZGF0YS5zbGljZSgwLCBkYXRhLmluZGV4T2YoJyAnKSkgKyAnPic7XG4gICAgfVxuXG4gICAgdmFyIG1lc3NhZ2UgPVxuICAgICAgJ3VucGFyc2FibGUgY29udGVudCAnICsgKGRhdGEgPyBkYXRhICsgJyAnIDogJycpICsgJ2RldGVjdGVkXFxuXFx0JyArXG4gICAgICAgICdsaW5lOiAnICsgbGluZSArICdcXG5cXHQnICtcbiAgICAgICAgJ2NvbHVtbjogJyArIGNvbHVtbiArICdcXG5cXHQnICtcbiAgICAgICAgJ25lc3RlZCBlcnJvcjogJyArIGVyci5tZXNzYWdlO1xuXG4gICAgaWYgKGxheCkge1xuICAgICAgY29udGV4dC5hZGRXYXJuaW5nKHtcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgICAgZXJyb3I6IGVyclxuICAgICAgfSk7XG5cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBlcnJvcihtZXNzYWdlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVXYXJuaW5nKGVyciwgZ2V0Q29udGV4dCkge1xuICAgIC8vIGp1c3QgbGlrZSBoYW5kbGluZyBlcnJvcnMgaW4gPGxheD10cnVlPiBtb2RlXG4gICAgcmV0dXJuIGhhbmRsZUVycm9yKGVyciwgZ2V0Q29udGV4dCwgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSBjb2xsZWN0ZWQgcmVmZXJlbmNlcyBvbiBwYXJzZSBlbmQuXG4gICAqL1xuICBmdW5jdGlvbiByZXNvbHZlUmVmZXJlbmNlcygpIHtcblxuICAgIHZhciBlbGVtZW50c0J5SWQgPSBjb250ZXh0LmVsZW1lbnRzQnlJZDtcbiAgICB2YXIgcmVmZXJlbmNlcyA9IGNvbnRleHQucmVmZXJlbmNlcztcblxuICAgIHZhciBpLCByO1xuXG4gICAgZm9yIChpID0gMDsgKHIgPSByZWZlcmVuY2VzW2ldKTsgaSsrKSB7XG4gICAgICB2YXIgZWxlbWVudCA9IHIuZWxlbWVudDtcbiAgICAgIHZhciByZWZlcmVuY2UgPSBlbGVtZW50c0J5SWRbci5pZF07XG4gICAgICB2YXIgcHJvcGVydHkgPSBnZXRNb2RkbGVEZXNjcmlwdG9yKGVsZW1lbnQpLnByb3BlcnRpZXNCeU5hbWVbci5wcm9wZXJ0eV07XG5cbiAgICAgIGlmICghcmVmZXJlbmNlKSB7XG4gICAgICAgIGNvbnRleHQuYWRkV2FybmluZyh7XG4gICAgICAgICAgbWVzc2FnZTogJ3VucmVzb2x2ZWQgcmVmZXJlbmNlIDwnICsgci5pZCArICc+JyxcbiAgICAgICAgICBlbGVtZW50OiByLmVsZW1lbnQsXG4gICAgICAgICAgcHJvcGVydHk6IHIucHJvcGVydHksXG4gICAgICAgICAgdmFsdWU6IHIuaWRcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChwcm9wZXJ0eS5pc01hbnkpIHtcbiAgICAgICAgdmFyIGNvbGxlY3Rpb24gPSBlbGVtZW50LmdldChwcm9wZXJ0eS5uYW1lKSxcbiAgICAgICAgICAgIGlkeCA9IGNvbGxlY3Rpb24uaW5kZXhPZihyKTtcblxuICAgICAgICAvLyB3ZSByZXBsYWNlIGFuIGV4aXN0aW5nIHBsYWNlIGhvbGRlciAoaWR4ICE9IC0xKSBvclxuICAgICAgICAvLyBhcHBlbmQgdG8gdGhlIGNvbGxlY3Rpb24gaW5zdGVhZFxuICAgICAgICBpZiAoaWR4ID09PSAtMSkge1xuICAgICAgICAgIGlkeCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFyZWZlcmVuY2UpIHtcbiAgICAgICAgICAvLyByZW1vdmUgdW5yZXNvbHZhYmxlIHJlZmVyZW5jZVxuICAgICAgICAgIGNvbGxlY3Rpb24uc3BsaWNlKGlkeCwgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gYWRkIG9yIHVwZGF0ZSByZWZlcmVuY2UgaW4gY29sbGVjdGlvblxuICAgICAgICAgIGNvbGxlY3Rpb25baWR4XSA9IHJlZmVyZW5jZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWxlbWVudC5zZXQocHJvcGVydHkubmFtZSwgcmVmZXJlbmNlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVDbG9zZSgpIHtcbiAgICBzdGFjay5wb3AoKS5oYW5kbGVFbmQoKTtcbiAgfVxuXG4gIHZhciBQUkVBTUJMRV9TVEFSVF9QQVRURVJOID0gL148XFw/eG1sIC9pO1xuXG4gIHZhciBFTkNPRElOR19QQVRURVJOID0gLyBlbmNvZGluZz1cIihbXlwiXSspXCIvaTtcblxuICB2YXIgVVRGXzhfUEFUVEVSTiA9IC9edXRmLTgkL2k7XG5cbiAgZnVuY3Rpb24gaGFuZGxlUXVlc3Rpb24ocXVlc3Rpb24pIHtcblxuICAgIGlmICghUFJFQU1CTEVfU1RBUlRfUEFUVEVSTi50ZXN0KHF1ZXN0aW9uKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBtYXRjaCA9IEVOQ09ESU5HX1BBVFRFUk4uZXhlYyhxdWVzdGlvbik7XG4gICAgdmFyIGVuY29kaW5nID0gbWF0Y2ggJiYgbWF0Y2hbMV07XG5cbiAgICBpZiAoIWVuY29kaW5nIHx8IFVURl84X1BBVFRFUk4udGVzdChlbmNvZGluZykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb250ZXh0LmFkZFdhcm5pbmcoe1xuICAgICAgbWVzc2FnZTpcbiAgICAgICAgJ3Vuc3VwcG9ydGVkIGRvY3VtZW50IGVuY29kaW5nIDwnICsgZW5jb2RpbmcgKyAnPiwgJyArXG4gICAgICAgICdmYWxsaW5nIGJhY2sgdG8gVVRGLTgnXG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiBoYW5kbGVPcGVuKG5vZGUsIGdldENvbnRleHQpIHtcbiAgICB2YXIgaGFuZGxlciA9IHN0YWNrLnBlZWsoKTtcblxuICAgIHRyeSB7XG4gICAgICBzdGFjay5wdXNoKGhhbmRsZXIuaGFuZGxlTm9kZShub2RlKSk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG5cbiAgICAgIGlmIChoYW5kbGVFcnJvcihlcnIsIGdldENvbnRleHQsIGxheCkpIHtcbiAgICAgICAgc3RhY2sucHVzaChuZXcgTm9vcEhhbmRsZXIoKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaGFuZGxlQ0RhdGEodGV4dCwgZ2V0Q29udGV4dCkge1xuXG4gICAgdHJ5IHtcbiAgICAgIHN0YWNrLnBlZWsoKS5oYW5kbGVUZXh0KHRleHQpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaGFuZGxlV2FybmluZyhlcnIsIGdldENvbnRleHQpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGhhbmRsZVRleHQodGV4dCwgZ2V0Q29udGV4dCkge1xuICAgIC8vIHN0cmlwIHdoaXRlc3BhY2Ugb25seSBub2RlcywgaS5lLiBiZWZvcmVcbiAgICAvLyA8IUNEQVRBWyAuLi4gXT4gc2VjdGlvbnMgYW5kIGluIGJldHdlZW4gdGFnc1xuICAgIHRleHQgPSB0ZXh0LnRyaW0oKTtcblxuICAgIGlmICghdGV4dCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGhhbmRsZUNEYXRhKHRleHQsIGdldENvbnRleHQpO1xuICB9XG5cbiAgdmFyIHVyaU1hcCA9IG1vZGVsLmdldFBhY2thZ2VzKCkucmVkdWNlKGZ1bmN0aW9uKHVyaU1hcCwgcCkge1xuICAgIHVyaU1hcFtwLnVyaV0gPSBwLnByZWZpeDtcblxuICAgIHJldHVybiB1cmlNYXA7XG4gIH0sIHtcbiAgICAnaHR0cDovL3d3dy53My5vcmcvWE1MLzE5OTgvbmFtZXNwYWNlJzogJ3htbCcgLy8gYWRkIGRlZmF1bHQgeG1sIG5zXG4gIH0pO1xuICBwYXJzZXJcbiAgICAubnModXJpTWFwKVxuICAgIC5vbignb3BlblRhZycsIGZ1bmN0aW9uKG9iaiwgZGVjb2RlU3RyLCBzZWxmQ2xvc2luZywgZ2V0Q29udGV4dCkge1xuXG4gICAgICAvLyBncmFjZWZ1bGx5IGhhbmRsZSB1bnBhcnNhYmxlIGF0dHJpYnV0ZXMgKGF0dHJzPWZhbHNlKVxuICAgICAgdmFyIGF0dHJzID0gb2JqLmF0dHJzIHx8IHt9O1xuXG4gICAgICB2YXIgZGVjb2RlZEF0dHJzID0gT2JqZWN0LmtleXMoYXR0cnMpLnJlZHVjZShmdW5jdGlvbihkLCBrZXkpIHtcbiAgICAgICAgdmFyIHZhbHVlID0gZGVjb2RlU3RyKGF0dHJzW2tleV0pO1xuXG4gICAgICAgIGRba2V5XSA9IHZhbHVlO1xuXG4gICAgICAgIHJldHVybiBkO1xuICAgICAgfSwge30pO1xuXG4gICAgICB2YXIgbm9kZSA9IHtcbiAgICAgICAgbmFtZTogb2JqLm5hbWUsXG4gICAgICAgIG9yaWdpbmFsTmFtZTogb2JqLm9yaWdpbmFsTmFtZSxcbiAgICAgICAgYXR0cmlidXRlczogZGVjb2RlZEF0dHJzLFxuICAgICAgICBuczogb2JqLm5zXG4gICAgICB9O1xuXG4gICAgICBoYW5kbGVPcGVuKG5vZGUsIGdldENvbnRleHQpO1xuICAgIH0pXG4gICAgLm9uKCdxdWVzdGlvbicsIGhhbmRsZVF1ZXN0aW9uKVxuICAgIC5vbignY2xvc2VUYWcnLCBoYW5kbGVDbG9zZSlcbiAgICAub24oJ2NkYXRhJywgaGFuZGxlQ0RhdGEpXG4gICAgLm9uKCd0ZXh0JywgZnVuY3Rpb24odGV4dCwgZGVjb2RlRW50aXRpZXMsIGdldENvbnRleHQpIHtcbiAgICAgIGhhbmRsZVRleHQoZGVjb2RlRW50aXRpZXModGV4dCksIGdldENvbnRleHQpO1xuICAgIH0pXG4gICAgLm9uKCdlcnJvcicsIGhhbmRsZUVycm9yKVxuICAgIC5vbignd2FybicsIGhhbmRsZVdhcm5pbmcpO1xuXG4gIC8vIGFzeW5jIFhNTCBwYXJzaW5nIHRvIG1ha2Ugc3VyZSB0aGUgZXhlY3V0aW9uIGVudmlyb25tZW50XG4gIC8vIChub2RlIG9yIGJyb3dlcikgaXMga2VwdCByZXNwb25zaXZlIGFuZCB0aGF0IGNlcnRhaW4gb3B0aW1pemF0aW9uXG4gIC8vIHN0cmF0ZWdpZXMgY2FuIGtpY2sgaW4uXG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyZXNvbHZlLCByZWplY3QpIHtcblxuICAgIHZhciBlcnI7XG5cbiAgICB0cnkge1xuICAgICAgcGFyc2VyLnBhcnNlKHhtbCk7XG5cbiAgICAgIHJlc29sdmVSZWZlcmVuY2VzKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgZXJyID0gZTtcbiAgICB9XG5cbiAgICB2YXIgcm9vdEVsZW1lbnQgPSByb290SGFuZGxlci5lbGVtZW50O1xuXG4gICAgaWYgKCFlcnIgJiYgIXJvb3RFbGVtZW50KSB7XG4gICAgICBlcnIgPSBlcnJvcignZmFpbGVkIHRvIHBhcnNlIGRvY3VtZW50IGFzIDwnICsgcm9vdEhhbmRsZXIudHlwZS4kZGVzY3JpcHRvci5uYW1lICsgJz4nKTtcbiAgICB9XG5cbiAgICB2YXIgd2FybmluZ3MgPSBjb250ZXh0Lndhcm5pbmdzO1xuICAgIHZhciByZWZlcmVuY2VzID0gY29udGV4dC5yZWZlcmVuY2VzO1xuICAgIHZhciBlbGVtZW50c0J5SWQgPSBjb250ZXh0LmVsZW1lbnRzQnlJZDtcblxuICAgIGlmIChlcnIpIHtcbiAgICAgIGVyci53YXJuaW5ncyA9IHdhcm5pbmdzO1xuXG4gICAgICByZXR1cm4gcmVqZWN0KGVycik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByZXNvbHZlKHtcbiAgICAgICAgcm9vdEVsZW1lbnQ6IHJvb3RFbGVtZW50LFxuICAgICAgICBlbGVtZW50c0J5SWQ6IGVsZW1lbnRzQnlJZCxcbiAgICAgICAgcmVmZXJlbmNlczogcmVmZXJlbmNlcyxcbiAgICAgICAgd2FybmluZ3M6IHdhcm5pbmdzXG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xufTtcblxuUmVhZGVyLnByb3RvdHlwZS5oYW5kbGVyID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gbmV3IFJvb3RFbGVtZW50SGFuZGxlcih0aGlzLm1vZGVsLCBuYW1lKTtcbn07XG5cblxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5mdW5jdGlvbiBjcmVhdGVTdGFjaygpIHtcbiAgdmFyIHN0YWNrID0gW107XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHN0YWNrLCAncGVlaycsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gdGhpc1t0aGlzLmxlbmd0aCAtIDFdO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHN0YWNrO1xufVxuXG52YXIgWE1MX1BSRUFNQkxFID0gJzw/eG1sIHZlcnNpb249XCIxLjBcIiBlbmNvZGluZz1cIlVURi04XCI/Plxcbic7XG5cbnZhciBFU0NBUEVfQVRUUl9DSEFSUyA9IC88fD58J3xcInwmfFxcblxccnxcXG4vZztcbnZhciBFU0NBUEVfQ0hBUlMgPSAvPHw+fCYvZztcblxuXG5mdW5jdGlvbiBOYW1lc3BhY2VzKHBhcmVudCkge1xuXG4gIHZhciBwcmVmaXhNYXAgPSB7fTtcbiAgdmFyIHVyaU1hcCA9IHt9O1xuICB2YXIgdXNlZCA9IHt9O1xuXG4gIHZhciB3ZWxsa25vd24gPSBbXTtcbiAgdmFyIGN1c3RvbSA9IFtdO1xuXG4gIC8vIEFQSVxuXG4gIHRoaXMuYnlVcmkgPSBmdW5jdGlvbih1cmkpIHtcbiAgICByZXR1cm4gdXJpTWFwW3VyaV0gfHwgKFxuICAgICAgcGFyZW50ICYmIHBhcmVudC5ieVVyaSh1cmkpXG4gICAgKTtcbiAgfTtcblxuICB0aGlzLmFkZCA9IGZ1bmN0aW9uKG5zLCBpc1dlbGxrbm93bikge1xuXG4gICAgdXJpTWFwW25zLnVyaV0gPSBucztcblxuICAgIGlmIChpc1dlbGxrbm93bikge1xuICAgICAgd2VsbGtub3duLnB1c2gobnMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjdXN0b20ucHVzaChucyk7XG4gICAgfVxuXG4gICAgdGhpcy5tYXBQcmVmaXgobnMucHJlZml4LCBucy51cmkpO1xuICB9O1xuXG4gIHRoaXMudXJpQnlQcmVmaXggPSBmdW5jdGlvbihwcmVmaXgpIHtcbiAgICByZXR1cm4gcHJlZml4TWFwW3ByZWZpeCB8fCAneG1sbnMnXTtcbiAgfTtcblxuICB0aGlzLm1hcFByZWZpeCA9IGZ1bmN0aW9uKHByZWZpeCwgdXJpKSB7XG4gICAgcHJlZml4TWFwW3ByZWZpeCB8fCAneG1sbnMnXSA9IHVyaTtcbiAgfTtcblxuICB0aGlzLmdldE5TS2V5ID0gZnVuY3Rpb24obnMpIHtcbiAgICByZXR1cm4gKG5zLnByZWZpeCAhPT0gdW5kZWZpbmVkKSA/IChucy51cmkgKyAnfCcgKyBucy5wcmVmaXgpIDogbnMudXJpO1xuICB9O1xuXG4gIHRoaXMubG9nVXNlZCA9IGZ1bmN0aW9uKG5zKSB7XG5cbiAgICB2YXIgdXJpID0gbnMudXJpO1xuICAgIHZhciBuc0tleSA9IHRoaXMuZ2V0TlNLZXkobnMpO1xuXG4gICAgdXNlZFtuc0tleV0gPSB0aGlzLmJ5VXJpKHVyaSk7XG5cbiAgICAvLyBJbmZvcm0gcGFyZW50IHJlY3Vyc2l2ZWx5IGFib3V0IHRoZSB1c2FnZSBvZiB0aGlzIE5TXG4gICAgaWYgKHBhcmVudCkge1xuICAgICAgcGFyZW50LmxvZ1VzZWQobnMpO1xuICAgIH1cbiAgfTtcblxuICB0aGlzLmdldFVzZWQgPSBmdW5jdGlvbihucykge1xuXG4gICAgZnVuY3Rpb24gaXNVc2VkKG5zKSB7XG4gICAgICB2YXIgbnNLZXkgPSBzZWxmLmdldE5TS2V5KG5zKTtcblxuICAgICAgcmV0dXJuIHVzZWRbbnNLZXldO1xuICAgIH1cblxuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIHZhciBhbGxOcyA9IFtdLmNvbmNhdCh3ZWxsa25vd24sIGN1c3RvbSk7XG5cbiAgICByZXR1cm4gYWxsTnMuZmlsdGVyKGlzVXNlZCk7XG4gIH07XG5cbn1cblxuZnVuY3Rpb24gbG93ZXIoc3RyaW5nKSB7XG4gIHJldHVybiBzdHJpbmcuY2hhckF0KDApLnRvTG93ZXJDYXNlKCkgKyBzdHJpbmcuc2xpY2UoMSk7XG59XG5cbmZ1bmN0aW9uIG5hbWVUb0FsaWFzKG5hbWUsIHBrZykge1xuICBpZiAoaGFzTG93ZXJDYXNlQWxpYXMocGtnKSkge1xuICAgIHJldHVybiBsb3dlcihuYW1lKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gbmFtZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3I7XG4gIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IHtcbiAgICAgIHZhbHVlOiBjdG9yLFxuICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICB3cml0YWJsZTogdHJ1ZSxcbiAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG5zTmFtZShucykge1xuICBpZiAoaXNTdHJpbmcobnMpKSB7XG4gICAgcmV0dXJuIG5zO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiAobnMucHJlZml4ID8gbnMucHJlZml4ICsgJzonIDogJycpICsgbnMubG9jYWxOYW1lO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldE5zQXR0cnMobmFtZXNwYWNlcykge1xuXG4gIHJldHVybiBtYXAobmFtZXNwYWNlcy5nZXRVc2VkKCksIGZ1bmN0aW9uKG5zKSB7XG4gICAgdmFyIG5hbWUgPSAneG1sbnMnICsgKG5zLnByZWZpeCA/ICc6JyArIG5zLnByZWZpeCA6ICcnKTtcbiAgICByZXR1cm4geyBuYW1lOiBuYW1lLCB2YWx1ZTogbnMudXJpIH07XG4gIH0pO1xuXG59XG5cbmZ1bmN0aW9uIGdldEVsZW1lbnROcyhucywgZGVzY3JpcHRvcikge1xuICBpZiAoZGVzY3JpcHRvci5pc0dlbmVyaWMpIHtcbiAgICByZXR1cm4gYXNzaWduKHsgbG9jYWxOYW1lOiBkZXNjcmlwdG9yLm5zLmxvY2FsTmFtZSB9LCBucyk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGFzc2lnbih7IGxvY2FsTmFtZTogbmFtZVRvQWxpYXMoZGVzY3JpcHRvci5ucy5sb2NhbE5hbWUsIGRlc2NyaXB0b3IuJHBrZykgfSwgbnMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGdldFByb3BlcnR5TnMobnMsIGRlc2NyaXB0b3IpIHtcbiAgcmV0dXJuIGFzc2lnbih7IGxvY2FsTmFtZTogZGVzY3JpcHRvci5ucy5sb2NhbE5hbWUgfSwgbnMpO1xufVxuXG5mdW5jdGlvbiBnZXRTZXJpYWxpemFibGVQcm9wZXJ0aWVzKGVsZW1lbnQpIHtcbiAgdmFyIGRlc2NyaXB0b3IgPSBlbGVtZW50LiRkZXNjcmlwdG9yO1xuXG4gIHJldHVybiBmaWx0ZXIoZGVzY3JpcHRvci5wcm9wZXJ0aWVzLCBmdW5jdGlvbihwKSB7XG4gICAgdmFyIG5hbWUgPSBwLm5hbWU7XG5cbiAgICBpZiAocC5pc1ZpcnR1YWwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBkbyBub3Qgc2VyaWFsaXplIGRlZmF1bHRzXG4gICAgaWYgKCFlbGVtZW50Lmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIHZhbHVlID0gZWxlbWVudFtuYW1lXTtcblxuICAgIC8vIGRvIG5vdCBzZXJpYWxpemUgZGVmYXVsdCBlcXVhbHNcbiAgICBpZiAodmFsdWUgPT09IHAuZGVmYXVsdCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIC8vIGRvIG5vdCBzZXJpYWxpemUgbnVsbCBwcm9wZXJ0aWVzXG4gICAgaWYgKHZhbHVlID09PSBudWxsKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHAuaXNNYW55ID8gdmFsdWUubGVuZ3RoIDogdHJ1ZTtcbiAgfSk7XG59XG5cbnZhciBFU0NBUEVfQVRUUl9NQVAgPSB7XG4gICdcXG4nOiAnIzEwJyxcbiAgJ1xcblxccic6ICcjMTAnLFxuICAnXCInOiAnIzM0JyxcbiAgJ1xcJyc6ICcjMzknLFxuICAnPCc6ICcjNjAnLFxuICAnPic6ICcjNjInLFxuICAnJic6ICcjMzgnXG59O1xuXG52YXIgRVNDQVBFX01BUCA9IHtcbiAgJzwnOiAnbHQnLFxuICAnPic6ICdndCcsXG4gICcmJzogJ2FtcCdcbn07XG5cbmZ1bmN0aW9uIGVzY2FwZShzdHIsIGNoYXJQYXR0ZXJuLCByZXBsYWNlTWFwKSB7XG5cbiAgLy8gZW5zdXJlIHdlIGFyZSBoYW5kbGluZyBzdHJpbmdzIGhlcmVcbiAgc3RyID0gaXNTdHJpbmcoc3RyKSA/IHN0ciA6ICcnICsgc3RyO1xuXG4gIHJldHVybiBzdHIucmVwbGFjZShjaGFyUGF0dGVybiwgZnVuY3Rpb24ocykge1xuICAgIHJldHVybiAnJicgKyByZXBsYWNlTWFwW3NdICsgJzsnO1xuICB9KTtcbn1cblxuLyoqXG4gKiBFc2NhcGUgYSBzdHJpbmcgYXR0cmlidXRlIHRvIG5vdCBjb250YWluIGFueSBiYWQgdmFsdWVzIChsaW5lIGJyZWFrcywgJ1wiJywgLi4uKVxuICpcbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgdGhlIHN0cmluZyB0byBlc2NhcGVcbiAqIEByZXR1cm4ge1N0cmluZ30gdGhlIGVzY2FwZWQgc3RyaW5nXG4gKi9cbmZ1bmN0aW9uIGVzY2FwZUF0dHIoc3RyKSB7XG4gIHJldHVybiBlc2NhcGUoc3RyLCBFU0NBUEVfQVRUUl9DSEFSUywgRVNDQVBFX0FUVFJfTUFQKTtcbn1cblxuZnVuY3Rpb24gZXNjYXBlQm9keShzdHIpIHtcbiAgcmV0dXJuIGVzY2FwZShzdHIsIEVTQ0FQRV9DSEFSUywgRVNDQVBFX01BUCk7XG59XG5cbmZ1bmN0aW9uIGZpbHRlckF0dHJpYnV0ZXMocHJvcHMpIHtcbiAgcmV0dXJuIGZpbHRlcihwcm9wcywgZnVuY3Rpb24ocCkgeyByZXR1cm4gcC5pc0F0dHI7IH0pO1xufVxuXG5mdW5jdGlvbiBmaWx0ZXJDb250YWluZWQocHJvcHMpIHtcbiAgcmV0dXJuIGZpbHRlcihwcm9wcywgZnVuY3Rpb24ocCkgeyByZXR1cm4gIXAuaXNBdHRyOyB9KTtcbn1cblxuXG5mdW5jdGlvbiBSZWZlcmVuY2VTZXJpYWxpemVyKHRhZ05hbWUpIHtcbiAgdGhpcy50YWdOYW1lID0gdGFnTmFtZTtcbn1cblxuUmVmZXJlbmNlU2VyaWFsaXplci5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG4gIHJldHVybiB0aGlzO1xufTtcblxuUmVmZXJlbmNlU2VyaWFsaXplci5wcm90b3R5cGUuc2VyaWFsaXplVG8gPSBmdW5jdGlvbih3cml0ZXIpIHtcbiAgd3JpdGVyXG4gICAgLmFwcGVuZEluZGVudCgpXG4gICAgLmFwcGVuZCgnPCcgKyB0aGlzLnRhZ05hbWUgKyAnPicgKyB0aGlzLmVsZW1lbnQuaWQgKyAnPC8nICsgdGhpcy50YWdOYW1lICsgJz4nKVxuICAgIC5hcHBlbmROZXdMaW5lKCk7XG59O1xuXG5mdW5jdGlvbiBCb2R5U2VyaWFsaXplcigpIHt9XG5cbkJvZHlTZXJpYWxpemVyLnByb3RvdHlwZS5zZXJpYWxpemVWYWx1ZSA9XG5Cb2R5U2VyaWFsaXplci5wcm90b3R5cGUuc2VyaWFsaXplVG8gPSBmdW5jdGlvbih3cml0ZXIpIHtcbiAgd3JpdGVyLmFwcGVuZChcbiAgICB0aGlzLmVzY2FwZVxuICAgICAgPyBlc2NhcGVCb2R5KHRoaXMudmFsdWUpXG4gICAgICA6IHRoaXMudmFsdWVcbiAgKTtcbn07XG5cbkJvZHlTZXJpYWxpemVyLnByb3RvdHlwZS5idWlsZCA9IGZ1bmN0aW9uKHByb3AsIHZhbHVlKSB7XG4gIHRoaXMudmFsdWUgPSB2YWx1ZTtcblxuICBpZiAocHJvcC50eXBlID09PSAnU3RyaW5nJyAmJiB2YWx1ZS5zZWFyY2goRVNDQVBFX0NIQVJTKSAhPT0gLTEpIHtcbiAgICB0aGlzLmVzY2FwZSA9IHRydWU7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIFZhbHVlU2VyaWFsaXplcih0YWdOYW1lKSB7XG4gIHRoaXMudGFnTmFtZSA9IHRhZ05hbWU7XG59XG5cbmluaGVyaXRzKFZhbHVlU2VyaWFsaXplciwgQm9keVNlcmlhbGl6ZXIpO1xuXG5WYWx1ZVNlcmlhbGl6ZXIucHJvdG90eXBlLnNlcmlhbGl6ZVRvID0gZnVuY3Rpb24od3JpdGVyKSB7XG5cbiAgd3JpdGVyXG4gICAgLmFwcGVuZEluZGVudCgpXG4gICAgLmFwcGVuZCgnPCcgKyB0aGlzLnRhZ05hbWUgKyAnPicpO1xuXG4gIHRoaXMuc2VyaWFsaXplVmFsdWUod3JpdGVyKTtcblxuICB3cml0ZXJcbiAgICAuYXBwZW5kKCc8LycgKyB0aGlzLnRhZ05hbWUgKyAnPicpXG4gICAgLmFwcGVuZE5ld0xpbmUoKTtcbn07XG5cbmZ1bmN0aW9uIEVsZW1lbnRTZXJpYWxpemVyKHBhcmVudCwgcHJvcGVydHlEZXNjcmlwdG9yKSB7XG4gIHRoaXMuYm9keSA9IFtdO1xuICB0aGlzLmF0dHJzID0gW107XG5cbiAgdGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG4gIHRoaXMucHJvcGVydHlEZXNjcmlwdG9yID0gcHJvcGVydHlEZXNjcmlwdG9yO1xufVxuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUuYnVpbGQgPSBmdW5jdGlvbihlbGVtZW50KSB7XG4gIHRoaXMuZWxlbWVudCA9IGVsZW1lbnQ7XG5cbiAgdmFyIGVsZW1lbnREZXNjcmlwdG9yID0gZWxlbWVudC4kZGVzY3JpcHRvcixcbiAgICAgIHByb3BlcnR5RGVzY3JpcHRvciA9IHRoaXMucHJvcGVydHlEZXNjcmlwdG9yO1xuXG4gIHZhciBvdGhlckF0dHJzLFxuICAgICAgcHJvcGVydGllcztcblxuICB2YXIgaXNHZW5lcmljID0gZWxlbWVudERlc2NyaXB0b3IuaXNHZW5lcmljO1xuXG4gIGlmIChpc0dlbmVyaWMpIHtcbiAgICBvdGhlckF0dHJzID0gdGhpcy5wYXJzZUdlbmVyaWMoZWxlbWVudCk7XG4gIH0gZWxzZSB7XG4gICAgb3RoZXJBdHRycyA9IHRoaXMucGFyc2VOc0F0dHJpYnV0ZXMoZWxlbWVudCk7XG4gIH1cblxuICBpZiAocHJvcGVydHlEZXNjcmlwdG9yKSB7XG4gICAgdGhpcy5ucyA9IHRoaXMubnNQcm9wZXJ0eVRhZ05hbWUocHJvcGVydHlEZXNjcmlwdG9yKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLm5zID0gdGhpcy5uc1RhZ05hbWUoZWxlbWVudERlc2NyaXB0b3IpO1xuICB9XG5cbiAgLy8gY29tcHV0ZSB0YWcgbmFtZVxuICB0aGlzLnRhZ05hbWUgPSB0aGlzLmFkZFRhZ05hbWUodGhpcy5ucyk7XG5cbiAgaWYgKCFpc0dlbmVyaWMpIHtcbiAgICBwcm9wZXJ0aWVzID0gZ2V0U2VyaWFsaXphYmxlUHJvcGVydGllcyhlbGVtZW50KTtcblxuICAgIHRoaXMucGFyc2VBdHRyaWJ1dGVzKGZpbHRlckF0dHJpYnV0ZXMocHJvcGVydGllcykpO1xuICAgIHRoaXMucGFyc2VDb250YWlubWVudHMoZmlsdGVyQ29udGFpbmVkKHByb3BlcnRpZXMpKTtcbiAgfVxuXG4gIHRoaXMucGFyc2VHZW5lcmljQXR0cmlidXRlcyhlbGVtZW50LCBvdGhlckF0dHJzKTtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbkVsZW1lbnRTZXJpYWxpemVyLnByb3RvdHlwZS5uc1RhZ05hbWUgPSBmdW5jdGlvbihkZXNjcmlwdG9yKSB7XG4gIHZhciBlZmZlY3RpdmVOcyA9IHRoaXMubG9nTmFtZXNwYWNlVXNlZChkZXNjcmlwdG9yLm5zKTtcbiAgcmV0dXJuIGdldEVsZW1lbnROcyhlZmZlY3RpdmVOcywgZGVzY3JpcHRvcik7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUubnNQcm9wZXJ0eVRhZ05hbWUgPSBmdW5jdGlvbihkZXNjcmlwdG9yKSB7XG4gIHZhciBlZmZlY3RpdmVOcyA9IHRoaXMubG9nTmFtZXNwYWNlVXNlZChkZXNjcmlwdG9yLm5zKTtcbiAgcmV0dXJuIGdldFByb3BlcnR5TnMoZWZmZWN0aXZlTnMsIGRlc2NyaXB0b3IpO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLmlzTG9jYWxOcyA9IGZ1bmN0aW9uKG5zKSB7XG4gIHJldHVybiBucy51cmkgPT09IHRoaXMubnMudXJpO1xufTtcblxuLyoqXG4gKiBHZXQgdGhlIGFjdHVhbCBucyBhdHRyaWJ1dGUgbmFtZSBmb3IgdGhlIGdpdmVuIGVsZW1lbnQuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnRcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW2VsZW1lbnQuaW5oZXJpdGVkPWZhbHNlXVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gbnNOYW1lXG4gKi9cbkVsZW1lbnRTZXJpYWxpemVyLnByb3RvdHlwZS5uc0F0dHJpYnV0ZU5hbWUgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgdmFyIG5zO1xuXG4gIGlmIChpc1N0cmluZyhlbGVtZW50KSkge1xuICAgIG5zID0gcGFyc2VOYW1lTlMoZWxlbWVudCk7XG4gIH0gZWxzZSB7XG4gICAgbnMgPSBlbGVtZW50Lm5zO1xuICB9XG5cbiAgLy8gcmV0dXJuIGp1c3QgbG9jYWwgbmFtZSBmb3IgaW5oZXJpdGVkIGF0dHJpYnV0ZXNcbiAgaWYgKGVsZW1lbnQuaW5oZXJpdGVkKSB7XG4gICAgcmV0dXJuIHsgbG9jYWxOYW1lOiBucy5sb2NhbE5hbWUgfTtcbiAgfVxuXG4gIC8vIHBhcnNlICsgbG9nIGVmZmVjdGl2ZSBuc1xuICB2YXIgZWZmZWN0aXZlTnMgPSB0aGlzLmxvZ05hbWVzcGFjZVVzZWQobnMpO1xuXG4gIC8vIExPRyBBQ1RVQUwgbmFtZXNwYWNlIHVzZVxuICB0aGlzLmdldE5hbWVzcGFjZXMoKS5sb2dVc2VkKGVmZmVjdGl2ZU5zKTtcblxuICAvLyBzdHJpcCBwcmVmaXggaWYgc2FtZSBuYW1lc3BhY2UgbGlrZSBwYXJlbnRcbiAgaWYgKHRoaXMuaXNMb2NhbE5zKGVmZmVjdGl2ZU5zKSkge1xuICAgIHJldHVybiB7IGxvY2FsTmFtZTogbnMubG9jYWxOYW1lIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGFzc2lnbih7IGxvY2FsTmFtZTogbnMubG9jYWxOYW1lIH0sIGVmZmVjdGl2ZU5zKTtcbiAgfVxufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLnBhcnNlR2VuZXJpYyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcblxuICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICBib2R5ID0gdGhpcy5ib2R5O1xuXG4gIHZhciBhdHRyaWJ1dGVzID0gW107XG5cbiAgZm9yRWFjaChlbGVtZW50LCBmdW5jdGlvbih2YWwsIGtleSkge1xuXG4gICAgdmFyIG5vbk5zQXR0cjtcblxuICAgIGlmIChrZXkgPT09ICckYm9keScpIHtcbiAgICAgIGJvZHkucHVzaChuZXcgQm9keVNlcmlhbGl6ZXIoKS5idWlsZCh7IHR5cGU6ICdTdHJpbmcnIH0sIHZhbCkpO1xuICAgIH0gZWxzZVxuICAgIGlmIChrZXkgPT09ICckY2hpbGRyZW4nKSB7XG4gICAgICBmb3JFYWNoKHZhbCwgZnVuY3Rpb24oY2hpbGQpIHtcbiAgICAgICAgYm9keS5wdXNoKG5ldyBFbGVtZW50U2VyaWFsaXplcihzZWxmKS5idWlsZChjaGlsZCkpO1xuICAgICAgfSk7XG4gICAgfSBlbHNlXG4gICAgaWYgKGtleS5pbmRleE9mKCckJykgIT09IDApIHtcbiAgICAgIG5vbk5zQXR0ciA9IHNlbGYucGFyc2VOc0F0dHJpYnV0ZShlbGVtZW50LCBrZXksIHZhbCk7XG5cbiAgICAgIGlmIChub25Oc0F0dHIpIHtcbiAgICAgICAgYXR0cmlidXRlcy5wdXNoKHsgbmFtZToga2V5LCB2YWx1ZTogdmFsIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGF0dHJpYnV0ZXM7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VOc0F0dHJpYnV0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5hbWUsIHZhbHVlKSB7XG4gIHZhciBtb2RlbCA9IGVsZW1lbnQuJG1vZGVsO1xuXG4gIHZhciBuYW1lTnMgPSBwYXJzZU5hbWVOUyhuYW1lKTtcblxuICB2YXIgbnM7XG5cbiAgLy8gcGFyc2UgeG1sbnM6Zm9vPVwiaHR0cDovL2Zvby5iYXJcIlxuICBpZiAobmFtZU5zLnByZWZpeCA9PT0gJ3htbG5zJykge1xuICAgIG5zID0geyBwcmVmaXg6IG5hbWVOcy5sb2NhbE5hbWUsIHVyaTogdmFsdWUgfTtcbiAgfVxuXG4gIC8vIHBhcnNlIHhtbG5zPVwiaHR0cDovL2Zvby5iYXJcIlxuICBpZiAoIW5hbWVOcy5wcmVmaXggJiYgbmFtZU5zLmxvY2FsTmFtZSA9PT0gJ3htbG5zJykge1xuICAgIG5zID0geyB1cmk6IHZhbHVlIH07XG4gIH1cblxuICBpZiAoIW5zKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5hbWU6IG5hbWUsXG4gICAgICB2YWx1ZTogdmFsdWVcbiAgICB9O1xuICB9XG5cbiAgaWYgKG1vZGVsICYmIG1vZGVsLmdldFBhY2thZ2UodmFsdWUpKSB7XG4gICAgLy8gcmVnaXN0ZXIgd2VsbCBrbm93biBuYW1lc3BhY2VcbiAgICB0aGlzLmxvZ05hbWVzcGFjZShucywgdHJ1ZSwgdHJ1ZSk7XG4gIH0gZWxzZSB7XG4gICAgLy8gbG9nIGN1c3RvbSBuYW1lc3BhY2UgZGlyZWN0bHkgYXMgdXNlZFxuICAgIHZhciBhY3R1YWxOcyA9IHRoaXMubG9nTmFtZXNwYWNlVXNlZChucywgdHJ1ZSk7XG5cbiAgICB0aGlzLmdldE5hbWVzcGFjZXMoKS5sb2dVc2VkKGFjdHVhbE5zKTtcbiAgfVxufTtcblxuXG4vKipcbiAqIFBhcnNlIG5hbWVzcGFjZXMgYW5kIHJldHVybiBhIGxpc3Qgb2YgbGVmdCBvdmVyIGdlbmVyaWMgYXR0cmlidXRlc1xuICpcbiAqIEBwYXJhbSAge09iamVjdH0gZWxlbWVudFxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn1cbiAqL1xuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLnBhcnNlTnNBdHRyaWJ1dGVzID0gZnVuY3Rpb24oZWxlbWVudCwgYXR0cnMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIHZhciBnZW5lcmljQXR0cnMgPSBlbGVtZW50LiRhdHRycztcblxuICB2YXIgYXR0cmlidXRlcyA9IFtdO1xuXG4gIC8vIHBhcnNlIG5hbWVzcGFjZSBhdHRyaWJ1dGVzIGZpcnN0XG4gIC8vIGFuZCBsb2cgdGhlbS4gcHVzaCBub24gbmFtZXNwYWNlIGF0dHJpYnV0ZXMgdG8gYSBsaXN0XG4gIC8vIGFuZCBwcm9jZXNzIHRoZW0gbGF0ZXJcbiAgZm9yRWFjaChnZW5lcmljQXR0cnMsIGZ1bmN0aW9uKHZhbHVlLCBuYW1lKSB7XG5cbiAgICB2YXIgbm9uTnNBdHRyID0gc2VsZi5wYXJzZU5zQXR0cmlidXRlKGVsZW1lbnQsIG5hbWUsIHZhbHVlKTtcblxuICAgIGlmIChub25Oc0F0dHIpIHtcbiAgICAgIGF0dHJpYnV0ZXMucHVzaChub25Oc0F0dHIpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGF0dHJpYnV0ZXM7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VHZW5lcmljQXR0cmlidXRlcyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGF0dHJpYnV0ZXMpIHtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZm9yRWFjaChhdHRyaWJ1dGVzLCBmdW5jdGlvbihhdHRyKSB7XG5cbiAgICAvLyBkbyBub3Qgc2VyaWFsaXplIHhzaTp0eXBlIGF0dHJpYnV0ZVxuICAgIC8vIGl0IGlzIHNldCBtYW51YWxseSBiYXNlZCBvbiB0aGUgYWN0dWFsIGltcGxlbWVudGF0aW9uIHR5cGVcbiAgICBpZiAoYXR0ci5uYW1lID09PSBYU0lfVFlQRSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBzZWxmLmFkZEF0dHJpYnV0ZShzZWxmLm5zQXR0cmlidXRlTmFtZShhdHRyLm5hbWUpLCBhdHRyLnZhbHVlKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICdtaXNzaW5nIG5hbWVzcGFjZSBpbmZvcm1hdGlvbiBmb3IgJyxcbiAgICAgICAgYXR0ci5uYW1lLCAnPScsIGF0dHIudmFsdWUsICdvbicsIGVsZW1lbnQsXG4gICAgICAgIGUpO1xuICAgIH1cbiAgfSk7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VDb250YWlubWVudHMgPSBmdW5jdGlvbihwcm9wZXJ0aWVzKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgYm9keSA9IHRoaXMuYm9keSxcbiAgICAgIGVsZW1lbnQgPSB0aGlzLmVsZW1lbnQ7XG5cbiAgZm9yRWFjaChwcm9wZXJ0aWVzLCBmdW5jdGlvbihwKSB7XG4gICAgdmFyIHZhbHVlID0gZWxlbWVudC5nZXQocC5uYW1lKSxcbiAgICAgICAgaXNSZWZlcmVuY2UgPSBwLmlzUmVmZXJlbmNlLFxuICAgICAgICBpc01hbnkgPSBwLmlzTWFueTtcblxuICAgIGlmICghaXNNYW55KSB7XG4gICAgICB2YWx1ZSA9IFsgdmFsdWUgXTtcbiAgICB9XG5cbiAgICBpZiAocC5pc0JvZHkpIHtcbiAgICAgIGJvZHkucHVzaChuZXcgQm9keVNlcmlhbGl6ZXIoKS5idWlsZChwLCB2YWx1ZVswXSkpO1xuICAgIH0gZWxzZVxuICAgIGlmIChpc1NpbXBsZVR5cGUocC50eXBlKSkge1xuICAgICAgZm9yRWFjaCh2YWx1ZSwgZnVuY3Rpb24odikge1xuICAgICAgICBib2R5LnB1c2gobmV3IFZhbHVlU2VyaWFsaXplcihzZWxmLmFkZFRhZ05hbWUoc2VsZi5uc1Byb3BlcnR5VGFnTmFtZShwKSkpLmJ1aWxkKHAsIHYpKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZVxuICAgIGlmIChpc1JlZmVyZW5jZSkge1xuICAgICAgZm9yRWFjaCh2YWx1ZSwgZnVuY3Rpb24odikge1xuICAgICAgICBib2R5LnB1c2gobmV3IFJlZmVyZW5jZVNlcmlhbGl6ZXIoc2VsZi5hZGRUYWdOYW1lKHNlbGYubnNQcm9wZXJ0eVRhZ05hbWUocCkpKS5idWlsZCh2KSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gYWxsb3cgc2VyaWFsaXphdGlvbiB2aWEgdHlwZVxuICAgICAgLy8gcmF0aGVyIHRoYW4gZWxlbWVudCBuYW1lXG4gICAgICB2YXIgYXNUeXBlID0gc2VyaWFsaXplQXNUeXBlKHApLFxuICAgICAgICAgIGFzUHJvcGVydHkgPSBzZXJpYWxpemVBc1Byb3BlcnR5KHApO1xuXG4gICAgICBmb3JFYWNoKHZhbHVlLCBmdW5jdGlvbih2KSB7XG4gICAgICAgIHZhciBzZXJpYWxpemVyO1xuXG4gICAgICAgIGlmIChhc1R5cGUpIHtcbiAgICAgICAgICBzZXJpYWxpemVyID0gbmV3IFR5cGVTZXJpYWxpemVyKHNlbGYsIHApO1xuICAgICAgICB9IGVsc2VcbiAgICAgICAgaWYgKGFzUHJvcGVydHkpIHtcbiAgICAgICAgICBzZXJpYWxpemVyID0gbmV3IEVsZW1lbnRTZXJpYWxpemVyKHNlbGYsIHApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNlcmlhbGl6ZXIgPSBuZXcgRWxlbWVudFNlcmlhbGl6ZXIoc2VsZik7XG4gICAgICAgIH1cblxuICAgICAgICBib2R5LnB1c2goc2VyaWFsaXplci5idWlsZCh2KSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH0pO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLmdldE5hbWVzcGFjZXMgPSBmdW5jdGlvbihsb2NhbCkge1xuXG4gIHZhciBuYW1lc3BhY2VzID0gdGhpcy5uYW1lc3BhY2VzLFxuICAgICAgcGFyZW50ID0gdGhpcy5wYXJlbnQsXG4gICAgICBwYXJlbnROYW1lc3BhY2VzO1xuXG4gIGlmICghbmFtZXNwYWNlcykge1xuICAgIHBhcmVudE5hbWVzcGFjZXMgPSBwYXJlbnQgJiYgcGFyZW50LmdldE5hbWVzcGFjZXMoKTtcblxuICAgIGlmIChsb2NhbCB8fCAhcGFyZW50TmFtZXNwYWNlcykge1xuICAgICAgdGhpcy5uYW1lc3BhY2VzID0gbmFtZXNwYWNlcyA9IG5ldyBOYW1lc3BhY2VzKHBhcmVudE5hbWVzcGFjZXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lc3BhY2VzID0gcGFyZW50TmFtZXNwYWNlcztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbmFtZXNwYWNlcztcbn07XG5cbkVsZW1lbnRTZXJpYWxpemVyLnByb3RvdHlwZS5sb2dOYW1lc3BhY2UgPSBmdW5jdGlvbihucywgd2VsbGtub3duLCBsb2NhbCkge1xuICB2YXIgbmFtZXNwYWNlcyA9IHRoaXMuZ2V0TmFtZXNwYWNlcyhsb2NhbCk7XG5cbiAgdmFyIG5zVXJpID0gbnMudXJpLFxuICAgICAgbnNQcmVmaXggPSBucy5wcmVmaXg7XG5cbiAgdmFyIGV4aXN0aW5nID0gbmFtZXNwYWNlcy5ieVVyaShuc1VyaSk7XG5cbiAgaWYgKG5zUHJlZml4ICE9PSAneG1sJyAmJiAoIWV4aXN0aW5nIHx8IGxvY2FsKSkge1xuICAgIG5hbWVzcGFjZXMuYWRkKG5zLCB3ZWxsa25vd24pO1xuICB9XG5cbiAgbmFtZXNwYWNlcy5tYXBQcmVmaXgobnNQcmVmaXgsIG5zVXJpKTtcblxuICByZXR1cm4gbnM7XG59O1xuXG5FbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUubG9nTmFtZXNwYWNlVXNlZCA9IGZ1bmN0aW9uKG5zLCBsb2NhbCkge1xuICB2YXIgZWxlbWVudCA9IHRoaXMuZWxlbWVudCxcbiAgICAgIG1vZGVsID0gZWxlbWVudC4kbW9kZWwsXG4gICAgICBuYW1lc3BhY2VzID0gdGhpcy5nZXROYW1lc3BhY2VzKGxvY2FsKTtcblxuICAvLyBucyBtYXkgYmVcbiAgLy9cbiAgLy8gICAqIHByZWZpeCBvbmx5XG4gIC8vICAgKiBwcmVmaXg6dXJpXG4gIC8vICAgKiBsb2NhbE5hbWUgb25seVxuXG4gIHZhciBwcmVmaXggPSBucy5wcmVmaXgsXG4gICAgICB1cmkgPSBucy51cmksXG4gICAgICBuZXdQcmVmaXgsIGlkeCxcbiAgICAgIHdlbGxrbm93blVyaTtcblxuICAvLyBoYW5kbGUgYW5vbnltb3VzIG5hbWVzcGFjZXMgKGVsZW1lbnRGb3JtPXVucXVhbGlmaWVkKSwgY2YuICMyM1xuICBpZiAoIXByZWZpeCAmJiAhdXJpKSB7XG4gICAgcmV0dXJuIHsgbG9jYWxOYW1lOiBucy5sb2NhbE5hbWUgfTtcbiAgfVxuXG4gIHdlbGxrbm93blVyaSA9IERFRkFVTFRfTlNfTUFQW3ByZWZpeF0gfHwgbW9kZWwgJiYgKG1vZGVsLmdldFBhY2thZ2UocHJlZml4KSB8fCB7fSkudXJpO1xuXG4gIHVyaSA9IHVyaSB8fCB3ZWxsa25vd25VcmkgfHwgbmFtZXNwYWNlcy51cmlCeVByZWZpeChwcmVmaXgpO1xuXG4gIGlmICghdXJpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdubyBuYW1lc3BhY2UgdXJpIGdpdmVuIGZvciBwcmVmaXggPCcgKyBwcmVmaXggKyAnPicpO1xuICB9XG5cbiAgbnMgPSBuYW1lc3BhY2VzLmJ5VXJpKHVyaSk7XG5cbiAgaWYgKCFucykge1xuICAgIG5ld1ByZWZpeCA9IHByZWZpeDtcbiAgICBpZHggPSAxO1xuXG4gICAgLy8gZmluZCBhIHByZWZpeCB0aGF0IGlzIG5vdCBtYXBwZWQgeWV0XG4gICAgd2hpbGUgKG5hbWVzcGFjZXMudXJpQnlQcmVmaXgobmV3UHJlZml4KSkge1xuICAgICAgbmV3UHJlZml4ID0gcHJlZml4ICsgJ18nICsgaWR4Kys7XG4gICAgfVxuXG4gICAgbnMgPSB0aGlzLmxvZ05hbWVzcGFjZSh7IHByZWZpeDogbmV3UHJlZml4LCB1cmk6IHVyaSB9LCB3ZWxsa25vd25VcmkgPT09IHVyaSk7XG4gIH1cblxuICBpZiAocHJlZml4KSB7XG4gICAgbmFtZXNwYWNlcy5tYXBQcmVmaXgocHJlZml4LCB1cmkpO1xuICB9XG5cbiAgcmV0dXJuIG5zO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLnBhcnNlQXR0cmlidXRlcyA9IGZ1bmN0aW9uKHByb3BlcnRpZXMpIHtcbiAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgZWxlbWVudCA9IHRoaXMuZWxlbWVudDtcblxuICBmb3JFYWNoKHByb3BlcnRpZXMsIGZ1bmN0aW9uKHApIHtcblxuICAgIHZhciB2YWx1ZSA9IGVsZW1lbnQuZ2V0KHAubmFtZSk7XG5cbiAgICBpZiAocC5pc1JlZmVyZW5jZSkge1xuXG4gICAgICBpZiAoIXAuaXNNYW55KSB7XG4gICAgICAgIHZhbHVlID0gdmFsdWUuaWQ7XG4gICAgICB9XG4gICAgICBlbHNlIHtcbiAgICAgICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgICAgICBmb3JFYWNoKHZhbHVlLCBmdW5jdGlvbih2KSB7XG4gICAgICAgICAgdmFsdWVzLnB1c2godi5pZCk7XG4gICAgICAgIH0pO1xuICAgICAgICAvLyBJRFJFRlMgaXMgYSB3aGl0ZXNwYWNlLXNlcGFyYXRlZCBsaXN0IG9mIHJlZmVyZW5jZXMuXG4gICAgICAgIHZhbHVlID0gdmFsdWVzLmpvaW4oJyAnKTtcbiAgICAgIH1cblxuICAgIH1cblxuICAgIHNlbGYuYWRkQXR0cmlidXRlKHNlbGYubnNBdHRyaWJ1dGVOYW1lKHApLCB2YWx1ZSk7XG4gIH0pO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLmFkZFRhZ05hbWUgPSBmdW5jdGlvbihuc1RhZ05hbWUpIHtcbiAgdmFyIGFjdHVhbE5zID0gdGhpcy5sb2dOYW1lc3BhY2VVc2VkKG5zVGFnTmFtZSk7XG5cbiAgdGhpcy5nZXROYW1lc3BhY2VzKCkubG9nVXNlZChhY3R1YWxOcyk7XG5cbiAgcmV0dXJuIG5zTmFtZShuc1RhZ05hbWUpO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLmFkZEF0dHJpYnV0ZSA9IGZ1bmN0aW9uKG5hbWUsIHZhbHVlKSB7XG4gIHZhciBhdHRycyA9IHRoaXMuYXR0cnM7XG5cbiAgaWYgKGlzU3RyaW5nKHZhbHVlKSkge1xuICAgIHZhbHVlID0gZXNjYXBlQXR0cih2YWx1ZSk7XG4gIH1cblxuICBhdHRycy5wdXNoKHsgbmFtZTogbmFtZSwgdmFsdWU6IHZhbHVlIH0pO1xufTtcblxuRWxlbWVudFNlcmlhbGl6ZXIucHJvdG90eXBlLnNlcmlhbGl6ZUF0dHJpYnV0ZXMgPSBmdW5jdGlvbih3cml0ZXIpIHtcbiAgdmFyIGF0dHJzID0gdGhpcy5hdHRycyxcbiAgICAgIG5hbWVzcGFjZXMgPSB0aGlzLm5hbWVzcGFjZXM7XG5cbiAgaWYgKG5hbWVzcGFjZXMpIHtcbiAgICBhdHRycyA9IGdldE5zQXR0cnMobmFtZXNwYWNlcykuY29uY2F0KGF0dHJzKTtcbiAgfVxuXG4gIGZvckVhY2goYXR0cnMsIGZ1bmN0aW9uKGEpIHtcbiAgICB3cml0ZXJcbiAgICAgIC5hcHBlbmQoJyAnKVxuICAgICAgLmFwcGVuZChuc05hbWUoYS5uYW1lKSkuYXBwZW5kKCc9XCInKS5hcHBlbmQoYS52YWx1ZSkuYXBwZW5kKCdcIicpO1xuICB9KTtcbn07XG5cbkVsZW1lbnRTZXJpYWxpemVyLnByb3RvdHlwZS5zZXJpYWxpemVUbyA9IGZ1bmN0aW9uKHdyaXRlcikge1xuICB2YXIgZmlyc3RCb2R5ID0gdGhpcy5ib2R5WzBdLFxuICAgICAgaW5kZW50ID0gZmlyc3RCb2R5ICYmIGZpcnN0Qm9keS5jb25zdHJ1Y3RvciAhPT0gQm9keVNlcmlhbGl6ZXI7XG5cbiAgd3JpdGVyXG4gICAgLmFwcGVuZEluZGVudCgpXG4gICAgLmFwcGVuZCgnPCcgKyB0aGlzLnRhZ05hbWUpO1xuXG4gIHRoaXMuc2VyaWFsaXplQXR0cmlidXRlcyh3cml0ZXIpO1xuXG4gIHdyaXRlci5hcHBlbmQoZmlyc3RCb2R5ID8gJz4nIDogJyAvPicpO1xuXG4gIGlmIChmaXJzdEJvZHkpIHtcblxuICAgIGlmIChpbmRlbnQpIHtcbiAgICAgIHdyaXRlclxuICAgICAgICAuYXBwZW5kTmV3TGluZSgpXG4gICAgICAgIC5pbmRlbnQoKTtcbiAgICB9XG5cbiAgICBmb3JFYWNoKHRoaXMuYm9keSwgZnVuY3Rpb24oYikge1xuICAgICAgYi5zZXJpYWxpemVUbyh3cml0ZXIpO1xuICAgIH0pO1xuXG4gICAgaWYgKGluZGVudCkge1xuICAgICAgd3JpdGVyXG4gICAgICAgIC51bmluZGVudCgpXG4gICAgICAgIC5hcHBlbmRJbmRlbnQoKTtcbiAgICB9XG5cbiAgICB3cml0ZXIuYXBwZW5kKCc8LycgKyB0aGlzLnRhZ05hbWUgKyAnPicpO1xuICB9XG5cbiAgd3JpdGVyLmFwcGVuZE5ld0xpbmUoKTtcbn07XG5cbi8qKlxuICogQSBzZXJpYWxpemVyIGZvciB0eXBlcyB0aGF0IGhhbmRsZXMgc2VyaWFsaXphdGlvbiBvZiBkYXRhIHR5cGVzXG4gKi9cbmZ1bmN0aW9uIFR5cGVTZXJpYWxpemVyKHBhcmVudCwgcHJvcGVydHlEZXNjcmlwdG9yKSB7XG4gIEVsZW1lbnRTZXJpYWxpemVyLmNhbGwodGhpcywgcGFyZW50LCBwcm9wZXJ0eURlc2NyaXB0b3IpO1xufVxuXG5pbmhlcml0cyhUeXBlU2VyaWFsaXplciwgRWxlbWVudFNlcmlhbGl6ZXIpO1xuXG5UeXBlU2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VOc0F0dHJpYnV0ZXMgPSBmdW5jdGlvbihlbGVtZW50KSB7XG5cbiAgLy8gZXh0cmFjdGVkIGF0dHJpYnV0ZXNcbiAgdmFyIGF0dHJpYnV0ZXMgPSBFbGVtZW50U2VyaWFsaXplci5wcm90b3R5cGUucGFyc2VOc0F0dHJpYnV0ZXMuY2FsbCh0aGlzLCBlbGVtZW50KTtcblxuICB2YXIgZGVzY3JpcHRvciA9IGVsZW1lbnQuJGRlc2NyaXB0b3I7XG5cbiAgLy8gb25seSBzZXJpYWxpemUgeHNpOnR5cGUgaWYgbmVjZXNzYXJ5XG4gIGlmIChkZXNjcmlwdG9yLm5hbWUgPT09IHRoaXMucHJvcGVydHlEZXNjcmlwdG9yLnR5cGUpIHtcbiAgICByZXR1cm4gYXR0cmlidXRlcztcbiAgfVxuXG4gIHZhciB0eXBlTnMgPSB0aGlzLnR5cGVOcyA9IHRoaXMubnNUYWdOYW1lKGRlc2NyaXB0b3IpO1xuICB0aGlzLmdldE5hbWVzcGFjZXMoKS5sb2dVc2VkKHRoaXMudHlwZU5zKTtcblxuICAvLyBhZGQgeHNpOnR5cGUgYXR0cmlidXRlIHRvIHJlcHJlc2VudCB0aGUgZWxlbWVudHNcbiAgLy8gYWN0dWFsIHR5cGVcblxuICB2YXIgcGtnID0gZWxlbWVudC4kbW9kZWwuZ2V0UGFja2FnZSh0eXBlTnMudXJpKSxcbiAgICAgIHR5cGVQcmVmaXggPSAocGtnLnhtbCAmJiBwa2cueG1sLnR5cGVQcmVmaXgpIHx8ICcnO1xuXG4gIHRoaXMuYWRkQXR0cmlidXRlKFxuICAgIHRoaXMubnNBdHRyaWJ1dGVOYW1lKFhTSV9UWVBFKSxcbiAgICAodHlwZU5zLnByZWZpeCA/IHR5cGVOcy5wcmVmaXggKyAnOicgOiAnJykgKyB0eXBlUHJlZml4ICsgZGVzY3JpcHRvci5ucy5sb2NhbE5hbWVcbiAgKTtcblxuICByZXR1cm4gYXR0cmlidXRlcztcbn07XG5cblR5cGVTZXJpYWxpemVyLnByb3RvdHlwZS5pc0xvY2FsTnMgPSBmdW5jdGlvbihucykge1xuICByZXR1cm4gbnMudXJpID09PSAodGhpcy50eXBlTnMgfHwgdGhpcy5ucykudXJpO1xufTtcblxuZnVuY3Rpb24gU2F2aW5nV3JpdGVyKCkge1xuICB0aGlzLnZhbHVlID0gJyc7XG5cbiAgdGhpcy53cml0ZSA9IGZ1bmN0aW9uKHN0cikge1xuICAgIHRoaXMudmFsdWUgKz0gc3RyO1xuICB9O1xufVxuXG5mdW5jdGlvbiBGb3JtYXRpbmdXcml0ZXIob3V0LCBmb3JtYXQpIHtcblxuICB2YXIgaW5kZW50ID0gWycnXTtcblxuICB0aGlzLmFwcGVuZCA9IGZ1bmN0aW9uKHN0cikge1xuICAgIG91dC53cml0ZShzdHIpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgdGhpcy5hcHBlbmROZXdMaW5lID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKGZvcm1hdCkge1xuICAgICAgb3V0LndyaXRlKCdcXG4nKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICB0aGlzLmFwcGVuZEluZGVudCA9IGZ1bmN0aW9uKCkge1xuICAgIGlmIChmb3JtYXQpIHtcbiAgICAgIG91dC53cml0ZShpbmRlbnQuam9pbignICAnKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgdGhpcy5pbmRlbnQgPSBmdW5jdGlvbigpIHtcbiAgICBpbmRlbnQucHVzaCgnJyk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgdGhpcy51bmluZGVudCA9IGZ1bmN0aW9uKCkge1xuICAgIGluZGVudC5wb3AoKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfTtcbn1cblxuLyoqXG4gKiBBIHdyaXRlciBmb3IgbWV0YS1tb2RlbCBiYWNrZWQgZG9jdW1lbnQgdHJlZXNcbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyBvdXRwdXQgb3B0aW9ucyB0byBwYXNzIGludG8gdGhlIHdyaXRlclxuICovXG5mdW5jdGlvbiBXcml0ZXIob3B0aW9ucykge1xuXG4gIG9wdGlvbnMgPSBhc3NpZ24oeyBmb3JtYXQ6IGZhbHNlLCBwcmVhbWJsZTogdHJ1ZSB9LCBvcHRpb25zIHx8IHt9KTtcblxuICBmdW5jdGlvbiB0b1hNTCh0cmVlLCB3cml0ZXIpIHtcbiAgICB2YXIgaW50ZXJuYWxXcml0ZXIgPSB3cml0ZXIgfHwgbmV3IFNhdmluZ1dyaXRlcigpO1xuICAgIHZhciBmb3JtYXRpbmdXcml0ZXIgPSBuZXcgRm9ybWF0aW5nV3JpdGVyKGludGVybmFsV3JpdGVyLCBvcHRpb25zLmZvcm1hdCk7XG5cbiAgICBpZiAob3B0aW9ucy5wcmVhbWJsZSkge1xuICAgICAgZm9ybWF0aW5nV3JpdGVyLmFwcGVuZChYTUxfUFJFQU1CTEUpO1xuICAgIH1cblxuICAgIG5ldyBFbGVtZW50U2VyaWFsaXplcigpLmJ1aWxkKHRyZWUpLnNlcmlhbGl6ZVRvKGZvcm1hdGluZ1dyaXRlcik7XG5cbiAgICBpZiAoIXdyaXRlcikge1xuICAgICAgcmV0dXJuIGludGVybmFsV3JpdGVyLnZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdG9YTUw6IHRvWE1MXG4gIH07XG59XG5cbmV4cG9ydCB7IFJlYWRlciwgV3JpdGVyIH07XG4iLCJpbXBvcnQgeyBmb3JFYWNoLCBiaW5kLCBwaWNrLCBhc3NpZ24sIGlzU3RyaW5nLCBpc09iamVjdCB9IGZyb20gJ21pbi1kYXNoJztcblxuLyoqXG4gKiBNb2RkbGUgYmFzZSBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBCYXNlKCkgeyB9XG5cbkJhc2UucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgcmV0dXJuIHRoaXMuJG1vZGVsLnByb3BlcnRpZXMuZ2V0KHRoaXMsIG5hbWUpO1xufTtcblxuQmFzZS5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgdGhpcy4kbW9kZWwucHJvcGVydGllcy5zZXQodGhpcywgbmFtZSwgdmFsdWUpO1xufTtcblxuLyoqXG4gKiBBIG1vZGVsIGVsZW1lbnQgZmFjdG9yeS5cbiAqXG4gKiBAcGFyYW0ge01vZGRsZX0gbW9kZWxcbiAqIEBwYXJhbSB7UHJvcGVydGllc30gcHJvcGVydGllc1xuICovXG5mdW5jdGlvbiBGYWN0b3J5KG1vZGVsLCBwcm9wZXJ0aWVzKSB7XG4gIHRoaXMubW9kZWwgPSBtb2RlbDtcbiAgdGhpcy5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbn1cblxuXG5GYWN0b3J5LnByb3RvdHlwZS5jcmVhdGVUeXBlID0gZnVuY3Rpb24oZGVzY3JpcHRvcikge1xuXG4gIHZhciBtb2RlbCA9IHRoaXMubW9kZWw7XG5cbiAgdmFyIHByb3BzID0gdGhpcy5wcm9wZXJ0aWVzLFxuICAgICAgcHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShCYXNlLnByb3RvdHlwZSk7XG5cbiAgLy8gaW5pdGlhbGl6ZSBkZWZhdWx0IHZhbHVlc1xuICBmb3JFYWNoKGRlc2NyaXB0b3IucHJvcGVydGllcywgZnVuY3Rpb24ocCkge1xuICAgIGlmICghcC5pc01hbnkgJiYgcC5kZWZhdWx0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHByb3RvdHlwZVtwLm5hbWVdID0gcC5kZWZhdWx0O1xuICAgIH1cbiAgfSk7XG5cbiAgcHJvcHMuZGVmaW5lTW9kZWwocHJvdG90eXBlLCBtb2RlbCk7XG4gIHByb3BzLmRlZmluZURlc2NyaXB0b3IocHJvdG90eXBlLCBkZXNjcmlwdG9yKTtcblxuICB2YXIgbmFtZSA9IGRlc2NyaXB0b3IubnMubmFtZTtcblxuICAvKipcbiAgICogVGhlIG5ldyB0eXBlIGNvbnN0cnVjdG9yXG4gICAqL1xuICBmdW5jdGlvbiBNb2RkbGVFbGVtZW50KGF0dHJzKSB7XG4gICAgcHJvcHMuZGVmaW5lKHRoaXMsICckdHlwZScsIHsgdmFsdWU6IG5hbWUsIGVudW1lcmFibGU6IHRydWUgfSk7XG4gICAgcHJvcHMuZGVmaW5lKHRoaXMsICckYXR0cnMnLCB7IHZhbHVlOiB7fSB9KTtcbiAgICBwcm9wcy5kZWZpbmUodGhpcywgJyRwYXJlbnQnLCB7IHdyaXRhYmxlOiB0cnVlIH0pO1xuXG4gICAgZm9yRWFjaChhdHRycywgYmluZChmdW5jdGlvbih2YWwsIGtleSkge1xuICAgICAgdGhpcy5zZXQoa2V5LCB2YWwpO1xuICAgIH0sIHRoaXMpKTtcbiAgfVxuXG4gIE1vZGRsZUVsZW1lbnQucHJvdG90eXBlID0gcHJvdG90eXBlO1xuXG4gIE1vZGRsZUVsZW1lbnQuaGFzVHlwZSA9IHByb3RvdHlwZS4kaW5zdGFuY2VPZiA9IHRoaXMubW9kZWwuaGFzVHlwZTtcblxuICAvLyBzdGF0aWMgbGlua3NcbiAgcHJvcHMuZGVmaW5lTW9kZWwoTW9kZGxlRWxlbWVudCwgbW9kZWwpO1xuICBwcm9wcy5kZWZpbmVEZXNjcmlwdG9yKE1vZGRsZUVsZW1lbnQsIGRlc2NyaXB0b3IpO1xuXG4gIHJldHVybiBNb2RkbGVFbGVtZW50O1xufTtcblxuLyoqXG4gKiBCdWlsdC1pbiBtb2RkbGUgdHlwZXNcbiAqL1xudmFyIEJVSUxUSU5TID0ge1xuICBTdHJpbmc6IHRydWUsXG4gIEJvb2xlYW46IHRydWUsXG4gIEludGVnZXI6IHRydWUsXG4gIFJlYWw6IHRydWUsXG4gIEVsZW1lbnQ6IHRydWVcbn07XG5cbi8qKlxuICogQ29udmVydGVycyBmb3IgYnVpbHQgaW4gdHlwZXMgZnJvbSBzdHJpbmcgcmVwcmVzZW50YXRpb25zXG4gKi9cbnZhciBUWVBFX0NPTlZFUlRFUlMgPSB7XG4gIFN0cmluZzogZnVuY3Rpb24ocykgeyByZXR1cm4gczsgfSxcbiAgQm9vbGVhbjogZnVuY3Rpb24ocykgeyByZXR1cm4gcyA9PT0gJ3RydWUnOyB9LFxuICBJbnRlZ2VyOiBmdW5jdGlvbihzKSB7IHJldHVybiBwYXJzZUludChzLCAxMCk7IH0sXG4gIFJlYWw6IGZ1bmN0aW9uKHMpIHsgcmV0dXJuIHBhcnNlRmxvYXQocywgMTApOyB9XG59O1xuXG4vKipcbiAqIENvbnZlcnQgYSB0eXBlIHRvIGl0cyByZWFsIHJlcHJlc2VudGF0aW9uXG4gKi9cbmZ1bmN0aW9uIGNvZXJjZVR5cGUodHlwZSwgdmFsdWUpIHtcblxuICB2YXIgY29udmVydGVyID0gVFlQRV9DT05WRVJURVJTW3R5cGVdO1xuXG4gIGlmIChjb252ZXJ0ZXIpIHtcbiAgICByZXR1cm4gY29udmVydGVyKHZhbHVlKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm4gd2hldGhlciB0aGUgZ2l2ZW4gdHlwZSBpcyBidWlsdC1pblxuICovXG5mdW5jdGlvbiBpc0J1aWx0SW4odHlwZSkge1xuICByZXR1cm4gISFCVUlMVElOU1t0eXBlXTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gd2hldGhlciB0aGUgZ2l2ZW4gdHlwZSBpcyBzaW1wbGVcbiAqL1xuZnVuY3Rpb24gaXNTaW1wbGUodHlwZSkge1xuICByZXR1cm4gISFUWVBFX0NPTlZFUlRFUlNbdHlwZV07XG59XG5cbi8qKlxuICogUGFyc2VzIGEgbmFtZXNwYWNlZCBhdHRyaWJ1dGUgbmFtZSBvZiB0aGUgZm9ybSAobnM6KWxvY2FsTmFtZSB0byBhbiBvYmplY3QsXG4gKiBnaXZlbiBhIGRlZmF1bHQgcHJlZml4IHRvIGFzc3VtZSBpbiBjYXNlIG5vIGV4cGxpY2l0IG5hbWVzcGFjZSBpcyBnaXZlbi5cbiAqXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtTdHJpbmd9IFtkZWZhdWx0UHJlZml4XSB0aGUgZGVmYXVsdCBwcmVmaXggdG8gdGFrZSwgaWYgbm9uZSBpcyBwcmVzZW50LlxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIHBhcnNlZCBuYW1lXG4gKi9cbmZ1bmN0aW9uIHBhcnNlTmFtZShuYW1lLCBkZWZhdWx0UHJlZml4KSB7XG4gIHZhciBwYXJ0cyA9IG5hbWUuc3BsaXQoLzovKSxcbiAgICAgIGxvY2FsTmFtZSwgcHJlZml4O1xuXG4gIC8vIG5vIHByZWZpeCAoaS5lLiBvbmx5IGxvY2FsIG5hbWUpXG4gIGlmIChwYXJ0cy5sZW5ndGggPT09IDEpIHtcbiAgICBsb2NhbE5hbWUgPSBuYW1lO1xuICAgIHByZWZpeCA9IGRlZmF1bHRQcmVmaXg7XG4gIH0gZWxzZVxuICAvLyBwcmVmaXggKyBsb2NhbCBuYW1lXG4gIGlmIChwYXJ0cy5sZW5ndGggPT09IDIpIHtcbiAgICBsb2NhbE5hbWUgPSBwYXJ0c1sxXTtcbiAgICBwcmVmaXggPSBwYXJ0c1swXTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIDxwcmVmaXg6bG9jYWxOYW1lPiBvciA8bG9jYWxOYW1lPiwgZ290ICcgKyBuYW1lKTtcbiAgfVxuXG4gIG5hbWUgPSAocHJlZml4ID8gcHJlZml4ICsgJzonIDogJycpICsgbG9jYWxOYW1lO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogbmFtZSxcbiAgICBwcmVmaXg6IHByZWZpeCxcbiAgICBsb2NhbE5hbWU6IGxvY2FsTmFtZVxuICB9O1xufVxuXG4vKipcbiAqIEEgdXRpbGl0eSB0byBidWlsZCBlbGVtZW50IGRlc2NyaXB0b3JzLlxuICovXG5mdW5jdGlvbiBEZXNjcmlwdG9yQnVpbGRlcihuYW1lTnMpIHtcbiAgdGhpcy5ucyA9IG5hbWVOcztcbiAgdGhpcy5uYW1lID0gbmFtZU5zLm5hbWU7XG4gIHRoaXMuYWxsVHlwZXMgPSBbXTtcbiAgdGhpcy5hbGxUeXBlc0J5TmFtZSA9IHt9O1xuICB0aGlzLnByb3BlcnRpZXMgPSBbXTtcbiAgdGhpcy5wcm9wZXJ0aWVzQnlOYW1lID0ge307XG59XG5cblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLmJ1aWxkID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBwaWNrKHRoaXMsIFtcbiAgICAnbnMnLFxuICAgICduYW1lJyxcbiAgICAnYWxsVHlwZXMnLFxuICAgICdhbGxUeXBlc0J5TmFtZScsXG4gICAgJ3Byb3BlcnRpZXMnLFxuICAgICdwcm9wZXJ0aWVzQnlOYW1lJyxcbiAgICAnYm9keVByb3BlcnR5JyxcbiAgICAnaWRQcm9wZXJ0eSdcbiAgXSk7XG59O1xuXG4vKipcbiAqIEFkZCBwcm9wZXJ0eSBhdCBnaXZlbiBpbmRleC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gcFxuICogQHBhcmFtIHtOdW1iZXJ9IFtpZHhdXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFt2YWxpZGF0ZT10cnVlXVxuICovXG5EZXNjcmlwdG9yQnVpbGRlci5wcm90b3R5cGUuYWRkUHJvcGVydHkgPSBmdW5jdGlvbihwLCBpZHgsIHZhbGlkYXRlKSB7XG5cbiAgaWYgKHR5cGVvZiBpZHggPT09ICdib29sZWFuJykge1xuICAgIHZhbGlkYXRlID0gaWR4O1xuICAgIGlkeCA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHRoaXMuYWRkTmFtZWRQcm9wZXJ0eShwLCB2YWxpZGF0ZSAhPT0gZmFsc2UpO1xuXG4gIHZhciBwcm9wZXJ0aWVzID0gdGhpcy5wcm9wZXJ0aWVzO1xuXG4gIGlmIChpZHggIT09IHVuZGVmaW5lZCkge1xuICAgIHByb3BlcnRpZXMuc3BsaWNlKGlkeCwgMCwgcCk7XG4gIH0gZWxzZSB7XG4gICAgcHJvcGVydGllcy5wdXNoKHApO1xuICB9XG59O1xuXG5cbkRlc2NyaXB0b3JCdWlsZGVyLnByb3RvdHlwZS5yZXBsYWNlUHJvcGVydHkgPSBmdW5jdGlvbihvbGRQcm9wZXJ0eSwgbmV3UHJvcGVydHksIHJlcGxhY2UpIHtcbiAgdmFyIG9sZE5hbWVOcyA9IG9sZFByb3BlcnR5Lm5zO1xuXG4gIHZhciBwcm9wcyA9IHRoaXMucHJvcGVydGllcyxcbiAgICAgIHByb3BlcnRpZXNCeU5hbWUgPSB0aGlzLnByb3BlcnRpZXNCeU5hbWUsXG4gICAgICByZW5hbWUgPSBvbGRQcm9wZXJ0eS5uYW1lICE9PSBuZXdQcm9wZXJ0eS5uYW1lO1xuXG4gIGlmIChvbGRQcm9wZXJ0eS5pc0lkKSB7XG4gICAgaWYgKCFuZXdQcm9wZXJ0eS5pc0lkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdwcm9wZXJ0eSA8JyArIG5ld1Byb3BlcnR5Lm5zLm5hbWUgKyAnPiBtdXN0IGJlIGlkIHByb3BlcnR5ICcgK1xuICAgICAgICAndG8gcmVmaW5lIDwnICsgb2xkUHJvcGVydHkubnMubmFtZSArICc+Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5zZXRJZFByb3BlcnR5KG5ld1Byb3BlcnR5LCBmYWxzZSk7XG4gIH1cblxuICBpZiAob2xkUHJvcGVydHkuaXNCb2R5KSB7XG5cbiAgICBpZiAoIW5ld1Byb3BlcnR5LmlzQm9keSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAncHJvcGVydHkgPCcgKyBuZXdQcm9wZXJ0eS5ucy5uYW1lICsgJz4gbXVzdCBiZSBib2R5IHByb3BlcnR5ICcgK1xuICAgICAgICAndG8gcmVmaW5lIDwnICsgb2xkUHJvcGVydHkubnMubmFtZSArICc+Jyk7XG4gICAgfVxuXG4gICAgLy8gVE9ETzogQ2hlY2sgY29tcGF0aWJpbGl0eVxuICAgIHRoaXMuc2V0Qm9keVByb3BlcnR5KG5ld1Byb3BlcnR5LCBmYWxzZSk7XG4gIH1cblxuICAvLyB2YWxpZGF0ZSBleGlzdGVuY2UgYW5kIGdldCBsb2NhdGlvbiBvZiBvbGQgcHJvcGVydHlcbiAgdmFyIGlkeCA9IHByb3BzLmluZGV4T2Yob2xkUHJvcGVydHkpO1xuICBpZiAoaWR4ID09PSAtMSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvcGVydHkgPCcgKyBvbGROYW1lTnMubmFtZSArICc+IG5vdCBmb3VuZCBpbiBwcm9wZXJ0eSBsaXN0Jyk7XG4gIH1cblxuICAvLyByZW1vdmUgb2xkIHByb3BlcnR5XG4gIHByb3BzLnNwbGljZShpZHgsIDEpO1xuXG4gIC8vIHJlcGxhY2luZyB0aGUgbmFtZWQgcHJvcGVydHkgaXMgaW50ZW50aW9uYWxcbiAgLy9cbiAgLy8gICogdmFsaWRhdGUgb25seSBpZiB0aGlzIGlzIGEgXCJyZW5hbWVcIiBvcGVyYXRpb25cbiAgLy8gICogYWRkIGF0IHNwZWNpZmljIGluZGV4IHVubGVzcyB3ZSBcInJlcGxhY2VcIlxuICAvL1xuICB0aGlzLmFkZFByb3BlcnR5KG5ld1Byb3BlcnR5LCByZXBsYWNlID8gdW5kZWZpbmVkIDogaWR4LCByZW5hbWUpO1xuXG4gIC8vIG1ha2UgbmV3IHByb3BlcnR5IGF2YWlsYWJsZSB1bmRlciBvbGQgbmFtZVxuICBwcm9wZXJ0aWVzQnlOYW1lW29sZE5hbWVOcy5uYW1lXSA9IHByb3BlcnRpZXNCeU5hbWVbb2xkTmFtZU5zLmxvY2FsTmFtZV0gPSBuZXdQcm9wZXJ0eTtcbn07XG5cblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLnJlZGVmaW5lUHJvcGVydHkgPSBmdW5jdGlvbihwLCB0YXJnZXRQcm9wZXJ0eU5hbWUsIHJlcGxhY2UpIHtcblxuICB2YXIgbnNQcmVmaXggPSBwLm5zLnByZWZpeDtcbiAgdmFyIHBhcnRzID0gdGFyZ2V0UHJvcGVydHlOYW1lLnNwbGl0KCcjJyk7XG5cbiAgdmFyIG5hbWUgPSBwYXJzZU5hbWUocGFydHNbMF0sIG5zUHJlZml4KTtcbiAgdmFyIGF0dHJOYW1lID0gcGFyc2VOYW1lKHBhcnRzWzFdLCBuYW1lLnByZWZpeCkubmFtZTtcblxuICB2YXIgcmVkZWZpbmVkUHJvcGVydHkgPSB0aGlzLnByb3BlcnRpZXNCeU5hbWVbYXR0ck5hbWVdO1xuICBpZiAoIXJlZGVmaW5lZFByb3BlcnR5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdyZWZpbmVkIHByb3BlcnR5IDwnICsgYXR0ck5hbWUgKyAnPiBub3QgZm91bmQnKTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnJlcGxhY2VQcm9wZXJ0eShyZWRlZmluZWRQcm9wZXJ0eSwgcCwgcmVwbGFjZSk7XG4gIH1cblxuICBkZWxldGUgcC5yZWRlZmluZXM7XG59O1xuXG5EZXNjcmlwdG9yQnVpbGRlci5wcm90b3R5cGUuYWRkTmFtZWRQcm9wZXJ0eSA9IGZ1bmN0aW9uKHAsIHZhbGlkYXRlKSB7XG4gIHZhciBucyA9IHAubnMsXG4gICAgICBwcm9wc0J5TmFtZSA9IHRoaXMucHJvcGVydGllc0J5TmFtZTtcblxuICBpZiAodmFsaWRhdGUpIHtcbiAgICB0aGlzLmFzc2VydE5vdERlZmluZWQocCwgbnMubmFtZSk7XG4gICAgdGhpcy5hc3NlcnROb3REZWZpbmVkKHAsIG5zLmxvY2FsTmFtZSk7XG4gIH1cblxuICBwcm9wc0J5TmFtZVtucy5uYW1lXSA9IHByb3BzQnlOYW1lW25zLmxvY2FsTmFtZV0gPSBwO1xufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLnJlbW92ZU5hbWVkUHJvcGVydHkgPSBmdW5jdGlvbihwKSB7XG4gIHZhciBucyA9IHAubnMsXG4gICAgICBwcm9wc0J5TmFtZSA9IHRoaXMucHJvcGVydGllc0J5TmFtZTtcblxuICBkZWxldGUgcHJvcHNCeU5hbWVbbnMubmFtZV07XG4gIGRlbGV0ZSBwcm9wc0J5TmFtZVtucy5sb2NhbE5hbWVdO1xufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLnNldEJvZHlQcm9wZXJ0eSA9IGZ1bmN0aW9uKHAsIHZhbGlkYXRlKSB7XG5cbiAgaWYgKHZhbGlkYXRlICYmIHRoaXMuYm9keVByb3BlcnR5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ2JvZHkgcHJvcGVydHkgZGVmaW5lZCBtdWx0aXBsZSB0aW1lcyAnICtcbiAgICAgICcoPCcgKyB0aGlzLmJvZHlQcm9wZXJ0eS5ucy5uYW1lICsgJz4sIDwnICsgcC5ucy5uYW1lICsgJz4pJyk7XG4gIH1cblxuICB0aGlzLmJvZHlQcm9wZXJ0eSA9IHA7XG59O1xuXG5EZXNjcmlwdG9yQnVpbGRlci5wcm90b3R5cGUuc2V0SWRQcm9wZXJ0eSA9IGZ1bmN0aW9uKHAsIHZhbGlkYXRlKSB7XG5cbiAgaWYgKHZhbGlkYXRlICYmIHRoaXMuaWRQcm9wZXJ0eSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdpZCBwcm9wZXJ0eSBkZWZpbmVkIG11bHRpcGxlIHRpbWVzICcgK1xuICAgICAgJyg8JyArIHRoaXMuaWRQcm9wZXJ0eS5ucy5uYW1lICsgJz4sIDwnICsgcC5ucy5uYW1lICsgJz4pJyk7XG4gIH1cblxuICB0aGlzLmlkUHJvcGVydHkgPSBwO1xufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLmFzc2VydE5vdERlZmluZWQgPSBmdW5jdGlvbihwLCBuYW1lKSB7XG4gIHZhciBwcm9wZXJ0eU5hbWUgPSBwLm5hbWUsXG4gICAgICBkZWZpbmVkUHJvcGVydHkgPSB0aGlzLnByb3BlcnRpZXNCeU5hbWVbcHJvcGVydHlOYW1lXTtcblxuICBpZiAoZGVmaW5lZFByb3BlcnR5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ3Byb3BlcnR5IDwnICsgcHJvcGVydHlOYW1lICsgJz4gYWxyZWFkeSBkZWZpbmVkOyAnICtcbiAgICAgICdvdmVycmlkZSBvZiA8JyArIGRlZmluZWRQcm9wZXJ0eS5kZWZpbmVkQnkubnMubmFtZSArICcjJyArIGRlZmluZWRQcm9wZXJ0eS5ucy5uYW1lICsgJz4gYnkgJyArXG4gICAgICAnPCcgKyBwLmRlZmluZWRCeS5ucy5uYW1lICsgJyMnICsgcC5ucy5uYW1lICsgJz4gbm90IGFsbG93ZWQgd2l0aG91dCByZWRlZmluZXMnKTtcbiAgfVxufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLmhhc1Byb3BlcnR5ID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gdGhpcy5wcm9wZXJ0aWVzQnlOYW1lW25hbWVdO1xufTtcblxuRGVzY3JpcHRvckJ1aWxkZXIucHJvdG90eXBlLmFkZFRyYWl0ID0gZnVuY3Rpb24odCwgaW5oZXJpdGVkKSB7XG5cbiAgdmFyIHR5cGVzQnlOYW1lID0gdGhpcy5hbGxUeXBlc0J5TmFtZSxcbiAgICAgIHR5cGVzID0gdGhpcy5hbGxUeXBlcztcblxuICB2YXIgdHlwZU5hbWUgPSB0Lm5hbWU7XG5cbiAgaWYgKHR5cGVOYW1lIGluIHR5cGVzQnlOYW1lKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgZm9yRWFjaCh0LnByb3BlcnRpZXMsIGJpbmQoZnVuY3Rpb24ocCkge1xuXG4gICAgLy8gY2xvbmUgcHJvcGVydHkgdG8gYWxsb3cgZXh0ZW5zaW9uc1xuICAgIHAgPSBhc3NpZ24oe30sIHAsIHtcbiAgICAgIG5hbWU6IHAubnMubG9jYWxOYW1lLFxuICAgICAgaW5oZXJpdGVkOiBpbmhlcml0ZWRcbiAgICB9KTtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwLCAnZGVmaW5lZEJ5Jywge1xuICAgICAgdmFsdWU6IHRcbiAgICB9KTtcblxuICAgIHZhciByZXBsYWNlcyA9IHAucmVwbGFjZXMsXG4gICAgICAgIHJlZGVmaW5lcyA9IHAucmVkZWZpbmVzO1xuXG4gICAgLy8gYWRkIHJlcGxhY2UvcmVkZWZpbmUgc3VwcG9ydFxuICAgIGlmIChyZXBsYWNlcyB8fCByZWRlZmluZXMpIHtcbiAgICAgIHRoaXMucmVkZWZpbmVQcm9wZXJ0eShwLCByZXBsYWNlcyB8fCByZWRlZmluZXMsIHJlcGxhY2VzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHAuaXNCb2R5KSB7XG4gICAgICAgIHRoaXMuc2V0Qm9keVByb3BlcnR5KHApO1xuICAgICAgfVxuICAgICAgaWYgKHAuaXNJZCkge1xuICAgICAgICB0aGlzLnNldElkUHJvcGVydHkocCk7XG4gICAgICB9XG4gICAgICB0aGlzLmFkZFByb3BlcnR5KHApO1xuICAgIH1cbiAgfSwgdGhpcykpO1xuXG4gIHR5cGVzLnB1c2godCk7XG4gIHR5cGVzQnlOYW1lW3R5cGVOYW1lXSA9IHQ7XG59O1xuXG4vKipcbiAqIEEgcmVnaXN0cnkgb2YgTW9kZGxlIHBhY2thZ2VzLlxuICpcbiAqIEBwYXJhbSB7QXJyYXk8UGFja2FnZT59IHBhY2thZ2VzXG4gKiBAcGFyYW0ge1Byb3BlcnRpZXN9IHByb3BlcnRpZXNcbiAqL1xuZnVuY3Rpb24gUmVnaXN0cnkocGFja2FnZXMsIHByb3BlcnRpZXMpIHtcbiAgdGhpcy5wYWNrYWdlTWFwID0ge307XG4gIHRoaXMudHlwZU1hcCA9IHt9O1xuXG4gIHRoaXMucGFja2FnZXMgPSBbXTtcblxuICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzO1xuXG4gIGZvckVhY2gocGFja2FnZXMsIGJpbmQodGhpcy5yZWdpc3RlclBhY2thZ2UsIHRoaXMpKTtcbn1cblxuXG5SZWdpc3RyeS5wcm90b3R5cGUuZ2V0UGFja2FnZSA9IGZ1bmN0aW9uKHVyaU9yUHJlZml4KSB7XG4gIHJldHVybiB0aGlzLnBhY2thZ2VNYXBbdXJpT3JQcmVmaXhdO1xufTtcblxuUmVnaXN0cnkucHJvdG90eXBlLmdldFBhY2thZ2VzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnBhY2thZ2VzO1xufTtcblxuXG5SZWdpc3RyeS5wcm90b3R5cGUucmVnaXN0ZXJQYWNrYWdlID0gZnVuY3Rpb24ocGtnKSB7XG5cbiAgLy8gY29weSBwYWNrYWdlXG4gIHBrZyA9IGFzc2lnbih7fSwgcGtnKTtcblxuICB2YXIgcGtnTWFwID0gdGhpcy5wYWNrYWdlTWFwO1xuXG4gIGVuc3VyZUF2YWlsYWJsZShwa2dNYXAsIHBrZywgJ3ByZWZpeCcpO1xuICBlbnN1cmVBdmFpbGFibGUocGtnTWFwLCBwa2csICd1cmknKTtcblxuICAvLyByZWdpc3RlciB0eXBlc1xuICBmb3JFYWNoKHBrZy50eXBlcywgYmluZChmdW5jdGlvbihkZXNjcmlwdG9yKSB7XG4gICAgdGhpcy5yZWdpc3RlclR5cGUoZGVzY3JpcHRvciwgcGtnKTtcbiAgfSwgdGhpcykpO1xuXG4gIHBrZ01hcFtwa2cudXJpXSA9IHBrZ01hcFtwa2cucHJlZml4XSA9IHBrZztcbiAgdGhpcy5wYWNrYWdlcy5wdXNoKHBrZyk7XG59O1xuXG5cbi8qKlxuICogUmVnaXN0ZXIgYSB0eXBlIGZyb20gYSBzcGVjaWZpYyBwYWNrYWdlIHdpdGggdXNcbiAqL1xuUmVnaXN0cnkucHJvdG90eXBlLnJlZ2lzdGVyVHlwZSA9IGZ1bmN0aW9uKHR5cGUsIHBrZykge1xuXG4gIHR5cGUgPSBhc3NpZ24oe30sIHR5cGUsIHtcbiAgICBzdXBlckNsYXNzOiAodHlwZS5zdXBlckNsYXNzIHx8IFtdKS5zbGljZSgpLFxuICAgIGV4dGVuZHM6ICh0eXBlLmV4dGVuZHMgfHwgW10pLnNsaWNlKCksXG4gICAgcHJvcGVydGllczogKHR5cGUucHJvcGVydGllcyB8fCBbXSkuc2xpY2UoKSxcbiAgICBtZXRhOiBhc3NpZ24oKHR5cGUubWV0YSB8fCB7fSkpXG4gIH0pO1xuXG4gIHZhciBucyA9IHBhcnNlTmFtZSh0eXBlLm5hbWUsIHBrZy5wcmVmaXgpLFxuICAgICAgbmFtZSA9IG5zLm5hbWUsXG4gICAgICBwcm9wZXJ0aWVzQnlOYW1lID0ge307XG5cbiAgLy8gcGFyc2UgcHJvcGVydGllc1xuICBmb3JFYWNoKHR5cGUucHJvcGVydGllcywgYmluZChmdW5jdGlvbihwKSB7XG5cbiAgICAvLyBuYW1lc3BhY2UgcHJvcGVydHkgbmFtZXNcbiAgICB2YXIgcHJvcGVydHlOcyA9IHBhcnNlTmFtZShwLm5hbWUsIG5zLnByZWZpeCksXG4gICAgICAgIHByb3BlcnR5TmFtZSA9IHByb3BlcnR5TnMubmFtZTtcblxuICAgIC8vIG5hbWVzcGFjZSBwcm9wZXJ0eSB0eXBlc1xuICAgIGlmICghaXNCdWlsdEluKHAudHlwZSkpIHtcbiAgICAgIHAudHlwZSA9IHBhcnNlTmFtZShwLnR5cGUsIHByb3BlcnR5TnMucHJlZml4KS5uYW1lO1xuICAgIH1cblxuICAgIGFzc2lnbihwLCB7XG4gICAgICBuczogcHJvcGVydHlOcyxcbiAgICAgIG5hbWU6IHByb3BlcnR5TmFtZVxuICAgIH0pO1xuXG4gICAgcHJvcGVydGllc0J5TmFtZVtwcm9wZXJ0eU5hbWVdID0gcDtcbiAgfSwgdGhpcykpO1xuXG4gIC8vIHVwZGF0ZSBucyArIG5hbWVcbiAgYXNzaWduKHR5cGUsIHtcbiAgICBuczogbnMsXG4gICAgbmFtZTogbmFtZSxcbiAgICBwcm9wZXJ0aWVzQnlOYW1lOiBwcm9wZXJ0aWVzQnlOYW1lXG4gIH0pO1xuXG4gIGZvckVhY2godHlwZS5leHRlbmRzLCBiaW5kKGZ1bmN0aW9uKGV4dGVuZHNOYW1lKSB7XG4gICAgdmFyIGV4dGVuZGVkID0gdGhpcy50eXBlTWFwW2V4dGVuZHNOYW1lXTtcblxuICAgIGV4dGVuZGVkLnRyYWl0cyA9IGV4dGVuZGVkLnRyYWl0cyB8fCBbXTtcbiAgICBleHRlbmRlZC50cmFpdHMucHVzaChuYW1lKTtcbiAgfSwgdGhpcykpO1xuXG4gIC8vIGxpbmsgdG8gcGFja2FnZVxuICB0aGlzLmRlZmluZVBhY2thZ2UodHlwZSwgcGtnKTtcblxuICAvLyByZWdpc3RlclxuICB0aGlzLnR5cGVNYXBbbmFtZV0gPSB0eXBlO1xufTtcblxuXG4vKipcbiAqIFRyYXZlcnNlIHRoZSB0eXBlIGhpZXJhcmNoeSBmcm9tIGJvdHRvbSB0byB0b3AsXG4gKiBjYWxsaW5nIGl0ZXJhdG9yIHdpdGggKHR5cGUsIGluaGVyaXRlZCkgZm9yIGFsbCBlbGVtZW50cyBpblxuICogdGhlIGluaGVyaXRhbmNlIGNoYWluLlxuICpcbiAqIEBwYXJhbSB7T2JqZWN0fSBuc05hbWVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdG9yXG4gKiBAcGFyYW0ge0Jvb2xlYW59IFt0cmFpdD1mYWxzZV1cbiAqL1xuUmVnaXN0cnkucHJvdG90eXBlLm1hcFR5cGVzID0gZnVuY3Rpb24obnNOYW1lLCBpdGVyYXRvciwgdHJhaXQpIHtcblxuICB2YXIgdHlwZSA9IGlzQnVpbHRJbihuc05hbWUubmFtZSkgPyB7IG5hbWU6IG5zTmFtZS5uYW1lIH0gOiB0aGlzLnR5cGVNYXBbbnNOYW1lLm5hbWVdO1xuXG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvKipcbiAgICogVHJhdmVyc2UgdGhlIHNlbGVjdGVkIHRyYWl0LlxuICAgKlxuICAgKiBAcGFyYW0ge1N0cmluZ30gY2xzXG4gICAqL1xuICBmdW5jdGlvbiB0cmF2ZXJzZVRyYWl0KGNscykge1xuICAgIHJldHVybiB0cmF2ZXJzZVN1cGVyKGNscywgdHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhdmVyc2UgdGhlIHNlbGVjdGVkIHN1cGVyIHR5cGUgb3IgdHJhaXRcbiAgICpcbiAgICogQHBhcmFtIHtTdHJpbmd9IGNsc1xuICAgKiBAcGFyYW0ge0Jvb2xlYW59IFt0cmFpdD1mYWxzZV1cbiAgICovXG4gIGZ1bmN0aW9uIHRyYXZlcnNlU3VwZXIoY2xzLCB0cmFpdCkge1xuICAgIHZhciBwYXJlbnROcyA9IHBhcnNlTmFtZShjbHMsIGlzQnVpbHRJbihjbHMpID8gJycgOiBuc05hbWUucHJlZml4KTtcbiAgICBzZWxmLm1hcFR5cGVzKHBhcmVudE5zLCBpdGVyYXRvciwgdHJhaXQpO1xuICB9XG5cbiAgaWYgKCF0eXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIHR5cGUgPCcgKyBuc05hbWUubmFtZSArICc+Jyk7XG4gIH1cblxuICBmb3JFYWNoKHR5cGUuc3VwZXJDbGFzcywgdHJhaXQgPyB0cmF2ZXJzZVRyYWl0IDogdHJhdmVyc2VTdXBlcik7XG5cbiAgLy8gY2FsbCBpdGVyYXRvciB3aXRoICh0eXBlLCBpbmhlcml0ZWQ9IXRyYWl0KVxuICBpdGVyYXRvcih0eXBlLCAhdHJhaXQpO1xuXG4gIGZvckVhY2godHlwZS50cmFpdHMsIHRyYXZlcnNlVHJhaXQpO1xufTtcblxuXG4vKipcbiAqIFJldHVybnMgdGhlIGVmZmVjdGl2ZSBkZXNjcmlwdG9yIGZvciBhIHR5cGUuXG4gKlxuICogQHBhcmFtICB7U3RyaW5nfSB0eXBlIHRoZSBuYW1lc3BhY2VkIG5hbWUgKG5zOmxvY2FsTmFtZSkgb2YgdGhlIHR5cGVcbiAqXG4gKiBAcmV0dXJuIHtEZXNjcmlwdG9yfSB0aGUgcmVzdWx0aW5nIGVmZmVjdGl2ZSBkZXNjcmlwdG9yXG4gKi9cblJlZ2lzdHJ5LnByb3RvdHlwZS5nZXRFZmZlY3RpdmVEZXNjcmlwdG9yID0gZnVuY3Rpb24obmFtZSkge1xuXG4gIHZhciBuc05hbWUgPSBwYXJzZU5hbWUobmFtZSk7XG5cbiAgdmFyIGJ1aWxkZXIgPSBuZXcgRGVzY3JpcHRvckJ1aWxkZXIobnNOYW1lKTtcblxuICB0aGlzLm1hcFR5cGVzKG5zTmFtZSwgZnVuY3Rpb24odHlwZSwgaW5oZXJpdGVkKSB7XG4gICAgYnVpbGRlci5hZGRUcmFpdCh0eXBlLCBpbmhlcml0ZWQpO1xuICB9KTtcblxuICB2YXIgZGVzY3JpcHRvciA9IGJ1aWxkZXIuYnVpbGQoKTtcblxuICAvLyBkZWZpbmUgcGFja2FnZSBsaW5rXG4gIHRoaXMuZGVmaW5lUGFja2FnZShkZXNjcmlwdG9yLCBkZXNjcmlwdG9yLmFsbFR5cGVzW2Rlc2NyaXB0b3IuYWxsVHlwZXMubGVuZ3RoIC0gMV0uJHBrZyk7XG5cbiAgcmV0dXJuIGRlc2NyaXB0b3I7XG59O1xuXG5cblJlZ2lzdHJ5LnByb3RvdHlwZS5kZWZpbmVQYWNrYWdlID0gZnVuY3Rpb24odGFyZ2V0LCBwa2cpIHtcbiAgdGhpcy5wcm9wZXJ0aWVzLmRlZmluZSh0YXJnZXQsICckcGtnJywgeyB2YWx1ZTogcGtnIH0pO1xufTtcblxuXG5cbi8vLy8vLy8vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZW5zdXJlQXZhaWxhYmxlKHBhY2thZ2VNYXAsIHBrZywgaWRlbnRpZmllcktleSkge1xuXG4gIHZhciB2YWx1ZSA9IHBrZ1tpZGVudGlmaWVyS2V5XTtcblxuICBpZiAodmFsdWUgaW4gcGFja2FnZU1hcCkge1xuICAgIHRocm93IG5ldyBFcnJvcigncGFja2FnZSB3aXRoICcgKyBpZGVudGlmaWVyS2V5ICsgJyA8JyArIHZhbHVlICsgJz4gYWxyZWFkeSBkZWZpbmVkJyk7XG4gIH1cbn1cblxuLyoqXG4gKiBBIHV0aWxpdHkgdGhhdCBnZXRzIGFuZCBzZXRzIHByb3BlcnRpZXMgb2YgbW9kZWwgZWxlbWVudHMuXG4gKlxuICogQHBhcmFtIHtNb2RlbH0gbW9kZWxcbiAqL1xuZnVuY3Rpb24gUHJvcGVydGllcyhtb2RlbCkge1xuICB0aGlzLm1vZGVsID0gbW9kZWw7XG59XG5cblxuLyoqXG4gKiBTZXRzIGEgbmFtZWQgcHJvcGVydHkgb24gdGhlIHRhcmdldCBlbGVtZW50LlxuICogSWYgdGhlIHZhbHVlIGlzIHVuZGVmaW5lZCwgdGhlIHByb3BlcnR5IGdldHMgZGVsZXRlZC5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gdGFyZ2V0XG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxuICogQHBhcmFtIHtPYmplY3R9IHZhbHVlXG4gKi9cblByb3BlcnRpZXMucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKHRhcmdldCwgbmFtZSwgdmFsdWUpIHtcblxuICB2YXIgcHJvcGVydHkgPSB0aGlzLm1vZGVsLmdldFByb3BlcnR5RGVzY3JpcHRvcih0YXJnZXQsIG5hbWUpO1xuXG4gIHZhciBwcm9wZXJ0eU5hbWUgPSBwcm9wZXJ0eSAmJiBwcm9wZXJ0eS5uYW1lO1xuXG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAvLyB1bnNldCB0aGUgcHJvcGVydHksIGlmIHRoZSBzcGVjaWZpZWQgdmFsdWUgaXMgdW5kZWZpbmVkO1xuICAgIC8vIGRlbGV0ZSBmcm9tICRhdHRycyAoZm9yIGV4dGVuc2lvbnMpIG9yIHRoZSB0YXJnZXQgaXRzZWxmXG4gICAgaWYgKHByb3BlcnR5KSB7XG4gICAgICBkZWxldGUgdGFyZ2V0W3Byb3BlcnR5TmFtZV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlbGV0ZSB0YXJnZXQuJGF0dHJzW25hbWVdO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBzZXQgdGhlIHByb3BlcnR5LCBkZWZpbmluZyB3ZWxsIGRlZmluZWQgcHJvcGVydGllcyBvbiB0aGUgZmx5XG4gICAgLy8gb3Igc2ltcGx5IHVwZGF0aW5nIHRoZW0gaW4gdGFyZ2V0LiRhdHRycyAoZm9yIGV4dGVuc2lvbnMpXG4gICAgaWYgKHByb3BlcnR5KSB7XG4gICAgICBpZiAocHJvcGVydHlOYW1lIGluIHRhcmdldCkge1xuICAgICAgICB0YXJnZXRbcHJvcGVydHlOYW1lXSA9IHZhbHVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXQuJGF0dHJzW25hbWVdID0gdmFsdWU7XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG5hbWVkIHByb3BlcnR5IG9mIHRoZSBnaXZlbiBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSAge1N0cmluZ30gbmFtZVxuICpcbiAqIEByZXR1cm4ge09iamVjdH1cbiAqL1xuUHJvcGVydGllcy5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24odGFyZ2V0LCBuYW1lKSB7XG5cbiAgdmFyIHByb3BlcnR5ID0gdGhpcy5tb2RlbC5nZXRQcm9wZXJ0eURlc2NyaXB0b3IodGFyZ2V0LCBuYW1lKTtcblxuICBpZiAoIXByb3BlcnR5KSB7XG4gICAgcmV0dXJuIHRhcmdldC4kYXR0cnNbbmFtZV07XG4gIH1cblxuICB2YXIgcHJvcGVydHlOYW1lID0gcHJvcGVydHkubmFtZTtcblxuICAvLyBjaGVjayBpZiBhY2Nlc3MgdG8gY29sbGVjdGlvbiBwcm9wZXJ0eSBhbmQgbGF6aWx5IGluaXRpYWxpemUgaXRcbiAgaWYgKCF0YXJnZXRbcHJvcGVydHlOYW1lXSAmJiBwcm9wZXJ0eS5pc01hbnkpIHtcbiAgICBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCBbXSk7XG4gIH1cblxuICByZXR1cm4gdGFyZ2V0W3Byb3BlcnR5TmFtZV07XG59O1xuXG5cbi8qKlxuICogRGVmaW5lIGEgcHJvcGVydHkgb24gdGhlIHRhcmdldCBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSAge1N0cmluZ30gbmFtZVxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gKi9cblByb3BlcnRpZXMucHJvdG90eXBlLmRlZmluZSA9IGZ1bmN0aW9uKHRhcmdldCwgbmFtZSwgb3B0aW9ucykge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBuYW1lLCBvcHRpb25zKTtcbn07XG5cblxuLyoqXG4gKiBEZWZpbmUgdGhlIGRlc2NyaXB0b3IgZm9yIGFuIGVsZW1lbnRcbiAqL1xuUHJvcGVydGllcy5wcm90b3R5cGUuZGVmaW5lRGVzY3JpcHRvciA9IGZ1bmN0aW9uKHRhcmdldCwgZGVzY3JpcHRvcikge1xuICB0aGlzLmRlZmluZSh0YXJnZXQsICckZGVzY3JpcHRvcicsIHsgdmFsdWU6IGRlc2NyaXB0b3IgfSk7XG59O1xuXG4vKipcbiAqIERlZmluZSB0aGUgbW9kZWwgZm9yIGFuIGVsZW1lbnRcbiAqL1xuUHJvcGVydGllcy5wcm90b3R5cGUuZGVmaW5lTW9kZWwgPSBmdW5jdGlvbih0YXJnZXQsIG1vZGVsKSB7XG4gIHRoaXMuZGVmaW5lKHRhcmdldCwgJyRtb2RlbCcsIHsgdmFsdWU6IG1vZGVsIH0pO1xufTtcblxuXG5mdW5jdGlvbiBpc1VuZGVmaW5lZCh2YWwpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICd1bmRlZmluZWQnO1xufVxuXG5mdW5jdGlvbiBkZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5LCB2YWx1ZSkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eS5uYW1lLCB7XG4gICAgZW51bWVyYWJsZTogIXByb3BlcnR5LmlzUmVmZXJlbmNlLFxuICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgIHZhbHVlOiB2YWx1ZSxcbiAgICBjb25maWd1cmFibGU6IHRydWVcbiAgfSk7XG59XG5cbi8vLy8gTW9kZGxlIGltcGxlbWVudGF0aW9uIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBAY2xhc3MgTW9kZGxlXG4gKlxuICogQSBtb2RlbCB0aGF0IGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBlbGVtZW50cyBvZiBhIHNwZWNpZmljIHR5cGUuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgTW9kZGxlID0gcmVxdWlyZSgnbW9kZGxlJyk7XG4gKlxuICogdmFyIHBrZyA9IHtcbiAqICAgbmFtZTogJ215cGFja2FnZScsXG4gKiAgIHByZWZpeDogJ215JyxcbiAqICAgdHlwZXM6IFtcbiAqICAgICB7IG5hbWU6ICdSb290JyB9XG4gKiAgIF1cbiAqIH07XG4gKlxuICogdmFyIG1vZGRsZSA9IG5ldyBNb2RkbGUoW3BrZ10pO1xuICpcbiAqIEBwYXJhbSB7QXJyYXk8UGFja2FnZT59IHBhY2thZ2VzIHRoZSBwYWNrYWdlcyB0byBjb250YWluXG4gKi9cbmZ1bmN0aW9uIE1vZGRsZShwYWNrYWdlcykge1xuXG4gIHRoaXMucHJvcGVydGllcyA9IG5ldyBQcm9wZXJ0aWVzKHRoaXMpO1xuXG4gIHRoaXMuZmFjdG9yeSA9IG5ldyBGYWN0b3J5KHRoaXMsIHRoaXMucHJvcGVydGllcyk7XG4gIHRoaXMucmVnaXN0cnkgPSBuZXcgUmVnaXN0cnkocGFja2FnZXMsIHRoaXMucHJvcGVydGllcyk7XG5cbiAgdGhpcy50eXBlQ2FjaGUgPSB7fTtcbn1cblxuXG4vKipcbiAqIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgc3BlY2lmaWVkIHR5cGUuXG4gKlxuICogQG1ldGhvZCBNb2RkbGUjY3JlYXRlXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgZm9vID0gbW9kZGxlLmNyZWF0ZSgnbXk6Rm9vJyk7XG4gKiB2YXIgYmFyID0gbW9kZGxlLmNyZWF0ZSgnbXk6QmFyJywgeyBpZDogJ0JBUl8xJyB9KTtcbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd8T2JqZWN0fSBkZXNjcmlwdG9yIHRoZSB0eXBlIGRlc2NyaXB0b3Igb3IgbmFtZSBrbm93IHRvIHRoZSBtb2RlbFxuICogQHBhcmFtICB7T2JqZWN0fSBhdHRycyAgIGEgbnVtYmVyIG9mIGF0dHJpYnV0ZXMgdG8gaW5pdGlhbGl6ZSB0aGUgbW9kZWwgaW5zdGFuY2Ugd2l0aFxuICogQHJldHVybiB7T2JqZWN0fSAgICAgICAgIG1vZGVsIGluc3RhbmNlXG4gKi9cbk1vZGRsZS5wcm90b3R5cGUuY3JlYXRlID0gZnVuY3Rpb24oZGVzY3JpcHRvciwgYXR0cnMpIHtcbiAgdmFyIFR5cGUgPSB0aGlzLmdldFR5cGUoZGVzY3JpcHRvcik7XG5cbiAgaWYgKCFUeXBlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmtub3duIHR5cGUgPCcgKyBkZXNjcmlwdG9yICsgJz4nKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgVHlwZShhdHRycyk7XG59O1xuXG5cbi8qKlxuICogUmV0dXJucyB0aGUgdHlwZSByZXByZXNlbnRpbmcgYSBnaXZlbiBkZXNjcmlwdG9yXG4gKlxuICogQG1ldGhvZCBNb2RkbGUjZ2V0VHlwZVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIEZvbyA9IG1vZGRsZS5nZXRUeXBlKCdteTpGb28nKTtcbiAqIHZhciBmb28gPSBuZXcgRm9vKHsgJ2lkJyA6ICdGT09fMScgfSk7XG4gKlxuICogQHBhcmFtICB7U3RyaW5nfE9iamVjdH0gZGVzY3JpcHRvciB0aGUgdHlwZSBkZXNjcmlwdG9yIG9yIG5hbWUga25vdyB0byB0aGUgbW9kZWxcbiAqIEByZXR1cm4ge09iamVjdH0gICAgICAgICB0aGUgdHlwZSByZXByZXNlbnRpbmcgdGhlIGRlc2NyaXB0b3JcbiAqL1xuTW9kZGxlLnByb3RvdHlwZS5nZXRUeXBlID0gZnVuY3Rpb24oZGVzY3JpcHRvcikge1xuXG4gIHZhciBjYWNoZSA9IHRoaXMudHlwZUNhY2hlO1xuXG4gIHZhciBuYW1lID0gaXNTdHJpbmcoZGVzY3JpcHRvcikgPyBkZXNjcmlwdG9yIDogZGVzY3JpcHRvci5ucy5uYW1lO1xuXG4gIHZhciB0eXBlID0gY2FjaGVbbmFtZV07XG5cbiAgaWYgKCF0eXBlKSB7XG4gICAgZGVzY3JpcHRvciA9IHRoaXMucmVnaXN0cnkuZ2V0RWZmZWN0aXZlRGVzY3JpcHRvcihuYW1lKTtcbiAgICB0eXBlID0gY2FjaGVbbmFtZV0gPSB0aGlzLmZhY3RvcnkuY3JlYXRlVHlwZShkZXNjcmlwdG9yKTtcbiAgfVxuXG4gIHJldHVybiB0eXBlO1xufTtcblxuXG4vKipcbiAqIENyZWF0ZXMgYW4gYW55LWVsZW1lbnQgdHlwZSB0byBiZSB1c2VkIHdpdGhpbiBtb2RlbCBpbnN0YW5jZXMuXG4gKlxuICogVGhpcyBjYW4gYmUgdXNlZCB0byBjcmVhdGUgY3VzdG9tIGVsZW1lbnRzIHRoYXQgbGllIG91dHNpZGUgdGhlIG1ldGEtbW9kZWwuXG4gKiBUaGUgY3JlYXRlZCBlbGVtZW50IGNvbnRhaW5zIGFsbCB0aGUgbWV0YS1kYXRhIHJlcXVpcmVkIHRvIHNlcmlhbGl6ZSBpdFxuICogYXMgcGFydCBvZiBtZXRhLW1vZGVsIGVsZW1lbnRzLlxuICpcbiAqIEBtZXRob2QgTW9kZGxlI2NyZWF0ZUFueVxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIGZvbyA9IG1vZGRsZS5jcmVhdGVBbnkoJ3ZlbmRvcjpGb28nLCAnaHR0cDovL3ZlbmRvcicsIHtcbiAqICAgdmFsdWU6ICdiYXInXG4gKiB9KTtcbiAqXG4gKiB2YXIgY29udGFpbmVyID0gbW9kZGxlLmNyZWF0ZSgnbXk6Q29udGFpbmVyJywgJ2h0dHA6Ly9teScsIHtcbiAqICAgYW55OiBbIGZvbyBdXG4gKiB9KTtcbiAqXG4gKiAvLyBnbyBhaGVhZCBhbmQgc2VyaWFsaXplIHRoZSBzdHVmZlxuICpcbiAqXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG5hbWUgIHRoZSBuYW1lIG9mIHRoZSBlbGVtZW50XG4gKiBAcGFyYW0gIHtTdHJpbmd9IG5zVXJpIHRoZSBuYW1lc3BhY2UgdXJpIG9mIHRoZSBlbGVtZW50XG4gKiBAcGFyYW0gIHtPYmplY3R9IFtwcm9wZXJ0aWVzXSBhIG1hcCBvZiBwcm9wZXJ0aWVzIHRvIGluaXRpYWxpemUgdGhlIGluc3RhbmNlIHdpdGhcbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIGFueSB0eXBlIGluc3RhbmNlXG4gKi9cbk1vZGRsZS5wcm90b3R5cGUuY3JlYXRlQW55ID0gZnVuY3Rpb24obmFtZSwgbnNVcmksIHByb3BlcnRpZXMpIHtcblxuICB2YXIgbmFtZU5zID0gcGFyc2VOYW1lKG5hbWUpO1xuXG4gIHZhciBlbGVtZW50ID0ge1xuICAgICR0eXBlOiBuYW1lLFxuICAgICRpbnN0YW5jZU9mOiBmdW5jdGlvbih0eXBlKSB7XG4gICAgICByZXR1cm4gdHlwZSA9PT0gdGhpcy4kdHlwZTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIGRlc2NyaXB0b3IgPSB7XG4gICAgbmFtZTogbmFtZSxcbiAgICBpc0dlbmVyaWM6IHRydWUsXG4gICAgbnM6IHtcbiAgICAgIHByZWZpeDogbmFtZU5zLnByZWZpeCxcbiAgICAgIGxvY2FsTmFtZTogbmFtZU5zLmxvY2FsTmFtZSxcbiAgICAgIHVyaTogbnNVcmlcbiAgICB9XG4gIH07XG5cbiAgdGhpcy5wcm9wZXJ0aWVzLmRlZmluZURlc2NyaXB0b3IoZWxlbWVudCwgZGVzY3JpcHRvcik7XG4gIHRoaXMucHJvcGVydGllcy5kZWZpbmVNb2RlbChlbGVtZW50LCB0aGlzKTtcbiAgdGhpcy5wcm9wZXJ0aWVzLmRlZmluZShlbGVtZW50LCAnJHBhcmVudCcsIHsgZW51bWVyYWJsZTogZmFsc2UsIHdyaXRhYmxlOiB0cnVlIH0pO1xuXG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24oYSwga2V5KSB7XG4gICAgaWYgKGlzT2JqZWN0KGEpICYmIGEudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgZWxlbWVudFthLm5hbWVdID0gYS52YWx1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudFtrZXldID0gYTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBlbGVtZW50O1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgcmVnaXN0ZXJlZCBwYWNrYWdlIGJ5IHVyaSBvciBwcmVmaXhcbiAqXG4gKiBAcmV0dXJuIHtPYmplY3R9IHRoZSBwYWNrYWdlXG4gKi9cbk1vZGRsZS5wcm90b3R5cGUuZ2V0UGFja2FnZSA9IGZ1bmN0aW9uKHVyaU9yUHJlZml4KSB7XG4gIHJldHVybiB0aGlzLnJlZ2lzdHJ5LmdldFBhY2thZ2UodXJpT3JQcmVmaXgpO1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGEgc25hcHNob3Qgb2YgYWxsIGtub3duIHBhY2thZ2VzXG4gKlxuICogQHJldHVybiB7T2JqZWN0fSB0aGUgcGFja2FnZVxuICovXG5Nb2RkbGUucHJvdG90eXBlLmdldFBhY2thZ2VzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnJlZ2lzdHJ5LmdldFBhY2thZ2VzKCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGRlc2NyaXB0b3IgZm9yIGFuIGVsZW1lbnRcbiAqL1xuTW9kZGxlLnByb3RvdHlwZS5nZXRFbGVtZW50RGVzY3JpcHRvciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQuJGRlc2NyaXB0b3I7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgZ2l2ZW4gZGVzY3JpcHRvciBvciBpbnN0YW5jZVxuICogcmVwcmVzZW50cyB0aGUgZ2l2ZW4gdHlwZS5cbiAqXG4gKiBNYXkgYmUgYXBwbGllZCB0byB0aGlzLCBpZiBlbGVtZW50IGlzIG9taXR0ZWQuXG4gKi9cbk1vZGRsZS5wcm90b3R5cGUuaGFzVHlwZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHR5cGUpIHtcbiAgaWYgKHR5cGUgPT09IHVuZGVmaW5lZCkge1xuICAgIHR5cGUgPSBlbGVtZW50O1xuICAgIGVsZW1lbnQgPSB0aGlzO1xuICB9XG5cbiAgdmFyIGRlc2NyaXB0b3IgPSBlbGVtZW50LiRtb2RlbC5nZXRFbGVtZW50RGVzY3JpcHRvcihlbGVtZW50KTtcblxuICByZXR1cm4gKHR5cGUgaW4gZGVzY3JpcHRvci5hbGxUeXBlc0J5TmFtZSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGRlc2NyaXB0b3Igb2YgYW4gZWxlbWVudHMgbmFtZWQgcHJvcGVydHlcbiAqL1xuTW9kZGxlLnByb3RvdHlwZS5nZXRQcm9wZXJ0eURlc2NyaXB0b3IgPSBmdW5jdGlvbihlbGVtZW50LCBwcm9wZXJ0eSkge1xuICByZXR1cm4gdGhpcy5nZXRFbGVtZW50RGVzY3JpcHRvcihlbGVtZW50KS5wcm9wZXJ0aWVzQnlOYW1lW3Byb3BlcnR5XTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIG1hcHBlZCB0eXBlJ3MgZGVzY3JpcHRvclxuICovXG5Nb2RkbGUucHJvdG90eXBlLmdldFR5cGVEZXNjcmlwdG9yID0gZnVuY3Rpb24odHlwZSkge1xuICByZXR1cm4gdGhpcy5yZWdpc3RyeS50eXBlTWFwW3R5cGVdO1xufTtcblxuZXhwb3J0IHsgTW9kZGxlLCBjb2VyY2VUeXBlLCBpc0J1aWx0SW4gYXMgaXNCdWlsdEluVHlwZSwgaXNTaW1wbGUgYXMgaXNTaW1wbGVUeXBlLCBwYXJzZU5hbWUgYXMgcGFyc2VOYW1lTlMgfTtcbiIsIm1vZHVsZS5leHBvcnRzID0gcmVxdWlyZSgnLi9saWIvcmVmcycpO1xuXG5tb2R1bGUuZXhwb3J0cy5Db2xsZWN0aW9uID0gcmVxdWlyZSgnLi9saWIvY29sbGVjdGlvbicpOyIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBBbiBlbXB0eSBjb2xsZWN0aW9uIHN0dWIuIFVzZSB7QGxpbmsgUmVmc0NvbGxlY3Rpb24uZXh0ZW5kfSB0byBleHRlbmQgYVxuICogY29sbGVjdGlvbiB3aXRoIHJlZiBzZW1hbnRpY3MuXG4gKlxuICogQGNsYXNzIFJlZnNDb2xsZWN0aW9uXG4gKi9cblxuLyoqXG4gKiBFeHRlbmRzIGEgY29sbGVjdGlvbiB3aXRoIHtAbGluayBSZWZzfSBhd2FyZSBtZXRob2RzXG4gKlxuICogQG1lbWJlcm9mIFJlZnNDb2xsZWN0aW9uXG4gKiBAc3RhdGljXG4gKlxuICogQHBhcmFtICB7QXJyYXk8T2JqZWN0Pn0gY29sbGVjdGlvblxuICogQHBhcmFtICB7UmVmc30gcmVmcyBpbnN0YW5jZVxuICogQHBhcmFtICB7T2JqZWN0fSBwcm9wZXJ0eSByZXByZXNlbnRlZCBieSB0aGUgY29sbGVjdGlvblxuICogQHBhcmFtICB7T2JqZWN0fSB0YXJnZXQgb2JqZWN0IHRoZSBjb2xsZWN0aW9uIGlzIGF0dGFjaGVkIHRvXG4gKlxuICogQHJldHVybiB7UmVmc0NvbGxlY3Rpb248T2JqZWN0Pn0gdGhlIGV4dGVuZGVkIGFycmF5XG4gKi9cbmZ1bmN0aW9uIGV4dGVuZChjb2xsZWN0aW9uLCByZWZzLCBwcm9wZXJ0eSwgdGFyZ2V0KSB7XG5cbiAgdmFyIGludmVyc2VQcm9wZXJ0eSA9IHByb3BlcnR5LmludmVyc2U7XG5cbiAgLyoqXG4gICAqIFJlbW92ZXMgdGhlIGdpdmVuIGVsZW1lbnQgZnJvbSB0aGUgYXJyYXkgYW5kIHJldHVybnMgaXQuXG4gICAqXG4gICAqIEBtZXRob2QgUmVmc0NvbGxlY3Rpb24jcmVtb3ZlXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50IHRoZSBlbGVtZW50IHRvIHJlbW92ZVxuICAgKi9cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbGxlY3Rpb24sICdyZW1vdmUnLCB7XG4gICAgdmFsdWU6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgICAgIHZhciBpZHggPSB0aGlzLmluZGV4T2YoZWxlbWVudCk7XG4gICAgICBpZiAoaWR4ICE9PSAtMSkge1xuICAgICAgICB0aGlzLnNwbGljZShpZHgsIDEpO1xuXG4gICAgICAgIC8vIHVuc2V0IGludmVyc2VcbiAgICAgICAgcmVmcy51bnNldChlbGVtZW50LCBpbnZlcnNlUHJvcGVydHksIHRhcmdldCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBlbGVtZW50O1xuICAgIH1cbiAgfSk7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgY29sbGVjdGlvbiBjb250YWlucyB0aGUgZ2l2ZW4gZWxlbWVudFxuICAgKlxuICAgKiBAbWV0aG9kIFJlZnNDb2xsZWN0aW9uI2NvbnRhaW5zXG4gICAqXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50IHRoZSBlbGVtZW50IHRvIGNoZWNrIGZvclxuICAgKi9cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbGxlY3Rpb24sICdjb250YWlucycsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24oZWxlbWVudCkge1xuICAgICAgcmV0dXJuIHRoaXMuaW5kZXhPZihlbGVtZW50KSAhPT0gLTE7XG4gICAgfVxuICB9KTtcblxuICAvKipcbiAgICogQWRkcyBhbiBlbGVtZW50IHRvIHRoZSBhcnJheSwgdW5sZXNzIGl0IGV4aXN0cyBhbHJlYWR5IChzZXQgc2VtYW50aWNzKS5cbiAgICpcbiAgICogQG1ldGhvZCBSZWZzQ29sbGVjdGlvbiNhZGRcbiAgICpcbiAgICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnQgdGhlIGVsZW1lbnQgdG8gYWRkXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25hbCBpbmRleCB0byBhZGQgZWxlbWVudCB0b1xuICAgKiAgICAgICAgICAgICAgICAgKHBvc3NpYmx5IG1vdmluZyBvdGhlciBlbGVtZW50cyBhcm91bmQpXG4gICAqL1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkoY29sbGVjdGlvbiwgJ2FkZCcsIHtcbiAgICB2YWx1ZTogZnVuY3Rpb24oZWxlbWVudCwgaWR4KSB7XG5cbiAgICAgIHZhciBjdXJyZW50SWR4ID0gdGhpcy5pbmRleE9mKGVsZW1lbnQpO1xuXG4gICAgICBpZiAodHlwZW9mIGlkeCA9PT0gJ3VuZGVmaW5lZCcpIHtcblxuICAgICAgICBpZiAoY3VycmVudElkeCAhPT0gLTEpIHtcbiAgICAgICAgICAvLyBlbGVtZW50IGFscmVhZHkgaW4gY29sbGVjdGlvbiAoISlcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZGQgdG8gZW5kIG9mIGFycmF5LCBhcyBubyBpZHggaXMgc3BlY2lmaWVkXG4gICAgICAgIGlkeCA9IHRoaXMubGVuZ3RoO1xuICAgICAgfVxuXG4gICAgICAvLyBoYW5kbGUgYWxyZWFkeSBpbiBjb2xsZWN0aW9uXG4gICAgICBpZiAoY3VycmVudElkeCAhPT0gLTEpIHtcblxuICAgICAgICAvLyByZW1vdmUgZWxlbWVudCBmcm9tIGN1cnJlbnRJZHhcbiAgICAgICAgdGhpcy5zcGxpY2UoY3VycmVudElkeCwgMSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGFkZCBlbGVtZW50IGF0IGlkeFxuICAgICAgdGhpcy5zcGxpY2UoaWR4LCAwLCBlbGVtZW50KTtcblxuICAgICAgaWYgKGN1cnJlbnRJZHggPT09IC0xKSB7XG4gICAgICAgIC8vIHNldCBpbnZlcnNlLCB1bmxlc3MgZWxlbWVudCB3YXNcbiAgICAgICAgLy8gaW4gY29sbGVjdGlvbiBhbHJlYWR5XG4gICAgICAgIHJlZnMuc2V0KGVsZW1lbnQsIGludmVyc2VQcm9wZXJ0eSwgdGFyZ2V0KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIC8vIGEgc2ltcGxlIG1hcmtlciwgaWRlbnRpZnlpbmcgdGhpcyBlbGVtZW50XG4gIC8vIGFzIGJlaW5nIGEgcmVmcyBjb2xsZWN0aW9uXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb2xsZWN0aW9uLCAnX19yZWZzX2NvbGxlY3Rpb24nLCB7XG4gICAgdmFsdWU6IHRydWVcbiAgfSk7XG5cbiAgcmV0dXJuIGNvbGxlY3Rpb247XG59XG5cblxuZnVuY3Rpb24gaXNFeHRlbmRlZChjb2xsZWN0aW9uKSB7XG4gIHJldHVybiBjb2xsZWN0aW9uLl9fcmVmc19jb2xsZWN0aW9uID09PSB0cnVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgPSBleHRlbmQ7XG5cbm1vZHVsZS5leHBvcnRzLmlzRXh0ZW5kZWQgPSBpc0V4dGVuZGVkOyIsIid1c2Ugc3RyaWN0JztcblxudmFyIENvbGxlY3Rpb24gPSByZXF1aXJlKCcuL2NvbGxlY3Rpb24nKTtcblxuZnVuY3Rpb24gaGFzT3duUHJvcGVydHkoZSwgcHJvcGVydHkpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChlLCBwcm9wZXJ0eS5uYW1lIHx8IHByb3BlcnR5KTtcbn1cblxuZnVuY3Rpb24gZGVmaW5lQ29sbGVjdGlvblByb3BlcnR5KHJlZiwgcHJvcGVydHksIHRhcmdldCkge1xuXG4gIHZhciBjb2xsZWN0aW9uID0gQ29sbGVjdGlvbi5leHRlbmQodGFyZ2V0W3Byb3BlcnR5Lm5hbWVdIHx8IFtdLCByZWYsIHByb3BlcnR5LCB0YXJnZXQpO1xuXG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIHByb3BlcnR5Lm5hbWUsIHtcbiAgICBlbnVtZXJhYmxlOiBwcm9wZXJ0eS5lbnVtZXJhYmxlLFxuICAgIHZhbHVlOiBjb2xsZWN0aW9uXG4gIH0pO1xuXG4gIGlmIChjb2xsZWN0aW9uLmxlbmd0aCkge1xuXG4gICAgY29sbGVjdGlvbi5mb3JFYWNoKGZ1bmN0aW9uKG8pIHtcbiAgICAgIHJlZi5zZXQobywgcHJvcGVydHkuaW52ZXJzZSwgdGFyZ2V0KTtcbiAgICB9KTtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIGRlZmluZVByb3BlcnR5KHJlZiwgcHJvcGVydHksIHRhcmdldCkge1xuXG4gIHZhciBpbnZlcnNlUHJvcGVydHkgPSBwcm9wZXJ0eS5pbnZlcnNlO1xuXG4gIHZhciBfdmFsdWUgPSB0YXJnZXRbcHJvcGVydHkubmFtZV07XG5cbiAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgcHJvcGVydHkubmFtZSwge1xuICAgIGNvbmZpZ3VyYWJsZTogcHJvcGVydHkuY29uZmlndXJhYmxlLFxuICAgIGVudW1lcmFibGU6IHByb3BlcnR5LmVudW1lcmFibGUsXG5cbiAgICBnZXQ6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIF92YWx1ZTtcbiAgICB9LFxuXG4gICAgc2V0OiBmdW5jdGlvbih2YWx1ZSkge1xuXG4gICAgICAvLyByZXR1cm4gaWYgd2UgYWxyZWFkeSBwZXJmb3JtZWQgYWxsIGNoYW5nZXNcbiAgICAgIGlmICh2YWx1ZSA9PT0gX3ZhbHVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdmFyIG9sZCA9IF92YWx1ZTtcblxuICAgICAgLy8gdGVtcG9yYXJ5IHNldCBudWxsXG4gICAgICBfdmFsdWUgPSBudWxsO1xuXG4gICAgICBpZiAob2xkKSB7XG4gICAgICAgIHJlZi51bnNldChvbGQsIGludmVyc2VQcm9wZXJ0eSwgdGFyZ2V0KTtcbiAgICAgIH1cblxuICAgICAgLy8gc2V0IG5ldyB2YWx1ZVxuICAgICAgX3ZhbHVlID0gdmFsdWU7XG5cbiAgICAgIC8vIHNldCBpbnZlcnNlIHZhbHVlXG4gICAgICByZWYuc2V0KF92YWx1ZSwgaW52ZXJzZVByb3BlcnR5LCB0YXJnZXQpO1xuICAgIH1cbiAgfSk7XG5cbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHJlZmVyZW5jZXMgb2JqZWN0IGRlZmluaW5nIHR3byBpbnZlcnNseSByZWxhdGVkXG4gKiBhdHRyaWJ1dGUgZGVzY3JpcHRvcnMgYSBhbmQgYi5cbiAqXG4gKiA8cD5cbiAqICAgV2hlbiBib3VuZCB0byBhbiBvYmplY3QgdXNpbmcge0BsaW5rIFJlZnMjYmluZH0gdGhlIHJlZmVyZW5jZXNcbiAqICAgZ2V0IGFjdGl2YXRlZCBhbmQgZW5zdXJlIHRoYXQgYWRkIGFuZCByZW1vdmUgb3BlcmF0aW9ucyBhcmUgYXBwbGllZFxuICogICByZXZlcnNlbHksIHRvby5cbiAqIDwvcD5cbiAqXG4gKiA8cD5cbiAqICAgRm9yIGF0dHJpYnV0ZXMgcmVwcmVzZW50ZWQgYXMgY29sbGVjdGlvbnMge0BsaW5rIFJlZnN9IHByb3ZpZGVzIHRoZVxuICogICB7QGxpbmsgUmVmc0NvbGxlY3Rpb24jYWRkfSwge0BsaW5rIFJlZnNDb2xsZWN0aW9uI3JlbW92ZX0gYW5kIHtAbGluayBSZWZzQ29sbGVjdGlvbiNjb250YWluc30gZXh0ZW5zaW9uc1xuICogICB0aGF0IG11c3QgYmUgdXNlZCB0byBwcm9wZXJseSBob29rIGludG8gdGhlIGludmVyc2UgY2hhbmdlIG1lY2hhbmlzbS5cbiAqIDwvcD5cbiAqXG4gKiBAY2xhc3MgUmVmc1xuICpcbiAqIEBjbGFzc2Rlc2MgQSBiaS1kaXJlY3Rpb25hbCByZWZlcmVuY2UgYmV0d2VlbiB0d28gYXR0cmlidXRlcy5cbiAqXG4gKiBAcGFyYW0ge1JlZnMuQXR0cmlidXRlRGVzY3JpcHRvcn0gYSBwcm9wZXJ0eSBkZXNjcmlwdG9yXG4gKiBAcGFyYW0ge1JlZnMuQXR0cmlidXRlRGVzY3JpcHRvcn0gYiBwcm9wZXJ0eSBkZXNjcmlwdG9yXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgcmVmcyA9IFJlZnMoeyBuYW1lOiAnd2hlZWxzJywgY29sbGVjdGlvbjogdHJ1ZSwgZW51bWVyYWJsZTogdHJ1ZSB9LCB7IG5hbWU6ICdjYXInIH0pO1xuICpcbiAqIHZhciBjYXIgPSB7IG5hbWU6ICd0b3lvdGEnIH07XG4gKiB2YXIgd2hlZWxzID0gW3sgcG9zOiAnZnJvbnQtbGVmdCcgfSwgeyBwb3M6ICdmcm9udC1yaWdodCcgfV07XG4gKlxuICogcmVmcy5iaW5kKGNhciwgJ3doZWVscycpO1xuICpcbiAqIGNhci53aGVlbHMgLy8gW11cbiAqIGNhci53aGVlbHMuYWRkKHdoZWVsc1swXSk7XG4gKiBjYXIud2hlZWxzLmFkZCh3aGVlbHNbMV0pO1xuICpcbiAqIGNhci53aGVlbHMgLy8gW3sgcG9zOiAnZnJvbnQtbGVmdCcgfSwgeyBwb3M6ICdmcm9udC1yaWdodCcgfV1cbiAqXG4gKiB3aGVlbHNbMF0uY2FyIC8vIHsgbmFtZTogJ3RveW90YScgfTtcbiAqIGNhci53aGVlbHMucmVtb3ZlKHdoZWVsc1swXSk7XG4gKlxuICogd2hlZWxzWzBdLmNhciAvLyB1bmRlZmluZWRcbiAqL1xuZnVuY3Rpb24gUmVmcyhhLCBiKSB7XG5cbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFJlZnMpKSB7XG4gICAgcmV0dXJuIG5ldyBSZWZzKGEsIGIpO1xuICB9XG5cbiAgLy8gbGlua1xuICBhLmludmVyc2UgPSBiO1xuICBiLmludmVyc2UgPSBhO1xuXG4gIHRoaXMucHJvcHMgPSB7fTtcbiAgdGhpcy5wcm9wc1thLm5hbWVdID0gYTtcbiAgdGhpcy5wcm9wc1tiLm5hbWVdID0gYjtcbn1cblxuLyoqXG4gKiBCaW5kcyBvbmUgc2lkZSBvZiBhIGJpLWRpcmVjdGlvbmFsIHJlZmVyZW5jZSB0byBhXG4gKiB0YXJnZXQgb2JqZWN0LlxuICpcbiAqIEBtZW1iZXJPZiBSZWZzXG4gKlxuICogQHBhcmFtICB7T2JqZWN0fSB0YXJnZXRcbiAqIEBwYXJhbSAge1N0cmluZ30gcHJvcGVydHlcbiAqL1xuUmVmcy5wcm90b3R5cGUuYmluZCA9IGZ1bmN0aW9uKHRhcmdldCwgcHJvcGVydHkpIHtcbiAgaWYgKHR5cGVvZiBwcm9wZXJ0eSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAoIXRoaXMucHJvcHNbcHJvcGVydHldKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ25vIHByb3BlcnR5IDwnICsgcHJvcGVydHkgKyAnPiBpbiByZWYnKTtcbiAgICB9XG4gICAgcHJvcGVydHkgPSB0aGlzLnByb3BzW3Byb3BlcnR5XTtcbiAgfVxuXG4gIGlmIChwcm9wZXJ0eS5jb2xsZWN0aW9uKSB7XG4gICAgZGVmaW5lQ29sbGVjdGlvblByb3BlcnR5KHRoaXMsIHByb3BlcnR5LCB0YXJnZXQpO1xuICB9IGVsc2Uge1xuICAgIGRlZmluZVByb3BlcnR5KHRoaXMsIHByb3BlcnR5LCB0YXJnZXQpO1xuICB9XG59O1xuXG5SZWZzLnByb3RvdHlwZS5lbnN1cmVSZWZzQ29sbGVjdGlvbiA9IGZ1bmN0aW9uKHRhcmdldCwgcHJvcGVydHkpIHtcblxuICB2YXIgY29sbGVjdGlvbiA9IHRhcmdldFtwcm9wZXJ0eS5uYW1lXTtcblxuICBpZiAoIUNvbGxlY3Rpb24uaXNFeHRlbmRlZChjb2xsZWN0aW9uKSkge1xuICAgIGRlZmluZUNvbGxlY3Rpb25Qcm9wZXJ0eSh0aGlzLCBwcm9wZXJ0eSwgdGFyZ2V0KTtcbiAgfVxuXG4gIHJldHVybiBjb2xsZWN0aW9uO1xufTtcblxuUmVmcy5wcm90b3R5cGUuZW5zdXJlQm91bmQgPSBmdW5jdGlvbih0YXJnZXQsIHByb3BlcnR5KSB7XG4gIGlmICghaGFzT3duUHJvcGVydHkodGFyZ2V0LCBwcm9wZXJ0eSkpIHtcbiAgICB0aGlzLmJpbmQodGFyZ2V0LCBwcm9wZXJ0eSk7XG4gIH1cbn07XG5cblJlZnMucHJvdG90eXBlLnVuc2V0ID0gZnVuY3Rpb24odGFyZ2V0LCBwcm9wZXJ0eSwgdmFsdWUpIHtcblxuICBpZiAodGFyZ2V0KSB7XG4gICAgdGhpcy5lbnN1cmVCb3VuZCh0YXJnZXQsIHByb3BlcnR5KTtcblxuICAgIGlmIChwcm9wZXJ0eS5jb2xsZWN0aW9uKSB7XG4gICAgICB0aGlzLmVuc3VyZVJlZnNDb2xsZWN0aW9uKHRhcmdldCwgcHJvcGVydHkpLnJlbW92ZSh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRhcmdldFtwcm9wZXJ0eS5uYW1lXSA9IHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cbn07XG5cblJlZnMucHJvdG90eXBlLnNldCA9IGZ1bmN0aW9uKHRhcmdldCwgcHJvcGVydHksIHZhbHVlKSB7XG5cbiAgaWYgKHRhcmdldCkge1xuICAgIHRoaXMuZW5zdXJlQm91bmQodGFyZ2V0LCBwcm9wZXJ0eSk7XG5cbiAgICBpZiAocHJvcGVydHkuY29sbGVjdGlvbikge1xuICAgICAgdGhpcy5lbnN1cmVSZWZzQ29sbGVjdGlvbih0YXJnZXQsIHByb3BlcnR5KS5hZGQodmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0YXJnZXRbcHJvcGVydHkubmFtZV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzID0gUmVmcztcblxuXG4vKipcbiAqIEFuIGF0dHJpYnV0ZSBkZXNjcmlwdG9yIHRvIGJlIHVzZWQgc3BlY2lmeSBhbiBhdHRyaWJ1dGUgaW4gYSB7QGxpbmsgUmVmc30gaW5zdGFuY2VcbiAqXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBSZWZzLkF0dHJpYnV0ZURlc2NyaXB0b3JcbiAqIEBwcm9wZXJ0eSB7U3RyaW5nfSBuYW1lXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IFtjb2xsZWN0aW9uPWZhbHNlXVxuICogQHByb3BlcnR5IHtib29sZWFufSBbZW51bWVyYWJsZT1mYWxzZV1cbiAqLyIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBUaGlzIGZpbGUgY29udGFpbnMgc291cmNlIGNvZGUgYWRhcHRlZCBmcm9tIFNuYXAuc3ZnIChsaWNlbnNlZCBBcGFjaGUtMi4wKS5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hZG9iZS13ZWJwbGF0Zm9ybS9TbmFwLnN2Zy9ibG9iL21hc3Rlci9zcmMvcGF0aC5qc1xuICovXG5cbi8qIGVzbGludCBuby1mYWxsdGhyb3VnaDogXCJvZmZcIiAqL1xuXG52YXIgcDJzID0gLyw/KFthLXpdKSw/L2dpLFxuICAgIHRvRmxvYXQgPSBwYXJzZUZsb2F0LFxuICAgIG1hdGggPSBNYXRoLFxuICAgIFBJID0gbWF0aC5QSSxcbiAgICBtbWluID0gbWF0aC5taW4sXG4gICAgbW1heCA9IG1hdGgubWF4LFxuICAgIHBvdyA9IG1hdGgucG93LFxuICAgIGFicyA9IG1hdGguYWJzLFxuICAgIHBhdGhDb21tYW5kID0gLyhbYS16XSlbXFxzLF0qKCgtP1xcZCpcXC4/XFxkKig/OmVbLStdP1xcZCspP1tcXHNdKiw/W1xcc10qKSspL2lnLFxuICAgIHBhdGhWYWx1ZXMgPSAvKC0/XFxkKlxcLj9cXGQqKD86ZVstK10/XFxcXGQrKT8pW1xcc10qLD9bXFxzXSovaWc7XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbihvKSB7IHJldHVybiBvIGluc3RhbmNlb2YgQXJyYXk7IH07XG5cbmZ1bmN0aW9uIGhhc1Byb3BlcnR5KG9iaiwgcHJvcGVydHkpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3BlcnR5KTtcbn1cblxuZnVuY3Rpb24gY2xvbmUob2JqKSB7XG5cbiAgaWYgKHR5cGVvZiBvYmogPT0gJ2Z1bmN0aW9uJyB8fCBPYmplY3Qob2JqKSAhPT0gb2JqKSB7XG4gICAgcmV0dXJuIG9iajtcbiAgfVxuXG4gIHZhciByZXMgPSBuZXcgb2JqLmNvbnN0cnVjdG9yO1xuXG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoaGFzUHJvcGVydHkob2JqLCBrZXkpKSB7XG4gICAgICByZXNba2V5XSA9IGNsb25lKG9ialtrZXldKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiByZXB1c2goYXJyYXksIGl0ZW0pIHtcbiAgZm9yICh2YXIgaSA9IDAsIGlpID0gYXJyYXkubGVuZ3RoOyBpIDwgaWk7IGkrKykgaWYgKGFycmF5W2ldID09PSBpdGVtKSB7XG4gICAgcmV0dXJuIGFycmF5LnB1c2goYXJyYXkuc3BsaWNlKGksIDEpWzBdKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjYWNoZXIoZikge1xuXG4gIGZ1bmN0aW9uIG5ld2YoKSB7XG5cbiAgICB2YXIgYXJnID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSxcbiAgICAgICAgYXJncyA9IGFyZy5qb2luKCdcXHUyNDAwJyksXG4gICAgICAgIGNhY2hlID0gbmV3Zi5jYWNoZSA9IG5ld2YuY2FjaGUgfHwge30sXG4gICAgICAgIGNvdW50ID0gbmV3Zi5jb3VudCA9IG5ld2YuY291bnQgfHwgW107XG5cbiAgICBpZiAoaGFzUHJvcGVydHkoY2FjaGUsIGFyZ3MpKSB7XG4gICAgICByZXB1c2goY291bnQsIGFyZ3MpO1xuICAgICAgcmV0dXJuIGNhY2hlW2FyZ3NdO1xuICAgIH1cblxuICAgIGNvdW50Lmxlbmd0aCA+PSAxZTMgJiYgZGVsZXRlIGNhY2hlW2NvdW50LnNoaWZ0KCldO1xuICAgIGNvdW50LnB1c2goYXJncyk7XG4gICAgY2FjaGVbYXJnc10gPSBmLmFwcGx5KDAsIGFyZyk7XG5cbiAgICByZXR1cm4gY2FjaGVbYXJnc107XG4gIH1cbiAgcmV0dXJuIG5ld2Y7XG59XG5cbmZ1bmN0aW9uIHBhcnNlUGF0aFN0cmluZyhwYXRoU3RyaW5nKSB7XG5cbiAgaWYgKCFwYXRoU3RyaW5nKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2YXIgcHRoID0gcGF0aHMocGF0aFN0cmluZyk7XG5cbiAgaWYgKHB0aC5hcnIpIHtcbiAgICByZXR1cm4gY2xvbmUocHRoLmFycik7XG4gIH1cblxuICB2YXIgcGFyYW1Db3VudHMgPSB7IGE6IDcsIGM6IDYsIGg6IDEsIGw6IDIsIG06IDIsIHE6IDQsIHM6IDQsIHQ6IDIsIHY6IDEsIHo6IDAgfSxcbiAgICAgIGRhdGEgPSBbXTtcblxuICBpZiAoaXNBcnJheShwYXRoU3RyaW5nKSAmJiBpc0FycmF5KHBhdGhTdHJpbmdbMF0pKSB7IC8vIHJvdWdoIGFzc3VtcHRpb25cbiAgICBkYXRhID0gY2xvbmUocGF0aFN0cmluZyk7XG4gIH1cblxuICBpZiAoIWRhdGEubGVuZ3RoKSB7XG5cbiAgICBTdHJpbmcocGF0aFN0cmluZykucmVwbGFjZShwYXRoQ29tbWFuZCwgZnVuY3Rpb24oYSwgYiwgYykge1xuICAgICAgdmFyIHBhcmFtcyA9IFtdLFxuICAgICAgICAgIG5hbWUgPSBiLnRvTG93ZXJDYXNlKCk7XG5cbiAgICAgIGMucmVwbGFjZShwYXRoVmFsdWVzLCBmdW5jdGlvbihhLCBiKSB7XG4gICAgICAgIGIgJiYgcGFyYW1zLnB1c2goK2IpO1xuICAgICAgfSk7XG5cbiAgICAgIGlmIChuYW1lID09ICdtJyAmJiBwYXJhbXMubGVuZ3RoID4gMikge1xuICAgICAgICBkYXRhLnB1c2goW2JdLmNvbmNhdChwYXJhbXMuc3BsaWNlKDAsIDIpKSk7XG4gICAgICAgIG5hbWUgPSAnbCc7XG4gICAgICAgIGIgPSBiID09ICdtJyA/ICdsJyA6ICdMJztcbiAgICAgIH1cblxuICAgICAgd2hpbGUgKHBhcmFtcy5sZW5ndGggPj0gcGFyYW1Db3VudHNbbmFtZV0pIHtcbiAgICAgICAgZGF0YS5wdXNoKFtiXS5jb25jYXQocGFyYW1zLnNwbGljZSgwLCBwYXJhbUNvdW50c1tuYW1lXSkpKTtcbiAgICAgICAgaWYgKCFwYXJhbUNvdW50c1tuYW1lXSkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBkYXRhLnRvU3RyaW5nID0gcGF0aHMudG9TdHJpbmc7XG4gIHB0aC5hcnIgPSBjbG9uZShkYXRhKTtcblxuICByZXR1cm4gZGF0YTtcbn1cblxuZnVuY3Rpb24gcGF0aHMocHMpIHtcbiAgdmFyIHAgPSBwYXRocy5wcyA9IHBhdGhzLnBzIHx8IHt9O1xuXG4gIGlmIChwW3BzXSkge1xuICAgIHBbcHNdLnNsZWVwID0gMTAwO1xuICB9IGVsc2Uge1xuICAgIHBbcHNdID0ge1xuICAgICAgc2xlZXA6IDEwMFxuICAgIH07XG4gIH1cblxuICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIGtleSBpbiBwKSB7XG4gICAgICBpZiAoaGFzUHJvcGVydHkocCwga2V5KSAmJiBrZXkgIT0gcHMpIHtcbiAgICAgICAgcFtrZXldLnNsZWVwLS07XG4gICAgICAgICFwW2tleV0uc2xlZXAgJiYgZGVsZXRlIHBba2V5XTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBwW3BzXTtcbn1cblxuZnVuY3Rpb24gcmVjdEJCb3goeCwgeSwgd2lkdGgsIGhlaWdodCkge1xuXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgeSA9IHgueTtcbiAgICB3aWR0aCA9IHgud2lkdGg7XG4gICAgaGVpZ2h0ID0geC5oZWlnaHQ7XG4gICAgeCA9IHgueDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgeDogeCxcbiAgICB5OiB5LFxuICAgIHdpZHRoOiB3aWR0aCxcbiAgICBoZWlnaHQ6IGhlaWdodCxcbiAgICB4MjogeCArIHdpZHRoLFxuICAgIHkyOiB5ICsgaGVpZ2h0XG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhdGhUb1N0cmluZygpIHtcbiAgcmV0dXJuIHRoaXMuam9pbignLCcpLnJlcGxhY2UocDJzLCAnJDEnKTtcbn1cblxuZnVuY3Rpb24gcGF0aENsb25lKHBhdGhBcnJheSkge1xuICB2YXIgcmVzID0gY2xvbmUocGF0aEFycmF5KTtcbiAgcmVzLnRvU3RyaW5nID0gcGF0aFRvU3RyaW5nO1xuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiBmaW5kRG90c0F0U2VnbWVudChwMXgsIHAxeSwgYzF4LCBjMXksIGMyeCwgYzJ5LCBwMngsIHAyeSwgdCkge1xuICB2YXIgdDEgPSAxIC0gdCxcbiAgICAgIHQxMyA9IHBvdyh0MSwgMyksXG4gICAgICB0MTIgPSBwb3codDEsIDIpLFxuICAgICAgdDIgPSB0ICogdCxcbiAgICAgIHQzID0gdDIgKiB0LFxuICAgICAgeCA9IHQxMyAqIHAxeCArIHQxMiAqIDMgKiB0ICogYzF4ICsgdDEgKiAzICogdCAqIHQgKiBjMnggKyB0MyAqIHAyeCxcbiAgICAgIHkgPSB0MTMgKiBwMXkgKyB0MTIgKiAzICogdCAqIGMxeSArIHQxICogMyAqIHQgKiB0ICogYzJ5ICsgdDMgKiBwMnk7XG5cbiAgcmV0dXJuIHtcbiAgICB4OiBmaXhFcnJvcih4KSxcbiAgICB5OiBmaXhFcnJvcih5KVxuICB9O1xufVxuXG5mdW5jdGlvbiBiZXppZXJCQm94KHBvaW50cykge1xuXG4gIHZhciBiYm94ID0gY3VydmVCQm94LmFwcGx5KG51bGwsIHBvaW50cyk7XG5cbiAgcmV0dXJuIHJlY3RCQm94KFxuICAgIGJib3gueDAsXG4gICAgYmJveC55MCxcbiAgICBiYm94LngxIC0gYmJveC54MCxcbiAgICBiYm94LnkxIC0gYmJveC55MFxuICApO1xufVxuXG5mdW5jdGlvbiBpc1BvaW50SW5zaWRlQkJveChiYm94LCB4LCB5KSB7XG4gIHJldHVybiB4ID49IGJib3gueCAmJlxuICAgIHggPD0gYmJveC54ICsgYmJveC53aWR0aCAmJlxuICAgIHkgPj0gYmJveC55ICYmXG4gICAgeSA8PSBiYm94LnkgKyBiYm94LmhlaWdodDtcbn1cblxuZnVuY3Rpb24gaXNCQm94SW50ZXJzZWN0KGJib3gxLCBiYm94Mikge1xuICBiYm94MSA9IHJlY3RCQm94KGJib3gxKTtcbiAgYmJveDIgPSByZWN0QkJveChiYm94Mik7XG4gIHJldHVybiBpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueCwgYmJveDEueSlcbiAgICB8fCBpc1BvaW50SW5zaWRlQkJveChiYm94MiwgYmJveDEueDIsIGJib3gxLnkpXG4gICAgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDIsIGJib3gxLngsIGJib3gxLnkyKVxuICAgIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gyLCBiYm94MS54MiwgYmJveDEueTIpXG4gICAgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDEsIGJib3gyLngsIGJib3gyLnkpXG4gICAgfHwgaXNQb2ludEluc2lkZUJCb3goYmJveDEsIGJib3gyLngyLCBiYm94Mi55KVxuICAgIHx8IGlzUG9pbnRJbnNpZGVCQm94KGJib3gxLCBiYm94Mi54LCBiYm94Mi55MilcbiAgICB8fCBpc1BvaW50SW5zaWRlQkJveChiYm94MSwgYmJveDIueDIsIGJib3gyLnkyKVxuICAgIHx8IChiYm94MS54IDwgYmJveDIueDIgJiYgYmJveDEueCA+IGJib3gyLnhcbiAgICAgICAgfHwgYmJveDIueCA8IGJib3gxLngyICYmIGJib3gyLnggPiBiYm94MS54KVxuICAgICYmIChiYm94MS55IDwgYmJveDIueTIgJiYgYmJveDEueSA+IGJib3gyLnlcbiAgICAgICAgfHwgYmJveDIueSA8IGJib3gxLnkyICYmIGJib3gyLnkgPiBiYm94MS55KTtcbn1cblxuZnVuY3Rpb24gYmFzZTModCwgcDEsIHAyLCBwMywgcDQpIHtcbiAgdmFyIHQxID0gLTMgKiBwMSArIDkgKiBwMiAtIDkgKiBwMyArIDMgKiBwNCxcbiAgICAgIHQyID0gdCAqIHQxICsgNiAqIHAxIC0gMTIgKiBwMiArIDYgKiBwMztcbiAgcmV0dXJuIHQgKiB0MiAtIDMgKiBwMSArIDMgKiBwMjtcbn1cblxuZnVuY3Rpb24gYmV6bGVuKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCwgeikge1xuXG4gIGlmICh6ID09IG51bGwpIHtcbiAgICB6ID0gMTtcbiAgfVxuXG4gIHogPSB6ID4gMSA/IDEgOiB6IDwgMCA/IDAgOiB6O1xuXG4gIHZhciB6MiA9IHogLyAyLFxuICAgICAgbiA9IDEyLFxuICAgICAgVHZhbHVlcyA9IFstLjEyNTIsLjEyNTIsLS4zNjc4LC4zNjc4LC0uNTg3MywuNTg3MywtLjc2OTksLjc2OTksLS45MDQxLC45MDQxLC0uOTgxNiwuOTgxNl0sXG4gICAgICBDdmFsdWVzID0gWzAuMjQ5MSwwLjI0OTEsMC4yMzM1LDAuMjMzNSwwLjIwMzIsMC4yMDMyLDAuMTYwMSwwLjE2MDEsMC4xMDY5LDAuMTA2OSwwLjA0NzIsMC4wNDcyXSxcbiAgICAgIHN1bSA9IDA7XG5cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICB2YXIgY3QgPSB6MiAqIFR2YWx1ZXNbaV0gKyB6MixcbiAgICAgICAgeGJhc2UgPSBiYXNlMyhjdCwgeDEsIHgyLCB4MywgeDQpLFxuICAgICAgICB5YmFzZSA9IGJhc2UzKGN0LCB5MSwgeTIsIHkzLCB5NCksXG4gICAgICAgIGNvbWIgPSB4YmFzZSAqIHhiYXNlICsgeWJhc2UgKiB5YmFzZTtcblxuICAgIHN1bSArPSBDdmFsdWVzW2ldICogbWF0aC5zcXJ0KGNvbWIpO1xuICB9XG5cbiAgcmV0dXJuIHoyICogc3VtO1xufVxuXG5cbmZ1bmN0aW9uIGludGVyc2VjdExpbmVzKHgxLCB5MSwgeDIsIHkyLCB4MywgeTMsIHg0LCB5NCkge1xuXG4gIGlmIChcbiAgICBtbWF4KHgxLCB4MikgPCBtbWluKHgzLCB4NCkgfHxcbiAgICAgIG1taW4oeDEsIHgyKSA+IG1tYXgoeDMsIHg0KSB8fFxuICAgICAgbW1heCh5MSwgeTIpIDwgbW1pbih5MywgeTQpIHx8XG4gICAgICBtbWluKHkxLCB5MikgPiBtbWF4KHkzLCB5NClcbiAgKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgdmFyIG54ID0gKHgxICogeTIgLSB5MSAqIHgyKSAqICh4MyAtIHg0KSAtICh4MSAtIHgyKSAqICh4MyAqIHk0IC0geTMgKiB4NCksXG4gICAgICBueSA9ICh4MSAqIHkyIC0geTEgKiB4MikgKiAoeTMgLSB5NCkgLSAoeTEgLSB5MikgKiAoeDMgKiB5NCAtIHkzICogeDQpLFxuICAgICAgZGVub21pbmF0b3IgPSAoeDEgLSB4MikgKiAoeTMgLSB5NCkgLSAoeTEgLSB5MikgKiAoeDMgLSB4NCk7XG5cbiAgaWYgKCFkZW5vbWluYXRvcikge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciBweCA9IGZpeEVycm9yKG54IC8gZGVub21pbmF0b3IpLFxuICAgICAgcHkgPSBmaXhFcnJvcihueSAvIGRlbm9taW5hdG9yKSxcbiAgICAgIHB4MiA9ICtweC50b0ZpeGVkKDIpLFxuICAgICAgcHkyID0gK3B5LnRvRml4ZWQoMik7XG5cbiAgaWYgKFxuICAgIHB4MiA8ICttbWluKHgxLCB4MikudG9GaXhlZCgyKSB8fFxuICAgICAgcHgyID4gK21tYXgoeDEsIHgyKS50b0ZpeGVkKDIpIHx8XG4gICAgICBweDIgPCArbW1pbih4MywgeDQpLnRvRml4ZWQoMikgfHxcbiAgICAgIHB4MiA+ICttbWF4KHgzLCB4NCkudG9GaXhlZCgyKSB8fFxuICAgICAgcHkyIDwgK21taW4oeTEsIHkyKS50b0ZpeGVkKDIpIHx8XG4gICAgICBweTIgPiArbW1heCh5MSwgeTIpLnRvRml4ZWQoMikgfHxcbiAgICAgIHB5MiA8ICttbWluKHkzLCB5NCkudG9GaXhlZCgyKSB8fFxuICAgICAgcHkyID4gK21tYXgoeTMsIHk0KS50b0ZpeGVkKDIpXG4gICkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHJldHVybiB7IHg6IHB4LCB5OiBweSB9O1xufVxuXG5mdW5jdGlvbiBmaXhFcnJvcihudW1iZXIpIHtcbiAgcmV0dXJuIE1hdGgucm91bmQobnVtYmVyICogMTAwMDAwMDAwMDAwKSAvIDEwMDAwMDAwMDAwMDtcbn1cblxuZnVuY3Rpb24gZmluZEJlemllckludGVyc2VjdGlvbnMoYmV6MSwgYmV6MiwganVzdENvdW50KSB7XG4gIHZhciBiYm94MSA9IGJlemllckJCb3goYmV6MSksXG4gICAgICBiYm94MiA9IGJlemllckJCb3goYmV6Mik7XG5cbiAgaWYgKCFpc0JCb3hJbnRlcnNlY3QoYmJveDEsIGJib3gyKSkge1xuICAgIHJldHVybiBqdXN0Q291bnQgPyAwIDogW107XG4gIH1cblxuICAvLyBBcyBhbiBvcHRpbWl6YXRpb24sIGxpbmVzIHdpbGwgaGF2ZSBvbmx5IDEgc2VnbWVudFxuXG4gIHZhciBsMSA9IGJlemxlbi5hcHBseSgwLCBiZXoxKSxcbiAgICAgIGwyID0gYmV6bGVuLmFwcGx5KDAsIGJlejIpLFxuICAgICAgbjEgPSBpc0xpbmUoYmV6MSkgPyAxIDogfn4obDEgLyA1KSB8fCAxLFxuICAgICAgbjIgPSBpc0xpbmUoYmV6MikgPyAxIDogfn4obDIgLyA1KSB8fCAxLFxuICAgICAgZG90czEgPSBbXSxcbiAgICAgIGRvdHMyID0gW10sXG4gICAgICB4eSA9IHt9LFxuICAgICAgcmVzID0ganVzdENvdW50ID8gMCA6IFtdO1xuXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjEgKyAxOyBpKyspIHtcbiAgICB2YXIgcCA9IGZpbmREb3RzQXRTZWdtZW50LmFwcGx5KDAsIGJlejEuY29uY2F0KGkgLyBuMSkpO1xuICAgIGRvdHMxLnB1c2goeyB4OiBwLngsIHk6IHAueSwgdDogaSAvIG4xIH0pO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IG4yICsgMTsgaSsrKSB7XG4gICAgcCA9IGZpbmREb3RzQXRTZWdtZW50LmFwcGx5KDAsIGJlejIuY29uY2F0KGkgLyBuMikpO1xuICAgIGRvdHMyLnB1c2goeyB4OiBwLngsIHk6IHAueSwgdDogaSAvIG4yIH0pO1xuICB9XG5cbiAgZm9yIChpID0gMDsgaSA8IG4xOyBpKyspIHtcblxuICAgIGZvciAodmFyIGogPSAwOyBqIDwgbjI7IGorKykge1xuICAgICAgdmFyIGRpID0gZG90czFbaV0sXG4gICAgICAgICAgZGkxID0gZG90czFbaSArIDFdLFxuICAgICAgICAgIGRqID0gZG90czJbal0sXG4gICAgICAgICAgZGoxID0gZG90czJbaiArIDFdLFxuICAgICAgICAgIGNpID0gYWJzKGRpMS54IC0gZGkueCkgPCAuMDEgPyAneScgOiAneCcsXG4gICAgICAgICAgY2ogPSBhYnMoZGoxLnggLSBkai54KSA8IC4wMSA/ICd5JyA6ICd4JyxcbiAgICAgICAgICBpcyA9IGludGVyc2VjdExpbmVzKGRpLngsIGRpLnksIGRpMS54LCBkaTEueSwgZGoueCwgZGoueSwgZGoxLngsIGRqMS55KSxcbiAgICAgICAgICBrZXk7XG5cbiAgICAgIGlmIChpcykge1xuICAgICAgICBrZXkgPSBpcy54LnRvRml4ZWQoOSkgKyAnIycgKyBpcy55LnRvRml4ZWQoOSk7XG5cbiAgICAgICAgaWYgKHh5W2tleV0pIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHh5W2tleV0gPSB0cnVlO1xuXG4gICAgICAgIHZhciB0MSA9IGRpLnQgKyBhYnMoKGlzW2NpXSAtIGRpW2NpXSkgLyAoZGkxW2NpXSAtIGRpW2NpXSkpICogKGRpMS50IC0gZGkudCksXG4gICAgICAgICAgICB0MiA9IGRqLnQgKyBhYnMoKGlzW2NqXSAtIGRqW2NqXSkgLyAoZGoxW2NqXSAtIGRqW2NqXSkpICogKGRqMS50IC0gZGoudCk7XG5cbiAgICAgICAgaWYgKHQxID49IDAgJiYgdDEgPD0gMSAmJiB0MiA+PSAwICYmIHQyIDw9IDEpIHtcblxuICAgICAgICAgIGlmIChqdXN0Q291bnQpIHtcbiAgICAgICAgICAgIHJlcysrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXMucHVzaCh7XG4gICAgICAgICAgICAgIHg6IGlzLngsXG4gICAgICAgICAgICAgIHk6IGlzLnksXG4gICAgICAgICAgICAgIHQxOiB0MSxcbiAgICAgICAgICAgICAgdDI6IHQyXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzO1xufVxuXG5cbi8qKlxuICogRmluZCBvciBjb3VudHMgdGhlIGludGVyc2VjdGlvbnMgYmV0d2VlbiB0d28gU1ZHIHBhdGhzLlxuICpcbiAqIFJldHVybnMgYSBudW1iZXIgaW4gY291bnRpbmcgbW9kZSBhbmQgYSBsaXN0IG9mIGludGVyc2VjdGlvbnMgb3RoZXJ3aXNlLlxuICpcbiAqIEEgc2luZ2xlIGludGVyc2VjdGlvbiBlbnRyeSBjb250YWlucyB0aGUgaW50ZXJzZWN0aW9uIGNvb3JkaW5hdGVzICh4LCB5KVxuICogYXMgd2VsbCBhcyBhZGRpdGlvbmFsIGluZm9ybWF0aW9uIHJlZ2FyZGluZyB0aGUgaW50ZXJzZWN0aW5nIHNlZ21lbnRzXG4gKiBvbiBlYWNoIHBhdGggKHNlZ21lbnQxLCBzZWdtZW50MikgYW5kIHRoZSByZWxhdGl2ZSBsb2NhdGlvbiBvZiB0aGVcbiAqIGludGVyc2VjdGlvbiBvbiB0aGVzZSBzZWdtZW50cyAodDEsIHQyKS5cbiAqXG4gKiBUaGUgcGF0aCBtYXkgYmUgYW4gU1ZHIHBhdGggc3RyaW5nIG9yIGEgbGlzdCBvZiBwYXRoIGNvbXBvbmVudHNcbiAqIHN1Y2ggYXMgYFsgWyAnTScsIDAsIDEwIF0sIFsgJ0wnLCAyMCwgMCBdIF1gLlxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIGludGVyc2VjdGlvbnMgPSBmaW5kUGF0aEludGVyc2VjdGlvbnMoXG4gKiAgICdNMCwwTDEwMCwxMDAnLFxuICogICBbIFsgJ00nLCAwLCAxMDAgXSwgWyAnTCcsIDEwMCwgMCBdIF1cbiAqICk7XG4gKlxuICogLy8gaW50ZXJzZWN0aW9ucyA9IFtcbiAqIC8vICAgeyB4OiA1MCwgeTogNTAsIHNlZ21lbnQxOiAxLCBzZWdtZW50MjogMSwgdDE6IDAuNSwgdDI6IDAuNSB9XG4gKiAvLyBdXG4gKlxuICogQHBhcmFtIHtTdHJpbmd8QXJyYXk8UGF0aERlZj59IHBhdGgxXG4gKiBAcGFyYW0ge1N0cmluZ3xBcnJheTxQYXRoRGVmPn0gcGF0aDJcbiAqIEBwYXJhbSB7Qm9vbGVhbn0gW2p1c3RDb3VudD1mYWxzZV1cbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxJbnRlcnNlY3Rpb24+fE51bWJlcn1cbiAqL1xuZnVuY3Rpb24gZmluZFBhdGhJbnRlcnNlY3Rpb25zKHBhdGgxLCBwYXRoMiwganVzdENvdW50KSB7XG4gIHBhdGgxID0gcGF0aFRvQ3VydmUocGF0aDEpO1xuICBwYXRoMiA9IHBhdGhUb0N1cnZlKHBhdGgyKTtcblxuICB2YXIgeDEsIHkxLCB4MiwgeTIsIHgxbSwgeTFtLCB4Mm0sIHkybSwgYmV6MSwgYmV6MixcbiAgICAgIHJlcyA9IGp1c3RDb3VudCA/IDAgOiBbXTtcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBwYXRoMS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgdmFyIHBpID0gcGF0aDFbaV07XG5cbiAgICBpZiAocGlbMF0gPT0gJ00nKSB7XG4gICAgICB4MSA9IHgxbSA9IHBpWzFdO1xuICAgICAgeTEgPSB5MW0gPSBwaVsyXTtcbiAgICB9IGVsc2Uge1xuXG4gICAgICBpZiAocGlbMF0gPT0gJ0MnKSB7XG4gICAgICAgIGJlejEgPSBbeDEsIHkxXS5jb25jYXQocGkuc2xpY2UoMSkpO1xuICAgICAgICB4MSA9IGJlejFbNl07XG4gICAgICAgIHkxID0gYmV6MVs3XTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJlejEgPSBbeDEsIHkxLCB4MSwgeTEsIHgxbSwgeTFtLCB4MW0sIHkxbV07XG4gICAgICAgIHgxID0geDFtO1xuICAgICAgICB5MSA9IHkxbTtcbiAgICAgIH1cblxuICAgICAgZm9yICh2YXIgaiA9IDAsIGpqID0gcGF0aDIubGVuZ3RoOyBqIDwgamo7IGorKykge1xuICAgICAgICB2YXIgcGogPSBwYXRoMltqXTtcblxuICAgICAgICBpZiAocGpbMF0gPT0gJ00nKSB7XG4gICAgICAgICAgeDIgPSB4Mm0gPSBwalsxXTtcbiAgICAgICAgICB5MiA9IHkybSA9IHBqWzJdO1xuICAgICAgICB9IGVsc2Uge1xuXG4gICAgICAgICAgaWYgKHBqWzBdID09ICdDJykge1xuICAgICAgICAgICAgYmV6MiA9IFt4MiwgeTJdLmNvbmNhdChwai5zbGljZSgxKSk7XG4gICAgICAgICAgICB4MiA9IGJlejJbNl07XG4gICAgICAgICAgICB5MiA9IGJlejJbN107XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGJlejIgPSBbeDIsIHkyLCB4MiwgeTIsIHgybSwgeTJtLCB4Mm0sIHkybV07XG4gICAgICAgICAgICB4MiA9IHgybTtcbiAgICAgICAgICAgIHkyID0geTJtO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBpbnRyID0gZmluZEJlemllckludGVyc2VjdGlvbnMoYmV6MSwgYmV6MiwganVzdENvdW50KTtcblxuICAgICAgICAgIGlmIChqdXN0Q291bnQpIHtcbiAgICAgICAgICAgIHJlcyArPSBpbnRyO1xuICAgICAgICAgIH0gZWxzZSB7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGsgPSAwLCBrayA9IGludHIubGVuZ3RoOyBrIDwga2s7IGsrKykge1xuICAgICAgICAgICAgICBpbnRyW2tdLnNlZ21lbnQxID0gaTtcbiAgICAgICAgICAgICAgaW50cltrXS5zZWdtZW50MiA9IGo7XG4gICAgICAgICAgICAgIGludHJba10uYmV6MSA9IGJlejE7XG4gICAgICAgICAgICAgIGludHJba10uYmV6MiA9IGJlejI7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJlcyA9IHJlcy5jb25jYXQoaW50cik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlcztcbn1cblxuXG5mdW5jdGlvbiBwYXRoVG9BYnNvbHV0ZShwYXRoQXJyYXkpIHtcbiAgdmFyIHB0aCA9IHBhdGhzKHBhdGhBcnJheSk7XG5cbiAgaWYgKHB0aC5hYnMpIHtcbiAgICByZXR1cm4gcGF0aENsb25lKHB0aC5hYnMpO1xuICB9XG5cbiAgaWYgKCFpc0FycmF5KHBhdGhBcnJheSkgfHwgIWlzQXJyYXkocGF0aEFycmF5ICYmIHBhdGhBcnJheVswXSkpIHsgLy8gcm91Z2ggYXNzdW1wdGlvblxuICAgIHBhdGhBcnJheSA9IHBhcnNlUGF0aFN0cmluZyhwYXRoQXJyYXkpO1xuICB9XG5cbiAgaWYgKCFwYXRoQXJyYXkgfHwgIXBhdGhBcnJheS5sZW5ndGgpIHtcbiAgICByZXR1cm4gW1snTScsIDAsIDBdXTtcbiAgfVxuXG4gIHZhciByZXMgPSBbXSxcbiAgICAgIHggPSAwLFxuICAgICAgeSA9IDAsXG4gICAgICBteCA9IDAsXG4gICAgICBteSA9IDAsXG4gICAgICBzdGFydCA9IDAsXG4gICAgICBwYTA7XG5cbiAgaWYgKHBhdGhBcnJheVswXVswXSA9PSAnTScpIHtcbiAgICB4ID0gK3BhdGhBcnJheVswXVsxXTtcbiAgICB5ID0gK3BhdGhBcnJheVswXVsyXTtcbiAgICBteCA9IHg7XG4gICAgbXkgPSB5O1xuICAgIHN0YXJ0Kys7XG4gICAgcmVzWzBdID0gWydNJywgeCwgeV07XG4gIH1cblxuICBmb3IgKHZhciByLCBwYSwgaSA9IHN0YXJ0LCBpaSA9IHBhdGhBcnJheS5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgcmVzLnB1c2gociA9IFtdKTtcbiAgICBwYSA9IHBhdGhBcnJheVtpXTtcbiAgICBwYTAgPSBwYVswXTtcblxuICAgIGlmIChwYTAgIT0gcGEwLnRvVXBwZXJDYXNlKCkpIHtcbiAgICAgIHJbMF0gPSBwYTAudG9VcHBlckNhc2UoKTtcblxuICAgICAgc3dpdGNoIChyWzBdKSB7XG4gICAgICBjYXNlICdBJzpcbiAgICAgICAgclsxXSA9IHBhWzFdO1xuICAgICAgICByWzJdID0gcGFbMl07XG4gICAgICAgIHJbM10gPSBwYVszXTtcbiAgICAgICAgcls0XSA9IHBhWzRdO1xuICAgICAgICByWzVdID0gcGFbNV07XG4gICAgICAgIHJbNl0gPSArcGFbNl0gKyB4O1xuICAgICAgICByWzddID0gK3BhWzddICsgeTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdWJzpcbiAgICAgICAgclsxXSA9ICtwYVsxXSArIHk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnSCc6XG4gICAgICAgIHJbMV0gPSArcGFbMV0gKyB4O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ00nOlxuICAgICAgICBteCA9ICtwYVsxXSArIHg7XG4gICAgICAgIG15ID0gK3BhWzJdICsgeTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGZvciAodmFyIGogPSAxLCBqaiA9IHBhLmxlbmd0aDsgaiA8IGpqOyBqKyspIHtcbiAgICAgICAgICByW2pdID0gK3BhW2pdICsgKChqICUgMikgPyB4IDogeSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZm9yICh2YXIgayA9IDAsIGtrID0gcGEubGVuZ3RoOyBrIDwga2s7IGsrKykge1xuICAgICAgICByW2tdID0gcGFba107XG4gICAgICB9XG4gICAgfVxuICAgIHBhMCA9IHBhMC50b1VwcGVyQ2FzZSgpO1xuXG4gICAgc3dpdGNoIChyWzBdKSB7XG4gICAgY2FzZSAnWic6XG4gICAgICB4ID0gK214O1xuICAgICAgeSA9ICtteTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ0gnOlxuICAgICAgeCA9IHJbMV07XG4gICAgICBicmVhaztcbiAgICBjYXNlICdWJzpcbiAgICAgIHkgPSByWzFdO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnTSc6XG4gICAgICBteCA9IHJbci5sZW5ndGggLSAyXTtcbiAgICAgIG15ID0gcltyLmxlbmd0aCAtIDFdO1xuICAgIGRlZmF1bHQ6XG4gICAgICB4ID0gcltyLmxlbmd0aCAtIDJdO1xuICAgICAgeSA9IHJbci5sZW5ndGggLSAxXTtcbiAgICB9XG4gIH1cblxuICByZXMudG9TdHJpbmcgPSBwYXRoVG9TdHJpbmc7XG4gIHB0aC5hYnMgPSBwYXRoQ2xvbmUocmVzKTtcblxuICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiBpc0xpbmUoYmV6KSB7XG4gIHJldHVybiAoXG4gICAgYmV6WzBdID09PSBiZXpbMl0gJiZcbiAgICBiZXpbMV0gPT09IGJlelszXSAmJlxuICAgIGJlels0XSA9PT0gYmV6WzZdICYmXG4gICAgYmV6WzVdID09PSBiZXpbN11cbiAgKTtcbn1cblxuZnVuY3Rpb24gbGluZVRvQ3VydmUoeDEsIHkxLCB4MiwgeTIpIHtcbiAgcmV0dXJuIFtcbiAgICB4MSwgeTEsIHgyLFxuICAgIHkyLCB4MiwgeTJcbiAgXTtcbn1cblxuZnVuY3Rpb24gcXViaWNUb0N1cnZlKHgxLCB5MSwgYXgsIGF5LCB4MiwgeTIpIHtcbiAgdmFyIF8xMyA9IDEgLyAzLFxuICAgICAgXzIzID0gMiAvIDM7XG5cbiAgcmV0dXJuIFtcbiAgICBfMTMgKiB4MSArIF8yMyAqIGF4LFxuICAgIF8xMyAqIHkxICsgXzIzICogYXksXG4gICAgXzEzICogeDIgKyBfMjMgKiBheCxcbiAgICBfMTMgKiB5MiArIF8yMyAqIGF5LFxuICAgIHgyLFxuICAgIHkyXG4gIF07XG59XG5cbmZ1bmN0aW9uIGFyY1RvQ3VydmUoeDEsIHkxLCByeCwgcnksIGFuZ2xlLCBsYXJnZV9hcmNfZmxhZywgc3dlZXBfZmxhZywgeDIsIHkyLCByZWN1cnNpdmUpIHtcblxuICAvLyBmb3IgbW9yZSBpbmZvcm1hdGlvbiBvZiB3aGVyZSB0aGlzIG1hdGggY2FtZSBmcm9tIHZpc2l0OlxuICAvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9TVkcxMS9pbXBsbm90ZS5odG1sI0FyY0ltcGxlbWVudGF0aW9uTm90ZXNcbiAgdmFyIF8xMjAgPSBQSSAqIDEyMCAvIDE4MCxcbiAgICAgIHJhZCA9IFBJIC8gMTgwICogKCthbmdsZSB8fCAwKSxcbiAgICAgIHJlcyA9IFtdLFxuICAgICAgeHksXG4gICAgICByb3RhdGUgPSBjYWNoZXIoZnVuY3Rpb24oeCwgeSwgcmFkKSB7XG4gICAgICAgIHZhciBYID0geCAqIG1hdGguY29zKHJhZCkgLSB5ICogbWF0aC5zaW4ocmFkKSxcbiAgICAgICAgICAgIFkgPSB4ICogbWF0aC5zaW4ocmFkKSArIHkgKiBtYXRoLmNvcyhyYWQpO1xuXG4gICAgICAgIHJldHVybiB7IHg6IFgsIHk6IFkgfTtcbiAgICAgIH0pO1xuXG4gIGlmICghcmVjdXJzaXZlKSB7XG4gICAgeHkgPSByb3RhdGUoeDEsIHkxLCAtcmFkKTtcbiAgICB4MSA9IHh5Lng7XG4gICAgeTEgPSB4eS55O1xuICAgIHh5ID0gcm90YXRlKHgyLCB5MiwgLXJhZCk7XG4gICAgeDIgPSB4eS54O1xuICAgIHkyID0geHkueTtcblxuICAgIHZhciB4ID0gKHgxIC0geDIpIC8gMixcbiAgICAgICAgeSA9ICh5MSAtIHkyKSAvIDI7XG5cbiAgICB2YXIgaCA9ICh4ICogeCkgLyAocnggKiByeCkgKyAoeSAqIHkpIC8gKHJ5ICogcnkpO1xuXG4gICAgaWYgKGggPiAxKSB7XG4gICAgICBoID0gbWF0aC5zcXJ0KGgpO1xuICAgICAgcnggPSBoICogcng7XG4gICAgICByeSA9IGggKiByeTtcbiAgICB9XG5cbiAgICB2YXIgcngyID0gcnggKiByeCxcbiAgICAgICAgcnkyID0gcnkgKiByeSxcbiAgICAgICAgayA9IChsYXJnZV9hcmNfZmxhZyA9PSBzd2VlcF9mbGFnID8gLTEgOiAxKSAqXG4gICAgICAgICAgICBtYXRoLnNxcnQoYWJzKChyeDIgKiByeTIgLSByeDIgKiB5ICogeSAtIHJ5MiAqIHggKiB4KSAvIChyeDIgKiB5ICogeSArIHJ5MiAqIHggKiB4KSkpLFxuICAgICAgICBjeCA9IGsgKiByeCAqIHkgLyByeSArICh4MSArIHgyKSAvIDIsXG4gICAgICAgIGN5ID0gayAqIC1yeSAqIHggLyByeCArICh5MSArIHkyKSAvIDIsXG4gICAgICAgIGYxID0gbWF0aC5hc2luKCgoeTEgLSBjeSkgLyByeSkudG9GaXhlZCg5KSksXG4gICAgICAgIGYyID0gbWF0aC5hc2luKCgoeTIgLSBjeSkgLyByeSkudG9GaXhlZCg5KSk7XG5cbiAgICBmMSA9IHgxIDwgY3ggPyBQSSAtIGYxIDogZjE7XG4gICAgZjIgPSB4MiA8IGN4ID8gUEkgLSBmMiA6IGYyO1xuICAgIGYxIDwgMCAmJiAoZjEgPSBQSSAqIDIgKyBmMSk7XG4gICAgZjIgPCAwICYmIChmMiA9IFBJICogMiArIGYyKTtcblxuICAgIGlmIChzd2VlcF9mbGFnICYmIGYxID4gZjIpIHtcbiAgICAgIGYxID0gZjEgLSBQSSAqIDI7XG4gICAgfVxuICAgIGlmICghc3dlZXBfZmxhZyAmJiBmMiA+IGYxKSB7XG4gICAgICBmMiA9IGYyIC0gUEkgKiAyO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmMSA9IHJlY3Vyc2l2ZVswXTtcbiAgICBmMiA9IHJlY3Vyc2l2ZVsxXTtcbiAgICBjeCA9IHJlY3Vyc2l2ZVsyXTtcbiAgICBjeSA9IHJlY3Vyc2l2ZVszXTtcbiAgfVxuXG4gIHZhciBkZiA9IGYyIC0gZjE7XG5cbiAgaWYgKGFicyhkZikgPiBfMTIwKSB7XG4gICAgdmFyIGYyb2xkID0gZjIsXG4gICAgICAgIHgyb2xkID0geDIsXG4gICAgICAgIHkyb2xkID0geTI7XG5cbiAgICBmMiA9IGYxICsgXzEyMCAqIChzd2VlcF9mbGFnICYmIGYyID4gZjEgPyAxIDogLTEpO1xuICAgIHgyID0gY3ggKyByeCAqIG1hdGguY29zKGYyKTtcbiAgICB5MiA9IGN5ICsgcnkgKiBtYXRoLnNpbihmMik7XG4gICAgcmVzID0gYXJjVG9DdXJ2ZSh4MiwgeTIsIHJ4LCByeSwgYW5nbGUsIDAsIHN3ZWVwX2ZsYWcsIHgyb2xkLCB5Mm9sZCwgW2YyLCBmMm9sZCwgY3gsIGN5XSk7XG4gIH1cblxuICBkZiA9IGYyIC0gZjE7XG5cbiAgdmFyIGMxID0gbWF0aC5jb3MoZjEpLFxuICAgICAgczEgPSBtYXRoLnNpbihmMSksXG4gICAgICBjMiA9IG1hdGguY29zKGYyKSxcbiAgICAgIHMyID0gbWF0aC5zaW4oZjIpLFxuICAgICAgdCA9IG1hdGgudGFuKGRmIC8gNCksXG4gICAgICBoeCA9IDQgLyAzICogcnggKiB0LFxuICAgICAgaHkgPSA0IC8gMyAqIHJ5ICogdCxcbiAgICAgIG0xID0gW3gxLCB5MV0sXG4gICAgICBtMiA9IFt4MSArIGh4ICogczEsIHkxIC0gaHkgKiBjMV0sXG4gICAgICBtMyA9IFt4MiArIGh4ICogczIsIHkyIC0gaHkgKiBjMl0sXG4gICAgICBtNCA9IFt4MiwgeTJdO1xuXG4gIG0yWzBdID0gMiAqIG0xWzBdIC0gbTJbMF07XG4gIG0yWzFdID0gMiAqIG0xWzFdIC0gbTJbMV07XG5cbiAgaWYgKHJlY3Vyc2l2ZSkge1xuICAgIHJldHVybiBbbTIsIG0zLCBtNF0uY29uY2F0KHJlcyk7XG4gIH0gZWxzZSB7XG4gICAgcmVzID0gW20yLCBtMywgbTRdLmNvbmNhdChyZXMpLmpvaW4oKS5zcGxpdCgnLCcpO1xuICAgIHZhciBuZXdyZXMgPSBbXTtcblxuICAgIGZvciAodmFyIGkgPSAwLCBpaSA9IHJlcy5sZW5ndGg7IGkgPCBpaTsgaSsrKSB7XG4gICAgICBuZXdyZXNbaV0gPSBpICUgMiA/IHJvdGF0ZShyZXNbaSAtIDFdLCByZXNbaV0sIHJhZCkueSA6IHJvdGF0ZShyZXNbaV0sIHJlc1tpICsgMV0sIHJhZCkueDtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3cmVzO1xuICB9XG59XG5cbi8vIFJldHVybnMgYm91bmRpbmcgYm94IG9mIGN1YmljIGJlemllciBjdXJ2ZS5cbi8vIFNvdXJjZTogaHR0cDovL2Jsb2cuaGFja2Vycy1jYWZlLm5ldC8yMDA5LzA2L2hvdy10by1jYWxjdWxhdGUtYmV6aWVyLWN1cnZlcy1ib3VuZGluZy5odG1sXG4vLyBPcmlnaW5hbCB2ZXJzaW9uOiBOSVNISU8gSGlyb2thenVcbi8vIE1vZGlmaWNhdGlvbnM6IGh0dHBzOi8vZ2l0aHViLmNvbS90aW1vMjIzNDVcbmZ1bmN0aW9uIGN1cnZlQkJveCh4MCwgeTAsIHgxLCB5MSwgeDIsIHkyLCB4MywgeTMpIHtcbiAgdmFyIHR2YWx1ZXMgPSBbXSxcbiAgICAgIGJvdW5kcyA9IFtbXSwgW11dLFxuICAgICAgYSwgYiwgYywgdCwgdDEsIHQyLCBiMmFjLCBzcXJ0YjJhYztcblxuICBmb3IgKHZhciBpID0gMDsgaSA8IDI7ICsraSkge1xuXG4gICAgaWYgKGkgPT0gMCkge1xuICAgICAgYiA9IDYgKiB4MCAtIDEyICogeDEgKyA2ICogeDI7XG4gICAgICBhID0gLTMgKiB4MCArIDkgKiB4MSAtIDkgKiB4MiArIDMgKiB4MztcbiAgICAgIGMgPSAzICogeDEgLSAzICogeDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGIgPSA2ICogeTAgLSAxMiAqIHkxICsgNiAqIHkyO1xuICAgICAgYSA9IC0zICogeTAgKyA5ICogeTEgLSA5ICogeTIgKyAzICogeTM7XG4gICAgICBjID0gMyAqIHkxIC0gMyAqIHkwO1xuICAgIH1cblxuICAgIGlmIChhYnMoYSkgPCAxZS0xMikge1xuXG4gICAgICBpZiAoYWJzKGIpIDwgMWUtMTIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHQgPSAtYyAvIGI7XG5cbiAgICAgIGlmICgwIDwgdCAmJiB0IDwgMSkge1xuICAgICAgICB0dmFsdWVzLnB1c2godCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGIyYWMgPSBiICogYiAtIDQgKiBjICogYTtcbiAgICBzcXJ0YjJhYyA9IG1hdGguc3FydChiMmFjKTtcblxuICAgIGlmIChiMmFjIDwgMCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdDEgPSAoLWIgKyBzcXJ0YjJhYykgLyAoMiAqIGEpO1xuXG4gICAgaWYgKDAgPCB0MSAmJiB0MSA8IDEpIHtcbiAgICAgIHR2YWx1ZXMucHVzaCh0MSk7XG4gICAgfVxuXG4gICAgdDIgPSAoLWIgLSBzcXJ0YjJhYykgLyAoMiAqIGEpO1xuXG4gICAgaWYgKDAgPCB0MiAmJiB0MiA8IDEpIHtcbiAgICAgIHR2YWx1ZXMucHVzaCh0Mik7XG4gICAgfVxuICB9XG5cbiAgdmFyIGogPSB0dmFsdWVzLmxlbmd0aCxcbiAgICAgIGpsZW4gPSBqLFxuICAgICAgbXQ7XG5cbiAgd2hpbGUgKGotLSkge1xuICAgIHQgPSB0dmFsdWVzW2pdO1xuICAgIG10ID0gMSAtIHQ7XG4gICAgYm91bmRzWzBdW2pdID0gKG10ICogbXQgKiBtdCAqIHgwKSArICgzICogbXQgKiBtdCAqIHQgKiB4MSkgKyAoMyAqIG10ICogdCAqIHQgKiB4MikgKyAodCAqIHQgKiB0ICogeDMpO1xuICAgIGJvdW5kc1sxXVtqXSA9IChtdCAqIG10ICogbXQgKiB5MCkgKyAoMyAqIG10ICogbXQgKiB0ICogeTEpICsgKDMgKiBtdCAqIHQgKiB0ICogeTIpICsgKHQgKiB0ICogdCAqIHkzKTtcbiAgfVxuXG4gIGJvdW5kc1swXVtqbGVuXSA9IHgwO1xuICBib3VuZHNbMV1bamxlbl0gPSB5MDtcbiAgYm91bmRzWzBdW2psZW4gKyAxXSA9IHgzO1xuICBib3VuZHNbMV1bamxlbiArIDFdID0geTM7XG4gIGJvdW5kc1swXS5sZW5ndGggPSBib3VuZHNbMV0ubGVuZ3RoID0gamxlbiArIDI7XG5cbiAgcmV0dXJuIHtcbiAgICB4MDogbW1pbi5hcHBseSgwLCBib3VuZHNbMF0pLFxuICAgIHkwOiBtbWluLmFwcGx5KDAsIGJvdW5kc1sxXSksXG4gICAgeDE6IG1tYXguYXBwbHkoMCwgYm91bmRzWzBdKSxcbiAgICB5MTogbW1heC5hcHBseSgwLCBib3VuZHNbMV0pXG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhdGhUb0N1cnZlKHBhdGgpIHtcblxuICB2YXIgcHRoID0gcGF0aHMocGF0aCk7XG5cbiAgLy8gcmV0dXJuIGNhY2hlZCBjdXJ2ZSwgaWYgZXhpc3RpbmdcbiAgaWYgKHB0aC5jdXJ2ZSkge1xuICAgIHJldHVybiBwYXRoQ2xvbmUocHRoLmN1cnZlKTtcbiAgfVxuXG4gIHZhciBjdXJ2ZWRQYXRoID0gcGF0aFRvQWJzb2x1dGUocGF0aCksXG4gICAgICBhdHRycyA9IHsgeDogMCwgeTogMCwgYng6IDAsIGJ5OiAwLCBYOiAwLCBZOiAwLCBxeDogbnVsbCwgcXk6IG51bGwgfSxcbiAgICAgIHByb2Nlc3NQYXRoID0gZnVuY3Rpb24ocGF0aCwgZCwgcGF0aENvbW1hbmQpIHtcbiAgICAgICAgdmFyIG54LCBueTtcblxuICAgICAgICBpZiAoIXBhdGgpIHtcbiAgICAgICAgICByZXR1cm4gWydDJywgZC54LCBkLnksIGQueCwgZC55LCBkLngsIGQueV07XG4gICAgICAgIH1cblxuICAgICAgICAhKHBhdGhbMF0gaW4geyBUOiAxLCBROiAxIH0pICYmIChkLnF4ID0gZC5xeSA9IG51bGwpO1xuXG4gICAgICAgIHN3aXRjaCAocGF0aFswXSkge1xuICAgICAgICBjYXNlICdNJzpcbiAgICAgICAgICBkLlggPSBwYXRoWzFdO1xuICAgICAgICAgIGQuWSA9IHBhdGhbMl07XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0EnOlxuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQoYXJjVG9DdXJ2ZS5hcHBseSgwLCBbZC54LCBkLnldLmNvbmNhdChwYXRoLnNsaWNlKDEpKSkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdTJzpcbiAgICAgICAgICBpZiAocGF0aENvbW1hbmQgPT0gJ0MnIHx8IHBhdGhDb21tYW5kID09ICdTJykge1xuICAgICAgICAgICAgLy8gSW4gJ1MnIGNhc2Ugd2UgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCwgaWYgdGhlIHByZXZpb3VzIGNvbW1hbmQgaXMgQy9TLlxuICAgICAgICAgICAgbnggPSBkLnggKiAyIC0gZC5ieDtcbiAgICAgICAgICAgIC8vIEFuZCByZWZsZWN0IHRoZSBwcmV2aW91c1xuICAgICAgICAgICAgbnkgPSBkLnkgKiAyIC0gZC5ieTtcbiAgICAgICAgICAgIC8vIGNvbW1hbmQncyBjb250cm9sIHBvaW50IHJlbGF0aXZlIHRvIHRoZSBjdXJyZW50IHBvaW50LlxuICAgICAgICAgIH1cbiAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIC8vIG9yIHNvbWUgZWxzZSBvciBub3RoaW5nXG4gICAgICAgICAgICBueCA9IGQueDtcbiAgICAgICAgICAgIG55ID0gZC55O1xuICAgICAgICAgIH1cbiAgICAgICAgICBwYXRoID0gWydDJywgbngsIG55XS5jb25jYXQocGF0aC5zbGljZSgxKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1QnOlxuICAgICAgICAgIGlmIChwYXRoQ29tbWFuZCA9PSAnUScgfHwgcGF0aENvbW1hbmQgPT0gJ1QnKSB7XG4gICAgICAgICAgICAvLyBJbiAnVCcgY2FzZSB3ZSBoYXZlIHRvIHRha2UgaW50byBhY2NvdW50LCBpZiB0aGUgcHJldmlvdXMgY29tbWFuZCBpcyBRL1QuXG4gICAgICAgICAgICBkLnF4ID0gZC54ICogMiAtIGQucXg7XG4gICAgICAgICAgICAvLyBBbmQgbWFrZSBhIHJlZmxlY3Rpb24gc2ltaWxhclxuICAgICAgICAgICAgZC5xeSA9IGQueSAqIDIgLSBkLnF5O1xuICAgICAgICAgICAgLy8gdG8gY2FzZSAnUycuXG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gb3Igc29tZXRoaW5nIGVsc2Ugb3Igbm90aGluZ1xuICAgICAgICAgICAgZC5xeCA9IGQueDtcbiAgICAgICAgICAgIGQucXkgPSBkLnk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQocXViaWNUb0N1cnZlKGQueCwgZC55LCBkLnF4LCBkLnF5LCBwYXRoWzFdLCBwYXRoWzJdKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1EnOlxuICAgICAgICAgIGQucXggPSBwYXRoWzFdO1xuICAgICAgICAgIGQucXkgPSBwYXRoWzJdO1xuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQocXViaWNUb0N1cnZlKGQueCwgZC55LCBwYXRoWzFdLCBwYXRoWzJdLCBwYXRoWzNdLCBwYXRoWzRdKSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0wnOlxuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQobGluZVRvQ3VydmUoZC54LCBkLnksIHBhdGhbMV0sIHBhdGhbMl0pKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnSCc6XG4gICAgICAgICAgcGF0aCA9IFsnQyddLmNvbmNhdChsaW5lVG9DdXJ2ZShkLngsIGQueSwgcGF0aFsxXSwgZC55KSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1YnOlxuICAgICAgICAgIHBhdGggPSBbJ0MnXS5jb25jYXQobGluZVRvQ3VydmUoZC54LCBkLnksIGQueCwgcGF0aFsxXSkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlICdaJzpcbiAgICAgICAgICBwYXRoID0gWydDJ10uY29uY2F0KGxpbmVUb0N1cnZlKGQueCwgZC55LCBkLlgsIGQuWSkpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHBhdGg7XG4gICAgICB9LFxuXG4gICAgICBmaXhBcmMgPSBmdW5jdGlvbihwcCwgaSkge1xuXG4gICAgICAgIGlmIChwcFtpXS5sZW5ndGggPiA3KSB7XG4gICAgICAgICAgcHBbaV0uc2hpZnQoKTtcbiAgICAgICAgICB2YXIgcGkgPSBwcFtpXTtcblxuICAgICAgICAgIHdoaWxlIChwaS5sZW5ndGgpIHtcbiAgICAgICAgICAgIHBhdGhDb21tYW5kc1tpXSA9ICdBJzsgLy8gaWYgY3JlYXRlZCBtdWx0aXBsZSBDOnMsIHRoZWlyIG9yaWdpbmFsIHNlZyBpcyBzYXZlZFxuICAgICAgICAgICAgcHAuc3BsaWNlKGkrKywgMCwgWydDJ10uY29uY2F0KHBpLnNwbGljZSgwLCA2KSkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHBwLnNwbGljZShpLCAxKTtcbiAgICAgICAgICBpaSA9IGN1cnZlZFBhdGgubGVuZ3RoO1xuICAgICAgICB9XG4gICAgICB9LFxuXG4gICAgICBwYXRoQ29tbWFuZHMgPSBbXSwgLy8gcGF0aCBjb21tYW5kcyBvZiBvcmlnaW5hbCBwYXRoIHBcbiAgICAgIHBmaXJzdCA9ICcnLCAvLyB0ZW1wb3JhcnkgaG9sZGVyIGZvciBvcmlnaW5hbCBwYXRoIGNvbW1hbmRcbiAgICAgIHBhdGhDb21tYW5kID0gJyc7IC8vIGhvbGRlciBmb3IgcHJldmlvdXMgcGF0aCBjb21tYW5kIG9mIG9yaWdpbmFsIHBhdGhcblxuICBmb3IgKHZhciBpID0gMCwgaWkgPSBjdXJ2ZWRQYXRoLmxlbmd0aDsgaSA8IGlpOyBpKyspIHtcbiAgICBjdXJ2ZWRQYXRoW2ldICYmIChwZmlyc3QgPSBjdXJ2ZWRQYXRoW2ldWzBdKTsgLy8gc2F2ZSBjdXJyZW50IHBhdGggY29tbWFuZFxuXG4gICAgaWYgKHBmaXJzdCAhPSAnQycpIC8vIEMgaXMgbm90IHNhdmVkIHlldCwgYmVjYXVzZSBpdCBtYXkgYmUgcmVzdWx0IG9mIGNvbnZlcnNpb25cbiAgICB7XG4gICAgICBwYXRoQ29tbWFuZHNbaV0gPSBwZmlyc3Q7IC8vIFNhdmUgY3VycmVudCBwYXRoIGNvbW1hbmRcbiAgICAgIGkgJiYgKHBhdGhDb21tYW5kID0gcGF0aENvbW1hbmRzW2kgLSAxXSk7IC8vIEdldCBwcmV2aW91cyBwYXRoIGNvbW1hbmQgcGF0aENvbW1hbmRcbiAgICB9XG4gICAgY3VydmVkUGF0aFtpXSA9IHByb2Nlc3NQYXRoKGN1cnZlZFBhdGhbaV0sIGF0dHJzLCBwYXRoQ29tbWFuZCk7IC8vIFByZXZpb3VzIHBhdGggY29tbWFuZCBpcyBpbnB1dHRlZCB0byBwcm9jZXNzUGF0aFxuXG4gICAgaWYgKHBhdGhDb21tYW5kc1tpXSAhPSAnQScgJiYgcGZpcnN0ID09ICdDJykgcGF0aENvbW1hbmRzW2ldID0gJ0MnOyAvLyBBIGlzIHRoZSBvbmx5IGNvbW1hbmRcbiAgICAvLyB3aGljaCBtYXkgcHJvZHVjZSBtdWx0aXBsZSBDOnNcbiAgICAvLyBzbyB3ZSBoYXZlIHRvIG1ha2Ugc3VyZSB0aGF0IEMgaXMgYWxzbyBDIGluIG9yaWdpbmFsIHBhdGhcblxuICAgIGZpeEFyYyhjdXJ2ZWRQYXRoLCBpKTsgLy8gZml4QXJjIGFkZHMgYWxzbyB0aGUgcmlnaHQgYW1vdW50IG9mIEE6cyB0byBwYXRoQ29tbWFuZHNcblxuICAgIHZhciBzZWcgPSBjdXJ2ZWRQYXRoW2ldLFxuICAgICAgICBzZWdsZW4gPSBzZWcubGVuZ3RoO1xuXG4gICAgYXR0cnMueCA9IHNlZ1tzZWdsZW4gLSAyXTtcbiAgICBhdHRycy55ID0gc2VnW3NlZ2xlbiAtIDFdO1xuICAgIGF0dHJzLmJ4ID0gdG9GbG9hdChzZWdbc2VnbGVuIC0gNF0pIHx8IGF0dHJzLng7XG4gICAgYXR0cnMuYnkgPSB0b0Zsb2F0KHNlZ1tzZWdsZW4gLSAzXSkgfHwgYXR0cnMueTtcbiAgfVxuXG4gIC8vIGNhY2hlIGN1cnZlXG4gIHB0aC5jdXJ2ZSA9IHBhdGhDbG9uZShjdXJ2ZWRQYXRoKTtcblxuICByZXR1cm4gY3VydmVkUGF0aDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmaW5kUGF0aEludGVyc2VjdGlvbnM7XG4iLCJ2YXIgZnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcblxudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcblxudmFyIEVOVElUWV9QQVRURVJOID0gLyYjKFxcZCspO3wmI3goWzAtOWEtZl0rKTt8JihcXHcrKTsvaWc7XG5cbnZhciBFTlRJVFlfTUFQUElORyA9IHtcbiAgJ2FtcCc6ICcmJyxcbiAgJ2Fwb3MnOiAnXFwnJyxcbiAgJ2d0JzogJz4nLFxuICAnbHQnOiAnPCcsXG4gICdxdW90JzogJ1wiJ1xufTtcblxuLy8gbWFwIFVQUEVSQ0FTRSB2YXJpYW50cyBvZiBzdXBwb3J0ZWQgc3BlY2lhbCBjaGFyc1xuT2JqZWN0LmtleXMoRU5USVRZX01BUFBJTkcpLmZvckVhY2goZnVuY3Rpb24oaykge1xuICBFTlRJVFlfTUFQUElOR1trLnRvVXBwZXJDYXNlKCldID0gRU5USVRZX01BUFBJTkdba107XG59KTtcblxuXG5mdW5jdGlvbiByZXBsYWNlRW50aXRpZXMoXywgZCwgeCwgeikge1xuXG4gIC8vIHJlc2VydmVkIG5hbWVzLCBpLmUuICZuYnNwO1xuICBpZiAoeikge1xuICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKEVOVElUWV9NQVBQSU5HLCB6KSkge1xuICAgICAgcmV0dXJuIEVOVElUWV9NQVBQSU5HW3pdO1xuICAgIH0gZWxzZSB7XG5cbiAgICAgIC8vIGZhbGwgYmFjayB0byBvcmlnaW5hbCB2YWx1ZVxuICAgICAgcmV0dXJuICcmJyArIHogKyAnOyc7XG4gICAgfVxuICB9XG5cbiAgLy8gZGVjaW1hbCBlbmNvZGVkIGNoYXJcbiAgaWYgKGQpIHtcbiAgICByZXR1cm4gZnJvbUNoYXJDb2RlKGQpO1xuICB9XG5cbiAgLy8gaGV4IGVuY29kZWQgY2hhclxuICByZXR1cm4gZnJvbUNoYXJDb2RlKHBhcnNlSW50KHgsIDE2KSk7XG59XG5cblxuLyoqXG4gKiBBIGJhc2ljIGVudGl0eSBkZWNvZGVyIHRoYXQgY2FuIGRlY29kZSBhIG1pbmltYWxcbiAqIHN1Yi1zZXQgb2YgcmVzZXJ2ZWQgbmFtZXMgKCZhbXA7KSBhcyB3ZWxsIGFzXG4gKiBoZXggKCYjeGFhZjspIGFuZCBkZWNpbWFsICgmIzEyMzE7KSBlbmNvZGVkIGNoYXJhY3RlcnMuXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IHN0clxuICpcbiAqIEByZXR1cm4ge3N0cmluZ30gZGVjb2RlZCBzdHJpbmdcbiAqL1xuZnVuY3Rpb24gZGVjb2RlRW50aXRpZXMocykge1xuICBpZiAocy5sZW5ndGggPiAzICYmIHMuaW5kZXhPZignJicpICE9PSAtMSkge1xuICAgIHJldHVybiBzLnJlcGxhY2UoRU5USVRZX1BBVFRFUk4sIHJlcGxhY2VFbnRpdGllcyk7XG4gIH1cblxuICByZXR1cm4gcztcbn1cblxudmFyIFhTSV9VUkkgPSAnaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2UnO1xudmFyIFhTSV9QUkVGSVggPSAneHNpJztcbnZhciBYU0lfVFlQRSA9ICd4c2k6dHlwZSc7XG5cbnZhciBOT05fV0hJVEVTUEFDRV9PVVRTSURFX1JPT1RfTk9ERSA9ICdub24td2hpdGVzcGFjZSBvdXRzaWRlIG9mIHJvb3Qgbm9kZSc7XG5cbmZ1bmN0aW9uIGVycm9yKG1zZykge1xuICByZXR1cm4gbmV3IEVycm9yKG1zZyk7XG59XG5cbmZ1bmN0aW9uIG1pc3NpbmdOYW1lc3BhY2VGb3JQcmVmaXgocHJlZml4KSB7XG4gIHJldHVybiAnbWlzc2luZyBuYW1lc3BhY2UgZm9yIHByZWZpeCA8JyArIHByZWZpeCArICc+Jztcbn1cblxuZnVuY3Rpb24gZ2V0dGVyKGdldEZuKSB7XG4gIHJldHVybiB7XG4gICAgJ2dldCc6IGdldEZuLFxuICAgICdlbnVtZXJhYmxlJzogdHJ1ZVxuICB9O1xufVxuXG5mdW5jdGlvbiBjbG9uZU5zTWF0cml4KG5zTWF0cml4KSB7XG4gIHZhciBjbG9uZSA9IHt9LCBrZXk7XG4gIGZvciAoa2V5IGluIG5zTWF0cml4KSB7XG4gICAgY2xvbmVba2V5XSA9IG5zTWF0cml4W2tleV07XG4gIH1cbiAgcmV0dXJuIGNsb25lO1xufVxuXG5mdW5jdGlvbiB1cmlQcmVmaXgocHJlZml4KSB7XG4gIHJldHVybiBwcmVmaXggKyAnJHVyaSc7XG59XG5cbmZ1bmN0aW9uIGJ1aWxkTnNNYXRyaXgobnNVcmlUb1ByZWZpeCkge1xuICB2YXIgbnNNYXRyaXggPSB7fSxcbiAgICAgIHVyaSxcbiAgICAgIHByZWZpeDtcblxuICBmb3IgKHVyaSBpbiBuc1VyaVRvUHJlZml4KSB7XG4gICAgcHJlZml4ID0gbnNVcmlUb1ByZWZpeFt1cmldO1xuICAgIG5zTWF0cml4W3ByZWZpeF0gPSBwcmVmaXg7XG4gICAgbnNNYXRyaXhbdXJpUHJlZml4KHByZWZpeCldID0gdXJpO1xuICB9XG5cbiAgcmV0dXJuIG5zTWF0cml4O1xufVxuXG5mdW5jdGlvbiBub29wR2V0Q29udGV4dCgpIHtcbiAgcmV0dXJuIHsgJ2xpbmUnOiAwLCAnY29sdW1uJzogMCB9O1xufVxuXG5mdW5jdGlvbiB0aHJvd0Z1bmMoZXJyKSB7XG4gIHRocm93IGVycjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHBhcnNlciB3aXRoIHRoZSBnaXZlbiBvcHRpb25zLlxuICpcbiAqIEBjb25zdHJ1Y3RvclxuICpcbiAqIEBwYXJhbSAgeyFPYmplY3Q8c3RyaW5nLCA/Pj19IG9wdGlvbnNcbiAqL1xuZnVuY3Rpb24gUGFyc2VyKG9wdGlvbnMpIHtcblxuICBpZiAoIXRoaXMpIHtcbiAgICByZXR1cm4gbmV3IFBhcnNlcihvcHRpb25zKTtcbiAgfVxuXG4gIHZhciBwcm94eSA9IG9wdGlvbnMgJiYgb3B0aW9uc1sncHJveHknXTtcblxuICB2YXIgb25UZXh0LFxuICAgICAgb25PcGVuVGFnLFxuICAgICAgb25DbG9zZVRhZyxcbiAgICAgIG9uQ0RBVEEsXG4gICAgICBvbkVycm9yID0gdGhyb3dGdW5jLFxuICAgICAgb25XYXJuaW5nLFxuICAgICAgb25Db21tZW50LFxuICAgICAgb25RdWVzdGlvbixcbiAgICAgIG9uQXR0ZW50aW9uO1xuXG4gIHZhciBnZXRDb250ZXh0ID0gbm9vcEdldENvbnRleHQ7XG5cbiAgLyoqXG4gICAqIERvIHdlIG5lZWQgdG8gcGFyc2UgdGhlIGN1cnJlbnQgZWxlbWVudHMgYXR0cmlidXRlcyBmb3IgbmFtZXNwYWNlcz9cbiAgICpcbiAgICogQHR5cGUge2Jvb2xlYW59XG4gICAqL1xuICB2YXIgbWF5YmVOUyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBEbyB3ZSBwcm9jZXNzIG5hbWVzcGFjZXMgYXQgYWxsP1xuICAgKlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIHZhciBpc05hbWVzcGFjZSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBUaGUgY2F1Z2h0IGVycm9yIHJldHVybmVkIG9uIHBhcnNlIGVuZFxuICAgKlxuICAgKiBAdHlwZSB7RXJyb3J9XG4gICAqL1xuICB2YXIgcmV0dXJuRXJyb3IgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBTaG91bGQgd2Ugc3RvcCBwYXJzaW5nP1xuICAgKlxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cbiAgICovXG4gIHZhciBwYXJzZVN0b3AgPSBmYWxzZTtcblxuICAvKipcbiAgICogQSBtYXAgb2YgeyB1cmk6IHByZWZpeCB9IHVzZWQgYnkgdGhlIHBhcnNlci5cbiAgICpcbiAgICogVGhpcyBtYXAgd2lsbCBlbnN1cmUgd2UgY2FuIG5vcm1hbGl6ZSBwcmVmaXhlcyBkdXJpbmcgcHJvY2Vzc2luZztcbiAgICogZm9yIGVhY2ggdXJpLCBvbmx5IG9uZSBwcmVmaXggd2lsbCBiZSBleHBvc2VkIHRvIHRoZSBoYW5kbGVycy5cbiAgICpcbiAgICogQHR5cGUgeyFPYmplY3Q8c3RyaW5nLCBzdHJpbmc+fX1cbiAgICovXG4gIHZhciBuc1VyaVRvUHJlZml4O1xuXG4gIC8qKlxuICAgKiBIYW5kbGUgcGFyc2UgZXJyb3IuXG4gICAqXG4gICAqIEBwYXJhbSAge3N0cmluZ3xFcnJvcn0gZXJyXG4gICAqL1xuICBmdW5jdGlvbiBoYW5kbGVFcnJvcihlcnIpIHtcbiAgICBpZiAoIShlcnIgaW5zdGFuY2VvZiBFcnJvcikpIHtcbiAgICAgIGVyciA9IGVycm9yKGVycik7XG4gICAgfVxuXG4gICAgcmV0dXJuRXJyb3IgPSBlcnI7XG5cbiAgICBvbkVycm9yKGVyciwgZ2V0Q29udGV4dCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHBhcnNlIGVycm9yLlxuICAgKlxuICAgKiBAcGFyYW0gIHtzdHJpbmd8RXJyb3J9IGVyclxuICAgKi9cbiAgZnVuY3Rpb24gaGFuZGxlV2FybmluZyhlcnIpIHtcblxuICAgIGlmICghb25XYXJuaW5nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKCEoZXJyIGluc3RhbmNlb2YgRXJyb3IpKSB7XG4gICAgICBlcnIgPSBlcnJvcihlcnIpO1xuICAgIH1cblxuICAgIG9uV2FybmluZyhlcnIsIGdldENvbnRleHQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIHBhcnNlIGxpc3RlbmVyLlxuICAgKlxuICAgKiBAcGFyYW0gIHtzdHJpbmd9ICAgbmFtZVxuICAgKiBAcGFyYW0gIHtGdW5jdGlvbn0gY2JcbiAgICpcbiAgICogQHJldHVybiB7UGFyc2VyfVxuICAgKi9cbiAgdGhpc1snb24nXSA9IGZ1bmN0aW9uKG5hbWUsIGNiKSB7XG5cbiAgICBpZiAodHlwZW9mIGNiICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICB0aHJvdyBlcnJvcigncmVxdWlyZWQgYXJncyA8bmFtZSwgY2I+Jyk7XG4gICAgfVxuXG4gICAgc3dpdGNoIChuYW1lKSB7XG4gICAgY2FzZSAnb3BlblRhZyc6IG9uT3BlblRhZyA9IGNiOyBicmVhaztcbiAgICBjYXNlICd0ZXh0Jzogb25UZXh0ID0gY2I7IGJyZWFrO1xuICAgIGNhc2UgJ2Nsb3NlVGFnJzogb25DbG9zZVRhZyA9IGNiOyBicmVhaztcbiAgICBjYXNlICdlcnJvcic6IG9uRXJyb3IgPSBjYjsgYnJlYWs7XG4gICAgY2FzZSAnd2Fybic6IG9uV2FybmluZyA9IGNiOyBicmVhaztcbiAgICBjYXNlICdjZGF0YSc6IG9uQ0RBVEEgPSBjYjsgYnJlYWs7XG4gICAgY2FzZSAnYXR0ZW50aW9uJzogb25BdHRlbnRpb24gPSBjYjsgYnJlYWs7IC8vIDwhWFhYWFggenp6ej1cImVlZWVcIj5cbiAgICBjYXNlICdxdWVzdGlvbic6IG9uUXVlc3Rpb24gPSBjYjsgYnJlYWs7IC8vIDw/IC4uLi4gID8+XG4gICAgY2FzZSAnY29tbWVudCc6IG9uQ29tbWVudCA9IGNiOyBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgZXJyb3IoJ3Vuc3VwcG9ydGVkIGV2ZW50OiAnICsgbmFtZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG5cbiAgLyoqXG4gICAqIFNldCB0aGUgbmFtZXNwYWNlIHRvIHByZWZpeCBtYXBwaW5nLlxuICAgKlxuICAgKiBAZXhhbXBsZVxuICAgKlxuICAgKiBwYXJzZXIubnMoe1xuICAgKiAgICdodHRwOi8vZm9vJzogJ2ZvbycsXG4gICAqICAgJ2h0dHA6Ly9iYXInOiAnYmFyJ1xuICAgKiB9KTtcbiAgICpcbiAgICogQHBhcmFtICB7IU9iamVjdDxzdHJpbmcsIHN0cmluZz59IG5zTWFwXG4gICAqXG4gICAqIEByZXR1cm4ge1BhcnNlcn1cbiAgICovXG4gIHRoaXNbJ25zJ10gPSBmdW5jdGlvbihuc01hcCkge1xuXG4gICAgaWYgKHR5cGVvZiBuc01hcCA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIG5zTWFwID0ge307XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBuc01hcCAhPT0gJ29iamVjdCcpIHtcbiAgICAgIHRocm93IGVycm9yKCdyZXF1aXJlZCBhcmdzIDxuc01hcD17fT4nKTtcbiAgICB9XG5cbiAgICB2YXIgX25zVXJpVG9QcmVmaXggPSB7fSwgaztcblxuICAgIGZvciAoayBpbiBuc01hcCkge1xuICAgICAgX25zVXJpVG9QcmVmaXhba10gPSBuc01hcFtrXTtcbiAgICB9XG5cbiAgICAvLyBGT1JDRSBkZWZhdWx0IG1hcHBpbmcgZm9yIHNjaGVtYSBpbnN0YW5jZVxuICAgIF9uc1VyaVRvUHJlZml4W1hTSV9VUkldID0gWFNJX1BSRUZJWDtcblxuICAgIGlzTmFtZXNwYWNlID0gdHJ1ZTtcbiAgICBuc1VyaVRvUHJlZml4ID0gX25zVXJpVG9QcmVmaXg7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogUGFyc2UgeG1sIHN0cmluZy5cbiAgICpcbiAgICogQHBhcmFtICB7c3RyaW5nfSB4bWxcbiAgICpcbiAgICogQHJldHVybiB7RXJyb3J9IHJldHVybkVycm9yLCBpZiBub3QgdGhyb3duXG4gICAqL1xuICB0aGlzWydwYXJzZSddID0gZnVuY3Rpb24oeG1sKSB7XG4gICAgaWYgKHR5cGVvZiB4bWwgIT09ICdzdHJpbmcnKSB7XG4gICAgICB0aHJvdyBlcnJvcigncmVxdWlyZWQgYXJncyA8eG1sPXN0cmluZz4nKTtcbiAgICB9XG5cbiAgICByZXR1cm5FcnJvciA9IG51bGw7XG5cbiAgICBwYXJzZSh4bWwpO1xuXG4gICAgZ2V0Q29udGV4dCA9IG5vb3BHZXRDb250ZXh0O1xuICAgIHBhcnNlU3RvcCA9IGZhbHNlO1xuXG4gICAgcmV0dXJuIHJldHVybkVycm9yO1xuICB9O1xuXG4gIC8qKlxuICAgKiBTdG9wIHBhcnNpbmcuXG4gICAqL1xuICB0aGlzWydzdG9wJ10gPSBmdW5jdGlvbigpIHtcbiAgICBwYXJzZVN0b3AgPSB0cnVlO1xuICB9O1xuXG4gIC8qKlxuICAgKiBQYXJzZSBzdHJpbmcsIGludm9raW5nIGNvbmZpZ3VyZWQgbGlzdGVuZXJzIG9uIGVsZW1lbnQuXG4gICAqXG4gICAqIEBwYXJhbSAge3N0cmluZ30geG1sXG4gICAqL1xuICBmdW5jdGlvbiBwYXJzZSh4bWwpIHtcbiAgICB2YXIgbnNNYXRyaXhTdGFjayA9IGlzTmFtZXNwYWNlID8gW10gOiBudWxsLFxuICAgICAgICBuc01hdHJpeCA9IGlzTmFtZXNwYWNlID8gYnVpbGROc01hdHJpeChuc1VyaVRvUHJlZml4KSA6IG51bGwsXG4gICAgICAgIF9uc01hdHJpeCxcbiAgICAgICAgbm9kZVN0YWNrID0gW10sXG4gICAgICAgIGFub255bW91c05zQ291bnQgPSAwLFxuICAgICAgICB0YWdTdGFydCA9IGZhbHNlLFxuICAgICAgICB0YWdFbmQgPSBmYWxzZSxcbiAgICAgICAgaSA9IDAsIGogPSAwLFxuICAgICAgICB4LCB5LCBxLCB3LCB2LFxuICAgICAgICB4bWxucyxcbiAgICAgICAgZWxlbWVudE5hbWUsXG4gICAgICAgIF9lbGVtZW50TmFtZSxcbiAgICAgICAgZWxlbWVudFByb3h5XG4gICAgICAgIDtcblxuICAgIHZhciBhdHRyc1N0cmluZyA9ICcnLFxuICAgICAgICBhdHRyc1N0YXJ0ID0gMCxcbiAgICAgICAgY2FjaGVkQXR0cnMgLy8gZmFsc2UgPSBwYXJzZWQgd2l0aCBlcnJvcnMsIG51bGwgPSBuZWVkcyBwYXJzaW5nXG4gICAgICAgIDtcblxuICAgIC8qKlxuICAgICAqIFBhcnNlIGF0dHJpYnV0ZXMgb24gZGVtYW5kIGFuZCByZXR1cm5zIHRoZSBwYXJzZWQgYXR0cmlidXRlcy5cbiAgICAgKlxuICAgICAqIFJldHVybiBzZW1hbnRpY3M6ICgxKSBgZmFsc2VgIG9uIGF0dHJpYnV0ZSBwYXJzZSBlcnJvcixcbiAgICAgKiAoMikgb2JqZWN0IGhhc2ggb24gZXh0cmFjdGVkIGF0dHJzLlxuICAgICAqXG4gICAgICogQHJldHVybiB7Ym9vbGVhbnxPYmplY3R9XG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0QXR0cnMoKSB7XG4gICAgICBpZiAoY2FjaGVkQXR0cnMgIT09IG51bGwpIHtcbiAgICAgICAgcmV0dXJuIGNhY2hlZEF0dHJzO1xuICAgICAgfVxuXG4gICAgICB2YXIgbnNVcmksXG4gICAgICAgICAgbnNVcmlQcmVmaXgsXG4gICAgICAgICAgbnNOYW1lLFxuICAgICAgICAgIGRlZmF1bHRBbGlhcyA9IGlzTmFtZXNwYWNlICYmIG5zTWF0cml4Wyd4bWxucyddLFxuICAgICAgICAgIGF0dHJMaXN0ID0gaXNOYW1lc3BhY2UgJiYgbWF5YmVOUyA/IFtdIDogbnVsbCxcbiAgICAgICAgICBpID0gYXR0cnNTdGFydCxcbiAgICAgICAgICBzID0gYXR0cnNTdHJpbmcsXG4gICAgICAgICAgbCA9IHMubGVuZ3RoLFxuICAgICAgICAgIGhhc05ld01hdHJpeCxcbiAgICAgICAgICBuZXdhbGlhcyxcbiAgICAgICAgICB2YWx1ZSxcbiAgICAgICAgICBhbGlhcyxcbiAgICAgICAgICBuYW1lLFxuICAgICAgICAgIGF0dHJzID0ge30sXG4gICAgICAgICAgc2VlbkF0dHJzID0ge30sXG4gICAgICAgICAgc2tpcEF0dHIsXG4gICAgICAgICAgdyxcbiAgICAgICAgICBqO1xuXG4gICAgICBwYXJzZUF0dHI6XG4gICAgICBmb3IgKDsgaSA8IGw7IGkrKykge1xuICAgICAgICBza2lwQXR0ciA9IGZhbHNlO1xuICAgICAgICB3ID0gcy5jaGFyQ29kZUF0KGkpO1xuXG4gICAgICAgIGlmICh3ID09PSAzMiB8fCAodyA8IDE0ICYmIHcgPiA4KSkgeyAvLyBXSElURVNQQUNFPXsgXFxmXFxuXFxyXFx0XFx2fVxuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gd2FpdCBmb3Igbm9uIHdoaXRlc3BhY2UgY2hhcmFjdGVyXG4gICAgICAgIGlmICh3IDwgNjUgfHwgdyA+IDEyMiB8fCAodyA+IDkwICYmIHcgPCA5NykpIHtcbiAgICAgICAgICBpZiAodyAhPT0gOTUgJiYgdyAhPT0gNTgpIHsgLy8gY2hhciA5NVwiX1wiIDU4XCI6XCJcbiAgICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2lsbGVnYWwgZmlyc3QgY2hhciBhdHRyaWJ1dGUgbmFtZScpO1xuICAgICAgICAgICAgc2tpcEF0dHIgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHBhcnNlIGF0dHJpYnV0ZSBuYW1lXG4gICAgICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbDsgaisrKSB7XG4gICAgICAgICAgdyA9IHMuY2hhckNvZGVBdChqKTtcblxuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIHcgPiA5NiAmJiB3IDwgMTIzIHx8XG4gICAgICAgICAgICB3ID4gNjQgJiYgdyA8IDkxIHx8XG4gICAgICAgICAgICB3ID4gNDcgJiYgdyA8IDU5IHx8XG4gICAgICAgICAgICB3ID09PSA0NiB8fCAvLyAnLidcbiAgICAgICAgICAgIHcgPT09IDQ1IHx8IC8vICctJ1xuICAgICAgICAgICAgdyA9PT0gOTUgLy8gJ18nXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyB1bmV4cGVjdGVkIHdoaXRlc3BhY2VcbiAgICAgICAgICBpZiAodyA9PT0gMzIgfHwgKHcgPCAxNCAmJiB3ID4gOCkpIHsgLy8gV0hJVEVTUEFDRVxuICAgICAgICAgICAgaGFuZGxlV2FybmluZygnbWlzc2luZyBhdHRyaWJ1dGUgdmFsdWUnKTtcbiAgICAgICAgICAgIGkgPSBqO1xuXG4gICAgICAgICAgICBjb250aW51ZSBwYXJzZUF0dHI7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gZXhwZWN0ZWQgXCI9XCJcbiAgICAgICAgICBpZiAodyA9PT0gNjEpIHsgLy8gXCI9XCIgPT0gNjFcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2lsbGVnYWwgYXR0cmlidXRlIG5hbWUgY2hhcicpO1xuICAgICAgICAgIHNraXBBdHRyID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5hbWUgPSBzLnN1YnN0cmluZyhpLCBqKTtcblxuICAgICAgICBpZiAobmFtZSA9PT0gJ3htbG5zOnhtbG5zJykge1xuICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2lsbGVnYWwgZGVjbGFyYXRpb24gb2YgeG1sbnMnKTtcbiAgICAgICAgICBza2lwQXR0ciA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICB3ID0gcy5jaGFyQ29kZUF0KGogKyAxKTtcblxuICAgICAgICBpZiAodyA9PT0gMzQpIHsgLy8gJ1wiJ1xuICAgICAgICAgIGogPSBzLmluZGV4T2YoJ1wiJywgaSA9IGogKyAyKTtcblxuICAgICAgICAgIGlmIChqID09PSAtMSkge1xuICAgICAgICAgICAgaiA9IHMuaW5kZXhPZignXFwnJywgaSk7XG5cbiAgICAgICAgICAgIGlmIChqICE9PSAtMSkge1xuICAgICAgICAgICAgICBoYW5kbGVXYXJuaW5nKCdhdHRyaWJ1dGUgdmFsdWUgcXVvdGUgbWlzc21hdGNoJyk7XG4gICAgICAgICAgICAgIHNraXBBdHRyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgfSBlbHNlIGlmICh3ID09PSAzOSkgeyAvLyBcIidcIlxuICAgICAgICAgIGogPSBzLmluZGV4T2YoJ1xcJycsIGkgPSBqICsgMik7XG5cbiAgICAgICAgICBpZiAoaiA9PT0gLTEpIHtcbiAgICAgICAgICAgIGogPSBzLmluZGV4T2YoJ1wiJywgaSk7XG5cbiAgICAgICAgICAgIGlmIChqICE9PSAtMSkge1xuICAgICAgICAgICAgICBoYW5kbGVXYXJuaW5nKCdhdHRyaWJ1dGUgdmFsdWUgcXVvdGUgbWlzc21hdGNoJyk7XG4gICAgICAgICAgICAgIHNraXBBdHRyID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBoYW5kbGVXYXJuaW5nKCdtaXNzaW5nIGF0dHJpYnV0ZSB2YWx1ZSBxdW90ZXMnKTtcbiAgICAgICAgICBza2lwQXR0ciA9IHRydWU7XG5cbiAgICAgICAgICAvLyBza2lwIHRvIG5leHQgc3BhY2VcbiAgICAgICAgICBmb3IgKGogPSBqICsgMTsgaiA8IGw7IGorKykge1xuICAgICAgICAgICAgdyA9IHMuY2hhckNvZGVBdChqICsgMSk7XG5cbiAgICAgICAgICAgIGlmICh3ID09PSAzMiB8fCAodyA8IDE0ICYmIHcgPiA4KSkgeyAvLyBXSElURVNQQUNFXG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGogPT09IC0xKSB7XG4gICAgICAgICAgaGFuZGxlV2FybmluZygnbWlzc2luZyBjbG9zaW5nIHF1b3RlcycpO1xuXG4gICAgICAgICAgaiA9IGw7XG4gICAgICAgICAgc2tpcEF0dHIgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFza2lwQXR0cikge1xuICAgICAgICAgIHZhbHVlID0gcy5zdWJzdHJpbmcoaSwgaik7XG4gICAgICAgIH1cblxuICAgICAgICBpID0gajtcblxuICAgICAgICAvLyBlbnN1cmUgU1BBQ0UgZm9sbG93cyBhdHRyaWJ1dGVcbiAgICAgICAgLy8gc2tpcCBpbGxlZ2FsIGNvbnRlbnQgb3RoZXJ3aXNlXG4gICAgICAgIC8vIGV4YW1wbGUgYT1cImJcImNcbiAgICAgICAgZm9yICg7IGogKyAxIDwgbDsgaisrKSB7XG4gICAgICAgICAgdyA9IHMuY2hhckNvZGVBdChqICsgMSk7XG5cbiAgICAgICAgICBpZiAodyA9PT0gMzIgfHwgKHcgPCAxNCAmJiB3ID4gOCkpIHsgLy8gV0hJVEVTUEFDRVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gRklSU1QgSUxMRUdBTCBDSEFSXG4gICAgICAgICAgaWYgKGkgPT09IGopIHtcbiAgICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2lsbGVnYWwgY2hhcmFjdGVyIGFmdGVyIGF0dHJpYnV0ZSBlbmQnKTtcbiAgICAgICAgICAgIHNraXBBdHRyID0gdHJ1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZHZhbmNlIGN1cnNvciB0byBuZXh0IGF0dHJpYnV0ZVxuICAgICAgICBpID0gaiArIDE7XG5cbiAgICAgICAgaWYgKHNraXBBdHRyKSB7XG4gICAgICAgICAgY29udGludWUgcGFyc2VBdHRyO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY2hlY2sgYXR0cmlidXRlIHJlLWRlY2xhcmF0aW9uXG4gICAgICAgIGlmIChuYW1lIGluIHNlZW5BdHRycykge1xuICAgICAgICAgIGhhbmRsZVdhcm5pbmcoJ2F0dHJpYnV0ZSA8JyArIG5hbWUgKyAnPiBhbHJlYWR5IGRlZmluZWQnKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHNlZW5BdHRyc1tuYW1lXSA9IHRydWU7XG5cbiAgICAgICAgaWYgKCFpc05hbWVzcGFjZSkge1xuICAgICAgICAgIGF0dHJzW25hbWVdID0gdmFsdWU7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB0cnkgdG8gZXh0cmFjdCBuYW1lc3BhY2UgaW5mb3JtYXRpb25cbiAgICAgICAgaWYgKG1heWJlTlMpIHtcbiAgICAgICAgICBuZXdhbGlhcyA9IChcbiAgICAgICAgICAgIG5hbWUgPT09ICd4bWxucydcbiAgICAgICAgICAgICAgPyAneG1sbnMnXG4gICAgICAgICAgICAgIDogKG5hbWUuY2hhckNvZGVBdCgwKSA9PT0gMTIwICYmIG5hbWUuc3Vic3RyKDAsIDYpID09PSAneG1sbnM6JylcbiAgICAgICAgICAgICAgICA/IG5hbWUuc3Vic3RyKDYpXG4gICAgICAgICAgICAgICAgOiBudWxsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIGhhbmRsZSB4bWxucyg6YWxpYXMpIGFzc2lnbm1lbnRcbiAgICAgICAgICBpZiAobmV3YWxpYXMgIT09IG51bGwpIHtcbiAgICAgICAgICAgIG5zVXJpID0gZGVjb2RlRW50aXRpZXModmFsdWUpO1xuICAgICAgICAgICAgbnNVcmlQcmVmaXggPSB1cmlQcmVmaXgobmV3YWxpYXMpO1xuXG4gICAgICAgICAgICBhbGlhcyA9IG5zVXJpVG9QcmVmaXhbbnNVcmldO1xuXG4gICAgICAgICAgICBpZiAoIWFsaWFzKSB7XG5cbiAgICAgICAgICAgICAgLy8gbm8gcHJlZml4IGRlZmluZWQgb3IgcHJlZml4IGNvbGxpc2lvblxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgKG5ld2FsaWFzID09PSAneG1sbnMnKSB8fFxuICAgICAgICAgICAgICAgIChuc1VyaVByZWZpeCBpbiBuc01hdHJpeCAmJiBuc01hdHJpeFtuc1VyaVByZWZpeF0gIT09IG5zVXJpKVxuICAgICAgICAgICAgICApIHtcblxuICAgICAgICAgICAgICAgIC8vIGFsb2NhdGUgZnJlZSBucyBwcmVmaXhcbiAgICAgICAgICAgICAgICBkbyB7XG4gICAgICAgICAgICAgICAgICBhbGlhcyA9ICducycgKyAoYW5vbnltb3VzTnNDb3VudCsrKTtcbiAgICAgICAgICAgICAgICB9IHdoaWxlICh0eXBlb2YgbnNNYXRyaXhbYWxpYXNdICE9PSAndW5kZWZpbmVkJyk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgYWxpYXMgPSBuZXdhbGlhcztcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIG5zVXJpVG9QcmVmaXhbbnNVcmldID0gYWxpYXM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChuc01hdHJpeFtuZXdhbGlhc10gIT09IGFsaWFzKSB7XG4gICAgICAgICAgICAgIGlmICghaGFzTmV3TWF0cml4KSB7XG4gICAgICAgICAgICAgICAgbnNNYXRyaXggPSBjbG9uZU5zTWF0cml4KG5zTWF0cml4KTtcbiAgICAgICAgICAgICAgICBoYXNOZXdNYXRyaXggPSB0cnVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgbnNNYXRyaXhbbmV3YWxpYXNdID0gYWxpYXM7XG4gICAgICAgICAgICAgIGlmIChuZXdhbGlhcyA9PT0gJ3htbG5zJykge1xuICAgICAgICAgICAgICAgIG5zTWF0cml4W3VyaVByZWZpeChhbGlhcyldID0gbnNVcmk7XG4gICAgICAgICAgICAgICAgZGVmYXVsdEFsaWFzID0gYWxpYXM7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBuc01hdHJpeFtuc1VyaVByZWZpeF0gPSBuc1VyaTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gZXhwb3NlIHhtbG5zKDphc2QpPVwiLi4uXCIgaW4gYXR0cmlidXRlc1xuICAgICAgICAgICAgYXR0cnNbbmFtZV0gPSB2YWx1ZTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGNvbGxlY3QgYXR0cmlidXRlcyB1bnRpbCBhbGwgbmFtZXNwYWNlXG4gICAgICAgICAgLy8gZGVjbGFyYXRpb25zIGFyZSBwcm9jZXNzZWRcbiAgICAgICAgICBhdHRyTGlzdC5wdXNoKG5hbWUsIHZhbHVlKTtcbiAgICAgICAgICBjb250aW51ZTtcblxuICAgICAgICB9IC8qKiBlbmQgaWYgKG1heWJlTnMpICovXG5cbiAgICAgICAgLy8gaGFuZGxlIGF0dHJpYnV0ZXMgb24gZWxlbWVudCB3aXRob3V0XG4gICAgICAgIC8vIG5hbWVzcGFjZSBkZWNsYXJhdGlvbnNcbiAgICAgICAgdyA9IG5hbWUuaW5kZXhPZignOicpO1xuICAgICAgICBpZiAodyA9PT0gLTEpIHtcbiAgICAgICAgICBhdHRyc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbm9ybWFsaXplIG5zIGF0dHJpYnV0ZSBuYW1lXG4gICAgICAgIGlmICghKG5zTmFtZSA9IG5zTWF0cml4W25hbWUuc3Vic3RyaW5nKDAsIHcpXSkpIHtcbiAgICAgICAgICBoYW5kbGVXYXJuaW5nKG1pc3NpbmdOYW1lc3BhY2VGb3JQcmVmaXgobmFtZS5zdWJzdHJpbmcoMCwgdykpKTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIG5hbWUgPSBkZWZhdWx0QWxpYXMgPT09IG5zTmFtZVxuICAgICAgICAgID8gbmFtZS5zdWJzdHIodyArIDEpXG4gICAgICAgICAgOiBuc05hbWUgKyBuYW1lLnN1YnN0cih3KTtcblxuICAgICAgICAvLyBlbmQ6IG5vcm1hbGl6ZSBucyBhdHRyaWJ1dGUgbmFtZVxuXG4gICAgICAgIC8vIG5vcm1hbGl6ZSB4c2k6dHlwZSBucyBhdHRyaWJ1dGUgdmFsdWVcbiAgICAgICAgaWYgKG5hbWUgPT09IFhTSV9UWVBFKSB7XG4gICAgICAgICAgdyA9IHZhbHVlLmluZGV4T2YoJzonKTtcblxuICAgICAgICAgIGlmICh3ICE9PSAtMSkge1xuICAgICAgICAgICAgbnNOYW1lID0gdmFsdWUuc3Vic3RyaW5nKDAsIHcpO1xuXG4gICAgICAgICAgICAvLyBoYW5kbGUgZGVmYXVsdCBwcmVmaXhlcywgaS5lLiB4czpTdHJpbmcgZ3JhY2VmdWxseVxuICAgICAgICAgICAgbnNOYW1lID0gbnNNYXRyaXhbbnNOYW1lXSB8fCBuc05hbWU7XG4gICAgICAgICAgICB2YWx1ZSA9IG5zTmFtZSArIHZhbHVlLnN1YnN0cmluZyh3KTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFsdWUgPSBkZWZhdWx0QWxpYXMgKyAnOicgKyB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBlbmQ6IG5vcm1hbGl6ZSB4c2k6dHlwZSBucyBhdHRyaWJ1dGUgdmFsdWVcblxuICAgICAgICBhdHRyc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgfVxuXG5cbiAgICAgIC8vIGhhbmRsZSBkZWZlcnJlZCwgcG9zc2libHkgbmFtZXNwYWNlZCBhdHRyaWJ1dGVzXG4gICAgICBpZiAobWF5YmVOUykge1xuXG4gICAgICAgIC8vIG5vcm1hbGl6ZSBjYXB0dXJlZCBhdHRyaWJ1dGVzXG4gICAgICAgIGZvciAoaSA9IDAsIGwgPSBhdHRyTGlzdC5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblxuICAgICAgICAgIG5hbWUgPSBhdHRyTGlzdFtpKytdO1xuICAgICAgICAgIHZhbHVlID0gYXR0ckxpc3RbaV07XG5cbiAgICAgICAgICB3ID0gbmFtZS5pbmRleE9mKCc6Jyk7XG5cbiAgICAgICAgICBpZiAodyAhPT0gLTEpIHtcblxuICAgICAgICAgICAgLy8gbm9ybWFsaXplIG5zIGF0dHJpYnV0ZSBuYW1lXG4gICAgICAgICAgICBpZiAoIShuc05hbWUgPSBuc01hdHJpeFtuYW1lLnN1YnN0cmluZygwLCB3KV0pKSB7XG4gICAgICAgICAgICAgIGhhbmRsZVdhcm5pbmcobWlzc2luZ05hbWVzcGFjZUZvclByZWZpeChuYW1lLnN1YnN0cmluZygwLCB3KSkpO1xuICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbmFtZSA9IGRlZmF1bHRBbGlhcyA9PT0gbnNOYW1lXG4gICAgICAgICAgICAgID8gbmFtZS5zdWJzdHIodyArIDEpXG4gICAgICAgICAgICAgIDogbnNOYW1lICsgbmFtZS5zdWJzdHIodyk7XG5cbiAgICAgICAgICAgIC8vIGVuZDogbm9ybWFsaXplIG5zIGF0dHJpYnV0ZSBuYW1lXG5cbiAgICAgICAgICAgIC8vIG5vcm1hbGl6ZSB4c2k6dHlwZSBucyBhdHRyaWJ1dGUgdmFsdWVcbiAgICAgICAgICAgIGlmIChuYW1lID09PSBYU0lfVFlQRSkge1xuICAgICAgICAgICAgICB3ID0gdmFsdWUuaW5kZXhPZignOicpO1xuXG4gICAgICAgICAgICAgIGlmICh3ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIG5zTmFtZSA9IHZhbHVlLnN1YnN0cmluZygwLCB3KTtcblxuICAgICAgICAgICAgICAgIC8vIGhhbmRsZSBkZWZhdWx0IHByZWZpeGVzLCBpLmUuIHhzOlN0cmluZyBncmFjZWZ1bGx5XG4gICAgICAgICAgICAgICAgbnNOYW1lID0gbnNNYXRyaXhbbnNOYW1lXSB8fCBuc05hbWU7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBuc05hbWUgKyB2YWx1ZS5zdWJzdHJpbmcodyk7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBkZWZhdWx0QWxpYXMgKyAnOicgKyB2YWx1ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBlbmQ6IG5vcm1hbGl6ZSB4c2k6dHlwZSBucyBhdHRyaWJ1dGUgdmFsdWVcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBhdHRyc1tuYW1lXSA9IHZhbHVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZW5kOiBub3JtYWxpemUgY2FwdHVyZWQgYXR0cmlidXRlc1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2FjaGVkQXR0cnMgPSBhdHRycztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0IHRoZSBwYXJzZSBjb250ZXh0IHsgbGluZSwgY29sdW1uLCBwYXJ0IH1cbiAgICAgKiBmcm9tIHRoZSBjdXJyZW50IHBhcnNlciBwb3NpdGlvbi5cbiAgICAgKlxuICAgICAqIEByZXR1cm4ge09iamVjdH0gcGFyc2UgY29udGV4dFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldFBhcnNlQ29udGV4dCgpIHtcbiAgICAgIHZhciBzcGxpdHNSZSA9IC8oXFxyXFxufFxccnxcXG4pL2c7XG5cbiAgICAgIHZhciBsaW5lID0gMDtcbiAgICAgIHZhciBjb2x1bW4gPSAwO1xuICAgICAgdmFyIHN0YXJ0T2ZMaW5lID0gMDtcbiAgICAgIHZhciBlbmRPZkxpbmUgPSBqO1xuICAgICAgdmFyIG1hdGNoO1xuICAgICAgdmFyIGRhdGE7XG5cbiAgICAgIHdoaWxlIChpID49IHN0YXJ0T2ZMaW5lKSB7XG5cbiAgICAgICAgbWF0Y2ggPSBzcGxpdHNSZS5leGVjKHhtbCk7XG5cbiAgICAgICAgaWYgKCFtYXRjaCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gZW5kIG9mIGxpbmUgPSAoYnJlYWsgaWR4ICsgYnJlYWsgY2hhcnMpXG4gICAgICAgIGVuZE9mTGluZSA9IG1hdGNoWzBdLmxlbmd0aCArIG1hdGNoLmluZGV4O1xuXG4gICAgICAgIGlmIChlbmRPZkxpbmUgPiBpKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBhZHZhbmNlIHRvIG5leHQgbGluZVxuICAgICAgICBsaW5lICs9IDE7XG5cbiAgICAgICAgc3RhcnRPZkxpbmUgPSBlbmRPZkxpbmU7XG4gICAgICB9XG5cbiAgICAgIC8vIEVPRiBlcnJvcnNcbiAgICAgIGlmIChpID09IC0xKSB7XG4gICAgICAgIGNvbHVtbiA9IGVuZE9mTGluZTtcbiAgICAgICAgZGF0YSA9IHhtbC5zdWJzdHJpbmcoaik7XG4gICAgICB9IGVsc2VcblxuICAgICAgLy8gc3RhcnQgZXJyb3JzXG4gICAgICBpZiAoaiA9PT0gMCkge1xuICAgICAgICBkYXRhID0geG1sLnN1YnN0cmluZyhqLCBpKTtcbiAgICAgIH1cblxuICAgICAgLy8gb3RoZXIgZXJyb3JzXG4gICAgICBlbHNlIHtcbiAgICAgICAgY29sdW1uID0gaSAtIHN0YXJ0T2ZMaW5lO1xuICAgICAgICBkYXRhID0gKGogPT0gLTEgPyB4bWwuc3Vic3RyaW5nKGkpIDogeG1sLnN1YnN0cmluZyhpLCBqICsgMSkpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICAnZGF0YSc6IGRhdGEsXG4gICAgICAgICdsaW5lJzogbGluZSxcbiAgICAgICAgJ2NvbHVtbic6IGNvbHVtblxuICAgICAgfTtcbiAgICB9XG5cbiAgICBnZXRDb250ZXh0ID0gZ2V0UGFyc2VDb250ZXh0O1xuXG5cbiAgICBpZiAocHJveHkpIHtcbiAgICAgIGVsZW1lbnRQcm94eSA9IE9iamVjdC5jcmVhdGUoe30sIHtcbiAgICAgICAgJ25hbWUnOiBnZXR0ZXIoZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcmV0dXJuIGVsZW1lbnROYW1lO1xuICAgICAgICB9KSxcbiAgICAgICAgJ29yaWdpbmFsTmFtZSc6IGdldHRlcihmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gX2VsZW1lbnROYW1lO1xuICAgICAgICB9KSxcbiAgICAgICAgJ2F0dHJzJzogZ2V0dGVyKGdldEF0dHJzKSxcbiAgICAgICAgJ25zJzogZ2V0dGVyKGZ1bmN0aW9uKCkge1xuICAgICAgICAgIHJldHVybiBuc01hdHJpeDtcbiAgICAgICAgfSlcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGFjdHVhbCBwYXJzZSBsb2dpY1xuICAgIHdoaWxlIChqICE9PSAtMSkge1xuXG4gICAgICBpZiAoeG1sLmNoYXJDb2RlQXQoaikgPT09IDYwKSB7IC8vIFwiPFwiXG4gICAgICAgIGkgPSBqO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaSA9IHhtbC5pbmRleE9mKCc8Jywgaik7XG4gICAgICB9XG5cbiAgICAgIC8vIHBhcnNlIGVuZFxuICAgICAgaWYgKGkgPT09IC0xKSB7XG4gICAgICAgIGlmIChub2RlU3RhY2subGVuZ3RoKSB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZUVycm9yKCd1bmV4cGVjdGVkIGVuZCBvZiBmaWxlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoaiA9PT0gMCkge1xuICAgICAgICAgIHJldHVybiBoYW5kbGVFcnJvcignbWlzc2luZyBzdGFydCB0YWcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChqIDwgeG1sLmxlbmd0aCkge1xuICAgICAgICAgIGlmICh4bWwuc3Vic3RyaW5nKGopLnRyaW0oKSkge1xuICAgICAgICAgICAgaGFuZGxlV2FybmluZyhOT05fV0hJVEVTUEFDRV9PVVRTSURFX1JPT1RfTk9ERSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBwYXJzZSB0ZXh0XG4gICAgICBpZiAoaiAhPT0gaSkge1xuXG4gICAgICAgIGlmIChub2RlU3RhY2subGVuZ3RoKSB7XG4gICAgICAgICAgaWYgKG9uVGV4dCkge1xuICAgICAgICAgICAgb25UZXh0KHhtbC5zdWJzdHJpbmcoaiwgaSksIGRlY29kZUVudGl0aWVzLCBnZXRDb250ZXh0KTtcblxuICAgICAgICAgICAgaWYgKHBhcnNlU3RvcCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh4bWwuc3Vic3RyaW5nKGosIGkpLnRyaW0oKSkge1xuICAgICAgICAgICAgaGFuZGxlV2FybmluZyhOT05fV0hJVEVTUEFDRV9PVVRTSURFX1JPT1RfTk9ERSk7XG5cbiAgICAgICAgICAgIGlmIChwYXJzZVN0b3ApIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB3ID0geG1sLmNoYXJDb2RlQXQoaSsxKTtcblxuICAgICAgLy8gcGFyc2UgY29tbWVudHMgKyBDREFUQVxuICAgICAgaWYgKHcgPT09IDMzKSB7IC8vIFwiIVwiXG4gICAgICAgIHEgPSB4bWwuY2hhckNvZGVBdChpKzIpO1xuXG4gICAgICAgIC8vIENEQVRBIHNlY3Rpb25cbiAgICAgICAgaWYgKHEgPT09IDkxICYmIHhtbC5zdWJzdHIoaSArIDMsIDYpID09PSAnQ0RBVEFbJykgeyAvLyA5MSA9PSBcIltcIlxuICAgICAgICAgIGogPSB4bWwuaW5kZXhPZignXV0+JywgaSk7XG4gICAgICAgICAgaWYgKGogPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ3VuY2xvc2VkIGNkYXRhJyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKG9uQ0RBVEEpIHtcbiAgICAgICAgICAgIG9uQ0RBVEEoeG1sLnN1YnN0cmluZyhpICsgOSwgaiksIGdldENvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHBhcnNlU3RvcCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaiArPSAzO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gY29tbWVudFxuICAgICAgICBpZiAocSA9PT0gNDUgJiYgeG1sLmNoYXJDb2RlQXQoaSArIDMpID09PSA0NSkgeyAvLyA0NSA9PSBcIi1cIlxuICAgICAgICAgIGogPSB4bWwuaW5kZXhPZignLS0+JywgaSk7XG4gICAgICAgICAgaWYgKGogPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ3VuY2xvc2VkIGNvbW1lbnQnKTtcbiAgICAgICAgICB9XG5cblxuICAgICAgICAgIGlmIChvbkNvbW1lbnQpIHtcbiAgICAgICAgICAgIG9uQ29tbWVudCh4bWwuc3Vic3RyaW5nKGkgKyA0LCBqKSwgZGVjb2RlRW50aXRpZXMsIGdldENvbnRleHQpO1xuICAgICAgICAgICAgaWYgKHBhcnNlU3RvcCkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaiArPSAzO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIHBhcnNlIHF1ZXN0aW9uIDw/IC4uLiA/PlxuICAgICAgaWYgKHcgPT09IDYzKSB7IC8vIFwiP1wiXG4gICAgICAgIGogPSB4bWwuaW5kZXhPZignPz4nLCBpKTtcbiAgICAgICAgaWYgKGogPT09IC0xKSB7XG4gICAgICAgICAgcmV0dXJuIGhhbmRsZUVycm9yKCd1bmNsb3NlZCBxdWVzdGlvbicpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9uUXVlc3Rpb24pIHtcbiAgICAgICAgICBvblF1ZXN0aW9uKHhtbC5zdWJzdHJpbmcoaSwgaiArIDIpLCBnZXRDb250ZXh0KTtcbiAgICAgICAgICBpZiAocGFyc2VTdG9wKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaiArPSAyO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gZmluZCBtYXRjaGluZyBjbG9zaW5nIHRhZyBmb3IgYXR0ZW50aW9uIG9yIHN0YW5kYXJkIHRhZ3NcbiAgICAgIC8vIGZvciB0aGF0IHdlIG11c3Qgc2tpcCB0aHJvdWdoIGF0dHJpYnV0ZSB2YWx1ZXNcbiAgICAgIC8vIChlbmNsb3NlZCBpbiBzaW5nbGUgb3IgZG91YmxlIHF1b3RlcylcbiAgICAgIGZvciAoeCA9IGkgKyAxOyA7IHgrKykge1xuICAgICAgICB2ID0geG1sLmNoYXJDb2RlQXQoeCk7XG4gICAgICAgIGlmIChpc05hTih2KSkge1xuICAgICAgICAgIGogPSAtMTtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ3VuY2xvc2VkIHRhZycpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gWzEwXSBBdHRWYWx1ZSA6Oj0gJ1wiJyAoW148JlwiXSB8IFJlZmVyZW5jZSkqICdcIicgfCBcIidcIiAoW148JiddIHwgUmVmZXJlbmNlKSogXCInXCJcbiAgICAgICAgLy8gc2tpcHMgdGhlIHF1b3RlZCBzdHJpbmdcbiAgICAgICAgLy8gKGRvdWJsZSBxdW90ZXMpIGRvZXMgbm90IGFwcGVhciBpbiBhIGxpdGVyYWwgZW5jbG9zZWQgYnkgKGRvdWJsZSBxdW90ZXMpXG4gICAgICAgIC8vIChzaW5nbGUgcXVvdGUpIGRvZXMgbm90IGFwcGVhciBpbiBhIGxpdGVyYWwgZW5jbG9zZWQgYnkgKHNpbmdsZSBxdW90ZSlcbiAgICAgICAgaWYgKHYgPT09IDM0KSB7IC8vICAnXCInXG4gICAgICAgICAgcSA9IHhtbC5pbmRleE9mKCdcIicsIHggKyAxKTtcbiAgICAgICAgICB4ID0gcSAhPT0gLTEgPyBxIDogeDtcbiAgICAgICAgfSBlbHNlIGlmICh2ID09PSAzOSkgeyAvLyBcIidcIlxuICAgICAgICAgIHEgPSB4bWwuaW5kZXhPZihcIidcIiwgeCArIDEpO1xuICAgICAgICAgIHggPSBxICE9PSAtMSA/IHEgOiB4O1xuICAgICAgICB9IGVsc2UgaWYgKHYgPT09IDYyKSB7IC8vICc+J1xuICAgICAgICAgIGogPSB4O1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cblxuICAgICAgLy8gcGFyc2UgYXR0ZW50aW9uIDwhIC4uLj5cbiAgICAgIC8vIHByZXZpb3VzbHkgY29tbWVudCBhbmQgQ0RBVEEgaGF2ZSBhbHJlYWR5IGJlZW4gcGFyc2VkXG4gICAgICBpZiAodyA9PT0gMzMpIHsgLy8gXCIhXCJcblxuICAgICAgICBpZiAob25BdHRlbnRpb24pIHtcbiAgICAgICAgICBvbkF0dGVudGlvbih4bWwuc3Vic3RyaW5nKGksIGogKyAxKSwgZGVjb2RlRW50aXRpZXMsIGdldENvbnRleHQpO1xuICAgICAgICAgIGlmIChwYXJzZVN0b3ApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBqICs9IDE7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyBkb24ndCBwcm9jZXNzIGF0dHJpYnV0ZXM7XG4gICAgICAvLyB0aGVyZSBhcmUgbm9uZVxuICAgICAgY2FjaGVkQXR0cnMgPSB7fTtcblxuICAgICAgLy8gaWYgKHhtbC5jaGFyQ29kZUF0KGkrMSkgPT09IDQ3KSB7IC8vIDwvLi4uXG4gICAgICBpZiAodyA9PT0gNDcpIHsgLy8gPC8uLi5cbiAgICAgICAgdGFnU3RhcnQgPSBmYWxzZTtcbiAgICAgICAgdGFnRW5kID0gdHJ1ZTtcblxuICAgICAgICBpZiAoIW5vZGVTdGFjay5sZW5ndGgpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ21pc3Npbmcgb3BlbiB0YWcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIHZlcmlmeSBvcGVuIDwtPiBjbG9zZSB0YWcgbWF0Y2hcbiAgICAgICAgeCA9IGVsZW1lbnROYW1lID0gbm9kZVN0YWNrLnBvcCgpO1xuICAgICAgICBxID0gaSArIDIgKyB4Lmxlbmd0aDtcblxuICAgICAgICBpZiAoeG1sLnN1YnN0cmluZyhpICsgMiwgcSkgIT09IHgpIHtcbiAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ2Nsb3NpbmcgdGFnIG1pc21hdGNoJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyB2ZXJpZnkgY2hhcnMgaW4gY2xvc2UgdGFnXG4gICAgICAgIGZvciAoOyBxIDwgajsgcSsrKSB7XG4gICAgICAgICAgdyA9IHhtbC5jaGFyQ29kZUF0KHEpO1xuXG4gICAgICAgICAgaWYgKHcgPT09IDMyIHx8ICh3ID4gOCAmJiB3IDwgMTQpKSB7IC8vIFxcZlxcblxcclxcdFxcdiBzcGFjZVxuICAgICAgICAgICAgY29udGludWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGhhbmRsZUVycm9yKCdjbG9zZSB0YWcnKTtcbiAgICAgICAgfVxuXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoeG1sLmNoYXJDb2RlQXQoaiAtIDEpID09PSA0NykgeyAvLyAuLi4vPlxuICAgICAgICAgIHggPSBlbGVtZW50TmFtZSA9IHhtbC5zdWJzdHJpbmcoaSArIDEsIGogLSAxKTtcblxuICAgICAgICAgIHRhZ1N0YXJ0ID0gdHJ1ZTtcbiAgICAgICAgICB0YWdFbmQgPSB0cnVlO1xuXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgeCA9IGVsZW1lbnROYW1lID0geG1sLnN1YnN0cmluZyhpICsgMSwgaik7XG5cbiAgICAgICAgICB0YWdTdGFydCA9IHRydWU7XG4gICAgICAgICAgdGFnRW5kID0gZmFsc2U7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoISh3ID4gOTYgJiYgdyA8IDEyMyB8fCB3ID4gNjQgJiYgdyA8IDkxIHx8IHcgPT09IDk1IHx8IHcgPT09IDU4KSkgeyAvLyBjaGFyIDk1XCJfXCIgNThcIjpcIlxuICAgICAgICAgIHJldHVybiBoYW5kbGVFcnJvcignaWxsZWdhbCBmaXJzdCBjaGFyIG5vZGVOYW1lJyk7XG4gICAgICAgIH1cblxuICAgICAgICBmb3IgKHEgPSAxLCB5ID0geC5sZW5ndGg7IHEgPCB5OyBxKyspIHtcbiAgICAgICAgICB3ID0geC5jaGFyQ29kZUF0KHEpO1xuXG4gICAgICAgICAgaWYgKHcgPiA5NiAmJiB3IDwgMTIzIHx8IHcgPiA2NCAmJiB3IDwgOTEgfHwgdyA+IDQ3ICYmIHcgPCA1OSB8fCB3ID09PSA0NSB8fCB3ID09PSA5NSB8fCB3ID09IDQ2KSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodyA9PT0gMzIgfHwgKHcgPCAxNCAmJiB3ID4gOCkpIHsgLy8gXFxmXFxuXFxyXFx0XFx2IHNwYWNlXG4gICAgICAgICAgICBlbGVtZW50TmFtZSA9IHguc3Vic3RyaW5nKDAsIHEpO1xuXG4gICAgICAgICAgICAvLyBtYXliZSB0aGVyZSBhcmUgYXR0cmlidXRlc1xuICAgICAgICAgICAgY2FjaGVkQXR0cnMgPSBudWxsO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGhhbmRsZUVycm9yKCdpbnZhbGlkIG5vZGVOYW1lJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRhZ0VuZCkge1xuICAgICAgICAgIG5vZGVTdGFjay5wdXNoKGVsZW1lbnROYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoaXNOYW1lc3BhY2UpIHtcblxuICAgICAgICBfbnNNYXRyaXggPSBuc01hdHJpeDtcblxuICAgICAgICBpZiAodGFnU3RhcnQpIHtcblxuICAgICAgICAgIC8vIHJlbWVtYmVyIG9sZCBuYW1lc3BhY2VcbiAgICAgICAgICAvLyB1bmxlc3Mgd2UncmUgc2VsZi1jbG9zaW5nXG4gICAgICAgICAgaWYgKCF0YWdFbmQpIHtcbiAgICAgICAgICAgIG5zTWF0cml4U3RhY2sucHVzaChfbnNNYXRyaXgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChjYWNoZWRBdHRycyA9PT0gbnVsbCkge1xuXG4gICAgICAgICAgICAvLyBxdWljayBjaGVjaywgd2hldGhlciB0aGVyZSBtYXkgYmUgbmFtZXNwYWNlXG4gICAgICAgICAgICAvLyBkZWNsYXJhdGlvbnMgb24gdGhlIG5vZGU7IGlmIHRoYXQgaXMgdGhlIGNhc2VcbiAgICAgICAgICAgIC8vIHdlIG5lZWQgdG8gZWFnZXJseSBwYXJzZSB0aGUgbm9kZSBhdHRyaWJ1dGVzXG4gICAgICAgICAgICBpZiAoKG1heWJlTlMgPSB4LmluZGV4T2YoJ3htbG5zJywgcSkgIT09IC0xKSkge1xuICAgICAgICAgICAgICBhdHRyc1N0YXJ0ID0gcTtcbiAgICAgICAgICAgICAgYXR0cnNTdHJpbmcgPSB4O1xuXG4gICAgICAgICAgICAgIGdldEF0dHJzKCk7XG5cbiAgICAgICAgICAgICAgbWF5YmVOUyA9IGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIF9lbGVtZW50TmFtZSA9IGVsZW1lbnROYW1lO1xuXG4gICAgICAgIHcgPSBlbGVtZW50TmFtZS5pbmRleE9mKCc6Jyk7XG4gICAgICAgIGlmICh3ICE9PSAtMSkge1xuICAgICAgICAgIHhtbG5zID0gbnNNYXRyaXhbZWxlbWVudE5hbWUuc3Vic3RyaW5nKDAsIHcpXTtcblxuICAgICAgICAgIC8vIHByZWZpeCBnaXZlbjsgbmFtZXNwYWNlIG11c3QgZXhpc3RcbiAgICAgICAgICBpZiAoIXhtbG5zKSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlRXJyb3IoJ21pc3NpbmcgbmFtZXNwYWNlIG9uIDwnICsgX2VsZW1lbnROYW1lICsgJz4nKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBlbGVtZW50TmFtZSA9IGVsZW1lbnROYW1lLnN1YnN0cih3ICsgMSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgeG1sbnMgPSBuc01hdHJpeFsneG1sbnMnXTtcblxuICAgICAgICAgIC8vIGlmIG5vIGRlZmF1bHQgbmFtZXNwYWNlIGlzIGRlZmluZWQsXG4gICAgICAgICAgLy8gd2UnbGwgaW1wb3J0IHRoZSBlbGVtZW50IGFzIGFub255bW91cy5cbiAgICAgICAgICAvL1xuICAgICAgICAgIC8vIGl0IGlzIHVwIHRvIHVzZXJzIHRvIGNvcnJlY3QgdGhhdCB0byB0aGUgZG9jdW1lbnQgZGVmaW5lZFxuICAgICAgICAgIC8vIHRhcmdldE5hbWVzcGFjZSwgb3Igd2hhdGV2ZXIgdGhlaXIgdW5kZXJzYW5kaW5nIG9mIHRoZVxuICAgICAgICAgIC8vIFhNTCBzcGVjIG1hbmRhdGVzLlxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWRqdXN0IG5hbWVzcGFjZSBwcmVmaXhzIGFzIGNvbmZpZ3VyZWRcbiAgICAgICAgaWYgKHhtbG5zKSB7XG4gICAgICAgICAgZWxlbWVudE5hbWUgPSB4bWxucyArICc6JyArIGVsZW1lbnROYW1lO1xuICAgICAgICB9XG5cbiAgICAgIH1cblxuICAgICAgaWYgKHRhZ1N0YXJ0KSB7XG4gICAgICAgIGF0dHJzU3RhcnQgPSBxO1xuICAgICAgICBhdHRyc1N0cmluZyA9IHg7XG5cbiAgICAgICAgaWYgKG9uT3BlblRhZykge1xuICAgICAgICAgIGlmIChwcm94eSkge1xuICAgICAgICAgICAgb25PcGVuVGFnKGVsZW1lbnRQcm94eSwgZGVjb2RlRW50aXRpZXMsIHRhZ0VuZCwgZ2V0Q29udGV4dCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9uT3BlblRhZyhlbGVtZW50TmFtZSwgZ2V0QXR0cnMsIGRlY29kZUVudGl0aWVzLCB0YWdFbmQsIGdldENvbnRleHQpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChwYXJzZVN0b3ApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgfVxuXG4gICAgICBpZiAodGFnRW5kKSB7XG5cbiAgICAgICAgaWYgKG9uQ2xvc2VUYWcpIHtcbiAgICAgICAgICBvbkNsb3NlVGFnKHByb3h5ID8gZWxlbWVudFByb3h5IDogZWxlbWVudE5hbWUsIGRlY29kZUVudGl0aWVzLCB0YWdTdGFydCwgZ2V0Q29udGV4dCk7XG5cbiAgICAgICAgICBpZiAocGFyc2VTdG9wKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gcmVzdG9yZSBvbGQgbmFtZXNwYWNlXG4gICAgICAgIGlmIChpc05hbWVzcGFjZSkge1xuICAgICAgICAgIGlmICghdGFnU3RhcnQpIHtcbiAgICAgICAgICAgIG5zTWF0cml4ID0gbnNNYXRyaXhTdGFjay5wb3AoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgbnNNYXRyaXggPSBfbnNNYXRyaXg7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGogKz0gMTtcbiAgICB9XG4gIH0gLyoqIGVuZCBwYXJzZSAqL1xuXG59XG5cbmV4cG9ydCB7IFBhcnNlciwgZGVjb2RlRW50aXRpZXMgYXMgZGVjb2RlIH07XG4iLCJpbXBvcnQge1xuICBkb21pZnksXG4gIGNsYXNzZXMgYXMgZG9tQ2xhc3NlcyxcbiAgbWF0Y2hlcyBhcyBkb21NYXRjaGVzLFxuICBkZWxlZ2F0ZSBhcyBkb21EZWxlZ2F0ZSxcbiAgcXVlcnkgYXMgZG9tUXVlcnksXG4gIHF1ZXJ5QWxsIGFzIGRvbVF1ZXJ5QWxsLFxuICBldmVudCBhcyBkb21FdmVudCxcbiAgYXR0ciBhcyBkb21BdHRyXG59IGZyb20gJ21pbi1kb20nO1xuXG5pbXBvcnQge1xuICBmaWx0ZXIsXG4gIGFzc2lnblxufSBmcm9tICdtaW4tZGFzaCc7XG5cbmltcG9ydCBjcmVhdGVFbWl0dGVyIGZyb20gJ21pdHQnO1xuXG52YXIgREVGQVVMVF9PUFRJT05TID0ge1xuICBzY3JvbGxTeW1ib2xMZWZ0OiAn4oC5JyxcbiAgc2Nyb2xsU3ltYm9sUmlnaHQ6ICfigLonXG59O1xuXG5cbi8qKlxuICogVGhpcyBjb21wb25lbnQgYWRkcyB0aGUgZnVuY3Rpb25hbGl0eSB0byBzY3JvbGwgb3ZlciBhIGxpc3Qgb2YgdGFicy5cbiAqXG4gKiBJdCBhZGRzIHNjcm9sbCBidXR0b25zIG9uIHRoZSBsZWZ0IGFuZCByaWdodCBzaWRlIG9mIHRoZSB0YWJzIGNvbnRhaW5lclxuICogaWYgbm90IGFsbCB0YWJzIGFyZSB2aXNpYmxlLiBJdCBhbHNvIGFkZHMgYSBtb3VzZSB3aGVlbCBsaXN0ZW5lciBvbiB0aGVcbiAqIGNvbnRhaW5lci5cbiAqXG4gKiBJZiBlaXRoZXIgYSBidXR0b24gaXMgY2xpY2tlZCBvciB0aGUgbW91c2Ugd2hlZWwgaXMgdXNlZCBvdmVyIHRoZSB0YWJzLFxuICogYSAnc2Nyb2xsJyBldmVudCBpcyBiZWluZyBmaXJlZC4gVGhpcyBldmVudCBjb250YWlucyB0aGUgbm9kZSBlbGVtZW50c1xuICogb2YgdGhlIG5ldyBhbmQgb2xkIGFjdGl2ZSB0YWIsIGFuZCB0aGUgZGlyZWN0aW9uIGluIHdoaWNoIHRoZSB0YWIgaGFzXG4gKiBjaGFuZ2VkIHJlbGF0aXZlIHRvIHRoZSBvbGQgYWN0aXZlIHRhYi5cbiAqXG4gKiBAZXhhbXBsZTpcbiAqICgxKSBwcm92aWRlIGEgdGFicy1jb250YWluZXI6XG4gKlxuICogdmFyICRlbCA9IChcbiAqICAgPGRpdj5cbiAqICAgICA8IS0tIGJ1dHRvbiBhZGRlZCBieSBzY3JvbGxUYWJzIC0tPlxuICogICAgIDxzcGFuIGNsYXNzPVwic2Nyb2xsLXRhYnMtYnV0dG9uIHNjcm9sbC10YWJzLWxlZnRcIj48L3NwYW4+XG4gKiAgICAgPHVsIGNsYXNzPVwibXktdGFicy1jb250YWluZXJcIj5cbiAqICAgICAgIDxsaSBjbGFzcz1cIm15LXRhYiBpLWFtLWFjdGl2ZVwiPjwvbGk+XG4gKiAgICAgICA8bGkgY2xhc3M9XCJteS10YWJcIj48L2xpPlxuICogICAgICAgPGxpIGNsYXNzPVwibXktdGFiIGlnbm9yZS1tZVwiPjwvbGk+XG4gKiAgICAgPC91bD5cbiAqICAgICA8IS0tIGJ1dHRvbiBhZGRlZCBieSBzY3JvbGxUYWJzIC0tPlxuICogICAgIDxzcGFuIGNsYXNzPVwic2Nyb2xsLXRhYnMtYnV0dG9uIHNjcm9sbC10YWJzLXJpZ2h0XCI+PC9zcGFuPlxuICogICA8L2Rpdj5cbiAqICk7XG4gKlxuICpcbiAqICgyKSBpbml0aWFsaXplIHNjcm9sbFRhYnM6XG4gKlxuICogIHZhciBzY3JvbGxlciA9IHNjcm9sbFRhYnModGFiQmFyTm9kZSwge1xuICogICAgc2VsZWN0b3JzOiB7XG4gKiAgICAgIHRhYnNDb250YWluZXI6ICcubXktdGFicy1jb250YWluZXInLFxuICogICAgICB0YWI6ICcubXktdGFiJyxcbiAqICAgICAgaWdub3JlOiAnLmlnbm9yZS1tZScsXG4gKiAgICAgIGFjdGl2ZTogJy5pLWFtLWFjdGl2ZSdcbiAqICAgIH1cbiAqICB9KTtcbiAqXG4gKlxuICogKDMpIGxpc3RlbiB0byB0aGUgc2Nyb2xsIGV2ZW50OlxuICpcbiAqIHNjcm9sbGVyLm9uKCdzY3JvbGwnLCBmdW5jdGlvbihuZXdBY3RpdmVOb2RlLCBvbGRBY3RpdmVOb2RlLCBkaXJlY3Rpb24pIHtcbiAqICAgLy8gZGlyZWN0aW9uIGlzIGFueSBvZiAoLTE6IGxlZnQsIDE6IHJpZ2h0KVxuICogICAvLyBhY3RpdmF0ZSB0aGUgbmV3IGFjdGl2ZSB0YWJcbiAqIH0pO1xuICpcbiAqXG4gKiAoNCkgdXBkYXRlIHRoZSBzY3JvbGxlciBpZiB0YWJzIGNoYW5nZSBhbmQgb3IgdGhlIHRhYiBjb250YWluZXIgcmVzaXplczpcbiAqXG4gKiBzY3JvbGxlci51cGRhdGUoKTtcbiAqXG4gKlxuICogQHBhcmFtICB7RE9NRWxlbWVudH0gZWxcbiAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zLnNlbGVjdG9yc1xuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNlbGVjdG9ycy50YWJzQ29udGFpbmVyIHRoZSBjb250YWluZXIgYWxsIHRhYnMgYXJlIGNvbnRhaW5lZCBpblxuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNlbGVjdG9ycy50YWIgYSBzaW5nbGUgdGFiIGluc2lkZSB0aGUgdGFiIGNvbnRhaW5lclxuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNlbGVjdG9ycy5pZ25vcmUgdGFicyB0aGF0IHNob3VsZCBiZSBpZ25vcmVkIGR1cmluZyBzY3JvbGwgbGVmdC9yaWdodFxuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNlbGVjdG9ycy5hY3RpdmUgc2VsZWN0b3IgZm9yIHRoZSBjdXJyZW50IGFjdGl2ZSB0YWJcbiAqIEBwYXJhbSAge1N0cmluZ30gW29wdGlvbnMuc2Nyb2xsU3ltYm9sTGVmdF1cbiAqIEBwYXJhbSAge1N0cmluZ30gW29wdGlvbnMuc2Nyb2xsU3ltYm9sUmlnaHRdXG4gKi9cbmZ1bmN0aW9uIFNjcm9sbFRhYnMoJGVsLCBvcHRpb25zKSB7XG5cbiAgLy8gd2UgYXJlIGFuIGV2ZW50IGVtaXR0ZXJcbiAgYXNzaWduKHRoaXMsIGNyZWF0ZUVtaXR0ZXIoKSk7XG5cbiAgdGhpcy5vcHRpb25zID0gb3B0aW9ucyA9IGFzc2lnbih7fSwgREVGQVVMVF9PUFRJT05TLCBvcHRpb25zKTtcbiAgdGhpcy5jb250YWluZXIgPSAkZWw7XG5cbiAgdGhpcy5fY3JlYXRlU2Nyb2xsQnV0dG9ucygkZWwsIG9wdGlvbnMpO1xuXG4gIHRoaXMuX2JpbmRFdmVudHMoJGVsKTtcbn1cblxuXG4vKipcbiAqIENyZWF0ZSBhIGNsaWNrYWJsZSBzY3JvbGwgYnV0dG9uXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAqIEBwYXJhbSB7U3RyaW5nfSBvcHRpb25zLmNsYXNzTmFtZVxuICogQHBhcmFtIHtTdHJpbmd9IG9wdGlvbnMubGFiZWxcbiAqIEBwYXJhbSB7TnVtYmVyfSBvcHRpb25zLmRpcmVjdGlvblxuICpcbiAqIEByZXR1cm4ge0RPTUVsZW1lbnR9IFRoZSBjcmVhdGVkIHNjcm9sbCBidXR0b24gbm9kZVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5fY3JlYXRlQnV0dG9uID0gZnVuY3Rpb24ocGFyZW50Tm9kZSwgb3B0aW9ucykge1xuXG4gIHZhciBjbGFzc05hbWUgPSBvcHRpb25zLmNsYXNzTmFtZSxcbiAgICAgIGRpcmVjdGlvbiA9IG9wdGlvbnMuZGlyZWN0aW9uO1xuXG5cbiAgdmFyIGJ1dHRvbiA9IGRvbVF1ZXJ5KCcuJyArIGNsYXNzTmFtZSwgcGFyZW50Tm9kZSk7XG5cbiAgaWYgKCFidXR0b24pIHtcbiAgICBidXR0b24gPSBkb21pZnkoJzxzcGFuIGNsYXNzPVwic2Nyb2xsLXRhYnMtYnV0dG9uICcgKyBjbGFzc05hbWUgKyAnXCI+JyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMubGFiZWwgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvc3Bhbj4nKTtcblxuICAgIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGJ1dHRvbiwgcGFyZW50Tm9kZS5jaGlsZE5vZGVzWzBdKTtcbiAgfVxuXG4gIGRvbUF0dHIoYnV0dG9uLCAnZGF0YS1kaXJlY3Rpb24nLCBkaXJlY3Rpb24pO1xuXG4gIHJldHVybiBidXR0b247XG59O1xuXG4vKipcbiAqIENyZWF0ZSBib3RoIHNjcm9sbCBidXR0b25zXG4gKlxuICogQHBhcmFtICB7RE9NRWxlbWVudH0gcGFyZW50Tm9kZVxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXG4gKiBAcGFyYW0gIHtTdHJpbmd9IG9wdGlvbnMuc2Nyb2xsU3ltYm9sTGVmdFxuICogQHBhcmFtICB7U3RyaW5nfSBvcHRpb25zLnNjcm9sbFN5bWJvbFJpZ2h0XG4gKi9cblNjcm9sbFRhYnMucHJvdG90eXBlLl9jcmVhdGVTY3JvbGxCdXR0b25zID0gZnVuY3Rpb24ocGFyZW50Tm9kZSwgb3B0aW9ucykge1xuXG4gIC8vIENyZWF0ZSBhIGJ1dHRvbiB0aGF0IHNjcm9sbHMgdG8gdGhlIHRhYiBsZWZ0IHRvIHRoZSBjdXJyZW50bHkgYWN0aXZlIHRhYlxuICB0aGlzLl9jcmVhdGVCdXR0b24ocGFyZW50Tm9kZSwge1xuICAgIGNsYXNzTmFtZTogJ3Njcm9sbC10YWJzLWxlZnQnLFxuICAgIGxhYmVsOiBvcHRpb25zLnNjcm9sbFN5bWJvbExlZnQsXG4gICAgZGlyZWN0aW9uOiAtMVxuICB9KTtcblxuICAvLyBDcmVhdGUgYSBidXR0b24gdGhhdCBzY3JvbGxzIHRvIHRoZSB0YWIgcmlnaHQgdG8gdGhlIGN1cnJlbnRseSBhY3RpdmUgdGFiXG4gIHRoaXMuX2NyZWF0ZUJ1dHRvbihwYXJlbnROb2RlLCB7XG4gICAgY2xhc3NOYW1lOiAnc2Nyb2xsLXRhYnMtcmlnaHQnLFxuICAgIGxhYmVsOiBvcHRpb25zLnNjcm9sbFN5bWJvbFJpZ2h0LFxuICAgIGRpcmVjdGlvbjogMVxuICB9KTtcbn07XG5cbi8qKlxuICogR2V0IHRoZSBjdXJyZW50IGFjdGl2ZSB0YWJcbiAqXG4gKiBAcmV0dXJuIHtET01FbGVtZW50fVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5nZXRBY3RpdmVUYWJOb2RlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBkb21RdWVyeSh0aGlzLm9wdGlvbnMuc2VsZWN0b3JzLmFjdGl2ZSwgdGhpcy5jb250YWluZXIpO1xufTtcblxuXG4vKipcbiAqIEdldCB0aGUgY29udGFpbmVyIGFsbCB0YWJzIGFyZSBjb250YWluZWQgaW5cbiAqXG4gKiBAcmV0dXJuIHtET01FbGVtZW50fVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5nZXRUYWJzQ29udGFpbmVyTm9kZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gZG9tUXVlcnkodGhpcy5vcHRpb25zLnNlbGVjdG9ycy50YWJzQ29udGFpbmVyLCB0aGlzLmNvbnRhaW5lcik7XG59O1xuXG5cbi8qKlxuICogR2V0IGFsbCB0YWJzICh2aXNpYmxlIGFuZCBpbnZpc2libGUgb25lcylcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxET01FbGVtZW50Pn1cbiAqL1xuU2Nyb2xsVGFicy5wcm90b3R5cGUuZ2V0QWxsVGFiTm9kZXMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGRvbVF1ZXJ5QWxsKHRoaXMub3B0aW9ucy5zZWxlY3RvcnMudGFiLCB0aGlzLmNvbnRhaW5lcik7XG59O1xuXG5cbi8qKlxuICogR2V0cyBhbGwgdGFicyB0aGF0IGRvbid0IGhhdmUgdGhlIGlnbm9yZSBjbGFzcyBzZXRcbiAqXG4gKiBAcmV0dXJuIHtBcnJheTxET01FbGVtZW50Pn1cbiAqL1xuU2Nyb2xsVGFicy5wcm90b3R5cGUuZ2V0VmlzaWJsZVRhYnMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGFsbFRhYnMgPSB0aGlzLmdldEFsbFRhYk5vZGVzKCk7XG5cbiAgdmFyIGlnbm9yZSA9IHRoaXMub3B0aW9ucy5zZWxlY3RvcnMuaWdub3JlO1xuXG4gIHJldHVybiBmaWx0ZXIoYWxsVGFicywgZnVuY3Rpb24odGFiTm9kZSkge1xuICAgIHJldHVybiAhZG9tTWF0Y2hlcyh0YWJOb2RlLCBpZ25vcmUpO1xuICB9KTtcbn07XG5cblxuLyoqXG4gKiBHZXQgYSB0YWIgcmVsYXRpdmUgdG8gYSByZWZlcmVuY2UgdGFiLlxuICpcbiAqIEBwYXJhbSAge0RPTUVsZW1lbnR9IHJlZmVyZW5jZVRhYk5vZGVcbiAqIEBwYXJhbSAge051bWJlcn0gbiBnZXRzIHRoZSBudGggdGFiIG5leHQgb3IgcHJldmlvdXMgdG8gdGhlIHJlZmVyZW5jZSB0YWJcbiAqXG4gKiBAcmV0dXJuIHtET01FbGVtZW50fVxuICpcbiAqIEBleGFtcGxlOlxuICogVmlzaWJsZSB0YWJzOiBbIEEgfCBCIHwgQyB8IEQgfCBFIF1cbiAqIEFzc3VtZSB0YWIgJ0MnIGlzIHRoZSByZWZlcmVuY2UgdGFiOlxuICogSWYgZGlyZWN0aW9uID09PSAtMSwgaXQgcmV0dXJucyB0YWIgJ0InLFxuICogaWYgZGlyZWN0aW9uID09PSAgMiwgaXQgcmV0dXJucyB0YWIgJ0UnXG4gKi9cblNjcm9sbFRhYnMucHJvdG90eXBlLmdldEFkamFjZW50VGFiID0gZnVuY3Rpb24ocmVmZXJlbmNlVGFiTm9kZSwgbikge1xuICB2YXIgdmlzaWJsZVRhYnMgPSB0aGlzLmdldFZpc2libGVUYWJzKCk7XG5cbiAgdmFyIGluZGV4ID0gdmlzaWJsZVRhYnMuaW5kZXhPZihyZWZlcmVuY2VUYWJOb2RlKTtcblxuICByZXR1cm4gdmlzaWJsZVRhYnNbaW5kZXggKyBuXTtcbn07XG5cblNjcm9sbFRhYnMucHJvdG90eXBlLl9iaW5kRXZlbnRzID0gZnVuY3Rpb24obm9kZSkge1xuICB0aGlzLl9iaW5kV2hlZWxFdmVudChub2RlKTtcbiAgdGhpcy5fYmluZFRhYkNsaWNrRXZlbnRzKG5vZGUpO1xuICB0aGlzLl9iaW5kU2Nyb2xsQnV0dG9uRXZlbnRzKG5vZGUpO1xufTtcblxuLyoqXG4gKiAgQmluZCBhIGNsaWNrIGxpc3RlbmVyIHRvIGEgRE9NIG5vZGUuXG4gKiAgTWFrZSBzdXJlIGEgdGFiIGxpbmsgaXMgZW50aXJlbHkgdmlzaWJsZSBhZnRlciBvbkNsaWNrLlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5fYmluZFRhYkNsaWNrRXZlbnRzID0gZnVuY3Rpb24obm9kZSkge1xuICB2YXIgc2VsZWN0b3IgPSB0aGlzLm9wdGlvbnMuc2VsZWN0b3JzLnRhYjtcblxuICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgZG9tRGVsZWdhdGUuYmluZChub2RlLCBzZWxlY3RvciwgJ2NsaWNrJywgZnVuY3Rpb24gb25DbGljayhldmVudCkge1xuICAgIHNlbGYuc2Nyb2xsVG9UYWJOb2RlKGV2ZW50LmRlbGVnYXRlVGFyZ2V0KTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuICogQmluZCB0aGUgd2hlZWwgZXZlbnQgbGlzdGVuZXIgdG8gYSBET00gbm9kZVxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gbm9kZVxuICovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5fYmluZFdoZWVsRXZlbnQgPSBmdW5jdGlvbihub2RlKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICBkb21FdmVudC5iaW5kKG5vZGUsICd3aGVlbCcsIGZ1bmN0aW9uKGUpIHtcblxuICAgIC8vIHNjcm9sbCBkaXJlY3Rpb24gKC0xOiBsZWZ0LCAxOiByaWdodClcbiAgICB2YXIgZGlyZWN0aW9uID0gTWF0aC5zaWduKGUuZGVsdGFZKTtcblxuICAgIHZhciBvbGRBY3RpdmVUYWIgPSBzZWxmLmdldEFjdGl2ZVRhYk5vZGUoKTtcblxuICAgIHZhciBuZXdBY3RpdmVUYWIgPSBzZWxmLmdldEFkamFjZW50VGFiKG9sZEFjdGl2ZVRhYiwgZGlyZWN0aW9uKTtcblxuICAgIGlmIChuZXdBY3RpdmVUYWIpIHtcbiAgICAgIHNlbGYuc2Nyb2xsVG9UYWJOb2RlKG5ld0FjdGl2ZVRhYik7XG4gICAgICBzZWxmLmVtaXQoJ3Njcm9sbCcsIG5ld0FjdGl2ZVRhYiwgb2xkQWN0aXZlVGFiLCBkaXJlY3Rpb24pO1xuICAgIH1cblxuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgfSk7XG59O1xuXG4vKipcbiAqIEJpbmQgc2Nyb2xsIGJ1dHRvbiBldmVudHMgdG8gYSBET00gbm9kZVxuICpcbiAqIEBwYXJhbSAge0RPTUVsZW1lbnR9IG5vZGVcbiAqL1xuU2Nyb2xsVGFicy5wcm90b3R5cGUuX2JpbmRTY3JvbGxCdXR0b25FdmVudHMgPSBmdW5jdGlvbihub2RlKSB7XG5cbiAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gIGRvbURlbGVnYXRlLmJpbmQobm9kZSwgJy5zY3JvbGwtdGFicy1idXR0b24nLCAnY2xpY2snLCBmdW5jdGlvbihldmVudCkge1xuXG4gICAgdmFyIHRhcmdldCA9IGV2ZW50LmRlbGVnYXRlVGFyZ2V0O1xuXG4gICAgLy8gZGF0YS1kaXJlY3Rpb24gaXMgZWl0aGVyIC0xIG9yIDFcbiAgICB2YXIgZGlyZWN0aW9uID0gcGFyc2VJbnQoZG9tQXR0cih0YXJnZXQsICdkYXRhLWRpcmVjdGlvbicpLCAxMCk7XG5cbiAgICB2YXIgb2xkQWN0aXZlVGFiTm9kZSA9IHNlbGYuZ2V0QWN0aXZlVGFiTm9kZSgpO1xuXG4gICAgdmFyIG5ld0FjdGl2ZVRhYk5vZGUgPSBzZWxmLmdldEFkamFjZW50VGFiKG9sZEFjdGl2ZVRhYk5vZGUsIGRpcmVjdGlvbik7XG5cbiAgICBpZiAobmV3QWN0aXZlVGFiTm9kZSkge1xuICAgICAgc2VsZi5zY3JvbGxUb1RhYk5vZGUobmV3QWN0aXZlVGFiTm9kZSk7XG4gICAgICBzZWxmLmVtaXQoJ3Njcm9sbCcsIG5ld0FjdGl2ZVRhYk5vZGUsIG9sZEFjdGl2ZVRhYk5vZGUsIGRpcmVjdGlvbik7XG4gICAgfVxuXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfSk7XG59O1xuXG5cbi8qKlxuKiBTY3JvbGwgdG8gYSB0YWIgaWYgaXQgaXMgbm90IGVudGlyZWx5IHZpc2libGVcbipcbiogQHBhcmFtICB7RE9NRWxlbWVudH0gdGFiTm9kZSB0YWIgbm9kZSB0byBzY3JvbGwgdG9cbiovXG5TY3JvbGxUYWJzLnByb3RvdHlwZS5zY3JvbGxUb1RhYk5vZGUgPSBmdW5jdGlvbih0YWJOb2RlKSB7XG4gIGlmICghdGFiTm9kZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHZhciB0YWJzQ29udGFpbmVyTm9kZSA9IHRhYk5vZGUucGFyZW50Tm9kZTtcblxuICB2YXIgdGFiV2lkdGggPSB0YWJOb2RlLm9mZnNldFdpZHRoLFxuICAgICAgdGFiT2Zmc2V0TGVmdCA9IHRhYk5vZGUub2Zmc2V0TGVmdCxcbiAgICAgIHRhYk9mZnNldFJpZ2h0ID0gdGFiT2Zmc2V0TGVmdCArIHRhYldpZHRoLFxuICAgICAgY29udGFpbmVyV2lkdGggPSB0YWJzQ29udGFpbmVyTm9kZS5vZmZzZXRXaWR0aCxcbiAgICAgIGNvbnRhaW5lclNjcm9sbExlZnQgPSB0YWJzQ29udGFpbmVyTm9kZS5zY3JvbGxMZWZ0O1xuXG4gIGlmIChjb250YWluZXJTY3JvbGxMZWZ0ID4gdGFiT2Zmc2V0TGVmdCkge1xuICAgIC8vIHNjcm9sbCB0byB0aGUgbGVmdCwgaWYgdGhlIHRhYiBpcyBvdmVyZmxvd2luZyBvbiB0aGUgbGVmdCBzaWRlXG4gICAgdGFic0NvbnRhaW5lck5vZGUuc2Nyb2xsTGVmdCA9IDA7XG4gIH0gZWxzZSBpZiAodGFiT2Zmc2V0UmlnaHQgPiBjb250YWluZXJXaWR0aCkge1xuICAgIC8vIHNjcm9sbCB0byB0aGUgcmlnaHQsIGlmIHRoZSB0YWIgaXMgb3ZlcmZsb3dpbmcgb24gdGhlIHJpZ2h0IHNpZGVcbiAgICB0YWJzQ29udGFpbmVyTm9kZS5zY3JvbGxMZWZ0ID0gdGFiT2Zmc2V0UmlnaHQgLSBjb250YWluZXJXaWR0aDtcbiAgfVxufTtcblxuXG4vKipcbiAqIFJlYWN0IG9uIHRhYiBjaGFuZ2VzIGZyb20gb3V0c2lkZSAocmVzaXplL3Nob3cvaGlkZS9hZGQvcmVtb3ZlKSxcbiAqIHVwZGF0ZSBzY3JvbGwgYnV0dG9uIHZpc2liaWxpdHkuXG4gKi9cblNjcm9sbFRhYnMucHJvdG90eXBlLnVwZGF0ZSA9IGZ1bmN0aW9uKCkge1xuXG4gIHZhciB0YWJzQ29udGFpbmVyTm9kZSA9IHRoaXMuZ2V0VGFic0NvbnRhaW5lck5vZGUoKTtcblxuICAvLyBjaGVjayBpZiB0YWJzIGZpdCBpbiBjb250YWluZXJcbiAgdmFyIG92ZXJmbG93ID0gdGFic0NvbnRhaW5lck5vZGUuc2Nyb2xsV2lkdGggPiB0YWJzQ29udGFpbmVyTm9kZS5vZmZzZXRXaWR0aDtcblxuICAvLyBUT0RPKG5pa2t1KTogZGlzdGluZ3Vpc2ggb3ZlcmZsb3cgbGVmdCAvIG92ZXJmbG93IHJpZ2h0P1xuICB2YXIgb3ZlcmZsb3dDbGFzcyA9ICdzY3JvbGwtdGFicy1vdmVyZmxvdyc7XG5cbiAgZG9tQ2xhc3Nlcyh0aGlzLmNvbnRhaW5lcikudG9nZ2xlKG92ZXJmbG93Q2xhc3MsIG92ZXJmbG93KTtcblxuICBpZiAob3ZlcmZsb3cpIHtcbiAgICAvLyBtYWtlIHN1cmUgdGhlIGN1cnJlbnQgYWN0aXZlIHRhYiBpcyBhbHdheXMgdmlzaWJsZVxuICAgIHRoaXMuc2Nyb2xsVG9UYWJOb2RlKHRoaXMuZ2V0QWN0aXZlVGFiTm9kZSgpKTtcbiAgfVxufTtcblxuXG4vLyBleHBvcnRzIC8vLy8vLy8vLy8vLy8vLy9cblxuLyoqXG4gKiBDcmVhdGUgYSBzY3JvbGxUYWJzIGluc3RhbmNlIG9uIHRoZSBnaXZlbiBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gJGVsXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICpcbiAqIEByZXR1cm4ge1Njcm9sbFRhYnN9XG4gKi9cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGNyZWF0ZSgkZWwsIG9wdGlvbnMpIHtcblxuICB2YXIgc2Nyb2xsVGFicyA9IGdldCgkZWwpO1xuXG4gIGlmICghc2Nyb2xsVGFicykge1xuICAgIHNjcm9sbFRhYnMgPSBuZXcgU2Nyb2xsVGFicygkZWwsIG9wdGlvbnMpO1xuXG4gICAgJGVsLl9fc2Nyb2xsVGFicyA9IHNjcm9sbFRhYnM7XG4gIH1cblxuICByZXR1cm4gc2Nyb2xsVGFicztcbn1cblxuXG4vKipcbiAqIFJldHVybiB0aGUgc2Nyb2xsVGFicyBpbnN0YW5jZSB0aGF0IGhhcyBiZWVuIHByZXZpb3VzbHlcbiAqIGluaXRpYWxpemVkIG9uIHRoZSBlbGVtZW50LlxuICpcbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gJGVsXG4gKiBAcmV0dXJuIHtTY3JvbGxUYWJzfVxuICovXG5mdW5jdGlvbiBnZXQoJGVsKSB7XG4gIHJldHVybiAkZWwuX19zY3JvbGxUYWJzO1xufVxuXG5jcmVhdGUuZ2V0ID0gZ2V0OyIsIid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBDYWxjdWxhdGUgdGhlIHNlbGVjdGlvbiB1cGRhdGUgZm9yIHRoZSBnaXZlblxuICogY3VycmVudCBhbmQgbmV3IGlucHV0IHZhbHVlcy5cbiAqXG4gKiBAcGFyYW0ge09iamVjdH0gY3VycmVudFNlbGVjdGlvbiBhcyB7c3RhcnQsIGVuZH1cbiAqIEBwYXJhbSB7U3RyaW5nfSBjdXJyZW50VmFsdWVcbiAqIEBwYXJhbSB7U3RyaW5nfSBuZXdWYWx1ZVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gbmV3U2VsZWN0aW9uIGFzIHtzdGFydCwgZW5kfVxuICovXG5mdW5jdGlvbiBjYWxjdWxhdGVVcGRhdGUoY3VycmVudFNlbGVjdGlvbiwgY3VycmVudFZhbHVlLCBuZXdWYWx1ZSkge1xuXG4gIHZhciBjdXJyZW50Q3Vyc29yID0gY3VycmVudFNlbGVjdGlvbi5zdGFydCxcbiAgICAgIG5ld0N1cnNvciA9IGN1cnJlbnRDdXJzb3IsXG4gICAgICBkaWZmID0gbmV3VmFsdWUubGVuZ3RoIC0gY3VycmVudFZhbHVlLmxlbmd0aCxcbiAgICAgIGlkeDtcblxuICB2YXIgbGVuZ3RoRGVsdGEgPSBuZXdWYWx1ZS5sZW5ndGggLSBjdXJyZW50VmFsdWUubGVuZ3RoO1xuXG4gIHZhciBjdXJyZW50VGFpbCA9IGN1cnJlbnRWYWx1ZS5zdWJzdHJpbmcoY3VycmVudEN1cnNvcik7XG5cbiAgLy8gY2hlY2sgaWYgd2UgY2FuIHJlbW92ZSBjb21tb24gZW5kaW5nIGZyb20gdGhlIGVxdWF0aW9uXG4gIC8vIHRvIGJlIGFibGUgdG8gcHJvcGVybHkgZGV0ZWN0IGEgc2VsZWN0aW9uIGNoYW5nZSBmb3JcbiAgLy8gdGhlIGZvbGxvd2luZyBzY2VuYXJpb3M6XG4gIC8vXG4gIC8vICAqIChBQUFUVFR8VEYpID0+IChBQUFUfFRGKVxuICAvLyAgKiAoQUFBVHxURikgPT4gIChBQUFUVFR8VEYpXG4gIC8vXG4gIGlmIChuZXdWYWx1ZS5sYXN0SW5kZXhPZihjdXJyZW50VGFpbCkgPT09IG5ld1ZhbHVlLmxlbmd0aCAtIGN1cnJlbnRUYWlsLmxlbmd0aCkge1xuICAgIGN1cnJlbnRWYWx1ZSA9IGN1cnJlbnRWYWx1ZS5zdWJzdHJpbmcoMCwgY3VycmVudFZhbHVlLmxlbmd0aCAtIGN1cnJlbnRUYWlsLmxlbmd0aCk7XG4gICAgbmV3VmFsdWUgPSBuZXdWYWx1ZS5zdWJzdHJpbmcoMCwgbmV3VmFsdWUubGVuZ3RoIC0gY3VycmVudFRhaWwubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIGRpZmZcbiAgdmFyIGRpZmYgPSBjcmVhdGVEaWZmKGN1cnJlbnRWYWx1ZSwgbmV3VmFsdWUpO1xuXG4gIGlmIChkaWZmKSB7XG4gICAgaWYgKGRpZmYudHlwZSA9PT0gJ3JlbW92ZScpIHtcbiAgICAgIG5ld0N1cnNvciA9IGRpZmYubmV3U3RhcnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0N1cnNvciA9IGRpZmYubmV3RW5kO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByYW5nZShuZXdDdXJzb3IpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNhbGN1bGF0ZVVwZGF0ZTtcblxuXG5mdW5jdGlvbiBjcmVhdGVEaWZmKGN1cnJlbnRWYWx1ZSwgbmV3VmFsdWUpIHtcblxuICB2YXIgaW5zZXJ0O1xuXG4gIHZhciBsX3N0ciwgbF9jaGFyLCBsX2lkeCA9IDAsXG4gICAgICBzX3N0ciwgc19jaGFyLCBzX2lkeCA9IDA7XG5cbiAgaWYgKG5ld1ZhbHVlLmxlbmd0aCA+IGN1cnJlbnRWYWx1ZS5sZW5ndGgpIHtcbiAgICBsX3N0ciA9IG5ld1ZhbHVlO1xuICAgIHNfc3RyID0gY3VycmVudFZhbHVlO1xuICB9IGVsc2Uge1xuICAgIGxfc3RyID0gY3VycmVudFZhbHVlO1xuICAgIHNfc3RyID0gbmV3VmFsdWU7XG4gIH1cblxuICAvLyBhc3N1bWUgdGhlcmUgd2lsbCBiZSBvbmx5IG9uZSBpbnNlcnQgLyByZW1vdmUgYW5kXG4gIC8vIGRldGVjdCB0aGF0IF9maXJzdF8gZWRpdCBvcGVyYXRpb24gb25seVxuICB3aGlsZSAobF9pZHggPCBsX3N0ci5sZW5ndGgpIHtcblxuICAgIGxfY2hhciA9IGxfc3RyLmNoYXJBdChsX2lkeCk7XG4gICAgc19jaGFyID0gc19zdHIuY2hhckF0KHNfaWR4KTtcblxuICAgIC8vIGNoYXJzIG5vIG5vdCBlcXVhbFxuICAgIGlmIChsX2NoYXIgIT09IHNfY2hhcikge1xuXG4gICAgICBpZiAoIWluc2VydCkge1xuICAgICAgICBpbnNlcnQgPSB7XG4gICAgICAgICAgbF9zdGFydDogbF9pZHgsXG4gICAgICAgICAgc19zdGFydDogc19pZHhcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgbF9pZHgrKztcbiAgICB9XG5cbiAgICAvLyBjaGFycyBlcXVhbCAoYWdhaW4/KVxuICAgIGVsc2Uge1xuXG4gICAgICBpZiAoaW5zZXJ0ICYmICFpbnNlcnQuY29tcGxldGUpIHtcbiAgICAgICAgaW5zZXJ0LmxfZW5kID0gbF9pZHg7XG4gICAgICAgIGluc2VydC5zX2VuZCA9IHNfaWR4O1xuICAgICAgICBpbnNlcnQuY29tcGxldGUgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBzX2lkeCsrO1xuICAgICAgbF9pZHgrKztcbiAgICB9XG4gIH1cblxuICBpZiAoaW5zZXJ0ICYmICFpbnNlcnQuY29tcGxldGUpIHtcbiAgICBpbnNlcnQuY29tcGxldGUgPSB0cnVlO1xuICAgIGluc2VydC5zX2VuZCA9IHNfc3RyLmxlbmd0aDtcbiAgICBpbnNlcnQubF9lbmQgPSBsX3N0ci5sZW5ndGg7XG4gIH1cblxuICAvLyBubyBkaWZmXG4gIGlmICghaW5zZXJ0KSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKG5ld1ZhbHVlLmxlbmd0aCA+IGN1cnJlbnRWYWx1ZS5sZW5ndGgpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmV3U3RhcnQ6IGluc2VydC5sX3N0YXJ0LFxuICAgICAgbmV3RW5kOiBpbnNlcnQubF9lbmQsXG4gICAgICB0eXBlOiAnYWRkJ1xuICAgIH07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5ld1N0YXJ0OiBpbnNlcnQuc19zdGFydCxcbiAgICAgIG5ld0VuZDogaW5zZXJ0LnNfZW5kLFxuICAgICAgdHlwZTogbmV3VmFsdWUubGVuZ3RoIDwgY3VycmVudFZhbHVlLmxlbmd0aCA/ICdyZW1vdmUnIDogJ3JlcGxhY2UnXG4gICAgfTtcbiAgfVxufVxuXG4vKipcbiAqIFV0aWxpdHkgbWV0aG9kIGZvciBjcmVhdGluZyBhIG5ldyBzZWxlY3Rpb24gcmFuZ2Uge3N0YXJ0LCBlbmR9IG9iamVjdC5cbiAqXG4gKiBAcGFyYW0ge051bWJlcn0gc3RhcnRcbiAqIEBwYXJhbSB7TnVtYmVyfSBbZW5kXVxuICpcbiAqIEByZXR1cm4ge09iamVjdH0gc2VsZWN0aW9uIHJhbmdlIGFzIHtzdGFydCwgZW5kfVxuICovXG5mdW5jdGlvbiByYW5nZShzdGFydCwgZW5kKSB7XG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IHN0YXJ0LFxuICAgIGVuZDogZW5kID09PSB1bmRlZmluZWQgPyBzdGFydCA6IGVuZFxuICB9O1xufVxuXG5tb2R1bGUuZXhwb3J0cy5yYW5nZSA9IHJhbmdlO1xuXG5cbmZ1bmN0aW9uIHNwbGl0U3RyKHN0ciwgcG9zaXRpb24pIHtcbiAgcmV0dXJuIHtcbiAgICBiZWZvcmU6IHN0ci5zdWJzdHJpbmcoMCwgcG9zaXRpb24pLFxuICAgIGFmdGVyOiBzdHIuc3Vic3RyaW5nKHBvc2l0aW9uKVxuICB9O1xufSIsImZ1bmN0aW9uIGVuc3VyZUltcG9ydGVkKGVsZW1lbnQsIHRhcmdldCkge1xuXG4gIGlmIChlbGVtZW50Lm93bmVyRG9jdW1lbnQgIT09IHRhcmdldC5vd25lckRvY3VtZW50KSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIG1heSBmYWlsIG9uIHdlYmtpdFxuICAgICAgcmV0dXJuIHRhcmdldC5vd25lckRvY3VtZW50LmltcG9ydE5vZGUoZWxlbWVudCwgdHJ1ZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gaWdub3JlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG5cbi8qKlxuICogYXBwZW5kVG8gdXRpbGl0eVxuICovXG5cbi8qKlxuICogQXBwZW5kIGEgbm9kZSB0byBhIHRhcmdldCBlbGVtZW50IGFuZCByZXR1cm4gdGhlIGFwcGVuZGVkIG5vZGUuXG4gKlxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gZWxlbWVudFxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gdGFyZ2V0XG4gKlxuICogQHJldHVybiB7U1ZHRWxlbWVudH0gdGhlIGFwcGVuZGVkIG5vZGVcbiAqL1xuZnVuY3Rpb24gYXBwZW5kVG8oZWxlbWVudCwgdGFyZ2V0KSB7XG4gIHJldHVybiB0YXJnZXQuYXBwZW5kQ2hpbGQoZW5zdXJlSW1wb3J0ZWQoZWxlbWVudCwgdGFyZ2V0KSk7XG59XG5cbi8qKlxuICogYXBwZW5kIHV0aWxpdHlcbiAqL1xuXG4vKipcbiAqIEFwcGVuZCBhIG5vZGUgdG8gYW4gZWxlbWVudFxuICpcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IGVsZW1lbnRcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IG5vZGVcbiAqXG4gKiBAcmV0dXJuIHtTVkdFbGVtZW50fSB0aGUgZWxlbWVudFxuICovXG5mdW5jdGlvbiBhcHBlbmQodGFyZ2V0LCBub2RlKSB7XG4gIGFwcGVuZFRvKG5vZGUsIHRhcmdldCk7XG4gIHJldHVybiB0YXJnZXQ7XG59XG5cbi8qKlxuICogYXR0cmlidXRlIGFjY2Vzc29yIHV0aWxpdHlcbiAqL1xuXG52YXIgTEVOR1RIX0FUVFIgPSAyO1xuXG52YXIgQ1NTX1BST1BFUlRJRVMgPSB7XG4gICdhbGlnbm1lbnQtYmFzZWxpbmUnOiAxLFxuICAnYmFzZWxpbmUtc2hpZnQnOiAxLFxuICAnY2xpcCc6IDEsXG4gICdjbGlwLXBhdGgnOiAxLFxuICAnY2xpcC1ydWxlJzogMSxcbiAgJ2NvbG9yJzogMSxcbiAgJ2NvbG9yLWludGVycG9sYXRpb24nOiAxLFxuICAnY29sb3ItaW50ZXJwb2xhdGlvbi1maWx0ZXJzJzogMSxcbiAgJ2NvbG9yLXByb2ZpbGUnOiAxLFxuICAnY29sb3ItcmVuZGVyaW5nJzogMSxcbiAgJ2N1cnNvcic6IDEsXG4gICdkaXJlY3Rpb24nOiAxLFxuICAnZGlzcGxheSc6IDEsXG4gICdkb21pbmFudC1iYXNlbGluZSc6IDEsXG4gICdlbmFibGUtYmFja2dyb3VuZCc6IDEsXG4gICdmaWxsJzogMSxcbiAgJ2ZpbGwtb3BhY2l0eSc6IDEsXG4gICdmaWxsLXJ1bGUnOiAxLFxuICAnZmlsdGVyJzogMSxcbiAgJ2Zsb29kLWNvbG9yJzogMSxcbiAgJ2Zsb29kLW9wYWNpdHknOiAxLFxuICAnZm9udCc6IDEsXG4gICdmb250LWZhbWlseSc6IDEsXG4gICdmb250LXNpemUnOiBMRU5HVEhfQVRUUixcbiAgJ2ZvbnQtc2l6ZS1hZGp1c3QnOiAxLFxuICAnZm9udC1zdHJldGNoJzogMSxcbiAgJ2ZvbnQtc3R5bGUnOiAxLFxuICAnZm9udC12YXJpYW50JzogMSxcbiAgJ2ZvbnQtd2VpZ2h0JzogMSxcbiAgJ2dseXBoLW9yaWVudGF0aW9uLWhvcml6b250YWwnOiAxLFxuICAnZ2x5cGgtb3JpZW50YXRpb24tdmVydGljYWwnOiAxLFxuICAnaW1hZ2UtcmVuZGVyaW5nJzogMSxcbiAgJ2tlcm5pbmcnOiAxLFxuICAnbGV0dGVyLXNwYWNpbmcnOiAxLFxuICAnbGlnaHRpbmctY29sb3InOiAxLFxuICAnbWFya2VyJzogMSxcbiAgJ21hcmtlci1lbmQnOiAxLFxuICAnbWFya2VyLW1pZCc6IDEsXG4gICdtYXJrZXItc3RhcnQnOiAxLFxuICAnbWFzayc6IDEsXG4gICdvcGFjaXR5JzogMSxcbiAgJ292ZXJmbG93JzogMSxcbiAgJ3BvaW50ZXItZXZlbnRzJzogMSxcbiAgJ3NoYXBlLXJlbmRlcmluZyc6IDEsXG4gICdzdG9wLWNvbG9yJzogMSxcbiAgJ3N0b3Atb3BhY2l0eSc6IDEsXG4gICdzdHJva2UnOiAxLFxuICAnc3Ryb2tlLWRhc2hhcnJheSc6IDEsXG4gICdzdHJva2UtZGFzaG9mZnNldCc6IDEsXG4gICdzdHJva2UtbGluZWNhcCc6IDEsXG4gICdzdHJva2UtbGluZWpvaW4nOiAxLFxuICAnc3Ryb2tlLW1pdGVybGltaXQnOiAxLFxuICAnc3Ryb2tlLW9wYWNpdHknOiAxLFxuICAnc3Ryb2tlLXdpZHRoJzogTEVOR1RIX0FUVFIsXG4gICd0ZXh0LWFuY2hvcic6IDEsXG4gICd0ZXh0LWRlY29yYXRpb24nOiAxLFxuICAndGV4dC1yZW5kZXJpbmcnOiAxLFxuICAndW5pY29kZS1iaWRpJzogMSxcbiAgJ3Zpc2liaWxpdHknOiAxLFxuICAnd29yZC1zcGFjaW5nJzogMSxcbiAgJ3dyaXRpbmctbW9kZSc6IDFcbn07XG5cblxuZnVuY3Rpb24gZ2V0QXR0cmlidXRlKG5vZGUsIG5hbWUpIHtcbiAgaWYgKENTU19QUk9QRVJUSUVTW25hbWVdKSB7XG4gICAgcmV0dXJuIG5vZGUuc3R5bGVbbmFtZV07XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5vZGUuZ2V0QXR0cmlidXRlTlMobnVsbCwgbmFtZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0QXR0cmlidXRlKG5vZGUsIG5hbWUsIHZhbHVlKSB7XG4gIHZhciBoeXBoZW5hdGVkID0gbmFtZS5yZXBsYWNlKC8oW2Etel0pKFtBLVpdKS9nLCAnJDEtJDInKS50b0xvd2VyQ2FzZSgpO1xuXG4gIHZhciB0eXBlID0gQ1NTX1BST1BFUlRJRVNbaHlwaGVuYXRlZF07XG5cbiAgaWYgKHR5cGUpIHtcbiAgICAvLyBhcHBlbmQgcGl4ZWwgdW5pdCwgdW5sZXNzIHByZXNlbnRcbiAgICBpZiAodHlwZSA9PT0gTEVOR1RIX0FUVFIgJiYgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgdmFsdWUgPSBTdHJpbmcodmFsdWUpICsgJ3B4JztcbiAgICB9XG5cbiAgICBub2RlLnN0eWxlW2h5cGhlbmF0ZWRdID0gdmFsdWU7XG4gIH0gZWxzZSB7XG4gICAgbm9kZS5zZXRBdHRyaWJ1dGVOUyhudWxsLCBuYW1lLCB2YWx1ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0QXR0cmlidXRlcyhub2RlLCBhdHRycykge1xuXG4gIHZhciBuYW1lcyA9IE9iamVjdC5rZXlzKGF0dHJzKSwgaSwgbmFtZTtcblxuICBmb3IgKGkgPSAwLCBuYW1lOyAobmFtZSA9IG5hbWVzW2ldKTsgaSsrKSB7XG4gICAgc2V0QXR0cmlidXRlKG5vZGUsIG5hbWUsIGF0dHJzW25hbWVdKTtcbiAgfVxufVxuXG4vKipcbiAqIEdldHMgb3Igc2V0cyByYXcgYXR0cmlidXRlcyBvbiBhIG5vZGUuXG4gKlxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gbm9kZVxuICogQHBhcmFtICB7T2JqZWN0fSBbYXR0cnNdXG4gKiBAcGFyYW0gIHtTdHJpbmd9IFtuYW1lXVxuICogQHBhcmFtICB7U3RyaW5nfSBbdmFsdWVdXG4gKlxuICogQHJldHVybiB7U3RyaW5nfVxuICovXG5mdW5jdGlvbiBhdHRyKG5vZGUsIG5hbWUsIHZhbHVlKSB7XG4gIGlmICh0eXBlb2YgbmFtZSA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgc2V0QXR0cmlidXRlKG5vZGUsIG5hbWUsIHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGdldEF0dHJpYnV0ZShub2RlLCBuYW1lKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgc2V0QXR0cmlidXRlcyhub2RlLCBuYW1lKTtcbiAgfVxuXG4gIHJldHVybiBub2RlO1xufVxuXG4vKipcclxuICogQ2xlYXIgdXRpbGl0eVxyXG4gKi9cclxuZnVuY3Rpb24gaW5kZXgoYXJyLCBvYmopIHtcclxuICBpZiAoYXJyLmluZGV4T2YpIHtcclxuICAgIHJldHVybiBhcnIuaW5kZXhPZihvYmopO1xyXG4gIH1cclxuXHJcblxyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XHJcbiAgICBpZiAoYXJyW2ldID09PSBvYmopIHtcclxuICAgICAgcmV0dXJuIGk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gLTE7XHJcbn1cclxuXHJcbnZhciByZSA9IC9cXHMrLztcclxuXHJcbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XHJcblxyXG5mdW5jdGlvbiBkZWZpbmVkKG8pIHtcclxuICByZXR1cm4gdHlwZW9mIG8gIT09ICd1bmRlZmluZWQnO1xyXG59XHJcblxyXG4vKipcclxuICogV3JhcCBgZWxgIGluIGEgYENsYXNzTGlzdGAuXHJcbiAqXHJcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxcclxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbmZ1bmN0aW9uIGNsYXNzZXMoZWwpIHtcclxuICByZXR1cm4gbmV3IENsYXNzTGlzdChlbCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIENsYXNzTGlzdChlbCkge1xyXG4gIGlmICghZWwgfHwgIWVsLm5vZGVUeXBlKSB7XHJcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgRE9NIGVsZW1lbnQgcmVmZXJlbmNlIGlzIHJlcXVpcmVkJyk7XHJcbiAgfVxyXG4gIHRoaXMuZWwgPSBlbDtcclxuICB0aGlzLmxpc3QgPSBlbC5jbGFzc0xpc3Q7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBZGQgY2xhc3MgYG5hbWVgIGlmIG5vdCBhbHJlYWR5IHByZXNlbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXHJcbiAqIEByZXR1cm4ge0NsYXNzTGlzdH1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uKG5hbWUpIHtcclxuXHJcbiAgLy8gY2xhc3NMaXN0XHJcbiAgaWYgKHRoaXMubGlzdCkge1xyXG4gICAgdGhpcy5saXN0LmFkZChuYW1lKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gZmFsbGJhY2tcclxuICB2YXIgYXJyID0gdGhpcy5hcnJheSgpO1xyXG4gIHZhciBpID0gaW5kZXgoYXJyLCBuYW1lKTtcclxuICBpZiAoIX5pKSB7XHJcbiAgICBhcnIucHVzaChuYW1lKTtcclxuICB9XHJcblxyXG4gIGlmIChkZWZpbmVkKHRoaXMuZWwuY2xhc3NOYW1lLmJhc2VWYWwpKSB7XHJcbiAgICB0aGlzLmVsLmNsYXNzTmFtZS5iYXNlVmFsID0gYXJyLmpvaW4oJyAnKTtcclxuICB9IGVsc2Uge1xyXG4gICAgdGhpcy5lbC5jbGFzc05hbWUgPSBhcnIuam9pbignICcpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG4vKipcclxuICogUmVtb3ZlIGNsYXNzIGBuYW1lYCB3aGVuIHByZXNlbnQsIG9yXHJcbiAqIHBhc3MgYSByZWd1bGFyIGV4cHJlc3Npb24gdG8gcmVtb3ZlXHJcbiAqIGFueSB3aGljaCBtYXRjaC5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd8UmVnRXhwfSBuYW1lXHJcbiAqIEByZXR1cm4ge0NsYXNzTGlzdH1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uKG5hbWUpIHtcclxuICBpZiAoJ1tvYmplY3QgUmVnRXhwXScgPT09IHRvU3RyaW5nLmNhbGwobmFtZSkpIHtcclxuICAgIHJldHVybiB0aGlzLnJlbW92ZU1hdGNoaW5nKG5hbWUpO1xyXG4gIH1cclxuXHJcbiAgLy8gY2xhc3NMaXN0XHJcbiAgaWYgKHRoaXMubGlzdCkge1xyXG4gICAgdGhpcy5saXN0LnJlbW92ZShuYW1lKTtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgLy8gZmFsbGJhY2tcclxuICB2YXIgYXJyID0gdGhpcy5hcnJheSgpO1xyXG4gIHZhciBpID0gaW5kZXgoYXJyLCBuYW1lKTtcclxuICBpZiAofmkpIHtcclxuICAgIGFyci5zcGxpY2UoaSwgMSk7XHJcbiAgfVxyXG4gIHRoaXMuZWwuY2xhc3NOYW1lLmJhc2VWYWwgPSBhcnIuam9pbignICcpO1xyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJlbW92ZSBhbGwgY2xhc3NlcyBtYXRjaGluZyBgcmVgLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1JlZ0V4cH0gcmVcclxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxyXG4gKiBAYXBpIHByaXZhdGVcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLnJlbW92ZU1hdGNoaW5nID0gZnVuY3Rpb24ocmUpIHtcclxuICB2YXIgYXJyID0gdGhpcy5hcnJheSgpO1xyXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XHJcbiAgICBpZiAocmUudGVzdChhcnJbaV0pKSB7XHJcbiAgICAgIHRoaXMucmVtb3ZlKGFycltpXSk7XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFRvZ2dsZSBjbGFzcyBgbmFtZWAsIGNhbiBmb3JjZSBzdGF0ZSB2aWEgYGZvcmNlYC5cclxuICpcclxuICogRm9yIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBjbGFzc0xpc3QsIGJ1dCBkbyBub3Qgc3VwcG9ydCBgZm9yY2VgIHlldCxcclxuICogdGhlIG1pc3Rha2Ugd2lsbCBiZSBkZXRlY3RlZCBhbmQgY29ycmVjdGVkLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gKiBAcGFyYW0ge0Jvb2xlYW59IGZvcmNlXHJcbiAqIEByZXR1cm4ge0NsYXNzTGlzdH1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uKG5hbWUsIGZvcmNlKSB7XHJcbiAgLy8gY2xhc3NMaXN0XHJcbiAgaWYgKHRoaXMubGlzdCkge1xyXG4gICAgaWYgKGRlZmluZWQoZm9yY2UpKSB7XHJcbiAgICAgIGlmIChmb3JjZSAhPT0gdGhpcy5saXN0LnRvZ2dsZShuYW1lLCBmb3JjZSkpIHtcclxuICAgICAgICB0aGlzLmxpc3QudG9nZ2xlKG5hbWUpOyAvLyB0b2dnbGUgYWdhaW4gdG8gY29ycmVjdFxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmxpc3QudG9nZ2xlKG5hbWUpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICAvLyBmYWxsYmFja1xyXG4gIGlmIChkZWZpbmVkKGZvcmNlKSkge1xyXG4gICAgaWYgKCFmb3JjZSkge1xyXG4gICAgICB0aGlzLnJlbW92ZShuYW1lKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuYWRkKG5hbWUpO1xyXG4gICAgfVxyXG4gIH0gZWxzZSB7XHJcbiAgICBpZiAodGhpcy5oYXMobmFtZSkpIHtcclxuICAgICAgdGhpcy5yZW1vdmUobmFtZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmFkZChuYW1lKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybiBhbiBhcnJheSBvZiBjbGFzc2VzLlxyXG4gKlxyXG4gKiBAcmV0dXJuIHtBcnJheX1cclxuICogQGFwaSBwdWJsaWNcclxuICovXHJcblxyXG5DbGFzc0xpc3QucHJvdG90eXBlLmFycmF5ID0gZnVuY3Rpb24oKSB7XHJcbiAgdmFyIGNsYXNzTmFtZSA9IHRoaXMuZWwuZ2V0QXR0cmlidXRlKCdjbGFzcycpIHx8ICcnO1xyXG4gIHZhciBzdHIgPSBjbGFzc05hbWUucmVwbGFjZSgvXlxccyt8XFxzKyQvZywgJycpO1xyXG4gIHZhciBhcnIgPSBzdHIuc3BsaXQocmUpO1xyXG4gIGlmICgnJyA9PT0gYXJyWzBdKSB7XHJcbiAgICBhcnIuc2hpZnQoKTtcclxuICB9XHJcbiAgcmV0dXJuIGFycjtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBDaGVjayBpZiBjbGFzcyBgbmFtZWAgaXMgcHJlc2VudC5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcclxuICogQHJldHVybiB7Q2xhc3NMaXN0fVxyXG4gKiBAYXBpIHB1YmxpY1xyXG4gKi9cclxuXHJcbkNsYXNzTGlzdC5wcm90b3R5cGUuaGFzID1cclxuQ2xhc3NMaXN0LnByb3RvdHlwZS5jb250YWlucyA9IGZ1bmN0aW9uKG5hbWUpIHtcclxuICByZXR1cm4gKFxyXG4gICAgdGhpcy5saXN0ID9cclxuICAgICAgdGhpcy5saXN0LmNvbnRhaW5zKG5hbWUpIDpcclxuICAgICAgISEgfmluZGV4KHRoaXMuYXJyYXkoKSwgbmFtZSlcclxuICApO1xyXG59O1xuXG5mdW5jdGlvbiByZW1vdmUoZWxlbWVudCkge1xuICB2YXIgcGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudDtcbn1cblxuLyoqXG4gKiBDbGVhciB1dGlsaXR5XG4gKi9cblxuLyoqXG4gKiBSZW1vdmVzIGFsbCBjaGlsZHJlbiBmcm9tIHRoZSBnaXZlbiBlbGVtZW50XG4gKlxuICogQHBhcmFtICB7RE9NRWxlbWVudH0gZWxlbWVudFxuICogQHJldHVybiB7RE9NRWxlbWVudH0gdGhlIGVsZW1lbnQgKGZvciBjaGFpbmluZylcbiAqL1xuZnVuY3Rpb24gY2xlYXIoZWxlbWVudCkge1xuICB2YXIgY2hpbGQ7XG5cbiAgd2hpbGUgKChjaGlsZCA9IGVsZW1lbnQuZmlyc3RDaGlsZCkpIHtcbiAgICByZW1vdmUoY2hpbGQpO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIGNsb25lKGVsZW1lbnQpIHtcbiAgcmV0dXJuIGVsZW1lbnQuY2xvbmVOb2RlKHRydWUpO1xufVxuXG52YXIgbnMgPSB7XG4gIHN2ZzogJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJ1xufTtcblxuLyoqXG4gKiBET00gcGFyc2luZyB1dGlsaXR5XG4gKi9cblxudmFyIFNWR19TVEFSVCA9ICc8c3ZnIHhtbG5zPVwiJyArIG5zLnN2ZyArICdcIic7XG5cbmZ1bmN0aW9uIHBhcnNlKHN2Zykge1xuXG4gIHZhciB1bndyYXAgPSBmYWxzZTtcblxuICAvLyBlbnN1cmUgd2UgaW1wb3J0IGEgdmFsaWQgc3ZnIGRvY3VtZW50XG4gIGlmIChzdmcuc3Vic3RyaW5nKDAsIDQpID09PSAnPHN2ZycpIHtcbiAgICBpZiAoc3ZnLmluZGV4T2YobnMuc3ZnKSA9PT0gLTEpIHtcbiAgICAgIHN2ZyA9IFNWR19TVEFSVCArIHN2Zy5zdWJzdHJpbmcoNCk7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIC8vIG5hbWVzcGFjZSBzdmdcbiAgICBzdmcgPSBTVkdfU1RBUlQgKyAnPicgKyBzdmcgKyAnPC9zdmc+JztcbiAgICB1bndyYXAgPSB0cnVlO1xuICB9XG5cbiAgdmFyIHBhcnNlZCA9IHBhcnNlRG9jdW1lbnQoc3ZnKTtcblxuICBpZiAoIXVud3JhcCkge1xuICAgIHJldHVybiBwYXJzZWQ7XG4gIH1cblxuICB2YXIgZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG5cbiAgdmFyIHBhcmVudCA9IHBhcnNlZC5maXJzdENoaWxkO1xuXG4gIHdoaWxlIChwYXJlbnQuZmlyc3RDaGlsZCkge1xuICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKHBhcmVudC5maXJzdENoaWxkKTtcbiAgfVxuXG4gIHJldHVybiBmcmFnbWVudDtcbn1cblxuZnVuY3Rpb24gcGFyc2VEb2N1bWVudChzdmcpIHtcblxuICB2YXIgcGFyc2VyO1xuXG4gIC8vIHBhcnNlXG4gIHBhcnNlciA9IG5ldyBET01QYXJzZXIoKTtcbiAgcGFyc2VyLmFzeW5jID0gZmFsc2U7XG5cbiAgcmV0dXJuIHBhcnNlci5wYXJzZUZyb21TdHJpbmcoc3ZnLCAndGV4dC94bWwnKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgdXRpbGl0eSBmb3IgU1ZHIGVsZW1lbnRzXG4gKi9cblxuXG4vKipcbiAqIENyZWF0ZSBhIHNwZWNpZmljIHR5cGUgZnJvbSBuYW1lIG9yIFNWRyBtYXJrdXAuXG4gKlxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgdGhlIG5hbWUgb3IgbWFya3VwIG9mIHRoZSBlbGVtZW50XG4gKiBAcGFyYW0ge09iamVjdH0gW2F0dHJzXSBhdHRyaWJ1dGVzIHRvIHNldCBvbiB0aGUgZWxlbWVudFxuICpcbiAqIEByZXR1cm5zIHtTVkdFbGVtZW50fVxuICovXG5mdW5jdGlvbiBjcmVhdGUobmFtZSwgYXR0cnMpIHtcbiAgdmFyIGVsZW1lbnQ7XG5cbiAgaWYgKG5hbWUuY2hhckF0KDApID09PSAnPCcpIHtcbiAgICBlbGVtZW50ID0gcGFyc2UobmFtZSkuZmlyc3RDaGlsZDtcbiAgICBlbGVtZW50ID0gZG9jdW1lbnQuaW1wb3J0Tm9kZShlbGVtZW50LCB0cnVlKTtcbiAgfSBlbHNlIHtcbiAgICBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKG5zLnN2ZywgbmFtZSk7XG4gIH1cblxuICBpZiAoYXR0cnMpIHtcbiAgICBhdHRyKGVsZW1lbnQsIGF0dHJzKTtcbiAgfVxuXG4gIHJldHVybiBlbGVtZW50O1xufVxuXG4vKipcbiAqIEV2ZW50cyBoYW5kbGluZyB1dGlsaXR5XG4gKi9cblxuZnVuY3Rpb24gb24obm9kZSwgZXZlbnQsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKSB7XG4gIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpO1xufVxuXG5mdW5jdGlvbiBvZmYobm9kZSwgZXZlbnQsIGxpc3RlbmVyLCB1c2VDYXB0dXJlKSB7XG4gIG5vZGUucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgbGlzdGVuZXIsIHVzZUNhcHR1cmUpO1xufVxuXG4vKipcbiAqIEdlb21ldHJ5IGhlbHBlcnNcbiAqL1xuXG4vLyBmYWtlIG5vZGUgdXNlZCB0byBpbnN0YW50aWF0ZSBzdmcgZ2VvbWV0cnkgZWxlbWVudHNcbnZhciBub2RlID0gY3JlYXRlKCdzdmcnKTtcblxuZnVuY3Rpb24gZXh0ZW5kKG9iamVjdCwgcHJvcHMpIHtcbiAgdmFyIGksIGssIGtleXMgPSBPYmplY3Qua2V5cyhwcm9wcyk7XG5cbiAgZm9yIChpID0gMDsgKGsgPSBrZXlzW2ldKTsgaSsrKSB7XG4gICAgb2JqZWN0W2tdID0gcHJvcHNba107XG4gIH1cblxuICByZXR1cm4gb2JqZWN0O1xufVxuXG5cbmZ1bmN0aW9uIGNyZWF0ZVBvaW50KHgsIHkpIHtcbiAgdmFyIHBvaW50ID0gbm9kZS5jcmVhdGVTVkdQb2ludCgpO1xuXG4gIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICBjYXNlIDA6XG4gICAgcmV0dXJuIHBvaW50O1xuICBjYXNlIDI6XG4gICAgeCA9IHtcbiAgICAgIHg6IHgsXG4gICAgICB5OiB5XG4gICAgfTtcbiAgICBicmVhaztcbiAgfVxuXG4gIHJldHVybiBleHRlbmQocG9pbnQsIHgpO1xufVxuXG4vKipcbiAqIENyZWF0ZSBtYXRyaXggdmlhIGFyZ3MuXG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiBjcmVhdGVNYXRyaXgoeyBhOiAxLCBiOiAxIH0pO1xuICogY3JlYXRlTWF0cml4KCk7XG4gKiBjcmVhdGVNYXRyaXgoMSwgMiwgMCwgMCwgMzAsIDIwKTtcbiAqXG4gKiBAcmV0dXJuIHtTVkdNYXRyaXh9XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZU1hdHJpeChhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIHZhciBtYXRyaXggPSBub2RlLmNyZWF0ZVNWR01hdHJpeCgpO1xuXG4gIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICBjYXNlIDA6XG4gICAgcmV0dXJuIG1hdHJpeDtcbiAgY2FzZSAxOlxuICAgIHJldHVybiBleHRlbmQobWF0cml4LCBhKTtcbiAgY2FzZSA2OlxuICAgIHJldHVybiBleHRlbmQobWF0cml4LCB7XG4gICAgICBhOiBhLFxuICAgICAgYjogYixcbiAgICAgIGM6IGMsXG4gICAgICBkOiBkLFxuICAgICAgZTogZSxcbiAgICAgIGY6IGZcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVUcmFuc2Zvcm0obWF0cml4KSB7XG4gIGlmIChtYXRyaXgpIHtcbiAgICByZXR1cm4gbm9kZS5jcmVhdGVTVkdUcmFuc2Zvcm1Gcm9tTWF0cml4KG1hdHJpeCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG5vZGUuY3JlYXRlU1ZHVHJhbnNmb3JtKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBTZXJpYWxpemF0aW9uIHV0aWxcbiAqL1xuXG52YXIgVEVYVF9FTlRJVElFUyA9IC8oWyY8Pl17MX0pL2c7XG52YXIgQVRUUl9FTlRJVElFUyA9IC8oW1xcblxcclwiXXsxfSkvZztcblxudmFyIEVOVElUWV9SRVBMQUNFTUVOVCA9IHtcbiAgJyYnOiAnJmFtcDsnLFxuICAnPCc6ICcmbHQ7JyxcbiAgJz4nOiAnJmd0OycsXG4gICdcIic6ICdcXCcnXG59O1xuXG5mdW5jdGlvbiBlc2NhcGUoc3RyLCBwYXR0ZXJuKSB7XG5cbiAgZnVuY3Rpb24gcmVwbGFjZUZuKG1hdGNoLCBlbnRpdHkpIHtcbiAgICByZXR1cm4gRU5USVRZX1JFUExBQ0VNRU5UW2VudGl0eV0gfHwgZW50aXR5O1xuICB9XG5cbiAgcmV0dXJuIHN0ci5yZXBsYWNlKHBhdHRlcm4sIHJlcGxhY2VGbik7XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZShub2RlLCBvdXRwdXQpIHtcblxuICB2YXIgaSwgbGVuLCBhdHRyTWFwLCBhdHRyTm9kZSwgY2hpbGROb2RlcztcblxuICBzd2l0Y2ggKG5vZGUubm9kZVR5cGUpIHtcbiAgLy8gVEVYVFxuICBjYXNlIDM6XG4gICAgLy8gcmVwbGFjZSBzcGVjaWFsIFhNTCBjaGFyYWN0ZXJzXG4gICAgb3V0cHV0LnB1c2goZXNjYXBlKG5vZGUudGV4dENvbnRlbnQsIFRFWFRfRU5USVRJRVMpKTtcbiAgICBicmVhaztcblxuICAvLyBFTEVNRU5UXG4gIGNhc2UgMTpcbiAgICBvdXRwdXQucHVzaCgnPCcsIG5vZGUudGFnTmFtZSk7XG5cbiAgICBpZiAobm9kZS5oYXNBdHRyaWJ1dGVzKCkpIHtcbiAgICAgIGF0dHJNYXAgPSBub2RlLmF0dHJpYnV0ZXM7XG4gICAgICBmb3IgKGkgPSAwLCBsZW4gPSBhdHRyTWFwLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgIGF0dHJOb2RlID0gYXR0ck1hcC5pdGVtKGkpO1xuICAgICAgICBvdXRwdXQucHVzaCgnICcsIGF0dHJOb2RlLm5hbWUsICc9XCInLCBlc2NhcGUoYXR0ck5vZGUudmFsdWUsIEFUVFJfRU5USVRJRVMpLCAnXCInKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobm9kZS5oYXNDaGlsZE5vZGVzKCkpIHtcbiAgICAgIG91dHB1dC5wdXNoKCc+Jyk7XG4gICAgICBjaGlsZE5vZGVzID0gbm9kZS5jaGlsZE5vZGVzO1xuICAgICAgZm9yIChpID0gMCwgbGVuID0gY2hpbGROb2Rlcy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICBzZXJpYWxpemUoY2hpbGROb2Rlcy5pdGVtKGkpLCBvdXRwdXQpO1xuICAgICAgfVxuICAgICAgb3V0cHV0LnB1c2goJzwvJywgbm9kZS50YWdOYW1lLCAnPicpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnLz4nKTtcbiAgICB9XG4gICAgYnJlYWs7XG5cbiAgLy8gQ09NTUVOVFxuICBjYXNlIDg6XG4gICAgb3V0cHV0LnB1c2goJzwhLS0nLCBlc2NhcGUobm9kZS5ub2RlVmFsdWUsIFRFWFRfRU5USVRJRVMpLCAnLS0+Jyk7XG4gICAgYnJlYWs7XG5cbiAgLy8gQ0RBVEFcbiAgY2FzZSA0OlxuICAgIG91dHB1dC5wdXNoKCc8IVtDREFUQVsnLCBub2RlLm5vZGVWYWx1ZSwgJ11dPicpO1xuICAgIGJyZWFrO1xuXG4gIGRlZmF1bHQ6XG4gICAgdGhyb3cgbmV3IEVycm9yKCd1bmFibGUgdG8gaGFuZGxlIG5vZGUgJyArIG5vZGUubm9kZVR5cGUpO1xuICB9XG5cbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuLyoqXG4gKiBpbm5lckhUTUwgbGlrZSBmdW5jdGlvbmFsaXR5IGZvciBTVkcgZWxlbWVudHMuXG4gKiBiYXNlZCBvbiBpbm5lclNWRyAoaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9pbm5lcnN2ZylcbiAqL1xuXG5cbmZ1bmN0aW9uIHNldChlbGVtZW50LCBzdmcpIHtcblxuICB2YXIgcGFyc2VkID0gcGFyc2Uoc3ZnKTtcblxuICAvLyBjbGVhciBlbGVtZW50IGNvbnRlbnRzXG4gIGNsZWFyKGVsZW1lbnQpO1xuXG4gIGlmICghc3ZnKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCFpc0ZyYWdtZW50KHBhcnNlZCkpIHtcbiAgICAvLyBleHRyYWN0IDxzdmc+IGZyb20gcGFyc2VkIGRvY3VtZW50XG4gICAgcGFyc2VkID0gcGFyc2VkLmRvY3VtZW50RWxlbWVudDtcbiAgfVxuXG4gIHZhciBub2RlcyA9IHNsaWNlKHBhcnNlZC5jaGlsZE5vZGVzKTtcblxuICAvLyBpbXBvcnQgKyBhcHBlbmQgZWFjaCBub2RlXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICBhcHBlbmRUbyhub2Rlc1tpXSwgZWxlbWVudCk7XG4gIH1cblxufVxuXG5mdW5jdGlvbiBnZXQoZWxlbWVudCkge1xuICB2YXIgY2hpbGQgPSBlbGVtZW50LmZpcnN0Q2hpbGQsXG4gICAgICBvdXRwdXQgPSBbXTtcblxuICB3aGlsZSAoY2hpbGQpIHtcbiAgICBzZXJpYWxpemUoY2hpbGQsIG91dHB1dCk7XG4gICAgY2hpbGQgPSBjaGlsZC5uZXh0U2libGluZztcbiAgfVxuXG4gIHJldHVybiBvdXRwdXQuam9pbignJyk7XG59XG5cbmZ1bmN0aW9uIGlzRnJhZ21lbnQobm9kZSkge1xuICByZXR1cm4gbm9kZS5ub2RlTmFtZSA9PT0gJyNkb2N1bWVudC1mcmFnbWVudCc7XG59XG5cbmZ1bmN0aW9uIGlubmVyU1ZHKGVsZW1lbnQsIHN2Zykge1xuXG4gIGlmIChzdmcgIT09IHVuZGVmaW5lZCkge1xuXG4gICAgdHJ5IHtcbiAgICAgIHNldChlbGVtZW50LCBzdmcpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignZXJyb3IgcGFyc2luZyBTVkc6ICcgKyBlLm1lc3NhZ2UpO1xuICAgIH1cblxuICAgIHJldHVybiBlbGVtZW50O1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBnZXQoZWxlbWVudCk7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBzbGljZShhcnIpIHtcbiAgcmV0dXJuIEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFycik7XG59XG5cbi8qKlxuICogU2VsZWN0aW9uIHV0aWxpdGllc1xuICovXG5cbmZ1bmN0aW9uIHNlbGVjdChub2RlLCBzZWxlY3Rvcikge1xuICByZXR1cm4gbm9kZS5xdWVyeVNlbGVjdG9yKHNlbGVjdG9yKTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0QWxsKG5vZGUsIHNlbGVjdG9yKSB7XG4gIHZhciBub2RlcyA9IG5vZGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG5cbiAgcmV0dXJuIFtdLm1hcC5jYWxsKG5vZGVzLCBmdW5jdGlvbihlbGVtZW50KSB7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH0pO1xufVxuXG4vKipcbiAqIHByZXBlbmRUbyB1dGlsaXR5XG4gKi9cblxuLyoqXG4gKiBQcmVwZW5kIGEgbm9kZSB0byBhIHRhcmdldCBlbGVtZW50IGFuZCByZXR1cm4gdGhlIHByZXBlbmRlZCBub2RlLlxuICpcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IG5vZGVcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IHRhcmdldFxuICpcbiAqIEByZXR1cm4ge1NWR0VsZW1lbnR9IHRoZSBwcmVwZW5kZWQgbm9kZVxuICovXG5mdW5jdGlvbiBwcmVwZW5kVG8obm9kZSwgdGFyZ2V0KSB7XG4gIHJldHVybiB0YXJnZXQuaW5zZXJ0QmVmb3JlKGVuc3VyZUltcG9ydGVkKG5vZGUsIHRhcmdldCksIHRhcmdldC5maXJzdENoaWxkIHx8IG51bGwpO1xufVxuXG4vKipcbiAqIHByZXBlbmQgdXRpbGl0eVxuICovXG5cbi8qKlxuICogUHJlcGVuZCBhIG5vZGUgdG8gYSB0YXJnZXQgZWxlbWVudFxuICpcbiAqIEBwYXJhbSAge1NWR0VsZW1lbnR9IHRhcmdldFxuICogQHBhcmFtICB7U1ZHRWxlbWVudH0gbm9kZVxuICpcbiAqIEByZXR1cm4ge1NWR0VsZW1lbnR9IHRoZSB0YXJnZXQgZWxlbWVudFxuICovXG5mdW5jdGlvbiBwcmVwZW5kKHRhcmdldCwgbm9kZSkge1xuICBwcmVwZW5kVG8obm9kZSwgdGFyZ2V0KTtcbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuLyoqXG4gKiBSZXBsYWNlIHV0aWxpdHlcbiAqL1xuXG5mdW5jdGlvbiByZXBsYWNlKGVsZW1lbnQsIHJlcGxhY2VtZW50KSB7XG4gIGVsZW1lbnQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQoZW5zdXJlSW1wb3J0ZWQocmVwbGFjZW1lbnQsIGVsZW1lbnQpLCBlbGVtZW50KTtcbiAgcmV0dXJuIHJlcGxhY2VtZW50O1xufVxuXG4vKipcbiAqIHRyYW5zZm9ybSBhY2Nlc3NvciB1dGlsaXR5XG4gKi9cblxuZnVuY3Rpb24gd3JhcE1hdHJpeCh0cmFuc2Zvcm1MaXN0LCB0cmFuc2Zvcm0pIHtcbiAgaWYgKHRyYW5zZm9ybSBpbnN0YW5jZW9mIFNWR01hdHJpeCkge1xuICAgIHJldHVybiB0cmFuc2Zvcm1MaXN0LmNyZWF0ZVNWR1RyYW5zZm9ybUZyb21NYXRyaXgodHJhbnNmb3JtKTtcbiAgfVxuXG4gIHJldHVybiB0cmFuc2Zvcm07XG59XG5cblxuZnVuY3Rpb24gc2V0VHJhbnNmb3Jtcyh0cmFuc2Zvcm1MaXN0LCB0cmFuc2Zvcm1zKSB7XG4gIHZhciBpLCB0O1xuXG4gIHRyYW5zZm9ybUxpc3QuY2xlYXIoKTtcblxuICBmb3IgKGkgPSAwOyAodCA9IHRyYW5zZm9ybXNbaV0pOyBpKyspIHtcbiAgICB0cmFuc2Zvcm1MaXN0LmFwcGVuZEl0ZW0od3JhcE1hdHJpeCh0cmFuc2Zvcm1MaXN0LCB0KSk7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXQgb3Igc2V0IHRoZSB0cmFuc2Zvcm1zIG9uIHRoZSBnaXZlbiBub2RlLlxuICpcbiAqIEBwYXJhbSB7U1ZHRWxlbWVudH0gbm9kZVxuICogQHBhcmFtICB7U1ZHVHJhbnNmb3JtfFNWR01hdHJpeHxBcnJheTxTVkdUcmFuc2Zvcm18U1ZHTWF0cml4Pn0gW3RyYW5zZm9ybXNdXG4gKlxuICogQHJldHVybiB7U1ZHVHJhbnNmb3JtfSB0aGUgY29uc29saWRhdGVkIHRyYW5zZm9ybVxuICovXG5mdW5jdGlvbiB0cmFuc2Zvcm0obm9kZSwgdHJhbnNmb3Jtcykge1xuICB2YXIgdHJhbnNmb3JtTGlzdCA9IG5vZGUudHJhbnNmb3JtLmJhc2VWYWw7XG5cbiAgaWYgKHRyYW5zZm9ybXMpIHtcblxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0cmFuc2Zvcm1zKSkge1xuICAgICAgdHJhbnNmb3JtcyA9IFsgdHJhbnNmb3JtcyBdO1xuICAgIH1cblxuICAgIHNldFRyYW5zZm9ybXModHJhbnNmb3JtTGlzdCwgdHJhbnNmb3Jtcyk7XG4gIH1cblxuICByZXR1cm4gdHJhbnNmb3JtTGlzdC5jb25zb2xpZGF0ZSgpO1xufVxuXG5leHBvcnQgeyBhcHBlbmQsIGFwcGVuZFRvLCBhdHRyLCBjbGFzc2VzLCBjbGVhciwgY2xvbmUsIGNyZWF0ZSwgaW5uZXJTVkcsIHByZXBlbmQsIHByZXBlbmRUbywgcmVtb3ZlLCByZXBsYWNlLCB0cmFuc2Zvcm0sIG9uLCBvZmYsIGNyZWF0ZVBvaW50LCBjcmVhdGVNYXRyaXgsIGNyZWF0ZVRyYW5zZm9ybSwgc2VsZWN0LCBzZWxlY3RBbGwgfTtcbiIsIm1vZHVsZS5leHBvcnRzPXtcclxuICBcIm5hbWVcIjogXCJBY3Rpdml0aVwiLFxyXG4gIFwidXJpXCI6IFwiaHR0cDovL2FjdGl2aXRpLm9yZy9icG1uXCIsXHJcbiAgXCJwcmVmaXhcIjogXCJhY3Rpdml0aVwiLFxyXG4gIFwieG1sXCI6IHtcclxuICAgIFwidGFnQWxpYXNcIjogXCJsb3dlckNhc2VcIlxyXG4gIH0sXHJcbiAgXCJhc3NvY2lhdGlvbnNcIjogW10sXHJcbiAgXCJ0eXBlc1wiOiBbXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkRlZmluaXRpb25zXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpEZWZpbml0aW9uc1wiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZGlhZ3JhbVJlbGF0aW9uSWRcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiSW5PdXRCaW5kaW5nXCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbXHJcbiAgICAgICAgXCJFbGVtZW50XCJcclxuICAgICAgXSxcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwic291cmNlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInNvdXJjZUV4cHJlc3Npb25cIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidGFyZ2V0XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImJ1c2luZXNzS2V5XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImxvY2FsXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQm9vbGVhblwiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IGZhbHNlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YXJpYWJsZXNcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiSW5cIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFtcclxuICAgICAgICBcIkluT3V0QmluZGluZ1wiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJicG1uOkNhbGxBY3Rpdml0eVwiXHJcbiAgICAgICAgXVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJPdXRcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFtcclxuICAgICAgICBcIkluT3V0QmluZGluZ1wiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJicG1uOkNhbGxBY3Rpdml0eVwiXHJcbiAgICAgICAgXVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJBc3luY0NhcGFibGVcIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOkFjdGl2aXR5XCIsXHJcbiAgICAgICAgXCJicG1uOkdhdGV3YXlcIixcclxuICAgICAgICBcImJwbW46RXZlbnRcIlxyXG4gICAgICBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImFzeW5jXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQm9vbGVhblwiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IGZhbHNlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJhc3luY0JlZm9yZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkJvb2xlYW5cIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBmYWxzZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiYXN5bmNBZnRlclwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkJvb2xlYW5cIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBmYWxzZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZXhjbHVzaXZlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQm9vbGVhblwiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkpvYlByaW9yaXplZFwiLFxyXG4gICAgICBcImlzQWJzdHJhY3RcIjogdHJ1ZSxcclxuICAgICAgXCJleHRlbmRzXCI6IFtcclxuICAgICAgICBcImJwbW46UHJvY2Vzc1wiLFxyXG4gICAgICAgIFwiYWN0aXZpdGk6QXN5bmNDYXBhYmxlXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJqb2JQcmlvcml0eVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJTaWduYWxFdmVudERlZmluaXRpb25cIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiYXN5bmNcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJCb29sZWFuXCIsXHJcbiAgICAgICAgICBcImRlZmF1bHRcIjogZmFsc2VcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkVycm9yRXZlbnREZWZpbml0aW9uXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpFcnJvckV2ZW50RGVmaW5pdGlvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZXJyb3JDb2RlVmFyaWFibGVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZXJyb3JNZXNzYWdlVmFyaWFibGVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiRXJyb3JcIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOkVycm9yXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJhY3Rpdml0aTplcnJvck1lc3NhZ2VcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiUG90ZW50aWFsU3RhcnRlclwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogW1xyXG4gICAgICAgIFwiRWxlbWVudFwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicmVzb3VyY2VBc3NpZ25tZW50RXhwcmVzc2lvblwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiYnBtbjpSZXNvdXJjZUFzc2lnbm1lbnRFeHByZXNzaW9uXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkZvcm1TdXBwb3J0ZWRcIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOlN0YXJ0RXZlbnRcIixcclxuICAgICAgICBcImJwbW46VXNlclRhc2tcIlxyXG4gICAgICBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImZvcm1IYW5kbGVyQ2xhc3NcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZm9ybUtleVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJUZW1wbGF0ZVN1cHBvcnRlZFwiLFxyXG4gICAgICBcImlzQWJzdHJhY3RcIjogdHJ1ZSxcclxuICAgICAgXCJleHRlbmRzXCI6IFtcclxuICAgICAgICBcImJwbW46UHJvY2Vzc1wiLFxyXG4gICAgICAgIFwiYnBtbjpGbG93RWxlbWVudFwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibW9kZWxlclRlbXBsYXRlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkluaXRpYXRvclwiLFxyXG4gICAgICBcImlzQWJzdHJhY3RcIjogdHJ1ZSxcclxuICAgICAgXCJleHRlbmRzXCI6IFsgXCJicG1uOlN0YXJ0RXZlbnRcIiBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImluaXRpYXRvclwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJTY3JpcHRUYXNrXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpTY3JpcHRUYXNrXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJyZXN1bHRWYXJpYWJsZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJyZXNvdXJjZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJQcm9jZXNzXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpQcm9jZXNzXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYW5kaWRhdGVTdGFydGVyQ29uZmlndXJhdGlvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYW5kaWRhdGVTdGFydGVyVXNlcnNcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidmVyc2lvblRhZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJoaXN0b3J5VGltZVRvTGl2ZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpc1N0YXJ0YWJsZUluVGFza2xpc3RcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJCb29sZWFuXCIsXHJcbiAgICAgICAgICBcImRlZmF1bHRcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicHJvY2Vzcy1pcy1leGVjdXRhYmxlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQm9vbGVhblwiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkVzY2FsYXRpb25FdmVudERlZmluaXRpb25cIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOkVzY2FsYXRpb25FdmVudERlZmluaXRpb25cIlxyXG4gICAgICBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImVzY2FsYXRpb25Db2RlVmFyaWFibGVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiRm9ybWFsRXhwcmVzc2lvblwiLFxyXG4gICAgICBcImlzQWJzdHJhY3RcIjogdHJ1ZSxcclxuICAgICAgXCJleHRlbmRzXCI6IFtcclxuICAgICAgICBcImJwbW46Rm9ybWFsRXhwcmVzc2lvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicmVzb3VyY2VcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiQXNzaWduYWJsZVwiLFxyXG4gICAgICBcImV4dGVuZHNcIjogWyBcImJwbW46VXNlclRhc2tcIiBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImFzc2lnbmVlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNhbmRpZGF0ZVVzZXJzXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNhbmRpZGF0ZUdyb3Vwc1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkdWVEYXRlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImZvbGxvd1VwRGF0ZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJwcmlvcml0eVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJDYWxsQWN0aXZpdHlcIixcclxuICAgICAgXCJleHRlbmRzXCI6IFsgXCJicG1uOkNhbGxBY3Rpdml0eVwiIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiY2FsbGVkRWxlbWVudEJpbmRpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBcImxhdGVzdFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYWxsZWRFbGVtZW50VmVyc2lvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYWxsZWRFbGVtZW50VmVyc2lvblRhZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYWxsZWRFbGVtZW50VGVuYW50SWRcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiY2FzZVJlZlwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjYXNlQmluZGluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJkZWZhdWx0XCI6IFwibGF0ZXN0XCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNhc2VWZXJzaW9uXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNhc2VUZW5hbnRJZFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YXJpYWJsZU1hcHBpbmdDbGFzc1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YXJpYWJsZU1hcHBpbmdEZWxlZ2F0ZUV4cHJlc3Npb25cIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiU2VydmljZVRhc2tMaWtlXCIsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOlNlcnZpY2VUYXNrXCIsXHJcbiAgICAgICAgXCJicG1uOkJ1c2luZXNzUnVsZVRhc2tcIixcclxuICAgICAgICBcImJwbW46U2VuZFRhc2tcIixcclxuICAgICAgICBcImJwbW46TWVzc2FnZUV2ZW50RGVmaW5pdGlvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZXhwcmVzc2lvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjbGFzc1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWxlZ2F0ZUV4cHJlc3Npb25cIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicmVzdWx0VmFyaWFibGVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiRG1uQ2FwYWJsZVwiLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpCdXNpbmVzc1J1bGVUYXNrXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWNpc2lvblJlZlwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWNpc2lvblJlZkJpbmRpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBcImxhdGVzdFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWNpc2lvblJlZlZlcnNpb25cIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibWFwRGVjaXNpb25SZXN1bHRcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiZGVmYXVsdFwiOiBcInJlc3VsdExpc3RcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZGVjaXNpb25SZWZUZW5hbnRJZFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJFeHRlcm5hbENhcGFibGVcIixcclxuICAgICAgXCJleHRlbmRzXCI6IFtcclxuICAgICAgICBcImFjdGl2aXRpOlNlcnZpY2VUYXNrTGlrZVwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidHlwZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ0b3BpY1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJUYXNrUHJpb3JpemVkXCIsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbXHJcbiAgICAgICAgXCJicG1uOlByb2Nlc3NcIixcclxuICAgICAgICBcImFjdGl2aXRpOkV4dGVybmFsQ2FwYWJsZVwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidGFza1ByaW9yaXR5XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIlByb3BlcnRpZXNcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFtcclxuICAgICAgICBcIkVsZW1lbnRcIlxyXG4gICAgICBdLFxyXG4gICAgICBcIm1ldGFcIjoge1xyXG4gICAgICAgIFwiYWxsb3dlZEluXCI6IFsgXCIqXCIgXVxyXG4gICAgICB9LFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlc1wiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiUHJvcGVydHlcIixcclxuICAgICAgICAgIFwiaXNNYW55XCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIlByb3BlcnR5XCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbXHJcbiAgICAgICAgXCJFbGVtZW50XCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpZFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJuYW1lXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkNvbm5lY3RvclwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogW1xyXG4gICAgICAgIFwiRWxlbWVudFwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJhY3Rpdml0aTpTZXJ2aWNlVGFza0xpa2VcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpbnB1dE91dHB1dFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiSW5wdXRPdXRwdXRcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiY29ubmVjdG9ySWRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJJbnB1dE91dHB1dFwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogW1xyXG4gICAgICAgIFwiRWxlbWVudFwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJicG1uOkZsb3dOb2RlXCIsXHJcbiAgICAgICAgICBcImFjdGl2aXRpOkNvbm5lY3RvclwiXHJcbiAgICAgICAgXVxyXG4gICAgICB9LFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImlucHV0T3V0cHV0XCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJJbnB1dE91dHB1dFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjb25uZWN0b3JJZFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImlucHV0UGFyYW1ldGVyc1wiLFxyXG4gICAgICAgICAgXCJpc01hbnlcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIklucHV0UGFyYW1ldGVyXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcIm91dHB1dFBhcmFtZXRlcnNcIixcclxuICAgICAgICAgIFwiaXNNYW55XCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJPdXRwdXRQYXJhbWV0ZXJcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiSW5wdXRPdXRwdXRQYXJhbWV0ZXJcIixcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJuYW1lXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImRlZmluaXRpb25cIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIklucHV0T3V0cHV0UGFyYW1ldGVyRGVmaW5pdGlvblwiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJJbnB1dE91dHB1dFBhcmFtZXRlckRlZmluaXRpb25cIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWVcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkxpc3RcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJJbnB1dE91dHB1dFBhcmFtZXRlckRlZmluaXRpb25cIiBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcIml0ZW1zXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiSW5wdXRPdXRwdXRQYXJhbWV0ZXJEZWZpbml0aW9uXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIk1hcFwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIklucHV0T3V0cHV0UGFyYW1ldGVyRGVmaW5pdGlvblwiIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZW50cmllc1wiLFxyXG4gICAgICAgICAgXCJpc01hbnlcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkVudHJ5XCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkVudHJ5XCIsXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwia2V5XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImRlZmluaXRpb25cIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIklucHV0T3V0cHV0UGFyYW1ldGVyRGVmaW5pdGlvblwiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJWYWx1ZVwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogW1xyXG4gICAgICAgIFwiSW5wdXRPdXRwdXRQYXJhbWV0ZXJEZWZpbml0aW9uXCJcclxuICAgICAgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpZFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJuYW1lXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIlNjcmlwdFwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIklucHV0T3V0cHV0UGFyYW1ldGVyRGVmaW5pdGlvblwiIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwic2NyaXB0Rm9ybWF0XCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInJlc291cmNlXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkZpZWxkXCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbIFwiRWxlbWVudFwiIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJhY3Rpdml0aTpTZXJ2aWNlVGFza0xpa2VcIixcclxuICAgICAgICAgIFwiYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXJcIixcclxuICAgICAgICAgIFwiYWN0aXZpdGk6VGFza0xpc3RlbmVyXCJcclxuICAgICAgICBdXHJcbiAgICAgIH0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibmFtZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJleHByZXNzaW9uXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwic3RyaW5nVmFsdWVcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwic3RyaW5nXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiSW5wdXRQYXJhbWV0ZXJcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJJbnB1dE91dHB1dFBhcmFtZXRlclwiIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIk91dHB1dFBhcmFtZXRlclwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIklucHV0T3V0cHV0UGFyYW1ldGVyXCIgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiQ29sbGVjdGFibGVcIixcclxuICAgICAgXCJpc0Fic3RyYWN0XCI6IHRydWUsXHJcbiAgICAgIFwiZXh0ZW5kc1wiOiBbIFwiYnBtbjpNdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljc1wiIF0sXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbIFwiYWN0aXZpdGk6QXN5bmNDYXBhYmxlXCIgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjb2xsZWN0aW9uXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImVsZW1lbnRWYXJpYWJsZVwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZVwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIkVsZW1lbnRcIiBdLFxyXG4gICAgICBcIm1ldGFcIjoge1xyXG4gICAgICAgIFwiYWxsb3dlZEluXCI6IFtcclxuICAgICAgICAgIFwiYWN0aXZpdGk6QXN5bmNDYXBhYmxlXCIsXHJcbiAgICAgICAgICBcImJwbW46TXVsdGlJbnN0YW5jZUxvb3BDaGFyYWN0ZXJpc3RpY3NcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJib2R5XCIsXHJcbiAgICAgICAgICBcImlzQm9keVwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkV4ZWN1dGlvbkxpc3RlbmVyXCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbIFwiRWxlbWVudFwiIF0sXHJcbiAgICAgIFwibWV0YVwiOiB7XHJcbiAgICAgICAgXCJhbGxvd2VkSW5cIjogW1xyXG4gICAgICAgICAgXCJicG1uOlRhc2tcIixcclxuICAgICAgICAgIFwiYnBtbjpTZXJ2aWNlVGFza1wiLFxyXG4gICAgICAgICAgXCJicG1uOlVzZXJUYXNrXCIsXHJcbiAgICAgICAgICBcImJwbW46QnVzaW5lc3NSdWxlVGFza1wiLFxyXG4gICAgICAgICAgXCJicG1uOlNjcmlwdFRhc2tcIixcclxuICAgICAgICAgIFwiYnBtbjpSZWNlaXZlVGFza1wiLFxyXG4gICAgICAgICAgXCJicG1uOk1hbnVhbFRhc2tcIixcclxuICAgICAgICAgIFwiYnBtbjpFeGNsdXNpdmVHYXRld2F5XCIsXHJcbiAgICAgICAgICBcImJwbW46U2VxdWVuY2VGbG93XCIsXHJcbiAgICAgICAgICBcImJwbW46UGFyYWxsZWxHYXRld2F5XCIsXHJcbiAgICAgICAgICBcImJwbW46SW5jbHVzaXZlR2F0ZXdheVwiLFxyXG4gICAgICAgICAgXCJicG1uOkV2ZW50QmFzZWRHYXRld2F5XCIsXHJcbiAgICAgICAgICBcImJwbW46U3RhcnRFdmVudFwiLFxyXG4gICAgICAgICAgXCJicG1uOkludGVybWVkaWF0ZUNhdGNoRXZlbnRcIixcclxuICAgICAgICAgIFwiYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50XCIsXHJcbiAgICAgICAgICBcImJwbW46RW5kRXZlbnRcIixcclxuICAgICAgICAgIFwiYnBtbjpCb3VuZGFyeUV2ZW50XCIsXHJcbiAgICAgICAgICBcImJwbW46Q2FsbEFjdGl2aXR5XCIsXHJcbiAgICAgICAgICBcImJwbW46U3ViUHJvY2Vzc1wiLFxyXG4gICAgICAgICAgXCJicG1uOlByb2Nlc3NcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJleHByZXNzaW9uXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNsYXNzXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImRlbGVnYXRlRXhwcmVzc2lvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJldmVudFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJzY3JpcHRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlNjcmlwdFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJmaWVsZHNcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkZpZWxkXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJUYXNrTGlzdGVuZXJcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJFbGVtZW50XCIgXSxcclxuICAgICAgXCJtZXRhXCI6IHtcclxuICAgICAgICBcImFsbG93ZWRJblwiOiBbXHJcbiAgICAgICAgICBcImJwbW46VXNlclRhc2tcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJleHByZXNzaW9uXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImNsYXNzXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImRlbGVnYXRlRXhwcmVzc2lvblwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJldmVudFwiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZSxcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJzY3JpcHRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlNjcmlwdFwiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJmaWVsZHNcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkZpZWxkXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJpZFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJldmVudERlZmluaXRpb25zXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJicG1uOlRpbWVyRXZlbnREZWZpbml0aW9uXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJGb3JtUHJvcGVydHlcIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJFbGVtZW50XCIgXSxcclxuICAgICAgXCJtZXRhXCI6IHtcclxuICAgICAgICBcImFsbG93ZWRJblwiOiBbXHJcbiAgICAgICAgICBcImJwbW46U3RhcnRFdmVudFwiLFxyXG4gICAgICAgICAgXCJicG1uOlVzZXJUYXNrXCJcclxuICAgICAgICBdXHJcbiAgICAgIH0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiaWRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibmFtZVwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ0eXBlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInJlcXVpcmVkXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInJlYWRhYmxlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcIndyaXRhYmxlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhcmlhYmxlXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcImV4cHJlc3Npb25cIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZGF0ZVBhdHRlcm5cIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiZGVmYXVsdFwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YWx1ZXNcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlZhbHVlXCIsXHJcbiAgICAgICAgICBcImlzTWFueVwiOiB0cnVlXHJcbiAgICAgICAgfVxyXG4gICAgICBdXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBcIm5hbWVcIjogXCJGb3JtRGF0YVwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIkVsZW1lbnRcIiBdLFxyXG4gICAgICBcIm1ldGFcIjoge1xyXG4gICAgICAgIFwiYWxsb3dlZEluXCI6IFtcclxuICAgICAgICAgIFwiYnBtbjpTdGFydEV2ZW50XCIsXHJcbiAgICAgICAgICBcImJwbW46VXNlclRhc2tcIlxyXG4gICAgICAgIF1cclxuICAgICAgfSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJmaWVsZHNcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIkZvcm1GaWVsZFwiLFxyXG4gICAgICAgICAgXCJpc01hbnlcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiYnVzaW5lc3NLZXlcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiRm9ybUZpZWxkXCIsXHJcbiAgICAgIFwic3VwZXJDbGFzc1wiOiBbIFwiRWxlbWVudFwiIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiaWRcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwibGFiZWxcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidHlwZVwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkYXRlUGF0dGVyblwiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJkZWZhdWx0VmFsdWVcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwicHJvcGVydGllc1wiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiUHJvcGVydGllc1wiXHJcbiAgICAgICAgfSxcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJ2YWxpZGF0aW9uXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJWYWxpZGF0aW9uXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhbHVlc1wiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiVmFsdWVcIixcclxuICAgICAgICAgIFwiaXNNYW55XCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIlZhbGlkYXRpb25cIixcclxuICAgICAgXCJzdXBlckNsYXNzXCI6IFsgXCJFbGVtZW50XCIgXSxcclxuICAgICAgXCJwcm9wZXJ0aWVzXCI6IFtcclxuICAgICAgICB7XHJcbiAgICAgICAgICBcIm5hbWVcIjogXCJjb25zdHJhaW50c1wiLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiQ29uc3RyYWludFwiLFxyXG4gICAgICAgICAgXCJpc01hbnlcIjogdHJ1ZVxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgXCJuYW1lXCI6IFwiQ29uc3RyYWludFwiLFxyXG4gICAgICBcInN1cGVyQ2xhc3NcIjogWyBcIkVsZW1lbnRcIiBdLFxyXG4gICAgICBcInByb3BlcnRpZXNcIjogW1xyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcIm5hbWVcIixcclxuICAgICAgICAgIFwidHlwZVwiOiBcIlN0cmluZ1wiLFxyXG4gICAgICAgICAgXCJpc0F0dHJcIjogdHJ1ZVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwiY29uZmlnXCIsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWVcclxuICAgICAgICB9XHJcbiAgICAgIF1cclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIFwibmFtZVwiOiBcIkNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uXCIsXHJcbiAgICAgIFwiaXNBYnN0cmFjdFwiOiB0cnVlLFxyXG4gICAgICBcImV4dGVuZHNcIjogW1xyXG4gICAgICAgIFwiYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvblwiXHJcbiAgICAgIF0sXHJcbiAgICAgIFwicHJvcGVydGllc1wiOiBbXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgXCJuYW1lXCI6IFwidmFyaWFibGVOYW1lXCIsXHJcbiAgICAgICAgICBcImlzQXR0clwiOiB0cnVlLFxyXG4gICAgICAgICAgXCJ0eXBlXCI6IFwiU3RyaW5nXCJcclxuICAgICAgICB9LFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIFwibmFtZVwiOiBcInZhcmlhYmxlRXZlbnRcIixcclxuICAgICAgICAgIFwiaXNBdHRyXCI6IHRydWUsXHJcbiAgICAgICAgICBcInR5cGVcIjogXCJTdHJpbmdcIlxyXG4gICAgICAgIH1cclxuICAgICAgXVxyXG4gICAgfVxyXG4gIF0sXHJcbiAgXCJlbXVtZXJhdGlvbnNcIjogWyBdXHJcbn1cclxuIiwiZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ3VzdG9tQ29udGV4dFBhZCB7XHJcbiAgY29uc3RydWN0b3IoY29uZmlnLCBjb250ZXh0UGFkLCBjcmVhdGUsIGVsZW1lbnRGYWN0b3J5LCBpbmplY3RvciwgdHJhbnNsYXRlKSB7XHJcbiAgICB0aGlzLmNyZWF0ZSA9IGNyZWF0ZTtcclxuICAgIHRoaXMuZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcclxuICAgIHRoaXMudHJhbnNsYXRlID0gdHJhbnNsYXRlO1xyXG4gICAgLy/oh6rliqjmkYbmlL7kvY3nva5cclxuICAgIGlmIChjb25maWcuYXV0b1BsYWNlICE9PSBmYWxzZSkge1xyXG4gICAgICB0aGlzLmF1dG9QbGFjZSA9IGluamVjdG9yLmdldCgnYXV0b1BsYWNlJywgZmFsc2UpO1xyXG4gICAgfVxyXG4gICAgLy/ms6jlhozlt6XlhbdcclxuICAgIGNvbnRleHRQYWQucmVnaXN0ZXJQcm92aWRlcih0aGlzKTtcclxuICB9XHJcbiAgZ2V0Q29udGV4dFBhZEVudHJpZXMoZWxlbWVudCkge1xyXG4gICAgY29uc3Qge1xyXG4gICAgICBhdXRvUGxhY2UsXHJcbiAgICAgIGNyZWF0ZSxcclxuICAgICAgZWxlbWVudEZhY3RvcnksXHJcbiAgICAgIHRyYW5zbGF0ZVxyXG4gICAgfSA9IHRoaXM7XHJcblxyXG4gICAgZnVuY3Rpb24gYXBwZW5kVXNlclRhc2soZXZlbnQsIGVsZW1lbnQpIHtcclxuICAgICAgaWYgKGF1dG9QbGFjZSkge1xyXG4gICAgICAgIGNvbnN0IHNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoeyB0eXBlOiAnYnBtbjpVc2VyVGFzaycgfSk7XHJcbiAgICAgICAgYXV0b1BsYWNlLmFwcGVuZChlbGVtZW50LCBzaGFwZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgYXBwZW5kVXNlclRhc2tTdGFydChldmVudCwgZWxlbWVudCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBhcHBlbmRVc2VyVGFza1N0YXJ0KGV2ZW50KSB7XHJcbiAgICAgICAgICBjb25zdCBzaGFwZSA9IGVsZW1lbnRGYWN0b3J5LmNyZWF0ZVNoYXBlKHsgdHlwZTogJ2JwbW46VXNlclRhc2snIH0pO1xyXG4gICAgICAgICAgY3JlYXRlLnN0YXJ0KGV2ZW50LCBzaGFwZSwgZWxlbWVudCk7XHJcbiAgICB9XHJcbiAgICBmdW5jdGlvbiBhcHBlbmRDYWxsQWN0aXZpdHlTdGFydChldmVudCkge1xyXG4gICAgICBjb25zdCBzaGFwZSA9IGVsZW1lbnRGYWN0b3J5LmNyZWF0ZVNoYXBlKHsgdHlwZTogJ2JwbW46Q2FsbEFjdGl2aXR5JyB9KTtcclxuICAgICAgY3JlYXRlLnN0YXJ0KGV2ZW50LCBzaGFwZSwgZWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gYXBwZW5kQ2FsbEFjdGl2aXR5KGV2ZW50LCBlbGVtZW50KSB7XHJcbiAgICAgICAgaWYgKGF1dG9QbGFjZSkge1xyXG4gICAgICAgICAgICBjb25zdCBzaGFwZSA9IGVsZW1lbnRGYWN0b3J5LmNyZWF0ZVNoYXBlKHsgdHlwZTogJ2JwbW46Q2FsbEFjdGl2aXR5JyB9KTtcclxuICAgICAgICAgICAgYXV0b1BsYWNlLmFwcGVuZChlbGVtZW50LCBzaGFwZSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYXBwZW5kQ2FsbEFjdGl2aXR5U3RhcnQoZXZlbnQsIGVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB7XHJcbiAgICAgICdhcHBlbmQudXNlci10YXNrJzoge1xyXG4gICAgICAgIGdyb3VwOiAnbW9kZWwnLFxyXG4gICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi11c2VyLXRhc2snLFxyXG4gICAgICAgIHRpdGxlOiB0cmFuc2xhdGUoJ0FwcGVuZCBTZXJ2aWNlVGFzaycpLFxyXG4gICAgICAgIGFjdGlvbjoge1xyXG4gICAgICAgICAgY2xpY2s6IGFwcGVuZFVzZXJUYXNrLFxyXG4gICAgICAgICAgZHJhZ3N0YXJ0OiBhcHBlbmRVc2VyVGFza1N0YXJ0XHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICAnYXBwZW5kLmNhbGwtYWN0aXZpdHknOntcclxuICAgICAgICAgIGdyb3VwOiAnbW9kZWwnLFxyXG4gICAgICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLWNhbGwtYWN0aXZpdHknLFxyXG4gICAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQXBwZW5kIENhbGxBY3Rpdml0eScpLFxyXG4gICAgICAgICAgYWN0aW9uOiB7XHJcbiAgICAgICAgICAgICAgY2xpY2s6IGFwcGVuZENhbGxBY3Rpdml0eSxcclxuICAgICAgICAgICAgICBkcmFnc3RhcnQ6IGFwcGVuZENhbGxBY3Rpdml0eVN0YXJ0XHJcbiAgICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgfVxyXG59XHJcbkN1c3RvbUNvbnRleHRQYWQuJGluamVjdCA9IFtcclxuICAnY29uZmlnJyxcclxuICAnY29udGV4dFBhZCcsXHJcbiAgJ2NyZWF0ZScsXHJcbiAgJ2VsZW1lbnRGYWN0b3J5JyxcclxuICAnaW5qZWN0b3InLFxyXG4gICd0cmFuc2xhdGUnXHJcbl07IiwiZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ3VzdG9tUGFsZXR0ZSB7XHJcbiAgY29uc3RydWN0b3IoY3JlYXRlLCBlbGVtZW50RmFjdG9yeSwgcGFsZXR0ZSwgdHJhbnNsYXRlKSB7XHJcbiAgICB0aGlzLmNyZWF0ZSA9IGNyZWF0ZTtcclxuICAgIHRoaXMuZWxlbWVudEZhY3RvcnkgPSBlbGVtZW50RmFjdG9yeTtcclxuICAgIHRoaXMudHJhbnNsYXRlID0gdHJhbnNsYXRlO1xyXG4gICAgcGFsZXR0ZS5yZWdpc3RlclByb3ZpZGVyKHRoaXMpO1xyXG4gIH1cclxuXHJcbiAgZ2V0UGFsZXR0ZUVudHJpZXMoZWxlbWVudCkge1xyXG4gICAgY29uc3Qge1xyXG4gICAgICBjcmVhdGUsXHJcbiAgICAgIGVsZW1lbnRGYWN0b3J5LFxyXG4gICAgICB0cmFuc2xhdGVcclxuICAgIH0gPSB0aGlzO1xyXG5cclxuICAgIGZ1bmN0aW9uIGNyZWF0ZVNlcnZpY2VUYXNrKGV2ZW50KSB7XHJcbiAgICAgIGNvbnN0IHNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoeyB0eXBlOiAnYnBtbjpVc2VyVGFzaycgfSk7XHJcbiAgICAgIGNyZWF0ZS5zdGFydChldmVudCwgc2hhcGUpO1xyXG4gICAgfVxyXG4gICAgICBmdW5jdGlvbiBjcmVhdGVDYWxsQWN0aXZpdHkoZXZlbnQpIHtcclxuICAgICAgICAgIGNvbnN0IHNoYXBlID0gZWxlbWVudEZhY3RvcnkuY3JlYXRlU2hhcGUoeyB0eXBlOiAnYnBtbjpDYWxsQWN0aXZpdHknIH0pO1xyXG4gICAgICAgICAgY3JlYXRlLnN0YXJ0KGV2ZW50LCBzaGFwZSk7XHJcbiAgICAgIH1cclxuXHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgJ2NyZWF0ZS51c2VyLXRhc2snOiB7XHJcbiAgICAgICAgZ3JvdXA6ICdhY3Rpdml0eScsXHJcbiAgICAgICAgY2xhc3NOYW1lOiAnYnBtbi1pY29uLXVzZXItdGFzaycsXHJcbiAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQ3JlYXRlIFVzZXJUYXNrJyksXHJcbiAgICAgICAgYWN0aW9uOiB7XHJcbiAgICAgICAgICBkcmFnc3RhcnQ6IGNyZWF0ZVNlcnZpY2VUYXNrLFxyXG4gICAgICAgICAgY2xpY2s6IGNyZWF0ZVNlcnZpY2VUYXNrXHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICAgICdjcmVhdGUuY2FsbC1hY3Rpdml0eSc6IHtcclxuICAgICAgICAgICAgZ3JvdXA6ICdhY3Rpdml0eScsXHJcbiAgICAgICAgICAgIGNsYXNzTmFtZTogJ2JwbW4taWNvbi1jYWxsLWFjdGl2aXR5JyxcclxuICAgICAgICAgICAgdGl0bGU6IHRyYW5zbGF0ZSgnQ3JlYXRlIENhbGxBY3Rpdml0eScpLFxyXG4gICAgICAgICAgICBhY3Rpb246IHtcclxuICAgICAgICAgICAgICAgIGRyYWdzdGFydDogY3JlYXRlQ2FsbEFjdGl2aXR5LFxyXG4gICAgICAgICAgICAgICAgY2xpY2s6IGNyZWF0ZUNhbGxBY3Rpdml0eVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuQ3VzdG9tUGFsZXR0ZS4kaW5qZWN0ID0gW1xyXG4gICdjcmVhdGUnLFxyXG4gICdlbGVtZW50RmFjdG9yeScsXHJcbiAgJ3BhbGV0dGUnLFxyXG4gICd0cmFuc2xhdGUnXHJcbl07IiwiaW1wb3J0IEN1c3RvbUNvbnRleHRQYWQgZnJvbSAnLi9DdXN0b21Db250ZXh0UGFkJztcclxuaW1wb3J0IEN1c3RvbVBhbGV0dGUgZnJvbSAnLi9DdXN0b21QYWxldHRlJztcclxuXHJcbmV4cG9ydCBkZWZhdWx0IHtcclxuICBfX2luaXRfXzogWyAnY3VzdG9tQ29udGV4dFBhZCcsICdjdXN0b21QYWxldHRlJyBdLFxyXG4gIGN1c3RvbUNvbnRleHRQYWQ6IFsgJ3R5cGUnLCBDdXN0b21Db250ZXh0UGFkIF0sXHJcbiAgY3VzdG9tUGFsZXR0ZTogWyAndHlwZScsIEN1c3RvbVBhbGV0dGUgXVxyXG59OyIsImltcG9ydCB0cmFuc2xhdGlvbnMgZnJvbSAnLi90cmFuc2xhdGlvbnNHZXJtYW4nO1xyXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiBjdXN0b21UcmFuc2xhdGUodGVtcGxhdGUsIHJlcGxhY2VtZW50cykge1xyXG4gIHJlcGxhY2VtZW50cyA9IHJlcGxhY2VtZW50cyB8fCB7fTtcclxuICB0ZW1wbGF0ZSA9IHRyYW5zbGF0aW9uc1t0ZW1wbGF0ZV0gfHwgdGVtcGxhdGU7XHJcbiAgcmV0dXJuIHRlbXBsYXRlLnJlcGxhY2UoL3soW159XSspfS9nLCBmdW5jdGlvbihfLCBrZXkpIHtcclxuXHQgdmFyIHN0ciA9IHJlcGxhY2VtZW50c1trZXldO1xyXG5cdCAgaWYodHJhbnNsYXRpb25zW3JlcGxhY2VtZW50c1trZXldXSAhPSBudWxsICYmIHRyYW5zbGF0aW9ucyBbcmVwbGFjZW1lbnRzW2tleV1dICE9ICd1bmRlZmluZWQnKXtcclxuXHRcdCAgc3RyID0gdHJhbnNsYXRpb25zW3JlcGxhY2VtZW50c1trZXldXTtcclxuXHQgIH1cclxuICAgIHJldHVybiAgc3RyIHx8ICd7JyArIGtleSArICd9JztcclxuICB9KTtcclxufSIsImV4cG9ydCBkZWZhdWx0IHtcclxuICAgIC8vIExhYmVsc1xyXG4gICAgJ0FjdGl2YXRlIHRoZSBnbG9iYWwgY29ubmVjdCB0b29sJyA6ICfmv4DmtLvlhajlsYDov57mjqXlt6XlhbcnLFxyXG4gICAgJ0FwcGVuZCB7dHlwZX0nOiAn6L+95YqgIHt0eXBlfScsXHJcbiAgICAnQXBwZW5kIEVuZEV2ZW50JzogJ+i/veWKoCDnu5PmnZ/kuovku7YgJyxcclxuICAgICdBcHBlbmQgVGFzayc6J+i/veWKoCDku7vliqEnLFxyXG4gICAgJ0FwcGVuZCBHYXRld2F5Jzon6L+95YqgIOe9keWFsycsXHJcbiAgICAnQXBwZW5kIEludGVybWVkaWF0ZS9Cb3VuZGFyeSBFdmVudCc6J+i/veWKoCDkuK3pl7Qv6L6555WMIOS6i+S7ticsXHJcbiAgICAnQWRkIExhbmUgYWJvdmUnOiAn5Zyo5LiK6Z2i5re75Yqg6YGTJyxcclxuICAgICdEaXZpZGUgaW50byB0d28gTGFuZXMnOiAn5YiG5Ymy5oiQ5Lik5Liq6YGTJyxcclxuICAgICdEaXZpZGUgaW50byB0aHJlZSBMYW5lcyc6ICfliIblibLmiJDkuInkuKrpgZMnLFxyXG4gICAgJ0FkZCBMYW5lIGJlbG93JzogJ+WcqOS4i+mdoua3u+WKoOmBkycsXHJcbiAgICAnQXBwZW5kIGNvbXBlbnNhdGlvbiBhY3Rpdml0eSc6ICfov73liqDooaXlgb/mtLvliqgnLFxyXG4gICAgJ0NoYW5nZSB0eXBlJzogJ+S/ruaUueexu+WeiycsXHJcbiAgICAnQ29ubmVjdCB1c2luZyBBc3NvY2lhdGlvbic6ICfkvb/nlKjlhbPogZTov57mjqUnLFxyXG4gICAgJ0Nvbm5lY3QgdXNpbmcgU2VxdWVuY2UvTWVzc2FnZUZsb3cgb3IgQXNzb2NpYXRpb24nOiAn5L2/55So6aG65bqPL+a2iOaBr+a1geaIluiAheWFs+iBlOi/nuaOpScsXHJcbiAgICAnQ29ubmVjdCB1c2luZyBEYXRhSW5wdXRBc3NvY2lhdGlvbic6ICfkvb/nlKjmlbDmja7ovpPlhaXlhbPogZTov57mjqUnLFxyXG4gICAgJ1JlbW92ZSc6ICfnp7vpmaQnLFxyXG4gICAgJ0FjdGl2YXRlIHRoZSBoYW5kIHRvb2wnOiAn5r+A5rS75oqT5omL5bel5YW3JyxcclxuICAgICdBY3RpdmF0ZSB0aGUgbGFzc28gdG9vbCc6ICfmv4DmtLvlpZfntKLlt6XlhbcnLFxyXG4gICAgJ0FjdGl2YXRlIHRoZSBjcmVhdGUvcmVtb3ZlIHNwYWNlIHRvb2wnOiAn5r+A5rS75Yib5bu6L+WIoOmZpOepuumXtOW3peWFtycsXHJcbiAgICAnQ3JlYXRlIGV4cGFuZGVkIFN1YlByb2Nlc3MnOiAn5Yib5bu65omp5bGV5a2Q6L+H56iLJyxcclxuICAgICdDcmVhdGUgSW50ZXJtZWRpYXRlVGhyb3dFdmVudC9Cb3VuZGFyeUV2ZW50JyA6ICfliJvlu7rkuK3pl7Tmipvlh7rkuovku7Yv6L6555WM5LqL5Lu2JyxcclxuICAgICdDcmVhdGUgUG9vbC9QYXJ0aWNpcGFudCc6ICfliJvlu7rmsaAv5Y+C5LiO6ICFJyxcclxuICAgICdQYXJhbGxlbCBNdWx0aSBJbnN0YW5jZSc6ICflubbooYzlpJrph43kuovku7YnLFxyXG4gICAgJ1NlcXVlbnRpYWwgTXVsdGkgSW5zdGFuY2UnOiAn5pe25bqP5aSa6YeN5LqL5Lu2JyxcclxuICAgICdEYXRhT2JqZWN0UmVmZXJlbmNlJzon5pWw5o2u5a+56LGh5Y+C6ICDJyxcclxuICAgICdEYXRhU3RvcmVSZWZlcmVuY2UnOifmlbDmja7lrZjlgqjlj4LogIMnLFxyXG4gICAgJ0xvb3AnOiAn5b6q546vJyxcclxuICAgICdBZC1ob2MnOiAn5Y2z5bitJyxcclxuICAgICdDcmVhdGUge3R5cGV9JzogJ+WIm+W7uiB7dHlwZX0nLFxyXG4gICAgJ0NyZWF0ZSBUYXNrJzon5Yib5bu65Lu75YqhJyxcclxuICAgICdDcmVhdGUgU3RhcnRFdmVudCc6J+WIm+W7uuW8gOWni+S6i+S7ticsXHJcbiAgICAnQ3JlYXRlIEVuZEV2ZW50Jzon5Yib5bu657uT5p2f5LqL5Lu2JyxcclxuICAgICdDcmVhdGUgR3JvdXAnOifliJvlu7rnu4QnLFxyXG4gICAgJ1Rhc2snOiAn5Lu75YqhJyxcclxuICAgICdTZW5kIFRhc2snOiAn5Y+R6YCB5Lu75YqhJyxcclxuICAgICdSZWNlaXZlIFRhc2snOiAn5o6l5pS25Lu75YqhJyxcclxuICAgICdVc2VyIFRhc2snOiAn55So5oi35Lu75YqhJyxcclxuICAgICdNYW51YWwgVGFzayc6ICfmiYvlt6Xku7vliqEnLFxyXG4gICAgJ0J1c2luZXNzIFJ1bGUgVGFzayc6ICfkuJrliqHop4TliJnku7vliqEnLFxyXG4gICAgJ1NlcnZpY2UgVGFzayc6ICfmnI3liqHku7vliqEnLFxyXG4gICAgJ1NjcmlwdCBUYXNrJzogJ+iEmuacrOS7u+WKoScsXHJcbiAgICAnQ2FsbCBBY3Rpdml0eSc6ICfosIPnlKjmtLvliqgnLFxyXG4gICAgJ1N1YiBQcm9jZXNzIChjb2xsYXBzZWQpJzogJ+WtkOa1geeoi++8iOaKmOWPoOeahO+8iScsXHJcbiAgICAnU3ViIFByb2Nlc3MgKGV4cGFuZGVkKSc6ICflrZDmtYHnqIvvvIjlsZXlvIDnmoTvvIknLFxyXG4gICAgJ1N0YXJ0IEV2ZW50JzogJ+W8gOWni+S6i+S7ticsXHJcbiAgICAnU3RhcnRFdmVudCc6ICflvIDlp4vkuovku7YnLFxyXG4gICAgJ0ludGVybWVkaWF0ZSBUaHJvdyBFdmVudCc6ICfkuK3pl7Tkuovku7YnLFxyXG4gICAgJ0VuZCBFdmVudCc6ICfnu5PmnZ/kuovku7YnLFxyXG4gICAgJ0VuZEV2ZW50JzogJ+e7k+adn+S6i+S7ticsXHJcbiAgICAnQ3JlYXRlIEdhdGV3YXknOiAn5Yib5bu6572R5YWzJyxcclxuICAgICdHYXRlV2F5Jzon572R5YWzJyxcclxuICAgICdDcmVhdGUgSW50ZXJtZWRpYXRlL0JvdW5kYXJ5IEV2ZW50JzogJ+WIm+W7uuS4remXtC/ovrnnlYzkuovku7YnLFxyXG4gICAgJ01lc3NhZ2UgU3RhcnQgRXZlbnQnOiAn5raI5oGv5byA5aeL5LqL5Lu2JyxcclxuICAgICdUaW1lciBTdGFydCBFdmVudCc6ICflrprml7blvIDlp4vkuovku7YnLFxyXG4gICAgJ0NvbmRpdGlvbmFsIFN0YXJ0IEV2ZW50JzogJ+adoeS7tuW8gOWni+S6i+S7ticsXHJcbiAgICAnU2lnbmFsIFN0YXJ0IEV2ZW50JzogJ+S/oeWPt+W8gOWni+S6i+S7ticsXHJcbiAgICAnRXJyb3IgU3RhcnQgRXZlbnQnOiAn6ZSZ6K+v5byA5aeL5LqL5Lu2JyxcclxuICAgICdFc2NhbGF0aW9uIFN0YXJ0IEV2ZW50JzogJ+WNh+e6p+W8gOWni+S6i+S7ticsXHJcbiAgICAnQ29tcGVuc2F0aW9uIFN0YXJ0IEV2ZW50JzogJ+ihpeWBv+W8gOWni+S6i+S7ticsXHJcbiAgICAnTWVzc2FnZSBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5raI5oGv5byA5aeL5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdUaW1lciBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5a6a5pe25byA5aeL5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdDb25kaXRpb25hbCBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5p2h5Lu25byA5aeL5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdTaWduYWwgU3RhcnQgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJzogJ+S/oeWPt+W8gOWni+S6i+S7tu+8iOmdnuS4reaWre+8iScsXHJcbiAgICAnRXNjYWxhdGlvbiBTdGFydCBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5Y2H57qn5byA5aeL5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdNZXNzYWdlIEludGVybWVkaWF0ZSBDYXRjaCBFdmVudCc6ICfmtojmga/kuK3pl7TmjZXojrfkuovku7YnLFxyXG4gICAgJ01lc3NhZ2UgSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JzogJ+a2iOaBr+S4remXtOaKm+WHuuS6i+S7ticsXHJcbiAgICAnVGltZXIgSW50ZXJtZWRpYXRlIENhdGNoIEV2ZW50JzogJ+WumuaXtuS4remXtOaNleiOt+S6i+S7ticsXHJcbiAgICAnRXNjYWxhdGlvbiBJbnRlcm1lZGlhdGUgVGhyb3cgRXZlbnQnOiAn5Y2H57qn5Lit6Ze05oqb5Ye65LqL5Lu2JyxcclxuICAgICdDb25kaXRpb25hbCBJbnRlcm1lZGlhdGUgQ2F0Y2ggRXZlbnQnOiAn5p2h5Lu25Lit6Ze05o2V6I635LqL5Lu2JyxcclxuICAgICdMaW5rIEludGVybWVkaWF0ZSBDYXRjaCBFdmVudCc6ICfpk77mjqXkuK3pl7TmjZXojrfkuovku7YnLFxyXG4gICAgJ0xpbmsgSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JzogJ+mTvuaOpeS4remXtOaKm+WHuuS6i+S7ticsXHJcbiAgICAnQ29tcGVuc2F0aW9uIEludGVybWVkaWF0ZSBUaHJvdyBFdmVudCc6ICfooaXlgb/kuK3pl7Tmipvlh7rkuovku7YnLFxyXG4gICAgJ1NpZ25hbCBJbnRlcm1lZGlhdGUgQ2F0Y2ggRXZlbnQnOiAn5L+h5Y+35Lit6Ze05o2V6I635LqL5Lu2JyxcclxuICAgICdTaWduYWwgSW50ZXJtZWRpYXRlIFRocm93IEV2ZW50JzogJ+S/oeWPt+S4remXtOaKm+WHuuS6i+S7ticsXHJcbiAgICAnTWVzc2FnZSBFbmQgRXZlbnQnOiAn5raI5oGv57uT5p2f5LqL5Lu2JyxcclxuICAgICdFc2NhbGF0aW9uIEVuZCBFdmVudCc6ICflrprml7bnu5PmnZ/kuovku7YnLFxyXG4gICAgJ0Vycm9yIEVuZCBFdmVudCc6ICfplJnor6/nu5PmnZ/kuovku7YnLFxyXG4gICAgJ0NhbmNlbCBFbmQgRXZlbnQnOiAn5Y+W5raI57uT5p2f5LqL5Lu2JyxcclxuICAgICdDb21wZW5zYXRpb24gRW5kIEV2ZW50JzogJ+ihpeWBv+e7k+adn+S6i+S7ticsXHJcbiAgICAnU2lnbmFsIEVuZCBFdmVudCc6ICfkv6Hlj7fnu5PmnZ/kuovku7YnLFxyXG4gICAgJ1Rlcm1pbmF0ZSBFbmQgRXZlbnQnOiAn57uI5q2i57uT5p2f5LqL5Lu2JyxcclxuICAgICdNZXNzYWdlIEJvdW5kYXJ5IEV2ZW50JzogJ+a2iOaBr+i+ueeVjOS6i+S7ticsXHJcbiAgICAnTWVzc2FnZSBCb3VuZGFyeSBFdmVudCAobm9uLWludGVycnVwdGluZyknOiAn5raI5oGv6L6555WM5LqL5Lu277yI6Z2e5Lit5pat77yJJyxcclxuICAgICdUaW1lciBCb3VuZGFyeSBFdmVudCc6ICflrprml7bovrnnlYzkuovku7YnLFxyXG4gICAgJ1RpbWVyIEJvdW5kYXJ5IEV2ZW50IChub24taW50ZXJydXB0aW5nKSc6ICflrprml7bovrnnlYzkuovku7bvvIjpnZ7kuK3mlq3vvIknLFxyXG4gICAgJ0VzY2FsYXRpb24gQm91bmRhcnkgRXZlbnQnOiAn5Y2H57qn6L6555WM5LqL5Lu2JyxcclxuICAgICdFc2NhbGF0aW9uIEJvdW5kYXJ5IEV2ZW50IChub24taW50ZXJydXB0aW5nKSc6ICfljYfnuqfovrnnlYzkuovku7bvvIjpnZ7kuK3mlq3vvIknLFxyXG4gICAgJ0NvbmRpdGlvbmFsIEJvdW5kYXJ5IEV2ZW50JzogJ+adoeS7tui+ueeVjOS6i+S7ticsXHJcbiAgICAnQ29uZGl0aW9uYWwgQm91bmRhcnkgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJzogJ+adoeS7tui+ueeVjOS6i+S7tu+8iOmdnuS4reaWre+8iScsXHJcbiAgICAnRXJyb3IgQm91bmRhcnkgRXZlbnQnOiAn6ZSZ6K+v6L6555WM5LqL5Lu2JyxcclxuICAgICdDYW5jZWwgQm91bmRhcnkgRXZlbnQnOiAn5Y+W5raI6L6555WM5LqL5Lu2JyxcclxuICAgICdTaWduYWwgQm91bmRhcnkgRXZlbnQnOiAn5L+h5Y+36L6555WM5LqL5Lu2JyxcclxuICAgICdTaWduYWwgQm91bmRhcnkgRXZlbnQgKG5vbi1pbnRlcnJ1cHRpbmcpJzogJ+S/oeWPt+i+ueeVjOS6i+S7tu+8iOmdnuS4reaWre+8iScsXHJcbiAgICAnQ29tcGVuc2F0aW9uIEJvdW5kYXJ5IEV2ZW50JzogJ+ihpeWBv+i+ueeVjOS6i+S7ticsXHJcbiAgICAnRXhjbHVzaXZlIEdhdGV3YXknOiAn5LqS5pal572R5YWzJyxcclxuICAgICdQYXJhbGxlbCBHYXRld2F5JzogJ+W5tuihjOe9keWFsycsXHJcbiAgICAnSW5jbHVzaXZlIEdhdGV3YXknOiAn55u45a65572R5YWzJyxcclxuICAgICdDb21wbGV4IEdhdGV3YXknOiAn5aSN5p2C572R5YWzJyxcclxuICAgICdFdmVudCBiYXNlZCBHYXRld2F5JzogJ+S6i+S7tue9keWFsycsXHJcbiAgICAnVHJhbnNhY3Rpb24nOiAn6L2s6L+QJyxcclxuICAgICdTdWIgUHJvY2Vzcyc6ICflrZDmtYHnqIsnLFxyXG4gICAgJ0V2ZW50IFN1YiBQcm9jZXNzJzogJ+S6i+S7tuWtkOa1geeoiycsXHJcbiAgICAnQ29sbGFwc2VkIFBvb2wnOiAn5oqY5Y+g5rGgJyxcclxuICAgICdFeHBhbmRlZCBQb29sJzogJ+WxleW8gOaxoCcsXHJcbiAgICAvLyBFcnJvcnNcclxuICAgICdubyBwYXJlbnQgZm9yIHtlbGVtZW50fSBpbiB7cGFyZW50fSc6ICflnKh7cGFyZW50femHjO+8jHtlbGVtZW50feayoeacieeItuexuycsXHJcbiAgICAnbm8gc2hhcGUgdHlwZSBzcGVjaWZpZWQnOiAn5rKh5pyJ5oyH5a6a55qE5b2i54q257G75Z6LJyxcclxuICAgICdmbG93IGVsZW1lbnRzIG11c3QgYmUgY2hpbGRyZW4gb2YgcG9vbHMvcGFydGljaXBhbnRzJzogJ+a1geWFg+e0oOW/hemhu+aYr+axoC/lj4LkuI7ogIXnmoTlrZDnsbsnLFxyXG4gICAgJ291dCBvZiBib3VuZHMgcmVsZWFzZSc6ICdvdXQgb2YgYm91bmRzIHJlbGVhc2UnLFxyXG4gICAgJ21vcmUgdGhhbiB7Y291bnR9IGNoaWxkIGxhbmVzJzogJ+WtkOmBk+Wkp+S6jntjb3VudH0gJyxcclxuICAgICdlbGVtZW50IHJlcXVpcmVkJzogJ+WFg+e0oOS4jeiDveS4uuepuicsXHJcbiAgICAnZGlhZ3JhbSBub3QgcGFydCBvZiBicG1uOkRlZmluaXRpb25zJzogJ+a1geeoi+WbvuS4jeespuWQiGJwbW7op4TojIMnLFxyXG4gICAgJ25vIGRpYWdyYW0gdG8gZGlzcGxheSc6ICfmsqHmnInlj6/lsZXnpLrnmoTmtYHnqIvlm74nLFxyXG4gICAgJ25vIHByb2Nlc3Mgb3IgY29sbGFib3JhdGlvbiB0byBkaXNwbGF5JzogJ+ayoeacieWPr+WxleekuueahOa1geeoiy/ljY/kvZwnLFxyXG4gICAgJ2VsZW1lbnQge2VsZW1lbnR9IHJlZmVyZW5jZWQgYnkge3JlZmVyZW5jZWR9I3twcm9wZXJ0eX0gbm90IHlldCBkcmF3bic6ICfnlLF7cmVmZXJlbmNlZH0je3Byb3BlcnR5feW8leeUqOeahHtlbGVtZW50feWFg+e0oOS7jeacque7mOWIticsXHJcbiAgICAnYWxyZWFkeSByZW5kZXJlZCB7ZWxlbWVudH0nOiAne2VsZW1lbnR9IOW3suiiq+a4suafkycsXHJcbiAgICAnZmFpbGVkIHRvIGltcG9ydCB7ZWxlbWVudH0nOiAn5a+85YWle2VsZW1lbnR95aSx6LSlJyxcclxuICAgIC8v5bGe5oCn6Z2i5p2/55qE5Y+C5pWwXHJcbiAgICAnSWQnOifnvJblj7cnLFxyXG4gICAgJ05hbWUnOiflkI3np7AnLFxyXG4gICAgJ0dlbmVyYWwnOifluLjop4QnLFxyXG4gICAgJ0RldGFpbHMnOifor6bmg4UnLFxyXG4gICAgJ01lc3NhZ2UgTmFtZSc6J+a2iOaBr+WQjeensCcsXHJcbiAgICAnTWVzc2FnZSc6J+a2iOaBrycsXHJcbiAgICAnSW5pdGlhdG9yJzon5Yib5bu66ICFJyxcclxuICAgICdBc3luY2hyb25vdXMgQ29udGludWF0aW9ucyc6J+aMgee7reW8guatpScsXHJcbiAgICAnQXN5bmNocm9ub3VzIEJlZm9yZSc6J+W8guatpeWJjScsXHJcbiAgICAnQXN5bmNocm9ub3VzIEFmdGVyJzon5byC5q2l5ZCOJyxcclxuICAgICdKb2IgQ29uZmlndXJhdGlvbic6J+W3peS9nOmFjee9ricsXHJcbiAgICAnRXhjbHVzaXZlJzon5o6S6ZmkJyxcclxuICAgICdKb2IgUHJpb3JpdHknOiflt6XkvZzkvJjlhYjnuqcnLFxyXG4gICAgJ1JldHJ5IFRpbWUgQ3ljbGUnOifph43or5Xml7bpl7TlkajmnJ8nLFxyXG4gICAgJ0RvY3VtZW50YXRpb24nOifmlofmoaMnLFxyXG4gICAgJ0VsZW1lbnQgRG9jdW1lbnRhdGlvbic6J+WFg+e0oOaWh+ahoycsXHJcbiAgICAnSGlzdG9yeSBDb25maWd1cmF0aW9uJzon5Y6G5Y+y6YWN572uJyxcclxuICAgICdIaXN0b3J5IFRpbWUgVG8gTGl2ZSc6J+WOhuWPsueahOeUn+WtmOaXtumXtCcsXHJcbiAgICAnRm9ybXMnOifooajljZUnLFxyXG4gICAgJ0Zvcm0gS2V5Jzon6KGo5Y2Va2V5JyxcclxuICAgICdGb3JtIEZpZWxkcyc6J+ihqOWNleWtl+autScsXHJcbiAgICAnQnVzaW5lc3MgS2V5Jzon5Lia5Yqha2V5JyxcclxuICAgICdGb3JtIEZpZWxkJzon6KGo5Y2V5a2X5q61JyxcclxuICAgICdJRCc6J+e8luWPtycsXHJcbiAgICAnVHlwZSc6J+exu+WeiycsXHJcbiAgICAnTGFiZWwnOiflkI3np7AnLFxyXG4gICAgJ0RlZmF1bHQgVmFsdWUnOifpu5jorqTlgLwnLFxyXG4gICAgJ1ZhbGlkYXRpb24nOifmoKHpqownLFxyXG4gICAgJ0FkZCBDb25zdHJhaW50Jzon5re75Yqg57qm5p2fJyxcclxuICAgICdDb25maWcnOifphY3nva4nLFxyXG4gICAgJ1Byb3BlcnRpZXMnOiflsZ7mgKcnLFxyXG4gICAgJ0FkZCBQcm9wZXJ0eSc6J+a3u+WKoOWxnuaApycsXHJcbiAgICAnVmFsdWUnOiflgLwnLFxyXG4gICAgJ0FkZCc6J+a3u+WKoCcsXHJcbiAgICAnVmFsdWVzJzon5YC8JyxcclxuICAgICdBZGQgVmFsdWUnOifmt7vliqDlgLwnLFxyXG4gICAgJ0xpc3RlbmVycyc6J+ebkeWQrOWZqCcsXHJcbiAgICAnRXhlY3V0aW9uIExpc3RlbmVyJzon5omn6KGM55uR5ZCsJyxcclxuICAgICdFdmVudCBUeXBlJzon5LqL5Lu257G75Z6LJyxcclxuICAgICdMaXN0ZW5lciBUeXBlJzon55uR5ZCs5Zmo57G75Z6LJyxcclxuICAgICdKYXZhIENsYXNzJzonSmF2YeexuycsXHJcbiAgICAnRXhwcmVzc2lvbic6J+ihqOi+vuW8jycsXHJcbiAgICAnTXVzdCBwcm92aWRlIGEgdmFsdWUnOiflv4Xpobvmj5DkvpvkuIDkuKrlgLwnLFxyXG4gICAgJ0RlbGVnYXRlIEV4cHJlc3Npb24nOifku6PnkIbooajovr7lvI8nLFxyXG4gICAgJ1NjcmlwdCc6J+iEmuacrCcsXHJcbiAgICAnU2NyaXB0IEZvcm1hdCc6J+iEmuacrOagvOW8jycsXHJcbiAgICAnU2NyaXB0IFR5cGUnOifohJrmnKznsbvlnosnLFxyXG4gICAgJ0lubGluZSBTY3JpcHQnOiflhoXogZTohJrmnKwnLFxyXG4gICAgJ0V4dGVybmFsIFNjcmlwdCc6J+WklumDqOiEmuacrCcsXHJcbiAgICAnUmVzb3VyY2UnOifotYTmupAnLFxyXG4gICAgJ0ZpZWxkIEluamVjdGlvbic6J+Wtl+auteazqOWFpScsXHJcbiAgICAnRXh0ZW5zaW9ucyc6J+aJqeWxlScsXHJcbiAgICAnSW5wdXQvT3V0cHV0Jzon6L6T5YWlL+i+k+WHuicsXHJcbiAgICAnSW5wdXQgUGFyYW1ldGVycyc6J+i+k+WFpeWPguaVsCcsXHJcbiAgICAnT3V0cHV0IFBhcmFtZXRlcnMnOifovpPlh7rlj4LmlbAnLFxyXG4gICAgJ1BhcmFtZXRlcnMnOiflj4LmlbAnLFxyXG4gICAgJ091dHB1dCBQYXJhbWV0ZXInOifovpPlh7rlj4LmlbAnLFxyXG4gICAgJ1RpbWVyIERlZmluaXRpb24gVHlwZSc6J+WumuaXtuWZqOWumuS5ieexu+WeiycsXHJcbiAgICAnVGltZXIgRGVmaW5pdGlvbic6J+WumuaXtuWZqOWumuS5iScsXHJcbiAgICAnRGF0ZSc6J+aXpeacnycsXHJcbiAgICAnRHVyYXRpb24nOifmjIHnu60nLFxyXG4gICAgJ0N5Y2xlJzon5b6q546vJyxcclxuICAgICdTaWduYWwnOifkv6Hlj7cnLFxyXG4gICAgJ1NpZ25hbCBOYW1lJzon5L+h5Y+35ZCN56ewJyxcclxuICAgICdFc2NhbGF0aW9uJzon5Y2H57qnJyxcclxuICAgICdFcnJvcic6J+mUmeivrycsXHJcbiAgICAnTGluayBOYW1lJzon6ZO+5o6l5ZCN56ewJyxcclxuICAgICdDb25kaXRpb24nOifmnaHku7blkI3np7AnLFxyXG4gICAgJ1ZhcmlhYmxlIE5hbWUnOiflj5jph4/lkI3np7AnLFxyXG4gICAgJ1ZhcmlhYmxlIEV2ZW50Jzon5Y+Y6YeP5LqL5Lu2JyxcclxuICAgICdTcGVjaWZ5IG1vcmUgdGhhbiBvbmUgdmFyaWFibGUgY2hhbmdlIGV2ZW50IGFzIGEgY29tbWEgc2VwYXJhdGVkIGxpc3QuJzon5aSa5Liq5Y+Y6YeP5LqL5Lu25Lul6YCX5Y+36ZqU5byAJyxcclxuICAgICdXYWl0IGZvciBDb21wbGV0aW9uJzon562J5b6F5a6M5oiQJyxcclxuICAgICdBY3Rpdml0eSBSZWYnOifmtLvliqjlj4LogIMnLFxyXG4gICAgJ1ZlcnNpb24gVGFnJzon54mI5pys5qCH562+JyxcclxuICAgICdFeGVjdXRhYmxlJzon5Y+v5omn6KGM5paH5Lu2JyxcclxuICAgICdFeHRlcm5hbCBUYXNrIENvbmZpZ3VyYXRpb24nOifmianlsZXku7vliqHphY3nva4nLFxyXG4gICAgJ1Rhc2sgUHJpb3JpdHknOifku7vliqHkvJjlhYjnuqcnLFxyXG4gICAgJ0V4dGVybmFsJzon5aSW6YOoJyxcclxuICAgICdDb25uZWN0b3InOifov57mjqXlmagnLFxyXG4gICAgJ011c3QgY29uZmlndXJlIENvbm5lY3Rvcic6J+W/hemhu+mFjee9rui/nuaOpeWZqCcsXHJcbiAgICAnQ29ubmVjdG9yIElkJzon6L+e5o6l5Zmo57yW5Y+3JyxcclxuICAgICdJbXBsZW1lbnRhdGlvbic6J+WunueOsOaWueW8jycsXHJcbiAgICAnRmllbGQgSW5qZWN0aW9ucyc6J+Wtl+auteazqOWFpScsXHJcbiAgICAnRmllbGRzJzon5a2X5q61JyxcclxuICAgICdSZXN1bHQgVmFyaWFibGUnOifnu5Pmnpzlj5jph48nLFxyXG4gICAgJ1RvcGljJzon5Li76aKYJyxcclxuICAgICdDb25maWd1cmUgQ29ubmVjdG9yJzon6YWN572u6L+e5o6l5ZmoJyxcclxuICAgICdJbnB1dCBQYXJhbWV0ZXInOifovpPlhaXlj4LmlbAnLFxyXG4gICAgJ0Fzc2lnbmVlJzon5Luj55CG5Lq6JyxcclxuICAgICdDYW5kaWRhdGUgVXNlcnMnOiflgJnpgInnlKjmiLcnLFxyXG4gICAgJ0NhbmRpZGF0ZSBHcm91cHMnOiflgJnpgInnu4QnLFxyXG4gICAgJ0R1ZSBEYXRlJzon5Yiw5pyf5pe26Ze0JyxcclxuICAgICdGb2xsb3cgVXAgRGF0ZSc6J+i3n+i4quaXpeacnycsXHJcbiAgICAnUHJpb3JpdHknOifkvJjlhYjnuqcnLFxyXG4gICAgJ1RoZSBmb2xsb3cgdXAgZGF0ZSBhcyBhbiBFTCBleHByZXNzaW9uIChlLmcuICR7c29tZURhdGV9IG9yIGFuIElTTyBkYXRlIChlLmcuIDIwMTUtMDYtMjZUMDk6NTQ6MDApJzon6Lef6Liq5pel5pyf5b+F6aG756ym5ZCIRUzooajovr7lvI/vvIzlpoLvvJogJHtzb21lRGF0ZX0gLOaIluiAheS4gOS4qklTT+agh+WHhuaXpeacn++8jOWmgu+8mjIwMTUtMDYtMjZUMDk6NTQ6MDAnLFxyXG4gICAgJ1RoZSBkdWUgZGF0ZSBhcyBhbiBFTCBleHByZXNzaW9uIChlLmcuICR7c29tZURhdGV9IG9yIGFuIElTTyBkYXRlIChlLmcuIDIwMTUtMDYtMjZUMDk6NTQ6MDApJzon6Lef6Liq5pel5pyf5b+F6aG756ym5ZCIRUzooajovr7lvI/vvIzlpoLvvJogJHtzb21lRGF0ZX0gLOaIluiAheS4gOS4qklTT+agh+WHhuaXpeacn++8jOWmgu+8mjIwMTUtMDYtMjZUMDk6NTQ6MDAnLFxyXG4gICAgJ1ZhcmlhYmxlcyc6J+WPmOmHjycsXHJcbiAgICAnQ2FuZGlkYXRlIFN0YXJ0ZXIgQ29uZmlndXJhdGlvbic6J+WAmemAieW8gOWni+mFjee9ricsXHJcbiAgICAnVGFzayBMaXN0ZW5lcic6J+S7u+WKoeebkeWQrOWZqCcsXHJcbiAgICAnQ2FuZGlkYXRlIFN0YXJ0ZXIgR3JvdXBzJzon5YCZ6YCJ5byA5aeL57uEJyxcclxuICAgICdDYW5kaWRhdGUgU3RhcnRlciBVc2Vycyc6J+WAmemAieW8gOWni+eUqOaItycsXHJcbiAgICAnVGFza2xpc3QgQ29uZmlndXJhdGlvbic6J+S7u+WKoeWIl+ihqOmFjee9ricsXHJcbiAgICAnU3RhcnRhYmxlJzon5ZCv5YqoJyxcclxuICAgICdTcGVjaWZ5IG1vcmUgdGhhbiBvbmUgZ3JvdXAgYXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdC4nOifmjIflrprlpJrkuKrnu4Qs55So6YCX5Y+35YiG6ZqUJyxcclxuICAgICdTcGVjaWZ5IG1vcmUgdGhhbiBvbmUgdXNlciBhcyBhIGNvbW1hIHNlcGFyYXRlZCBsaXN0Lic6J+aMh+WumuWkmuS4queUqOaItyznlKjpgJflj7fliIbpmpQnLFxyXG4gICAgJ1RoaXMgbWFwcyB0byB0aGUgcHJvY2VzcyBkZWZpbml0aW9uIGtleS4nOifov5nkvJrmmKDlsITkuLrmtYHnqIvlrprkuYnnmoTplK4nLFxyXG4gICAgJ0NhbGxBY3Rpdml0eSBUeXBlJzon6LCD55So5rS75Yqo57G75Z6LJyxcclxuICAgICdDb25kaXRpb24gVHlwZSc6J+adoeS7tuexu+WeiycsXHJcbiAgICAnQ3JlYXRlIFVzZXJUYXNrJzon5Yib5bu655So5oi35Lu75YqhJyxcclxuICAgICdDcmVhdGUgQ2FsbEFjdGl2aXR5Jzon5Yib5bu66LCD55So5rS75YqoJyxcclxuICAgICdDYWxsZWQgRWxlbWVudCc6J+iwg+eUqOWFg+e0oCcsXHJcbiAgICAnQ3JlYXRlIERhdGFPYmplY3RSZWZlcmVuY2UnOifliJvlu7rmlbDmja7lr7nosaHlvJXnlKgnLFxyXG4gICAgJ0NyZWF0ZSBEYXRhU3RvcmVSZWZlcmVuY2UnOifliJvlu7rmlbDmja7lrZjlgqjlvJXnlKgnLFxyXG4gICAgJ011bHRpIEluc3RhbmNlJzon5aSa5a6e5L6LJyxcclxuICAgICdMb29wIENhcmRpbmFsaXR5Jzon5a6e5L6L5pWw6YePJyxcclxuICAgICdDb2xsZWN0aW9uJzon5Lu75Yqh5Y+C5LiO5Lq65YiX6KGoJyxcclxuICAgICdFbGVtZW50IFZhcmlhYmxlJzon5YWD57Sg5Y+Y6YePJyxcclxuICAgICdDb21wbGV0aW9uIENvbmRpdGlvbic6J+WujOaIkOadoeS7tidcclxufTtcclxuIiwibW9kdWxlLmV4cG9ydHMgPSBcIjw/eG1sIHZlcnNpb249XFxcIjEuMFxcXCIgZW5jb2Rpbmc9XFxcIlVURi04XFxcIj8+XFxyXFxuPGJwbW4yOmRlZmluaXRpb25zIHhtbG5zOnhzaT1cXFwiaHR0cDovL3d3dy53My5vcmcvMjAwMS9YTUxTY2hlbWEtaW5zdGFuY2VcXFwiIHhtbG5zOmJwbW4yPVxcXCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9CUE1OLzIwMTAwNTI0L01PREVMXFxcIiB4bWxuczpicG1uZGk9XFxcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0JQTU4vMjAxMDA1MjQvRElcXFwiIHhtbG5zOmRjPVxcXCJodHRwOi8vd3d3Lm9tZy5vcmcvc3BlYy9ERC8yMDEwMDUyNC9EQ1xcXCIgeG1sbnM6ZGk9XFxcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0RELzIwMTAwNTI0L0RJXFxcIiB4c2k6c2NoZW1hTG9jYXRpb249XFxcImh0dHA6Ly93d3cub21nLm9yZy9zcGVjL0JQTU4vMjAxMDA1MjQvTU9ERUwgQlBNTjIwLnhzZFxcXCIgaWQ9XFxcInNhbXBsZS1kaWFncmFtXFxcIiB0YXJnZXROYW1lc3BhY2U9XFxcImh0dHA6Ly9hY3Rpdml0aS5vcmcvYnBtblxcXCI+XFxyXFxuICA8YnBtbjI6cHJvY2VzcyBpZD1cXFwiUHJvY2Vzc18xXFxcIiBpc0V4ZWN1dGFibGU9XFxcInRydWVcXFwiPlxcclxcbiAgICA8YnBtbjI6c3RhcnRFdmVudCBpZD1cXFwiU3RhcnRFdmVudF8xXFxcIi8+XFxyXFxuICA8L2JwbW4yOnByb2Nlc3M+XFxyXFxuICA8YnBtbmRpOkJQTU5EaWFncmFtIGlkPVxcXCJCUE1ORGlhZ3JhbV8xXFxcIj5cXHJcXG4gICAgPGJwbW5kaTpCUE1OUGxhbmUgaWQ9XFxcIkJQTU5QbGFuZV8xXFxcIiBicG1uRWxlbWVudD1cXFwiUHJvY2Vzc18xXFxcIj5cXHJcXG4gICAgICA8YnBtbmRpOkJQTU5TaGFwZSBpZD1cXFwiX0JQTU5TaGFwZV9TdGFydEV2ZW50XzJcXFwiIGJwbW5FbGVtZW50PVxcXCJTdGFydEV2ZW50XzFcXFwiPlxcclxcbiAgICAgICAgPGRjOkJvdW5kcyBoZWlnaHQ9XFxcIjM2LjBcXFwiIHdpZHRoPVxcXCIzNi4wXFxcIiB4PVxcXCI0MTIuMFxcXCIgeT1cXFwiMjQwLjBcXFwiLz5cXHJcXG4gICAgICA8L2JwbW5kaTpCUE1OU2hhcGU+XFxyXFxuICAgIDwvYnBtbmRpOkJQTU5QbGFuZT5cXHJcXG4gIDwvYnBtbmRpOkJQTU5EaWFncmFtPlxcclxcbjwvYnBtbjI6ZGVmaW5pdGlvbnM+XCI7XG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgREVGQVVMVF9QUklPUklUWSA9IDEwMDA7XHJcblxyXG5cclxuLyoqXHJcbiAqIEEgY29tcG9uZW50IHRoYXQgZGVjaWRlcyB1cG9uIHRoZSB2aXNpYmlsaXR5IC8gZWRpdGFibGVcclxuICogc3RhdGUgb2YgcHJvcGVydGllcyBpbiB0aGUgcHJvcGVydGllcyBwYW5lbC5cclxuICpcclxuICogSW1wbGVtZW50b3JzIG11c3Qgc3ViY2xhc3MgdGhpcyBjb21wb25lbnQgYW5kIG92ZXJyaWRlXHJcbiAqIHtAbGluayBQcm9wZXJ0aWVzQWN0aXZhdG9yI2lzRW50cnlWaXNpYmxlfSBhbmRcclxuICoge0BsaW5rIFByb3BlcnRpZXNBY3RpdmF0b3IjaXNQcm9wZXJ0eUVkaXRhYmxlfSB0byBwcm92aWRlXHJcbiAqIGN1c3RvbSBiZWhhdmlvci5cclxuICpcclxuICogQGNsYXNzXHJcbiAqIEBjb25zdHJ1Y3RvclxyXG4gKlxyXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xyXG4gKiBAcGFyYW0ge051bWJlcn0gW3ByaW9yaXR5XSBhdCB3aGljaCBwcmlvcml0eSB0byBob29rIGludG8gdGhlIGFjdGl2YXRpb25cclxuICovXHJcbmZ1bmN0aW9uIFByb3BlcnRpZXNBY3RpdmF0b3IoZXZlbnRCdXMsIHByaW9yaXR5KSB7XHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICBwcmlvcml0eSA9IHByaW9yaXR5IHx8IERFRkFVTFRfUFJJT1JJVFk7XHJcblxyXG4gIGV2ZW50QnVzLm9uKCdwcm9wZXJ0aWVzUGFuZWwuaXNFbnRyeVZpc2libGUnLCBwcmlvcml0eSwgZnVuY3Rpb24oZSkge1xyXG4gICAgcmV0dXJuIHNlbGYuaXNFbnRyeVZpc2libGUoZS5lbnRyeSwgZS5lbGVtZW50KTtcclxuICB9KTtcclxuXHJcbiAgZXZlbnRCdXMub24oJ3Byb3BlcnRpZXNQYW5lbC5pc1Byb3BlcnR5RWRpdGFibGUnLCBwcmlvcml0eSwgZnVuY3Rpb24oZSkge1xyXG4gICAgcmV0dXJuIHNlbGYuaXNQcm9wZXJ0eUVkaXRhYmxlKGUuZW50cnksIGUucHJvcGVydHlOYW1lLCBlLmVsZW1lbnQpO1xyXG4gIH0pO1xyXG59XHJcblxyXG5Qcm9wZXJ0aWVzQWN0aXZhdG9yLiRpbmplY3QgPSBbICdldmVudEJ1cycgXTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gUHJvcGVydGllc0FjdGl2YXRvcjtcclxuXHJcblxyXG4vKipcclxuICogU2hvdWxkIHRoZSBnaXZlbiBlbnRyeSBiZSB2aXNpYmxlIGZvciB0aGUgc3BlY2lmaWVkIGVsZW1lbnQuXHJcbiAqXHJcbiAqIEBtZXRob2QgIFByb3BlcnRpZXNBY3RpdmF0b3IjaXNFbnRyeVZpc2libGVcclxuICpcclxuICogQHBhcmFtIHtFbnRyeURlc2NyaXB0b3J9IGVudHJ5XHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn1cclxuICovXHJcblByb3BlcnRpZXNBY3RpdmF0b3IucHJvdG90eXBlLmlzRW50cnlWaXNpYmxlID0gZnVuY3Rpb24oZW50cnksIGVsZW1lbnQpIHtcclxuICByZXR1cm4gdHJ1ZTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBTaG91bGQgdGhlIGdpdmVuIHByb3BlcnR5IGJlIGVkaXRhYmxlIGZvciB0aGUgc3BlY2lmaWVkIGVsZW1lbnRcclxuICpcclxuICogQG1ldGhvZCAgUHJvcGVydGllc0FjdGl2YXRvciNpc1Byb3BlcnR5RWRpdGFibGVcclxuICpcclxuICogQHBhcmFtIHtFbnRyeURlc2NyaXB0b3J9IGVudHJ5XHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eU5hbWVcclxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm5zIHtCb29sZWFufVxyXG4gKi9cclxuUHJvcGVydGllc0FjdGl2YXRvci5wcm90b3R5cGUuaXNQcm9wZXJ0eUVkaXRhYmxlID0gZnVuY3Rpb24oZW50cnksIHByb3BlcnR5TmFtZSwgZWxlbWVudCkge1xyXG4gIHJldHVybiB0cnVlO1xyXG59OyIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBkb21RdWVyeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeSxcclxuICAgIGRvbUNsZWFyID0gcmVxdWlyZSgnbWluLWRvbScpLmNsZWFyLFxyXG4gICAgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyksXHJcbiAgICBkb21pZnkgPSByZXF1aXJlKCdtaW4tZG9tJykuZG9taWZ5LFxyXG4gICAgSWRzID0gcmVxdWlyZSgnaWRzJykuZGVmYXVsdDtcclxuXHJcbnZhciBTUEFDRV9SRUdFWCA9IC9cXHMvO1xyXG5cclxuLy8gZm9yIFFOYW1lIHZhbGlkYXRpb24gYXMgcGVyIGh0dHA6Ly93d3cudzMub3JnL1RSL1JFQy14bWwvI05ULU5hbWVDaGFyXHJcbnZhciBRTkFNRV9SRUdFWCA9IC9eKFthLXpdW1xcdy0uXSo6KT9bYS16X11bXFx3LS5dKiQvaTtcclxuXHJcbi8vIGZvciBJRCB2YWxpZGF0aW9uIGFzIHBlciBCUE1OIFNjaGVtYSAoUU5hbWUgLSBOYW1lc3BhY2UpXHJcbnZhciBJRF9SRUdFWCA9IC9eW2Etel9dW1xcdy0uXSokL2k7XHJcblxyXG52YXIgUExBQ0VIT0xERVJfUkVHRVggPSAvXFwkXFx7KFtefV0qKVxcfS9nO1xyXG5cclxudmFyIEhUTUxfRVNDQVBFX01BUCA9IHtcclxuICAnJic6ICcmYW1wOycsXHJcbiAgJzwnOiAnJmx0OycsXHJcbiAgJz4nOiAnJmd0OycsXHJcbiAgJ1wiJzogJyZxdW90OycsXHJcbiAgJ1xcJyc6ICcmIzM5OydcclxufTtcclxuXHJcbmZ1bmN0aW9uIHNlbGVjdGVkT3B0aW9uKHNlbGVjdEJveCkge1xyXG4gIGlmIChzZWxlY3RCb3guc2VsZWN0ZWRJbmRleCA+PSAwKSB7XHJcbiAgICByZXR1cm4gc2VsZWN0Qm94Lm9wdGlvbnNbc2VsZWN0Qm94LnNlbGVjdGVkSW5kZXhdLnZhbHVlO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuc2VsZWN0ZWRPcHRpb24gPSBzZWxlY3RlZE9wdGlvbjtcclxuXHJcblxyXG5mdW5jdGlvbiBzZWxlY3RlZFR5cGUoZWxlbWVudFN5bnRheCwgaW5wdXROb2RlKSB7XHJcbiAgdmFyIHR5cGVTZWxlY3QgPSBkb21RdWVyeShlbGVtZW50U3ludGF4LCBpbnB1dE5vZGUpO1xyXG4gIHJldHVybiBzZWxlY3RlZE9wdGlvbih0eXBlU2VsZWN0KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuc2VsZWN0ZWRUeXBlID0gc2VsZWN0ZWRUeXBlO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBSZXRyaWV2ZSB0aGUgcm9vdCBlbGVtZW50IHRoZSBkb2N1bWVudCB0aGlzXHJcbiAqIGJ1c2luZXNzIG9iamVjdCBpcyBjb250YWluZWQgaW4uXHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRSb290KGJ1c2luZXNzT2JqZWN0KSB7XHJcbiAgdmFyIHBhcmVudCA9IGJ1c2luZXNzT2JqZWN0O1xyXG4gIHdoaWxlIChwYXJlbnQuJHBhcmVudCkge1xyXG4gICAgcGFyZW50ID0gcGFyZW50LiRwYXJlbnQ7XHJcbiAgfVxyXG4gIHJldHVybiBwYXJlbnQ7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmdldFJvb3QgPSBnZXRSb290O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBmaWx0ZXJzIGFsbCBlbGVtZW50cyBpbiB0aGUgbGlzdCB3aGljaCBoYXZlIGEgZ2l2ZW4gdHlwZS5cclxuICogcmVtb3ZlcyBhIG5ldyBsaXN0XHJcbiAqL1xyXG5mdW5jdGlvbiBmaWx0ZXJFbGVtZW50c0J5VHlwZShvYmplY3RMaXN0LCB0eXBlKSB7XHJcbiAgdmFyIGxpc3QgPSBvYmplY3RMaXN0IHx8IFtdO1xyXG4gIHZhciByZXN1bHQgPSBbXTtcclxuICBmb3JFYWNoKGxpc3QsIGZ1bmN0aW9uKG9iaikge1xyXG4gICAgaWYgKGlzKG9iaiwgdHlwZSkpIHtcclxuICAgICAgcmVzdWx0LnB1c2gob2JqKTtcclxuICAgIH1cclxuICB9KTtcclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5maWx0ZXJFbGVtZW50c0J5VHlwZSA9IGZpbHRlckVsZW1lbnRzQnlUeXBlO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGZpbmRSb290RWxlbWVudHNCeVR5cGUoYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRUeXBlKSB7XHJcbiAgdmFyIHJvb3QgPSBnZXRSb290KGJ1c2luZXNzT2JqZWN0KTtcclxuXHJcbiAgcmV0dXJuIGZpbHRlckVsZW1lbnRzQnlUeXBlKHJvb3Qucm9vdEVsZW1lbnRzLCByZWZlcmVuY2VkVHlwZSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmZpbmRSb290RWxlbWVudHNCeVR5cGUgPSBmaW5kUm9vdEVsZW1lbnRzQnlUeXBlO1xyXG5cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZUFsbENoaWxkcmVuKGRvbUVsZW1lbnQpIHtcclxuICB3aGlsZSAoZG9tRWxlbWVudC5maXJzdENoaWxkKSB7XHJcbiAgICBkb21FbGVtZW50LnJlbW92ZUNoaWxkKGRvbUVsZW1lbnQuZmlyc3RDaGlsZCk7XHJcbiAgfVxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5yZW1vdmVBbGxDaGlsZHJlbiA9IHJlbW92ZUFsbENoaWxkcmVuO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBhZGRzIGFuIGVtcHR5IG9wdGlvbiB0byB0aGUgbGlzdFxyXG4gKi9cclxuZnVuY3Rpb24gYWRkRW1wdHlQYXJhbWV0ZXIobGlzdCkge1xyXG4gIHJldHVybiBsaXN0LnB1c2goeyAnbGFiZWwnOiAnJywgJ3ZhbHVlJzogJycsICduYW1lJzogJycgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmFkZEVtcHR5UGFyYW1ldGVyID0gYWRkRW1wdHlQYXJhbWV0ZXI7XHJcblxyXG5cclxuLyoqXHJcbiAqIHJldHVybnMgYSBsaXN0IHdpdGggYWxsIHJvb3QgZWxlbWVudHMgZm9yIHRoZSBnaXZlbiBwYXJhbWV0ZXIgJ3JlZmVyZW5jZWRUeXBlJ1xyXG4gKi9cclxuZnVuY3Rpb24gcmVmcmVzaE9wdGlvbnNNb2RlbChidXNpbmVzc09iamVjdCwgcmVmZXJlbmNlZFR5cGUpIHtcclxuICB2YXIgbW9kZWwgPSBbXTtcclxuICB2YXIgcmVmZXJhYmxlT2JqZWN0cyA9IGZpbmRSb290RWxlbWVudHNCeVR5cGUoYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRUeXBlKTtcclxuICBmb3JFYWNoKHJlZmVyYWJsZU9iamVjdHMsIGZ1bmN0aW9uKG9iaikge1xyXG4gICAgbW9kZWwucHVzaCh7XHJcbiAgICAgIGxhYmVsOiAob2JqLm5hbWUgfHwgJycpICsgJyAoaWQ9JytvYmouaWQrJyknLFxyXG4gICAgICB2YWx1ZTogb2JqLmlkLFxyXG4gICAgICBuYW1lOiBvYmoubmFtZVxyXG4gICAgfSk7XHJcbiAgfSk7XHJcbiAgcmV0dXJuIG1vZGVsO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5yZWZyZXNoT3B0aW9uc01vZGVsID0gcmVmcmVzaE9wdGlvbnNNb2RlbDtcclxuXHJcblxyXG4vKipcclxuICogZmlsbHMgdGhlIGRyb3AgZG93biB3aXRoIG9wdGlvbnNcclxuICovXHJcbmZ1bmN0aW9uIHVwZGF0ZU9wdGlvbnNEcm9wRG93bihkb21TZWxlY3RvciwgYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRUeXBlLCBlbnRyeU5vZGUpIHtcclxuICB2YXIgb3B0aW9ucyA9IHJlZnJlc2hPcHRpb25zTW9kZWwoYnVzaW5lc3NPYmplY3QsIHJlZmVyZW5jZWRUeXBlKTtcclxuICBhZGRFbXB0eVBhcmFtZXRlcihvcHRpb25zKTtcclxuICB2YXIgc2VsZWN0Qm94ID0gZG9tUXVlcnkoZG9tU2VsZWN0b3IsIGVudHJ5Tm9kZSk7XHJcbiAgZG9tQ2xlYXIoc2VsZWN0Qm94KTtcclxuXHJcbiAgZm9yRWFjaChvcHRpb25zLCBmdW5jdGlvbihvcHRpb24pIHtcclxuICAgIHZhciBvcHRpb25FbnRyeSA9IGRvbWlmeSgnPG9wdGlvbiB2YWx1ZT1cIicgKyBlc2NhcGVIVE1MKG9wdGlvbi52YWx1ZSkgKyAnXCI+JyArIGVzY2FwZUhUTUwob3B0aW9uLmxhYmVsKSArICc8L29wdGlvbj4nKTtcclxuICAgIHNlbGVjdEJveC5hcHBlbmRDaGlsZChvcHRpb25FbnRyeSk7XHJcbiAgfSk7XHJcbiAgcmV0dXJuIG9wdGlvbnM7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLnVwZGF0ZU9wdGlvbnNEcm9wRG93biA9IHVwZGF0ZU9wdGlvbnNEcm9wRG93bjtcclxuXHJcblxyXG4vKipcclxuICogY2hlY2tzIHdoZXRoZXIgdGhlIGlkIHZhbHVlIGlzIHZhbGlkXHJcbiAqXHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gYm9cclxuICogQHBhcmFtIHtTdHJpbmd9IGlkVmFsdWVcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNsYXRlXHJcbiAqXHJcbiAqIEByZXR1cm4ge1N0cmluZ30gZXJyb3IgbWVzc2FnZVxyXG4gKi9cclxuZnVuY3Rpb24gaXNJZFZhbGlkKGJvLCBpZFZhbHVlLCB0cmFuc2xhdGUpIHtcclxuICB2YXIgYXNzaWduZWQgPSBiby4kbW9kZWwuaWRzLmFzc2lnbmVkKGlkVmFsdWUpO1xyXG5cclxuICB2YXIgaWRFeGlzdHMgPSBhc3NpZ25lZCAmJiBhc3NpZ25lZCAhPT0gYm87XHJcblxyXG4gIGlmICghaWRWYWx1ZSB8fCBpZEV4aXN0cykge1xyXG4gICAgcmV0dXJuIHRyYW5zbGF0ZSgnRWxlbWVudCBtdXN0IGhhdmUgYW4gdW5pcXVlIGlkLicpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHZhbGlkYXRlSWQoaWRWYWx1ZSwgdHJhbnNsYXRlKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuaXNJZFZhbGlkID0gaXNJZFZhbGlkO1xyXG5cclxuXHJcbmZ1bmN0aW9uIHZhbGlkYXRlSWQoaWRWYWx1ZSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlkVmFsdWUgPSBzdHJpcFBsYWNlaG9sZGVycyhpZFZhbHVlKTtcclxuXHJcbiAgaWYgKGNvbnRhaW5zU3BhY2UoaWRWYWx1ZSkpIHtcclxuICAgIHJldHVybiB0cmFuc2xhdGUoJ0lkIG11c3Qgbm90IGNvbnRhaW4gc3BhY2VzLicpO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFJRF9SRUdFWC50ZXN0KGlkVmFsdWUpKSB7XHJcblxyXG4gICAgaWYgKFFOQU1FX1JFR0VYLnRlc3QoaWRWYWx1ZSkpIHtcclxuICAgICAgcmV0dXJuIHRyYW5zbGF0ZSgnSWQgbXVzdCBub3QgY29udGFpbiBwcmVmaXguJyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRyYW5zbGF0ZSgnSWQgbXVzdCBiZSBhIHZhbGlkIFFOYW1lLicpO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMudmFsaWRhdGVJZCA9IHZhbGlkYXRlSWQ7XHJcblxyXG5cclxuZnVuY3Rpb24gY29udGFpbnNTcGFjZSh2YWx1ZSkge1xyXG4gIHJldHVybiBTUEFDRV9SRUdFWC50ZXN0KHZhbHVlKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuY29udGFpbnNTcGFjZSA9IGNvbnRhaW5zU3BhY2U7XHJcblxyXG5cclxuZnVuY3Rpb24gc3RyaXBQbGFjZWhvbGRlcnMoaWRWYWx1ZSkge1xyXG5cclxuICAvLyByZXBsYWNlIGV4cHJlc3Npb24gZS5nLiAke1ZFUlNJT05fVEFHfVxyXG4gIC8vIHVzZSBvbmx5IHRoZSBjb250ZW50IGJldHdlZW4gJHt9XHJcbiAgLy8gZm9yIHRoZSBSRUdFWCBjaGVja1xyXG4gIHJldHVybiBpZFZhbHVlLnJlcGxhY2UoUExBQ0VIT0xERVJfUkVHRVgsICckMScpO1xyXG59XHJcblxyXG4vKipcclxuICogZ2VuZXJhdGUgYSBzZW1hbnRpYyBpZCB3aXRoIGdpdmVuIHByZWZpeFxyXG4gKi9cclxuZnVuY3Rpb24gbmV4dElkKHByZWZpeCkge1xyXG4gIHZhciBpZHMgPSBuZXcgSWRzKFszMiwzMiwxXSk7XHJcblxyXG4gIHJldHVybiBpZHMubmV4dFByZWZpeGVkKHByZWZpeCk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLm5leHRJZCA9IG5leHRJZDtcclxuXHJcblxyXG5mdW5jdGlvbiB0cmlnZ2VyQ2xpY2tFdmVudChlbGVtZW50KSB7XHJcbiAgdmFyIGV2dDtcclxuICB2YXIgZXZlbnRUeXBlID0gJ2NsaWNrJztcclxuXHJcbiAgaWYgKGRvY3VtZW50LmNyZWF0ZUV2ZW50KSB7XHJcbiAgICB0cnkge1xyXG4gICAgICAvLyBDaHJvbWUsIFNhZmFyaSwgRmlyZWZveFxyXG4gICAgICBldnQgPSBuZXcgTW91c2VFdmVudCgoZXZlbnRUeXBlKSwgeyB2aWV3OiB3aW5kb3csIGJ1YmJsZXM6IHRydWUsIGNhbmNlbGFibGU6IHRydWUgfSk7XHJcbiAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgIC8vIElFIDExLCBQaGFudG9tSlMgKHdhdCEpXHJcbiAgICAgIGV2dCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50Jyk7XHJcblxyXG4gICAgICBldnQuaW5pdEV2ZW50KChldmVudFR5cGUpLCB0cnVlLCB0cnVlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBlbGVtZW50LmRpc3BhdGNoRXZlbnQoZXZ0KTtcclxuICB9IGVsc2Uge1xyXG4gICAgLy8gV2VsY29tZSBJRVxyXG4gICAgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnRPYmplY3QoKTtcclxuXHJcbiAgICByZXR1cm4gZWxlbWVudC5maXJlRXZlbnQoJ29uJyArIGV2ZW50VHlwZSwgZXZ0KTtcclxuICB9XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLnRyaWdnZXJDbGlja0V2ZW50ID0gdHJpZ2dlckNsaWNrRXZlbnQ7XHJcblxyXG5cclxuZnVuY3Rpb24gZXNjYXBlSFRNTChzdHIpIHtcclxuICBzdHIgPSAnJyArIHN0cjtcclxuXHJcbiAgcmV0dXJuIHN0ciAmJiBzdHIucmVwbGFjZSgvWyY8PlwiJ10vZywgZnVuY3Rpb24obWF0Y2gpIHtcclxuICAgIHJldHVybiBIVE1MX0VTQ0FQRV9NQVBbbWF0Y2hdO1xyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5lc2NhcGVIVE1MID0gZXNjYXBlSFRNTDsiLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uL1V0aWxzJykuZXNjYXBlSFRNTDtcclxuXHJcbnZhciBlbnRyeUZpZWxkRGVzY3JpcHRpb24gPSByZXF1aXJlKCcuL0VudHJ5RmllbGREZXNjcmlwdGlvbicpO1xyXG5cclxuXHJcbnZhciBjaGVja2JveCA9IGZ1bmN0aW9uKG9wdGlvbnMsIGRlZmF1bHRQYXJhbWV0ZXJzKSB7XHJcbiAgdmFyIHJlc291cmNlID0gZGVmYXVsdFBhcmFtZXRlcnMsXHJcbiAgICAgIGlkID0gcmVzb3VyY2UuaWQsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCB8fCBpZCxcclxuICAgICAgY2FuQmVEaXNhYmxlZCA9ICEhb3B0aW9ucy5kaXNhYmxlZCAmJiB0eXBlb2Ygb3B0aW9ucy5kaXNhYmxlZCA9PT0gJ2Z1bmN0aW9uJyxcclxuICAgICAgY2FuQmVIaWRkZW4gPSAhIW9wdGlvbnMuaGlkZGVuICYmIHR5cGVvZiBvcHRpb25zLmhpZGRlbiA9PT0gJ2Z1bmN0aW9uJyxcclxuICAgICAgZGVzY3JpcHRpb24gPSBvcHRpb25zLmRlc2NyaXB0aW9uO1xyXG5cclxuICByZXNvdXJjZS5odG1sID1cclxuICAgICc8aW5wdXQgaWQ9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChpZCkgKyAnXCIgJyArXHJcbiAgICAgICAgICd0eXBlPVwiY2hlY2tib3hcIiAnICtcclxuICAgICAgICAgJ25hbWU9XCInICsgZXNjYXBlSFRNTChvcHRpb25zLm1vZGVsUHJvcGVydHkpICsgJ1wiICcgK1xyXG4gICAgICAgICAoY2FuQmVEaXNhYmxlZCA/ICdkYXRhLWRpc2FibGU9XCJpc0Rpc2FibGVkXCInIDogJycpICtcclxuICAgICAgICAgKGNhbkJlSGlkZGVuID8gJ2RhdGEtc2hvdz1cImlzSGlkZGVuXCInIDogJycpICtcclxuICAgICAgICAgJyAvPicgK1xyXG4gICAgJzxsYWJlbCBmb3I9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChpZCkgKyAnXCIgJyArXHJcbiAgICAgICAgIChjYW5CZURpc2FibGVkID8gJ2RhdGEtZGlzYWJsZT1cImlzRGlzYWJsZWRcIicgOiAnJykgK1xyXG4gICAgICAgICAoY2FuQmVIaWRkZW4gPyAnZGF0YS1zaG93PVwiaXNIaWRkZW5cIicgOiAnJykgK1xyXG4gICAgICAgICAnPicgKyBlc2NhcGVIVE1MKGxhYmVsKSArICc8L2xhYmVsPic7XHJcblxyXG4gIC8vIGFkZCBkZXNjcmlwdGlvbiBiZWxvdyBjaGVja2JveCBlbnRyeSBmaWVsZFxyXG4gIGlmIChkZXNjcmlwdGlvbikge1xyXG4gICAgcmVzb3VyY2UuaHRtbCArPSBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgcmVzb3VyY2UuZ2V0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksXHJcbiAgICAgICAgcmVzID0ge307XHJcblxyXG4gICAgcmVzW29wdGlvbnMubW9kZWxQcm9wZXJ0eV0gPSBiby5nZXQob3B0aW9ucy5tb2RlbFByb3BlcnR5KTtcclxuXHJcbiAgICByZXR1cm4gcmVzO1xyXG4gIH07XHJcblxyXG4gIHJlc291cmNlLnNldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgdmFyIHJlcyA9IHt9O1xyXG5cclxuICAgIHJlc1tvcHRpb25zLm1vZGVsUHJvcGVydHldID0gISF2YWx1ZXNbb3B0aW9ucy5tb2RlbFByb3BlcnR5XTtcclxuXHJcbiAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcmVzKTtcclxuICB9O1xyXG5cclxuICBpZiAodHlwZW9mIG9wdGlvbnMuc2V0ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICByZXNvdXJjZS5zZXQgPSBvcHRpb25zLnNldDtcclxuICB9XHJcblxyXG4gIGlmICh0eXBlb2Ygb3B0aW9ucy5nZXQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgIHJlc291cmNlLmdldCA9IG9wdGlvbnMuZ2V0O1xyXG4gIH1cclxuXHJcbiAgaWYgKGNhbkJlRGlzYWJsZWQpIHtcclxuICAgIHJlc291cmNlLmlzRGlzYWJsZWQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgcmV0dXJuIG9wdGlvbnMuZGlzYWJsZWQuYXBwbHkocmVzb3VyY2UsIGFyZ3VtZW50cyk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgaWYgKGNhbkJlSGlkZGVuKSB7XHJcbiAgICByZXNvdXJjZS5pc0hpZGRlbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICByZXR1cm4gIW9wdGlvbnMuaGlkZGVuLmFwcGx5KHJlc291cmNlLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJlc291cmNlLmNzc0NsYXNzZXMgPSBbJ2JwcC1jaGVja2JveCddO1xyXG5cclxuICByZXR1cm4gcmVzb3VyY2U7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNoZWNrYm94O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpLFxyXG4gICAgZmluZCA9IHJlcXVpcmUoJ2xvZGFzaC9maW5kJyk7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnk7XHJcblxyXG52YXIgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uL1V0aWxzJykuZXNjYXBlSFRNTDtcclxuXHJcbnZhciBzZWxlY3RFbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuL1NlbGVjdEVudHJ5RmFjdG9yeScpLFxyXG4gICAgZW50cnlGaWVsZERlc2NyaXB0aW9uID0gcmVxdWlyZSgnLi9FbnRyeUZpZWxkRGVzY3JpcHRpb24nKTtcclxuXHJcblxyXG4vKipcclxuICogVGhlIGNvbWJvIGJveCBpcyBhIHNwZWNpYWwgaW1wbGVtZW50YXRpb24gb2YgdGhlIHNlbGVjdCBlbnRyeSBhbmQgYWRkcyB0aGUgb3B0aW9uICdjdXN0b20nIHRvIHRoZVxyXG4gKiBzZWxlY3QgYm94LiBJZiAnY3VzdG9tJyBpcyBzZWxlY3RlZCwgYW4gYWRkaXRpb25hbCB0ZXh0IGlucHV0IGZpZWxkIGlzIHNob3duIHdoaWNoIGFsbG93cyB0byBkZWZpbmVcclxuICogYSBjdXN0b20gdmFsdWUuXHJcbiAqXHJcbiAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMuaWRcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmxhYmVsXHJcbiAqIEBwYXJhbSAge0FycmF5PE9iamVjdD59IG9wdGlvbnMuc2VsZWN0T3B0aW9ucyBsaXN0IG9mIG5hbWUvdmFsdWUgcGFpcnNcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLm1vZGVsUHJvcGVydHlcclxuICogQHBhcmFtICB7ZnVuY3Rpb259IG9wdGlvbnMuZ2V0XHJcbiAqIEBwYXJhbSAge2Z1bmN0aW9ufSBvcHRpb25zLnNldFxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IFtvcHRpb25zLmN1c3RvbVZhbHVlXSBjdXN0b20gc2VsZWN0IG9wdGlvbiB2YWx1ZSAoZGVmYXVsdDogJ2N1c3RvbScpXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gW29wdGlvbnMuY3VzdG9tTmFtZV0gY3VzdG9tIHNlbGVjdCBvcHRpb24gbmFtZSB2aXNpYmxlIGluIHRoZSBzZWxlY3QgYm94IChkZWZhdWx0OiAnY3VzdG9tJylcclxuICpcclxuICogQHJldHVybiB7T2JqZWN0fVxyXG4gKi9cclxudmFyIGNvbWJvQm94ID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG5cclxuICB2YXIgc2VsZWN0T3B0aW9ucyA9IG9wdGlvbnMuc2VsZWN0T3B0aW9ucyxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eSxcclxuICAgICAgY3VzdG9tVmFsdWUgPSBvcHRpb25zLmN1c3RvbVZhbHVlIHx8ICdjdXN0b20nLFxyXG4gICAgICBjdXN0b21OYW1lID0gb3B0aW9ucy5jdXN0b21OYW1lIHx8ICdjdXN0b20gJyArIG1vZGVsUHJvcGVydHksXHJcbiAgICAgIGRlc2NyaXB0aW9uID0gb3B0aW9ucy5kZXNjcmlwdGlvbjtcclxuXHJcbiAgLy8gY2hlY2sgaWYgYSB2YWx1ZSBpcyBub3QgYSBidWlsdCBpbiB2YWx1ZVxyXG4gIHZhciBpc0N1c3RvbVZhbHVlID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2YgdmFsdWVbbW9kZWxQcm9wZXJ0eV0gPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgaXNDdXN0b20gPSAhZmluZChzZWxlY3RPcHRpb25zLCBmdW5jdGlvbihvcHRpb24pIHtcclxuICAgICAgcmV0dXJuIHZhbHVlW21vZGVsUHJvcGVydHldID09PSBvcHRpb24udmFsdWU7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gaXNDdXN0b207XHJcbiAgfTtcclxuXHJcbiAgdmFyIGNvbWJvT3B0aW9ucyA9IGFzc2lnbih7fSwgb3B0aW9ucyk7XHJcblxyXG4gIC8vIHRydWUgaWYgdGhlIHNlbGVjdGVkIHZhbHVlIGluIHRoZSBzZWxlY3QgYm94IGlzIGN1c3RvbVZhbHVlXHJcbiAgY29tYm9PcHRpb25zLnNob3dDdXN0b21JbnB1dCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciBzZWxlY3RCb3ggPSBkb21RdWVyeSgnW2RhdGEtZW50cnk9XCInKyBvcHRpb25zLmlkICsnXCJdIHNlbGVjdCcsIG5vZGUucGFyZW50Tm9kZSk7XHJcblxyXG4gICAgaWYgKHNlbGVjdEJveCkge1xyXG4gICAgICByZXR1cm4gc2VsZWN0Qm94LnZhbHVlID09PSBjdXN0b21WYWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfTtcclxuXHJcbiAgY29tYm9PcHRpb25zLmdldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciB2YWx1ZSA9IG9wdGlvbnMuZ2V0KGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgIHZhciBtb2RpZmllZFZhbHVlcyA9IHt9O1xyXG5cclxuICAgIGlmICghaXNDdXN0b21WYWx1ZSh2YWx1ZSkpIHtcclxuICAgICAgbW9kaWZpZWRWYWx1ZXNbbW9kZWxQcm9wZXJ0eV0gPSB2YWx1ZVttb2RlbFByb3BlcnR5XSB8fCAnJztcclxuXHJcbiAgICAgIHJldHVybiBtb2RpZmllZFZhbHVlcztcclxuICAgIH1cclxuXHJcbiAgICBtb2RpZmllZFZhbHVlc1ttb2RlbFByb3BlcnR5XSA9IGN1c3RvbVZhbHVlO1xyXG4gICAgbW9kaWZpZWRWYWx1ZXNbJ2N1c3RvbS0nK21vZGVsUHJvcGVydHldID0gdmFsdWVbbW9kZWxQcm9wZXJ0eV07XHJcblxyXG4gICAgcmV0dXJuIG1vZGlmaWVkVmFsdWVzO1xyXG4gIH07XHJcblxyXG4gIGNvbWJvT3B0aW9ucy5zZXQgPSBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgIHZhciBtb2RpZmllZFZhbHVlcyA9IHt9O1xyXG5cclxuICAgIC8vIGlmIHRoZSBjdXN0b20gc2VsZWN0IG9wdGlvbiBoYXMgYmVlbiBzZWxlY3RlZFxyXG4gICAgLy8gdGFrZSB0aGUgdmFsdWUgZnJvbSB0aGUgdGV4dCBpbnB1dCBmaWVsZFxyXG4gICAgaWYgKHZhbHVlc1ttb2RlbFByb3BlcnR5XSA9PT0gY3VzdG9tVmFsdWUpIHtcclxuICAgICAgbW9kaWZpZWRWYWx1ZXNbbW9kZWxQcm9wZXJ0eV0gPSB2YWx1ZXNbJ2N1c3RvbS0nICsgbW9kZWxQcm9wZXJ0eV0gfHwgJyc7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmIChvcHRpb25zLmVtcHR5UGFyYW1ldGVyICYmIHZhbHVlc1ttb2RlbFByb3BlcnR5XSA9PT0gJycpIHtcclxuICAgICAgbW9kaWZpZWRWYWx1ZXNbbW9kZWxQcm9wZXJ0eV0gPSB1bmRlZmluZWQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBtb2RpZmllZFZhbHVlc1ttb2RlbFByb3BlcnR5XSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XTtcclxuICAgIH1cclxuICAgIHJldHVybiBvcHRpb25zLnNldChlbGVtZW50LCBtb2RpZmllZFZhbHVlcywgbm9kZSk7XHJcbiAgfTtcclxuXHJcbiAgY29tYm9PcHRpb25zLnNlbGVjdE9wdGlvbnMucHVzaCh7IG5hbWU6IGN1c3RvbU5hbWUsIHZhbHVlOiBjdXN0b21WYWx1ZSB9KTtcclxuXHJcbiAgdmFyIGNvbWJvQm94RW50cnkgPSBhc3NpZ24oe30sIHNlbGVjdEVudHJ5RmFjdG9yeShjb21ib09wdGlvbnMsIGNvbWJvT3B0aW9ucykpO1xyXG5cclxuICBjb21ib0JveEVudHJ5Lmh0bWwgKz0gJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlciBicHAtY29tYm8taW5wdXRcIiAnICtcclxuICAgICdkYXRhLXNob3c9XCJzaG93Q3VzdG9tSW5wdXRcIicgK1xyXG4gICAgJz4nICtcclxuICAgICc8aW5wdXQgaWQ9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChvcHRpb25zLmlkKSArICctaW5wdXRcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJjdXN0b20tJyArXHJcbiAgICAgIGVzY2FwZUhUTUwobW9kZWxQcm9wZXJ0eSkgKyAnXCIgJyArXHJcbiAgICAnIC8+JyArXHJcbiAgJzwvZGl2Pic7XHJcblxyXG4gIC8vIGFkZCBkZXNjcmlwdGlvbiBiZWxvdyBjb21ibyBib3ggZW50cnkgZmllbGRcclxuICBpZiAoZGVzY3JpcHRpb24pIHtcclxuICAgIGNvbWJvQm94RW50cnkuaHRtbCArPSBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGNvbWJvQm94RW50cnk7XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGNvbWJvQm94O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuLy8gaW5wdXQgZW50aXRpZXNcclxudmFyIHRleHRJbnB1dEZpZWxkID0gcmVxdWlyZSgnLi9UZXh0SW5wdXRFbnRyeUZhY3RvcnknKSxcclxuICAgIGNoZWNrYm94RmllbGQgPSByZXF1aXJlKCcuL0NoZWNrYm94RW50cnlGYWN0b3J5JyksXHJcbiAgICBzZWxlY3RCb3hGaWVsZCA9IHJlcXVpcmUoJy4vU2VsZWN0RW50cnlGYWN0b3J5JyksXHJcbiAgICBjb21ib0JveEZpZWxkID0gcmVxdWlyZSgnLi9Db21ib0VudHJ5RmFjdG9yeScpLFxyXG4gICAgdGV4dEJveEZpZWxkID0gcmVxdWlyZSgnLi9UZXh0Qm94RW50cnlGYWN0b3J5JyksXHJcbiAgICB2YWxpZGF0aW9uQXdhcmVUZXh0SW5wdXRGaWVsZCA9IHJlcXVpcmUoJy4vVmFsaWRhdGlvbkF3YXJlVGV4dElucHV0JyksXHJcbiAgICB0YWJsZUZpZWxkID0gcmVxdWlyZSgnLi9UYWJsZUVudHJ5RmFjdG9yeScpLFxyXG4gICAgbGFiZWxFbnRyeSA9IHJlcXVpcmUoJy4vTGFiZWxGYWN0b3J5JyksXHJcbiAgICBsaW5rID0gcmVxdWlyZSgnLi9MaW5rRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxuLy8gaGVscGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBlbnN1cmVOb3ROdWxsKHByb3ApIHtcclxuICBpZiAoIXByb3ApIHtcclxuICAgIHRocm93IG5ldyBFcnJvcihwcm9wICsgJyBtdXN0IGJlIHNldC4nKTtcclxuICB9XHJcblxyXG4gIHJldHVybiBwcm9wO1xyXG59XHJcblxyXG4vKipcclxuICogc2V0cyB0aGUgZGVmYXVsdCBwYXJhbWV0ZXJzIHdoaWNoIGFyZSBuZWVkZWQgdG8gY3JlYXRlIGFuIGVudHJ5XHJcbiAqXHJcbiAqIEBwYXJhbSBvcHRpb25zXHJcbiAqIEByZXR1cm5zIHt7aWQ6ICosIGRlc2NyaXB0aW9uOiAoKnxzdHJpbmcpLCBnZXQ6ICgqfEZ1bmN0aW9uKSwgc2V0OiAoKnxGdW5jdGlvbiksXHJcbiAqICAgICAgICAgICAgdmFsaWRhdGU6ICgqfEZ1bmN0aW9uKSwgaHRtbDogc3RyaW5nfX1cclxuICovXHJcbnZhciBzZXREZWZhdWx0UGFyYW1ldGVycyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuXHJcbiAgLy8gZGVmYXVsdCBtZXRob2QgdG8gZmV0Y2ggdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGlucHV0IGZpZWxkXHJcbiAgdmFyIGRlZmF1bHRHZXQgPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICByZXMgPSB7fSxcclxuICAgICAgICBwcm9wID0gZW5zdXJlTm90TnVsbChvcHRpb25zLm1vZGVsUHJvcGVydHkpO1xyXG4gICAgcmVzW3Byb3BdID0gYm8uZ2V0KHByb3ApO1xyXG5cclxuICAgIHJldHVybiByZXM7XHJcbiAgfTtcclxuXHJcbiAgLy8gZGVmYXVsdCBtZXRob2QgdG8gc2V0IGEgbmV3IHZhbHVlIHRvIHRoZSBpbnB1dCBmaWVsZFxyXG4gIHZhciBkZWZhdWx0U2V0ID0gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICB2YXIgcmVzID0ge30sXHJcbiAgICAgICAgcHJvcCA9IGVuc3VyZU5vdE51bGwob3B0aW9ucy5tb2RlbFByb3BlcnR5KTtcclxuICAgIGlmICh2YWx1ZXNbcHJvcF0gIT09ICcnKSB7XHJcbiAgICAgIHJlc1twcm9wXSA9IHZhbHVlc1twcm9wXTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJlc1twcm9wXSA9IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcmVzKTtcclxuICB9O1xyXG5cclxuICAvLyBkZWZhdWx0IHZhbGlkYXRpb24gbWV0aG9kXHJcbiAgdmFyIGRlZmF1bHRWYWxpZGF0ZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHt9O1xyXG4gIH07XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBpZCA6IG9wdGlvbnMuaWQsXHJcbiAgICBkZXNjcmlwdGlvbiA6IChvcHRpb25zLmRlc2NyaXB0aW9uIHx8ICcnKSxcclxuICAgIGdldCA6IChvcHRpb25zLmdldCB8fCBkZWZhdWx0R2V0KSxcclxuICAgIHNldCA6IChvcHRpb25zLnNldCB8fCBkZWZhdWx0U2V0KSxcclxuICAgIHZhbGlkYXRlIDogKG9wdGlvbnMudmFsaWRhdGUgfHwgZGVmYXVsdFZhbGlkYXRlKSxcclxuICAgIGh0bWw6ICcnXHJcbiAgfTtcclxufTtcclxuXHJcbmZ1bmN0aW9uIEVudHJ5RmFjdG9yeSgpIHtcclxuXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYW4gdGV4dCBpbnB1dCBlbnRyeSBvYmplY3QgZm9yIGEgcHJvcGVydHkgcGFuZWwuXHJcbiAqIG9wdGlvbnMgYXJlOlxyXG4gKiAtIGlkOiBpZCBvZiB0aGUgZW50cnkgLSBTdHJpbmdcclxuICpcclxuICogLSBkZXNjcmlwdGlvbjogZGVzY3JpcHRpb24gb2YgdGhlIHByb3BlcnR5IC0gU3RyaW5nXHJcbiAqXHJcbiAqIC0gbGFiZWw6IGxhYmVsIGZvciB0aGUgaW5wdXQgZmllbGQgLSBTdHJpbmdcclxuICpcclxuICogLSBzZXQ6IHNldHRlciBtZXRob2QgLSBGdW5jdGlvblxyXG4gKlxyXG4gKiAtIGdldDogZ2V0dGVyIG1ldGhvZCAtIEZ1bmN0aW9uXHJcbiAqXHJcbiAqIC0gdmFsaWRhdGU6IHZhbGlkYXRpb24gbWVodG9kIC0gRnVuY3Rpb25cclxuICpcclxuICogLSBtb2RlbFByb3BlcnR5OiBuYW1lIG9mIHRoZSBtb2RlbCBwcm9wZXJ0eSAtIFN0cmluZ1xyXG4gKlxyXG4gKiAtIGJ1dHRvbkFjdGlvbjogT2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczogLSBPYmplY3RcclxuICogLS0tLSBuYW1lOiBuYW1lIG9mIHRoZSBbZGF0YS1hY3Rpb25dIGNhbGxiYWNrIC0gU3RyaW5nXHJcbiAqIC0tLS0gbWV0aG9kOiBjYWxsYmFjayBmdW5jdGlvbiBmb3IgW2RhdGEtYWN0aW9uXSAtIEZ1bmN0aW9uXHJcbiAqXHJcbiAqIC0gYnV0dG9uU2hvdzogT2JqZWN0IHdoaWNoIGNvbnRhaW5zIHRoZSBmb2xsb3dpbmcgcHJvcGVydGllczogLSBPYmplY3RcclxuICogLS0tLSBuYW1lOiBuYW1lIG9mIHRoZSBbZGF0YS1zaG93XSBjYWxsYmFjayAtIFN0cmluZ1xyXG4gKiAtLS0tIG1ldGhvZDogY2FsbGJhY2sgZnVuY3Rpb24gZm9yIFtkYXRhLXNob3ddIC0gRnVuY3Rpb25cclxuICpcclxuICogQHBhcmFtIG9wdGlvbnNcclxuICogQHJldHVybnMgdGhlIHByb3BlcnR5UGFuZWwgZW50cnkgcmVzb3VyY2Ugb2JqZWN0XHJcbiAqL1xyXG5FbnRyeUZhY3RvcnkudGV4dEZpZWxkID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG4gIHJldHVybiB0ZXh0SW5wdXRGaWVsZChvcHRpb25zLCBzZXREZWZhdWx0UGFyYW1ldGVycyhvcHRpb25zKSk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkudmFsaWRhdGlvbkF3YXJlVGV4dEZpZWxkID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG4gIHJldHVybiB2YWxpZGF0aW9uQXdhcmVUZXh0SW5wdXRGaWVsZChvcHRpb25zLCBzZXREZWZhdWx0UGFyYW1ldGVycyhvcHRpb25zKSk7XHJcbn07XHJcblxyXG4vKipcclxuICogR2VuZXJhdGVzIGEgY2hlY2tib3ggaW5wdXQgZW50cnkgb2JqZWN0IGZvciBhIHByb3BlcnR5IHBhbmVsLlxyXG4gKiBvcHRpb25zIGFyZTpcclxuICogLSBpZDogaWQgb2YgdGhlIGVudHJ5IC0gU3RyaW5nXHJcbiAqXHJcbiAqIC0gZGVzY3JpcHRpb246IGRlc2NyaXB0aW9uIG9mIHRoZSBwcm9wZXJ0eSAtIFN0cmluZ1xyXG4gKlxyXG4gKiAtIGxhYmVsOiBsYWJlbCBmb3IgdGhlIGlucHV0IGZpZWxkIC0gU3RyaW5nXHJcbiAqXHJcbiAqIC0gc2V0OiBzZXR0ZXIgbWV0aG9kIC0gRnVuY3Rpb25cclxuICpcclxuICogLSBnZXQ6IGdldHRlciBtZXRob2QgLSBGdW5jdGlvblxyXG4gKlxyXG4gKiAtIHZhbGlkYXRlOiB2YWxpZGF0aW9uIG1ldGhvZCAtIEZ1bmN0aW9uXHJcbiAqXHJcbiAqIC0gbW9kZWxQcm9wZXJ0eTogbmFtZSBvZiB0aGUgbW9kZWwgcHJvcGVydHkgLSBTdHJpbmdcclxuICpcclxuICogQHBhcmFtIG9wdGlvbnNcclxuICogQHJldHVybnMgdGhlIHByb3BlcnR5UGFuZWwgZW50cnkgcmVzb3VyY2Ugb2JqZWN0XHJcbiAqL1xyXG5FbnRyeUZhY3RvcnkuY2hlY2tib3ggPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIGNoZWNrYm94RmllbGQob3B0aW9ucywgc2V0RGVmYXVsdFBhcmFtZXRlcnMob3B0aW9ucykpO1xyXG59O1xyXG5cclxuRW50cnlGYWN0b3J5LnRleHRCb3ggPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIHRleHRCb3hGaWVsZChvcHRpb25zLCBzZXREZWZhdWx0UGFyYW1ldGVycyhvcHRpb25zKSk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3Rvcnkuc2VsZWN0Qm94ID0gZnVuY3Rpb24ob3B0aW9ucykge1xyXG4gIHJldHVybiBzZWxlY3RCb3hGaWVsZChvcHRpb25zLCBzZXREZWZhdWx0UGFyYW1ldGVycyhvcHRpb25zKSk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkuY29tYm9Cb3ggPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIGNvbWJvQm94RmllbGQob3B0aW9ucyk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkudGFibGUgPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIHRhYmxlRmllbGQob3B0aW9ucyk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkubGFiZWwgPSBmdW5jdGlvbihvcHRpb25zKSB7XHJcbiAgcmV0dXJuIGxhYmVsRW50cnkob3B0aW9ucyk7XHJcbn07XHJcblxyXG5FbnRyeUZhY3RvcnkubGluayA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuICByZXR1cm4gbGluayhvcHRpb25zKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gRW50cnlGYWN0b3J5O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uL1V0aWxzJykuZXNjYXBlSFRNTDtcclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYSBsaW5raWZpZWQgYW5kIEhUTUwgZXNjYXBlZCBlbnRyeSBmaWVsZCBkZXNjcmlwdGlvbi5cclxuICpcclxuICogQXMgYSBzcGVjaWFsIGZlYXR1cmUsIHRoaXMgZGVzY3JpcHRpb24gbWF5IGNvbnRhaW4gYm90aCBtYXJrZG93blxyXG4gKiBhbmQgcGxhaW4gPGEgaHJlZj4gbGlua3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBkZXNjcmlwdGlvblxyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pIHtcclxuXHJcbiAgLy8gd2UgdG9rZW5pemUgdGhlIGRlc2NyaXB0aW9uIHRvIGV4dHJhY3QgdGV4dCwgSFRNTCBhbmQgbWFya2Rvd24gbGlua3NcclxuICAvLyB0ZXh0IGFuZCBsaW5rcyBhcmUgaGFuZGxlZCBzZXBlcmF0ZWx5XHJcblxyXG4gIHZhciBlc2NhcGVkID0gW107XHJcblxyXG4gIC8vIG1hdGNoIG1hcmtkb3duIFt7VEVYVH1dKHtVUkx9KSBhbmQgSFRNTCBsaW5rcyA8YSBocmVmPVwie1VSTH1cIj57VEVYVH08L2E+XHJcbiAgdmFyIHBhdHRlcm4gPSAvKD86XFxbKFteXFxdXSspXFxdXFwoKGh0dHBzPzpcXC9cXC9bXlwiPD5cXF1dKylcXCkpfCg/OjxhIGhyZWY9XCIoaHR0cHM/OlxcL1xcL1teXCI8Pl0rKVwiPihbXjxdKik8XFwvYT4pL2dpO1xyXG5cclxuICB2YXIgaW5kZXggPSAwO1xyXG4gIHZhciBtYXRjaDtcclxuICB2YXIgbGluaywgdGV4dDtcclxuXHJcbiAgd2hpbGUgKChtYXRjaCA9IHBhdHRlcm4uZXhlYyhkZXNjcmlwdGlvbikpKSB7XHJcblxyXG4gICAgLy8gZXNjYXBlICsgaW5zZXJ0IHRleHQgYmVmb3JlIG1hdGNoXHJcbiAgICBpZiAobWF0Y2guaW5kZXggPiBpbmRleCkge1xyXG4gICAgICBlc2NhcGVkLnB1c2goZXNjYXBlSFRNTChkZXNjcmlwdGlvbi5zdWJzdHJpbmcoaW5kZXgsIG1hdGNoLmluZGV4KSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGxpbmsgPSBtYXRjaFsyXSB8fCBtYXRjaFszXTtcclxuICAgIHRleHQgPSBtYXRjaFsxXSB8fCBtYXRjaFs0XTtcclxuXHJcbiAgICAvLyBpbnNlcnQgc2FmZSBsaW5rXHJcbiAgICBlc2NhcGVkLnB1c2goJzxhIGhyZWY9XCInICsgbGluayArICdcIiB0YXJnZXQ9XCJfYmxhbmtcIj4nICsgZXNjYXBlSFRNTCh0ZXh0KSArICc8L2E+Jyk7XHJcblxyXG4gICAgaW5kZXggPSBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aDtcclxuICB9XHJcblxyXG4gIC8vIGVzY2FwZSBhbmQgaW5zZXJ0IHRleHQgYWZ0ZXIgbGFzdCBtYXRjaFxyXG4gIGlmIChpbmRleCA8IGRlc2NyaXB0aW9uLmxlbmd0aCkge1xyXG4gICAgZXNjYXBlZC5wdXNoKGVzY2FwZUhUTUwoZGVzY3JpcHRpb24uc3Vic3RyaW5nKGluZGV4KSkpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLWRlc2NyaXB0aW9uXCI+JyArIGVzY2FwZWQuam9pbignJykgKyAnPC9kaXY+JztcclxufTsiLCIndXNlIHN0cmljdCc7XHJcblxyXG4vKipcclxuICogVGhlIGxhYmVsIGZhY3RvcnkgcHJvdmlkZXMgYSBsYWJlbCBlbnRyeS4gRm9yIHRoZSBsYWJlbCB0ZXh0XHJcbiAqIGl0IGV4cGVjdHMgZWl0aGVyIGEgc3RyaW5nIHByb3ZpZGVkIGJ5IHRoZSBvcHRpb25zLmxhYmVsVGV4dFxyXG4gKiBwYXJhbWV0ZXIgb3IgaXQgY291bGQgYmUgZ2VuZXJhdGVkIHByb2dyYW1tYXRpY2FsbHkgdXNpbmcgYVxyXG4gKiBmdW5jdGlvbiBwYXNzZWQgYXMgdGhlIG9wdGlvbnMuZ2V0IHBhcmFtZXRlci5cclxuICpcclxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5pZFxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IFtvcHRpb25zLmxhYmVsVGV4dF1cclxuICogQHBhcmFtICB7RnVuY3Rpb259IFtvcHRpb25zLmdldF1cclxuICogQHBhcmFtICB7RnVuY3Rpb259IFtvcHRpb25zLnNob3dMYWJlbF1cclxuICogQHBhcmFtICB7Qm9vbGVhbn0gW29wdGlvbnMuZGl2aWRlcl0gYWRkcyBhIGRpdmlkZXIgYXQgdGhlIHRvcCBvZiB0aGUgbGFiZWwgaWYgdHJ1ZTsgZGVmYXVsdDogZmFsc2VcclxuICovXHJcbnZhciBsYWJlbCA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuICByZXR1cm4ge1xyXG4gICAgaWQ6IG9wdGlvbnMuaWQsXHJcbiAgICBodG1sOiAnPGxhYmVsIGRhdGEtdmFsdWU9XCJsYWJlbFwiICcgK1xyXG4gICAgICAgICAgICAnZGF0YS1zaG93PVwic2hvd0xhYmVsXCIgJyArXHJcbiAgICAgICAgICAgICdjbGFzcz1cImVudHJ5LWxhYmVsJyArIChvcHRpb25zLmRpdmlkZXIgPyAnIGRpdmlkZXInIDogJycpICsgJ1wiPicgK1xyXG4gICAgICAgICAgJzwvbGFiZWw+JyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMuZ2V0ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuZ2V0KGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB7IGxhYmVsOiBvcHRpb25zLmxhYmVsVGV4dCB9O1xyXG4gICAgfSxcclxuICAgIHNob3dMYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICBpZiAodHlwZW9mIG9wdGlvbnMuc2hvd0xhYmVsID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMuc2hvd0xhYmVsKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG4gIH07XHJcbn07XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGxhYmVsO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uL1V0aWxzJykuZXNjYXBlSFRNTDtcclxuXHJcbnZhciBlbnRyeUZpZWxkRGVzY3JpcHRpb24gPSByZXF1aXJlKCcuL0VudHJ5RmllbGREZXNjcmlwdGlvbicpO1xyXG5cclxudmFyIGJpbmQgPSByZXF1aXJlKCdsb2Rhc2gvYmluZCcpO1xyXG5cclxuLyoqXHJcbiAqIEFuIGVudHJ5IHRoYXQgcmVuZGVycyBhIGNsaWNrYWJsZSBsaW5rLlxyXG4gKlxyXG4gKiBBIHBhc3NlZCB7QGxpbmsgb3B0aW9ucyNoYW5kbGVDbGlja30gaGFuZGxlciBpcyByZXNwb25zaWJsZVxyXG4gKiB0byBwcm9jZXNzIHRoZSBjbGljay5cclxuICpcclxuICogVGhlIGxpbmsgbWF5IGJlIGNvbmRpdGlvbmFsbHkgc2hvd24gb3IgaGlkZGVuLiBUaGlzIGNhbiBiZVxyXG4gKiBjb250cm9sbGVkIHZpYSB0aGUge0BsaW5rIG9wdGlvbnMuc2hvd0xpbmt9LlxyXG4gKlxyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xyXG4gKiBAcGFyYW0ge1N0cmluZ30gb3B0aW9ucy5pZFxyXG4gKiBAcGFyYW0ge1N0cmluZ30gW29wdGlvbnMubGFiZWxdXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG9wdGlvbnMuaGFuZGxlQ2xpY2tcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gW29wdGlvbnMuc2hvd0xpbmtdIHJldHVybmluZyBmYWxzZSB0byBoaWRlIGxpbmtcclxuICogQHBhcmFtIHtTdHJpbmd9IFtvcHRpb25zLmRlc2NyaXB0aW9uXVxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKlxyXG4gKiB2YXIgbGlua0VudHJ5ID0gbGluayh7XHJcbiAqICAgaWQ6ICdmb28nLFxyXG4gKiAgIGRlc2NyaXB0aW9uOiAnU29tZSBEZXNjcmlwdGlvbicsXHJcbiAqICAgaGFuZGxlQ2xpY2s6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50KSB7IC4uLiB9LFxyXG4gKiAgIHNob3dMaW5rOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7IC4uLiB9XHJcbiAqIH0pO1xyXG4gKlxyXG4gKiBAcmV0dXJuIHtFbnRyeX0gdGhlIG5ld2x5IGNyZWF0ZWQgZW50cnlcclxuICovXHJcbmZ1bmN0aW9uIGxpbmsob3B0aW9ucykge1xyXG5cclxuICB2YXIgaWQgPSBvcHRpb25zLmlkLFxyXG4gICAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgaWQsXHJcbiAgICAgIHNob3dMaW5rID0gb3B0aW9ucy5zaG93TGluayxcclxuICAgICAgaGFuZGxlQ2xpY2sgPSBvcHRpb25zLmhhbmRsZUNsaWNrLFxyXG4gICAgICBkZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb247XHJcblxyXG4gIGlmIChzaG93TGluayAmJiB0eXBlb2Ygc2hvd0xpbmsgIT09ICdmdW5jdGlvbicpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcignb3B0aW9ucy5zaG93TGluayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcclxuICB9XHJcblxyXG4gIGlmICh0eXBlb2YgaGFuZGxlQ2xpY2sgIT09ICdmdW5jdGlvbicpIHtcclxuICAgIHRocm93IG5ldyBFcnJvcignb3B0aW9ucy5oYW5kbGVDbGljayBtdXN0IGJlIGEgZnVuY3Rpb24nKTtcclxuICB9XHJcblxyXG4gIHZhciByZXNvdXJjZSA9IHtcclxuICAgIGlkOiBpZFxyXG4gIH07XHJcblxyXG4gIHJlc291cmNlLmh0bWwgPVxyXG4gICAgJzxhIGRhdGEtYWN0aW9uPVwiaGFuZGxlQ2xpY2tcIiAnICtcclxuICAgIChzaG93TGluayA/ICdkYXRhLXNob3c9XCJzaG93TGlua1wiICcgOiAnJykgK1xyXG4gICAgJ2NsYXNzPVwiYnBwLWVudHJ5LWxpbmsnICsgKG9wdGlvbnMuY3NzQ2xhc3NlcyA/ICcgJyArIGVzY2FwZUhUTUwob3B0aW9ucy5jc3NDbGFzc2VzKSA6ICcnKSArXHJcbiAgICAnXCI+JyArIGVzY2FwZUhUTUwobGFiZWwpICsgJzwvYT4nO1xyXG5cclxuICAvLyBhZGQgZGVzY3JpcHRpb24gYmVsb3cgbGluayBlbnRyeSBmaWVsZFxyXG4gIGlmIChkZXNjcmlwdGlvbikge1xyXG4gICAgcmVzb3VyY2UuaHRtbCArPSBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgcmVzb3VyY2UuaGFuZGxlQ2xpY2sgPSBiaW5kKGhhbmRsZUNsaWNrLCByZXNvdXJjZSk7XHJcblxyXG4gIGlmICh0eXBlb2Ygc2hvd0xpbmsgPT09ICdmdW5jdGlvbicpIHtcclxuICAgIHJlc291cmNlLnNob3dMaW5rID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgIHJldHVybiBzaG93TGluay5hcHBseShyZXNvdXJjZSwgYXJndW1lbnRzKTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcmVzb3VyY2U7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gbGluaztcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVzY2FwZUhUTUwgPSByZXF1aXJlKCcuLi9VdGlscycpLmVzY2FwZUhUTUw7XHJcblxyXG52YXIgZG9taWZ5ID0gcmVxdWlyZSgnbWluLWRvbScpLmRvbWlmeTtcclxuXHJcbnZhciBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKTtcclxuXHJcbnZhciBlbnRyeUZpZWxkRGVzY3JpcHRpb24gPSByZXF1aXJlKCcuL0VudHJ5RmllbGREZXNjcmlwdGlvbicpO1xyXG5cclxuXHJcbnZhciBpc0xpc3QgPSBmdW5jdGlvbihsaXN0KSB7XHJcbiAgcmV0dXJuICEoIWxpc3QgfHwgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGxpc3QpICE9PSAnW29iamVjdCBBcnJheV0nKTtcclxufTtcclxuXHJcbnZhciBhZGRFbXB0eVBhcmFtZXRlciA9IGZ1bmN0aW9uKGxpc3QpIHtcclxuICByZXR1cm4gbGlzdC5jb25jYXQoWyB7IG5hbWU6ICcnLCB2YWx1ZTogJycgfSBdKTtcclxufTtcclxuXHJcbnZhciBjcmVhdGVPcHRpb24gPSBmdW5jdGlvbihvcHRpb24pIHtcclxuICByZXR1cm4gJzxvcHRpb24gdmFsdWU9XCInICsgb3B0aW9uLnZhbHVlICsgJ1wiPicgKyBvcHRpb24ubmFtZSArICc8L29wdGlvbj4nO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIEBwYXJhbSAge09iamVjdH0gb3B0aW9uc1xyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMuaWRcclxuICogQHBhcmFtICB7c3RyaW5nfSBbb3B0aW9ucy5sYWJlbF1cclxuICogQHBhcmFtICB7QXJyYXk8T2JqZWN0Pn0gb3B0aW9ucy5zZWxlY3RPcHRpb25zXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5tb2RlbFByb3BlcnR5XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IG9wdGlvbnMuZW1wdHlQYXJhbWV0ZXJcclxuICogQHBhcmFtICB7ZnVuY3Rpb259IG9wdGlvbnMuZGlzYWJsZWRcclxuICogQHBhcmFtICB7ZnVuY3Rpb259IG9wdGlvbnMuaGlkZGVuXHJcbiAqIEBwYXJhbSAge09iamVjdH0gZGVmYXVsdFBhcmFtZXRlcnNcclxuICpcclxuICogQHJldHVybiB7T2JqZWN0fVxyXG4gKi9cclxudmFyIHNlbGVjdGJveCA9IGZ1bmN0aW9uKG9wdGlvbnMsIGRlZmF1bHRQYXJhbWV0ZXJzKSB7XHJcbiAgdmFyIHJlc291cmNlID0gZGVmYXVsdFBhcmFtZXRlcnMsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCB8fCByZXNvdXJjZS5pZCxcclxuICAgICAgc2VsZWN0T3B0aW9ucyA9IG9wdGlvbnMuc2VsZWN0T3B0aW9ucyB8fCBbIHsgbmFtZTogJycsIHZhbHVlOiAnJyB9IF0sXHJcbiAgICAgIG1vZGVsUHJvcGVydHkgPSBvcHRpb25zLm1vZGVsUHJvcGVydHksXHJcbiAgICAgIGVtcHR5UGFyYW1ldGVyID0gb3B0aW9ucy5lbXB0eVBhcmFtZXRlcixcclxuICAgICAgY2FuQmVEaXNhYmxlZCA9ICEhb3B0aW9ucy5kaXNhYmxlZCAmJiB0eXBlb2Ygb3B0aW9ucy5kaXNhYmxlZCA9PT0gJ2Z1bmN0aW9uJyxcclxuICAgICAgY2FuQmVIaWRkZW4gPSAhIW9wdGlvbnMuaGlkZGVuICYmIHR5cGVvZiBvcHRpb25zLmhpZGRlbiA9PT0gJ2Z1bmN0aW9uJyxcclxuICAgICAgZGVzY3JpcHRpb24gPSBvcHRpb25zLmRlc2NyaXB0aW9uO1xyXG5cclxuXHJcbiAgaWYgKGVtcHR5UGFyYW1ldGVyKSB7XHJcbiAgICBzZWxlY3RPcHRpb25zID0gYWRkRW1wdHlQYXJhbWV0ZXIoc2VsZWN0T3B0aW9ucyk7XHJcbiAgfVxyXG5cclxuXHJcbiAgcmVzb3VyY2UuaHRtbCA9XHJcbiAgICAnPGxhYmVsIGZvcj1cImFjdGl2aXRpLScgKyBlc2NhcGVIVE1MKHJlc291cmNlLmlkKSArICdcIicgK1xyXG4gICAgKGNhbkJlRGlzYWJsZWQgPyAnZGF0YS1kaXNhYmxlPVwiaXNEaXNhYmxlZFwiICcgOiAnJykgK1xyXG4gICAgKGNhbkJlSGlkZGVuID8gJ2RhdGEtc2hvdz1cImlzSGlkZGVuXCIgJyA6ICcnKSArXHJcbiAgICAnPicgKyBlc2NhcGVIVE1MKGxhYmVsKSArICc8L2xhYmVsPicgK1xyXG4gICAgJzxzZWxlY3QgaWQ9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChyZXNvdXJjZS5pZCkgKyAnLXNlbGVjdFwiIG5hbWU9XCInICtcclxuICAgIGVzY2FwZUhUTUwobW9kZWxQcm9wZXJ0eSkgKyAnXCInICtcclxuICAgIChjYW5CZURpc2FibGVkID8gJ2RhdGEtZGlzYWJsZT1cImlzRGlzYWJsZWRcIiAnIDogJycpICtcclxuICAgIChjYW5CZUhpZGRlbiA/ICdkYXRhLXNob3c9XCJpc0hpZGRlblwiICcgOiAnJykgK1xyXG4gICAgJyBkYXRhLXZhbHVlPic7XHJcblxyXG4gIGlmIChpc0xpc3Qoc2VsZWN0T3B0aW9ucykpIHtcclxuICAgIGZvckVhY2goc2VsZWN0T3B0aW9ucywgZnVuY3Rpb24ob3B0aW9uKSB7XHJcbiAgICAgIHJlc291cmNlLmh0bWwgKz0gJzxvcHRpb24gdmFsdWU9XCInICsgZXNjYXBlSFRNTChvcHRpb24udmFsdWUpICsgJ1wiPicgK1xyXG4gICAgICAob3B0aW9uLm5hbWUgPyBlc2NhcGVIVE1MKG9wdGlvbi5uYW1lKSA6ICcnKSArICc8L29wdGlvbj4nO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXNvdXJjZS5odG1sICs9ICc8L3NlbGVjdD4nO1xyXG5cclxuICAvLyBhZGQgZGVzY3JpcHRpb24gYmVsb3cgc2VsZWN0IGJveCBlbnRyeSBmaWVsZFxyXG4gIGlmIChkZXNjcmlwdGlvbiAmJiB0eXBlb2Ygb3B0aW9ucy5zaG93Q3VzdG9tSW5wdXQgIT09ICdmdW5jdGlvbicpIHtcclxuICAgIHJlc291cmNlLmh0bWwgKz0gZW50cnlGaWVsZERlc2NyaXB0aW9uKGRlc2NyaXB0aW9uKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZpbGwgdGhlIHNlbGVjdCBib3ggb3B0aW9ucyBkeW5hbWljYWxseS5cclxuICAgKlxyXG4gICAqIENhbGxzIHRoZSBkZWZpbmVkIGZ1bmN0aW9uICNzZWxlY3RPcHRpb25zIGluIHRoZSBlbnRyeSB0byBnZXQgdGhlXHJcbiAgICogdmFsdWVzIGZvciB0aGUgb3B0aW9ucyBhbmQgc2V0IHRoZSB2YWx1ZSB0byB0aGUgaW5wdXROb2RlLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gICAqIEBwYXJhbSB7SFRNTEVsZW1lbnR9IGVudHJ5Tm9kZVxyXG4gICAqIEBwYXJhbSB7RW50cnlEZXNjcmlwdG9yfSBpbnB1dE5vZGVcclxuICAgKiBAcGFyYW0ge09iamVjdH0gaW5wdXROYW1lXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IG5ld1ZhbHVlXHJcbiAgICovXHJcbiAgcmVzb3VyY2Uuc2V0Q29udHJvbFZhbHVlID0gZnVuY3Rpb24oZWxlbWVudCwgZW50cnlOb2RlLCBpbnB1dE5vZGUsIGlucHV0TmFtZSwgbmV3VmFsdWUpIHtcclxuICAgIGlmICh0eXBlb2Ygc2VsZWN0T3B0aW9ucyA9PT0gJ2Z1bmN0aW9uJykge1xyXG5cclxuICAgICAgdmFyIG9wdGlvbnMgPSBzZWxlY3RPcHRpb25zKGVsZW1lbnQsIGlucHV0Tm9kZSk7XHJcblxyXG4gICAgICBpZiAob3B0aW9ucykge1xyXG5cclxuICAgICAgICAvLyByZW1vdmUgZXhpc3Rpbmcgb3B0aW9uc1xyXG4gICAgICAgIHdoaWxlIChpbnB1dE5vZGUuZmlyc3RDaGlsZCkge1xyXG4gICAgICAgICAgaW5wdXROb2RlLnJlbW92ZUNoaWxkKGlucHV0Tm9kZS5maXJzdENoaWxkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGFkZCBvcHRpb25zXHJcbiAgICAgICAgZm9yRWFjaChvcHRpb25zLCBmdW5jdGlvbihvcHRpb24pIHtcclxuICAgICAgICAgIHZhciB0ZW1wbGF0ZSA9IGRvbWlmeShjcmVhdGVPcHRpb24ob3B0aW9uKSk7XHJcblxyXG4gICAgICAgICAgaW5wdXROb2RlLmFwcGVuZENoaWxkKHRlbXBsYXRlKTtcclxuICAgICAgICB9KTtcclxuXHJcblxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gc2V0IHNlbGVjdCB2YWx1ZVxyXG4gICAgaWYgKG5ld1ZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgaW5wdXROb2RlLnZhbHVlID0gbmV3VmFsdWU7XHJcbiAgICB9XHJcblxyXG4gIH07XHJcblxyXG4gIGlmIChjYW5CZURpc2FibGVkKSB7XHJcbiAgICByZXNvdXJjZS5pc0Rpc2FibGVkID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgIHJldHVybiBvcHRpb25zLmRpc2FibGVkLmFwcGx5KHJlc291cmNlLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIGlmIChjYW5CZUhpZGRlbikge1xyXG4gICAgcmVzb3VyY2UuaXNIaWRkZW4gPSBmdW5jdGlvbigpIHtcclxuICAgICAgcmV0dXJuICFvcHRpb25zLmhpZGRlbi5hcHBseShyZXNvdXJjZSwgYXJndW1lbnRzKTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICByZXNvdXJjZS5jc3NDbGFzc2VzID0gWydicHAtZHJvcGRvd24nXTtcclxuXHJcbiAgcmV0dXJuIHJlc291cmNlO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBzZWxlY3Rib3g7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlc2NhcGVIVE1MID0gcmVxdWlyZSgnLi4vVXRpbHMnKS5lc2NhcGVIVE1MO1xyXG5cclxudmFyIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbnZhciBkb21RdWVyeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5xdWVyeSxcclxuICAgIGRvbUF0dHIgPSByZXF1aXJlKCdtaW4tZG9tJykuYXR0cixcclxuICAgIGRvbUNsb3Nlc3QgPSByZXF1aXJlKCdtaW4tZG9tJykuY2xvc2VzdDtcclxuXHJcbnZhciBmaWx0ZXIgPSByZXF1aXJlKCdsb2Rhc2gvZmlsdGVyJyksXHJcbiAgICBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKSxcclxuICAgIGtleXMgPSByZXF1aXJlKCdsb2Rhc2gva2V5cycpO1xyXG5cclxudmFyIGRvbWlmeSA9IHJlcXVpcmUoJ21pbi1kb20nKS5kb21pZnk7XHJcblxyXG52YXIgZW50cnlGaWVsZERlc2NyaXB0aW9uID0gcmVxdWlyZSgnLi9FbnRyeUZpZWxkRGVzY3JpcHRpb24nKTtcclxuXHJcbnZhciB1cGRhdGVTZWxlY3Rpb24gPSByZXF1aXJlKCdzZWxlY3Rpb24tdXBkYXRlJyk7XHJcblxyXG52YXIgVEFCTEVfUk9XX0RJVl9TTklQUEVUID0gJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlciBicHAtdGFibGUtcm93XCI+JztcclxudmFyIERFTEVURV9ST1dfQlVUVE9OX1NOSVBQRVQgPSAnPGJ1dHRvbiBjbGFzcz1cImNsZWFyXCIgZGF0YS1hY3Rpb249XCJkZWxldGVFbGVtZW50XCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHNwYW4+WDwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPC9idXR0b24+JztcclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUlucHV0Um93VGVtcGxhdGUocHJvcGVydGllcywgY2FuUmVtb3ZlKSB7XHJcbiAgdmFyIHRlbXBsYXRlID0gVEFCTEVfUk9XX0RJVl9TTklQUEVUO1xyXG4gIHRlbXBsYXRlICs9IGNyZWF0ZUlucHV0VGVtcGxhdGUocHJvcGVydGllcywgY2FuUmVtb3ZlKTtcclxuICB0ZW1wbGF0ZSArPSBjYW5SZW1vdmUgPyBERUxFVEVfUk9XX0JVVFRPTl9TTklQUEVUIDogJyc7XHJcbiAgdGVtcGxhdGUgKz0gJzwvZGl2Pic7XHJcblxyXG4gIHJldHVybiB0ZW1wbGF0ZTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlSW5wdXRUZW1wbGF0ZShwcm9wZXJ0aWVzLCBjYW5SZW1vdmUpIHtcclxuICB2YXIgY29sdW1ucyA9IHByb3BlcnRpZXMubGVuZ3RoO1xyXG4gIHZhciB0ZW1wbGF0ZSA9ICcnO1xyXG4gIGZvckVhY2gocHJvcGVydGllcywgZnVuY3Rpb24ocHJvcCkge1xyXG4gICAgdGVtcGxhdGUgKz0gJzxpbnB1dCBjbGFzcz1cImJwcC10YWJsZS1yb3ctY29sdW1ucy0nICsgY29sdW1ucyArICcgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2FuUmVtb3ZlID8gJ2JwcC10YWJsZS1yb3ctcmVtb3ZhYmxlJyA6ICcnKSArICdcIiAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAnaWQ9XCJhY3Rpdml0aS10YWJsZS1yb3ctY2VsbC1pbnB1dC12YWx1ZVwiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICd0eXBlPVwidGV4dFwiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICduYW1lPVwiJyArIGVzY2FwZUhUTUwocHJvcCkgKyAnXCIgLz4nO1xyXG4gIH0pO1xyXG4gIHJldHVybiB0ZW1wbGF0ZTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlTGFiZWxSb3dUZW1wbGF0ZShsYWJlbHMpIHtcclxuICB2YXIgdGVtcGxhdGUgPSBUQUJMRV9ST1dfRElWX1NOSVBQRVQ7XHJcbiAgdGVtcGxhdGUgKz0gY3JlYXRlTGFiZWxUZW1wbGF0ZShsYWJlbHMpO1xyXG4gIHRlbXBsYXRlICs9ICc8L2Rpdj4nO1xyXG5cclxuICByZXR1cm4gdGVtcGxhdGU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUxhYmVsVGVtcGxhdGUobGFiZWxzKSB7XHJcbiAgdmFyIGNvbHVtbnMgPSBsYWJlbHMubGVuZ3RoO1xyXG4gIHZhciB0ZW1wbGF0ZSA9ICcnO1xyXG4gIGZvckVhY2gobGFiZWxzLCBmdW5jdGlvbihsYWJlbCkge1xyXG4gICAgdGVtcGxhdGUgKz0gJzxsYWJlbCBjbGFzcz1cImJwcC10YWJsZS1yb3ctY29sdW1ucy0nICsgY29sdW1ucyArICdcIj4nICsgZXNjYXBlSFRNTChsYWJlbCkgKyAnPC9sYWJlbD4nO1xyXG4gIH0pO1xyXG4gIHJldHVybiB0ZW1wbGF0ZTtcclxufVxyXG5cclxuZnVuY3Rpb24gcGljayhlbGVtZW50cywgcHJvcGVydGllcykge1xyXG4gIHJldHVybiAoZWxlbWVudHMgfHwgW10pLm1hcChmdW5jdGlvbihlbGVtKSB7XHJcbiAgICB2YXIgbmV3RWxlbWVudCA9IHt9O1xyXG4gICAgZm9yRWFjaChwcm9wZXJ0aWVzLCBmdW5jdGlvbihwcm9wKSB7XHJcbiAgICAgIG5ld0VsZW1lbnRbcHJvcF0gPSBlbGVtW3Byb3BdIHx8ICcnO1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gbmV3RWxlbWVudDtcclxuICB9KTtcclxufVxyXG5cclxuZnVuY3Rpb24gZGlmZihlbGVtZW50LCBub2RlLCB2YWx1ZXMsIG9sZFZhbHVlcywgZWRpdGFibGUpIHtcclxuICByZXR1cm4gZmlsdGVyKHZhbHVlcywgZnVuY3Rpb24odmFsdWUsIGlkeCkge1xyXG4gICAgcmV0dXJuICF2YWx1ZUVxdWFsKGVsZW1lbnQsIG5vZGUsIHZhbHVlLCBvbGRWYWx1ZXNbaWR4XSwgZWRpdGFibGUsIGlkeCk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHZhbHVlRXF1YWwoZWxlbWVudCwgbm9kZSwgdmFsdWUsIG9sZFZhbHVlLCBlZGl0YWJsZSwgaWR4KSB7XHJcbiAgaWYgKHZhbHVlICYmICFvbGRWYWx1ZSkge1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuICB2YXIgYWxsS2V5cyA9IGtleXModmFsdWUpLmNvbmNhdChrZXlzKG9sZFZhbHVlKSk7XHJcblxyXG4gIHJldHVybiBhbGxLZXlzLmV2ZXJ5KGZ1bmN0aW9uKGtleSkge1xyXG4gICAgdmFyIG4gPSB2YWx1ZVtrZXldIHx8IHVuZGVmaW5lZDtcclxuICAgIHZhciBvID0gb2xkVmFsdWVba2V5XSB8fCB1bmRlZmluZWQ7XHJcbiAgICByZXR1cm4gIWVkaXRhYmxlKGVsZW1lbnQsIG5vZGUsIGtleSwgaWR4KSB8fCBuID09PSBvO1xyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRFbnRyeU5vZGUobm9kZSkge1xyXG4gIHJldHVybiBkb21DbG9zZXN0KG5vZGUsICdbZGF0YS1lbnRyeV0nLCB0cnVlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0Q29udGFpbmVyKG5vZGUpIHtcclxuICByZXR1cm4gZG9tUXVlcnkoJ2RpdltkYXRhLWxpc3QtZW50cnktY29udGFpbmVyXScsIG5vZGUpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRTZWxlY3Rpb24obm9kZSkge1xyXG4gIHJldHVybiB7XHJcbiAgICBzdGFydDogbm9kZS5zZWxlY3Rpb25TdGFydCxcclxuICAgIGVuZDogbm9kZS5zZWxlY3Rpb25FbmRcclxuICB9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRTZWxlY3Rpb24obm9kZSwgc2VsZWN0aW9uKSB7XHJcbiAgbm9kZS5zZWxlY3Rpb25TdGFydCA9IHNlbGVjdGlvbi5zdGFydDtcclxuICBub2RlLnNlbGVjdGlvbkVuZCA9IHNlbGVjdGlvbi5lbmQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmlkXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5kZXNjcmlwdGlvblxyXG4gKiBAcGFyYW0gIHtBcnJheTxzdHJpbmc+fSBvcHRpb25zLm1vZGVsUHJvcGVydGllc1xyXG4gKiBAcGFyYW0gIHtBcnJheTxzdHJpbmc+fSBvcHRpb25zLmxhYmVsc1xyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gb3B0aW9ucy5nZXRFbGVtZW50cyAtIHRoaXMgY2FsbGJhY2sgZnVuY3Rpb24gbXVzdCByZXR1cm4gYSBsaXN0IG9mIGJ1c2luZXNzIG9iamVjdCBpdGVtc1xyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gb3B0aW9ucy5yZW1vdmVFbGVtZW50XHJcbiAqIEBwYXJhbSAge0Z1bmN0aW9ufSBvcHRpb25zLmFkZEVsZW1lbnRcclxuICogQHBhcmFtICB7RnVuY3Rpb259IG9wdGlvbnMudXBkYXRlRWxlbWVudFxyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gb3B0aW9ucy5lZGl0YWJsZVxyXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gb3B0aW9ucy5zZXRDb250cm9sVmFsdWVcclxuICogQHBhcmFtICB7RnVuY3Rpb259IG9wdGlvbnMuc2hvd1xyXG4gKlxyXG4gKiBAcmV0dXJuIHtPYmplY3R9XHJcbiAqL1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcclxuXHJcbiAgdmFyIGlkID0gb3B0aW9ucy5pZCxcclxuICAgICAgbW9kZWxQcm9wZXJ0aWVzID0gb3B0aW9ucy5tb2RlbFByb3BlcnRpZXMsXHJcbiAgICAgIGxhYmVscyA9IG9wdGlvbnMubGFiZWxzLFxyXG4gICAgICBkZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb247XHJcblxyXG4gIHZhciBsYWJlbFJvdyA9IGNyZWF0ZUxhYmVsUm93VGVtcGxhdGUobGFiZWxzKTtcclxuXHJcbiAgdmFyIGdldEVsZW1lbnRzID0gb3B0aW9ucy5nZXRFbGVtZW50cztcclxuXHJcbiAgdmFyIHJlbW92ZUVsZW1lbnQgPSBvcHRpb25zLnJlbW92ZUVsZW1lbnQsXHJcbiAgICAgIGNhblJlbW92ZSA9IHR5cGVvZiByZW1vdmVFbGVtZW50ID09PSAnZnVuY3Rpb24nO1xyXG5cclxuICB2YXIgYWRkRWxlbWVudCA9IG9wdGlvbnMuYWRkRWxlbWVudCxcclxuICAgICAgY2FuQWRkID0gdHlwZW9mIGFkZEVsZW1lbnQgPT09ICdmdW5jdGlvbicsXHJcbiAgICAgIGFkZExhYmVsID0gb3B0aW9ucy5hZGRMYWJlbCB8fCAnQWRkIFZhbHVlJztcclxuXHJcbiAgdmFyIHVwZGF0ZUVsZW1lbnQgPSBvcHRpb25zLnVwZGF0ZUVsZW1lbnQsXHJcbiAgICAgIGNhblVwZGF0ZSA9IHR5cGVvZiB1cGRhdGVFbGVtZW50ID09PSAnZnVuY3Rpb24nO1xyXG5cclxuICB2YXIgZWRpdGFibGUgPSBvcHRpb25zLmVkaXRhYmxlIHx8IGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSxcclxuICAgICAgc2V0Q29udHJvbFZhbHVlID0gb3B0aW9ucy5zZXRDb250cm9sVmFsdWU7XHJcblxyXG4gIHZhciBzaG93ID0gb3B0aW9ucy5zaG93LFxyXG4gICAgICBjYW5CZVNob3duID0gdHlwZW9mIHNob3cgPT09ICdmdW5jdGlvbic7XHJcblxyXG4gIHZhciBlbGVtZW50cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHJldHVybiBwaWNrKGdldEVsZW1lbnRzKGVsZW1lbnQsIG5vZGUpLCBtb2RlbFByb3BlcnRpZXMpO1xyXG4gIH07XHJcblxyXG4gIHZhciBmYWN0b3J5ID0ge1xyXG4gICAgaWQ6IGlkLFxyXG4gICAgaHRtbDogKGNhbkFkZCA/XHJcbiAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLXRhYmxlLWFkZC1yb3dcIiAnICsgKGNhbkJlU2hvd24gPyAnZGF0YS1zaG93PVwic2hvd1wiJyA6ICcnKSArICc+JyArXHJcbiAgICAgICAgICAgICc8bGFiZWw+JyArIGVzY2FwZUhUTUwoYWRkTGFiZWwpICsgJzwvbGFiZWw+JyArXHJcbiAgICAgICAgICAgICc8YnV0dG9uIGNsYXNzPVwiYWRkXCIgZGF0YS1hY3Rpb249XCJhZGRFbGVtZW50XCI+PHNwYW4+Kzwvc3Bhbj48L2J1dHRvbj4nICtcclxuICAgICAgICAgICc8L2Rpdj4nIDogJycpICtcclxuICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLXRhYmxlXCIgZGF0YS1zaG93PVwic2hvd1RhYmxlXCI+JyArXHJcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXIgYnBwLXRhYmxlLXJvd1wiPicgK1xyXG4gICAgICAgICAgICAgICBsYWJlbFJvdyArXHJcbiAgICAgICAgICAgICc8L2Rpdj4nICtcclxuICAgICAgICAgICAgJzxkaXYgZGF0YS1saXN0LWVudHJ5LWNvbnRhaW5lcj4nICtcclxuICAgICAgICAgICAgJzwvZGl2PicgK1xyXG4gICAgICAgICAgJzwvZGl2PicgK1xyXG5cclxuICAgICAgICAgIC8vIGFkZCBkZXNjcmlwdGlvbiBiZWxvdyB0YWJsZSBlbnRyeSBmaWVsZFxyXG4gICAgICAgICAgKGRlc2NyaXB0aW9uID8gZW50cnlGaWVsZERlc2NyaXB0aW9uKGRlc2NyaXB0aW9uKSA6ICcnKSxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvRWxlbWVudHMgPSBlbGVtZW50cyhlbGVtZW50LCBub2RlLCB0aGlzLl9faW52YWxpZFZhbHVlcyk7XHJcblxyXG4gICAgICB2YXIgaW52YWxpZFZhbHVlcyA9IHRoaXMuX19pbnZhbGlkVmFsdWVzO1xyXG5cclxuICAgICAgZGVsZXRlIHRoaXMuX19pbnZhbGlkVmFsdWVzO1xyXG5cclxuICAgICAgZm9yRWFjaChpbnZhbGlkVmFsdWVzLCBmdW5jdGlvbih2YWx1ZSwgaWR4KSB7XHJcbiAgICAgICAgdmFyIGVsZW1lbnQgPSBib0VsZW1lbnRzW2lkeF07XHJcblxyXG4gICAgICAgIGZvckVhY2gobW9kZWxQcm9wZXJ0aWVzLCBmdW5jdGlvbihwcm9wKSB7XHJcbiAgICAgICAgICBlbGVtZW50W3Byb3BdID0gdmFsdWVbcHJvcF07XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgcmV0dXJuIGJvRWxlbWVudHM7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBhY3Rpb24gPSB0aGlzLl9fYWN0aW9uIHx8IHt9O1xyXG4gICAgICBkZWxldGUgdGhpcy5fX2FjdGlvbjtcclxuXHJcbiAgICAgIGlmIChhY3Rpb24uaWQgPT09ICdkZWxldGUtZWxlbWVudCcpIHtcclxuICAgICAgICByZXR1cm4gcmVtb3ZlRWxlbWVudChlbGVtZW50LCBub2RlLCBhY3Rpb24uaWR4KTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmIChhY3Rpb24uaWQgPT09ICdhZGQtZWxlbWVudCcpIHtcclxuICAgICAgICByZXR1cm4gYWRkRWxlbWVudChlbGVtZW50LCBub2RlKTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmIChjYW5VcGRhdGUpIHtcclxuICAgICAgICB2YXIgY29tbWFuZHMgPSBbXSxcclxuICAgICAgICAgICAgdmFsdWVzVG9WYWxpZGF0ZSA9IHZhbHVlcztcclxuXHJcbiAgICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnZhbGlkYXRlICE9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICB2YWx1ZXNUb1ZhbGlkYXRlID0gZGlmZihlbGVtZW50LCBub2RlLCB2YWx1ZXMsIGVsZW1lbnRzKGVsZW1lbnQsIG5vZGUpLCBlZGl0YWJsZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gICAgICAgIGZvckVhY2godmFsdWVzVG9WYWxpZGF0ZSwgZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICAgIHZhciB2YWxpZGF0aW9uRXJyb3IsXHJcbiAgICAgICAgICAgICAgaWR4ID0gdmFsdWVzLmluZGV4T2YodmFsdWUpO1xyXG5cclxuICAgICAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy52YWxpZGF0ZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9uRXJyb3IgPSBvcHRpb25zLnZhbGlkYXRlKGVsZW1lbnQsIHZhbHVlLCBub2RlLCBpZHgpO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGlmICghdmFsaWRhdGlvbkVycm9yKSB7XHJcbiAgICAgICAgICAgIHZhciBjbWQgPSB1cGRhdGVFbGVtZW50KGVsZW1lbnQsIHZhbHVlLCBub2RlLCBpZHgpO1xyXG5cclxuICAgICAgICAgICAgaWYgKGNtZCkge1xyXG4gICAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goY21kKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gY2FjaGUgaW52YWxpZCB2YWx1ZSBpbiBhbiBvYmplY3QgYnkgaW5kZXggYXMga2V5XHJcbiAgICAgICAgICAgIHNlbGYuX19pbnZhbGlkVmFsdWVzID0gc2VsZi5fX2ludmFsaWRWYWx1ZXMgfHwge307XHJcbiAgICAgICAgICAgIHNlbGYuX19pbnZhbGlkVmFsdWVzW2lkeF0gPSB2YWx1ZTtcclxuXHJcbiAgICAgICAgICAgIC8vIGV4ZWN1dGUgYSBjb21tYW5kLCB3aGljaCBkb2VzIG5vdCBkbyBhbnl0aGluZ1xyXG4gICAgICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHt9KSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIGNyZWF0ZUxpc3RFbnRyeVRlbXBsYXRlOiBmdW5jdGlvbih2YWx1ZSwgaW5kZXgsIHNlbGVjdEJveCkge1xyXG4gICAgICByZXR1cm4gY3JlYXRlSW5wdXRSb3dUZW1wbGF0ZShtb2RlbFByb3BlcnRpZXMsIGNhblJlbW92ZSk7XHJcbiAgICB9LFxyXG5cclxuICAgIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50LCBzY29wZU5vZGUpIHtcclxuICAgICAgdmFyIHRlbXBsYXRlID0gZG9taWZ5KGNyZWF0ZUlucHV0Um93VGVtcGxhdGUobW9kZWxQcm9wZXJ0aWVzLCBjYW5SZW1vdmUpKTtcclxuXHJcbiAgICAgIHZhciBjb250YWluZXIgPSBnZXRDb250YWluZXIobm9kZSk7XHJcbiAgICAgIGNvbnRhaW5lci5hcHBlbmRDaGlsZCh0ZW1wbGF0ZSk7XHJcblxyXG4gICAgICB0aGlzLl9fYWN0aW9uID0ge1xyXG4gICAgICAgIGlkOiAnYWRkLWVsZW1lbnQnXHJcbiAgICAgIH07XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgZGVsZXRlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgZXZlbnQsIHNjb3BlTm9kZSkge1xyXG4gICAgICB2YXIgY29udGFpbmVyID0gZ2V0Q29udGFpbmVyKG5vZGUpO1xyXG4gICAgICB2YXIgcm93VG9EZWxldGUgPSBldmVudC5kZWxlZ2F0ZVRhcmdldC5wYXJlbnROb2RlO1xyXG4gICAgICB2YXIgaWR4ID0gcGFyc2VJbnQoZG9tQXR0cihyb3dUb0RlbGV0ZSwgJ2RhdGEtaW5kZXgnKSwgMTApO1xyXG5cclxuICAgICAgY29udGFpbmVyLnJlbW92ZUNoaWxkKHJvd1RvRGVsZXRlKTtcclxuXHJcbiAgICAgIHRoaXMuX19hY3Rpb24gPSB7XHJcbiAgICAgICAgaWQ6ICdkZWxldGUtZWxlbWVudCcsXHJcbiAgICAgICAgaWR4OiBpZHhcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICBlZGl0YWJsZTogZnVuY3Rpb24oZWxlbWVudCwgcm93Tm9kZSwgaW5wdXQsIHByb3AsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGVudHJ5Tm9kZSA9IGRvbUNsb3Nlc3Qocm93Tm9kZSwgJ1tkYXRhLWVudHJ5XScpO1xyXG4gICAgICByZXR1cm4gZWRpdGFibGUoZWxlbWVudCwgZW50cnlOb2RlLCBwcm9wLCBpZHgpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzaG93OiBmdW5jdGlvbihlbGVtZW50LCBlbnRyeU5vZGUsIG5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICBlbnRyeU5vZGUgPSBnZXRFbnRyeU5vZGUoZW50cnlOb2RlKTtcclxuICAgICAgcmV0dXJuIHNob3coZWxlbWVudCwgZW50cnlOb2RlLCBub2RlLCBzY29wZU5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzaG93VGFibGU6IGZ1bmN0aW9uKGVsZW1lbnQsIGVudHJ5Tm9kZSwgbm9kZSwgc2NvcGVOb2RlKSB7XHJcbiAgICAgIGVudHJ5Tm9kZSA9IGdldEVudHJ5Tm9kZShlbnRyeU5vZGUpO1xyXG4gICAgICB2YXIgZWxlbXMgPSBlbGVtZW50cyhlbGVtZW50LCBlbnRyeU5vZGUpO1xyXG4gICAgICByZXR1cm4gZWxlbXMgJiYgZWxlbXMubGVuZ3RoICYmICghY2FuQmVTaG93biB8fCBzaG93KGVsZW1lbnQsIGVudHJ5Tm9kZSwgbm9kZSwgc2NvcGVOb2RlKSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkYXRlTGlzdEl0ZW06IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlLCBub2RlLCBpZHgpIHtcclxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnZhbGlkYXRlID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgcmV0dXJuIG9wdGlvbnMudmFsaWRhdGUoZWxlbWVudCwgdmFsdWUsIG5vZGUsIGlkeCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgfTtcclxuXHJcbiAgLy8gVXBkYXRlL3NldCB0aGUgc2VsZWN0aW9uIG9uIHRoZSBjb3JyZWN0IHBvc2l0aW9uLlxyXG4gIC8vIEl0J3MgdGhlIHNhbWUgY29kZSBsaWtlIGZvciBhbiBpbnB1dCB2YWx1ZSBpbiB0aGUgUHJvcGVydGllc1BhbmVsLmpzLlxyXG4gIGlmIChzZXRDb250cm9sVmFsdWUpIHtcclxuICAgIGZhY3Rvcnkuc2V0Q29udHJvbFZhbHVlID0gZnVuY3Rpb24oZWxlbWVudCwgcm93Tm9kZSwgaW5wdXQsIHByb3AsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGVudHJ5Tm9kZSA9IGdldEVudHJ5Tm9kZShyb3dOb2RlKTtcclxuXHJcbiAgICAgIHZhciBpc1JlYWRPbmx5ID0gZG9tQXR0cihpbnB1dCwgJ3JlYWRvbmx5Jyk7XHJcbiAgICAgIHZhciBvbGRWYWx1ZSA9IGlucHV0LnZhbHVlO1xyXG5cclxuICAgICAgdmFyIHNlbGVjdGlvbjtcclxuXHJcbiAgICAgIC8vIHByZXZlbnRzIGlucHV0IGZpZWxkcyBmcm9tIGhhdmluZyB0aGUgdmFsdWUgJ3VuZGVmaW5lZCdcclxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICB2YWx1ZSA9ICcnO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyB3aGVuIHRoZSBhdHRyaWJ1dGUgJ3JlYWRvbmx5JyBleGlzdHMsIGlnbm9yZSB0aGUgY29tcGFyaXNvblxyXG4gICAgICAvLyB3aXRoICdvbGRWYWx1ZScgYW5kICd2YWx1ZSdcclxuICAgICAgaWYgKCEhaXNSZWFkT25seSAmJiBvbGRWYWx1ZSA9PT0gdmFsdWUpIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBzZWxlY3Rpb24gb24gdW5kby9yZWRvXHJcbiAgICAgIGlmIChkb2N1bWVudC5hY3RpdmVFbGVtZW50ID09PSBpbnB1dCkge1xyXG4gICAgICAgIHNlbGVjdGlvbiA9IHVwZGF0ZVNlbGVjdGlvbihnZXRTZWxlY3Rpb24oaW5wdXQpLCBvbGRWYWx1ZSwgdmFsdWUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZXRDb250cm9sVmFsdWUoZWxlbWVudCwgZW50cnlOb2RlLCBpbnB1dCwgcHJvcCwgdmFsdWUsIGlkeCk7XHJcblxyXG4gICAgICBpZiAoc2VsZWN0aW9uKSB7XHJcbiAgICAgICAgc2V0U2VsZWN0aW9uKGlucHV0LCBzZWxlY3Rpb24pO1xyXG4gICAgICB9XHJcblxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJldHVybiBmYWN0b3J5O1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVzY2FwZUhUTUwgPSByZXF1aXJlKCcuLi9VdGlscycpLmVzY2FwZUhUTUw7XHJcblxyXG52YXIgZW50cnlGaWVsZERlc2NyaXB0aW9uID0gcmVxdWlyZSgnLi9FbnRyeUZpZWxkRGVzY3JpcHRpb24nKTtcclxuXHJcblxyXG52YXIgdGV4dEJveCA9IGZ1bmN0aW9uKG9wdGlvbnMsIGRlZmF1bHRQYXJhbWV0ZXJzKSB7XHJcblxyXG4gIHZhciByZXNvdXJjZSA9IGRlZmF1bHRQYXJhbWV0ZXJzLFxyXG4gICAgICBsYWJlbCA9IG9wdGlvbnMubGFiZWwgfHwgcmVzb3VyY2UuaWQsXHJcbiAgICAgIGNhbkJlU2hvd24gPSAhIW9wdGlvbnMuc2hvdyAmJiB0eXBlb2Ygb3B0aW9ucy5zaG93ID09PSAnZnVuY3Rpb24nLFxyXG4gICAgICBkZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb247XHJcblxyXG4gIHJlc291cmNlLmh0bWwgPVxyXG4gICAgJzxsYWJlbCBmb3I9XCJhY3Rpdml0aS0nICsgZXNjYXBlSFRNTChyZXNvdXJjZS5pZCkgKyAnXCIgJyArXHJcbiAgICAoY2FuQmVTaG93biA/ICdkYXRhLXNob3c9XCJpc1Nob3duXCInIDogJycpICtcclxuICAgICc+JyArIGxhYmVsICsgJzwvbGFiZWw+JyArXHJcbiAgICAnPGRpdiBjbGFzcz1cImJwcC1maWVsZC13cmFwcGVyXCIgJyArXHJcbiAgICAoY2FuQmVTaG93biA/ICdkYXRhLXNob3c9XCJpc1Nob3duXCInIDogJycpICtcclxuICAgICc+JyArXHJcbiAgICAgICc8ZGl2IGNvbnRlbnRlZGl0YWJsZT1cInRydWVcIiBpZD1cImFjdGl2aXRpLScgKyBlc2NhcGVIVE1MKHJlc291cmNlLmlkKSArICdcIiAnICtcclxuICAgICAgICAgICAgJ25hbWU9XCInICsgZXNjYXBlSFRNTChvcHRpb25zLm1vZGVsUHJvcGVydHkpICsgJ1wiIC8+JyArXHJcbiAgICAnPC9kaXY+JztcclxuXHJcbiAgLy8gYWRkIGRlc2NyaXB0aW9uIGJlbG93IHRleHQgYm94IGVudHJ5IGZpZWxkXHJcbiAgaWYgKGRlc2NyaXB0aW9uKSB7XHJcbiAgICByZXNvdXJjZS5odG1sICs9IGVudHJ5RmllbGREZXNjcmlwdGlvbihkZXNjcmlwdGlvbik7XHJcbiAgfVxyXG5cclxuICBpZiAoY2FuQmVTaG93bikge1xyXG4gICAgcmVzb3VyY2UuaXNTaG93biA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5zaG93LmFwcGx5KHJlc291cmNlLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJlc291cmNlLmNzc0NsYXNzZXMgPSBbJ2JwcC10ZXh0Ym94J107XHJcblxyXG4gIHJldHVybiByZXNvdXJjZTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gdGV4dEJveDtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVzY2FwZUhUTUwgPSByZXF1aXJlKCcuLi9VdGlscycpLmVzY2FwZUhUTUw7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnk7XHJcblxyXG52YXIgZW50cnlGaWVsZERlc2NyaXB0aW9uID0gcmVxdWlyZSgnLi9FbnRyeUZpZWxkRGVzY3JpcHRpb24nKTtcclxuXHJcblxyXG52YXIgdGV4dEZpZWxkID0gZnVuY3Rpb24ob3B0aW9ucywgZGVmYXVsdFBhcmFtZXRlcnMpIHtcclxuXHJcbiAgLy8gRGVmYXVsdCBhY3Rpb24gZm9yIHRoZSBidXR0b24gbmV4dCB0byB0aGUgaW5wdXQtZmllbGRcclxuICB2YXIgZGVmYXVsdEJ1dHRvbkFjdGlvbiA9IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSkge1xyXG4gICAgdmFyIGlucHV0ID0gZG9tUXVlcnkoJ2lucHV0W25hbWU9XCInICsgb3B0aW9ucy5tb2RlbFByb3BlcnR5ICsgJ1wiXScsIGlucHV0Tm9kZSk7XHJcbiAgICBpbnB1dC52YWx1ZSA9ICcnO1xyXG5cclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH07XHJcblxyXG4gIC8vIGRlZmF1bHQgbWV0aG9kIHRvIGRldGVybWluZSBpZiB0aGUgYnV0dG9uIHNob3VsZCBiZSB2aXNpYmxlXHJcbiAgdmFyIGRlZmF1bHRCdXR0b25TaG93ID0gZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlKSB7XHJcbiAgICB2YXIgaW5wdXQgPSBkb21RdWVyeSgnaW5wdXRbbmFtZT1cIicgKyBvcHRpb25zLm1vZGVsUHJvcGVydHkgKyAnXCJdJywgaW5wdXROb2RlKTtcclxuXHJcbiAgICByZXR1cm4gaW5wdXQudmFsdWUgIT09ICcnO1xyXG4gIH07XHJcblxyXG5cclxuICB2YXIgcmVzb3VyY2UgPSBkZWZhdWx0UGFyYW1ldGVycyxcclxuICAgICAgbGFiZWwgPSBvcHRpb25zLmxhYmVsIHx8IHJlc291cmNlLmlkLFxyXG4gICAgICBkYXRhVmFsdWVMYWJlbCA9IG9wdGlvbnMuZGF0YVZhbHVlTGFiZWwsXHJcbiAgICAgIGJ1dHRvbkxhYmVsID0gKG9wdGlvbnMuYnV0dG9uTGFiZWwgfHwgJ1gnKSxcclxuICAgICAgYWN0aW9uTmFtZSA9ICh0eXBlb2Ygb3B0aW9ucy5idXR0b25BY3Rpb24gIT0gJ3VuZGVmaW5lZCcpID8gb3B0aW9ucy5idXR0b25BY3Rpb24ubmFtZSA6ICdjbGVhcicsXHJcbiAgICAgIGFjdGlvbk1ldGhvZCA9ICh0eXBlb2Ygb3B0aW9ucy5idXR0b25BY3Rpb24gIT0gJ3VuZGVmaW5lZCcpID8gb3B0aW9ucy5idXR0b25BY3Rpb24ubWV0aG9kIDogZGVmYXVsdEJ1dHRvbkFjdGlvbixcclxuICAgICAgc2hvd05hbWUgPSAodHlwZW9mIG9wdGlvbnMuYnV0dG9uU2hvdyAhPSAndW5kZWZpbmVkJykgPyBvcHRpb25zLmJ1dHRvblNob3cubmFtZSA6ICdjYW5DbGVhcicsXHJcbiAgICAgIHNob3dNZXRob2QgPSAodHlwZW9mIG9wdGlvbnMuYnV0dG9uU2hvdyAhPSAndW5kZWZpbmVkJykgPyBvcHRpb25zLmJ1dHRvblNob3cubWV0aG9kIDogZGVmYXVsdEJ1dHRvblNob3csXHJcbiAgICAgIGNhbkJlRGlzYWJsZWQgPSAhIW9wdGlvbnMuZGlzYWJsZWQgJiYgdHlwZW9mIG9wdGlvbnMuZGlzYWJsZWQgPT09ICdmdW5jdGlvbicsXHJcbiAgICAgIGNhbkJlSGlkZGVuID0gISFvcHRpb25zLmhpZGRlbiAmJiB0eXBlb2Ygb3B0aW9ucy5oaWRkZW4gPT09ICdmdW5jdGlvbicsXHJcbiAgICAgIGRlc2NyaXB0aW9uID0gb3B0aW9ucy5kZXNjcmlwdGlvbjtcclxuXHJcbiAgcmVzb3VyY2UuaHRtbCA9XHJcbiAgICAnPGxhYmVsIGZvcj1cImFjdGl2aXRpLScgKyBlc2NhcGVIVE1MKHJlc291cmNlLmlkKSArICdcIiAnICtcclxuICAgICAgKGNhbkJlRGlzYWJsZWQgPyAnZGF0YS1kaXNhYmxlPVwiaXNEaXNhYmxlZFwiICcgOiAnJykgK1xyXG4gICAgICAoY2FuQmVIaWRkZW4gPyAnZGF0YS1zaG93PVwiaXNIaWRkZW5cIiAnIDogJycpICtcclxuICAgICAgKGRhdGFWYWx1ZUxhYmVsID8gJ2RhdGEtdmFsdWU9XCInICsgZXNjYXBlSFRNTChkYXRhVmFsdWVMYWJlbCkgKyAnXCInIDogJycpICsgJz4nKyBlc2NhcGVIVE1MKGxhYmVsKSArJzwvbGFiZWw+JyArXHJcbiAgICAnPGRpdiBjbGFzcz1cImJwcC1maWVsZC13cmFwcGVyXCIgJyArXHJcbiAgICAgIChjYW5CZURpc2FibGVkID8gJ2RhdGEtZGlzYWJsZT1cImlzRGlzYWJsZWRcIicgOiAnJykgK1xyXG4gICAgICAoY2FuQmVIaWRkZW4gPyAnZGF0YS1zaG93PVwiaXNIaWRkZW5cIicgOiAnJykgK1xyXG4gICAgICAnPicgK1xyXG4gICAgICAnPGlucHV0IGlkPVwiYWN0aXZpdGktJyArIGVzY2FwZUhUTUwocmVzb3VyY2UuaWQpICsgJ1wiIHR5cGU9XCJ0ZXh0XCIgbmFtZT1cIicgKyBlc2NhcGVIVE1MKG9wdGlvbnMubW9kZWxQcm9wZXJ0eSkgKyAnXCIgJyArXHJcbiAgICAgICAgKGNhbkJlRGlzYWJsZWQgPyAnZGF0YS1kaXNhYmxlPVwiaXNEaXNhYmxlZFwiJyA6ICcnKSArXHJcbiAgICAgICAgKGNhbkJlSGlkZGVuID8gJ2RhdGEtc2hvdz1cImlzSGlkZGVuXCInIDogJycpICtcclxuICAgICAgICAnIC8+JyArXHJcbiAgICAgICc8YnV0dG9uIGNsYXNzPVwiJyArIGVzY2FwZUhUTUwoYWN0aW9uTmFtZSkgKyAnXCIgZGF0YS1hY3Rpb249XCInICsgZXNjYXBlSFRNTChhY3Rpb25OYW1lKSArICdcIiBkYXRhLXNob3c9XCInICsgZXNjYXBlSFRNTChzaG93TmFtZSkgKyAnXCIgJyArXHJcbiAgICAgICAgKGNhbkJlRGlzYWJsZWQgPyAnZGF0YS1kaXNhYmxlPVwiaXNEaXNhYmxlZFwiJyA6ICcnKSArXHJcbiAgICAgICAgKGNhbkJlSGlkZGVuID8gJyBkYXRhLXNob3c9XCJpc0hpZGRlblwiJyA6ICcnKSArICc+JyArXHJcbiAgICAgICAgJzxzcGFuPicgKyBlc2NhcGVIVE1MKGJ1dHRvbkxhYmVsKSArICc8L3NwYW4+JyArXHJcbiAgICAgICc8L2J1dHRvbj4nICtcclxuICAgICc8L2Rpdj4nO1xyXG5cclxuICAvLyBhZGQgZGVzY3JpcHRpb24gYmVsb3cgdGV4dCBpbnB1dCBlbnRyeSBmaWVsZFxyXG4gIGlmIChkZXNjcmlwdGlvbikge1xyXG4gICAgcmVzb3VyY2UuaHRtbCArPSBlbnRyeUZpZWxkRGVzY3JpcHRpb24oZGVzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgcmVzb3VyY2VbYWN0aW9uTmFtZV0gPSBhY3Rpb25NZXRob2Q7XHJcbiAgcmVzb3VyY2Vbc2hvd05hbWVdID0gc2hvd01ldGhvZDtcclxuXHJcbiAgaWYgKGNhbkJlRGlzYWJsZWQpIHtcclxuICAgIHJlc291cmNlLmlzRGlzYWJsZWQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgcmV0dXJuIG9wdGlvbnMuZGlzYWJsZWQuYXBwbHkocmVzb3VyY2UsIGFyZ3VtZW50cyk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgaWYgKGNhbkJlSGlkZGVuKSB7XHJcbiAgICByZXNvdXJjZS5pc0hpZGRlbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICByZXR1cm4gIW9wdGlvbnMuaGlkZGVuLmFwcGx5KHJlc291cmNlLCBhcmd1bWVudHMpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJlc291cmNlLmNzc0NsYXNzZXMgPSBbJ2JwcC10ZXh0ZmllbGQnXTtcclxuXHJcbiAgcmV0dXJuIHJlc291cmNlO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB0ZXh0RmllbGQ7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciB0ZXh0RmllbGQgPSByZXF1aXJlKCcuL1RleHRJbnB1dEVudHJ5RmFjdG9yeScpO1xyXG5cclxuLyoqXHJcbiAqIFRoaXMgZnVuY3Rpb24gaXMgYSB3cmFwcGVyIGFyb3VuZCBUZXh0SW5wdXRFbnRyeUZhY3RvcnkuXHJcbiAqIEl0IGFkZHMgZnVuY3Rpb25hbGl0eSB0byBjYWNoZSBhbiBpbnZhbGlkIHZhbHVlIGVudGVyZWQgaW4gdGhlXHJcbiAqIHRleHQgaW5wdXQsIGluc3RlYWQgb2Ygc2V0dGluZyBpdCBvbiB0aGUgYnVzaW5lc3Mgb2JqZWN0LlxyXG4gKi9cclxudmFyIHZhbGlkYXRpb25Bd2FyZVRleHRGaWVsZCA9IGZ1bmN0aW9uKG9wdGlvbnMsIGRlZmF1bHRQYXJhbWV0ZXJzKSB7XHJcblxyXG4gIHZhciBtb2RlbFByb3BlcnR5ID0gb3B0aW9ucy5tb2RlbFByb3BlcnR5O1xyXG5cclxuICBkZWZhdWx0UGFyYW1ldGVycy5nZXQgPSBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICB2YXIgdmFsdWUgPSB0aGlzLl9fbGFzdEludmFsaWRWYWx1ZTtcclxuXHJcbiAgICBkZWxldGUgdGhpcy5fX2xhc3RJbnZhbGlkVmFsdWU7XHJcblxyXG4gICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcclxuXHJcbiAgICBwcm9wZXJ0aWVzW21vZGVsUHJvcGVydHldID0gdmFsdWUgIT09IHVuZGVmaW5lZCA/IHZhbHVlIDogb3B0aW9ucy5nZXRQcm9wZXJ0eShlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICByZXR1cm4gcHJvcGVydGllcztcclxuICB9O1xyXG5cclxuICBkZWZhdWx0UGFyYW1ldGVycy5zZXQgPSBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgIHZhciB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGUuYXBwbHkodGhpcywgWyBlbGVtZW50LCB2YWx1ZXMsIG5vZGUgXSksXHJcbiAgICAgICAgcHJvcGVydHlWYWx1ZSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XTtcclxuXHJcbiAgICAvLyBtYWtlIHN1cmUgd2UgZG8gbm90IHVwZGF0ZSB0aGUgaWRcclxuICAgIGlmICh2YWxpZGF0aW9uRXJyb3JzICYmIHZhbGlkYXRpb25FcnJvcnNbbW9kZWxQcm9wZXJ0eV0pIHtcclxuICAgICAgdGhpcy5fX2xhc3RJbnZhbGlkVmFsdWUgPSBwcm9wZXJ0eVZhbHVlO1xyXG5cclxuICAgICAgcmV0dXJuIG9wdGlvbnMuc2V0UHJvcGVydHkoZWxlbWVudCwge30sIG5vZGUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdmFyIHByb3BlcnRpZXMgPSB7fTtcclxuXHJcbiAgICAgIHByb3BlcnRpZXNbbW9kZWxQcm9wZXJ0eV0gPSBwcm9wZXJ0eVZhbHVlO1xyXG5cclxuICAgICAgcmV0dXJuIG9wdGlvbnMuc2V0UHJvcGVydHkoZWxlbWVudCwgcHJvcGVydGllcywgbm9kZSk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgdmFyIHZhbGlkYXRlID0gZGVmYXVsdFBhcmFtZXRlcnMudmFsaWRhdGUgPSBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgIHZhciB2YWx1ZSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XSB8fCB0aGlzLl9fbGFzdEludmFsaWRWYWx1ZTtcclxuXHJcbiAgICB2YXIgcHJvcGVydHkgPSB7fTtcclxuICAgIHByb3BlcnR5W21vZGVsUHJvcGVydHldID0gdmFsdWU7XHJcblxyXG4gICAgcmV0dXJuIG9wdGlvbnMudmFsaWRhdGUoZWxlbWVudCwgcHJvcGVydHksIG5vZGUpO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiB0ZXh0RmllbGQob3B0aW9ucywgZGVmYXVsdFBhcmFtZXRlcnMpO1xyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB2YWxpZGF0aW9uQXdhcmVUZXh0RmllbGQ7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBtYXAgPSByZXF1aXJlKCdsb2Rhc2gvbWFwJyk7XHJcblxyXG52YXIgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIgPSByZXF1aXJlKCcuL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyJyk7XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBhdHRyaWJ1dGUgJ2FjdGl2aXRpOmFzeW5jQmVmb3JlJyBpcyBzZXRcclxuICogdG8gdHJ1ZS5cclxuICpcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gYm9cclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBpc0FzeW5jQmVmb3JlKGJvKSB7XHJcbiAgcmV0dXJuICEhKGJvLmdldCgnYWN0aXZpdGk6YXN5bmNCZWZvcmUnKSB8fCBiby5nZXQoJ2FjdGl2aXRpOmFzeW5jJykpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5pc0FzeW5jQmVmb3JlID0gaXNBc3luY0JlZm9yZTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGF0dHJpYnV0ZSAnYWN0aXZpdGk6YXN5bmNBZnRlcicgaXMgc2V0XHJcbiAqIHRvIHRydWUuXHJcbiAqXHJcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnR9IGJvXHJcbiAqXHJcbiAqIEByZXR1cm4ge2Jvb2xlYW59IGEgYm9vbGVhbiB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gaXNBc3luY0FmdGVyKGJvKSB7XHJcbiAgcmV0dXJuICEhYm8uZ2V0KCdhY3Rpdml0aTphc3luY0FmdGVyJyk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmlzQXN5bmNBZnRlciA9IGlzQXN5bmNBZnRlcjtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIGF0dHJpYnV0ZSAnYWN0aXZpdGk6ZXhjbHVzaXZlJyBpcyBzZXRcclxuICogdG8gdHJ1ZS5cclxuICpcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gYm9cclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBpc0V4Y2x1c2l2ZShibykge1xyXG4gIHJldHVybiAhIWJvLmdldCgnYWN0aXZpdGk6ZXhjbHVzaXZlJyk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmlzRXhjbHVzaXZlID0gaXNFeGNsdXNpdmU7XHJcblxyXG4vKipcclxuICogR2V0IGZpcnN0ICdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZScgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0LlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50fSBib1xyXG4gKlxyXG4gKiBAcmV0dXJuIHtBcnJheTxNb2RkbGVFbGVtZW50Pn0gYSBsaXN0IG9mICdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZSdcclxuICovXHJcbmZ1bmN0aW9uIGdldEZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGJvKSB7XHJcbiAgcmV0dXJuIChleHRlbnNpb25FbGVtZW50c0hlbHBlci5nZXRFeHRlbnNpb25FbGVtZW50cyhibywgJ2FjdGl2aXRpOkZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlJykgfHwgW10pWzBdO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5nZXRGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZSA9IGdldEZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlO1xyXG5cclxuLyoqXHJcbiAqIFJlbW92ZXMgYWxsIGV4aXN0aW5nICdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZScgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0XHJcbiAqXHJcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnR9IGJvXHJcbiAqXHJcbiAqIEByZXR1cm4ge0FycmF5PE1vZGRsZUVsZW1lbnQ+fSBhIGxpc3Qgb2YgJ2FjdGl2aXRpOkZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlJ1xyXG4gKi9cclxuZnVuY3Rpb24gcmVtb3ZlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUoYm8sIGVsZW1lbnQpIHtcclxuICB2YXIgcmV0cnlUaW1lQ3ljbGVzID0gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZScpO1xyXG4gIHJldHVybiBtYXAocmV0cnlUaW1lQ3ljbGVzLCBmdW5jdGlvbihjeWNsZSkge1xyXG4gICAgcmV0dXJuIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLnJlbW92ZUVudHJ5KGJvLCBlbGVtZW50LCBjeWNsZSk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLnJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlID0gcmVtb3ZlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGU7IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGNvbGxlY3Rpb25BZGQgPSByZXF1aXJlKCdkaWFncmFtLWpzL2xpYi91dGlsL0NvbGxlY3Rpb25zJykuYWRkLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIENhdGVnb3J5SGVscGVyID0ge307XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IENhdGVnb3J5SGVscGVyO1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgYnBtbjpDYXRlZ29yeVZhbHVlIGluc2lkZSBhIG5ldyBicG1uOkNhdGVnb3J5XHJcbiAqXHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gZGVmaW5pdGlvbnNcclxuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gY2F0ZWdvcnlWYWx1ZS5cclxuICovXHJcbkNhdGVnb3J5SGVscGVyLmNyZWF0ZUNhdGVnb3J5VmFsdWUgPSBmdW5jdGlvbihkZWZpbml0aW9ucywgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgY2F0ZWdvcnlWYWx1ZSA9IGJwbW5GYWN0b3J5LmNyZWF0ZSgnYnBtbjpDYXRlZ29yeVZhbHVlJyksXHJcbiAgICAgIGNhdGVnb3J5ID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkNhdGVnb3J5Jywge1xyXG4gICAgICAgIGNhdGVnb3J5VmFsdWU6IFsgY2F0ZWdvcnlWYWx1ZSBdXHJcbiAgICAgIH0pO1xyXG5cclxuICAvLyBhZGQgdG8gY29ycmVjdCBwbGFjZVxyXG4gIGNvbGxlY3Rpb25BZGQoZGVmaW5pdGlvbnMuZ2V0KCdyb290RWxlbWVudHMnKSwgY2F0ZWdvcnkpO1xyXG4gIGdldEJ1c2luZXNzT2JqZWN0KGNhdGVnb3J5KS4kcGFyZW50ID0gZGVmaW5pdGlvbnM7XHJcbiAgZ2V0QnVzaW5lc3NPYmplY3QoY2F0ZWdvcnlWYWx1ZSkuJHBhcmVudCA9IGNhdGVnb3J5O1xyXG5cclxuICByZXR1cm4gY2F0ZWdvcnlWYWx1ZTtcclxuXHJcbn07IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIENtZEhlbHBlciA9IHt9O1xyXG5tb2R1bGUuZXhwb3J0cyA9IENtZEhlbHBlcjtcclxuXHJcbkNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzID0gZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiB7XHJcbiAgICBjbWQ6ICdlbGVtZW50LnVwZGF0ZVByb3BlcnRpZXMnLFxyXG4gICAgY29udGV4dDogeyBlbGVtZW50OiBlbGVtZW50LCBwcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzIH1cclxuICB9O1xyXG59O1xyXG5cclxuQ21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0ID0gZnVuY3Rpb24oZWxlbWVudCwgYnVzaW5lc3NPYmplY3QsIG5ld1Byb3BlcnRpZXMpIHtcclxuICByZXR1cm4ge1xyXG4gICAgY21kOiAncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QnLFxyXG4gICAgY29udGV4dDoge1xyXG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICBidXNpbmVzc09iamVjdDogYnVzaW5lc3NPYmplY3QsXHJcbiAgICAgIHByb3BlcnRpZXM6IG5ld1Byb3BlcnRpZXNcclxuICAgIH1cclxuICB9O1xyXG59O1xyXG5cclxuQ21kSGVscGVyLmFkZEVsZW1lbnRzVG9saXN0ID0gZnVuY3Rpb24oZWxlbWVudCwgYnVzaW5lc3NPYmplY3QsIGxpc3RQcm9wZXJ0eU5hbWUsIG9iamVjdHNUb0FkZCkge1xyXG4gIHJldHVybiB7XHJcbiAgICBjbWQ6ICdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0JyxcclxuICAgIGNvbnRleHQ6IHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgY3VycmVudE9iamVjdDogYnVzaW5lc3NPYmplY3QsXHJcbiAgICAgIHByb3BlcnR5TmFtZTogbGlzdFByb3BlcnR5TmFtZSxcclxuICAgICAgb2JqZWN0c1RvQWRkOiBvYmplY3RzVG9BZGRcclxuICAgIH1cclxuICB9O1xyXG59O1xyXG5cclxuQ21kSGVscGVyLnJlbW92ZUVsZW1lbnRzRnJvbUxpc3QgPSBmdW5jdGlvbihlbGVtZW50LCBidXNpbmVzc09iamVjdCwgbGlzdFByb3BlcnR5TmFtZSwgcmVmZXJlbmNlUHJvcGVydHlOYW1lLCBvYmplY3RzVG9SZW1vdmUpIHtcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGNtZDogJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0LWxpc3QnLFxyXG4gICAgY29udGV4dDoge1xyXG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICBjdXJyZW50T2JqZWN0OiBidXNpbmVzc09iamVjdCxcclxuICAgICAgcHJvcGVydHlOYW1lOiBsaXN0UHJvcGVydHlOYW1lLFxyXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eU5hbWU6IHJlZmVyZW5jZVByb3BlcnR5TmFtZSxcclxuICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvYmplY3RzVG9SZW1vdmVcclxuICAgIH1cclxuICB9O1xyXG59O1xyXG5cclxuXHJcbkNtZEhlbHBlci5hZGRBbmRSZW1vdmVFbGVtZW50c0Zyb21MaXN0ID0gZnVuY3Rpb24oZWxlbWVudCwgYnVzaW5lc3NPYmplY3QsIGxpc3RQcm9wZXJ0eU5hbWUsIHJlZmVyZW5jZVByb3BlcnR5TmFtZSwgb2JqZWN0c1RvQWRkLCBvYmplY3RzVG9SZW1vdmUpIHtcclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGNtZDogJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0LWxpc3QnLFxyXG4gICAgY29udGV4dDoge1xyXG4gICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICBjdXJyZW50T2JqZWN0OiBidXNpbmVzc09iamVjdCxcclxuICAgICAgcHJvcGVydHlOYW1lOiBsaXN0UHJvcGVydHlOYW1lLFxyXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eU5hbWU6IHJlZmVyZW5jZVByb3BlcnR5TmFtZSxcclxuICAgICAgb2JqZWN0c1RvQWRkOiBvYmplY3RzVG9BZGQsXHJcbiAgICAgIG9iamVjdHNUb1JlbW92ZTogb2JqZWN0c1RvUmVtb3ZlXHJcbiAgICB9XHJcbiAgfTtcclxufTtcclxuXHJcblxyXG5DbWRIZWxwZXIuc2V0TGlzdCA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJ1c2luZXNzT2JqZWN0LCBsaXN0UHJvcGVydHlOYW1lLCB1cGRhdGVkT2JqZWN0TGlzdCkge1xyXG4gIHJldHVybiB7XHJcbiAgICBjbWQ6ICdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0JyxcclxuICAgIGNvbnRleHQ6IHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgY3VycmVudE9iamVjdDogYnVzaW5lc3NPYmplY3QsXHJcbiAgICAgIHByb3BlcnR5TmFtZTogbGlzdFByb3BlcnR5TmFtZSxcclxuICAgICAgdXBkYXRlZE9iamVjdExpc3Q6IHVwZGF0ZWRPYmplY3RMaXN0XHJcbiAgICB9XHJcbiAgfTtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIEVsZW1lbnRIZWxwZXIgPSB7fTtcclxubW9kdWxlLmV4cG9ydHMgPSBFbGVtZW50SGVscGVyO1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZXMgYSBuZXcgZWxlbWVudCBhbmQgc2V0IHRoZSBwYXJlbnQgdG8gaXRcclxuICpcclxuICogQG1ldGhvZCBFbGVtZW50SGVscGVyI2NyZWF0ZUVsZW1lbnRcclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGVsZW1lbnRUeXBlIG9mIHRoZSBuZXcgZWxlbWVudFxyXG4gKiBAcGFyYW0ge09iamVjdH0gcHJvcGVydGllcyBvZiB0aGUgbmV3IGVsZW1lbnQgaW4ga2V5LXZhbHVlIHBhaXJzXHJcbiAqIEBwYXJhbSB7bW9kZGxlLm9iamVjdH0gcGFyZW50IG9mIHRoZSBuZXcgZWxlbWVudFxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBmYWN0b3J5IHdoaWNoIGNyZWF0ZXMgdGhlIG5ldyBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm5zIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudCB3aGljaCBpcyBjcmVhdGVkXHJcbiAqL1xyXG5FbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50VHlwZSwgcHJvcGVydGllcywgcGFyZW50LCBmYWN0b3J5KSB7XHJcbiAgdmFyIGVsZW1lbnQgPSBmYWN0b3J5LmNyZWF0ZShlbGVtZW50VHlwZSwgcHJvcGVydGllcyk7XHJcbiAgZWxlbWVudC4kcGFyZW50ID0gcGFyZW50O1xyXG5cclxuICByZXR1cm4gZWxlbWVudDtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xyXG5cclxudmFyIEV2ZW50RGVmaW5pdGlvbkhlbHBlciA9IHt9O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBFdmVudERlZmluaXRpb25IZWxwZXI7XHJcblxyXG5FdmVudERlZmluaXRpb25IZWxwZXIuZ2V0RXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCwgZXZlbnRUeXBlKSB7XHJcblxyXG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxyXG4gICAgICBldmVudERlZmluaXRpb24gPSBudWxsO1xyXG5cclxuICBpZiAoYm8uZXZlbnREZWZpbml0aW9ucykge1xyXG4gICAgZm9yRWFjaChiby5ldmVudERlZmluaXRpb25zLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgICBpZiAoaXMoZXZlbnQsIGV2ZW50VHlwZSkpIHtcclxuICAgICAgICBldmVudERlZmluaXRpb24gPSBldmVudDtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZXZlbnREZWZpbml0aW9uO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldFRpbWVyRXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLmdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpUaW1lckV2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldE1lc3NhZ2VFdmVudERlZmluaXRpb24gPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0RXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOk1lc3NhZ2VFdmVudERlZmluaXRpb24nKTtcclxufTtcclxuXHJcbkV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRTaWduYWxFdmVudERlZmluaXRpb24gPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0RXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOlNpZ25hbEV2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldEVycm9yRXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLmdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpFcnJvckV2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldEVzY2FsYXRpb25FdmVudERlZmluaXRpb24gPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0RXZlbnREZWZpbml0aW9uKGVsZW1lbnQsICdicG1uOkVzY2FsYXRpb25FdmVudERlZmluaXRpb24nKTtcclxufTtcclxuXHJcbkV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLmdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uJyk7XHJcbn07XHJcblxyXG5FdmVudERlZmluaXRpb25IZWxwZXIuZ2V0TGlua0V2ZW50RGVmaW5pdGlvbiA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gdGhpcy5nZXRFdmVudERlZmluaXRpb24oZWxlbWVudCwgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG5cclxuRXZlbnREZWZpbml0aW9uSGVscGVyLmdldENvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiB0aGlzLmdldEV2ZW50RGVmaW5pdGlvbihlbGVtZW50LCAnYnBtbjpDb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbicpO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgY21kSGVscGVyID0gcmVxdWlyZSgnLi9DbWRIZWxwZXInKSxcclxuICAgIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuL0VsZW1lbnRIZWxwZXInKTtcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIgPSB7fTtcclxuXHJcbnZhciBnZXRFeHRlbnNpb25FbGVtZW50cyA9IGZ1bmN0aW9uKGJvKSB7XHJcbiAgcmV0dXJuIGJvLmdldCgnZXh0ZW5zaW9uRWxlbWVudHMnKTtcclxufTtcclxuXHJcbkV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLmdldEV4dGVuc2lvbkVsZW1lbnRzID0gZnVuY3Rpb24oYm8sIHR5cGUpIHtcclxuICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBnZXRFeHRlbnNpb25FbGVtZW50cyhibyk7XHJcbiAgaWYgKHR5cGVvZiBleHRlbnNpb25FbGVtZW50cyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHZhciBleHRlbnNpb25WYWx1ZXMgPSBleHRlbnNpb25FbGVtZW50cy5nZXQoJ3ZhbHVlcycpO1xyXG4gICAgaWYgKHR5cGVvZiBleHRlbnNpb25WYWx1ZXMgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHZhciBlbGVtZW50cyA9IGV4dGVuc2lvblZhbHVlcy5maWx0ZXIoZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgICByZXR1cm4gaXModmFsdWUsIHR5cGUpO1xyXG4gICAgICB9KTtcclxuICAgICAgaWYgKGVsZW1lbnRzLmxlbmd0aCkge1xyXG4gICAgICAgIHJldHVybiBlbGVtZW50cztcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufTtcclxuXHJcbkV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLmFkZEVudHJ5ID0gZnVuY3Rpb24oYm8sIGVsZW1lbnQsIGVudHJ5LCBicG1uRmFjdG9yeSkge1xyXG4gIHZhciBleHRlbnNpb25FbGVtZW50cyA9IGJvLmdldCgnZXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuXHJcbiAgLy8gaWYgdGhlcmUgaXMgbm8gZXh0ZW5zaW9uRWxlbWVudHMgbGlzdCwgY3JlYXRlIG9uZVxyXG4gIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgIC8vIFRPRE86IEFzayBEYW5pZWwgd2hpY2ggb3BlcmF0aW9uIGNvc3RzIG1vcmVcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJywgeyB2YWx1ZXM6IFtlbnRyeV0gfSwgYm8sIGJwbW5GYWN0b3J5KTtcclxuICAgIHJldHVybiB7IGV4dGVuc2lvbkVsZW1lbnRzIDogZXh0ZW5zaW9uRWxlbWVudHMgfTtcclxuICB9IGVsc2Uge1xyXG4gICAgLy8gYWRkIG5ldyBmYWlsZWRKb2JSZXRyeUV4dGVuc2lvbkVsZW1lbnQgdG8gZXhpc3RpbmcgZXh0ZW5zaW9uRWxlbWVudHMgbGlzdFxyXG4gICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgJ3ZhbHVlcycsIFtlbnRyeV0pO1xyXG4gIH1cclxufTtcclxuXHJcbkV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLnJlbW92ZUVudHJ5ID0gZnVuY3Rpb24oYm8sIGVsZW1lbnQsIGVudHJ5KSB7XHJcbiAgdmFyIGV4dGVuc2lvbkVsZW1lbnRzID0gYm8uZ2V0KCdleHRlbnNpb25FbGVtZW50cycpO1xyXG5cclxuICBpZiAoIWV4dGVuc2lvbkVsZW1lbnRzKSB7XHJcblxyXG4gICAgLy8gcmV0dXJuIGFuIGVtcHR5IGNvbW1hbmQgd2hlbiB0aGVyZSBpcyBubyBleHRlbnNpb25FbGVtZW50cyBsaXN0XHJcbiAgICByZXR1cm4ge307XHJcbiAgfVxyXG5cclxuICByZXR1cm4gY21kSGVscGVyLnJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsICd2YWx1ZXMnLCAnZXh0ZW5zaW9uRWxlbWVudHMnLCBbZW50cnldKTtcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXI7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBnZXRFeHRlbnNpb25FbGVtZW50cyA9IHJlcXVpcmUoJy4vRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXInKS5nZXRFeHRlbnNpb25FbGVtZW50cztcclxuXHJcbnZhciBGb3JtSGVscGVyID0ge307XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEZvcm1IZWxwZXI7XHJcblxyXG4vKipcclxuICogUmV0dXJuIGZvcm0gZGF0YSBmcm9tIGJ1c2luZXNzIG9iamVjdCBvciB1bmRlZmluZWQgaWYgbm9uZSBleGlzdFxyXG4gKlxyXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fHVuZGVmaW5lZH0gZm9ybURhdGFcclxuICpcclxuICog5q2k5pa55rOV5bqf5byDXHJcbiAqXHJcbiAqL1xyXG5Gb3JtSGVscGVyLmdldEZvcm1EYXRhID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gLyogdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBmb3JtRmllbGRzID0gZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpGb3JtUHJvcGVydHknKTtcclxuXHJcbiAgdmFyIGZvcm1EYXRhID0ge31cclxuXHJcbiAgaWYgKHR5cGVvZiBmb3JtRGF0YSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJldHVybiBmb3JtRGF0YVswXTtcclxuICB9Ki9cclxuIHJldHVybiB7fTtcclxufTtcclxuXHJcblxyXG4vKipcclxuICogUmV0dXJuIGFsbCBmb3JtIGZpZWxkcyBleGlzdGluZyBpbiB0aGUgYnVzaW5lc3Mgb2JqZWN0LCBhbmRcclxuICogYW4gZW1wdHkgYXJyYXkgaWYgbm9uZSBleGlzdC5cclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7QXJyYXl9IGEgbGlzdCBvZiBmb3JtIGZpZWxkIG9iamVjdHNcclxuICovXHJcbkZvcm1IZWxwZXIuZ2V0Rm9ybUZpZWxkcyA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuXHJcbiAgLyoq55u05o6l6I635Y+WIEV4dGVuc2lvbkVsZW1lbnRz55qEIGFjdGl2aXRpOkZvcm1Qcm9wZXJ0eeWFg+e0oCovXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBmb3JtRmllbGRzID0gZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpGb3JtUHJvcGVydHknKTtcclxuXHJcbiAgcmV0dXJuIGZvcm1GaWVsZHMgfHwgW107XHJcbn07XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBhIGZvcm0gZmllbGQgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0IGF0IGdpdmVuIGluZGV4XHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtIHtudW1iZXJ9IGlkeFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fSB0aGUgZm9ybSBmaWVsZFxyXG4gKi9cclxuRm9ybUhlbHBlci5nZXRGb3JtRmllbGQgPSBmdW5jdGlvbihlbGVtZW50LCBpZHgpIHtcclxuXHJcbiAgdmFyIGZvcm1GaWVsZHMgPSB0aGlzLmdldEZvcm1GaWVsZHMoZWxlbWVudCk7XHJcblxyXG4gIHJldHVybiBmb3JtRmllbGRzW2lkeF07XHJcbn07XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBhbGwgY29uc3RyYWludHMgZm9yIGEgc3BlY2lmaWMgZm9ybSBmaWVsZCBmcm9tIHRoZSBidXNpbmVzcyBvYmplY3RcclxuICpcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gZm9ybUZpZWxkXHJcbiAqXHJcbiAqIEByZXR1cm4ge0FycmF5PE1vZGRsZUVsZW1lbnQ+fSBhIGxpc3Qgb2YgY29uc3RyYWludCBvYmplY3RzXHJcbiAqL1xyXG5Gb3JtSGVscGVyLmdldENvbnN0cmFpbnRzID0gZnVuY3Rpb24oZm9ybUZpZWxkKSB7XHJcbiAgaWYgKGZvcm1GaWVsZCAmJiBmb3JtRmllbGQudmFsaWRhdGlvbiAmJiBmb3JtRmllbGQudmFsaWRhdGlvbi5jb25zdHJhaW50cykge1xyXG4gICAgcmV0dXJuIGZvcm1GaWVsZC52YWxpZGF0aW9uLmNvbnN0cmFpbnRzO1xyXG4gIH1cclxuICByZXR1cm4gW107XHJcbn07XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCBhbGwgYWN0aXZpdGk6dmFsdWUgb2JqZWN0cyBmb3IgYSBzcGVjaWZpYyBmb3JtIGZpZWxkIGZyb20gdGhlIGJ1c2luZXNzIG9iamVjdFxyXG4gKlxyXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50fSBmb3JtRmllbGRcclxuICpcclxuICogQHJldHVybiB7QXJyYXk8TW9kZGxlRWxlbWVudD59IGEgbGlzdCBvZiBhY3Rpdml0aTp2YWx1ZSBvYmplY3RzXHJcbiAqL1xyXG5Gb3JtSGVscGVyLmdldEVudW1WYWx1ZXMgPSBmdW5jdGlvbihmb3JtRmllbGQpIHtcclxuICBpZiAoZm9ybUZpZWxkICYmIGZvcm1GaWVsZC52YWx1ZXMpIHtcclxuICAgIHJldHVybiBmb3JtRmllbGQudmFsdWVzO1xyXG4gIH1cclxuICByZXR1cm4gW107XHJcbn07XHJcblxyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgTW9kZWxVdGlsID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKSxcclxuICAgIGlzID0gTW9kZWxVdGlsLmlzLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBNb2RlbFV0aWwuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgZXZlbnREZWZpbml0aW9uSGVscGVyID0gcmVxdWlyZSgnLi9FdmVudERlZmluaXRpb25IZWxwZXInKTtcclxudmFyIGV4dGVuc2lvbnNFbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpO1xyXG5cclxudmFyIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlciA9IHt9O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXI7XHJcblxyXG4vKipcclxuICogUmV0dXJucyAndHJ1ZScgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgJ2FjdGl2aXRpOlNlcnZpY2VUYXNrTGlrZSdcclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtib29sZWFufSBhIGJvb2xlYW4gdmFsdWVcclxuICovXHJcbkltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5pc1NlcnZpY2VUYXNrTGlrZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2FjdGl2aXRpOlNlcnZpY2VUYXNrTGlrZScpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgJ3RydWUnIGlmIHRoZSBnaXZlbiBlbGVtZW50IGlzICdhY3Rpdml0aTpEbW5DYXBhYmxlJ1xyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge2Jvb2xlYW59IGEgYm9vbGVhbiB2YWx1ZVxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzRG1uQ2FwYWJsZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2FjdGl2aXRpOkRtbkNhcGFibGUnKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zICd0cnVlJyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBpcyAnYWN0aXZpdGk6RXh0ZXJuYWxDYXBhYmxlJ1xyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge2Jvb2xlYW59IGEgYm9vbGVhbiB2YWx1ZVxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzRXh0ZXJuYWxDYXBhYmxlID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiBpcyhlbGVtZW50LCAnYWN0aXZpdGk6RXh0ZXJuYWxDYXBhYmxlJyk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyAndHJ1ZScgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgJ2FjdGl2aXRpOlRhc2tMaXN0ZW5lcidcclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtib29sZWFufSBhIGJvb2xlYW4gdmFsdWVcclxuICovXHJcbkltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5pc1Rhc2tMaXN0ZW5lciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2FjdGl2aXRpOlRhc2tMaXN0ZW5lcicpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgJ3RydWUnIGlmIHRoZSBnaXZlbiBlbGVtZW50IGlzICdhY3Rpdml0aTpFeGVjdXRpb25MaXN0ZW5lcidcclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtib29sZWFufSBhIGJvb2xlYW4gdmFsdWVcclxuICovXHJcbkltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5pc0V4ZWN1dGlvbkxpc3RlbmVyID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiBpcyhlbGVtZW50LCAnYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXInKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zICd0cnVlJyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBpcyAnYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXInIG9yXHJcbiAqICdhY3Rpdml0aTpUYXNrTGlzdGVuZXInXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuaXNMaXN0ZW5lciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gdGhpcy5pc1Rhc2tMaXN0ZW5lcihlbGVtZW50KSB8fCB0aGlzLmlzRXhlY3V0aW9uTGlzdGVuZXIoZWxlbWVudCk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyAndHJ1ZScgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgJ2JwbW46U2VxdWVuY2VGbG93J1xyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge2Jvb2xlYW59IGEgYm9vbGVhbiB2YWx1ZVxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzU2VxdWVuY2VGbG93ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHJldHVybiBpcyhlbGVtZW50LCAnYnBtbjpTZXF1ZW5jZUZsb3cnKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSAnYWN0aXZpdGk6U2VydmljZVRhc2tMaWtlJyBidXNpbmVzcyBvYmplY3QuXHJcbiAqXHJcbiAqIElmIHRoZSBnaXZlbiBlbGVtZW50IGlzIG5vdCBhICdhY3Rpdml0aTpTZXJ2aWNlVGFza0xpa2UnLCB0aGVuICdmYWxzZSdcclxuICogaXMgcmV0dXJuZWQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gdGhlICdhY3Rpdml0aTpTZXJ2aWNlVGFza0xpa2UnIGJ1c2luZXNzIG9iamVjdFxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldFNlcnZpY2VUYXNrTGlrZUJ1c2luZXNzT2JqZWN0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcpIHx8IGlzKGVsZW1lbnQsICdicG1uOkVuZEV2ZW50JykpIHtcclxuXHJcbiAgICAvLyBjaGFuZ2UgYnVzaW5lc3Mgb2JqZWN0IHRvICdtZXNzYWdlRXZlbnREZWZpbml0aW9uJyB3aGVuXHJcbiAgICAvLyB0aGUgZWxlbWVudCBpcyBhIG1lc3NhZ2UgaW50ZXJtZWRpYXRlIHRocm93IGV2ZW50IG9yIG1lc3NhZ2UgZW5kIGV2ZW50XHJcbiAgICAvLyBiZWNhdXNlIHRoZSBhY3Rpdml0aSBleHRlbnNpb25zIChlLmcuIGFjdGl2aXRpOmNsYXNzKSBhcmUgaW4gdGhlIG1lc3NhZ2VcclxuICAgIC8vIGV2ZW50IGRlZmluaXRpb24gdGFnIGFuZCBub3QgaW4gdGhlIGludGVybWVkaWF0ZSB0aHJvdyBldmVudCBvciBlbmQgZXZlbnQgdGFnXHJcbiAgICB2YXIgbWVzc2FnZUV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRNZXNzYWdlRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG4gICAgaWYgKG1lc3NhZ2VFdmVudERlZmluaXRpb24pIHtcclxuICAgICAgZWxlbWVudCA9IG1lc3NhZ2VFdmVudERlZmluaXRpb247XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gdGhpcy5pc1NlcnZpY2VUYXNrTGlrZShlbGVtZW50KSAmJiBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyB0aGUgaW1wbGVtZW50YXRpb24gdHlwZSBvZiB0aGUgZ2l2ZW4gZWxlbWVudC5cclxuICpcclxuICogUG9zc2libGUgaW1wbGVtZW50YXRpb24gdHlwZXMgYXJlOlxyXG4gKiAtIGRtblxyXG4gKiAtIGNvbm5lY3RvclxyXG4gKiAtIGV4dGVybmFsXHJcbiAqIC0gY2xhc3NcclxuICogLSBleHByZXNzaW9uXHJcbiAqIC0gZGVsZWdhdGVFeHByZXNzaW9uXHJcbiAqIC0gc2NyaXB0XHJcbiAqIC0gb3IgdW5kZWZpbmVkLCB3aGVuIG5vIG1hdGNoaW5nIGltcGxlbWVudGF0aW9uIHR5cGUgaXMgZm91bmRcclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7U3RyaW5nfSB0aGUgaW1wbGVtZW50YXRpb24gdHlwZVxyXG4gKi9cclxuSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldEltcGxlbWVudGF0aW9uVHlwZSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuXHJcbiAgdmFyIGJvID0gdGhpcy5nZXRTZXJ2aWNlVGFza0xpa2VCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgaWYgKCFibykge1xyXG4gICAgaWYgKHRoaXMuaXNMaXN0ZW5lcihlbGVtZW50KSkge1xyXG4gICAgICBibyA9IGVsZW1lbnQ7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZiAodGhpcy5pc0RtbkNhcGFibGUoYm8pKSB7XHJcbiAgICB2YXIgZGVjaXNpb25SZWYgPSBiby5nZXQoJ2FjdGl2aXRpOmRlY2lzaW9uUmVmJyk7XHJcbiAgICBpZiAodHlwZW9mIGRlY2lzaW9uUmVmICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICByZXR1cm4gJ2Rtbic7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZiAodGhpcy5pc1NlcnZpY2VUYXNrTGlrZShibykpIHtcclxuICAgIHZhciBjb25uZWN0b3JzID0gZXh0ZW5zaW9uc0VsZW1lbnRIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpDb25uZWN0b3InKTtcclxuICAgIGlmICh0eXBlb2YgY29ubmVjdG9ycyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgcmV0dXJuICdjb25uZWN0b3InO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKHRoaXMuaXNFeHRlcm5hbENhcGFibGUoYm8pKSB7XHJcbiAgICB2YXIgdHlwZSA9IGJvLmdldCgnYWN0aXZpdGk6dHlwZScpO1xyXG4gICAgaWYgKHR5cGUgPT09ICdleHRlcm5hbCcpIHtcclxuICAgICAgcmV0dXJuICdleHRlcm5hbCc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB2YXIgY2xzID0gYm8uZ2V0KCdhY3Rpdml0aTpjbGFzcycpO1xyXG4gIGlmICh0eXBlb2YgY2xzICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmV0dXJuICdjbGFzcyc7XHJcbiAgfVxyXG5cclxuICB2YXIgZXhwcmVzc2lvbiA9IGJvLmdldCgnYWN0aXZpdGk6ZXhwcmVzc2lvbicpO1xyXG4gIGlmICh0eXBlb2YgZXhwcmVzc2lvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJldHVybiAnZXhwcmVzc2lvbic7XHJcbiAgfVxyXG5cclxuICB2YXIgZGVsZWdhdGVFeHByZXNzaW9uID0gYm8uZ2V0KCdhY3Rpdml0aTpkZWxlZ2F0ZUV4cHJlc3Npb24nKTtcclxuICBpZiAodHlwZW9mIGRlbGVnYXRlRXhwcmVzc2lvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJldHVybiAnZGVsZWdhdGVFeHByZXNzaW9uJztcclxuICB9XHJcblxyXG4gIGlmICh0aGlzLmlzTGlzdGVuZXIoYm8pKSB7XHJcbiAgICB2YXIgc2NyaXB0ID0gYm8uZ2V0KCdzY3JpcHQnKTtcclxuICAgIGlmICh0eXBlb2Ygc2NyaXB0ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICByZXR1cm4gJ3NjcmlwdCc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIE1vZGVsVXRpbCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJyksXHJcbiAgICBpcyA9IE1vZGVsVXRpbC5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gTW9kZWxVdGlsLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyID0gcmVxdWlyZSgnLi9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpLFxyXG4gICAgaW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi9JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXInKTtcclxuXHJcbnZhciBJbnB1dE91dHB1dEhlbHBlciA9IHt9O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBJbnB1dE91dHB1dEhlbHBlcjtcclxuXHJcbmZ1bmN0aW9uIGdldEVsZW1lbnRzKGJvLCB0eXBlLCBwcm9wKSB7XHJcbiAgdmFyIGVsZW1zID0gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sIHR5cGUpIHx8IFtdO1xyXG4gIHJldHVybiAhcHJvcCA/IGVsZW1zIDogKGVsZW1zWzBdIHx8IHt9KVtwcm9wXSB8fCBbXTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0UGFyYW1ldGVycyhlbGVtZW50LCBwcm9wLCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICB2YXIgaW5wdXRPdXRwdXQgPSBJbnB1dE91dHB1dEhlbHBlci5nZXRJbnB1dE91dHB1dChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG4gIHJldHVybiAoaW5wdXRPdXRwdXQgJiYgaW5wdXRPdXRwdXQuZ2V0KHByb3ApKSB8fCBbXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBhIGlucHV0T3V0cHV0IGZyb20gdGhlIGJ1c2luZXNzIG9iamVjdFxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGluc2lkZUNvbm5lY3RvclxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fSB0aGUgaW5wdXRPdXRwdXQgb2JqZWN0XHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5nZXRJbnB1dE91dHB1dCA9IGZ1bmN0aW9uKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcikge1xyXG4gIGlmICghaW5zaWRlQ29ubmVjdG9yKSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgIHJldHVybiAoZ2V0RWxlbWVudHMoYm8sICdhY3Rpdml0aTpJbnB1dE91dHB1dCcpIHx8IFtdKVswXTtcclxuICB9XHJcbiAgdmFyIGNvbm5lY3RvciA9IHRoaXMuZ2V0Q29ubmVjdG9yKGVsZW1lbnQpO1xyXG4gIHJldHVybiBjb25uZWN0b3IgJiYgY29ubmVjdG9yLmdldCgnaW5wdXRPdXRwdXQnKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBjb25uZWN0b3IgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0XHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gdGhlIGNvbm5lY3RvciBvYmplY3RcclxuICovXHJcbklucHV0T3V0cHV0SGVscGVyLmdldENvbm5lY3RvciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICB2YXIgYm8gPSBpbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0U2VydmljZVRhc2tMaWtlQnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgcmV0dXJuIGJvICYmIChnZXRFbGVtZW50cyhibywgJ2FjdGl2aXRpOkNvbm5lY3RvcicpIHx8IFtdKVswXTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm4gYWxsIGlucHV0IHBhcmFtZXRlcnMgZXhpc3RpbmcgaW4gdGhlIGJ1c2luZXNzIG9iamVjdCwgYW5kXHJcbiAqIGFuIGVtcHR5IGFycmF5IGlmIG5vbmUgZXhpc3QuXHJcbiAqXHJcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGluc2lkZUNvbm5lY3RvclxyXG4gKlxyXG4gKiBAcmV0dXJuIHtBcnJheX0gYSBsaXN0IG9mIGlucHV0IHBhcmFtZXRlciBvYmplY3RzXHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5nZXRJbnB1dFBhcmFtZXRlcnMgPSBmdW5jdGlvbihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICByZXR1cm4gZ2V0UGFyYW1ldGVycy5hcHBseSh0aGlzLCBbIGVsZW1lbnQsICdpbnB1dFBhcmFtZXRlcnMnLCBpbnNpZGVDb25uZWN0b3IgXSk7XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJuIGFsbCBvdXRwdXQgcGFyYW1ldGVycyBleGlzdGluZyBpbiB0aGUgYnVzaW5lc3Mgb2JqZWN0LCBhbmRcclxuICogYW4gZW1wdHkgYXJyYXkgaWYgbm9uZSBleGlzdC5cclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtICB7Ym9vbGVhbn0gaW5zaWRlQ29ubmVjdG9yXHJcbiAqXHJcbiAqIEByZXR1cm4ge0FycmF5fSBhIGxpc3Qgb2Ygb3V0cHV0IHBhcmFtZXRlciBvYmplY3RzXHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5nZXRPdXRwdXRQYXJhbWV0ZXJzID0gZnVuY3Rpb24oZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSB7XHJcbiAgcmV0dXJuIGdldFBhcmFtZXRlcnMuYXBwbHkodGhpcywgWyBlbGVtZW50LCAnb3V0cHV0UGFyYW1ldGVycycsIGluc2lkZUNvbm5lY3RvciBdKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBpbnB1dCBwYXJhbWV0ZXIgZnJvbSB0aGUgYnVzaW5lc3Mgb2JqZWN0IGF0IGdpdmVuIGluZGV4XHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtICB7Ym9vbGVhbn0gaW5zaWRlQ29ubmVjdG9yXHJcbiAqIEBwYXJhbSB7bnVtYmVyfSBpZHhcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gaW5wdXQgcGFyYW1ldGVyXHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5nZXRJbnB1dFBhcmFtZXRlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0SW5wdXRQYXJhbWV0ZXJzKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvcilbaWR4XTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBvdXRwdXQgcGFyYW1ldGVyIGZyb20gdGhlIGJ1c2luZXNzIG9iamVjdCBhdCBnaXZlbiBpbmRleFxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGluc2lkZUNvbm5lY3RvclxyXG4gKiBAcGFyYW0ge251bWJlcn0gaWR4XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9IG91dHB1dCBwYXJhbWV0ZXJcclxuICovXHJcbklucHV0T3V0cHV0SGVscGVyLmdldE91dHB1dFBhcmFtZXRlciA9IGZ1bmN0aW9uKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KSB7XHJcbiAgcmV0dXJuIHRoaXMuZ2V0T3V0cHV0UGFyYW1ldGVycyhlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpW2lkeF07XHJcbn07XHJcblxyXG4vKipcclxuICogUmV0dXJucyAndHJ1ZScgaWYgdGhlIGdpdmVuIGVsZW1lbnQgc3VwcG9ydHMgaW5wdXRPdXRwdXRcclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0gIHtib29sZWFufSBpbnNpZGVDb25uZWN0b3JcclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5JbnB1dE91dHB1dEhlbHBlci5pc0lucHV0T3V0cHV0U3VwcG9ydGVkID0gZnVuY3Rpb24oZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSB7XHJcblxyXG4gIGlmIChpbnNpZGVDb25uZWN0b3IpIHtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHJldHVybiAoXHJcbiAgICBpcyhibywgJ2JwbW46Rmxvd05vZGUnKSAmJiAhKFxyXG4gICAgICBpcyhibywgJ2JwbW46U3RhcnRFdmVudCcpIHx8XHJcbiAgICAgIGlzKGJvLCAnYnBtbjpHYXRld2F5JykgfHxcclxuICAgICAgaXMoYm8sICdicG1uOkJvdW5kYXJ5RXZlbnQnKSB8fFxyXG4gICAgICAoXHJcbiAgICAgICAgaXMoYm8sICdicG1uOlN1YlByb2Nlc3MnKSAmJiBiby5nZXQoJ3RyaWdnZXJlZEJ5RXZlbnQnKVxyXG4gICAgICApXHJcbiAgICApXHJcbiAgKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zICd0cnVlJyBpZiB0aGUgZ2l2ZW4gZWxlbWVudCBzdXBwb3J0cyBvdXRwdXQgcGFyYW1ldGVyc1xyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge2Jvb2xlYW59IGluc2lkZUNvbm5lY3RvclxyXG4gKlxyXG4gKiBAcmV0dXJuIHtib29sZWFufSBhIGJvb2xlYW4gdmFsdWVcclxuICovXHJcbklucHV0T3V0cHV0SGVscGVyLmFyZU91dHB1dFBhcmFtZXRlcnNTdXBwb3J0ZWQgPSBmdW5jdGlvbihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICByZXR1cm4gaW5zaWRlQ29ubmVjdG9yIHx8ICghaXMoYm8sICdicG1uOkVuZEV2ZW50JykgJiYgIWJvLmxvb3BDaGFyYWN0ZXJpc3RpY3MpO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi9DbWRIZWxwZXInKTtcclxuXHJcblxyXG52YXIgUGFydGljaXBhbnRIZWxwZXIgPSB7fTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gUGFydGljaXBhbnRIZWxwZXI7XHJcblxyXG5QYXJ0aWNpcGFudEhlbHBlci5tb2RpZnlQcm9jZXNzQnVzaW5lc3NPYmplY3QgPSBmdW5jdGlvbihlbGVtZW50LCBwcm9wZXJ0eSwgdmFsdWVzKSB7XHJcbiAgaWYgKCFpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICByZXR1cm4ge307XHJcbiAgfVxyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5nZXQoJ3Byb2Nlc3NSZWYnKSxcclxuICAgICAgcHJvcGVydGllcyA9IHt9O1xyXG5cclxuICBwcm9wZXJ0aWVzW3Byb3BlcnR5XSA9IHZhbHVlc1twcm9wZXJ0eV07XHJcblxyXG4gIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHByb3BlcnRpZXMpO1xyXG59O1xyXG5cclxuUGFydGljaXBhbnRIZWxwZXIuZ2V0UHJvY2Vzc0J1c2luZXNzT2JqZWN0ID0gZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydHlOYW1lKSB7XHJcbiAgaWYgKCFpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICByZXR1cm4ge307XHJcbiAgfVxyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5nZXQoJ3Byb2Nlc3NSZWYnKSxcclxuICAgICAgcHJvcGVydGllcyA9IHt9O1xyXG5cclxuICBwcm9wZXJ0aWVzW3Byb3BlcnR5TmFtZV0gPSBiby5nZXQocHJvcGVydHlOYW1lKTtcclxuXHJcbiAgcmV0dXJuIHByb3BlcnRpZXM7XHJcbn07IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcclxuXHJcbnZhciBQcm9wZXJ0aWVzQWN0aXZhdG9yID0gcmVxdWlyZSgnLi4vLi4vUHJvcGVydGllc0FjdGl2YXRvcicpO1xyXG5cclxudmFyIGFzeW5jQ2FwYWJsZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uL2hlbHBlci9Bc3luY0NhcGFibGVIZWxwZXInKSxcclxuICAgIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uL2hlbHBlci9JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXInKTtcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG4vLyBicG1uIHByb3BlcnRpZXNcclxudmFyIHByb2Nlc3NQcm9wcyA9IHJlcXVpcmUoJy4uLy4uL3Byb3ZpZGVyL2JwbW4vcGFydHMvUHJvY2Vzc1Byb3BzJyksXHJcbiAgICBldmVudFByb3BzID0gcmVxdWlyZSgnLi4vLi4vcHJvdmlkZXIvYnBtbi9wYXJ0cy9FdmVudFByb3BzJyksXHJcbiAgICBsaW5rUHJvcHMgPSByZXF1aXJlKCcuLi8uLi9wcm92aWRlci9icG1uL3BhcnRzL0xpbmtQcm9wcycpLFxyXG4gICAgZG9jdW1lbnRhdGlvblByb3BzID0gcmVxdWlyZSgnLi4vLi4vcHJvdmlkZXIvYnBtbi9wYXJ0cy9Eb2N1bWVudGF0aW9uUHJvcHMnKSxcclxuICAgIGlkUHJvcHMgPSByZXF1aXJlKCcuLi8uLi9wcm92aWRlci9icG1uL3BhcnRzL0lkUHJvcHMnKSxcclxuICAgIG5hbWVQcm9wcyA9IHJlcXVpcmUoJy4uLy4uL3Byb3ZpZGVyL2JwbW4vcGFydHMvTmFtZVByb3BzJyksXHJcbiAgICBleGVjdXRhYmxlUHJvcHMgPSByZXF1aXJlKCcuLi8uLi9wcm92aWRlci9icG1uL3BhcnRzL0V4ZWN1dGFibGVQcm9wcycpO1xyXG5cclxuLy8gYWN0aXZpdGkgcHJvcGVydGllc1xyXG52YXIgc2VydmljZVRhc2tEZWxlZ2F0ZVByb3BzID0gcmVxdWlyZSgnLi9wYXJ0cy9TZXJ2aWNlVGFza0RlbGVnYXRlUHJvcHMnKSxcclxuICAgIHVzZXJUYXNrUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL1VzZXJUYXNrUHJvcHMnKSxcclxuICAgIGFzeW5jaHJvbm91c0NvbnRpbnVhdGlvblByb3BzID0gcmVxdWlyZSgnLi9wYXJ0cy9Bc3luY2hyb25vdXNDb250aW51YXRpb25Qcm9wcycpLFxyXG4gICAgY2FsbEFjdGl2aXR5UHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL0NhbGxBY3Rpdml0eVByb3BzJyksXHJcbiAgICBtdWx0aUluc3RhbmNlUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL011bHRpSW5zdGFuY2VMb29wUHJvcHMnKSxcclxuICAgIGNvbmRpdGlvbmFsUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL0NvbmRpdGlvbmFsUHJvcHMnKSxcclxuICAgIHNjcmlwdFByb3BzID0gcmVxdWlyZSgnLi9wYXJ0cy9TY3JpcHRUYXNrUHJvcHMnKSxcclxuICAgIGVycm9yUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL0Vycm9yRXZlbnRQcm9wcycpLFxyXG4gICAgZm9ybVByb3BzID0gcmVxdWlyZSgnLi9wYXJ0cy9Gb3JtUHJvcHMnKSxcclxuICAgIHN0YXJ0RXZlbnRJbml0aWF0b3IgPSByZXF1aXJlKCcuL3BhcnRzL1N0YXJ0RXZlbnRJbml0aWF0b3InKSxcclxuICAgIHZhcmlhYmxlTWFwcGluZyA9IHJlcXVpcmUoJy4vcGFydHMvVmFyaWFibGVNYXBwaW5nUHJvcHMnKSxcclxuICAgIHZlcnNpb25UYWcgPSByZXF1aXJlKCcuL3BhcnRzL1ZlcnNpb25UYWdQcm9wcycpO1xyXG5cclxudmFyIGxpc3RlbmVyUHJvcHMgPSByZXF1aXJlKCcuL3BhcnRzL0xpc3RlbmVyUHJvcHMnKSxcclxuICAgIGxpc3RlbmVyRGV0YWlscyA9IHJlcXVpcmUoJy4vcGFydHMvTGlzdGVuZXJEZXRhaWxQcm9wcycpLFxyXG4gICAgbGlzdGVuZXJGaWVsZHMgPSByZXF1aXJlKCcuL3BhcnRzL0xpc3RlbmVyRmllbGRJbmplY3Rpb25Qcm9wcycpO1xyXG5cclxudmFyIGVsZW1lbnRUZW1wbGF0ZUNob29zZXJQcm9wcyA9IHJlcXVpcmUoJy4vZWxlbWVudC10ZW1wbGF0ZXMvcGFydHMvQ2hvb3NlclByb3BzJyksXHJcbiAgICBlbGVtZW50VGVtcGxhdGVDdXN0b21Qcm9wcyA9IHJlcXVpcmUoJy4vZWxlbWVudC10ZW1wbGF0ZXMvcGFydHMvQ3VzdG9tUHJvcHMnKTtcclxuXHJcbi8vIElucHV0L091dHB1dFxyXG52YXIgaW5wdXRPdXRwdXQgPSByZXF1aXJlKCcuL3BhcnRzL0lucHV0T3V0cHV0UHJvcHMnKSxcclxuICAgIGlucHV0T3V0cHV0UGFyYW1ldGVyID0gcmVxdWlyZSgnLi9wYXJ0cy9JbnB1dE91dHB1dFBhcmFtZXRlclByb3BzJyk7XHJcblxyXG4vLyBDb25uZWN0b3JcclxudmFyIGNvbm5lY3RvckRldGFpbHMgPSByZXF1aXJlKCcuL3BhcnRzL0Nvbm5lY3RvckRldGFpbFByb3BzJyksXHJcbiAgICBjb25uZWN0b3JJbnB1dE91dHB1dCA9IHJlcXVpcmUoJy4vcGFydHMvQ29ubmVjdG9ySW5wdXRPdXRwdXRQcm9wcycpLFxyXG4gICAgY29ubmVjdG9ySW5wdXRPdXRwdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuL3BhcnRzL0Nvbm5lY3RvcklucHV0T3V0cHV0UGFyYW1ldGVyUHJvcHMnKTtcclxuXHJcbi8vIHByb3BlcnRpZXNcclxudmFyIHByb3BlcnRpZXMgPSByZXF1aXJlKCcuL3BhcnRzL1Byb3BlcnRpZXNQcm9wcycpO1xyXG5cclxuLy8gam9iIGNvbmZpZ3VyYXRpb25cclxudmFyIGpvYkNvbmZpZ3VyYXRpb24gPSByZXF1aXJlKCcuL3BhcnRzL0pvYkNvbmZpZ3VyYXRpb25Qcm9wcycpO1xyXG5cclxuLy8gaGlzdG9yeSB0aW1lIHRvIGxpdmVcclxudmFyIGhpc3RvcnlUaW1lVG9MaXZlID0gcmVxdWlyZSgnLi9wYXJ0cy9IaXN0b3J5VGltZVRvTGl2ZVByb3BzJyk7XHJcblxyXG4vLyBjYW5kaWRhdGUgc3RhcnRlciBncm91cHMvdXNlcnNcclxudmFyIGNhbmRpZGF0ZVN0YXJ0ZXIgPSByZXF1aXJlKCcuL3BhcnRzL0NhbmRpZGF0ZVN0YXJ0ZXJQcm9wcycpO1xyXG5cclxuLy8gdGFza2xpc3RcclxudmFyIHRhc2tsaXN0ID0gcmVxdWlyZSgnLi9wYXJ0cy9UYXNrbGlzdFByb3BzJyk7XHJcblxyXG4vLyBleHRlcm5hbCB0YXNrIGNvbmZpZ3VyYXRpb25cclxudmFyIGV4dGVybmFsVGFza0NvbmZpZ3VyYXRpb24gPSByZXF1aXJlKCcuL3BhcnRzL0V4dGVybmFsVGFza0NvbmZpZ3VyYXRpb25Qcm9wcycpO1xyXG5cclxuLy8gZmllbGQgaW5qZWN0aW9uXHJcbnZhciBmaWVsZEluamVjdGlvbnMgPSByZXF1aXJlKCcuL3BhcnRzL0ZpZWxkSW5qZWN0aW9uUHJvcHMnKTtcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyksXHJcbiAgICBpbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi9oZWxwZXIvSW1wbGVtZW50YXRpb25UeXBlSGVscGVyJyk7XHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbnZhciBpc0V4dGVybmFsVGFza1ByaW9yaXR5RW5hYmxlZCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICB2YXIgYnVzaW5lc3NPYmplY3QgPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgLy8gc2hvdyBvbmx5IGlmIGVsZW1lbnQgaXMgYSBwcm9jZXNzLCBhIHBhcnRpY2lwYW50IC4uLlxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSAmJiBidXNpbmVzc09iamVjdC5nZXQoJ3Byb2Nlc3NSZWYnKSkge1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICB2YXIgZXh0ZXJuYWxCbyA9IEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRTZXJ2aWNlVGFza0xpa2VCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgaXNFeHRlcm5hbFRhc2sgPSBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0SW1wbGVtZW50YXRpb25UeXBlKGV4dGVybmFsQm8pID09PSAnZXh0ZXJuYWwnO1xyXG5cclxuICAvLyAuLi4gb3IgYW4gZXh0ZXJuYWwgdGFzayB3aXRoIHNlbGVjdGVkIGV4dGVybmFsIGltcGxlbWVudGF0aW9uIHR5cGVcclxuICByZXR1cm4gISFJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuaXNFeHRlcm5hbENhcGFibGUoZXh0ZXJuYWxCbykgJiYgaXNFeHRlcm5hbFRhc2s7XHJcbn07XHJcblxyXG52YXIgaXNKb2JDb25maWdFbmFibGVkID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UHJvY2VzcycpIHx8IGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdwcm9jZXNzUmVmJykpIHtcclxuICAgIHJldHVybiB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLy8gYXN5bmMgYmVoYXZpb3JcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICBpZiAoYXN5bmNDYXBhYmxlSGVscGVyLmlzQXN5bmNCZWZvcmUoYm8pIHx8IGFzeW5jQ2FwYWJsZUhlbHBlci5pc0FzeW5jQWZ0ZXIoYm8pKSB7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIC8vIHRpbWVyIGRlZmluaXRpb25cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSkge1xyXG4gICAgcmV0dXJuICEhZXZlbnREZWZpbml0aW9uSGVscGVyLmdldFRpbWVyRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGZhbHNlO1xyXG59O1xyXG5cclxudmFyIGdldElucHV0T3V0cHV0UGFyYW1ldGVyTGFiZWwgPSBmdW5jdGlvbihwYXJhbSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlmIChpcyhwYXJhbSwgJ2FjdGl2aXRpOklucHV0UGFyYW1ldGVyJykpIHtcclxuICAgIHJldHVybiB0cmFuc2xhdGUoJ0lucHV0IFBhcmFtZXRlcicpO1xyXG4gIH1cclxuXHJcbiAgaWYgKGlzKHBhcmFtLCAnYWN0aXZpdGk6T3V0cHV0UGFyYW1ldGVyJykpIHtcclxuICAgIHJldHVybiB0cmFuc2xhdGUoJ091dHB1dCBQYXJhbWV0ZXInKTtcclxuICB9XHJcblxyXG4gIHJldHVybiAnJztcclxufTtcclxuXHJcbnZhciBnZXRMaXN0ZW5lckxhYmVsID0gZnVuY3Rpb24ocGFyYW0sIHRyYW5zbGF0ZSkge1xyXG5cclxuICBpZiAoaXMocGFyYW0sICdhY3Rpdml0aTpFeGVjdXRpb25MaXN0ZW5lcicpKSB7XHJcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdFeGVjdXRpb24gTGlzdGVuZXInKTtcclxuICB9XHJcblxyXG4gIGlmIChpcyhwYXJhbSwgJ2FjdGl2aXRpOlRhc2tMaXN0ZW5lcicpKSB7XHJcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdUYXNrIExpc3RlbmVyJyk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gJyc7XHJcbn07XHJcblxyXG52YXIgUFJPQ0VTU19LRVlfSElOVCA9ICdUaGlzIG1hcHMgdG8gdGhlIHByb2Nlc3MgZGVmaW5pdGlvbiBrZXkuJztcclxudmFyIFRBU0tfS0VZX0hJTlQgPSAnVGhpcyBtYXBzIHRvIHRoZSB0YXNrIGRlZmluaXRpb24ga2V5Lic7XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVHZW5lcmFsVGFiR3JvdXBzKFxyXG4gICAgZWxlbWVudCwgY2FudmFzLCBicG1uRmFjdG9yeSxcclxuICAgIGVsZW1lbnRSZWdpc3RyeSwgZWxlbWVudFRlbXBsYXRlcywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIC8vIHJlZmVyIHRvIHRhcmdldCBlbGVtZW50IGZvciBleHRlcm5hbCBsYWJlbHNcclxuICBlbGVtZW50ID0gZWxlbWVudC5sYWJlbFRhcmdldCB8fCBlbGVtZW50O1xyXG5cclxuICB2YXIgZ2VuZXJhbEdyb3VwID0ge1xyXG4gICAgaWQ6ICdnZW5lcmFsJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0dlbmVyYWwnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgdmFyIGlkT3B0aW9ucztcclxuICB2YXIgcHJvY2Vzc09wdGlvbnM7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykpIHtcclxuICAgIGlkT3B0aW9ucyA9IHsgZGVzY3JpcHRpb246IFBST0NFU1NfS0VZX0hJTlQgfTtcclxuICB9XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpVc2VyVGFzaycpKSB7XHJcbiAgICBpZE9wdGlvbnMgPSB7IGRlc2NyaXB0aW9uOiBUQVNLX0tFWV9ISU5UIH07XHJcbiAgfVxyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgcHJvY2Vzc09wdGlvbnMgPSB7IHByb2Nlc3NJZERlc2NyaXB0aW9uOiBQUk9DRVNTX0tFWV9ISU5UIH07XHJcbiAgfVxyXG5cclxuICBpZFByb3BzKGdlbmVyYWxHcm91cCwgZWxlbWVudCwgdHJhbnNsYXRlLCBpZE9wdGlvbnMpO1xyXG4gIG5hbWVQcm9wcyhnZW5lcmFsR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjYW52YXMsIHRyYW5zbGF0ZSk7XHJcbiAgcHJvY2Vzc1Byb3BzKGdlbmVyYWxHcm91cCwgZWxlbWVudCwgdHJhbnNsYXRlLCBwcm9jZXNzT3B0aW9ucyk7XHJcbiAgdmVyc2lvblRhZyhnZW5lcmFsR3JvdXAsIGVsZW1lbnQsIHRyYW5zbGF0ZSk7XHJcbiAgZXhlY3V0YWJsZVByb3BzKGdlbmVyYWxHcm91cCwgZWxlbWVudCwgdHJhbnNsYXRlKTtcclxuICBlbGVtZW50VGVtcGxhdGVDaG9vc2VyUHJvcHMoZ2VuZXJhbEdyb3VwLCBlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzLCB0cmFuc2xhdGUpO1xyXG5cclxuICB2YXIgY3VzdG9tRmllbGRzR3JvdXBzID0gZWxlbWVudFRlbXBsYXRlQ3VzdG9tUHJvcHMoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcywgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBkZXRhaWxzR3JvdXAgPSB7XHJcbiAgICBpZDogJ2RldGFpbHMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnRGV0YWlscycpLFxyXG4gICAgZW50cmllczogW11cclxuICB9O1xyXG4gIHNlcnZpY2VUYXNrRGVsZWdhdGVQcm9wcyhkZXRhaWxzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG4gIHVzZXJUYXNrUHJvcHMoZGV0YWlsc0dyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpO1xyXG4gIHNjcmlwdFByb3BzKGRldGFpbHNHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcbiAgbGlua1Byb3BzKGRldGFpbHNHcm91cCwgZWxlbWVudCwgdHJhbnNsYXRlKTtcclxuICBjYWxsQWN0aXZpdHlQcm9wcyhkZXRhaWxzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG4gIGV2ZW50UHJvcHMoZGV0YWlsc0dyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpO1xyXG4gIGVycm9yUHJvcHMoZGV0YWlsc0dyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuICBjb25kaXRpb25hbFByb3BzKGRldGFpbHNHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcbiAgc3RhcnRFdmVudEluaXRpYXRvcihkZXRhaWxzR3JvdXAsIGVsZW1lbnQsIHRyYW5zbGF0ZSk7IC8vIHRoaXMgbXVzdCBiZSB0aGUgbGFzdCBlbGVtZW50IG9mIHRoZSBkZXRhaWxzIGdyb3VwIVxyXG5cclxuICB2YXIgbXVsdGlJbnN0YW5jZUdyb3VwID0ge1xyXG4gICAgaWQ6ICdtdWx0aUluc3RhbmNlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ011bHRpIEluc3RhbmNlJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcbiAgbXVsdGlJbnN0YW5jZVByb3BzKG11bHRpSW5zdGFuY2VHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBhc3luY0dyb3VwID0ge1xyXG4gICAgaWQgOiAnYXN5bmMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQXN5bmNocm9ub3VzIENvbnRpbnVhdGlvbnMnKSxcclxuICAgIGVudHJpZXMgOiBbXVxyXG4gIH07XHJcbiAgYXN5bmNocm9ub3VzQ29udGludWF0aW9uUHJvcHMoYXN5bmNHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBqb2JDb25maWd1cmF0aW9uR3JvdXAgPSB7XHJcbiAgICBpZCA6ICdqb2JDb25maWd1cmF0aW9uJyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdKb2IgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllcyA6IFtdLFxyXG4gICAgZW5hYmxlZDogaXNKb2JDb25maWdFbmFibGVkXHJcbiAgfTtcclxuICBqb2JDb25maWd1cmF0aW9uKGpvYkNvbmZpZ3VyYXRpb25Hcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBleHRlcm5hbFRhc2tHcm91cCA9IHtcclxuICAgIGlkIDogJ2V4dGVybmFsVGFza0NvbmZpZ3VyYXRpb24nLFxyXG4gICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0V4dGVybmFsIFRhc2sgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllcyA6IFtdLFxyXG4gICAgZW5hYmxlZDogaXNFeHRlcm5hbFRhc2tQcmlvcml0eUVuYWJsZWRcclxuICB9O1xyXG4gIGV4dGVybmFsVGFza0NvbmZpZ3VyYXRpb24oZXh0ZXJuYWxUYXNrR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuXHJcbiAgdmFyIGNhbmRpZGF0ZVN0YXJ0ZXJHcm91cCA9IHtcclxuICAgIGlkOiAnY2FuZGlkYXRlU3RhcnRlckNvbmZpZ3VyYXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ2FuZGlkYXRlIFN0YXJ0ZXIgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllczogW11cclxuICB9O1xyXG4gIGNhbmRpZGF0ZVN0YXJ0ZXIoY2FuZGlkYXRlU3RhcnRlckdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGhpc3RvcnlUaW1lVG9MaXZlR3JvdXAgPSB7XHJcbiAgICBpZDogJ2hpc3RvcnlDb25maWd1cmF0aW9uJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0hpc3RvcnkgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllczogW11cclxuICB9O1xyXG4gIGhpc3RvcnlUaW1lVG9MaXZlKGhpc3RvcnlUaW1lVG9MaXZlR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICB2YXIgdGFza2xpc3RHcm91cCA9IHtcclxuICAgIGlkOiAndGFza2xpc3QnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGFza2xpc3QgQ29uZmlndXJhdGlvbicpLFxyXG4gICAgZW50cmllczogW11cclxuICB9O1xyXG4gIHRhc2tsaXN0KHRhc2tsaXN0R3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICB2YXIgZG9jdW1lbnRhdGlvbkdyb3VwID0ge1xyXG4gICAgaWQ6ICdkb2N1bWVudGF0aW9uJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0RvY3VtZW50YXRpb24nKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuICBkb2N1bWVudGF0aW9uUHJvcHMoZG9jdW1lbnRhdGlvbkdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGdyb3VwcyA9IFtdO1xyXG4gIGdyb3Vwcy5wdXNoKGdlbmVyYWxHcm91cCk7XHJcbiAgY3VzdG9tRmllbGRzR3JvdXBzLmZvckVhY2goZnVuY3Rpb24oZ3JvdXApIHtcclxuICAgIGdyb3Vwcy5wdXNoKGdyb3VwKTtcclxuICB9KTtcclxuICBncm91cHMucHVzaChkZXRhaWxzR3JvdXApO1xyXG4gIGdyb3Vwcy5wdXNoKGV4dGVybmFsVGFza0dyb3VwKTtcclxuICBncm91cHMucHVzaChtdWx0aUluc3RhbmNlR3JvdXApO1xyXG4gIGdyb3Vwcy5wdXNoKGFzeW5jR3JvdXApO1xyXG4gIGdyb3Vwcy5wdXNoKGpvYkNvbmZpZ3VyYXRpb25Hcm91cCk7XHJcbiAgZ3JvdXBzLnB1c2goY2FuZGlkYXRlU3RhcnRlckdyb3VwKTtcclxuICBncm91cHMucHVzaChoaXN0b3J5VGltZVRvTGl2ZUdyb3VwKTtcclxuICBncm91cHMucHVzaCh0YXNrbGlzdEdyb3VwKTtcclxuICBncm91cHMucHVzaChkb2N1bWVudGF0aW9uR3JvdXApO1xyXG5cclxuICByZXR1cm4gZ3JvdXBzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVWYXJpYWJsZXNUYWJHcm91cHMoZWxlbWVudCwgYnBtbkZhY3RvcnksIGVsZW1lbnRSZWdpc3RyeSwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIHZhcmlhYmxlc0dyb3VwID0ge1xyXG4gICAgaWQgOiAndmFyaWFibGVzJyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdWYXJpYWJsZXMnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuICB2YXJpYWJsZU1hcHBpbmcodmFyaWFibGVzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICByZXR1cm4gW1xyXG4gICAgdmFyaWFibGVzR3JvdXBcclxuICBdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVGb3Jtc1RhYkdyb3VwcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpIHtcclxuICB2YXIgZm9ybUdyb3VwID0ge1xyXG4gICAgaWQgOiAnZm9ybXMnLFxyXG4gICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0Zvcm1zJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcbiAgZm9ybVByb3BzKGZvcm1Hcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHJldHVybiBbXHJcbiAgICBmb3JtR3JvdXBcclxuICBdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVMaXN0ZW5lcnNUYWJHcm91cHMoZWxlbWVudCwgYnBtbkZhY3RvcnksIGVsZW1lbnRSZWdpc3RyeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBsaXN0ZW5lcnNHcm91cCA9IHtcclxuICAgIGlkIDogJ2xpc3RlbmVycycsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdMaXN0ZW5lcnMnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgdmFyIG9wdGlvbnMgPSBsaXN0ZW5lclByb3BzKGxpc3RlbmVyc0dyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGxpc3RlbmVyRGV0YWlsc0dyb3VwID0ge1xyXG4gICAgaWQ6ICdsaXN0ZW5lci1kZXRhaWxzJyxcclxuICAgIGVudHJpZXM6IFtdLFxyXG4gICAgZW5hYmxlZDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5nZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuICAgIGxhYmVsOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBwYXJhbSA9IG9wdGlvbnMuZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGdldExpc3RlbmVyTGFiZWwocGFyYW0sIHRyYW5zbGF0ZSk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgbGlzdGVuZXJEZXRhaWxzKGxpc3RlbmVyRGV0YWlsc0dyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGxpc3RlbmVyRmllbGRzR3JvdXAgPSB7XHJcbiAgICBpZDogJ2xpc3RlbmVyLWZpZWxkcycsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdGaWVsZCBJbmplY3Rpb24nKSxcclxuICAgIGVudHJpZXM6IFtdLFxyXG4gICAgZW5hYmxlZDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5nZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfVxyXG4gIH07XHJcblxyXG4gIGxpc3RlbmVyRmllbGRzKGxpc3RlbmVyRmllbGRzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpO1xyXG5cclxuICByZXR1cm4gW1xyXG4gICAgbGlzdGVuZXJzR3JvdXAsXHJcbiAgICBsaXN0ZW5lckRldGFpbHNHcm91cCxcclxuICAgIGxpc3RlbmVyRmllbGRzR3JvdXBcclxuICBdO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVJbnB1dE91dHB1dFRhYkdyb3VwcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGlucHV0T3V0cHV0R3JvdXAgPSB7XHJcbiAgICBpZDogJ2lucHV0LW91dHB1dCcsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdQYXJhbWV0ZXJzJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcblxyXG4gIHZhciBvcHRpb25zID0gaW5wdXRPdXRwdXQoaW5wdXRPdXRwdXRHcm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSk7XHJcblxyXG4gIHZhciBpbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwID0ge1xyXG4gICAgaWQ6ICdpbnB1dC1vdXRwdXQtcGFyYW1ldGVyJyxcclxuICAgIGVudHJpZXM6IFtdLFxyXG4gICAgZW5hYmxlZDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5nZXRTZWxlY3RlZFBhcmFtZXRlcihlbGVtZW50LCBub2RlKTtcclxuICAgIH0sXHJcbiAgICBsYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgcGFyYW0gPSBvcHRpb25zLmdldFNlbGVjdGVkUGFyYW1ldGVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gZ2V0SW5wdXRPdXRwdXRQYXJhbWV0ZXJMYWJlbChwYXJhbSwgdHJhbnNsYXRlKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBpbnB1dE91dHB1dFBhcmFtZXRlcihpbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKTtcclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIGlucHV0T3V0cHV0R3JvdXAsXHJcbiAgICBpbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwXHJcbiAgXTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlQ29ubmVjdG9yVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSkge1xyXG4gIHZhciBjb25uZWN0b3JEZXRhaWxzR3JvdXAgPSB7XHJcbiAgICBpZDogJ2Nvbm5lY3Rvci1kZXRhaWxzJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0RldGFpbHMnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgY29ubmVjdG9yRGV0YWlscyhjb25uZWN0b3JEZXRhaWxzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICB2YXIgY29ubmVjdG9ySW5wdXRPdXRwdXRHcm91cCA9IHtcclxuICAgIGlkOiAnY29ubmVjdG9yLWlucHV0LW91dHB1dCcsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdJbnB1dC9PdXRwdXQnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgdmFyIG9wdGlvbnMgPSBjb25uZWN0b3JJbnB1dE91dHB1dChjb25uZWN0b3JJbnB1dE91dHB1dEdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgdmFyIGNvbm5lY3RvcklucHV0T3V0cHV0UGFyYW1ldGVyR3JvdXAgPSB7XHJcbiAgICBpZDogJ2Nvbm5lY3Rvci1pbnB1dC1vdXRwdXQtcGFyYW1ldGVyJyxcclxuICAgIGVudHJpZXM6IFtdLFxyXG4gICAgZW5hYmxlZDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gb3B0aW9ucy5nZXRTZWxlY3RlZFBhcmFtZXRlcihlbGVtZW50LCBub2RlKTtcclxuICAgIH0sXHJcbiAgICBsYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgcGFyYW0gPSBvcHRpb25zLmdldFNlbGVjdGVkUGFyYW1ldGVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gZ2V0SW5wdXRPdXRwdXRQYXJhbWV0ZXJMYWJlbChwYXJhbSwgdHJhbnNsYXRlKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBjb25uZWN0b3JJbnB1dE91dHB1dFBhcmFtZXRlcihjb25uZWN0b3JJbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKTtcclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIGNvbm5lY3RvckRldGFpbHNHcm91cCxcclxuICAgIGNvbm5lY3RvcklucHV0T3V0cHV0R3JvdXAsXHJcbiAgICBjb25uZWN0b3JJbnB1dE91dHB1dFBhcmFtZXRlckdyb3VwXHJcbiAgXTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlRmllbGRJbmplY3Rpb25zVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZmllbGRHcm91cCA9IHtcclxuICAgIGlkOiAnZmllbGQtaW5qZWN0aW9ucy1wcm9wZXJ0aWVzJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0ZpZWxkIEluamVjdGlvbnMnKSxcclxuICAgIGVudHJpZXM6IFtdXHJcbiAgfTtcclxuXHJcbiAgZmllbGRJbmplY3Rpb25zKGZpZWxkR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICByZXR1cm4gW1xyXG4gICAgZmllbGRHcm91cFxyXG4gIF07XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnRzR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgcHJvcGVydGllc0dyb3VwID0ge1xyXG4gICAgaWQgOiAnZXh0ZW5zaW9uRWxlbWVudHMtcHJvcGVydGllcycsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdQcm9wZXJ0aWVzJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcbiAgcHJvcGVydGllcyhwcm9wZXJ0aWVzR3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpO1xyXG5cclxuICByZXR1cm4gW1xyXG4gICAgcHJvcGVydGllc0dyb3VwXHJcbiAgXTtcclxufVxyXG5cclxuLy8gYWN0aXZpdGkgUHJvcGVydGllcyBQcm92aWRlciAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5cclxuLyoqXHJcbiAqIEEgcHJvcGVydGllcyBwcm92aWRlciBmb3IgYWN0aXZpdGkgcmVsYXRlZCBwcm9wZXJ0aWVzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xyXG4gKiBAcGFyYW0ge0NhbnZhc30gY2FudmFzXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqIEBwYXJhbSB7RWxlbWVudFJlZ2lzdHJ5fSBlbGVtZW50UmVnaXN0cnlcclxuICogQHBhcmFtIHtFbGVtZW50VGVtcGxhdGVzfSBlbGVtZW50VGVtcGxhdGVzXHJcbiAqIEBwYXJhbSB7VHJhbnNsYXRlfSB0cmFuc2xhdGVcclxuICovXHJcbmZ1bmN0aW9uIEFjdGl2aXRpUHJvcGVydGllc1Byb3ZpZGVyKFxyXG4gICAgZXZlbnRCdXMsIGNhbnZhcywgYnBtbkZhY3RvcnksXHJcbiAgICBlbGVtZW50UmVnaXN0cnksIGVsZW1lbnRUZW1wbGF0ZXMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICBQcm9wZXJ0aWVzQWN0aXZhdG9yLmNhbGwodGhpcywgZXZlbnRCdXMpO1xyXG5cclxuICB0aGlzLmdldFRhYnMgPSBmdW5jdGlvbihlbGVtZW50KSB7XHJcblxyXG4gICAgdmFyIGdlbmVyYWxUYWIgPSB7XHJcbiAgICAgIGlkOiAnZ2VuZXJhbCcsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0dlbmVyYWwnKSxcclxuICAgICAgZ3JvdXBzOiBjcmVhdGVHZW5lcmFsVGFiR3JvdXBzKFxyXG4gICAgICAgIGVsZW1lbnQsIGNhbnZhcywgYnBtbkZhY3RvcnksXHJcbiAgICAgICAgZWxlbWVudFJlZ2lzdHJ5LCBlbGVtZW50VGVtcGxhdGVzLCB0cmFuc2xhdGUpXHJcbiAgICB9O1xyXG5cclxuICAgIHZhciB2YXJpYWJsZXNUYWIgPSB7XHJcbiAgICAgIGlkOiAndmFyaWFibGVzJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnVmFyaWFibGVzJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlVmFyaWFibGVzVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSlcclxuICAgIH07XHJcblxyXG4gICAgdmFyIGZvcm1zVGFiID0ge1xyXG4gICAgICBpZDogJ2Zvcm1zJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnRm9ybXMnKSxcclxuICAgICAgZ3JvdXBzOiBjcmVhdGVGb3Jtc1RhYkdyb3VwcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpXHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBsaXN0ZW5lcnNUYWIgPSB7XHJcbiAgICAgIGlkOiAnbGlzdGVuZXJzJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnTGlzdGVuZXJzJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlTGlzdGVuZXJzVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSksXHJcbiAgICAgIGVuYWJsZWQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gIWV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRMaW5rRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpXHJcbiAgICAgICAgICB8fCAoIWlzKGVsZW1lbnQsICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnKVxyXG4gICAgICAgICAgJiYgZXZlbnREZWZpbml0aW9uSGVscGVyLmdldExpbmtFdmVudERlZmluaXRpb24oZWxlbWVudCkpO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBpbnB1dE91dHB1dFRhYiA9IHtcclxuICAgICAgaWQ6ICdpbnB1dC1vdXRwdXQnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdJbnB1dC9PdXRwdXQnKSxcclxuICAgICAgZ3JvdXBzOiBjcmVhdGVJbnB1dE91dHB1dFRhYkdyb3VwcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpXHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBjb25uZWN0b3JUYWIgPSB7XHJcbiAgICAgIGlkOiAnY29ubmVjdG9yJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ29ubmVjdG9yJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlQ29ubmVjdG9yVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSksXHJcbiAgICAgIGVuYWJsZWQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgYm8gPSBpbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0U2VydmljZVRhc2tMaWtlQnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgICAgcmV0dXJuIGJvICYmIGltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRJbXBsZW1lbnRhdGlvblR5cGUoYm8pID09PSAnY29ubmVjdG9yJztcclxuICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgZmllbGRJbmplY3Rpb25zVGFiID0ge1xyXG4gICAgICBpZDogJ2ZpZWxkLWluamVjdGlvbnMnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdGaWVsZCBJbmplY3Rpb25zJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlRmllbGRJbmplY3Rpb25zVGFiR3JvdXBzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSlcclxuICAgIH07XHJcblxyXG4gICAgdmFyIGV4dGVuc2lvbnNUYWIgPSB7XHJcbiAgICAgIGlkOiAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdFeHRlbnNpb25zJyksXHJcbiAgICAgIGdyb3VwczogY3JlYXRlRXh0ZW5zaW9uRWxlbWVudHNHcm91cHMoZWxlbWVudCwgYnBtbkZhY3RvcnksIGVsZW1lbnRSZWdpc3RyeSwgdHJhbnNsYXRlKVxyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gW1xyXG4gICAgICBnZW5lcmFsVGFiLFxyXG4gICAgICB2YXJpYWJsZXNUYWIsXHJcbiAgICAgIGNvbm5lY3RvclRhYixcclxuICAgICAgZm9ybXNUYWIsXHJcbiAgICAgIGxpc3RlbmVyc1RhYixcclxuICAgICAgaW5wdXRPdXRwdXRUYWIsXHJcbiAgICAgIGZpZWxkSW5qZWN0aW9uc1RhYixcclxuICAgICAgZXh0ZW5zaW9uc1RhYlxyXG4gICAgXTtcclxuICB9O1xyXG5cclxufVxyXG5cclxuQWN0aXZpdGlQcm9wZXJ0aWVzUHJvdmlkZXIuJGluamVjdCA9IFtcclxuICAnZXZlbnRCdXMnLFxyXG4gICdjYW52YXMnLFxyXG4gICdicG1uRmFjdG9yeScsXHJcbiAgJ2VsZW1lbnRSZWdpc3RyeScsXHJcbiAgJ2VsZW1lbnRUZW1wbGF0ZXMnLFxyXG4gICd0cmFuc2xhdGUnXHJcbl07XHJcblxyXG5pbmhlcml0cyhBY3Rpdml0aVByb3BlcnRpZXNQcm92aWRlciwgUHJvcGVydGllc0FjdGl2YXRvcik7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEFjdGl2aXRpUHJvcGVydGllc1Byb3ZpZGVyO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhbiBpbnB1dCBwYXJhbWV0ZXIgcmVwcmVzZW50aW5nIHRoZSBnaXZlblxyXG4gKiBiaW5kaW5nIGFuZCB2YWx1ZS5cclxuICpcclxuICogQHBhcmFtIHtQcm9wZXJ0eUJpbmRpbmd9IGJpbmRpbmdcclxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9XHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVJbnB1dFBhcmFtZXRlcihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgc2NyaXB0Rm9ybWF0ID0gYmluZGluZy5zY3JpcHRGb3JtYXQsXHJcbiAgICAgIHBhcmFtZXRlclZhbHVlLFxyXG4gICAgICBwYXJhbWV0ZXJEZWZpbml0aW9uO1xyXG5cclxuICBpZiAoc2NyaXB0Rm9ybWF0KSB7XHJcbiAgICBwYXJhbWV0ZXJEZWZpbml0aW9uID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdhY3Rpdml0aTpTY3JpcHQnLCB7XHJcbiAgICAgIHNjcmlwdEZvcm1hdDogc2NyaXB0Rm9ybWF0LFxyXG4gICAgICB2YWx1ZTogdmFsdWVcclxuICAgIH0pO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBwYXJhbWV0ZXJWYWx1ZSA9IHZhbHVlO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGJwbW5GYWN0b3J5LmNyZWF0ZSgnYWN0aXZpdGk6SW5wdXRQYXJhbWV0ZXInLCB7XHJcbiAgICBuYW1lOiBiaW5kaW5nLm5hbWUsXHJcbiAgICB2YWx1ZTogcGFyYW1ldGVyVmFsdWUsXHJcbiAgICBkZWZpbml0aW9uOiBwYXJhbWV0ZXJEZWZpbml0aW9uXHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmNyZWF0ZUlucHV0UGFyYW1ldGVyID0gY3JlYXRlSW5wdXRQYXJhbWV0ZXI7XHJcblxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhbiBvdXRwdXQgcGFyYW1ldGVyIHJlcHJlc2VudGluZyB0aGUgZ2l2ZW5cclxuICogYmluZGluZyBhbmQgdmFsdWUuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UHJvcGVydHlCaW5kaW5nfSBiaW5kaW5nXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlT3V0cHV0UGFyYW1ldGVyKGJpbmRpbmcsIHZhbHVlLCBicG1uRmFjdG9yeSkge1xyXG4gIHZhciBzY3JpcHRGb3JtYXQgPSBiaW5kaW5nLnNjcmlwdEZvcm1hdCxcclxuICAgICAgcGFyYW1ldGVyVmFsdWUsXHJcbiAgICAgIHBhcmFtZXRlckRlZmluaXRpb247XHJcblxyXG4gIGlmIChzY3JpcHRGb3JtYXQpIHtcclxuICAgIHBhcmFtZXRlckRlZmluaXRpb24gPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOlNjcmlwdCcsIHtcclxuICAgICAgc2NyaXB0Rm9ybWF0OiBzY3JpcHRGb3JtYXQsXHJcbiAgICAgIHZhbHVlOiBiaW5kaW5nLnNvdXJjZVxyXG4gICAgfSk7XHJcbiAgfSBlbHNlIHtcclxuICAgIHBhcmFtZXRlclZhbHVlID0gYmluZGluZy5zb3VyY2U7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gYnBtbkZhY3RvcnkuY3JlYXRlKCdhY3Rpdml0aTpPdXRwdXRQYXJhbWV0ZXInLCB7XHJcbiAgICBuYW1lOiB2YWx1ZSxcclxuICAgIHZhbHVlOiBwYXJhbWV0ZXJWYWx1ZSxcclxuICAgIGRlZmluaXRpb246IHBhcmFtZXRlckRlZmluaXRpb25cclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuY3JlYXRlT3V0cHV0UGFyYW1ldGVyID0gY3JlYXRlT3V0cHV0UGFyYW1ldGVyO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYWN0aXZpdGkgcHJvcGVydHkgZnJvbSB0aGUgZ2l2ZW4gYmluZGluZy5cclxuICpcclxuICogQHBhcmFtIHtQcm9wZXJ0eUJpbmRpbmd9IGJpbmRpbmdcclxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9XHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aVByb3BlcnR5KGJpbmRpbmcsIHZhbHVlLCBicG1uRmFjdG9yeSkge1xyXG4gIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOlByb3BlcnR5Jywge1xyXG4gICAgbmFtZTogYmluZGluZy5uYW1lLFxyXG4gICAgdmFsdWU6IHZhbHVlIHx8ICcnXHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmNyZWF0ZUFjdGl2aXRpUHJvcGVydHkgPSBjcmVhdGVBY3Rpdml0aVByb3BlcnR5O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYWN0aXZpdGk6aW4gZWxlbWVudCBmcm9tIGdpdmVuIGJpbmRpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UHJvcGVydHlCaW5kaW5nfSBiaW5kaW5nXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQWN0aXZpdGlJbihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuXHJcbiAgdmFyIHByb3BlcnRpZXMgPSBjcmVhdGVBY3Rpdml0aUluT3V0QXR0cnMoYmluZGluZywgdmFsdWUpO1xyXG5cclxuICByZXR1cm4gYnBtbkZhY3RvcnkuY3JlYXRlKCdhY3Rpdml0aTpJbicsIHByb3BlcnRpZXMpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5jcmVhdGVBY3Rpdml0aUluID0gY3JlYXRlQWN0aXZpdGlJbjtcclxuXHJcblxyXG4vKipcclxuICogQ3JlYXRlIGFjdGl2aXRpOmluIHdpdGggYnVzaW5lc3NLZXkgZWxlbWVudCBmcm9tIGdpdmVuIGJpbmRpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UHJvcGVydHlCaW5kaW5nfSBiaW5kaW5nXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleShiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuICByZXR1cm4gYnBtbkZhY3RvcnkuY3JlYXRlKCdhY3Rpdml0aTpJbicsIHtcclxuICAgIGJ1c2luZXNzS2V5OiB2YWx1ZVxyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5jcmVhdGVBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5ID0gY3JlYXRlQWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleTtcclxuXHJcblxyXG4vKipcclxuICogQ3JlYXRlIGFjdGl2aXRpOm91dCBlbGVtZW50IGZyb20gZ2l2ZW4gYmluZGluZy5cclxuICpcclxuICogQHBhcmFtIHtQcm9wZXJ0eUJpbmRpbmd9IGJpbmRpbmdcclxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnR9XHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aU91dChiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgcHJvcGVydGllcyA9IGNyZWF0ZUFjdGl2aXRpSW5PdXRBdHRycyhiaW5kaW5nLCB2YWx1ZSk7XHJcblxyXG4gIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOk91dCcsIHByb3BlcnRpZXMpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5jcmVhdGVBY3Rpdml0aU91dCA9IGNyZWF0ZUFjdGl2aXRpT3V0O1xyXG5cclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYWN0aXZpdGk6ZXhlY3V0aW9uTGlzdGVuZXIgZWxlbWVudCBjb250YWluaW5nIGFuIGlubGluZSBzY3JpcHQgZnJvbSBnaXZlbiBiaW5kaW5nLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5QmluZGluZ30gYmluZGluZ1xyXG4gKiBAcGFyYW0ge1N0cmluZ30gdmFsdWVcclxuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH1cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUFjdGl2aXRpRXhlY3V0aW9uTGlzdGVuZXJTY3JpcHQoYmluZGluZywgdmFsdWUsIGJwbW5GYWN0b3J5KSB7XHJcbiAgdmFyIHNjcmlwdEZvcm1hdCA9IGJpbmRpbmcuc2NyaXB0Rm9ybWF0LFxyXG4gICAgICBwYXJhbWV0ZXJWYWx1ZSxcclxuICAgICAgcGFyYW1ldGVyRGVmaW5pdGlvbjtcclxuXHJcbiAgaWYgKHNjcmlwdEZvcm1hdCkge1xyXG4gICAgcGFyYW1ldGVyRGVmaW5pdGlvbiA9IGJwbW5GYWN0b3J5LmNyZWF0ZSgnYWN0aXZpdGk6U2NyaXB0Jywge1xyXG4gICAgICBzY3JpcHRGb3JtYXQ6IHNjcmlwdEZvcm1hdCxcclxuICAgICAgdmFsdWU6IHZhbHVlXHJcbiAgICB9KTtcclxuICB9IGVsc2Uge1xyXG4gICAgcGFyYW1ldGVyVmFsdWUgPSB2YWx1ZTtcclxuICB9XHJcblxyXG4gIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOkV4ZWN1dGlvbkxpc3RlbmVyJywge1xyXG4gICAgZXZlbnQ6IGJpbmRpbmcuZXZlbnQsXHJcbiAgICB2YWx1ZTogcGFyYW1ldGVyVmFsdWUsXHJcbiAgICBzY3JpcHQ6IHBhcmFtZXRlckRlZmluaXRpb25cclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuY3JlYXRlQWN0aXZpdGlFeGVjdXRpb25MaXN0ZW5lclNjcmlwdCA9IGNyZWF0ZUFjdGl2aXRpRXhlY3V0aW9uTGlzdGVuZXJTY3JpcHQ7XHJcblxyXG4vKipcclxuICogQ3JlYXRlIGFjdGl2aXRpOmZpZWxkIGVsZW1lbnQgY29udGFpbmluZyBzdHJpbmcgb3IgZXhwcmVzc2lvbiBmcm9tIGdpdmVuIGJpbmRpbmcuXHJcbiAqXHJcbiAqIEBwYXJhbSB7UHJvcGVydHlCaW5kaW5nfSBiaW5kaW5nXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQWN0aXZpdGlGaWVsZEluamVjdGlvbihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgREVGQVVMVF9QUk9QUyA9IHtcclxuICAgICdzdHJpbmcnOiB1bmRlZmluZWQsXHJcbiAgICAnZXhwcmVzc2lvbic6IHVuZGVmaW5lZCxcclxuICAgICduYW1lJzogdW5kZWZpbmVkXHJcbiAgfTtcclxuXHJcbiAgdmFyIHByb3BzID0gYXNzaWduKHt9LCBERUZBVUxUX1BST1BTKTtcclxuXHJcbiAgaWYgKCFiaW5kaW5nLmV4cHJlc3Npb24pIHtcclxuICAgIHByb3BzLnN0cmluZyA9IHZhbHVlO1xyXG4gIH0gZWxzZSB7XHJcbiAgICBwcm9wcy5leHByZXNzaW9uID0gdmFsdWU7XHJcbiAgfVxyXG4gIHByb3BzLm5hbWUgPSBiaW5kaW5nLm5hbWU7XHJcblxyXG4gIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOkZpZWxkJywgcHJvcHMpO1xyXG59XHJcbm1vZHVsZS5leHBvcnRzLmNyZWF0ZUFjdGl2aXRpRmllbGRJbmplY3Rpb24gPSBjcmVhdGVBY3Rpdml0aUZpZWxkSW5qZWN0aW9uO1xyXG5cclxuXHJcbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBwcm9wZXJ0aWVzIGZvciBhY3Rpdml0aTppbiBhbmQgYWN0aXZpdGk6b3V0IHR5cGVzLlxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQWN0aXZpdGlJbk91dEF0dHJzKGJpbmRpbmcsIHZhbHVlKSB7XHJcblxyXG4gIHZhciBwcm9wZXJ0aWVzID0ge307XHJcblxyXG4gIC8vIGFjdGl2aXRpOmluIHNvdXJjZShFeHByZXNzaW9uKSB0YXJnZXRcclxuICBpZiAoYmluZGluZy50YXJnZXQpIHtcclxuXHJcbiAgICBwcm9wZXJ0aWVzLnRhcmdldCA9IGJpbmRpbmcudGFyZ2V0O1xyXG5cclxuICAgIGlmIChiaW5kaW5nLmV4cHJlc3Npb24pIHtcclxuICAgICAgcHJvcGVydGllcy5zb3VyY2VFeHByZXNzaW9uID0gdmFsdWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBwcm9wZXJ0aWVzLnNvdXJjZSA9IHZhbHVlO1xyXG4gICAgfVxyXG4gIH0gZWxzZVxyXG5cclxuICAvLyBhY3Rpdml0aTooaW58b3V0KSB2YXJpYWJsZXMgbG9jYWxcclxuICBpZiAoYmluZGluZy52YXJpYWJsZXMpIHtcclxuICAgIHByb3BlcnRpZXMudmFyaWFibGVzID0gJ2FsbCc7XHJcblxyXG4gICAgaWYgKGJpbmRpbmcudmFyaWFibGVzID09PSAnbG9jYWwnKSB7XHJcbiAgICAgIHByb3BlcnRpZXMubG9jYWwgPSB0cnVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gYWN0aXZpdGk6b3V0IHNvdXJjZShFeHByZXNzaW9uKSB0YXJnZXRcclxuICBlbHNlIHtcclxuICAgIHByb3BlcnRpZXMudGFyZ2V0ID0gdmFsdWU7XHJcblxyXG4gICAgWyAnc291cmNlJywgJ3NvdXJjZUV4cHJlc3Npb24nIF0uZm9yRWFjaChmdW5jdGlvbihrKSB7XHJcbiAgICAgIGlmIChiaW5kaW5nW2tdKSB7XHJcbiAgICAgICAgcHJvcGVydGllc1trXSA9IGJpbmRpbmdba107XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHByb3BlcnRpZXM7XHJcbn1cclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGluaGVyaXRzID0gcmVxdWlyZSgnaW5oZXJpdHMnKTtcclxuXHJcbnZhciBnZXRUZW1wbGF0ZSA9IHJlcXVpcmUoJy4vSGVscGVyJykuZ2V0VGVtcGxhdGU7XHJcblxyXG52YXIgUHJvcGVydGllc0FjdGl2YXRvciA9IHJlcXVpcmUoJy4uLy4uLy4uL1Byb3BlcnRpZXNBY3RpdmF0b3InKTtcclxuXHJcbnZhciBISUdIRVJfUFJJT1JJVFkgPSAxMTAwO1xyXG5cclxuLyoqXHJcbiAqIEFwcGxpZXMgdGVtcGxhdGUgdmlzaWJpbGl0eSBzZXR0aW5ncy5cclxuICpcclxuICogQ29udHJvbGxlZCB1c2luZyBgZW50cmllc1Zpc2libGVgIG9uIHRlbXBsYXRlIGNvbmZpZyBvYmplY3Q6XHJcbiAqXHJcbiAqIGBgYGpzb25cclxuICogICAgIFwiZW50cmllc1Zpc2libGVcIjoge1xyXG4gKiAgICAgICBcIl9hbGxcIjogdHJ1ZXxmYWxzZSxcclxuICogICAgICAgXCJlbnRyeU5hbWVcIjogdHJ1ZXxmYWxzZSxcclxuICogICAgICAgLi4uXHJcbiAqICAgICB9XHJcbiAqIGBgYFxyXG4gKlxyXG4gKiBAcGFyYW0ge0V2ZW50QnVzfSBldmVudEJ1c1xyXG4gKiBAcGFyYW0ge0VsZW1lbnRUZW1wbGF0ZXN9IGVsZW1lbnRUZW1wbGF0ZXNcclxuICovXHJcbmZ1bmN0aW9uIEN1c3RvbUVsZW1lbnRzUHJvcGVydGllc0FjdGl2YXRvcihldmVudEJ1cywgZWxlbWVudFRlbXBsYXRlcykge1xyXG4gIFByb3BlcnRpZXNBY3RpdmF0b3IuY2FsbCh0aGlzLCBldmVudEJ1cywgSElHSEVSX1BSSU9SSVRZKTtcclxuXHJcbiAgdGhpcy5pc0VudHJ5VmlzaWJsZSA9IGZ1bmN0aW9uKGVudHJ5LCBlbGVtZW50KSB7XHJcblxyXG4gICAgdmFyIHRlbXBsYXRlID0gZ2V0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcyk7XHJcblxyXG4gICAgaWYgKHRlbXBsYXRlICYmICFpc0VudHJ5VmlzaWJsZShlbnRyeSwgdGVtcGxhdGUpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICB0aGlzLmlzUHJvcGVydHlFZGl0YWJsZSA9IGZ1bmN0aW9uKGVudHJ5LCBwcm9wZXJ0eU5hbWUsIGVsZW1lbnQpIHtcclxuXHJcbiAgICB2YXIgdGVtcGxhdGUgPSBnZXRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKTtcclxuXHJcbiAgICBpZiAodGVtcGxhdGUgJiYgIWlzRW50cnlFZGl0YWJsZShlbnRyeSwgdGVtcGxhdGUpKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICB9O1xyXG59XHJcblxyXG5DdXN0b21FbGVtZW50c1Byb3BlcnRpZXNBY3RpdmF0b3IuJGluamVjdCA9IFsgJ2V2ZW50QnVzJywgJ2VsZW1lbnRUZW1wbGF0ZXMnIF07XHJcblxyXG5pbmhlcml0cyhDdXN0b21FbGVtZW50c1Byb3BlcnRpZXNBY3RpdmF0b3IsIFByb3BlcnRpZXNBY3RpdmF0b3IpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBDdXN0b21FbGVtZW50c1Byb3BlcnRpZXNBY3RpdmF0b3I7XHJcblxyXG5cclxuXHJcbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5cclxudmFyIENVU1RPTV9QUk9QRVJUSUVTX1BBVFRFUk4gPSAvXmN1c3RvbS0vO1xyXG5cclxudmFyIERFRkFVTFRfRU5UUklFU19WSVNJQkxFID0ge1xyXG4gIF9hbGw6IGZhbHNlLFxyXG4gIGlkOiB0cnVlLFxyXG4gIG5hbWU6IHRydWVcclxufTtcclxuXHJcbmZ1bmN0aW9uIGlzQ3VzdG9tRW50cnkoZW50cnkpIHtcclxuICByZXR1cm4gQ1VTVE9NX1BST1BFUlRJRVNfUEFUVEVSTi50ZXN0KGVudHJ5LmlkKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNFbnRyeVZpc2libGUoZW50cnksIHRlbXBsYXRlKSB7XHJcblxyXG4gIHZhciBlbnRyeUlkID0gZW50cnkuaWQ7XHJcblxyXG4gIGlmIChlbnRyeUlkID09PSAnZWxlbWVudFRlbXBsYXRlLWNob29zZXInIHx8IGlzQ3VzdG9tRW50cnkoZW50cnkpKSB7XHJcbiAgICByZXR1cm4gdHJ1ZTtcclxuICB9XHJcblxyXG4gIHZhciBlbnRyaWVzVmlzaWJsZSA9IHRlbXBsYXRlLmVudHJpZXNWaXNpYmxlIHx8IERFRkFVTFRfRU5UUklFU19WSVNJQkxFO1xyXG5cclxuICBpZiAodHlwZW9mIGVudHJpZXNWaXNpYmxlID09PSAnYm9vbGVhbicpIHtcclxuICAgIHJldHVybiBlbnRyaWVzVmlzaWJsZTtcclxuICB9XHJcblxyXG4gIHZhciBkZWZhdWx0VmlzaWJsZSA9IGVudHJpZXNWaXNpYmxlLl9hbGwgfHwgZmFsc2UsXHJcbiAgICAgIGVudHJ5VmlzaWJsZSA9IGVudHJpZXNWaXNpYmxlW2VudHJ5SWRdO1xyXG5cclxuICAvLyBkID0gdHJ1ZSwgZSA9IGZhbHNlID0+IGZhbHNlXHJcbiAgLy8gZCA9IGZhbHNlLCBlID0gdHJ1ZSA9PiB0cnVlXHJcbiAgLy8gZCA9IGZhbHNlLCBlID0gZmFsc2VcclxuICByZXR1cm4gKFxyXG4gICAgKGRlZmF1bHRWaXNpYmxlID09PSB0cnVlICYmIGVudHJ5VmlzaWJsZSAhPT0gZmFsc2UpIHx8XHJcbiAgICAoZGVmYXVsdFZpc2libGUgPT09IGZhbHNlICYmIGVudHJ5VmlzaWJsZSA9PT0gdHJ1ZSlcclxuICApO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0VudHJ5RWRpdGFibGUoZW50cnksIHRlbXBsYXRlKSB7XHJcblxyXG4gIHZhciBwcm9wZXJ0eTtcclxuXHJcbiAgaWYgKGlzQ3VzdG9tRW50cnkoZW50cnkpKSB7XHJcbiAgICBwcm9wZXJ0eSA9IGdldFByb3BlcnR5KHRlbXBsYXRlLCBlbnRyeSk7XHJcblxyXG4gICAgcmV0dXJuIHByb3BlcnR5ICYmIHByb3BlcnR5LmVkaXRhYmxlICE9PSBmYWxzZTtcclxuICB9XHJcblxyXG4gIHJldHVybiB0cnVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRQcm9wZXJ0eSh0ZW1wbGF0ZSwgZW50cnkpIHtcclxuXHJcbiAgdmFyIGluZGV4O1xyXG4gIHZhciBpZHggPSBlbnRyeS5pZC5yZXBsYWNlKCdjdXN0b20tJyArIHRlbXBsYXRlLmlkICsgJy0nLCAnJyk7XHJcbiAgaWYgKGlkeC5pbmRleE9mKCctJykgIT09IC0xKSB7XHJcbiAgICB2YXIgaW5kZXhlcyA9IGlkeC5zcGxpdCgnLScpO1xyXG4gICAgaWYgKGluZGV4ZXMubGVuZ3RoID09IDIpIHtcclxuICAgICAgdmFyIHNjb3BlTmFtZSA9IGluZGV4ZXNbMF0ucmVwbGFjZSgvXy9nLCAnOicpO1xyXG4gICAgICBpbmRleCA9IHBhcnNlSW50KGluZGV4ZXNbMV0sIDEwKTtcclxuICAgICAgaWYgKHNjb3BlTmFtZSAmJiAhaXNOYU4oaW5kZXgpKSB7XHJcbiAgICAgICAgcmV0dXJuIHRlbXBsYXRlLnNjb3Blc1tzY29wZU5hbWVdLnByb3BlcnRpZXNbaW5kZXhdO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSBlbHNlIHtcclxuICAgIGluZGV4ID0gcGFyc2VJbnQoaWR4LCAxMCk7XHJcbiAgICBpZiAoIWlzTmFOKGluZGV4KSkge1xyXG4gICAgICByZXR1cm4gdGVtcGxhdGUucHJvcGVydGllc1tpbmRleF07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBleHRyYWN0IHByb3BlcnR5IGluZGV4IGZvciBlbnRyeSA8JyArIGVudHJ5LmlkICsgJz4nKTtcclxufVxyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgdmFsdWVzID0gcmVxdWlyZSgnbG9kYXNoL3ZhbHVlcycpO1xyXG5cclxuLyoqXHJcbiAqIFRoZSBndXkga25vd2luZyBhbGwgY29uZmlndXJlZCBlbGVtZW50IHRlbXBsYXRlcy5cclxuICpcclxuICogVGhpcyByZWdpc3RyeSB3b24ndCB2YWxpZGF0ZS4gVXNlIHRoZSB7QGxpbmsgVmFsaWRhdG9yfVxyXG4gKiB0byB2ZXJpZnkgYSB0ZW1wbGF0ZSBpcyB2YWxpZCBwcmlvciB0byBhZGRpbmcgaXQgdG9cclxuICogdGhpcyByZWdpc3RyeS5cclxuICovXHJcbmZ1bmN0aW9uIEVsZW1lbnRUZW1wbGF0ZXMoKSB7XHJcblxyXG4gIHRoaXMuX3RlbXBsYXRlcyA9IHt9O1xyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBrbm93biBlbGVtZW50IHRlbXBsYXRlcy5cclxuICAgKlxyXG4gICAqIEBwYXJhbSB7QXJyYXk8VGVtcGxhdGVEZXNjcmlwdG9yPn0gZGVzY3JpcHRvcnNcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge0VsZW1lbnRUZW1wbGF0ZXN9XHJcbiAgICovXHJcbiAgdGhpcy5zZXQgPSBmdW5jdGlvbihkZXNjcmlwdG9ycykge1xyXG5cclxuICAgIHZhciB0ZW1wbGF0ZXMgPSB0aGlzLl90ZW1wbGF0ZXMgPSB7fTtcclxuXHJcbiAgICBkZXNjcmlwdG9ycy5mb3JFYWNoKGZ1bmN0aW9uKGRlc2NyaXB0b3IpIHtcclxuICAgICAgdGVtcGxhdGVzW2Rlc2NyaXB0b3IuaWRdID0gZGVzY3JpcHRvcjtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCB0ZW1wbGF0ZSBkZXNjcmlwdG9yIHdpdGggZ2l2ZW4gaWQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge1N0cmluZ30gaWRcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge1RlbXBsYXRlRGVzY3JpcHRvcn1cclxuICAgKi9cclxuICB0aGlzLmdldCA9IGZ1bmN0aW9uKGlkKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fdGVtcGxhdGVzW2lkXTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm4gYWxsIGtub3duIHRlbXBsYXRlIGRlc2NyaXB0b3JzLlxyXG4gICAqXHJcbiAgICogQHJldHVybiB7QXJyYXk8VGVtcGxhdGVEZXNjcmlwdG9yPn1cclxuICAgKi9cclxuICB0aGlzLmdldEFsbCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHZhbHVlcyh0aGlzLl90ZW1wbGF0ZXMpO1xyXG4gIH07XHJcblxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEVsZW1lbnRUZW1wbGF0ZXM7IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIFZhbGlkYXRvciA9IHJlcXVpcmUoJy4vVmFsaWRhdG9yJyk7XHJcblxyXG4vKipcclxuICogVGhlIGd1eSByZXNwb25zaWJsZSBmb3IgdGVtcGxhdGUgbG9hZGluZy5cclxuICpcclxuICogUHJvdmlkZSB0aGUgYWN0dWFsIHRlbXBsYXRlcyB2aWEgdGhlIGBjb25maWcuZWxlbWVudFRlbXBsYXRlc2AuXHJcbiAqXHJcbiAqIFRoYXQgY29uZmlndXJhdGlvbiBjYW4gZWl0aGVyIGJlIGFuIGFycmF5IG9mIHRlbXBsYXRlXHJcbiAqIGRlc2NyaXB0b3JzIG9yIGEgbm9kZSBzdHlsZSBjYWxsYmFjayB0byByZXRyaWV2ZVxyXG4gKiB0aGUgdGVtcGxhdGVzIGFzeW5jaHJvbm91c2x5LlxyXG4gKlxyXG4gKiBAcGFyYW0ge0FycmF5PFRlbXBsYXRlRGVzY3JpcHRvcj58RnVuY3Rpb259IGxvYWRUZW1wbGF0ZXNcclxuICogQHBhcmFtIHtFdmVudEJ1c30gZXZlbnRCdXNcclxuICogQHBhcmFtIHtFbGVtZW50VGVtcGxhdGVzfSBlbGVtZW50VGVtcGxhdGVzXHJcbiAqL1xyXG5mdW5jdGlvbiBFbGVtZW50VGVtcGxhdGVzTG9hZGVyKGxvYWRUZW1wbGF0ZXMsIGV2ZW50QnVzLCBlbGVtZW50VGVtcGxhdGVzKSB7XHJcbiAgdGhpcy5fbG9hZFRlbXBsYXRlcyA9IGxvYWRUZW1wbGF0ZXM7XHJcbiAgdGhpcy5fZXZlbnRCdXMgPSBldmVudEJ1cztcclxuICB0aGlzLl9lbGVtZW50VGVtcGxhdGVzID0gZWxlbWVudFRlbXBsYXRlcztcclxuXHJcbiAgdmFyIHNlbGYgPSB0aGlzO1xyXG5cclxuICBldmVudEJ1cy5vbignZGlhZ3JhbS5pbml0JywgZnVuY3Rpb24oKSB7XHJcbiAgICBzZWxmLnJlbG9hZCgpO1xyXG4gIH0pO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IEVsZW1lbnRUZW1wbGF0ZXNMb2FkZXI7XHJcblxyXG5FbGVtZW50VGVtcGxhdGVzTG9hZGVyLiRpbmplY3QgPSBbXHJcbiAgJ2NvbmZpZy5lbGVtZW50VGVtcGxhdGVzJyxcclxuICAnZXZlbnRCdXMnLFxyXG4gICdlbGVtZW50VGVtcGxhdGVzJ1xyXG5dO1xyXG5cclxuXHJcbkVsZW1lbnRUZW1wbGF0ZXNMb2FkZXIucHJvdG90eXBlLnJlbG9hZCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICB2YXIgc2VsZiA9IHRoaXM7XHJcblxyXG4gIHZhciBsb2FkVGVtcGxhdGVzID0gdGhpcy5fbG9hZFRlbXBsYXRlcztcclxuXHJcbiAgLy8gbm8gdGVtcGxhdGVzIHNwZWNpZmllZFxyXG4gIGlmICh0eXBlb2YgbG9hZFRlbXBsYXRlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIHRlbXBsYXRlIGxvYWRlciBmdW5jdGlvbiBzcGVjaWZpZWRcclxuICBpZiAodHlwZW9mIGxvYWRUZW1wbGF0ZXMgPT09ICdmdW5jdGlvbicpIHtcclxuXHJcbiAgICByZXR1cm4gbG9hZFRlbXBsYXRlcyhmdW5jdGlvbihlcnIsIHRlbXBsYXRlcykge1xyXG5cclxuICAgICAgaWYgKGVycikge1xyXG4gICAgICAgIHJldHVybiBzZWxmLnRlbXBsYXRlRXJyb3JzKFsgZXJyIF0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzZWxmLnNldFRlbXBsYXRlcyh0ZW1wbGF0ZXMpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyB0ZW1wbGF0ZXMgYXJyYXkgc3BlY2lmaWVkXHJcbiAgaWYgKGxvYWRUZW1wbGF0ZXMubGVuZ3RoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zZXRUZW1wbGF0ZXMobG9hZFRlbXBsYXRlcyk7XHJcbiAgfVxyXG5cclxufTtcclxuXHJcbkVsZW1lbnRUZW1wbGF0ZXNMb2FkZXIucHJvdG90eXBlLnNldFRlbXBsYXRlcyA9IGZ1bmN0aW9uKHRlbXBsYXRlcykge1xyXG5cclxuICB2YXIgZWxlbWVudFRlbXBsYXRlcyA9IHRoaXMuX2VsZW1lbnRUZW1wbGF0ZXM7XHJcblxyXG4gIHZhciB2YWxpZGF0b3IgPSBuZXcgVmFsaWRhdG9yKCkuYWRkQWxsKHRlbXBsYXRlcyk7XHJcblxyXG4gIHZhciBlcnJvcnMgPSB2YWxpZGF0b3IuZ2V0RXJyb3JzKCksXHJcbiAgICAgIHZhbGlkVGVtcGxhdGVzID0gdmFsaWRhdG9yLmdldFZhbGlkVGVtcGxhdGVzKCk7XHJcblxyXG4gIGVsZW1lbnRUZW1wbGF0ZXMuc2V0KHZhbGlkVGVtcGxhdGVzKTtcclxuXHJcbiAgaWYgKGVycm9ycy5sZW5ndGgpIHtcclxuICAgIHRoaXMudGVtcGxhdGVFcnJvcnMoZXJyb3JzKTtcclxuICB9XHJcblxyXG4gIHRoaXMudGVtcGxhdGVzQ2hhbmdlZCgpO1xyXG59O1xyXG5cclxuRWxlbWVudFRlbXBsYXRlc0xvYWRlci5wcm90b3R5cGUudGVtcGxhdGVzQ2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xyXG4gIHRoaXMuX2V2ZW50QnVzLmZpcmUoJ2VsZW1lbnRUZW1wbGF0ZXMuY2hhbmdlZCcpO1xyXG59O1xyXG5cclxuRWxlbWVudFRlbXBsYXRlc0xvYWRlci5wcm90b3R5cGUudGVtcGxhdGVFcnJvcnMgPSBmdW5jdGlvbihlcnJvcnMpIHtcclxuICB0aGlzLl9ldmVudEJ1cy5maXJlKCdlbGVtZW50VGVtcGxhdGVzLmVycm9ycycsIHtcclxuICAgIGVycm9yczogZXJyb3JzXHJcbiAgfSk7XHJcbn07IiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBpc0FueSA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJykuaXNBbnk7XHJcblxyXG52YXIgZmluZCA9IHJlcXVpcmUoJ2xvZGFzaC9maW5kJyk7XHJcblxyXG5cclxudmFyIFRFTVBMQVRFX0FUVFIgPSAnYWN0aXZpdGk6bW9kZWxlclRlbXBsYXRlJztcclxuXHJcbi8qKlxyXG4gKiBUaGUgQlBNTiAyLjAgZXh0ZW5zaW9uIGF0dHJpYnV0ZSBuYW1lIHVuZGVyXHJcbiAqIHdoaWNoIHRoZSBlbGVtZW50IHRlbXBsYXRlIGlzIHN0b3JlZC5cclxuICpcclxuICogQHR5cGUge1N0cmluZ31cclxuICovXHJcbm1vZHVsZS5leHBvcnRzLlRFTVBMQVRFX0FUVFIgPSBURU1QTEFURV9BVFRSO1xyXG5cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGVtcGxhdGUgaWQgZm9yIGEgZ2l2ZW4gZGlhZ3JhbSBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge1N0cmluZ31cclxuICovXHJcbmZ1bmN0aW9uIGdldFRlbXBsYXRlSWQoZWxlbWVudCkge1xyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgaWYgKGJvKSB7XHJcbiAgICByZXR1cm4gYm8uZ2V0KFRFTVBMQVRFX0FUVFIpO1xyXG4gIH1cclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuZ2V0VGVtcGxhdGVJZCA9IGdldFRlbXBsYXRlSWQ7XHJcblxyXG5cclxuLyoqXHJcbiAqIEdldCB0ZW1wbGF0ZSBvZiBhIGdpdmVuIGVsZW1lbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7RWxlbWVudH0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge0VsZW1lbnRUZW1wbGF0ZXN9IGVsZW1lbnRUZW1wbGF0ZXNcclxuICpcclxuICogQHJldHVybiB7VGVtcGxhdGVEZWZpbml0aW9ufVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcykge1xyXG4gIHZhciBpZCA9IGdldFRlbXBsYXRlSWQoZWxlbWVudCk7XHJcblxyXG4gIHJldHVybiBpZCAmJiBlbGVtZW50VGVtcGxhdGVzLmdldChpZCk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmdldFRlbXBsYXRlID0gZ2V0VGVtcGxhdGU7XHJcblxyXG4vKipcclxuICogR2V0IGRlZmF1bHQgdGVtcGxhdGUgZm9yIGEgZ2l2ZW4gZWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtFbGVtZW50fSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7RWxlbWVudFRlbXBsYXRlc30gZWxlbWVudFRlbXBsYXRlc1xyXG4gKlxyXG4gKiBAcmV0dXJuIHtUZW1wbGF0ZURlZmluaXRpb259XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXREZWZhdWx0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcykge1xyXG5cclxuICAvLyByZXR1cm4gZmlyc3QgZGVmYXVsdCB0ZW1wbGF0ZSwgaWYgYW55IGV4aXN0c1xyXG4gIHJldHVybiAoXHJcbiAgICBlbGVtZW50VGVtcGxhdGVzLmdldEFsbCgpLmZpbHRlcihmdW5jdGlvbih0KSB7XHJcbiAgICAgIHJldHVybiBpc0FueShlbGVtZW50LCB0LmFwcGxpZXNUbykgJiYgdC5pc0RlZmF1bHQ7XHJcbiAgICB9KVxyXG4gIClbMF07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmdldERlZmF1bHRUZW1wbGF0ZSA9IGdldERlZmF1bHRUZW1wbGF0ZTtcclxuXHJcblxyXG4vKipcclxuICogRmluZCBleHRlbnNpb24gd2l0aCBnaXZlbiB0eXBlIGluXHJcbiAqIEJQTU4gZWxlbWVudCwgZGlhZ3JhbSBlbGVtZW50IG9yIEV4dGVuc2lvbkVsZW1lbnQuXHJcbiAqXHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudHxkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fSB0aGUgZXh0ZW5zaW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBmaW5kRXh0ZW5zaW9uKGVsZW1lbnQsIHR5cGUpIHtcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgdmFyIGV4dGVuc2lvbkVsZW1lbnRzO1xyXG5cclxuICBpZiAoaXMoYm8sICdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJykpIHtcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzID0gYm87XHJcbiAgfSBlbHNlIHtcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzID0gYm8uZXh0ZW5zaW9uRWxlbWVudHM7XHJcbiAgfVxyXG5cclxuICBpZiAoIWV4dGVuc2lvbkVsZW1lbnRzKSB7XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcblxyXG4gIHJldHVybiBmaW5kKGV4dGVuc2lvbkVsZW1lbnRzLmdldCgndmFsdWVzJyksIGZ1bmN0aW9uKGUpIHtcclxuICAgIHJldHVybiBpcyhlLCB0eXBlKTtcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuZmluZEV4dGVuc2lvbiA9IGZpbmRFeHRlbnNpb247XHJcblxyXG5cclxuZnVuY3Rpb24gZmluZEV4dGVuc2lvbnMoZWxlbWVudCwgdHlwZXMpIHtcclxuICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBnZXRFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuXHJcbiAgaWYgKCFleHRlbnNpb25FbGVtZW50cykge1xyXG4gICAgcmV0dXJuIFtdO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGV4dGVuc2lvbkVsZW1lbnRzLmdldCgndmFsdWVzJykuZmlsdGVyKGZ1bmN0aW9uKGUpIHtcclxuICAgIHJldHVybiBpc0FueShlLCB0eXBlcyk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmZpbmRFeHRlbnNpb25zID0gZmluZEV4dGVuc2lvbnM7XHJcblxyXG5cclxuZnVuY3Rpb24gZmluZEFjdGl2aXRpSW5PdXQoZWxlbWVudCwgYmluZGluZykge1xyXG5cclxuICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBnZXRFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuXHJcbiAgaWYgKCFleHRlbnNpb25FbGVtZW50cykge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgdmFyIG1hdGNoZXI7XHJcblxyXG4gIGlmIChiaW5kaW5nLnR5cGUgPT09ICdhY3Rpdml0aTppbicpIHtcclxuICAgIG1hdGNoZXIgPSBmdW5jdGlvbihlKSB7XHJcbiAgICAgIHJldHVybiBpcyhlLCAnYWN0aXZpdGk6SW4nKSAmJiBpc0luT3V0KGUsIGJpbmRpbmcpO1xyXG4gICAgfTtcclxuICB9IGVsc2VcclxuICBpZiAoYmluZGluZy50eXBlID09PSAnYWN0aXZpdGk6b3V0Jykge1xyXG4gICAgbWF0Y2hlciA9IGZ1bmN0aW9uKGUpIHtcclxuICAgICAgcmV0dXJuIGlzKGUsICdhY3Rpdml0aTpPdXQnKSAmJiBpc0luT3V0KGUsIGJpbmRpbmcpO1xyXG4gICAgfTtcclxuICB9IGVsc2VcclxuICBpZiAoYmluZGluZy50eXBlID09PSAnYWN0aXZpdGk6aW46YnVzaW5lc3NLZXknKSB7XHJcbiAgICBtYXRjaGVyID0gZnVuY3Rpb24oZSkge1xyXG4gICAgICByZXR1cm4gaXMoZSwgJ2FjdGl2aXRpOkluJykgJiYgJ2J1c2luZXNzS2V5JyBpbiBlO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHJldHVybiBmaW5kKGV4dGVuc2lvbkVsZW1lbnRzLmdldCgndmFsdWVzJyksIG1hdGNoZXIpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5maW5kQWN0aXZpdGlJbk91dCA9IGZpbmRBY3Rpdml0aUluT3V0O1xyXG5cclxuZnVuY3Rpb24gZmluZEFjdGl2aXRpUHJvcGVydHkoYWN0aXZpdGlQcm9wZXJ0aWVzLCBiaW5kaW5nKSB7XHJcbiAgcmV0dXJuIGZpbmQoYWN0aXZpdGlQcm9wZXJ0aWVzLmdldCgndmFsdWVzJyksIGZ1bmN0aW9uKHApIHtcclxuICAgIHJldHVybiBwLm5hbWUgPT09IGJpbmRpbmcubmFtZTtcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuZmluZEFjdGl2aXRpUHJvcGVydHkgPSBmaW5kQWN0aXZpdGlQcm9wZXJ0eTtcclxuXHJcblxyXG5mdW5jdGlvbiBmaW5kSW5wdXRQYXJhbWV0ZXIoaW5wdXRPdXRwdXQsIGJpbmRpbmcpIHtcclxuICB2YXIgcGFyYW1ldGVycyA9IGlucHV0T3V0cHV0LmdldCgnaW5wdXRQYXJhbWV0ZXJzJyk7XHJcblxyXG4gIHJldHVybiBmaW5kKHBhcmFtZXRlcnMsIGZ1bmN0aW9uKHApIHtcclxuICAgIHJldHVybiBwLm5hbWUgPT09IGJpbmRpbmcubmFtZTtcclxuICB9KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMuZmluZElucHV0UGFyYW1ldGVyID0gZmluZElucHV0UGFyYW1ldGVyO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGZpbmRPdXRwdXRQYXJhbWV0ZXIoaW5wdXRPdXRwdXQsIGJpbmRpbmcpIHtcclxuICB2YXIgcGFyYW1ldGVycyA9IGlucHV0T3V0cHV0LmdldCgnb3V0cHV0UGFyYW1ldGVycycpO1xyXG5cclxuICByZXR1cm4gZmluZChwYXJhbWV0ZXJzLCBmdW5jdGlvbihwKSB7XHJcbiAgICB2YXIgdmFsdWUgPSBwLnZhbHVlO1xyXG5cclxuICAgIGlmICghYmluZGluZy5zY3JpcHRGb3JtYXQpIHtcclxuICAgICAgcmV0dXJuIHZhbHVlID09PSBiaW5kaW5nLnNvdXJjZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZGVmaW5pdGlvbiA9IHAuZGVmaW5pdGlvbjtcclxuXHJcbiAgICBpZiAoIWRlZmluaXRpb24gfHwgYmluZGluZy5zY3JpcHRGb3JtYXQgIT09IGRlZmluaXRpb24uc2NyaXB0Rm9ybWF0KSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZGVmaW5pdGlvbi52YWx1ZSA9PT0gYmluZGluZy5zb3VyY2U7XHJcbiAgfSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLmZpbmRPdXRwdXRQYXJhbWV0ZXIgPSBmaW5kT3V0cHV0UGFyYW1ldGVyO1xyXG5cclxuXHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuZnVuY3Rpb24gZ2V0RXh0ZW5zaW9uRWxlbWVudHMoZWxlbWVudCkge1xyXG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoaXMoYm8sICdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJykpIHtcclxuICAgIHJldHVybiBibztcclxuICB9IGVsc2Uge1xyXG4gICAgcmV0dXJuIGJvLmV4dGVuc2lvbkVsZW1lbnRzO1xyXG4gIH1cclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIGlzSW5PdXQoZWxlbWVudCwgYmluZGluZykge1xyXG5cclxuICBpZiAoYmluZGluZy50eXBlID09PSAnYWN0aXZpdGk6aW4nKSB7XHJcbiAgICAvLyBmaW5kIGJhc2VkIG9uIHRhcmdldCBhdHRyaWJ1dGVcclxuICAgIGlmIChiaW5kaW5nLnRhcmdldCkge1xyXG4gICAgICByZXR1cm4gZWxlbWVudC50YXJnZXQgPT09IGJpbmRpbmcudGFyZ2V0O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKGJpbmRpbmcudHlwZSA9PT0gJ2FjdGl2aXRpOm91dCcpIHtcclxuICAgIC8vIGZpbmQgYmFzZWQgb24gc291cmNlIC8gc291cmNlRXhwcmVzc2lvblxyXG4gICAgaWYgKGJpbmRpbmcuc291cmNlKSB7XHJcbiAgICAgIHJldHVybiBlbGVtZW50LnNvdXJjZSA9PT0gYmluZGluZy5zb3VyY2U7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGJpbmRpbmcuc291cmNlRXhwcmVzc2lvbikge1xyXG4gICAgICByZXR1cm4gZWxlbWVudC5zb3VyY2VFeHByZXNzaW9uID09PSBiaW5kaW5nLnNvdXJjZUV4cHJlc3Npb247XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBmaW5kIGJhc2VkIHZhcmlhYmxlcyAvIGxvY2FsIGNvbWJpbmF0aW9uXHJcbiAgaWYgKGJpbmRpbmcudmFyaWFibGVzKSB7XHJcbiAgICByZXR1cm4gZWxlbWVudC52YXJpYWJsZXMgPT09ICdhbGwnICYmIChcclxuICAgICAgYmluZGluZy52YXJpYWJsZXMgIT09ICdsb2NhbCcgfHwgZWxlbWVudC5sb2NhbFxyXG4gICAgKTtcclxuICB9XHJcbn1cclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzQXJyYXkgPSByZXF1aXJlKCdsb2Rhc2gvaXNBcnJheScpO1xyXG52YXIgaXNPYmplY3QgPSByZXF1aXJlKCdsb2Rhc2gvaXNPYmplY3QnKTtcclxuXHJcbnZhciBEUk9QRE9XTl9UWVBFID0gJ0Ryb3Bkb3duJztcclxuXHJcbnZhciBWQUxJRF9UWVBFUyA9IFsgJ1N0cmluZycsICdUZXh0JywgJ0Jvb2xlYW4nLCAnSGlkZGVuJywgRFJPUERPV05fVFlQRSBdO1xyXG5cclxudmFyIFBST1BFUlRZX1RZUEUgPSAncHJvcGVydHknLFxyXG4gICAgQUNUSVZJVElfUFJPUEVSVFlfVFlQRSA9ICdhY3Rpdml0aTpwcm9wZXJ0eScsXHJcbiAgICBBQ1RJVklUSV9JTlBVVF9QQVJBTUVURVJfVFlQRSA9ICdhY3Rpdml0aTppbnB1dFBhcmFtZXRlcicsXHJcbiAgICBBQ1RJVklUSV9PVVRQVVRfUEFSQU1FVEVSX1RZUEUgPSAnYWN0aXZpdGk6b3V0cHV0UGFyYW1ldGVyJyxcclxuICAgIEFDVElWSVRJX0lOX1RZUEUgPSAnYWN0aXZpdGk6aW4nLFxyXG4gICAgQUNUSVZJVElfT1VUX1RZUEUgPSAnYWN0aXZpdGk6b3V0JyxcclxuICAgIEFDVElWSVRJX0lOX0JVU0lORVNTX0tFWV9UWVBFID0gJ2FjdGl2aXRpOmluOmJ1c2luZXNzS2V5JyxcclxuICAgIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUiA9ICdhY3Rpdml0aTpleGVjdXRpb25MaXN0ZW5lcicsXHJcbiAgICBBQ1RJVklUSV9GSUVMRCA9ICdhY3Rpdml0aTpmaWVsZCc7XHJcblxyXG52YXIgVkFMSURfQklORElOR19UWVBFUyA9IFtcclxuICBQUk9QRVJUWV9UWVBFLFxyXG4gIEFDVElWSVRJX1BST1BFUlRZX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5QVVRfUEFSQU1FVEVSX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUUFVUX1BBUkFNRVRFUl9UWVBFLFxyXG4gIEFDVElWSVRJX0lOX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5fQlVTSU5FU1NfS0VZX1RZUEUsXHJcbiAgQUNUSVZJVElfRVhFQ1VUSU9OX0xJU1RFTkVSLFxyXG4gIEFDVElWSVRJX0ZJRUxEXHJcbl07XHJcblxyXG5cclxuLyoqXHJcbiAqIEEgZWxlbWVudCB0ZW1wbGF0ZSB2YWxpZGF0b3IuXHJcbiAqL1xyXG5mdW5jdGlvbiBWYWxpZGF0b3IoKSB7XHJcblxyXG4gIHRoaXMuX3RlbXBsYXRlc0J5SWQgPSB7fTtcclxuXHJcbiAgdGhpcy5fdmFsaWRUZW1wbGF0ZXMgPSBbXTtcclxuICB0aGlzLl9lcnJvcnMgPSBbXTtcclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZHMgdGhlIHRlbXBsYXRlcy5cclxuICAgKlxyXG4gICAqIEBwYXJhbSB7QXJyYXk8VGVtcGxhdGVEZXNjcmlwdG9yPn0gdGVtcGxhdGVzXHJcbiAgICpcclxuICAgKiBAcmV0dXJuIHtWYWxpZGF0b3J9IHNlbGZcclxuICAgKi9cclxuICB0aGlzLmFkZEFsbCA9IGZ1bmN0aW9uKHRlbXBsYXRlcykge1xyXG5cclxuICAgIGlmICghaXNBcnJheSh0ZW1wbGF0ZXMpKSB7XHJcbiAgICAgIHRoaXMuX2xvZ0Vycm9yKCd0ZW1wbGF0ZXMgbXVzdCBiZSBbXScpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGVtcGxhdGVzLmZvckVhY2godGhpcy5hZGQsIHRoaXMpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZCB0aGUgZ2l2ZW4gZWxlbWVudCB0ZW1wbGF0ZSwgaWYgaXQgaXMgdmFsaWQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge1RlbXBsYXRlRGVzY3JpcHRvcn0gdGVtcGxhdGVcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge1ZhbGlkYXRvcn0gc2VsZlxyXG4gICAqL1xyXG4gIHRoaXMuYWRkID0gZnVuY3Rpb24odGVtcGxhdGUpIHtcclxuXHJcbiAgICB2YXIgZXJyID0gdGhpcy5fdmFsaWRhdGVUZW1wbGF0ZSh0ZW1wbGF0ZSk7XHJcblxyXG4gICAgaWYgKCFlcnIpIHtcclxuICAgICAgdGhpcy5fdGVtcGxhdGVzQnlJZFt0ZW1wbGF0ZS5pZF0gPSB0ZW1wbGF0ZTtcclxuXHJcbiAgICAgIHRoaXMuX3ZhbGlkVGVtcGxhdGVzLnB1c2godGVtcGxhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFZhbGlkYXRlIGdpdmVuIHRlbXBsYXRlIGFuZCByZXR1cm4gZXJyb3IgKGlmIGFueSkuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge1RlbXBsYXRlRGVzY3JpcHRvcn0gdGVtcGxhdGVcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge0Vycm9yfSB2YWxpZGF0aW9uIGVycm9yLCBpZiBhbnlcclxuICAgKi9cclxuICB0aGlzLl92YWxpZGF0ZVRlbXBsYXRlID0gZnVuY3Rpb24odGVtcGxhdGUpIHtcclxuXHJcbiAgICB2YXIgZXJyLFxyXG4gICAgICAgIGlkID0gdGVtcGxhdGUuaWQsXHJcbiAgICAgICAgYXBwbGllc1RvID0gdGVtcGxhdGUuYXBwbGllc1RvLFxyXG4gICAgICAgIHByb3BlcnRpZXMgPSB0ZW1wbGF0ZS5wcm9wZXJ0aWVzLFxyXG4gICAgICAgIHNjb3BlcyA9IHRlbXBsYXRlLnNjb3BlcztcclxuXHJcbiAgICBpZiAoIWlkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9sb2dFcnJvcignbWlzc2luZyB0ZW1wbGF0ZSBpZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChpZCBpbiB0aGlzLl90ZW1wbGF0ZXNCeUlkKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9sb2dFcnJvcigndGVtcGxhdGUgaWQgPCcgKyBpZCArICc+IGFscmVhZHkgdXNlZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghaXNBcnJheShhcHBsaWVzVG8pKSB7XHJcbiAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKCdtaXNzaW5nIGFwcGxpZXNUbz1bXScsIHRlbXBsYXRlKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWlzQXJyYXkocHJvcGVydGllcykpIHtcclxuICAgICAgZXJyID0gdGhpcy5fbG9nRXJyb3IoJ21pc3NpbmcgcHJvcGVydGllcz1bXScsIHRlbXBsYXRlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmICghdGhpcy5fdmFsaWRhdGVQcm9wZXJ0aWVzKHByb3BlcnRpZXMpKSB7XHJcbiAgICAgICAgZXJyID0gbmV3IEVycm9yKCdpbnZhbGlkIHByb3BlcnRpZXMnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChzY29wZXMpIHtcclxuICAgICAgZXJyID0gdGhpcy5fdmFsaWRhdGVTY29wZXModGVtcGxhdGUsIHNjb3Blcyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVycjtcclxuICB9O1xyXG5cclxuICB0aGlzLl92YWxpZGF0ZVNjb3BlcyA9IGZ1bmN0aW9uKHRlbXBsYXRlLCBzY29wZXMpIHtcclxuXHJcbiAgICB2YXIgZXJyLFxyXG4gICAgICAgIHNjb3BlLFxyXG4gICAgICAgIHNjb3BlTmFtZTtcclxuXHJcbiAgICBpZiAoIWlzT2JqZWN0KHNjb3BlcykgfHwgaXNBcnJheShzY29wZXMpKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9sb2dFcnJvcignaW52YWxpZCBzY29wZXMsIHNob3VsZCBiZSBzY29wZXM9e30nLCB0ZW1wbGF0ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yIChzY29wZU5hbWUgaW4gc2NvcGVzKSB7XHJcbiAgICAgIHNjb3BlID0gc2NvcGVzW3Njb3BlTmFtZV07XHJcblxyXG4gICAgICBpZiAoIWlzT2JqZWN0KHNjb3BlKSB8fCBpc0FycmF5KHNjb3BlKSkge1xyXG4gICAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKCdpbnZhbGlkIHNjb3BlLCBzaG91bGQgYmUgc2NvcGU9e30nLCB0ZW1wbGF0ZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghaXNBcnJheShzY29wZS5wcm9wZXJ0aWVzKSkge1xyXG4gICAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKFxyXG4gICAgICAgICAgJ21pc3NpbmcgcHJvcGVydGllcz1bXSBpbiBzY29wZSA8JyArIHNjb3BlTmFtZSArICc+JywgdGVtcGxhdGVcclxuICAgICAgICApO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICghdGhpcy5fdmFsaWRhdGVQcm9wZXJ0aWVzKHNjb3BlLnByb3BlcnRpZXMpKSB7XHJcbiAgICAgICAgICBlcnIgPSBuZXcgRXJyb3IoJ2ludmFsaWQgcHJvcGVydGllcyBpbiBzY29wZSA8JyArIHNjb3BlTmFtZSArICc+Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGVycjtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0ZSBwcm9wZXJ0aWVzIGFuZCByZXR1cm4gZmFsc2UgaWYgYW55IGlzIGludmFsaWQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge0FycmF5PFByb3BlcnR5RGVzY3JpcHRvcj59IHByb3BlcnRpZXNcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgYWxsIHByb3BlcnRpZXMgYXJlIHZhbGlkXHJcbiAgICovXHJcbiAgdGhpcy5fdmFsaWRhdGVQcm9wZXJ0aWVzID0gZnVuY3Rpb24ocHJvcGVydGllcykge1xyXG4gICAgdmFyIHZhbGlkUHJvcGVydGllcyA9IHByb3BlcnRpZXMuZmlsdGVyKHRoaXMuX3ZhbGlkYXRlUHJvcGVydHksIHRoaXMpO1xyXG5cclxuICAgIHJldHVybiBwcm9wZXJ0aWVzLmxlbmd0aCA9PT0gdmFsaWRQcm9wZXJ0aWVzLmxlbmd0aDtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0ZSBwcm9wZXJ0eSBhbmQgcmV0dXJuIGZhbHNlLCBpZiB0aGVyZSB3YXNcclxuICAgKiBhIHZhbGlkYXRpb24gZXJyb3IuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICAgKlxyXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59IHRydWUgaWYgcHJvcGVydHkgaXMgdmFsaWRcclxuICAgKi9cclxuICB0aGlzLl92YWxpZGF0ZVByb3BlcnR5ID0gZnVuY3Rpb24ocHJvcGVydHkpIHtcclxuXHJcbiAgICB2YXIgdHlwZSA9IHByb3BlcnR5LnR5cGUsXHJcbiAgICAgICAgYmluZGluZyA9IHByb3BlcnR5LmJpbmRpbmc7XHJcblxyXG4gICAgdmFyIGVycjtcclxuXHJcbiAgICB2YXIgYmluZGluZ1R5cGUgPSBiaW5kaW5nLnR5cGU7XHJcblxyXG4gICAgaWYgKFZBTElEX1RZUEVTLmluZGV4T2YodHlwZSkgPT09IC0xKSB7XHJcbiAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKFxyXG4gICAgICAgICdpbnZhbGlkIHByb3BlcnR5IHR5cGUgPCcgKyB0eXBlICsgJz47ICcgK1xyXG4gICAgICAgICdtdXN0IGJlIGFueSBvZiB7ICcgKyBWQUxJRF9UWVBFUy5qb2luKCcsICcpICsgJyB9J1xyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSBEUk9QRE9XTl9UWVBFICYmIGJpbmRpbmdUeXBlICE9PSBBQ1RJVklUSV9FWEVDVVRJT05fTElTVEVORVIpIHtcclxuICAgICAgaWYgKCFpc0FycmF5KHByb3BlcnR5LmNob2ljZXMpKSB7XHJcbiAgICAgICAgZXJyID0gdGhpcy5fbG9nRXJyb3IoXHJcbiAgICAgICAgICAnbXVzdCBwcm92aWRlIGNob2ljZXM9W10gd2l0aCAnICsgRFJPUERPV05fVFlQRSArICcgdHlwZSdcclxuICAgICAgICApO1xyXG4gICAgICB9IGVsc2VcclxuXHJcbiAgICAgIGlmICghcHJvcGVydHkuY2hvaWNlcy5ldmVyeShpc0Ryb3Bkb3duQ2hvaWNlVmFsaWQpKSB7XHJcbiAgICAgICAgZXJyID0gdGhpcy5fbG9nRXJyb3IoXHJcbiAgICAgICAgICAneyBuYW1lLCB2YWx1ZSB9IG11c3QgYmUgc3BlY2lmaWVkIGZvciAnICtcclxuICAgICAgICAgIERST1BET1dOX1RZUEUgKyAnIGNob2ljZXMnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICghYmluZGluZykge1xyXG4gICAgICByZXR1cm4gdGhpcy5fbG9nRXJyb3IoJ3Byb3BlcnR5IG1pc3NpbmcgYmluZGluZycpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChWQUxJRF9CSU5ESU5HX1RZUEVTLmluZGV4T2YoYmluZGluZ1R5cGUpID09PSAtMSkge1xyXG4gICAgICBlcnIgPSB0aGlzLl9sb2dFcnJvcihcclxuICAgICAgICAnaW52YWxpZCBwcm9wZXJ0eS5iaW5kaW5nIHR5cGUgPCcgKyBiaW5kaW5nVHlwZSArICc+OyAnICtcclxuICAgICAgICAnbXVzdCBiZSBhbnkgb2YgeyAnICsgVkFMSURfQklORElOR19UWVBFUy5qb2luKCcsICcpICsgJyB9J1xyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChiaW5kaW5nVHlwZSA9PT0gUFJPUEVSVFlfVFlQRSB8fFxyXG4gICAgICAgIGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9QUk9QRVJUWV9UWVBFIHx8XHJcbiAgICAgICAgYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX0lOUFVUX1BBUkFNRVRFUl9UWVBFIHx8XHJcbiAgICAgICAgYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX0ZJRUxEKSB7XHJcblxyXG4gICAgICBpZiAoIWJpbmRpbmcubmFtZSkge1xyXG4gICAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKFxyXG4gICAgICAgICAgJ3Byb3BlcnR5LmJpbmRpbmcgPCcgKyBiaW5kaW5nVHlwZSArICc+IHJlcXVpcmVzIG5hbWUnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfT1VUUFVUX1BBUkFNRVRFUl9UWVBFKSB7XHJcbiAgICAgIGlmICghYmluZGluZy5zb3VyY2UpIHtcclxuICAgICAgICBlcnIgPSB0aGlzLl9sb2dFcnJvcihcclxuICAgICAgICAgICdwcm9wZXJ0eS5iaW5kaW5nIDwnICsgYmluZGluZ1R5cGUgKyAnPiByZXF1aXJlcyBzb3VyY2UnXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfSU5fVFlQRSkge1xyXG5cclxuICAgICAgaWYgKCFiaW5kaW5nLnZhcmlhYmxlcyAmJiAhYmluZGluZy50YXJnZXQpIHtcclxuICAgICAgICBlcnIgPSB0aGlzLl9sb2dFcnJvcihcclxuICAgICAgICAgICdwcm9wZXJ0eS5iaW5kaW5nIDwnICsgYmluZGluZ1R5cGUgKyAnPiByZXF1aXJlcyAnICtcclxuICAgICAgICAgICd2YXJpYWJsZXMgb3IgdGFyZ2V0J1xyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX09VVF9UWVBFKSB7XHJcblxyXG4gICAgICBpZiAoIWJpbmRpbmcudmFyaWFibGVzICYmICFiaW5kaW5nLnNvdXJjZSAmJiAhYmluZGluZy5zb3VyY2VFeHByZXNzaW9uKSB7XHJcbiAgICAgICAgZXJyID0gdGhpcy5fbG9nRXJyb3IoXHJcbiAgICAgICAgICAncHJvcGVydHkuYmluZGluZyA8JyArIGJpbmRpbmdUeXBlICsgJz4gcmVxdWlyZXMgJyArXHJcbiAgICAgICAgICAndmFyaWFibGVzLCBzb3VyY2VFeHByZXNzaW9uIG9yIHNvdXJjZSdcclxuICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9FWEVDVVRJT05fTElTVEVORVIpIHtcclxuXHJcbiAgICAgIGlmICh0eXBlICE9PSAnSGlkZGVuJykge1xyXG4gICAgICAgIGVyciA9IHRoaXMuX2xvZ0Vycm9yKFxyXG4gICAgICAgICAgJ2ludmFsaWQgcHJvcGVydHkgdHlwZSA8JyArIHR5cGUgKyAnPiBmb3IgJyArIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUiArICc7ICcgK1xyXG4gICAgICAgICAgJ211c3QgYmUgPEhpZGRlbj4nXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAhZXJyO1xyXG4gIH07XHJcblxyXG5cclxuICB0aGlzLl9sb2dFcnJvciA9IGZ1bmN0aW9uKGVyciwgdGVtcGxhdGUpIHtcclxuXHJcbiAgICBpZiAodHlwZW9mIGVyciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgaWYgKHRlbXBsYXRlKSB7XHJcbiAgICAgICAgZXJyID0gJ3RlbXBsYXRlKGlkOiAnICsgdGVtcGxhdGUuaWQgKyAnKSAnICsgZXJyO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBlcnIgPSBuZXcgRXJyb3IoZXJyKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9lcnJvcnMucHVzaChlcnIpO1xyXG5cclxuICAgIHJldHVybiBlcnI7XHJcbiAgfTtcclxuXHJcbiAgdGhpcy5nZXRFcnJvcnMgPSBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiB0aGlzLl9lcnJvcnM7XHJcbiAgfTtcclxuXHJcbiAgdGhpcy5nZXRWYWxpZFRlbXBsYXRlcyA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX3ZhbGlkVGVtcGxhdGVzO1xyXG4gIH07XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gVmFsaWRhdG9yO1xyXG5cclxuXHJcbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIGlzRHJvcGRvd25DaG9pY2VWYWxpZChjKSB7XHJcbiAgcmV0dXJuICduYW1lJyBpbiBjICYmICd2YWx1ZScgaW4gYztcclxufVxyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZmluZEV4dGVuc2lvbiA9IHJlcXVpcmUoJy4uL0hlbHBlcicpLmZpbmRFeHRlbnNpb24sXHJcbiAgICBmaW5kRXh0ZW5zaW9ucyA9IHJlcXVpcmUoJy4uL0hlbHBlcicpLmZpbmRFeHRlbnNpb25zO1xyXG5cclxudmFyIGNyZWF0ZUFjdGl2aXRpUHJvcGVydHkgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aVByb3BlcnR5LFxyXG4gICAgY3JlYXRlSW5wdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVJbnB1dFBhcmFtZXRlcixcclxuICAgIGNyZWF0ZU91dHB1dFBhcmFtZXRlciA9IHJlcXVpcmUoJy4uL0NyZWF0ZUhlbHBlcicpLmNyZWF0ZU91dHB1dFBhcmFtZXRlcixcclxuICAgIGNyZWF0ZUFjdGl2aXRpSW4gPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aUluLFxyXG4gICAgY3JlYXRlQWN0aXZpdGlPdXQgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aU91dCxcclxuICAgIGNyZWF0ZUFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5LFxyXG4gICAgY3JlYXRlQWN0aXZpdGlFeGVjdXRpb25MaXN0ZW5lclNjcmlwdCA9IHJlcXVpcmUoJy4uL0NyZWF0ZUhlbHBlcicpLmNyZWF0ZUFjdGl2aXRpRXhlY3V0aW9uTGlzdGVuZXJTY3JpcHQsXHJcbiAgICBjcmVhdGVBY3Rpdml0aUZpZWxkSW5qZWN0aW9uID0gcmVxdWlyZSgnLi4vQ3JlYXRlSGVscGVyJykuY3JlYXRlQWN0aXZpdGlGaWVsZEluamVjdGlvbjtcclxuXHJcbnZhciBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKTtcclxuXHJcbnZhciBBQ1RJVklUSV9TRVJWSUNFX1RBU0tfTElLRSA9IFtcclxuICAnYWN0aXZpdGk6Y2xhc3MnLFxyXG4gICdhY3Rpdml0aTpkZWxlZ2F0ZUV4cHJlc3Npb24nLFxyXG4gICdhY3Rpdml0aTpleHByZXNzaW9uJ1xyXG5dO1xyXG5cclxuLyoqXHJcbiAqIEEgaGFuZGxlciB0aGF0IGNoYW5nZXMgdGhlIG1vZGVsaW5nIHRlbXBsYXRlIG9mIGEgQlBNTiBlbGVtZW50LlxyXG4gKi9cclxuZnVuY3Rpb24gQ2hhbmdlRWxlbWVudFRlbXBsYXRlSGFuZGxlcihtb2RlbGluZywgY29tbWFuZFN0YWNrLCBicG1uRmFjdG9yeSkge1xyXG5cclxuICBmdW5jdGlvbiBnZXRPckNyZWF0ZUV4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQpIHtcclxuXHJcbiAgICB2YXIgYm8gPSBlbGVtZW50LmJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICAgIHZhciBleHRlbnNpb25FbGVtZW50cyA9IGJvLmV4dGVuc2lvbkVsZW1lbnRzO1xyXG5cclxuICAgIC8vIGFkZCBleHRlbnNpb24gZWxlbWVudHNcclxuICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBicG1uRmFjdG9yeS5jcmVhdGUoJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnLCB7XHJcbiAgICAgICAgdmFsdWVzOiBbXVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwge1xyXG4gICAgICAgIGV4dGVuc2lvbkVsZW1lbnRzOiBleHRlbnNpb25FbGVtZW50c1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZXh0ZW5zaW9uRWxlbWVudHM7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiB1cGRhdGVNb2RlbGVyVGVtcGxhdGUoZWxlbWVudCwgbmV3VGVtcGxhdGUpIHtcclxuICAgIG1vZGVsaW5nLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwge1xyXG4gICAgICAnYWN0aXZpdGk6bW9kZWxlclRlbXBsYXRlJzogbmV3VGVtcGxhdGUgJiYgbmV3VGVtcGxhdGUuaWRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlSW9NYXBwaW5ncyhlbGVtZW50LCBuZXdUZW1wbGF0ZSwgY29udGV4dCkge1xyXG5cclxuICAgIHZhciBuZXdNYXBwaW5ncyA9IGNyZWF0ZUlucHV0T3V0cHV0TWFwcGluZ3MobmV3VGVtcGxhdGUsIGJwbW5GYWN0b3J5KSxcclxuICAgICAgICBvbGRNYXBwaW5ncztcclxuXHJcbiAgICBpZiAoIW5ld01hcHBpbmdzKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29udGV4dCkge1xyXG4gICAgICBjb21tYW5kU3RhY2suZXhlY3V0ZSgncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBidXNpbmVzc09iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0aWVzOiB7IGlucHV0T3V0cHV0OiBuZXdNYXBwaW5ncyB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29udGV4dCA9IGdldE9yQ3JlYXRlRXh0ZW5zaW9uRWxlbWVudHMoZWxlbWVudCk7XHJcbiAgICAgIG9sZE1hcHBpbmdzID0gZmluZEV4dGVuc2lvbihlbGVtZW50LCAnYWN0aXZpdGk6SW5wdXRPdXRwdXQnKTtcclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0LWxpc3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBjdXJyZW50T2JqZWN0OiBjb250ZXh0LFxyXG4gICAgICAgIHByb3BlcnR5TmFtZTogJ3ZhbHVlcycsXHJcbiAgICAgICAgb2JqZWN0c1RvQWRkOiBbIG5ld01hcHBpbmdzIF0sXHJcbiAgICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvbGRNYXBwaW5ncyA/IFsgb2xkTWFwcGluZ3MgXSA6IFtdXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlQWN0aXZpdGlGaWVsZChlbGVtZW50LCBuZXdUZW1wbGF0ZSwgY29udGV4dCkge1xyXG5cclxuICAgIHZhciBuZXdNYXBwaW5ncyA9IGNyZWF0ZUFjdGl2aXRpRmllbGRJbmplY3Rpb25zKG5ld1RlbXBsYXRlLCBicG1uRmFjdG9yeSksXHJcbiAgICAgICAgb2xkTWFwcGluZ3M7XHJcblxyXG4gICAgaWYgKCFuZXdNYXBwaW5ncykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAoY29udGV4dCkge1xyXG4gICAgICBjb21tYW5kU3RhY2suZXhlY3V0ZSgncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBidXNpbmVzc09iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0aWVzOiB7IGZpZWxkOiBuZXdNYXBwaW5ncyB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29udGV4dCA9IGdldE9yQ3JlYXRlRXh0ZW5zaW9uRWxlbWVudHMoZWxlbWVudCk7XHJcbiAgICAgIG9sZE1hcHBpbmdzID0gZmluZEV4dGVuc2lvbnMoZWxlbWVudCwgWydhY3Rpdml0aTpGaWVsZCddKTtcclxuXHJcbiAgICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKCdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgY3VycmVudE9iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0eU5hbWU6ICd2YWx1ZXMnLFxyXG4gICAgICAgIG9iamVjdHNUb0FkZDogbmV3TWFwcGluZ3MsXHJcbiAgICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvbGRNYXBwaW5ncyA/IG9sZE1hcHBpbmdzIDogW11cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlQWN0aXZpdGlQcm9wZXJ0aWVzKGVsZW1lbnQsIG5ld1RlbXBsYXRlLCBjb250ZXh0KSB7XHJcblxyXG4gICAgdmFyIG5ld1Byb3BlcnRpZXMgPSBjcmVhdGVBY3Rpdml0aVByb3BlcnRpZXMobmV3VGVtcGxhdGUsIGJwbW5GYWN0b3J5KSxcclxuICAgICAgICBvbGRQcm9wZXJ0aWVzO1xyXG5cclxuICAgIGlmICghbmV3UHJvcGVydGllcykge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGNvbnRleHQpIHtcclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgYnVzaW5lc3NPYmplY3Q6IGNvbnRleHQsXHJcbiAgICAgICAgcHJvcGVydGllczogeyBwcm9wZXJ0aWVzOiBuZXdQcm9wZXJ0aWVzIH1cclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0ID0gZ2V0T3JDcmVhdGVFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuICAgICAgb2xkUHJvcGVydGllcyA9IGZpbmRFeHRlbnNpb24oZWxlbWVudCwgJ2FjdGl2aXRpOlByb3BlcnRpZXMnKTtcclxuXHJcbiAgICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKCdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgY3VycmVudE9iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0eU5hbWU6ICd2YWx1ZXMnLFxyXG4gICAgICAgIG9iamVjdHNUb0FkZDogWyBuZXdQcm9wZXJ0aWVzIF0sXHJcbiAgICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvbGRQcm9wZXJ0aWVzID8gWyBvbGRQcm9wZXJ0aWVzIF0gOiBbXVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIHVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgbmV3VGVtcGxhdGUsIGNvbnRleHQpIHtcclxuXHJcbiAgICB2YXIgbmV3UHJvcGVydGllcyA9IGNyZWF0ZUJwbW5Qcm9wZXJ0eVVwZGF0ZXMobmV3VGVtcGxhdGUsIGJwbW5GYWN0b3J5KTtcclxuXHJcbiAgICB2YXIgbmV3UHJvcGVydGllc0NvdW50ID0gT2JqZWN0LmtleXMobmV3UHJvcGVydGllcykubGVuZ3RoO1xyXG5cclxuICAgIGlmICghbmV3UHJvcGVydGllc0NvdW50KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29udGV4dCkge1xyXG4gICAgICBjb21tYW5kU3RhY2suZXhlY3V0ZSgncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBidXNpbmVzc09iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0aWVzOiBuZXdQcm9wZXJ0aWVzXHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbW9kZWxpbmcudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBuZXdQcm9wZXJ0aWVzKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIHVwZGF0ZUluT3V0KGVsZW1lbnQsIG5ld1RlbXBsYXRlLCBjb250ZXh0KSB7XHJcblxyXG4gICAgdmFyIG5ld0luT3V0ID0gY3JlYXRlQWN0aXZpdGlJbk91dChuZXdUZW1wbGF0ZSwgYnBtbkZhY3RvcnkpLFxyXG4gICAgICAgIG9sZEluT3V0O1xyXG5cclxuICAgIGlmICghbmV3SW5PdXQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChjb250ZXh0KSB7XHJcbiAgICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKCdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdCcsIHtcclxuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0OiBjb250ZXh0LFxyXG4gICAgICAgIHByb3BlcnRpZXM6IHsgaW5vdXQ6IG5ld0luT3V0IH1cclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0ID0gZ2V0T3JDcmVhdGVFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuICAgICAgb2xkSW5PdXQgPSBmaW5kRXh0ZW5zaW9ucyhjb250ZXh0LCBbICdhY3Rpdml0aTpJbicsICdhY3Rpdml0aTpPdXQnIF0pO1xyXG5cclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0LWxpc3QnLCB7XHJcbiAgICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgICBjdXJyZW50T2JqZWN0OiBjb250ZXh0LFxyXG4gICAgICAgIHByb3BlcnR5TmFtZTogJ3ZhbHVlcycsXHJcbiAgICAgICAgb2JqZWN0c1RvQWRkOiBuZXdJbk91dCxcclxuICAgICAgICBvYmplY3RzVG9SZW1vdmU6IG9sZEluT3V0XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdXBkYXRlRXhlY3V0aW9uTGlzdGVuZXIoZWxlbWVudCwgbmV3VGVtcGxhdGUsIGNvbnRleHQpIHtcclxuXHJcbiAgICB2YXIgbmV3RXhlY3V0aW9uTGlzdGVuZXJzID0gY3JlYXRlQWN0aXZpdGlFeGVjdXRpb25MaXN0ZW5lcnMobmV3VGVtcGxhdGUsIGJwbW5GYWN0b3J5KSxcclxuICAgICAgICBvbGRFeGVjdXRpb25zTGlzdGVuZXJzO1xyXG5cclxuICAgIGlmICghbmV3RXhlY3V0aW9uTGlzdGVuZXJzLmxlbmd0aCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGNvbnRleHQpIHtcclxuICAgICAgY29tbWFuZFN0YWNrLmV4ZWN1dGUoJ3Byb3BlcnRpZXMtcGFuZWwudXBkYXRlLWJ1c2luZXNzb2JqZWN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgYnVzaW5lc3NPYmplY3Q6IGNvbnRleHQsXHJcbiAgICAgICAgcHJvcGVydGllczogeyBleGVjdXRpb25MaXN0ZW5lcjogbmV3RXhlY3V0aW9uTGlzdGVuZXJzIH1cclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjb250ZXh0ID0gZ2V0T3JDcmVhdGVFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuICAgICAgb2xkRXhlY3V0aW9uc0xpc3RlbmVycyA9IGZpbmRFeHRlbnNpb25zKGNvbnRleHQsIFsgJ2FjdGl2aXRpOkV4ZWN1dGlvbkxpc3RlbmVyJyBdKTtcclxuXHJcbiAgICAgIGNvbW1hbmRTdGFjay5leGVjdXRlKCdwcm9wZXJ0aWVzLXBhbmVsLnVwZGF0ZS1idXNpbmVzc29iamVjdC1saXN0Jywge1xyXG4gICAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgICAgY3VycmVudE9iamVjdDogY29udGV4dCxcclxuICAgICAgICBwcm9wZXJ0eU5hbWU6ICd2YWx1ZXMnLFxyXG4gICAgICAgIG9iamVjdHNUb0FkZDogbmV3RXhlY3V0aW9uTGlzdGVuZXJzLFxyXG4gICAgICAgIG9iamVjdHNUb1JlbW92ZTogb2xkRXhlY3V0aW9uc0xpc3RlbmVyc1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFVwZGF0ZSAvIHJlY3JlYXRlIGEgc2NvcGVkIGVsZW1lbnQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50IHRoZSBkaWFncmFtIHBhcmVudCBlbGVtZW50XHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHNjb3BlTmFtZSBuYW1lIG9mIHRoZSBzY29wZSwgaS5lLiBhY3Rpdml0aTpDb25uZWN0b3JcclxuICAgKiBAcGFyYW0ge09iamVjdH0gc2NvcGVEZWZpbml0aW9uXHJcbiAgICovXHJcbiAgZnVuY3Rpb24gdXBkYXRlU2NvcGVFbGVtZW50cyhlbGVtZW50LCBzY29wZU5hbWUsIHNjb3BlRGVmaW5pdGlvbikge1xyXG5cclxuICAgIHZhciBzY29wZUVsZW1lbnQgPSBicG1uRmFjdG9yeS5jcmVhdGUoc2NvcGVOYW1lKTtcclxuXHJcbiAgICAvLyB1cGRhdGUgYWN0aXZpdGk6aW5wdXRPdXRwdXRcclxuICAgIHVwZGF0ZUlvTWFwcGluZ3MoZWxlbWVudCwgc2NvcGVEZWZpbml0aW9uLCBzY29wZUVsZW1lbnQpO1xyXG5cclxuICAgIC8vIHVwZGF0ZSBhY3Rpdml0aTpmaWVsZFxyXG4gICAgdXBkYXRlQWN0aXZpdGlGaWVsZChlbGVtZW50LCBzY29wZURlZmluaXRpb24sIHNjb3BlRWxlbWVudCk7XHJcblxyXG4gICAgLy8gdXBkYXRlIGFjdGl2aXRpOnByb3BlcnRpZXNcclxuICAgIHVwZGF0ZUFjdGl2aXRpUHJvcGVydGllcyhlbGVtZW50LCBzY29wZURlZmluaXRpb24sIHNjb3BlRWxlbWVudCk7XHJcblxyXG4gICAgLy8gdXBkYXRlIG90aGVyIHByb3BlcnRpZXMgKGJwbW46Y29uZGl0aW9uLCBhY3Rpdml0aTphc3luYywgLi4uKVxyXG4gICAgdXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBzY29wZURlZmluaXRpb24sIHNjb3BlRWxlbWVudCk7XHJcblxyXG4gICAgLy8gdXBkYXRlIGFjdGl2aXRpOmluIGFuZCBhY3Rpdml0aTpvdXRcclxuICAgIHVwZGF0ZUluT3V0KGVsZW1lbnQsIHNjb3BlRGVmaW5pdGlvbiwgc2NvcGVFbGVtZW50KTtcclxuXHJcbiAgICAvLyB1cGRhdGUgYWN0aXZpdGk6ZXhlY3V0aW9uTGlzdGVuZXJcclxuICAgIHVwZGF0ZUV4ZWN1dGlvbkxpc3RlbmVyKGVsZW1lbnQsIHNjb3BlRGVmaW5pdGlvbiwgc2NvcGVFbGVtZW50KTtcclxuXHJcbiAgICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBnZXRPckNyZWF0ZUV4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQpO1xyXG4gICAgdmFyIG9sZFNjb3BlID0gZmluZEV4dGVuc2lvbihleHRlbnNpb25FbGVtZW50cywgc2NvcGVOYW1lKTtcclxuXHJcbiAgICBjb21tYW5kU3RhY2suZXhlY3V0ZSgncHJvcGVydGllcy1wYW5lbC51cGRhdGUtYnVzaW5lc3NvYmplY3QtbGlzdCcsIHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgY3VycmVudE9iamVjdDogZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgIHByb3BlcnR5TmFtZTogJ3ZhbHVlcycsXHJcbiAgICAgIG9iamVjdHNUb0FkZDogWyBzY29wZUVsZW1lbnQgXSxcclxuICAgICAgb2JqZWN0c1RvUmVtb3ZlOiBvbGRTY29wZSA/IFsgb2xkU2NvcGUgXSA6IFtdXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbXBvc2UgYW4gZWxlbWVudCB0ZW1wbGF0ZSBjaGFuZ2UgYWN0aW9uLCB1cGRhdGluZyBhbGxcclxuICAgKiBuZWNlc3NhcnkgdW5kZXJseWluZyBwcm9wZXJ0aWVzLlxyXG4gICAqXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHRcclxuICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dC5lbGVtZW50XHJcbiAgICogQHBhcmFtIHtPYmplY3R9IGNvbnRleHQub2xkVGVtcGxhdGVcclxuICAgKiBAcGFyYW0ge09iamVjdH0gY29udGV4dC5uZXdUZW1wbGF0ZVxyXG4gICAqL1xyXG4gIHRoaXMucHJlRXhlY3V0ZSA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuXHJcbiAgICB2YXIgZWxlbWVudCA9IGNvbnRleHQuZWxlbWVudCxcclxuICAgICAgICBuZXdUZW1wbGF0ZSA9IGNvbnRleHQubmV3VGVtcGxhdGU7XHJcblxyXG4gICAgLy8gdXBkYXRlIGFjdGl2aXRpOm1vZGVsZXJUZW1wbGF0ZSBhdHRyaWJ1dGVcclxuICAgIHVwZGF0ZU1vZGVsZXJUZW1wbGF0ZShlbGVtZW50LCBuZXdUZW1wbGF0ZSk7XHJcblxyXG4gICAgaWYgKG5ld1RlbXBsYXRlKSB7XHJcblxyXG4gICAgICAvLyB1cGRhdGUgYWN0aXZpdGk6aW5wdXRPdXRwdXRcclxuICAgICAgdXBkYXRlSW9NYXBwaW5ncyhlbGVtZW50LCBuZXdUZW1wbGF0ZSk7XHJcblxyXG4gICAgICAvLyB1cGRhdGUgYWN0aXZpdGk6ZmllbGRcclxuICAgICAgdXBkYXRlQWN0aXZpdGlGaWVsZChlbGVtZW50LCBuZXdUZW1wbGF0ZSk7XHJcblxyXG4gICAgICAvLyB1cGRhdGUgYWN0aXZpdGk6cHJvcGVydGllc1xyXG4gICAgICB1cGRhdGVBY3Rpdml0aVByb3BlcnRpZXMoZWxlbWVudCwgbmV3VGVtcGxhdGUpO1xyXG5cclxuICAgICAgLy8gdXBkYXRlIG90aGVyIHByb3BlcnRpZXMgKGJwbW46Y29uZGl0aW9uLCBhY3Rpdml0aTphc3luYywgLi4uKVxyXG4gICAgICB1cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIG5ld1RlbXBsYXRlKTtcclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBhY3Rpdml0aTppbiBhbmQgYWN0aXZpdGk6b3V0XHJcbiAgICAgIHVwZGF0ZUluT3V0KGVsZW1lbnQsIG5ld1RlbXBsYXRlKTtcclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBhY3Rpdml0aTpleGVjdXRpb25MaXN0ZW5lclxyXG4gICAgICB1cGRhdGVFeGVjdXRpb25MaXN0ZW5lcihlbGVtZW50LCBuZXdUZW1wbGF0ZSk7XHJcblxyXG4gICAgICAvLyBsb29wIG9uIHNjb3BlcyBwcm9wZXJ0aWVzXHJcbiAgICAgIGZvckVhY2gobmV3VGVtcGxhdGUuc2NvcGVzLCBmdW5jdGlvbihzY29wZURlZmluaXRpb24sIHNjb3BlTmFtZSkge1xyXG4gICAgICAgIHVwZGF0ZVNjb3BlRWxlbWVudHMoZWxlbWVudCwgc2NvcGVOYW1lLCBzY29wZURlZmluaXRpb24pO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICB9XHJcbiAgfTtcclxufVxyXG5cclxuQ2hhbmdlRWxlbWVudFRlbXBsYXRlSGFuZGxlci4kaW5qZWN0ID0gWyAnbW9kZWxpbmcnLCAnY29tbWFuZFN0YWNrJywgJ2JwbW5GYWN0b3J5JyBdO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBDaGFuZ2VFbGVtZW50VGVtcGxhdGVIYW5kbGVyO1xyXG5cclxuXHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVCcG1uUHJvcGVydHlVcGRhdGVzKHRlbXBsYXRlLCBicG1uRmFjdG9yeSkge1xyXG5cclxuICB2YXIgcHJvcGVydHlVcGRhdGVzID0ge307XHJcblxyXG4gIHRlbXBsYXRlLnByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwKSB7XHJcblxyXG4gICAgdmFyIGJpbmRpbmcgPSBwLmJpbmRpbmcsXHJcbiAgICAgICAgYmluZGluZ1RhcmdldCA9IGJpbmRpbmcubmFtZSxcclxuICAgICAgICBwcm9wZXJ0eVZhbHVlO1xyXG5cclxuICAgIGlmIChiaW5kaW5nLnR5cGUgPT09ICdwcm9wZXJ0eScpIHtcclxuXHJcbiAgICAgIGlmIChiaW5kaW5nVGFyZ2V0ID09PSAnY29uZGl0aW9uRXhwcmVzc2lvbicpIHtcclxuICAgICAgICBwcm9wZXJ0eVZhbHVlID0gYnBtbkZhY3RvcnkuY3JlYXRlKCdicG1uOkZvcm1hbEV4cHJlc3Npb24nLCB7XHJcbiAgICAgICAgICBib2R5OiBwLnZhbHVlLFxyXG4gICAgICAgICAgbGFuZ3VhZ2U6IGJpbmRpbmcuc2NyaXB0Rm9ybWF0XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcHJvcGVydHlWYWx1ZSA9IHAudmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIGFzc2lnbmluZyBhY3Rpdml0aTphc3luYyB0byB0cnVlfGZhbHNlXHJcbiAgICAgIC8vIGFzc2lnbmluZyBicG1uOmNvbmRpdGlvbkV4cHJlc3Npb24gdG8geyAkdHlwZTogJ2JwbW46Rm9ybWFsRXhwcmVzc2lvbicsIC4uLiB9XHJcbiAgICAgIHByb3BlcnR5VXBkYXRlc1tiaW5kaW5nVGFyZ2V0XSA9IHByb3BlcnR5VmFsdWU7XHJcblxyXG4gICAgICAvLyBtYWtlIHN1cmUgd2UgdW5zZXQgb3RoZXIgXCJpbXBsZW1lbnRhdGlvbiB0eXBlc1wiXHJcbiAgICAgIC8vIHdoZW4gYXBwbHlpbmcgYSBhY3Rpdml0aTpjbGFzcyB0ZW1wbGF0ZSBvbnRvIGEgcHJlY29uZmlndXJlZFxyXG4gICAgICAvLyBhY3Rpdml0aTpkZWxlZ2F0ZUV4cHJlc3Npb24gZWxlbWVudFxyXG4gICAgICBpZiAoQUNUSVZJVElfU0VSVklDRV9UQVNLX0xJS0UuaW5kZXhPZihiaW5kaW5nVGFyZ2V0KSAhPT0gLTEpIHtcclxuICAgICAgICBBQ1RJVklUSV9TRVJWSUNFX1RBU0tfTElLRS5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApIHtcclxuICAgICAgICAgIGlmIChwcm9wICE9PSBiaW5kaW5nVGFyZ2V0KSB7XHJcbiAgICAgICAgICAgIHByb3BlcnR5VXBkYXRlc1twcm9wXSA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gcHJvcGVydHlVcGRhdGVzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aUZpZWxkSW5qZWN0aW9ucyh0ZW1wbGF0ZSwgYnBtbkZhY3RvcnkpIHtcclxuICB2YXIgaW5qZWN0aW9ucyA9IFtdO1xyXG5cclxuICB0ZW1wbGF0ZS5wcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24ocCkge1xyXG4gICAgdmFyIGJpbmRpbmcgPSBwLmJpbmRpbmcsXHJcbiAgICAgICAgYmluZGluZ1R5cGUgPSBiaW5kaW5nLnR5cGU7XHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09ICdhY3Rpdml0aTpmaWVsZCcpIHtcclxuICAgICAgaW5qZWN0aW9ucy5wdXNoKGNyZWF0ZUFjdGl2aXRpRmllbGRJbmplY3Rpb24oXHJcbiAgICAgICAgYmluZGluZywgcC52YWx1ZSwgYnBtbkZhY3RvcnlcclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIGlmIChpbmplY3Rpb25zLmxlbmd0aCkge1xyXG4gICAgcmV0dXJuIGluamVjdGlvbnM7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aVByb3BlcnRpZXModGVtcGxhdGUsIGJwbW5GYWN0b3J5KSB7XHJcblxyXG4gIHZhciBwcm9wZXJ0aWVzID0gW107XHJcblxyXG4gIHRlbXBsYXRlLnByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwKSB7XHJcbiAgICB2YXIgYmluZGluZyA9IHAuYmluZGluZyxcclxuICAgICAgICBiaW5kaW5nVHlwZSA9IGJpbmRpbmcudHlwZTtcclxuXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09ICdhY3Rpdml0aTpwcm9wZXJ0eScpIHtcclxuICAgICAgcHJvcGVydGllcy5wdXNoKGNyZWF0ZUFjdGl2aXRpUHJvcGVydHkoXHJcbiAgICAgICAgYmluZGluZywgcC52YWx1ZSwgYnBtbkZhY3RvcnlcclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIGlmIChwcm9wZXJ0aWVzLmxlbmd0aCkge1xyXG4gICAgcmV0dXJuIGJwbW5GYWN0b3J5LmNyZWF0ZSgnYWN0aXZpdGk6UHJvcGVydGllcycsIHtcclxuICAgICAgdmFsdWVzOiBwcm9wZXJ0aWVzXHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZUlucHV0T3V0cHV0TWFwcGluZ3ModGVtcGxhdGUsIGJwbW5GYWN0b3J5KSB7XHJcblxyXG4gIHZhciBpbnB1dFBhcmFtZXRlcnMgPSBbXSxcclxuICAgICAgb3V0cHV0UGFyYW1ldGVycyA9IFtdO1xyXG5cclxuICB0ZW1wbGF0ZS5wcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24ocCkge1xyXG4gICAgdmFyIGJpbmRpbmcgPSBwLmJpbmRpbmcsXHJcbiAgICAgICAgYmluZGluZ1R5cGUgPSBiaW5kaW5nLnR5cGU7XHJcblxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSAnYWN0aXZpdGk6aW5wdXRQYXJhbWV0ZXInKSB7XHJcbiAgICAgIGlucHV0UGFyYW1ldGVycy5wdXNoKGNyZWF0ZUlucHV0UGFyYW1ldGVyKFxyXG4gICAgICAgIGJpbmRpbmcsIHAudmFsdWUsIGJwbW5GYWN0b3J5XHJcbiAgICAgICkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChiaW5kaW5nVHlwZSA9PT0gJ2FjdGl2aXRpOm91dHB1dFBhcmFtZXRlcicpIHtcclxuICAgICAgb3V0cHV0UGFyYW1ldGVycy5wdXNoKGNyZWF0ZU91dHB1dFBhcmFtZXRlcihcclxuICAgICAgICBiaW5kaW5nLCBwLnZhbHVlLCBicG1uRmFjdG9yeVxyXG4gICAgICApKTtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gZG8gd2UgbmVlZCB0byBjcmVhdGUgbmV3IGlvTWFwcGluZ3MgKD8pXHJcbiAgaWYgKG91dHB1dFBhcmFtZXRlcnMubGVuZ3RoIHx8IGlucHV0UGFyYW1ldGVycy5sZW5ndGgpIHtcclxuICAgIHJldHVybiBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOklucHV0T3V0cHV0Jywge1xyXG4gICAgICBpbnB1dFBhcmFtZXRlcnM6IGlucHV0UGFyYW1ldGVycyxcclxuICAgICAgb3V0cHV0UGFyYW1ldGVyczogb3V0cHV0UGFyYW1ldGVyc1xyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aUluT3V0KHRlbXBsYXRlLCBicG1uRmFjdG9yeSkge1xyXG5cclxuICB2YXIgaW5PdXRzID0gW107XHJcblxyXG4gIHRlbXBsYXRlLnByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwKSB7XHJcbiAgICB2YXIgYmluZGluZyA9IHAuYmluZGluZyxcclxuICAgICAgICBiaW5kaW5nVHlwZSA9IGJpbmRpbmcudHlwZTtcclxuXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09ICdhY3Rpdml0aTppbicpIHtcclxuICAgICAgaW5PdXRzLnB1c2goY3JlYXRlQWN0aXZpdGlJbihcclxuICAgICAgICBiaW5kaW5nLCBwLnZhbHVlLCBicG1uRmFjdG9yeVxyXG4gICAgICApKTtcclxuICAgIH0gZWxzZVxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSAnYWN0aXZpdGk6b3V0Jykge1xyXG4gICAgICBpbk91dHMucHVzaChjcmVhdGVBY3Rpdml0aU91dChcclxuICAgICAgICBiaW5kaW5nLCBwLnZhbHVlLCBicG1uRmFjdG9yeVxyXG4gICAgICApKTtcclxuICAgIH0gZWxzZVxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSAnYWN0aXZpdGk6aW46YnVzaW5lc3NLZXknKSB7XHJcbiAgICAgIGluT3V0cy5wdXNoKGNyZWF0ZUFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkoXHJcbiAgICAgICAgYmluZGluZywgcC52YWx1ZSwgYnBtbkZhY3RvcnlcclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBpbk91dHM7XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0aUV4ZWN1dGlvbkxpc3RlbmVycyh0ZW1wbGF0ZSwgYnBtbkZhY3RvcnkpIHtcclxuXHJcbiAgdmFyIGV4ZWN1dGlvbkxpc3RlbmVyID0gW107XHJcblxyXG4gIHRlbXBsYXRlLnByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwKSB7XHJcbiAgICB2YXIgYmluZGluZyA9IHAuYmluZGluZyxcclxuICAgICAgICBiaW5kaW5nVHlwZSA9IGJpbmRpbmcudHlwZTtcclxuXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09ICdhY3Rpdml0aTpleGVjdXRpb25MaXN0ZW5lcicpIHtcclxuICAgICAgZXhlY3V0aW9uTGlzdGVuZXIucHVzaChjcmVhdGVBY3Rpdml0aUV4ZWN1dGlvbkxpc3RlbmVyU2NyaXB0KFxyXG4gICAgICAgIGJpbmRpbmcsIHAudmFsdWUsIGJwbW5GYWN0b3J5XHJcbiAgICAgICkpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gZXhlY3V0aW9uTGlzdGVuZXI7XHJcbn1cclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIENoYW5nZUVsZW1lbnRUZW1wbGF0ZUhhbmRsZXIgPSByZXF1aXJlKCcuL0NoYW5nZUVsZW1lbnRUZW1wbGF0ZUhhbmRsZXInKTtcclxuXHJcbnZhciBnZXRUZW1wbGF0ZSA9IHJlcXVpcmUoJy4uL0hlbHBlcicpLmdldFRlbXBsYXRlLFxyXG4gICAgZ2V0RGVmYXVsdFRlbXBsYXRlID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZ2V0RGVmYXVsdFRlbXBsYXRlO1xyXG5cclxuZnVuY3Rpb24gcmVnaXN0ZXJIYW5kbGVycyhjb21tYW5kU3RhY2ssIGVsZW1lbnRUZW1wbGF0ZXMsIGV2ZW50QnVzLCBlbGVtZW50UmVnaXN0cnkpIHtcclxuICBjb21tYW5kU3RhY2sucmVnaXN0ZXJIYW5kbGVyKFxyXG4gICAgJ3Byb3BlcnRpZXNQYW5lbC5hY3Rpdml0aS5jaGFuZ2VUZW1wbGF0ZScsXHJcbiAgICBDaGFuZ2VFbGVtZW50VGVtcGxhdGVIYW5kbGVyXHJcbiAgKTtcclxuXHJcbiAgLy8gYXBwbHkgZGVmYXVsdCBlbGVtZW50IHRlbXBsYXRlcyBvbiBzaGFwZSBjcmVhdGlvblxyXG4gIGV2ZW50QnVzLm9uKFsgJ2NvbW1hbmRTdGFjay5zaGFwZS5jcmVhdGUucG9zdEV4ZWN1dGVkJyBdLCBmdW5jdGlvbihjb250ZXh0KSB7XHJcbiAgICBhcHBseURlZmF1bHRUZW1wbGF0ZShjb250ZXh0LmNvbnRleHQuc2hhcGUsIGVsZW1lbnRUZW1wbGF0ZXMsIGNvbW1hbmRTdGFjayk7XHJcbiAgfSk7XHJcblxyXG4gIC8vIGFwcGx5IGRlZmF1bHQgZWxlbWVudCB0ZW1wbGF0ZXMgb24gY29ubmVjdGlvbiBjcmVhdGlvblxyXG4gIGV2ZW50QnVzLm9uKFsgJ2NvbW1hbmRTdGFjay5jb25uZWN0aW9uLmNyZWF0ZS5wb3N0RXhlY3V0ZWQnIF0sIGZ1bmN0aW9uKGNvbnRleHQpIHtcclxuICAgIGFwcGx5RGVmYXVsdFRlbXBsYXRlKGNvbnRleHQuY29udGV4dC5jb25uZWN0aW9uLCBlbGVtZW50VGVtcGxhdGVzLCBjb21tYW5kU3RhY2spO1xyXG4gIH0pO1xyXG59XHJcblxyXG5yZWdpc3RlckhhbmRsZXJzLiRpbmplY3QgPSBbICdjb21tYW5kU3RhY2snLCAnZWxlbWVudFRlbXBsYXRlcycsICdldmVudEJ1cycsICdlbGVtZW50UmVnaXN0cnknIF07XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSB7XHJcbiAgX19pbml0X186IFsgcmVnaXN0ZXJIYW5kbGVycyBdXHJcbn07XHJcblxyXG5cclxuZnVuY3Rpb24gYXBwbHlEZWZhdWx0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcywgY29tbWFuZFN0YWNrKSB7XHJcblxyXG4gIGlmICghZ2V0VGVtcGxhdGUoZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcylcclxuICAgICAgJiYgZ2V0RGVmYXVsdFRlbXBsYXRlKGVsZW1lbnQsIGVsZW1lbnRUZW1wbGF0ZXMpKSB7XHJcblxyXG4gICAgdmFyIGNvbW1hbmQgPSAncHJvcGVydGllc1BhbmVsLmFjdGl2aXRpLmNoYW5nZVRlbXBsYXRlJztcclxuICAgIHZhciBjb21tYW5kQ29udGV4dCA9IHtcclxuICAgICAgZWxlbWVudDogZWxlbWVudCxcclxuICAgICAgbmV3VGVtcGxhdGU6IGdldERlZmF1bHRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKVxyXG4gICAgfTtcclxuXHJcbiAgICBjb21tYW5kU3RhY2suZXhlY3V0ZShjb21tYW5kLCBjb21tYW5kQ29udGV4dCk7XHJcbiAgfVxyXG59XHJcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xyXG4gIF9fZGVwZW5kc19fOiBbXHJcbiAgICByZXF1aXJlKCcuL2NtZC9pbmRleCcpLFxyXG4gICAgcmVxdWlyZSgnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnKS5kZWZhdWx0XHJcbiAgXSxcclxuICBfX2luaXRfXzogW1xyXG4gICAgJ2N1c3RvbUVsZW1lbnRzUHJvcGVydGllc0FjdGl2YXRvcicsXHJcbiAgICAnZWxlbWVudFRlbXBsYXRlc0xvYWRlcidcclxuICBdLFxyXG4gIGN1c3RvbUVsZW1lbnRzUHJvcGVydGllc0FjdGl2YXRvcjogWyAndHlwZScsIHJlcXVpcmUoJy4vQ3VzdG9tRWxlbWVudHNQcm9wZXJ0aWVzQWN0aXZhdG9yJykgXSxcclxuICBlbGVtZW50VGVtcGxhdGVzOiBbICd0eXBlJywgcmVxdWlyZSgnLi9FbGVtZW50VGVtcGxhdGVzJykgXSxcclxuICBlbGVtZW50VGVtcGxhdGVzTG9hZGVyOiBbICd0eXBlJywgcmVxdWlyZSgnLi9FbGVtZW50VGVtcGxhdGVzTG9hZGVyJykgXVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldFRlbXBsYXRlID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZ2V0VGVtcGxhdGUsXHJcbiAgICBnZXRUZW1wbGF0ZUlkID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZ2V0VGVtcGxhdGVJZDtcclxuXHJcbnZhciBmaW5kID0gcmVxdWlyZSgnbG9kYXNoL2ZpbmQnKTtcclxuXHJcbnZhciBURU1QTEFURV9BVFRSID0gcmVxdWlyZSgnLi4vSGVscGVyJykuVEVNUExBVEVfQVRUUjtcclxuXHJcbmZ1bmN0aW9uIGlzQW55KGVsZW1lbnQsIHR5cGVzKSB7XHJcbiAgcmV0dXJuIHR5cGVzLnJlZHVjZShmdW5jdGlvbihyZXN1bHQsIHR5cGUpIHtcclxuICAgIHJldHVybiByZXN1bHQgfHwgaXMoZWxlbWVudCwgdHlwZSk7XHJcbiAgfSwgZmFsc2UpO1xyXG59XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBvcHRpb25zID0gZ2V0VGVtcGxhdGVPcHRpb25zKGVsZW1lbnQsIGVsZW1lbnRUZW1wbGF0ZXMsIHRyYW5zbGF0ZSk7XHJcblxyXG4gIGlmIChvcHRpb25zLmxlbmd0aCA9PT0gMSAmJiAhb3B0aW9uc1swXS5pc0RlZmF1bHQpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8vIHNlbGVjdCBlbGVtZW50IHRlbXBsYXRlICh2aWEgZHJvcGRvd24pXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6ICdlbGVtZW50VGVtcGxhdGUtY2hvb3NlcicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdFbGVtZW50IFRlbXBsYXRlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnYWN0aXZpdGk6bW9kZWxlclRlbXBsYXRlJyxcclxuICAgIHNlbGVjdE9wdGlvbnM6IG9wdGlvbnMsXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHByb3BlcnRpZXMpIHtcclxuICAgICAgcmV0dXJuIGFwcGx5VGVtcGxhdGUoZWxlbWVudCwgcHJvcGVydGllc1tURU1QTEFURV9BVFRSXSwgZWxlbWVudFRlbXBsYXRlcyk7XHJcbiAgICB9LFxyXG4gICAgZGlzYWJsZWQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICB2YXIgdGVtcGxhdGUgPSBnZXRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKTtcclxuXHJcbiAgICAgIHJldHVybiB0ZW1wbGF0ZSAmJiBpc0RlZmF1bHRUZW1wbGF0ZSh0ZW1wbGF0ZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxufTtcclxuXHJcblxyXG4vLyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBhcHBseVRlbXBsYXRlKGVsZW1lbnQsIG5ld1RlbXBsYXRlSWQsIGVsZW1lbnRUZW1wbGF0ZXMpIHtcclxuXHJcbiAgLy8gY2xlYW51cFxyXG4gIC8vIGNsZWFyIGlucHV0IG91dHB1dCBtYXBwaW5nc1xyXG4gIC8vIHVuZG8gY2hhbmdlcyB0byBwcm9wZXJ0aWVzIGRlZmluZWQgaW4gdGVtcGxhdGVcclxuXHJcbiAgLy8gcmUtZXN0YWJsaXNoXHJcbiAgLy8gc2V0IGlucHV0IG91dHB1dCBtYXBwaW5nc1xyXG4gIC8vIGFwcGx5IGNoYW5nZXMgdG8gcHJvcGVydGllcyBhcyBkZWZpbmVkIGluIG5ldyB0ZW1wbGF0ZVxyXG5cclxuICB2YXIgb2xkVGVtcGxhdGUgPSBnZXRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKSxcclxuICAgICAgbmV3VGVtcGxhdGUgPSBlbGVtZW50VGVtcGxhdGVzLmdldChuZXdUZW1wbGF0ZUlkKTtcclxuXHJcbiAgaWYgKG9sZFRlbXBsYXRlID09PSBuZXdUZW1wbGF0ZSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHtcclxuICAgIGNtZDogJ3Byb3BlcnRpZXNQYW5lbC5hY3Rpdml0aS5jaGFuZ2VUZW1wbGF0ZScsXHJcbiAgICBjb250ZXh0OiB7XHJcbiAgICAgIGVsZW1lbnQ6IGVsZW1lbnQsXHJcbiAgICAgIG9sZFRlbXBsYXRlOiBvbGRUZW1wbGF0ZSxcclxuICAgICAgbmV3VGVtcGxhdGU6IG5ld1RlbXBsYXRlXHJcbiAgICB9XHJcbiAgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0VGVtcGxhdGVPcHRpb25zKGVsZW1lbnQsIGVsZW1lbnRUZW1wbGF0ZXMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgY3VycmVudFRlbXBsYXRlSWQgPSBnZXRUZW1wbGF0ZUlkKGVsZW1lbnQpO1xyXG5cclxuICB2YXIgZW1wdHlPcHRpb24gPSB7XHJcbiAgICBuYW1lOiAnJyxcclxuICAgIHZhbHVlOiAnJ1xyXG4gIH07XHJcblxyXG4gIHZhciBhbGxPcHRpb25zID0gZWxlbWVudFRlbXBsYXRlcy5nZXRBbGwoKS5yZWR1Y2UoZnVuY3Rpb24odGVtcGxhdGVzLCB0KSB7XHJcbiAgICBpZiAoIWlzQW55KGVsZW1lbnQsIHQuYXBwbGllc1RvKSkge1xyXG4gICAgICByZXR1cm4gdGVtcGxhdGVzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0ZW1wbGF0ZXMuY29uY2F0KHtcclxuICAgICAgbmFtZTogdHJhbnNsYXRlKHQubmFtZSksXHJcbiAgICAgIHZhbHVlOiB0LmlkLFxyXG4gICAgICBpc0RlZmF1bHQ6IHQuaXNEZWZhdWx0XHJcbiAgICB9KTtcclxuICB9LCBbIGVtcHR5T3B0aW9uIF0pO1xyXG5cclxuXHJcbiAgdmFyIGRlZmF1bHRPcHRpb24gPSBmaW5kKGFsbE9wdGlvbnMsIGZ1bmN0aW9uKG9wdGlvbikge1xyXG4gICAgcmV0dXJuIGlzRGVmYXVsdFRlbXBsYXRlKG9wdGlvbik7XHJcbiAgfSk7XHJcblxyXG4gIHZhciBjdXJyZW50T3B0aW9uID0gZmluZChhbGxPcHRpb25zLCBmdW5jdGlvbihvcHRpb24pIHtcclxuICAgIHJldHVybiBvcHRpb24udmFsdWUgPT09IGN1cnJlbnRUZW1wbGF0ZUlkO1xyXG4gIH0pO1xyXG5cclxuICBpZiAoY3VycmVudFRlbXBsYXRlSWQgJiYgIWN1cnJlbnRPcHRpb24pIHtcclxuICAgIGN1cnJlbnRPcHRpb24gPSB1bmtub3duVGVtcGxhdGUoY3VycmVudFRlbXBsYXRlSWQsIHRyYW5zbGF0ZSk7XHJcblxyXG4gICAgYWxsT3B0aW9ucy5wdXNoKGN1cnJlbnRPcHRpb24pO1xyXG4gIH1cclxuXHJcbiAgaWYgKCFkZWZhdWx0T3B0aW9uKSB7XHJcblxyXG4gICAgLy8gcmV0dXJuIGFsbCBvcHRpb25zLCBpbmNsdWRpbmcgZW1wdHlcclxuICAgIC8vIGFuZCBvcHRpb25hbGx5IHVua25vd25UZW1wbGF0ZSBvcHRpb25cclxuICAgIHJldHVybiBhbGxPcHRpb25zO1xyXG4gIH1cclxuXHJcbiAgLy8gc3BlY2lhbCBsaW1pdGVkIGhhbmRsaW5nIGZvclxyXG4gIC8vIGRlZmF1bHQgb3B0aW9uc1xyXG5cclxuICB2YXIgb3B0aW9ucyA9IFtdO1xyXG5cclxuICAvLyBjdXJyZW50IHRlbXBsYXRlIG5vdCBzZXRcclxuICBpZiAoIWN1cnJlbnRUZW1wbGF0ZUlkKSB7XHJcbiAgICBvcHRpb25zLnB1c2goe1xyXG4gICAgICBuYW1lOiAnJyxcclxuICAgICAgdmFsdWU6ICcnXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8vIGN1cnJlbnQgdGVtcGxhdGUgbm90IGRlZmF1bHRcclxuICBpZiAoY3VycmVudE9wdGlvbiAmJiBjdXJyZW50T3B0aW9uICE9PSBkZWZhdWx0T3B0aW9uKSB7XHJcbiAgICBvcHRpb25zLnB1c2goY3VycmVudE9wdGlvbik7XHJcbiAgfVxyXG5cclxuICBvcHRpb25zLnB1c2goZGVmYXVsdE9wdGlvbik7XHJcblxyXG4gIC8vIFsgKGVtcHR5KSwgKGN1cnJlbnQpLCBkZWZhdWx0T3B0aW9uIF1cclxuICByZXR1cm4gb3B0aW9ucztcclxufVxyXG5cclxuZnVuY3Rpb24gdW5rbm93blRlbXBsYXRlKHRlbXBsYXRlSWQsIHRyYW5zbGF0ZSkge1xyXG4gIHJldHVybiB7XHJcbiAgICBuYW1lOiB0cmFuc2xhdGUoJ1t1bmtub3duIHRlbXBsYXRlOiB7dGVtcGxhdGVJZH1dJywgeyB0ZW1wbGF0ZUlkOiB0ZW1wbGF0ZUlkIH0pLFxyXG4gICAgdmFsdWU6IHRlbXBsYXRlSWRcclxuICB9O1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0RlZmF1bHRUZW1wbGF0ZShlbGVtZW50VGVtcGxhdGUpIHtcclxuICByZXR1cm4gZWxlbWVudFRlbXBsYXRlLmlzRGVmYXVsdDtcclxufSIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyk7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGdldFRlbXBsYXRlID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZ2V0VGVtcGxhdGUsXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKTtcclxuXHJcbnZhciBmaW5kRXh0ZW5zaW9uID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZmluZEV4dGVuc2lvbixcclxuICAgIGZpbmRFeHRlbnNpb25zID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZmluZEV4dGVuc2lvbnMsXHJcbiAgICBmaW5kSW5wdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuLi9IZWxwZXInKS5maW5kSW5wdXRQYXJhbWV0ZXIsXHJcbiAgICBmaW5kT3V0cHV0UGFyYW1ldGVyID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZmluZE91dHB1dFBhcmFtZXRlcixcclxuICAgIGZpbmRBY3Rpdml0aVByb3BlcnR5ID0gcmVxdWlyZSgnLi4vSGVscGVyJykuZmluZEFjdGl2aXRpUHJvcGVydHksXHJcbiAgICBmaW5kQWN0aXZpdGlJbk91dCA9IHJlcXVpcmUoJy4uL0hlbHBlcicpLmZpbmRBY3Rpdml0aUluT3V0O1xyXG5cclxudmFyIGNyZWF0ZUFjdGl2aXRpUHJvcGVydHkgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aVByb3BlcnR5LFxyXG4gICAgY3JlYXRlSW5wdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVJbnB1dFBhcmFtZXRlcixcclxuICAgIGNyZWF0ZU91dHB1dFBhcmFtZXRlciA9IHJlcXVpcmUoJy4uL0NyZWF0ZUhlbHBlcicpLmNyZWF0ZU91dHB1dFBhcmFtZXRlcixcclxuICAgIGNyZWF0ZUFjdGl2aXRpSW4gPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aUluLFxyXG4gICAgY3JlYXRlQWN0aXZpdGlPdXQgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aU91dCxcclxuICAgIGNyZWF0ZUFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkgPSByZXF1aXJlKCcuLi9DcmVhdGVIZWxwZXInKS5jcmVhdGVBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5LFxyXG4gICAgY3JlYXRlQWN0aXZpdGlGaWVsZEluamVjdGlvbiA9IHJlcXVpcmUoJy4uL0NyZWF0ZUhlbHBlcicpLmNyZWF0ZUFjdGl2aXRpRmllbGRJbmplY3Rpb247XHJcblxyXG52YXIgQUNUSVZJVElfUFJPUEVSVFlfVFlQRSA9ICdhY3Rpdml0aTpwcm9wZXJ0eScsXHJcbiAgICBBQ1RJVklUSV9JTlBVVF9QQVJBTUVURVJfVFlQRSA9ICdhY3Rpdml0aTppbnB1dFBhcmFtZXRlcicsXHJcbiAgICBBQ1RJVklUSV9PVVRQVVRfUEFSQU1FVEVSX1RZUEUgPSAnYWN0aXZpdGk6b3V0cHV0UGFyYW1ldGVyJyxcclxuICAgIEFDVElWSVRJX0lOX1RZUEUgPSAnYWN0aXZpdGk6aW4nLFxyXG4gICAgQUNUSVZJVElfT1VUX1RZUEUgPSAnYWN0aXZpdGk6b3V0JyxcclxuICAgIEFDVElWSVRJX0lOX0JVU0lORVNTX0tFWV9UWVBFID0gJ2FjdGl2aXRpOmluOmJ1c2luZXNzS2V5JyxcclxuICAgIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUl9UWVBFID0gJ2FjdGl2aXRpOmV4ZWN1dGlvbkxpc3RlbmVyJyxcclxuICAgIEFDVElWSVRJX0ZJRUxEID0gJ2FjdGl2aXRpOmZpZWxkJztcclxuXHJcbnZhciBCQVNJQ19NT0RETEVfVFlQRVMgPSBbXHJcbiAgJ0Jvb2xlYW4nLFxyXG4gICdJbnRlZ2VyJyxcclxuICAnU3RyaW5nJ1xyXG5dO1xyXG5cclxudmFyIEVYVEVOU0lPTl9CSU5ESU5HX1RZUEVTID0gW1xyXG4gIEFDVElWSVRJX1BST1BFUlRZX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5QVVRfUEFSQU1FVEVSX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUUFVUX1BBUkFNRVRFUl9UWVBFLFxyXG4gIEFDVElWSVRJX0lOX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5fQlVTSU5FU1NfS0VZX1RZUEUsXHJcbiAgQUNUSVZJVElfRklFTERcclxuXTtcclxuXHJcbnZhciBJT19CSU5ESU5HX1RZUEVTID0gW1xyXG4gIEFDVElWSVRJX0lOUFVUX1BBUkFNRVRFUl9UWVBFLFxyXG4gIEFDVElWSVRJX09VVFBVVF9QQVJBTUVURVJfVFlQRVxyXG5dO1xyXG5cclxudmFyIElOX09VVF9CSU5ESU5HX1RZUEVTID0gW1xyXG4gIEFDVElWSVRJX0lOX1RZUEUsXHJcbiAgQUNUSVZJVElfT1VUX1RZUEUsXHJcbiAgQUNUSVZJVElfSU5fQlVTSU5FU1NfS0VZX1RZUEVcclxuXTtcclxuXHJcbi8qKlxyXG4gKiBJbmplY3RzIGN1c3RvbSBwcm9wZXJ0aWVzIGludG8gdGhlIGdpdmVuIGdyb3VwLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7RWxlbWVudFRlbXBsYXRlc30gZWxlbWVudFRlbXBsYXRlc1xyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSB0cmFuc2xhdGVcclxuICovXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgZWxlbWVudFRlbXBsYXRlcywgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgdGVtcGxhdGUgPSBnZXRUZW1wbGF0ZShlbGVtZW50LCBlbGVtZW50VGVtcGxhdGVzKTtcclxuXHJcbiAgaWYgKCF0ZW1wbGF0ZSkge1xyXG4gICAgcmV0dXJuIFtdO1xyXG4gIH1cclxuXHJcbiAgdmFyIHJlbmRlckN1c3RvbUZpZWxkID0gZnVuY3Rpb24oaWQsIHAsIGlkeCkge1xyXG4gICAgdmFyIHByb3BlcnR5VHlwZSA9IHAudHlwZTtcclxuXHJcbiAgICB2YXIgZW50cnlPcHRpb25zID0ge1xyXG4gICAgICBpZDogaWQsXHJcbiAgICAgIGRlc2NyaXB0aW9uOiBwLmRlc2NyaXB0aW9uLFxyXG4gICAgICBsYWJlbDogcC5sYWJlbCA/IHRyYW5zbGF0ZShwLmxhYmVsKSA6IHAubGFiZWwsXHJcbiAgICAgIG1vZGVsUHJvcGVydHk6IGlkLFxyXG4gICAgICBnZXQ6IHByb3BlcnR5R2V0dGVyKGlkLCBwKSxcclxuICAgICAgc2V0OiBwcm9wZXJ0eVNldHRlcihpZCwgcCwgYnBtbkZhY3RvcnkpLFxyXG4gICAgICB2YWxpZGF0ZTogcHJvcGVydHlWYWxpZGF0b3IoaWQsIHAsIHRyYW5zbGF0ZSlcclxuICAgIH07XHJcblxyXG4gICAgdmFyIGVudHJ5O1xyXG5cclxuICAgIGlmIChwcm9wZXJ0eVR5cGUgPT09ICdCb29sZWFuJykge1xyXG4gICAgICBlbnRyeSA9IGVudHJ5RmFjdG9yeS5jaGVja2JveChlbnRyeU9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChwcm9wZXJ0eVR5cGUgPT09ICdTdHJpbmcnKSB7XHJcbiAgICAgIGVudHJ5ID0gZW50cnlGYWN0b3J5LnRleHRGaWVsZChlbnRyeU9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChwcm9wZXJ0eVR5cGUgPT09ICdUZXh0Jykge1xyXG4gICAgICBlbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0Qm94KGVudHJ5T3B0aW9ucyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHByb3BlcnR5VHlwZSA9PT0gJ0Ryb3Bkb3duJykge1xyXG4gICAgICBlbnRyeU9wdGlvbnMuc2VsZWN0T3B0aW9ucyA9IHAuY2hvaWNlcztcclxuXHJcbiAgICAgIGVudHJ5ID0gZW50cnlGYWN0b3J5LnNlbGVjdEJveChlbnRyeU9wdGlvbnMpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBlbnRyeTtcclxuICB9O1xyXG5cclxuICB2YXIgZ3JvdXBzID0gW107XHJcbiAgdmFyIGlkLCBlbnRyeTtcclxuXHJcbiAgdmFyIGN1c3RvbUZpZWxkc0dyb3VwID0ge1xyXG4gICAgaWQ6ICdjdXN0b21GaWVsZCcsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdDdXN0b20gRmllbGRzJyksXHJcbiAgICBlbnRyaWVzOiBbXVxyXG4gIH07XHJcbiAgdGVtcGxhdGUucHJvcGVydGllcy5mb3JFYWNoKGZ1bmN0aW9uKHAsIGlkeCkge1xyXG5cclxuICAgIGlkID0gJ2N1c3RvbS0nICsgdGVtcGxhdGUuaWQgKyAnLScgKyBpZHg7XHJcblxyXG4gICAgZW50cnkgPSByZW5kZXJDdXN0b21GaWVsZChpZCwgcCwgaWR4KTtcclxuICAgIGlmIChlbnRyeSkge1xyXG4gICAgICBjdXN0b21GaWVsZHNHcm91cC5lbnRyaWVzLnB1c2goZW50cnkpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG4gIGlmIChjdXN0b21GaWVsZHNHcm91cC5lbnRyaWVzLmxlbmd0aCA+IDApIHtcclxuICAgIGdyb3Vwcy5wdXNoKGN1c3RvbUZpZWxkc0dyb3VwKTtcclxuICB9XHJcblxyXG4gIGlmICh0ZW1wbGF0ZS5zY29wZXMpIHtcclxuICAgIGZvciAodmFyIHNjb3BlTmFtZSBpbiB0ZW1wbGF0ZS5zY29wZXMpIHtcclxuXHJcbiAgICAgIHZhciBzY29wZSA9IHRlbXBsYXRlLnNjb3Blc1tzY29wZU5hbWVdO1xyXG4gICAgICB2YXIgaWRTY29wZU5hbWUgPSBzY29wZU5hbWUucmVwbGFjZSgvOi9nLCAnXycpO1xyXG5cclxuICAgICAgdmFyIGN1c3RvbVNjb3BlRmllbGRzR3JvdXAgPSB7XHJcbiAgICAgICAgaWQ6ICdjdXN0b21GaWVsZC0nICsgaWRTY29wZU5hbWUsXHJcbiAgICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ3VzdG9tIEZpZWxkcyBmb3Igc2NvcGU6ICcpICsgc2NvcGVOYW1lLFxyXG4gICAgICAgIGVudHJpZXM6IFtdXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBzY29wZS5wcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24ocCwgaWR4KSB7XHJcblxyXG4gICAgICAgIHZhciBwcm9wZXJ0eUlkID0gJ2N1c3RvbS0nICsgdGVtcGxhdGUuaWQgKyAnLScgKyBpZFNjb3BlTmFtZSArICctJyArIGlkeDtcclxuXHJcbiAgICAgICAgdmFyIHNjb3BlZFByb3BlcnR5ID0gcHJvcGVydHlXaXRoU2NvcGUocCwgc2NvcGVOYW1lKTtcclxuXHJcbiAgICAgICAgZW50cnkgPSByZW5kZXJDdXN0b21GaWVsZChwcm9wZXJ0eUlkLCBzY29wZWRQcm9wZXJ0eSwgaWR4KTtcclxuICAgICAgICBpZiAoZW50cnkpIHtcclxuICAgICAgICAgIGN1c3RvbVNjb3BlRmllbGRzR3JvdXAuZW50cmllcy5wdXNoKGVudHJ5KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaWYgKGN1c3RvbVNjb3BlRmllbGRzR3JvdXAuZW50cmllcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgZ3JvdXBzLnB1c2goY3VzdG9tU2NvcGVGaWVsZHNHcm91cCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBncm91cHM7XHJcbn07XHJcblxyXG5cclxuLy8gZ2V0dGVycywgc2V0dGVycyBhbmQgdmFsaWRhdG9ycyAvLy8vLy8vLy8vLy8vLy9cclxuXHJcblxyXG4vKipcclxuICogUmV0dXJuIGEgZ2V0dGVyIHRoYXQgcmV0cmlldmVzIHRoZSBnaXZlbiBwcm9wZXJ0eS5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWVcclxuICogQHBhcmFtIHtQcm9wZXJ0eURlc2NyaXB0b3J9IHByb3BlcnR5XHJcbiAqXHJcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxyXG4gKi9cclxuZnVuY3Rpb24gcHJvcGVydHlHZXR0ZXIobmFtZSwgcHJvcGVydHkpIHtcclxuXHJcbiAgLyogZ2V0dGVyICovXHJcbiAgcmV0dXJuIGZ1bmN0aW9uIGdldChlbGVtZW50KSB7XHJcbiAgICB2YXIgdmFsdWUgPSBnZXRQcm9wZXJ0eVZhbHVlKGVsZW1lbnQsIHByb3BlcnR5KTtcclxuXHJcbiAgICByZXR1cm4gb2JqZWN0V2l0aEtleShuYW1lLCB2YWx1ZSk7XHJcbiAgfTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybiBhIHNldHRlciB0aGF0IHVwZGF0ZXMgdGhlIGdpdmVuIHByb3BlcnR5LlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICpcclxuICogQHJldHVybiB7RnVuY3Rpb259XHJcbiAqL1xyXG5mdW5jdGlvbiBwcm9wZXJ0eVNldHRlcihuYW1lLCBwcm9wZXJ0eSwgYnBtbkZhY3RvcnkpIHtcclxuXHJcbiAgLyogc2V0dGVyICovXHJcbiAgcmV0dXJuIGZ1bmN0aW9uIHNldChlbGVtZW50LCB2YWx1ZXMpIHtcclxuXHJcbiAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbbmFtZV07XHJcblxyXG4gICAgcmV0dXJuIHNldFByb3BlcnR5VmFsdWUoZWxlbWVudCwgcHJvcGVydHksIHZhbHVlLCBicG1uRmFjdG9yeSk7XHJcbiAgfTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybiBhIHZhbGlkYXRvciB0aGF0IGVuc3VyZXMgdGhlIHByb3BlcnR5IGlzIG9rLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1N0cmluZ30gbmFtZVxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNsYXRlXHJcbiAqXHJcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufVxyXG4gKi9cclxuZnVuY3Rpb24gcHJvcGVydHlWYWxpZGF0b3IobmFtZSwgcHJvcGVydHksIHRyYW5zbGF0ZSkge1xyXG5cclxuICAvKiB2YWxpZGF0b3IgKi9cclxuICByZXR1cm4gZnVuY3Rpb24gdmFsaWRhdGUoZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICB2YXIgdmFsdWUgPSB2YWx1ZXNbbmFtZV07XHJcblxyXG4gICAgdmFyIGVycm9yID0gdmFsaWRhdGVWYWx1ZSh2YWx1ZSwgcHJvcGVydHksIHRyYW5zbGF0ZSk7XHJcblxyXG4gICAgaWYgKGVycm9yKSB7XHJcbiAgICAgIHJldHVybiBvYmplY3RXaXRoS2V5KG5hbWUsIGVycm9yKTtcclxuICAgIH1cclxuICB9O1xyXG59XHJcblxyXG5cclxuLy8gZ2V0LCBzZXQgYW5kIHZhbGlkYXRlIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuLyoqXHJcbiAqIFJldHVybiB0aGUgdmFsdWUgb2YgdGhlIHNwZWNpZmllZCBwcm9wZXJ0eSBkZXNjcmlwdG9yLFxyXG4gKiBvbiB0aGUgcGFzc2VkIGRpYWdyYW0gZWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICpcclxuICogQHJldHVybiB7QW55fVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UHJvcGVydHlWYWx1ZShlbGVtZW50LCBwcm9wZXJ0eSkge1xyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgdmFyIGJpbmRpbmcgPSBwcm9wZXJ0eS5iaW5kaW5nLFxyXG4gICAgICBzY29wZSA9IHByb3BlcnR5LnNjb3BlO1xyXG5cclxuICB2YXIgYmluZGluZ1R5cGUgPSBiaW5kaW5nLnR5cGUsXHJcbiAgICAgIGJpbmRpbmdOYW1lID0gYmluZGluZy5uYW1lO1xyXG5cclxuICB2YXIgcHJvcGVydHlWYWx1ZSA9IHByb3BlcnR5LnZhbHVlIHx8ICcnO1xyXG5cclxuICBpZiAoc2NvcGUpIHtcclxuICAgIGJvID0gZmluZEV4dGVuc2lvbihibywgc2NvcGUubmFtZSk7XHJcbiAgICBpZiAoIWJvKSB7XHJcbiAgICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gcHJvcGVydHlcclxuICBpZiAoYmluZGluZ1R5cGUgPT09ICdwcm9wZXJ0eScpIHtcclxuXHJcbiAgICB2YXIgdmFsdWUgPSBiby5nZXQoYmluZGluZ05hbWUpO1xyXG5cclxuICAgIGlmIChiaW5kaW5nTmFtZSA9PT0gJ2NvbmRpdGlvbkV4cHJlc3Npb24nKSB7XHJcbiAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgIHJldHVybiB2YWx1ZS5ib2R5O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIHJldHVybiBkZWZpbmVkIGRlZmF1bHRcclxuICAgICAgICByZXR1cm4gcHJvcGVydHlWYWx1ZTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gcmV0dXJuIHZhbHVlOyBkZWZhdWx0IHRvIGRlZmluZWQgZGVmYXVsdFxyXG4gICAgICByZXR1cm4gdHlwZW9mIHZhbHVlICE9PSAndW5kZWZpbmVkJyA/IHZhbHVlIDogcHJvcGVydHlWYWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHZhciBhY3Rpdml0aVByb3BlcnRpZXMsXHJcbiAgICAgIGFjdGl2aXRpUHJvcGVydHk7XHJcblxyXG4gIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfUFJPUEVSVFlfVFlQRSkge1xyXG4gICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgIGFjdGl2aXRpUHJvcGVydGllcyA9IGJvLmdldCgncHJvcGVydGllcycpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgYWN0aXZpdGlQcm9wZXJ0aWVzID0gZmluZEV4dGVuc2lvbihibywgJ2FjdGl2aXRpOlByb3BlcnRpZXMnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoYWN0aXZpdGlQcm9wZXJ0aWVzKSB7XHJcbiAgICAgIGFjdGl2aXRpUHJvcGVydHkgPSBmaW5kQWN0aXZpdGlQcm9wZXJ0eShhY3Rpdml0aVByb3BlcnRpZXMsIGJpbmRpbmcpO1xyXG5cclxuICAgICAgaWYgKGFjdGl2aXRpUHJvcGVydHkpIHtcclxuICAgICAgICByZXR1cm4gYWN0aXZpdGlQcm9wZXJ0eS52YWx1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlO1xyXG4gIH1cclxuXHJcbiAgdmFyIGlucHV0T3V0cHV0LFxyXG4gICAgICBpb1BhcmFtZXRlcjtcclxuXHJcbiAgaWYgKElPX0JJTkRJTkdfVFlQRVMuaW5kZXhPZihiaW5kaW5nVHlwZSkgIT09IC0xKSB7XHJcblxyXG4gICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgIGlucHV0T3V0cHV0ID0gYm8uZ2V0KCdpbnB1dE91dHB1dCcpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaW5wdXRPdXRwdXQgPSBmaW5kRXh0ZW5zaW9uKGJvLCAnYWN0aXZpdGk6SW5wdXRPdXRwdXQnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWlucHV0T3V0cHV0KSB7XHJcbiAgICAgIC8vIGlvUGFyYW1ldGVyIGNhbm5vdCBleGlzdCB5ZXQsIHJldHVybiBwcm9wZXJ0eSB2YWx1ZVxyXG4gICAgICByZXR1cm4gcHJvcGVydHlWYWx1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIGFjdGl2aXRpIGlucHV0IHBhcmFtZXRlclxyXG4gIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfSU5QVVRfUEFSQU1FVEVSX1RZUEUpIHtcclxuICAgIGlvUGFyYW1ldGVyID0gZmluZElucHV0UGFyYW1ldGVyKGlucHV0T3V0cHV0LCBiaW5kaW5nKTtcclxuXHJcbiAgICBpZiAoaW9QYXJhbWV0ZXIpIHtcclxuICAgICAgaWYgKGJpbmRpbmcuc2NyaXB0Rm9ybWF0KSB7XHJcbiAgICAgICAgaWYgKGlvUGFyYW1ldGVyLmRlZmluaXRpb24pIHtcclxuICAgICAgICAgIHJldHVybiBpb1BhcmFtZXRlci5kZWZpbml0aW9uLnZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZXR1cm4gaW9QYXJhbWV0ZXIudmFsdWUgfHwgJyc7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcHJvcGVydHlWYWx1ZTtcclxuICB9XHJcblxyXG4gIC8vIGFjdGl2aXRpIG91dHB1dCBwYXJhbWV0ZXJcclxuICBpZiAoYmluZGluZy50eXBlID09PSBBQ1RJVklUSV9PVVRQVVRfUEFSQU1FVEVSX1RZUEUpIHtcclxuICAgIGlvUGFyYW1ldGVyID0gZmluZE91dHB1dFBhcmFtZXRlcihpbnB1dE91dHB1dCwgYmluZGluZyk7XHJcblxyXG4gICAgaWYgKGlvUGFyYW1ldGVyKSB7XHJcbiAgICAgIHJldHVybiBpb1BhcmFtZXRlci5uYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlO1xyXG4gIH1cclxuXHJcblxyXG4gIHZhciBpb0VsZW1lbnQ7XHJcblxyXG4gIGlmIChJTl9PVVRfQklORElOR19UWVBFUy5pbmRleE9mKGJpbmRpbmdUeXBlKSAhPSAtMSkge1xyXG4gICAgaW9FbGVtZW50ID0gZmluZEFjdGl2aXRpSW5PdXQoYm8sIGJpbmRpbmcpO1xyXG5cclxuICAgIGlmIChpb0VsZW1lbnQpIHtcclxuICAgICAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9JTl9CVVNJTkVTU19LRVlfVFlQRSkge1xyXG4gICAgICAgIHJldHVybiBpb0VsZW1lbnQuYnVzaW5lc3NLZXk7XHJcbiAgICAgIH0gZWxzZVxyXG4gICAgICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX09VVF9UWVBFKSB7XHJcbiAgICAgICAgcmV0dXJuIGlvRWxlbWVudC50YXJnZXQ7XHJcbiAgICAgIH0gZWxzZVxyXG4gICAgICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX0lOX1RZUEUpIHtcclxuICAgICAgICByZXR1cm4gaW9FbGVtZW50W2JpbmRpbmcuZXhwcmVzc2lvbiA/ICdzb3VyY2VFeHByZXNzaW9uJyA6ICdzb3VyY2UnXTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwcm9wZXJ0eVZhbHVlO1xyXG4gIH1cclxuXHJcbiAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9FWEVDVVRJT05fTElTVEVORVJfVFlQRSkge1xyXG4gICAgdmFyIGV4ZWN1dGlvbkxpc3RlbmVyO1xyXG4gICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgIGV4ZWN1dGlvbkxpc3RlbmVyID0gYm8uZ2V0KCdleGVjdXRpb25MaXN0ZW5lcicpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgZXhlY3V0aW9uTGlzdGVuZXIgPSBmaW5kRXh0ZW5zaW9uKGJvLCAnYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXInKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gZXhlY3V0aW9uTGlzdGVuZXIuc2NyaXB0LnZhbHVlO1xyXG4gIH1cclxuXHJcbiAgdmFyIGZpZWxkSW5qZWN0aW9uO1xyXG4gIGlmIChBQ1RJVklUSV9GSUVMRCA9PT0gYmluZGluZ1R5cGUpIHtcclxuICAgIHZhciBmaWVsZEluamVjdGlvbnMgPSBmaW5kRXh0ZW5zaW9ucyhibywgWyAnYWN0aXZpdGk6RmllbGQnIF0pO1xyXG4gICAgZmllbGRJbmplY3Rpb25zLmZvckVhY2goZnVuY3Rpb24oaXRlbSkge1xyXG4gICAgICBpZiAoaXRlbS5uYW1lID09PSBiaW5kaW5nLm5hbWUpIHtcclxuICAgICAgICBmaWVsZEluamVjdGlvbiA9IGl0ZW07XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgaWYgKGZpZWxkSW5qZWN0aW9uKSB7XHJcbiAgICAgIHJldHVybiBmaWVsZEluamVjdGlvbi5zdHJpbmcgfHwgZmllbGRJbmplY3Rpb24uZXhwcmVzc2lvbjtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHRocm93IHVua25vd25Qcm9wZXJ0eUJpbmRpbmcocHJvcGVydHkpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cy5nZXRQcm9wZXJ0eVZhbHVlID0gZ2V0UHJvcGVydHlWYWx1ZTtcclxuXHJcblxyXG4vKipcclxuICogUmV0dXJuIGFuIHVwZGF0ZSBvcGVyYXRpb24gdGhhdCBjaGFuZ2VzIHRoZSBkaWFncmFtXHJcbiAqIGVsZW1lbnQncyBjdXN0b20gcHJvcGVydHkgdG8gdGhlIGdpdmVuIHZhbHVlLlxyXG4gKlxyXG4gKiBUaGUgcmVzcG9uc2Ugb2YgdGhpcyBtZXRob2Qgd2lsbCBiZSBwcm9jZXNzZWQgdmlhXHJcbiAqIHtAbGluayBQcm9wZXJ0aWVzUGFuZWwjYXBwbHlDaGFuZ2VzfS5cclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICogQHBhcmFtIHtTdHJpbmd9IHZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqXHJcbiAqIEByZXR1cm4ge09iamVjdHxBcnJheTxPYmplY3Q+fSByZXN1bHRzIHRvIGJlIHByb2Nlc3NlZFxyXG4gKi9cclxuZnVuY3Rpb24gc2V0UHJvcGVydHlWYWx1ZShlbGVtZW50LCBwcm9wZXJ0eSwgdmFsdWUsIGJwbW5GYWN0b3J5KSB7XHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBiaW5kaW5nID0gcHJvcGVydHkuYmluZGluZyxcclxuICAgICAgc2NvcGUgPSBwcm9wZXJ0eS5zY29wZTtcclxuXHJcbiAgdmFyIGJpbmRpbmdUeXBlID0gYmluZGluZy50eXBlLFxyXG4gICAgICBiaW5kaW5nTmFtZSA9IGJpbmRpbmcubmFtZTtcclxuXHJcbiAgdmFyIHByb3BlcnR5VmFsdWU7XHJcblxyXG4gIHZhciB1cGRhdGVzID0gW107XHJcblxyXG4gIHZhciBleHRlbnNpb25FbGVtZW50cztcclxuXHJcbiAgaWYgKEVYVEVOU0lPTl9CSU5ESU5HX1RZUEVTLmluZGV4T2YoYmluZGluZ1R5cGUpICE9PSAtMSkge1xyXG4gICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBiby5nZXQoJ2V4dGVuc2lvbkVsZW1lbnRzJyk7XHJcblxyXG4gICAgLy8gY3JlYXRlIGV4dGVuc2lvbiBlbGVtZW50cywgaWYgdGhleSBkbyBub3QgZXhpc3QgKHlldClcclxuICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnLCBudWxsLCBlbGVtZW50LCBicG1uRmFjdG9yeSk7XHJcblxyXG4gICAgICB1cGRhdGVzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KFxyXG4gICAgICAgIGVsZW1lbnQsIGJvLCBvYmplY3RXaXRoS2V5KCdleHRlbnNpb25FbGVtZW50cycsIGV4dGVuc2lvbkVsZW1lbnRzKVxyXG4gICAgICApKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGlmIChzY29wZSkge1xyXG4gICAgYm8gPSBmaW5kRXh0ZW5zaW9uKGJvLCBzY29wZS5uYW1lKTtcclxuICAgIGlmICghYm8pIHtcclxuICAgICAgYm8gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoc2NvcGUubmFtZSwgbnVsbCwgZWxlbWVudCwgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChcclxuICAgICAgICBibywgZXh0ZW5zaW9uRWxlbWVudHMsICd2YWx1ZXMnLCBbIGJvIF1cclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBwcm9wZXJ0eVxyXG4gIGlmIChiaW5kaW5nVHlwZSA9PT0gJ3Byb3BlcnR5Jykge1xyXG5cclxuICAgIGlmIChiaW5kaW5nTmFtZSA9PT0gJ2NvbmRpdGlvbkV4cHJlc3Npb24nKSB7XHJcblxyXG4gICAgICBwcm9wZXJ0eVZhbHVlID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkZvcm1hbEV4cHJlc3Npb24nLCB7XHJcbiAgICAgICAgYm9keTogdmFsdWUsXHJcbiAgICAgICAgbGFuZ3VhZ2U6IGJpbmRpbmcuc2NyaXB0Rm9ybWF0XHJcbiAgICAgIH0sIGJvLCBicG1uRmFjdG9yeSk7XHJcbiAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgdmFyIG1vZGRsZVByb3BlcnR5RGVzY3JpcHRvciA9IGJvLiRkZXNjcmlwdG9yLnByb3BlcnRpZXNCeU5hbWVbYmluZGluZ05hbWVdO1xyXG5cclxuICAgICAgdmFyIG1vZGRsZVR5cGUgPSBtb2RkbGVQcm9wZXJ0eURlc2NyaXB0b3IudHlwZTtcclxuXHJcbiAgICAgIC8vIG1ha2Ugc3VyZSB3ZSBvbmx5IHVwZGF0ZSBTdHJpbmcsIEludGVnZXIsIFJlYWwgYW5kXHJcbiAgICAgIC8vIEJvb2xlYW4gcHJvcGVydGllcyAoZG8gbm90IGFjY2lkZW50YWxseSBvdmVycmlkZSBjb21wbGV4IG9iamVjdHMuLi4pXHJcbiAgICAgIGlmIChCQVNJQ19NT0RETEVfVFlQRVMuaW5kZXhPZihtb2RkbGVUeXBlKSA9PT0gLTEpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2Nhbm5vdCBzZXQgbW9kZGxlIHR5cGUgPCcgKyBtb2RkbGVUeXBlICsgJz4nKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKG1vZGRsZVR5cGUgPT09ICdCb29sZWFuJykge1xyXG4gICAgICAgIHByb3BlcnR5VmFsdWUgPSAhIXZhbHVlO1xyXG4gICAgICB9IGVsc2VcclxuICAgICAgaWYgKG1vZGRsZVR5cGUgPT09ICdJbnRlZ2VyJykge1xyXG4gICAgICAgIHByb3BlcnR5VmFsdWUgPSBwYXJzZUludCh2YWx1ZSwgMTApO1xyXG5cclxuICAgICAgICBpZiAoaXNOYU4ocHJvcGVydHlWYWx1ZSkpIHtcclxuICAgICAgICAgIC8vIGRvIG5vdCB3cml0ZSBOYU4gdmFsdWVcclxuICAgICAgICAgIHByb3BlcnR5VmFsdWUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHByb3BlcnR5VmFsdWUgPSB2YWx1ZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChwcm9wZXJ0eVZhbHVlICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChcclxuICAgICAgICBlbGVtZW50LCBibywgb2JqZWN0V2l0aEtleShiaW5kaW5nTmFtZSwgcHJvcGVydHlWYWx1ZSlcclxuICAgICAgKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBhY3Rpdml0aTpwcm9wZXJ0eVxyXG4gIHZhciBhY3Rpdml0aVByb3BlcnRpZXMsXHJcbiAgICAgIGV4aXN0aW5nQWN0aXZpdGlQcm9wZXJ0eSxcclxuICAgICAgbmV3QWN0aXZpdGlQcm9wZXJ0eTtcclxuXHJcbiAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9QUk9QRVJUWV9UWVBFKSB7XHJcblxyXG4gICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgIGFjdGl2aXRpUHJvcGVydGllcyA9IGJvLmdldCgncHJvcGVydGllcycpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgYWN0aXZpdGlQcm9wZXJ0aWVzID0gZmluZEV4dGVuc2lvbihleHRlbnNpb25FbGVtZW50cywgJ2FjdGl2aXRpOlByb3BlcnRpZXMnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWFjdGl2aXRpUHJvcGVydGllcykge1xyXG4gICAgICBhY3Rpdml0aVByb3BlcnRpZXMgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2FjdGl2aXRpOlByb3BlcnRpZXMnLCBudWxsLCBibywgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChcclxuICAgICAgICAgIGVsZW1lbnQsIGJvLCB7IHByb3BlcnRpZXM6IGFjdGl2aXRpUHJvcGVydGllcyB9XHJcbiAgICAgICAgKSk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChcclxuICAgICAgICAgIGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCAndmFsdWVzJywgWyBhY3Rpdml0aVByb3BlcnRpZXMgXVxyXG4gICAgICAgICkpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZXhpc3RpbmdBY3Rpdml0aVByb3BlcnR5ID0gZmluZEFjdGl2aXRpUHJvcGVydHkoYWN0aXZpdGlQcm9wZXJ0aWVzLCBiaW5kaW5nKTtcclxuXHJcbiAgICBuZXdBY3Rpdml0aVByb3BlcnR5ID0gY3JlYXRlQWN0aXZpdGlQcm9wZXJ0eShiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgIHVwZGF0ZXMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgZWxlbWVudCxcclxuICAgICAgYWN0aXZpdGlQcm9wZXJ0aWVzLFxyXG4gICAgICAndmFsdWVzJyxcclxuICAgICAgbnVsbCxcclxuICAgICAgWyBuZXdBY3Rpdml0aVByb3BlcnR5IF0sXHJcbiAgICAgIGV4aXN0aW5nQWN0aXZpdGlQcm9wZXJ0eSA/IFsgZXhpc3RpbmdBY3Rpdml0aVByb3BlcnR5IF0gOiBbXVxyXG4gICAgKSk7XHJcbiAgfVxyXG5cclxuICAvLyBhY3Rpdml0aTppbnB1dFBhcmFtZXRlclxyXG4gIC8vIGFjdGl2aXRpOm91dHB1dFBhcmFtZXRlclxyXG4gIHZhciBpbnB1dE91dHB1dCxcclxuICAgICAgZXhpc3RpbmdJb1BhcmFtZXRlcixcclxuICAgICAgbmV3SW9QYXJhbWV0ZXI7XHJcblxyXG4gIGlmIChJT19CSU5ESU5HX1RZUEVTLmluZGV4T2YoYmluZGluZ1R5cGUpICE9PSAtMSkge1xyXG5cclxuICAgIGlmIChzY29wZSkge1xyXG4gICAgICBpbnB1dE91dHB1dCA9IGJvLmdldCgnaW5wdXRPdXRwdXQnKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlucHV0T3V0cHV0ID0gZmluZEV4dGVuc2lvbihleHRlbnNpb25FbGVtZW50cywgJ2FjdGl2aXRpOklucHV0T3V0cHV0Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gY3JlYXRlIGlucHV0T3V0cHV0IGVsZW1lbnQsIGlmIGl0IGRvIG5vdCBleGlzdCAoeWV0KVxyXG4gICAgaWYgKCFpbnB1dE91dHB1dCkge1xyXG4gICAgICBpbnB1dE91dHB1dCA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6SW5wdXRPdXRwdXQnLCBudWxsLCBibywgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgICAgaWYgKHNjb3BlKSB7XHJcbiAgICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChcclxuICAgICAgICAgIGVsZW1lbnQsIGJvLCB7IGlucHV0T3V0cHV0OiBpbnB1dE91dHB1dCB9XHJcbiAgICAgICAgKSk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgdXBkYXRlcy5wdXNoKGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChcclxuICAgICAgICAgIGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCAndmFsdWVzJywgaW5wdXRPdXRwdXRcclxuICAgICAgICApKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9JTlBVVF9QQVJBTUVURVJfVFlQRSkge1xyXG5cclxuICAgIGV4aXN0aW5nSW9QYXJhbWV0ZXIgPSBmaW5kSW5wdXRQYXJhbWV0ZXIoaW5wdXRPdXRwdXQsIGJpbmRpbmcpO1xyXG5cclxuICAgIG5ld0lvUGFyYW1ldGVyID0gY3JlYXRlSW5wdXRQYXJhbWV0ZXIoYmluZGluZywgdmFsdWUsIGJwbW5GYWN0b3J5KTtcclxuXHJcbiAgICB1cGRhdGVzLnB1c2goY21kSGVscGVyLmFkZEFuZFJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoXHJcbiAgICAgIGVsZW1lbnQsXHJcbiAgICAgIGlucHV0T3V0cHV0LFxyXG4gICAgICAnaW5wdXRQYXJhbWV0ZXJzJyxcclxuICAgICAgbnVsbCxcclxuICAgICAgWyBuZXdJb1BhcmFtZXRlciBdLFxyXG4gICAgICBleGlzdGluZ0lvUGFyYW1ldGVyID8gWyBleGlzdGluZ0lvUGFyYW1ldGVyIF0gOiBbXVxyXG4gICAgKSk7XHJcbiAgfVxyXG5cclxuICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX09VVFBVVF9QQVJBTUVURVJfVFlQRSkge1xyXG5cclxuICAgIGV4aXN0aW5nSW9QYXJhbWV0ZXIgPSBmaW5kT3V0cHV0UGFyYW1ldGVyKGlucHV0T3V0cHV0LCBiaW5kaW5nKTtcclxuXHJcbiAgICBuZXdJb1BhcmFtZXRlciA9IGNyZWF0ZU91dHB1dFBhcmFtZXRlcihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgIHVwZGF0ZXMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgZWxlbWVudCxcclxuICAgICAgaW5wdXRPdXRwdXQsXHJcbiAgICAgICdvdXRwdXRQYXJhbWV0ZXJzJyxcclxuICAgICAgbnVsbCxcclxuICAgICAgWyBuZXdJb1BhcmFtZXRlciBdLFxyXG4gICAgICBleGlzdGluZ0lvUGFyYW1ldGVyID8gWyBleGlzdGluZ0lvUGFyYW1ldGVyIF0gOiBbXVxyXG4gICAgKSk7XHJcbiAgfVxyXG5cclxuXHJcbiAgLy8gYWN0aXZpdGk6aW5cclxuICAvLyBhY3Rpdml0aTpvdXRcclxuICAvLyBhY3Rpdml0aTppbjpidXNpbmVzc0tleVxyXG4gIHZhciBleGlzdGluZ0luT3V0LFxyXG4gICAgICBuZXdJbk91dDtcclxuXHJcbiAgaWYgKElOX09VVF9CSU5ESU5HX1RZUEVTLmluZGV4T2YoYmluZGluZ1R5cGUpICE9PSAtMSkge1xyXG5cclxuICAgIGV4aXN0aW5nSW5PdXQgPSBmaW5kQWN0aXZpdGlJbk91dChibywgYmluZGluZyk7XHJcblxyXG4gICAgaWYgKGJpbmRpbmdUeXBlID09PSBBQ1RJVklUSV9JTl9UWVBFKSB7XHJcbiAgICAgIG5ld0luT3V0ID0gY3JlYXRlQWN0aXZpdGlJbihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpO1xyXG4gICAgfSBlbHNlXHJcbiAgICBpZiAoYmluZGluZ1R5cGUgPT09IEFDVElWSVRJX09VVF9UWVBFKSB7XHJcbiAgICAgIG5ld0luT3V0ID0gY3JlYXRlQWN0aXZpdGlPdXQoYmluZGluZywgdmFsdWUsIGJwbW5GYWN0b3J5KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIG5ld0luT3V0ID0gY3JlYXRlQWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleShiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZXMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgZWxlbWVudCxcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgICd2YWx1ZXMnLFxyXG4gICAgICBudWxsLFxyXG4gICAgICBbIG5ld0luT3V0IF0sXHJcbiAgICAgIGV4aXN0aW5nSW5PdXQgPyBbIGV4aXN0aW5nSW5PdXQgXSA6IFtdXHJcbiAgICApKTtcclxuICB9XHJcblxyXG4gIGlmIChiaW5kaW5nVHlwZSA9PT0gQUNUSVZJVElfRklFTEQpIHtcclxuICAgIHZhciBleGlzdGluZ0ZpZWxkSW5qZWN0aW9ucyA9IGZpbmRFeHRlbnNpb25zKGJvLCBbICdhY3Rpdml0aTpGaWVsZCcgXSk7XHJcbiAgICB2YXIgbmV3RmllbGRJbmplY3Rpb25zID0gW107XHJcblxyXG4gICAgaWYgKGV4aXN0aW5nRmllbGRJbmplY3Rpb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgZXhpc3RpbmdGaWVsZEluamVjdGlvbnMuZm9yRWFjaChmdW5jdGlvbihpdGVtKSB7XHJcbiAgICAgICAgaWYgKGl0ZW0ubmFtZSA9PT0gYmluZGluZy5uYW1lKSB7XHJcbiAgICAgICAgICBuZXdGaWVsZEluamVjdGlvbnMucHVzaChjcmVhdGVBY3Rpdml0aUZpZWxkSW5qZWN0aW9uKGJpbmRpbmcsIHZhbHVlLCBicG1uRmFjdG9yeSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBuZXdGaWVsZEluamVjdGlvbnMucHVzaChpdGVtKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgbmV3RmllbGRJbmplY3Rpb25zLnB1c2goY3JlYXRlQWN0aXZpdGlGaWVsZEluamVjdGlvbihiaW5kaW5nLCB2YWx1ZSwgYnBtbkZhY3RvcnkpKTtcclxuICAgIH1cclxuXHJcbiAgICB1cGRhdGVzLnB1c2goY21kSGVscGVyLmFkZEFuZFJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoXHJcbiAgICAgIGVsZW1lbnQsXHJcbiAgICAgIGV4dGVuc2lvbkVsZW1lbnRzLFxyXG4gICAgICAndmFsdWVzJyxcclxuICAgICAgbnVsbCxcclxuICAgICAgbmV3RmllbGRJbmplY3Rpb25zLFxyXG4gICAgICBleGlzdGluZ0ZpZWxkSW5qZWN0aW9ucyA/IGV4aXN0aW5nRmllbGRJbmplY3Rpb25zIDogW11cclxuICAgICkpO1xyXG4gIH1cclxuXHJcbiAgaWYgKHVwZGF0ZXMubGVuZ3RoKSB7XHJcbiAgICByZXR1cm4gdXBkYXRlcztcclxuICB9XHJcblxyXG4gIC8vIHF1aWNrIHdhcm5pbmcgZm9yIGJldHRlciBkZWJ1Z2dpbmdcclxuICBjb25zb2xlLndhcm4oJ25vIHVwZGF0ZScsIGVsZW1lbnQsIHByb3BlcnR5LCB2YWx1ZSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzLnNldFByb3BlcnR5VmFsdWUgPSBzZXRQcm9wZXJ0eVZhbHVlO1xyXG5cclxuLyoqXHJcbiAqIFZhbGlkYXRlIHZhbHVlIG9mIGEgZ2l2ZW4gcHJvcGVydHkuXHJcbiAqXHJcbiAqIEBwYXJhbSB7U3RyaW5nfSB2YWx1ZVxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICogQHBhcmFtIHtGdW5jdGlvbn0gdHJhbnNsYXRlXHJcbiAqXHJcbiAqIEByZXR1cm4ge09iamVjdH0gd2l0aCB2YWxpZGF0aW9uIGVycm9yc1xyXG4gKi9cclxuZnVuY3Rpb24gdmFsaWRhdGVWYWx1ZSh2YWx1ZSwgcHJvcGVydHksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgY29uc3RyYWludHMgPSBwcm9wZXJ0eS5jb25zdHJhaW50cyB8fCB7fTtcclxuXHJcbiAgaWYgKGNvbnN0cmFpbnRzLm5vdEVtcHR5ICYmIGlzRW1wdHkodmFsdWUpKSB7XHJcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdNdXN0IG5vdCBiZSBlbXB0eScpO1xyXG4gIH1cclxuXHJcbiAgaWYgKGNvbnN0cmFpbnRzLm1heExlbmd0aCAmJiB2YWx1ZS5sZW5ndGggPiBjb25zdHJhaW50cy5tYXhMZW5ndGgpIHtcclxuICAgIHJldHVybiB0cmFuc2xhdGUoJ011c3QgaGF2ZSBtYXggbGVuZ3RoIHtsZW5ndGh9JywgeyBsZW5ndGg6IGNvbnN0cmFpbnRzLm1heExlbmd0aCB9KTtcclxuICB9XHJcblxyXG4gIGlmIChjb25zdHJhaW50cy5taW5MZW5ndGggJiYgdmFsdWUubGVuZ3RoIDwgY29uc3RyYWludHMubWluTGVuZ3RoKSB7XHJcbiAgICByZXR1cm4gdHJhbnNsYXRlKCdNdXN0IGhhdmUgbWluIGxlbmd0aCB7bGVuZ3RofScsIHsgbGVuZ3RoOiBjb25zdHJhaW50cy5taW5MZW5ndGggfSk7XHJcbiAgfVxyXG5cclxuICB2YXIgcGF0dGVybiA9IGNvbnN0cmFpbnRzLnBhdHRlcm4sXHJcbiAgICAgIG1lc3NhZ2U7XHJcblxyXG4gIGlmIChwYXR0ZXJuKSB7XHJcblxyXG4gICAgaWYgKHR5cGVvZiBwYXR0ZXJuICE9PSAnc3RyaW5nJykge1xyXG4gICAgICBtZXNzYWdlID0gcGF0dGVybi5tZXNzYWdlO1xyXG4gICAgICBwYXR0ZXJuID0gcGF0dGVybi52YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIW1hdGNoZXNQYXR0ZXJuKHZhbHVlLCBwYXR0ZXJuKSkge1xyXG4gICAgICByZXR1cm4gbWVzc2FnZSB8fCB0cmFuc2xhdGUoJ011c3QgbWF0Y2ggcGF0dGVybiB7cGF0dGVybn0nLCB7IHBhdHRlcm46IHBhdHRlcm4gfSk7XHJcbiAgICB9XHJcbiAgfVxyXG59XHJcblxyXG5cclxuLy8gbWlzYyBoZWxwZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbmZ1bmN0aW9uIHByb3BlcnR5V2l0aFNjb3BlKHByb3BlcnR5LCBzY29wZU5hbWUpIHtcclxuICBpZiAoIXNjb3BlTmFtZSkge1xyXG4gICAgcmV0dXJuIHByb3BlcnR5O1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGFzc2lnbih7fSwgcHJvcGVydHksIHtcclxuICAgIHNjb3BlOiB7XHJcbiAgICAgIG5hbWU6IHNjb3BlTmFtZVxyXG4gICAgfVxyXG4gIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJuIGFuIG9iamVjdCB3aXRoIGEgc2luZ2xlIGtleSAtPiB2YWx1ZSBhc3NvY2lhdGlvbi5cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IGtleVxyXG4gKiBAcGFyYW0ge0FueX0gdmFsdWVcclxuICpcclxuICogQHJldHVybiB7T2JqZWN0fVxyXG4gKi9cclxuZnVuY3Rpb24gb2JqZWN0V2l0aEtleShrZXksIHZhbHVlKSB7XHJcbiAgdmFyIG9iaiA9IHt9O1xyXG5cclxuICBvYmpba2V5XSA9IHZhbHVlO1xyXG5cclxuICByZXR1cm4gb2JqO1xyXG59XHJcblxyXG4vKipcclxuICogRG9lcyB0aGUgZ2l2ZW4gc3RyaW5nIG1hdGNoIHRoZSBzcGVjaWZpZWQgcGF0dGVybj9cclxuICpcclxuICogQHBhcmFtIHtTdHJpbmd9IHN0clxyXG4gKiBAcGFyYW0ge1N0cmluZ30gcGF0dGVyblxyXG4gKlxyXG4gKiBAcmV0dXJuIHtCb29sZWFufVxyXG4gKi9cclxuZnVuY3Rpb24gbWF0Y2hlc1BhdHRlcm4oc3RyLCBwYXR0ZXJuKSB7XHJcbiAgdmFyIHJlZ2V4cCA9IG5ldyBSZWdFeHAocGF0dGVybik7XHJcblxyXG4gIHJldHVybiByZWdleHAudGVzdChzdHIpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0VtcHR5KHN0cikge1xyXG4gIHJldHVybiAhc3RyIHx8IC9eXFxzKiQvLnRlc3Qoc3RyKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhIG5ldyB7QGxpbmsgRXJyb3J9IGluZGljYXRpbmcgYW4gdW5rbm93blxyXG4gKiBwcm9wZXJ0eSBiaW5kaW5nLlxyXG4gKlxyXG4gKiBAcGFyYW0ge1Byb3BlcnR5RGVzY3JpcHRvcn0gcHJvcGVydHlcclxuICpcclxuICogQHJldHVybiB7RXJyb3J9XHJcbiAqL1xyXG5mdW5jdGlvbiB1bmtub3duUHJvcGVydHlCaW5kaW5nKHByb3BlcnR5KSB7XHJcbiAgdmFyIGJpbmRpbmcgPSBwcm9wZXJ0eS5iaW5kaW5nO1xyXG5cclxuICByZXR1cm4gbmV3IEVycm9yKCd1bmtub3duIGJpbmRpbmc6IDwnICsgYmluZGluZy50eXBlICsgJz4nKTtcclxufVxyXG4iLCJtb2R1bGUuZXhwb3J0cyA9IHtcclxuICBfX2RlcGVuZHNfXzogW1xyXG4gICAgcmVxdWlyZSgnLi9lbGVtZW50LXRlbXBsYXRlcy9pbmRleCcpLFxyXG4gICAgcmVxdWlyZSgnZGlhZ3JhbS1qcy9saWIvaTE4bi90cmFuc2xhdGUnKS5kZWZhdWx0XHJcbiAgXSxcclxuICBfX2luaXRfXzogWyAncHJvcGVydGllc1Byb3ZpZGVyJyBdLFxyXG4gIHByb3BlcnRpZXNQcm92aWRlcjogWyAndHlwZScsIHJlcXVpcmUoJy4vQWN0aXZpdGlQcm9wZXJ0aWVzUHJvdmlkZXInKSBdXHJcbn07XHJcblxyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgYXN5bmNDb250aW51YXRpb24gPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0FzeW5jQ29udGludWF0aW9uJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6QXN5bmNDYXBhYmxlJykpIHtcclxuXHJcbiAgICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoYXN5bmNDb250aW51YXRpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGdldEJ1c2luZXNzT2JqZWN0XHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgfVxyXG59OyIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjYWxsYWJsZSA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQ2FsbGFibGUnKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgZmxhdHRlbkRlZXAgPSByZXF1aXJlKCdsb2Rhc2gvZmxhdHRlbkRlZXAnKTtcclxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJ2xvZGFzaC9hc3NpZ24nKTtcclxuXHJcbmZ1bmN0aW9uIGdldENhbGxhYmxlVHlwZShlbGVtZW50KSB7XHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBib0NhbGxlZEVsZW1lbnQgPSBiby5nZXQoJ2NhbGxlZEVsZW1lbnQnKSxcclxuICAgICAgYm9DYXNlUmVmID0gYm8uZ2V0KCdhY3Rpdml0aTpjYXNlUmVmJyk7XHJcblxyXG4gIHZhciBjYWxsQWN0aXZpdHlUeXBlID0gJyc7XHJcbiAgaWYgKHR5cGVvZiBib0NhbGxlZEVsZW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICBjYWxsQWN0aXZpdHlUeXBlID0gJ2JwbW4nO1xyXG4gIH0gZWxzZVxyXG5cclxuICBpZiAodHlwZW9mIGJvQ2FzZVJlZiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgIGNhbGxBY3Rpdml0eVR5cGUgPSAnY21tbic7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gY2FsbEFjdGl2aXR5VHlwZTtcclxufVxyXG5cclxudmFyIERFRkFVTFRfUFJPUFMgPSB7XHJcbiAgY2FsbGVkRWxlbWVudDogdW5kZWZpbmVkLFxyXG4gICdhY3Rpdml0aTpjYWxsZWRFbGVtZW50QmluZGluZyc6ICdsYXRlc3QnLFxyXG4gICdhY3Rpdml0aTpjYWxsZWRFbGVtZW50VmVyc2lvbic6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6Y2FsbGVkRWxlbWVudFRlbmFudElkJzogdW5kZWZpbmVkLFxyXG4gICdhY3Rpdml0aTp2YXJpYWJsZU1hcHBpbmdDbGFzcycgOiB1bmRlZmluZWQsXHJcbiAgJ2FjdGl2aXRpOnZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbicgOiB1bmRlZmluZWQsXHJcbiAgJ2FjdGl2aXRpOmNhc2VSZWYnOiB1bmRlZmluZWQsXHJcbiAgJ2FjdGl2aXRpOmNhc2VCaW5kaW5nJzogJ2xhdGVzdCcsXHJcbiAgJ2FjdGl2aXRpOmNhc2VWZXJzaW9uJzogdW5kZWZpbmVkLFxyXG4gICdhY3Rpdml0aTpjYXNlVGVuYW50SWQnOiB1bmRlZmluZWRcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgaWYgKCFpcyhlbGVtZW50LCAnYWN0aXZpdGk6Q2FsbEFjdGl2aXR5JykpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3Rvcnkuc2VsZWN0Qm94KHtcclxuICAgIGlkIDogJ2NhbGxBY3Rpdml0eScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdDYWxsQWN0aXZpdHkgVHlwZScpLFxyXG4gICAgc2VsZWN0T3B0aW9uczogW1xyXG4gICAgICB7IG5hbWU6ICdCUE1OJywgdmFsdWU6ICdicG1uJyB9LFxyXG4gICAgICB7IG5hbWU6ICdDTU1OJywgdmFsdWU6ICdjbW1uJyB9XHJcbiAgICBdLFxyXG4gICAgZW1wdHlQYXJhbWV0ZXI6IHRydWUsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY2FsbEFjdGl2aXR5VHlwZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgY2FsbEFjdGl2aXR5VHlwZTogZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciB0eXBlID0gdmFsdWVzLmNhbGxBY3Rpdml0eVR5cGU7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIERFRkFVTFRfUFJPUFMpO1xyXG5cclxuICAgICAgaWYgKHR5cGUgPT09ICdicG1uJykge1xyXG4gICAgICAgIHByb3BzLmNhbGxlZEVsZW1lbnQgPSAnJztcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmICh0eXBlID09PSAnY21tbicpIHtcclxuICAgICAgICBwcm9wc1snYWN0aXZpdGk6Y2FzZVJlZiddID0gJyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBwcm9wcyk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGNhbGxhYmxlKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBnZXRDYWxsYWJsZVR5cGU6IGdldENhbGxhYmxlVHlwZVxyXG4gIH0sIHRyYW5zbGF0ZSkpO1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZmxhdHRlbkRlZXAoZ3JvdXAuZW50cmllcyk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgY2FuZGlkYXRlU3RhcnRlciA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQ2FuZGlkYXRlU3RhcnRlcicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2FjdGl2aXRpOlByb2Nlc3MnKSB8fFxyXG4gICAgICBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpICYmIGJ1c2luZXNzT2JqZWN0LmdldCgncHJvY2Vzc1JlZicpKSB7XHJcblxyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGNhbmRpZGF0ZVN0YXJ0ZXIoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKCFpcyhibywgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGJvO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGJvLmdldCgncHJvY2Vzc1JlZicpO1xyXG4gICAgICB9XHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgfVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgaXNBbnkgPSByZXF1aXJlKCdicG1uLWpzL2xpYi9mZWF0dXJlcy9tb2RlbGluZy91dGlsL01vZGVsaW5nVXRpbCcpLmlzQW55LFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgZXNjYXBlSFRNTCA9IHJlcXVpcmUoJy4uLy4uLy4uL1V0aWxzJykuZXNjYXBlSFRNTCxcclxuICAgIGRvbVF1ZXJ5ID0gcmVxdWlyZSgnbWluLWRvbScpLnF1ZXJ5LFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyksXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyksXHJcbiAgICBzY3JpcHRJbXBsZW1lbnRhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vU2NyaXB0Jyk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG4gIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoIWJvKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgY29uZGl0aW9uYWxFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gIGlmICghKGlzKGVsZW1lbnQsICdicG1uOlNlcXVlbmNlRmxvdycpICYmIGlzQ29uZGl0aW9uYWxTb3VyY2UoZWxlbWVudC5zb3VyY2UpKVxyXG4gICAgJiYgIWNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgc2NyaXB0ID0gc2NyaXB0SW1wbGVtZW50YXRpb24oJ2xhbmd1YWdlJywgJ2JvZHknLCB0cnVlLCB0cmFuc2xhdGUpO1xyXG4gIGdyb3VwLmVudHJpZXMucHVzaCh7XHJcbiAgICBpZDogJ2NvbmRpdGlvbicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdDb25kaXRpb24nKSxcclxuICAgIGh0bWw6ICc8ZGl2IGNsYXNzPVwiYnBwLXJvd1wiPicgK1xyXG4gICAgICAgICAgICAgICc8bGFiZWwgZm9yPVwiY2FtLWNvbmRpdGlvbi10eXBlXCI+JysgZXNjYXBlSFRNTCh0cmFuc2xhdGUoJ0NvbmRpdGlvbiBUeXBlJykpICsgJzwvbGFiZWw+JyArXHJcbiAgICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlclwiPicgK1xyXG4gICAgICAgICAgICAgICAgJzxzZWxlY3QgaWQ9XCJjYW0tY29uZGl0aW9uLXR5cGVcIiBuYW1lPVwiY29uZGl0aW9uVHlwZVwiIGRhdGEtdmFsdWU+JyArXHJcbiAgICAgICAgICAgICAgICAgICc8b3B0aW9uIHZhbHVlPVwiZXhwcmVzc2lvblwiPicrIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdFeHByZXNzaW9uJykpICsgJzwvb3B0aW9uPicgK1xyXG4gICAgICAgICAgICAgICAgICAnPG9wdGlvbiB2YWx1ZT1cInNjcmlwdFwiPicrIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdTY3JpcHQnKSkgKyAnPC9vcHRpb24+JyArXHJcbiAgICAgICAgICAgICAgICAgICc8b3B0aW9uIHZhbHVlPVwiXCIgc2VsZWN0ZWQ+PC9vcHRpb24+JyArXHJcbiAgICAgICAgICAgICAgICAnPC9zZWxlY3Q+JyArXHJcbiAgICAgICAgICAgICAgJzwvZGl2PicgK1xyXG4gICAgICAgICAgICAnPC9kaXY+JyArXHJcblxyXG4gICAgICAgICAgICAvLyBleHByZXNzaW9uXHJcbiAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLXJvd1wiPicgK1xyXG4gICAgICAgICAgICAgICc8bGFiZWwgZm9yPVwiY2FtLWNvbmRpdGlvblwiIGRhdGEtc2hvdz1cImlzRXhwcmVzc2lvblwiPicgKyBlc2NhcGVIVE1MKHRyYW5zbGF0ZSgnRXhwcmVzc2lvbicpKSArICc8L2xhYmVsPicgK1xyXG4gICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXJcIiBkYXRhLXNob3c9XCJpc0V4cHJlc3Npb25cIj4nICtcclxuICAgICAgICAgICAgICAgICc8aW5wdXQgaWQ9XCJjYW0tY29uZGl0aW9uXCIgdHlwZT1cInRleHRcIiBuYW1lPVwiY29uZGl0aW9uXCIgLz4nICtcclxuICAgICAgICAgICAgICAgICc8YnV0dG9uIGNsYXNzPVwiY2xlYXJcIiBkYXRhLWFjdGlvbj1cImNsZWFyXCIgZGF0YS1zaG93PVwiY2FuQ2xlYXJcIj4nICtcclxuICAgICAgICAgICAgICAgICAgJzxzcGFuPlg8L3NwYW4+JyArXHJcbiAgICAgICAgICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICAgICAgICAgJzwvZGl2PicgK1xyXG4gICAgICAgICAgICAgICc8ZGl2IGRhdGEtc2hvdz1cImlzU2NyaXB0XCI+JyArXHJcbiAgICAgICAgICAgICAgICBzY3JpcHQudGVtcGxhdGUgK1xyXG4gICAgICAgICAgICAgICc8L2Rpdj4nICtcclxuICAgICAgICAgICAgJzwvZGl2PicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBwcm9wZXJ0eU5hbWUpIHtcclxuICAgICAgdmFyIGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uID0gZXZlbnREZWZpbml0aW9uSGVscGVyLmdldENvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG5cclxuICAgICAgdmFyIGNvbmRpdGlvbkV4cHJlc3Npb24gPSBjb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvblxyXG4gICAgICAgID8gY29uZGl0aW9uYWxFdmVudERlZmluaXRpb24uY29uZGl0aW9uXHJcbiAgICAgICAgOiBiby5jb25kaXRpb25FeHByZXNzaW9uO1xyXG5cclxuICAgICAgdmFyIHZhbHVlcyA9IHt9LFxyXG4gICAgICAgICAgY29uZGl0aW9uVHlwZSA9ICcnO1xyXG5cclxuICAgICAgaWYgKGNvbmRpdGlvbkV4cHJlc3Npb24pIHtcclxuICAgICAgICB2YXIgY29uZGl0aW9uTGFuZ3VhZ2UgPSBjb25kaXRpb25FeHByZXNzaW9uLmxhbmd1YWdlO1xyXG4gICAgICAgIGlmICh0eXBlb2YgY29uZGl0aW9uTGFuZ3VhZ2UgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICBjb25kaXRpb25UeXBlID0gJ3NjcmlwdCc7XHJcbiAgICAgICAgICB2YWx1ZXMgPSBzY3JpcHQuZ2V0KGVsZW1lbnQsIGNvbmRpdGlvbkV4cHJlc3Npb24pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb25kaXRpb25UeXBlID0gJ2V4cHJlc3Npb24nO1xyXG4gICAgICAgICAgdmFsdWVzLmNvbmRpdGlvbiA9IGNvbmRpdGlvbkV4cHJlc3Npb24uZ2V0KCdib2R5Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YWx1ZXMuY29uZGl0aW9uVHlwZSA9IGNvbmRpdGlvblR5cGU7XHJcblxyXG4gICAgICByZXR1cm4gdmFsdWVzO1xyXG5cclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIGNvbnRhaW5lckVsZW1lbnQpIHtcclxuICAgICAgdmFyIGNvbmRpdGlvblR5cGUgPSB2YWx1ZXMuY29uZGl0aW9uVHlwZTtcclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcblxyXG4gICAgICB2YXIgY29uZGl0aW9uUHJvcHMgPSB7XHJcbiAgICAgICAgYm9keTogdW5kZWZpbmVkXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpZiAoY29uZGl0aW9uVHlwZSA9PT0gJ3NjcmlwdCcpIHtcclxuICAgICAgICBjb25kaXRpb25Qcm9wcyA9IHNjcmlwdC5zZXQoZWxlbWVudCwgdmFsdWVzLCBjb250YWluZXJFbGVtZW50KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB2YXIgY29uZGl0aW9uID0gdmFsdWVzLmNvbmRpdGlvbjtcclxuXHJcbiAgICAgICAgY29uZGl0aW9uUHJvcHMuYm9keSA9IGNvbmRpdGlvbjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGNvbmRpdGlvbk9yQ29uZGl0aW9uRXhwcmVzc2lvbjtcclxuXHJcbiAgICAgIGlmIChjb25kaXRpb25UeXBlKSB7XHJcbiAgICAgICAgY29uZGl0aW9uT3JDb25kaXRpb25FeHByZXNzaW9uID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KFxyXG4gICAgICAgICAgJ2JwbW46Rm9ybWFsRXhwcmVzc2lvbicsXHJcbiAgICAgICAgICBjb25kaXRpb25Qcm9wcyxcclxuICAgICAgICAgIGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uIHx8IGJvLFxyXG4gICAgICAgICAgYnBtbkZhY3RvcnlcclxuICAgICAgICApO1xyXG5cclxuICAgICAgICB2YXIgc291cmNlID0gZWxlbWVudC5zb3VyY2U7XHJcblxyXG4gICAgICAgIC8vIGlmIGRlZmF1bHQtZmxvdywgcmVtb3ZlIGRlZmF1bHQtcHJvcGVydHkgZnJvbSBzb3VyY2VcclxuICAgICAgICBpZiAoc291cmNlICYmIHNvdXJjZS5idXNpbmVzc09iamVjdC5kZWZhdWx0ID09PSBibykge1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhzb3VyY2UsIHsgJ2RlZmF1bHQnOiB1bmRlZmluZWQgfSkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHVwZGF0ZSA9IGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uXHJcbiAgICAgICAgPyB7IGNvbmRpdGlvbjogY29uZGl0aW9uT3JDb25kaXRpb25FeHByZXNzaW9uIH1cclxuICAgICAgICA6IHsgY29uZGl0aW9uRXhwcmVzc2lvbjogY29uZGl0aW9uT3JDb25kaXRpb25FeHByZXNzaW9uIH07XHJcblxyXG4gICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBjb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbiB8fCBibywgdXBkYXRlKSk7XHJcblxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIHZhbGlkYXRpb25SZXN1bHQgPSB7fTtcclxuXHJcbiAgICAgIGlmICghdmFsdWVzLmNvbmRpdGlvbiAmJiB2YWx1ZXMuY29uZGl0aW9uVHlwZSA9PT0gJ2V4cHJlc3Npb24nKSB7XHJcbiAgICAgICAgdmFsaWRhdGlvblJlc3VsdC5jb25kaXRpb24gPSB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAodmFsdWVzLmNvbmRpdGlvblR5cGUgPT09ICdzY3JpcHQnKSB7XHJcbiAgICAgICAgdmFsaWRhdGlvblJlc3VsdCA9IHNjcmlwdC52YWxpZGF0ZShlbGVtZW50LCB2YWx1ZXMpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdmFsaWRhdGlvblJlc3VsdDtcclxuICAgIH0sXHJcblxyXG4gICAgaXNFeHByZXNzaW9uOiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUpIHtcclxuICAgICAgdmFyIGNvbmRpdGlvblR5cGUgPSBkb21RdWVyeSgnc2VsZWN0W25hbWU9Y29uZGl0aW9uVHlwZV0nLCBpbnB1dE5vZGUpO1xyXG4gICAgICBpZiAoY29uZGl0aW9uVHlwZS5zZWxlY3RlZEluZGV4ID49IDApIHtcclxuICAgICAgICByZXR1cm4gY29uZGl0aW9uVHlwZS5vcHRpb25zW2NvbmRpdGlvblR5cGUuc2VsZWN0ZWRJbmRleF0udmFsdWUgPT09ICdleHByZXNzaW9uJztcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBpc1NjcmlwdDogZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlKSB7XHJcbiAgICAgIHZhciBjb25kaXRpb25UeXBlID0gZG9tUXVlcnkoJ3NlbGVjdFtuYW1lPWNvbmRpdGlvblR5cGVdJywgaW5wdXROb2RlKTtcclxuICAgICAgaWYgKGNvbmRpdGlvblR5cGUuc2VsZWN0ZWRJbmRleCA+PSAwKSB7XHJcbiAgICAgICAgcmV0dXJuIGNvbmRpdGlvblR5cGUub3B0aW9uc1tjb25kaXRpb25UeXBlLnNlbGVjdGVkSW5kZXhdLnZhbHVlID09PSAnc2NyaXB0JztcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBjbGVhcjogZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlKSB7XHJcbiAgICAgIC8vIGNsZWFyIHRleHQgaW5wdXRcclxuICAgICAgZG9tUXVlcnkoJ2lucHV0W25hbWU9Y29uZGl0aW9uXScsIGlucHV0Tm9kZSkudmFsdWU9Jyc7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgY2FuQ2xlYXI6IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSkge1xyXG4gICAgICB2YXIgaW5wdXQgPSBkb21RdWVyeSgnaW5wdXRbbmFtZT1jb25kaXRpb25dJywgaW5wdXROb2RlKTtcclxuXHJcbiAgICAgIHJldHVybiBpbnB1dC52YWx1ZSAhPT0gJyc7XHJcbiAgICB9LFxyXG5cclxuICAgIHNjcmlwdCA6IHNjcmlwdCxcclxuXHJcbiAgICBjc3NDbGFzc2VzOiBbICdicHAtdGV4dGZpZWxkJyBdXHJcbiAgfSk7XHJcbn07XHJcblxyXG5cclxuLy8gdXRpbGl0aWVzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG52YXIgQ09ORElUSU9OQUxfU09VUkNFUyA9IFtcclxuICAnYnBtbjpBY3Rpdml0eScsXHJcbiAgJ2JwbW46RXhjbHVzaXZlR2F0ZXdheScsXHJcbiAgJ2JwbW46SW5jbHVzaXZlR2F0ZXdheScsXHJcbiAgJ2JwbW46Q29tcGxleEdhdGV3YXknXHJcbl07XHJcblxyXG5mdW5jdGlvbiBpc0NvbmRpdGlvbmFsU291cmNlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXNBbnkoZWxlbWVudCwgQ09ORElUSU9OQUxfU09VUkNFUyk7XHJcbn1cclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXInKSxcclxuICAgIElucHV0T3V0cHV0SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0lucHV0T3V0cHV0SGVscGVyJyk7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbmZ1bmN0aW9uIGdldEltcGxlbWVudGF0aW9uVHlwZShlbGVtZW50KSB7XHJcbiAgcmV0dXJuIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpIHtcclxuICByZXR1cm4gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldFNlcnZpY2VUYXNrTGlrZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRDb25uZWN0b3IoYm8pIHtcclxuICByZXR1cm4gSW5wdXRPdXRwdXRIZWxwZXIuZ2V0Q29ubmVjdG9yKGJvKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNDb25uZWN0b3IoZWxlbWVudCkge1xyXG4gIHJldHVybiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkgPT09ICdjb25uZWN0b3InO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnY29ubmVjdG9ySWQnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ29ubmVjdG9yIElkJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY29ubmVjdG9ySWQnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIGNvbm5lY3RvciA9IGJvICYmIGdldENvbm5lY3Rvcihibyk7XHJcbiAgICAgIHZhciB2YWx1ZSA9IGNvbm5lY3RvciAmJiBjb25uZWN0b3IuZ2V0KCdjb25uZWN0b3JJZCcpO1xyXG4gICAgICByZXR1cm4geyBjb25uZWN0b3JJZDogdmFsdWUgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHZhciBjb25uZWN0b3IgPSBnZXRDb25uZWN0b3IoYm8pO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGNvbm5lY3Rvciwge1xyXG4gICAgICAgIGNvbm5lY3RvcklkOiB2YWx1ZXMuY29ubmVjdG9ySWQgfHwgdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBpc0Nvbm5lY3RvcihlbGVtZW50KSAmJiAhdmFsdWVzLmNvbm5lY3RvcklkID8geyBjb25uZWN0b3JJZDogdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpIH0gOiB7fTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhaXNDb25uZWN0b3IoZWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyk7XHJcblxyXG52YXIgaW5wdXRPdXRwdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0lucHV0T3V0cHV0UGFyYW1ldGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIG9wdGlvbnMgPSBhc3NpZ24oe1xyXG4gICAgaWRQcmVmaXg6ICdjb25uZWN0b3ItJyxcclxuICAgIGluc2lkZUNvbm5lY3RvcjogdHJ1ZVxyXG4gIH0sIG9wdGlvbnMpO1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoaW5wdXRPdXRwdXRQYXJhbWV0ZXIoZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlucHV0T3V0cHV0ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9JbnB1dE91dHB1dCcpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgaW5wdXRPdXRwdXRFbnRyeSA9IGlucHV0T3V0cHV0KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZFByZWZpeDogJ2Nvbm5lY3Rvci0nLFxyXG4gICAgaW5zaWRlQ29ubmVjdG9yOiB0cnVlXHJcbiAgfSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGlucHV0T3V0cHV0RW50cnkuZW50cmllcyk7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBnZXRTZWxlY3RlZFBhcmFtZXRlcjogaW5wdXRPdXRwdXRFbnRyeS5nZXRTZWxlY3RlZFBhcmFtZXRlclxyXG4gIH07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZXZlbnREZWZpbml0aW9uSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0V2ZW50RGVmaW5pdGlvbkhlbHBlcicpLFxyXG4gICAgZXJyb3IgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0Vycm9yRXZlbnREZWZpbml0aW9uJyk7XHJcblxyXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZXJyb3JFdmVudHMgPSBbXHJcbiAgICAnYnBtbjpTdGFydEV2ZW50JyxcclxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxyXG4gICAgJ2JwbW46RW5kRXZlbnQnXHJcbiAgXTtcclxuXHJcbiAgZm9yRWFjaChlcnJvckV2ZW50cywgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIGlmIChpcyhlbGVtZW50LCBldmVudCkpIHtcclxuXHJcbiAgICAgIHZhciBlcnJvckV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRFcnJvckV2ZW50RGVmaW5pdGlvbihlbGVtZW50KTtcclxuXHJcbiAgICAgIGlmIChlcnJvckV2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgICAgIHZhciBpc0NhdGNoaW5nRXJyb3JFdmVudCA9IGlzKGVsZW1lbnQsICdicG1uOlN0YXJ0RXZlbnQnKSB8fCBpcyAoZWxlbWVudCwgJ2JwbW46Qm91bmRhcnlFdmVudCcpO1xyXG5cclxuICAgICAgICB2YXIgc2hvd0Vycm9yQ29kZVZhcmlhYmxlID0gaXNDYXRjaGluZ0Vycm9yRXZlbnQsXHJcbiAgICAgICAgICAgIHNob3dFcnJvck1lc3NhZ2VWYXJpYWJsZSA9IGlzQ2F0Y2hpbmdFcnJvckV2ZW50O1xyXG5cclxuICAgICAgICBlcnJvcihcclxuICAgICAgICAgIGdyb3VwLFxyXG4gICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgIGJwbW5GYWN0b3J5LFxyXG4gICAgICAgICAgZXJyb3JFdmVudERlZmluaXRpb24sXHJcbiAgICAgICAgICBzaG93RXJyb3JDb2RlVmFyaWFibGUsXHJcbiAgICAgICAgICBzaG93RXJyb3JNZXNzYWdlVmFyaWFibGUsXHJcbiAgICAgICAgICB0cmFuc2xhdGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgSW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0ltcGxlbWVudGF0aW9uVHlwZUhlbHBlcicpO1xyXG5cclxudmFyIGV4dGVybmFsVGFza1ByaW9yaXR5ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9FeHRlcm5hbFRhc2tQcmlvcml0eScpO1xyXG5cclxuZnVuY3Rpb24gZ2V0U2VydmljZVRhc2tMaWtlQnVzaW5lc3NPYmplY3QoZWxlbWVudCkge1xyXG4gIHZhciBibyA9IEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRTZXJ2aWNlVGFza0xpa2VCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgLy8gaWYgdGhlIGVsZW1lbnQgaXMgbm90IGEgc2VydmljZVRhc2tMaWtlIGVsZW1lbnQsIGZldGNoIHRoZSBub3JtYWwgYnVzaW5lc3Mgb2JqZWN0XHJcbiAgLy8gVGhpcyBhdm9pZHMgdGhlIGxvc3Mgb2YgdGhlIHByb2Nlc3MgLyBwYXJ0aWNpcGFudCBidXNpbmVzcyBvYmplY3RcclxuICBpZiAoIWJvKSB7XHJcbiAgICBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGJvO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBibyA9IGdldFNlcnZpY2VUYXNrTGlrZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICBpZiAoIWJvKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICBpZiAoaXMoYm8sICdhY3Rpdml0aTpUYXNrUHJpb3JpemVkJykgfHwgKGlzKGJvLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSAmJiBiby5nZXQoJ3Byb2Nlc3NSZWYnKSkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGV4dGVybmFsVGFza1ByaW9yaXR5KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0OiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgICAgaWYgKCFpcyhibywgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGJvO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYm8uZ2V0KCdwcm9jZXNzUmVmJyk7XHJcbiAgICAgIH1cclxuICAgIH0sIHRyYW5zbGF0ZSkpO1xyXG4gIH1cclxufTsiLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgSW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0ltcGxlbWVudGF0aW9uVHlwZUhlbHBlcicpO1xyXG5cclxudmFyIGZpZWxkSW5qZWN0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9GaWVsZEluamVjdGlvbicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgYm8gPSBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0U2VydmljZVRhc2tMaWtlQnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIHZhciBmaWVsZEluamVjdGlvbkVudHJ5ID0gZmllbGRJbmplY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSwgeyBidXNpbmVzc09iamVjdDogYm8gfSk7XHJcblxyXG4gIGlmIChmaWVsZEluamVjdGlvbkVudHJ5ICYmIGZpZWxkSW5qZWN0aW9uRW50cnkubGVuZ3RoID4gMCkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGZpZWxkSW5qZWN0aW9uRW50cnkpO1xyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBnZXRFeHRlbnNpb25FbGVtZW50cyA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpLmdldEV4dGVuc2lvbkVsZW1lbnRzLFxyXG4gICAgcmVtb3ZlRW50cnkgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXInKS5yZW1vdmVFbnRyeSxcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9FeHRlbnNpb25FbGVtZW50cycpLFxyXG4gICAgcHJvcGVydGllcyA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vUHJvcGVydGllcycpLFxyXG4gICAgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgZm9ybUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9Gb3JtSGVscGVyJyksXHJcbiAgICB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uL1V0aWxzJyksXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBmaW5kID0gcmVxdWlyZSgnbG9kYXNoL2ZpbmQnKSxcclxuICAgIGVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVWYWx1ZUlkKCkge1xyXG4gIHJldHVybiB1dGlscy5uZXh0SWQoJ1ZhbHVlXycpO1xyXG59XHJcblxyXG4vKipcclxuICogR2VuZXJhdGUgYSBmb3JtIGZpZWxkIHNwZWNpZmljIHRleHRGaWVsZCB1c2luZyBlbnRyeUZhY3RvcnkuXHJcbiAqXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5pZFxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMubGFiZWxcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLm1vZGVsUHJvcGVydHlcclxuICogQHBhcmFtICB7ZnVuY3Rpb259IG9wdGlvbnMudmFsaWRhdGVcclxuICpcclxuICogQHJldHVybiB7T2JqZWN0fSBhbiBlbnRyeUZhY3RvcnkudGV4dEZpZWxkIG9iamVjdFxyXG4gKi9cclxuZnVuY3Rpb24gZm9ybUZpZWxkVGV4dEZpZWxkKG9wdGlvbnMsIGdldFNlbGVjdGVkRm9ybUZpZWxkKSB7XHJcblxyXG4gIHZhciBpZCA9IG9wdGlvbnMuaWQsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eSxcclxuICAgICAgdmFsaWRhdGUgPSBvcHRpb25zLnZhbGlkYXRlO1xyXG5cclxuICByZXR1cm4gZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogaWQsXHJcbiAgICBsYWJlbDogbGFiZWwsXHJcbiAgICBtb2RlbFByb3BlcnR5OiBtb2RlbFByb3BlcnR5LFxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpIHx8IHt9LFxyXG4gICAgICAgICAgdmFsdWVzID0ge307XHJcblxyXG4gICAgICB2YWx1ZXNbbW9kZWxQcm9wZXJ0eV0gPSBzZWxlY3RlZEZvcm1GaWVsZFttb2RlbFByb3BlcnR5XTtcclxuXHJcbiAgICAgIHJldHVybiB2YWx1ZXM7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiBvcHRpb25zLnNldCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIHZhciBjbWQgPSBvcHRpb25zLnNldChlbGVtZW50LCB2YWx1ZXMsIG5vZGUpO1xyXG5cclxuICAgICAgICBpZiAoY21kKSB7XHJcbiAgICAgICAgICBjb21tYW5kcy5wdXNoKGNtZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSksXHJcbiAgICAgICAgICBwcm9wZXJ0aWVzID0ge307XHJcblxyXG4gICAgICBwcm9wZXJ0aWVzW21vZGVsUHJvcGVydHldID0gdmFsdWVzW21vZGVsUHJvcGVydHldIHx8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGZvcm1GaWVsZCwgcHJvcGVydGllcykpO1xyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfSxcclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuICAgIHZhbGlkYXRlOiB2YWxpZGF0ZVxyXG4gIH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBlbnN1cmVGb3JtS2V5QW5kRGF0YVN1cHBvcnRlZChlbGVtZW50KSB7XHJcbiAgcmV0dXJuIChcclxuICAgIGlzKGVsZW1lbnQsICdicG1uOlN0YXJ0RXZlbnQnKSAmJiAhaXMoZWxlbWVudC5wYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKVxyXG4gICkgfHwgaXMoZWxlbWVudCwgJ2JwbW46VXNlclRhc2snKTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICBpZiAoIWVuc3VyZUZvcm1LZXlBbmREYXRhU3VwcG9ydGVkKGVsZW1lbnQpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJuIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgZm9ybSBmaWVsZCBxdWVyeWluZyB0aGUgZm9ybSBmaWVsZCBzZWxlY3QgYm94XHJcbiAgICogZnJvbSB0aGUgRE9NLlxyXG4gICAqXHJcbiAgICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICAgKiBAcGFyYW0gIHtET01FbGVtZW50fSBub2RlIC0gRE9NIGVsZW1lbnQgb2YgYW55IGZvcm0gZmllbGQgdGV4dCBpbnB1dFxyXG4gICAqXHJcbiAgICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBmb3JtIGZpZWxkXHJcbiAgICovXHJcbiAgZnVuY3Rpb24gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSkge1xyXG4gICAgdmFyIHNlbGVjdGVkID0gZm9ybUZpZWxkc0VudHJ5LmdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUucGFyZW50Tm9kZSk7XHJcblxyXG4gICAgaWYgKHNlbGVjdGVkLmlkeCA9PT0gLTEpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmb3JtSGVscGVyLmdldEZvcm1GaWVsZChlbGVtZW50LCBzZWxlY3RlZC5pZHgpO1xyXG4gIH1cclxuXHJcbiAgLy8gW0Zvcm1LZXldIGZvcm0ga2V5IHRleHQgaW5wdXQgZmllbGRcclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZCA6ICdmb3JtLWtleScsXHJcbiAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnRm9ybSBLZXknKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdmb3JtS2V5JyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZm9ybUtleTogYm8uZ2V0KCdhY3Rpdml0aTpmb3JtS2V5JylcclxuICAgICAgfTtcclxuICAgIH0sXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICAgIGZvcm1LZXkgPSB2YWx1ZXMuZm9ybUtleSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGJvLCB7ICdhY3Rpdml0aTpmb3JtS2V5JzogZm9ybUtleSB9KTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBzZWxlY3QgYm94XHJcbiAgdmFyIGZvcm1GaWVsZHNFbnRyeSA9IGV4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ2Zvcm0tZmllbGRzJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0Zvcm0gRmllbGRzJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnaWQnLFxyXG4gICAgcHJlZml4OiAnRm9ybVByb3BlcnR5JyxcclxuICAgIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCB2YWx1ZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSwgY29tbWFuZHMgPSBbXTtcclxuXHJcbiAgICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgICBleHRlbnNpb25FbGVtZW50cyA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYnBtbjpFeHRlbnNpb25FbGVtZW50cycsIHsgdmFsdWVzOiBbXSB9LCBibywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgeyBleHRlbnNpb25FbGVtZW50czogZXh0ZW5zaW9uRWxlbWVudHMgfSkpO1xyXG4gICAgICB9XHJcbiAgICAgLyogdmFyIGZvcm1EYXRhID0gZm9ybUhlbHBlci5nZXRGb3JtRGF0YShlbGVtZW50KTtcclxuXHJcbiAgICAgIGlmICghZm9ybURhdGEpIHtcclxuICAgICAgICBmb3JtRGF0YSA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6Rm9ybURhdGEnLCB7IGZpZWxkczogW10gfSwgZXh0ZW5zaW9uRWxlbWVudHMsIGJwbW5GYWN0b3J5KTtcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5hZGRBbmRSZW1vdmVFbGVtZW50c0Zyb21MaXN0KFxyXG4gICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgIGV4dGVuc2lvbkVsZW1lbnRzLFxyXG4gICAgICAgICAgJ3ZhbHVlcycsXHJcbiAgICAgICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICAgICAgW2Zvcm1EYXRhXSxcclxuICAgICAgICAgIFtdXHJcbiAgICAgICAgKSk7XHJcbiAgICAgIH0qL1xyXG4gICAgICAvKiphY3Rpdml0aSDmmK/lkJEgZXh0ZW5zaW9uRWxlbWVudHMg5LiL6L+95Yqg5YWD57Sg77yM6ICM5LiN5pivIGZvcm1EYXRhIOS4i++8jCovXHJcbiAgICAgIHZhciBmaWVsZCA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6Rm9ybVByb3BlcnR5JywgeyBpZDogdmFsdWUgfSwgZXh0ZW5zaW9uRWxlbWVudHMsIGJwbW5GYWN0b3J5KTtcclxuICAgICAgaWYgKHR5cGVvZiBleHRlbnNpb25FbGVtZW50cy52YWx1ZXMgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkRWxlbWVudHNUb2xpc3QoZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsICd2YWx1ZXMnLCBbIGZpZWxkIF0pKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywge1xyXG4gICAgICAgICAgICB2YWx1ZXM6IFsgZmllbGQgXVxyXG4gICAgICAgIH0pKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcbiAgICB9LFxyXG4gICAgcmVtb3ZlRXh0ZW5zaW9uRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGZpZWxkcyA9IGZvcm1IZWxwZXIuZ2V0Rm9ybUZpZWxkcyhlbGVtZW50KTtcclxuICAgICAgdmFyIGVudHJ5ID0gZmllbGRzW2lkeF0sXHJcbiAgICAgICAgICBjb21tYW5kcyA9IFtdO1xyXG5cclxuICAgICAgaWYgKGZpZWxkcy5sZW5ndGggPCAyKSB7XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChyZW1vdmVFbnRyeShnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSwgZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMpKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5yZW1vdmVFbGVtZW50c0Zyb21MaXN0KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCAndmFsdWVzJywgbnVsbCwgW2VudHJ5XSkpO1xyXG4gICAgICAgLyogaWYgKGVudHJ5LmlkID09PSBmb3JtRGF0YS5nZXQoJ2J1c2luZXNzS2V5JykpIHtcclxuICAgICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCB7ICdidXNpbmVzc0tleSc6IHVuZGVmaW5lZCB9KSk7XHJcbiAgICAgICAgfSovXHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgIH0sXHJcbiAgICBnZXRFeHRlbnNpb25FbGVtZW50czogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICByZXR1cm4gZm9ybUhlbHBlci5nZXRGb3JtRmllbGRzKGVsZW1lbnQpO1xyXG4gICAgfSxcclxuICAgIGhpZGVFeHRlbnNpb25FbGVtZW50czogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgfSk7XHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGZvcm1GaWVsZHNFbnRyeSk7XHJcblxyXG5cclxuICAvLyBbRm9ybURhdGFdIEZvcm0gRmllbGQgbGFiZWxcclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmxhYmVsKHtcclxuICAgIGlkOiAnZm9ybS1maWVsZC1oZWFkZXInLFxyXG4gICAgbGFiZWxUZXh0OiB0cmFuc2xhdGUoJ0Zvcm0gRmllbGQnKSxcclxuICAgIHNob3dMYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gISFnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBpZCB0ZXh0IGlucHV0IGZpZWxkXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS52YWxpZGF0aW9uQXdhcmVUZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdmb3JtLWZpZWxkLWlkJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0lEJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnaWQnLFxyXG5cclxuICAgIGdldFByb3BlcnR5OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpIHx8IHt9O1xyXG5cclxuICAgICAgcmV0dXJuIHNlbGVjdGVkRm9ybUZpZWxkLmlkO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydGllcywgbm9kZSkge1xyXG4gICAgICB2YXIgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGZvcm1GaWVsZCwgcHJvcGVydGllcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcblxyXG4gICAgICB2YXIgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICBpZiAoZm9ybUZpZWxkKSB7XHJcblxyXG4gICAgICAgIHZhciBpZFZhbHVlID0gdmFsdWVzLmlkO1xyXG5cclxuICAgICAgICBpZiAoIWlkVmFsdWUgfHwgaWRWYWx1ZS50cmltKCkgPT09ICcnKSB7XHJcbiAgICAgICAgICByZXR1cm4geyBpZDogJ0Zvcm0gZmllbGQgaWQgbXVzdCBub3QgYmUgZW1wdHknIH07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgZm9ybUZpZWxkcyA9IGZvcm1IZWxwZXIuZ2V0Rm9ybUZpZWxkcyhlbGVtZW50KTtcclxuXHJcbiAgICAgICAgdmFyIGV4aXN0aW5nRm9ybUZpZWxkID0gZmluZChmb3JtRmllbGRzLCBmdW5jdGlvbihmKSB7XHJcbiAgICAgICAgICByZXR1cm4gZiAhPT0gZm9ybUZpZWxkICYmIGYuaWQgPT09IGlkVmFsdWU7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGlmIChleGlzdGluZ0Zvcm1GaWVsZCkge1xyXG4gICAgICAgICAgcmV0dXJuIHsgaWQ6ICdGb3JtIGZpZWxkIGlkIGFscmVhZHkgdXNlZCBpbiBmb3JtIGRhdGEuJyB9O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbiAgLy8gW0Zvcm1EYXRhXSBmb3JtIGZpZWxkIHR5cGUgY29tYm8gYm94XHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5jb21ib0JveCh7XHJcbiAgICBpZDogJ2Zvcm0tZmllbGQtdHlwZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdUeXBlJyksXHJcbiAgICBzZWxlY3RPcHRpb25zOiBbXHJcbiAgICAgIHsgbmFtZTogJ3N0cmluZycsIHZhbHVlOiAnc3RyaW5nJyB9LFxyXG4gICAgICB7IG5hbWU6ICdsb25nJywgdmFsdWU6ICdsb25nJyB9LFxyXG4gICAgICB7IG5hbWU6ICdib29sZWFuJywgdmFsdWU6ICdib29sZWFuJyB9LFxyXG4gICAgICB7IG5hbWU6ICdkYXRlJywgdmFsdWU6ICdkYXRlJyB9LFxyXG4gICAgICB7IG5hbWU6ICdlbnVtJywgdmFsdWU6ICdlbnVtJyB9XHJcbiAgICBdLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3R5cGUnLFxyXG4gICAgZW1wdHlQYXJhbWV0ZXI6IHRydWUsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgaWYgKHNlbGVjdGVkRm9ybUZpZWxkKSB7XHJcbiAgICAgICAgcmV0dXJuIHsgdHlwZTogc2VsZWN0ZWRGb3JtRmllbGQudHlwZSB9O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiB7fTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgY29tbWFuZHMgPSBbXTtcclxuXHJcbiAgICAgIGlmIChzZWxlY3RlZEZvcm1GaWVsZC50eXBlID09PSAnZW51bScgJiYgdmFsdWVzLnR5cGUgIT09ICdlbnVtJykge1xyXG4gICAgICAgIC8vIGRlbGV0ZSBhY3Rpdml0aTp2YWx1ZSBvYmplY3RzIGZyb20gZm9ybUZpZWxkLnZhbHVlcyB3aGVuIHN3aXRjaGluZyBmcm9tIHR5cGUgZW51bVxyXG4gICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHNlbGVjdGVkRm9ybUZpZWxkLCB7IHZhbHVlczogdW5kZWZpbmVkIH0pKTtcclxuICAgICAgfVxyXG4gICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBzZWxlY3RlZEZvcm1GaWVsZCwgdmFsdWVzKSk7XHJcblxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcbiAgICB9LFxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuICAvLyBbRm9ybURhdGFdIGZvcm0gZmllbGQgbGFiZWwgdGV4dCBpbnB1dCBmaWVsZFxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChmb3JtRmllbGRUZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdmb3JtLWZpZWxkLWxhYmVsJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0xhYmVsJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnbGFiZWwnXHJcbiAgfSwgZ2V0U2VsZWN0ZWRGb3JtRmllbGQpKTtcclxuXHJcbiAgLy8gW0Zvcm1EYXRhXSBmb3JtIGZpZWxkIGRlZmF1bHRWYWx1ZSB0ZXh0IGlucHV0IGZpZWxkXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGZvcm1GaWVsZFRleHRGaWVsZCh7XHJcbiAgICBpZDogJ2Zvcm0tZmllbGQtZGVmYXVsdFZhbHVlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0RlZmF1bHQgVmFsdWUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdkZWZhdWx0VmFsdWUnXHJcbiAgfSwgZ2V0U2VsZWN0ZWRGb3JtRmllbGQpKTtcclxuXHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBlbnVtIHZhbHVlcyBsYWJlbFxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkubGFiZWwoe1xyXG4gICAgaWQ6ICdmb3JtLWZpZWxkLWVudW0tdmFsdWVzLWhlYWRlcicsXHJcbiAgICBsYWJlbFRleHQ6IHRyYW5zbGF0ZSgnVmFsdWVzJyksXHJcbiAgICBkaXZpZGVyOiB0cnVlLFxyXG4gICAgc2hvd0xhYmVsOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgcmV0dXJuIHNlbGVjdGVkRm9ybUZpZWxkICYmIHNlbGVjdGVkRm9ybUZpZWxkLnR5cGUgPT09ICdlbnVtJztcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBlbnVtIHZhbHVlcyB0YWJsZVxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGFibGUoe1xyXG4gICAgaWQ6ICdmb3JtLWZpZWxkLWVudW0tdmFsdWVzJyxcclxuICAgIGxhYmVsczogWyB0cmFuc2xhdGUoJ0lkJyksIHRyYW5zbGF0ZSgnTmFtZScpIF0sXHJcbiAgICBtb2RlbFByb3BlcnRpZXM6IFsgJ2lkJywgJ25hbWUnIF0sXHJcbiAgICBhZGRMYWJlbDp0cmFuc2xhdGUoJ0FkZCBWYWx1ZScpLFxyXG4gICAgc2hvdzogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgc2VsZWN0ZWRGb3JtRmllbGQgPSBnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICAgIHJldHVybiBzZWxlY3RlZEZvcm1GaWVsZCAmJiBzZWxlY3RlZEZvcm1GaWVsZC50eXBlID09PSAnZW51bSc7XHJcbiAgICB9LFxyXG4gICAgZ2V0RWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIHNlbGVjdGVkRm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gZm9ybUhlbHBlci5nZXRFbnVtVmFsdWVzKHNlbGVjdGVkRm9ybUZpZWxkKTtcclxuICAgIH0sXHJcbiAgICBhZGRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgaWQgPSBnZW5lcmF0ZVZhbHVlSWQoKTtcclxuXHJcbiAgICAgIHZhciBlbnVtVmFsdWUgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoXHJcbiAgICAgICAgJ2FjdGl2aXRpOlZhbHVlJyxcclxuICAgICAgICB7IGlkOiBpZCwgbmFtZTogdW5kZWZpbmVkIH0sXHJcbiAgICAgICAgZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksXHJcbiAgICAgICAgYnBtbkZhY3RvcnlcclxuICAgICAgKTtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIuYWRkRWxlbWVudHNUb2xpc3QoZWxlbWVudCwgc2VsZWN0ZWRGb3JtRmllbGQsICd2YWx1ZXMnLCBbZW51bVZhbHVlXSk7XHJcbiAgICB9LFxyXG4gICAgcmVtb3ZlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgaWR4KSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgZW51bVZhbHVlID0gc2VsZWN0ZWRGb3JtRmllbGQudmFsdWVzW2lkeF07XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoZWxlbWVudCwgc2VsZWN0ZWRGb3JtRmllbGQsICd2YWx1ZXMnLCBudWxsLCBbZW51bVZhbHVlXSk7XHJcbiAgICB9LFxyXG4gICAgdXBkYXRlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWUsIG5vZGUsIGlkeCkge1xyXG4gICAgICB2YXIgc2VsZWN0ZWRGb3JtRmllbGQgPSBnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKSxcclxuICAgICAgICAgIGVudW1WYWx1ZSA9IHNlbGVjdGVkRm9ybUZpZWxkLnZhbHVlc1tpZHhdO1xyXG5cclxuICAgICAgdmFsdWUubmFtZSA9IHZhbHVlLm5hbWUgfHwgdW5kZWZpbmVkO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGVudW1WYWx1ZSwgdmFsdWUpO1xyXG4gICAgfSxcclxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSwgbm9kZSwgaWR4KSB7XHJcblxyXG4gICAgICB2YXIgc2VsZWN0ZWRGb3JtRmllbGQgPSBnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKSxcclxuICAgICAgICAgIGVudW1WYWx1ZSA9IHNlbGVjdGVkRm9ybUZpZWxkLnZhbHVlc1tpZHhdO1xyXG5cclxuICAgICAgaWYgKGVudW1WYWx1ZSkge1xyXG4gICAgICAgIC8vIGNoZWNrIGlmIGlkIGlzIHZhbGlkXHJcbiAgICAgICAgdmFyIHZhbGlkYXRpb25FcnJvciA9IHV0aWxzLmlzSWRWYWxpZChlbnVtVmFsdWUsIHZhbHVlLmlkLCB0cmFuc2xhdGUpO1xyXG5cclxuICAgICAgICBpZiAodmFsaWRhdGlvbkVycm9yKSB7XHJcbiAgICAgICAgICByZXR1cm4geyBpZDogdmFsaWRhdGlvbkVycm9yIH07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuICAvLyBbRm9ybURhdGFdIFZhbGlkYXRpb24gbGFiZWxcclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmxhYmVsKHtcclxuICAgIGlkOiAnZm9ybS1maWVsZC12YWxpZGF0aW9uLWhlYWRlcicsXHJcbiAgICBsYWJlbFRleHQ6IHRyYW5zbGF0ZSgnVmFsaWRhdGlvbicpLFxyXG4gICAgZGl2aWRlcjogdHJ1ZSxcclxuICAgIHNob3dMYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gISFnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gZm9ybSBmaWVsZCBjb25zdHJhaW50cyB0YWJsZVxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGFibGUoe1xyXG4gICAgaWQ6ICdjb25zdHJhaW50cy1saXN0JyxcclxuICAgIG1vZGVsUHJvcGVydGllczogWyAnbmFtZScsICdjb25maWcnIF0sXHJcbiAgICBsYWJlbHM6IFsgdHJhbnNsYXRlKCdOYW1lJyksIHRyYW5zbGF0ZSgnQ29uZmlnJykgXSxcclxuICAgIGFkZExhYmVsOiB0cmFuc2xhdGUoJ0FkZCBDb25zdHJhaW50JyksXHJcbiAgICBnZXRFbGVtZW50czogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gZm9ybUhlbHBlci5nZXRDb25zdHJhaW50cyhmb3JtRmllbGQpO1xyXG4gICAgfSxcclxuICAgIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuXHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdLFxyXG4gICAgICAgICAgZm9ybUZpZWxkID0gZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSksXHJcbiAgICAgICAgICB2YWxpZGF0aW9uID0gZm9ybUZpZWxkLnZhbGlkYXRpb247XHJcblxyXG4gICAgICBpZiAoIXZhbGlkYXRpb24pIHtcclxuICAgICAgICAvLyBjcmVhdGUgdmFsaWRhdGlvbiBidXNpbmVzcyBvYmplY3QgYW5kIGFkZCBpdCB0byBmb3JtIGRhdGEsIGlmIGl0IGRvZXNuJ3QgZXhpc3RcclxuICAgICAgICB2YWxpZGF0aW9uID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdhY3Rpdml0aTpWYWxpZGF0aW9uJywge30sIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLCBicG1uRmFjdG9yeSk7XHJcblxyXG4gICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGZvcm1GaWVsZCwgeyAndmFsaWRhdGlvbic6IHZhbGlkYXRpb24gfSkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgbmV3Q29uc3RyYWludCA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudChcclxuICAgICAgICAnYWN0aXZpdGk6Q29uc3RyYWludCcsXHJcbiAgICAgICAgeyBuYW1lOiB1bmRlZmluZWQsIGNvbmZpZzogdW5kZWZpbmVkIH0sXHJcbiAgICAgICAgdmFsaWRhdGlvbixcclxuICAgICAgICBicG1uRmFjdG9yeVxyXG4gICAgICApO1xyXG5cclxuICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkRWxlbWVudHNUb2xpc3QoZWxlbWVudCwgdmFsaWRhdGlvbiwgJ2NvbnN0cmFpbnRzJywgWyBuZXdDb25zdHJhaW50IF0pKTtcclxuXHJcbiAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgIH0sXHJcbiAgICB1cGRhdGVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSwgbm9kZSwgaWR4KSB7XHJcbiAgICAgIHZhciBmb3JtRmllbGQgPSBnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKSxcclxuICAgICAgICAgIGNvbnN0cmFpbnQgPSBmb3JtSGVscGVyLmdldENvbnN0cmFpbnRzKGZvcm1GaWVsZClbaWR4XTtcclxuXHJcbiAgICAgIHZhbHVlLm5hbWUgPSB2YWx1ZS5uYW1lIHx8IHVuZGVmaW5lZDtcclxuICAgICAgdmFsdWUuY29uZmlnID0gdmFsdWUuY29uZmlnIHx8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgY29uc3RyYWludCwgdmFsdWUpO1xyXG4gICAgfSxcclxuICAgIHJlbW92ZUVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGlkeCkge1xyXG4gICAgICB2YXIgY29tbWFuZHMgPSBbXSxcclxuICAgICAgICAgIGZvcm1GaWVsZCA9IGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgY29uc3RyYWludHMgPSBmb3JtSGVscGVyLmdldENvbnN0cmFpbnRzKGZvcm1GaWVsZCksXHJcbiAgICAgICAgICBjdXJyZW50Q29uc3RyYWludCA9IGNvbnN0cmFpbnRzW2lkeF07XHJcblxyXG4gICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5yZW1vdmVFbGVtZW50c0Zyb21MaXN0KFxyXG4gICAgICAgIGVsZW1lbnQsXHJcbiAgICAgICAgZm9ybUZpZWxkLnZhbGlkYXRpb24sXHJcbiAgICAgICAgJ2NvbnN0cmFpbnRzJyxcclxuICAgICAgICBudWxsLFxyXG4gICAgICAgIFsgY3VycmVudENvbnN0cmFpbnQgXVxyXG4gICAgICApKTtcclxuXHJcbiAgICAgIGlmIChjb25zdHJhaW50cy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAvLyByZW1vdmUgYWN0aXZpdGk6dmFsaWRhdGlvbiBpZiB0aGUgbGFzdCBleGlzdGluZyBjb25zdHJhaW50IGhhcyBiZWVuIHJlbW92ZWRcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBmb3JtRmllbGQsIHsgdmFsaWRhdGlvbjogdW5kZWZpbmVkIH0pKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfSxcclxuICAgIHNob3c6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICEhZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuICAvLyBbRm9ybURhdGFdIFByb3BlcnRpZXMgbGFiZWxcclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmxhYmVsKHtcclxuICAgIGlkOiAnZm9ybS1maWVsZC1wcm9wZXJ0aWVzLWhlYWRlcicsXHJcbiAgICBsYWJlbFRleHQ6IHRyYW5zbGF0ZSgnUHJvcGVydGllcycpLFxyXG4gICAgZGl2aWRlcjogdHJ1ZSxcclxuICAgIHNob3dMYWJlbDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gISFnZXRTZWxlY3RlZEZvcm1GaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG4gIC8vIFtGb3JtRGF0YV0gYWN0aXZpdGk6cHJvcGVydGllcyB0YWJsZVxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChwcm9wZXJ0aWVzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ2Zvcm0tZmllbGQtcHJvcGVydGllcycsXHJcbiAgICBtb2RlbFByb3BlcnRpZXM6IFsgJ2lkJywgJ3ZhbHVlJyBdLFxyXG4gICAgbGFiZWxzOiBbIHRyYW5zbGF0ZSgnSWQnKSwgdHJhbnNsYXRlKCdWYWx1ZScpIF0sXHJcbiAgICBnZXRQYXJlbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGdldFNlbGVjdGVkRm9ybUZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuICAgIHNob3c6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICEhZ2V0U2VsZWN0ZWRGb3JtRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSwgdHJhbnNsYXRlKSk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgaGlzdG9yeVRpbWVUb0xpdmUgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0hpc3RvcnlUaW1lVG9MaXZlJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6UHJvY2VzcycpIHx8XHJcbiAgICAgIGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdwcm9jZXNzUmVmJykpIHtcclxuXHJcbiAgICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoaGlzdG9yeVRpbWVUb0xpdmUoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKCFpcyhibywgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGJvO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGJvLmdldCgncHJvY2Vzc1JlZicpO1xyXG4gICAgICB9XHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgfVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaW5wdXRPdXRwdXRQYXJhbWV0ZXIgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0lucHV0T3V0cHV0UGFyYW1ldGVyJyk7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoaW5wdXRPdXRwdXRQYXJhbWV0ZXIoZWxlbWVudCwgYnBtbkZhY3RvcnksIGFzc2lnbih7fSwgb3B0aW9ucyksIHRyYW5zbGF0ZSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlucHV0T3V0cHV0ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9JbnB1dE91dHB1dCcpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgaW5wdXRPdXRwdXRFbnRyeSA9IGlucHV0T3V0cHV0KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7fSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGlucHV0T3V0cHV0RW50cnkuZW50cmllcyk7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICBnZXRTZWxlY3RlZFBhcmFtZXRlcjogaW5wdXRPdXRwdXRFbnRyeS5nZXRTZWxlY3RlZFBhcmFtZXRlclxyXG4gIH07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIGpvYlByaW9yaXR5ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9Kb2JQcmlvcml0eScpLFxyXG4gICAgam9iUmV0cnlUaW1lQ3ljbGUgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0pvYlJldHJ5VGltZUN5Y2xlJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6Sm9iUHJpb3JpemVkJykgfHxcclxuICAgICAgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSAmJiBidXNpbmVzc09iamVjdC5nZXQoJ3Byb2Nlc3NSZWYnKSkge1xyXG5cclxuICAgIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChqb2JQcmlvcml0eShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgICBnZXRCdXNpbmVzc09iamVjdDogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgICBpZiAoIWlzKGJvLCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICAgICAgICByZXR1cm4gYm87XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYm8uZ2V0KCdwcm9jZXNzUmVmJyk7XHJcbiAgICAgIH1cclxuICAgIH0sIHRyYW5zbGF0ZSkpO1xyXG4gIH1cclxuXHJcbiAgaWYgKGlzKGVsZW1lbnQsICdhY3Rpdml0aTpBc3luY0NhcGFibGUnKSkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGpvYlJldHJ5VGltZUN5Y2xlKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0OiBnZXRCdXNpbmVzc09iamVjdFxyXG4gICAgfSwgdHJhbnNsYXRlKSk7XHJcbiAgfVxyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgSW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0ltcGxlbWVudGF0aW9uVHlwZUhlbHBlcicpLFxyXG5cclxuICAgIHNjcmlwdEltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9TY3JpcHQnKTtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBMSVNURU5FUl9UWVBFX0xBQkVMID0ge1xyXG4gICAgY2xhc3M6IHRyYW5zbGF0ZSgnSmF2YSBDbGFzcycpLFxyXG4gICAgZXhwcmVzc2lvbjogdHJhbnNsYXRlKCdFeHByZXNzaW9uJyksXHJcbiAgICBkZWxlZ2F0ZUV4cHJlc3Npb246IHRyYW5zbGF0ZSgnRGVsZWdhdGUgRXhwcmVzc2lvbicpLFxyXG4gICAgc2NyaXB0OiB0cmFuc2xhdGUoJ1NjcmlwdCcpXHJcbiAgfTtcclxuXHJcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG4gIHZhciBnZXRTZWxlY3RlZExpc3RlbmVyID0gb3B0aW9ucy5nZXRTZWxlY3RlZExpc3RlbmVyO1xyXG5cclxuICB2YXIgY2xhc3NQcm9wID0gJ2NsYXNzJyxcclxuICAgICAgZXhwcmVzc2lvblByb3AgPSAnZXhwcmVzc2lvbicsXHJcbiAgICAgIGRlbGVnYXRlRXhwcmVzc2lvblByb3AgPSAnZGVsZWdhdGVFeHByZXNzaW9uJyxcclxuICAgICAgc2NyaXB0UHJvcCA9ICdzY3JpcHQnO1xyXG5cclxuICB2YXIgZXhlY3V0aW9uTGlzdGVuZXJFdmVudFR5cGVPcHRpb25zID0gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzU2VxdWVuY2VGbG93KGVsZW1lbnQpID8gW1xyXG4gICAgeyBuYW1lOiB0cmFuc2xhdGUoJ3Rha2UnKSwgdmFsdWU6ICd0YWtlJyB9XHJcbiAgXSA6IFtcclxuICAgIHsgbmFtZTogdHJhbnNsYXRlKCdzdGFydCcpLCB2YWx1ZTogJ3N0YXJ0JyB9LFxyXG4gICAgeyBuYW1lOiB0cmFuc2xhdGUoJ2VuZCcpLCB2YWx1ZTogJ2VuZCcgfVxyXG4gIF07XHJcblxyXG4gIHZhciB0YXNrTGlzdGVuZXJFdmVudFR5cGVPcHRpb25zID0gW1xyXG4gICAgeyBuYW1lOiB0cmFuc2xhdGUoJ2NyZWF0ZScpLCB2YWx1ZTogJ2NyZWF0ZScgfSxcclxuICAgIHsgbmFtZTogdHJhbnNsYXRlKCdhc3NpZ25tZW50JyksIHZhbHVlOiAnYXNzaWdubWVudCcgfSxcclxuICAgIHsgbmFtZTogdHJhbnNsYXRlKCdjb21wbGV0ZScpLCB2YWx1ZTogJ2NvbXBsZXRlJyB9LFxyXG4gICAgeyBuYW1lOiB0cmFuc2xhdGUoJ2RlbGV0ZScpLCB2YWx1ZTogJ2RlbGV0ZScgfVxyXG4gIF07XHJcblxyXG4gIHZhciBpc1NlbGVjdGVkID0gZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgcmV0dXJuIGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcbiAgfTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6ICdsaXN0ZW5lci1ldmVudC10eXBlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0V2ZW50IFR5cGUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdldmVudFR5cGUnLFxyXG4gICAgZW1wdHlQYXJhbWV0ZXI6IGZhbHNlLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG5cclxuXHJcbiAgICAgIHZhciBsaXN0ZW5lciA9IGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICB2YXIgZXZlbnRUeXBlID0gbGlzdGVuZXIgJiYgbGlzdGVuZXIuZ2V0KCdldmVudCcpO1xyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBldmVudFR5cGU6IGV2ZW50VHlwZVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgZXZlbnRUeXBlID0gdmFsdWVzLmV2ZW50VHlwZTtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKSwgeyBldmVudDogZXZlbnRUeXBlIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZWxlY3RPcHRpb25zOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBldmVudFR5cGVPcHRpb25zO1xyXG5cclxuICAgICAgdmFyIHNlbGVjdGVkTGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICBpZiAoSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzVGFza0xpc3RlbmVyKHNlbGVjdGVkTGlzdGVuZXIpKSB7XHJcbiAgICAgICAgZXZlbnRUeXBlT3B0aW9ucyA9IHRhc2tMaXN0ZW5lckV2ZW50VHlwZU9wdGlvbnM7XHJcbiAgICAgIH0gZWxzZSBpZiAoSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzRXhlY3V0aW9uTGlzdGVuZXIoc2VsZWN0ZWRMaXN0ZW5lcikpIHtcclxuICAgICAgICBldmVudFR5cGVPcHRpb25zID0gZXhlY3V0aW9uTGlzdGVuZXJFdmVudFR5cGVPcHRpb25zO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gZXZlbnRUeXBlT3B0aW9ucztcclxuXHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3Rvcnkuc2VsZWN0Qm94KHtcclxuICAgIGlkOiAnbGlzdGVuZXItdHlwZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdMaXN0ZW5lciBUeXBlJyksXHJcbiAgICBzZWxlY3RPcHRpb25zOiBbXHJcbiAgICAgIHsgdmFsdWU6IGNsYXNzUHJvcCwgbmFtZTogdHJhbnNsYXRlKCdKYXZhIENsYXNzJykgfSxcclxuICAgICAgeyB2YWx1ZTogZXhwcmVzc2lvblByb3AsIG5hbWU6IHRyYW5zbGF0ZSgnRXhwcmVzc2lvbicpIH0sXHJcbiAgICAgIHsgdmFsdWU6IGRlbGVnYXRlRXhwcmVzc2lvblByb3AsIG5hbWU6IHRyYW5zbGF0ZSgnRGVsZWdhdGUgRXhwcmVzc2lvbicpIH0sXHJcbiAgICAgIHsgdmFsdWU6IHNjcmlwdFByb3AsIG5hbWU6IHRyYW5zbGF0ZSgnU2NyaXB0JykgfVxyXG4gICAgXSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdsaXN0ZW5lclR5cGUnLFxyXG4gICAgZW1wdHlQYXJhbWV0ZXI6IGZhbHNlLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxpc3RlbmVyVHlwZTogSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldEltcGxlbWVudGF0aW9uVHlwZShsaXN0ZW5lcilcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGxpc3RlbmVyID0gZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKSxcclxuICAgICAgICAgIGxpc3RlbmVyVHlwZSA9IHZhbHVlcy5saXN0ZW5lclR5cGUgfHwgdW5kZWZpbmVkLFxyXG4gICAgICAgICAgdXBkYXRlID0ge307XHJcblxyXG4gICAgICB1cGRhdGVbY2xhc3NQcm9wXSA9IGxpc3RlbmVyVHlwZSA9PT0gY2xhc3NQcm9wID8gJycgOiB1bmRlZmluZWQ7XHJcbiAgICAgIHVwZGF0ZVtleHByZXNzaW9uUHJvcF0gPSBsaXN0ZW5lclR5cGUgPT09IGV4cHJlc3Npb25Qcm9wID8gJycgOiB1bmRlZmluZWQ7XHJcbiAgICAgIHVwZGF0ZVtkZWxlZ2F0ZUV4cHJlc3Npb25Qcm9wXSA9IGxpc3RlbmVyVHlwZSA9PT0gZGVsZWdhdGVFeHByZXNzaW9uUHJvcCA/ICcnIDogdW5kZWZpbmVkO1xyXG4gICAgICB1cGRhdGVbc2NyaXB0UHJvcF0gPSBsaXN0ZW5lclR5cGUgPT09IHNjcmlwdFByb3AgPyBicG1uRmFjdG9yeS5jcmVhdGUoJ2FjdGl2aXRpOlNjcmlwdCcpIDogdW5kZWZpbmVkO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBsaXN0ZW5lciwgdXBkYXRlKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhaXNTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuXHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdsaXN0ZW5lci12YWx1ZScsXHJcbiAgICBkYXRhVmFsdWVMYWJlbDogJ2xpc3RlbmVyVmFsdWVMYWJlbCcsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnbGlzdGVuZXJWYWx1ZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciB2YWx1ZSA9IHt9LFxyXG4gICAgICAgICAgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgbGlzdGVuZXJUeXBlID0gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldEltcGxlbWVudGF0aW9uVHlwZShsaXN0ZW5lcik7XHJcblxyXG4gICAgICB2YWx1ZS5saXN0ZW5lclZhbHVlTGFiZWwgPSBMSVNURU5FUl9UWVBFX0xBQkVMW2xpc3RlbmVyVHlwZV0gfHwgJyc7XHJcbiAgICAgIHZhbHVlLmxpc3RlbmVyVmFsdWUgPSAobGlzdGVuZXIgJiYgbGlzdGVuZXIuZ2V0KGxpc3RlbmVyVHlwZSkpIHx8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIHVwZGF0ZSA9IHt9LFxyXG4gICAgICAgICAgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpLFxyXG4gICAgICAgICAgbGlzdGVuZXJUeXBlID0gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmdldEltcGxlbWVudGF0aW9uVHlwZShsaXN0ZW5lcik7XHJcblxyXG4gICAgICB1cGRhdGVbbGlzdGVuZXJUeXBlXSA9IHZhbHVlcy5saXN0ZW5lclZhbHVlIHx8ICcnO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBsaXN0ZW5lciwgdXBkYXRlKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBsaXN0ZW5lciA9IGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiAhbGlzdGVuZXIgfHwgbGlzdGVuZXIuc2NyaXB0O1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciB2YWx1ZSA9IHZhbHVlcy5saXN0ZW5lclZhbHVlLFxyXG4gICAgICAgICAgdmFsaWRhdGUgPSB7fTtcclxuXHJcbiAgICAgIGlmICghdmFsdWUpIHtcclxuICAgICAgICB2YWxpZGF0ZS5saXN0ZW5lclZhbHVlID0gdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdmFsaWRhdGU7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgdmFyIHNjcmlwdCA9IHNjcmlwdEltcGxlbWVudGF0aW9uKCdzY3JpcHRGb3JtYXQnLCAndmFsdWUnLCB0cnVlLCB0cmFuc2xhdGUpO1xyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goe1xyXG4gICAgaWQ6ICdsaXN0ZW5lci1zY3JpcHQtdmFsdWUnLFxyXG4gICAgaHRtbDogJzxkaXYgZGF0YS1zaG93PVwiaXNTY3JpcHRcIj4nICtcclxuICAgICAgICAgICAgc2NyaXB0LnRlbXBsYXRlICtcclxuICAgICAgICAgICc8L2Rpdj4nLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gbGlzdGVuZXIgJiYgbGlzdGVuZXIuc2NyaXB0ID8gc2NyaXB0LmdldChlbGVtZW50LCBsaXN0ZW5lci5zY3JpcHQpIDoge307XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBsaXN0ZW5lciA9IGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciB1cGRhdGUgPSBzY3JpcHQuc2V0KGVsZW1lbnQsIHZhbHVlcywgbGlzdGVuZXIpO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGxpc3RlbmVyLnNjcmlwdCwgdXBkYXRlKTtcclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgbGlzdGVuZXIgPSBnZXRTZWxlY3RlZExpc3RlbmVyKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gbGlzdGVuZXIgJiYgbGlzdGVuZXIuc2NyaXB0ID8gc2NyaXB0LnZhbGlkYXRlKGVsZW1lbnQsIHZhbHVlcykgOiB7fTtcclxuICAgIH0sXHJcblxyXG4gICAgaXNTY3JpcHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGxpc3RlbmVyID0gZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGxpc3RlbmVyICYmIGxpc3RlbmVyLnNjcmlwdDtcclxuICAgIH0sXHJcblxyXG4gICAgc2NyaXB0OiBzY3JpcHRcclxuXHJcbiAgfSk7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xyXG5cclxudmFyIGZpZWxkSW5qZWN0aW9uID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9GaWVsZEluamVjdGlvbicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICBvcHRpb25zID0gYXNzaWduKHtcclxuICAgIGlkUHJlZml4OiAnbGlzdGVuZXItJyxcclxuICAgIGluc2lkZUxpc3RlbmVyOiB0cnVlXHJcbiAgfSwgb3B0aW9ucyk7XHJcblxyXG4gIHZhciBmaWVsZEluamVjdGlvbkVudHJ5ID0gZmllbGRJbmplY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSwgb3B0aW9ucyk7XHJcblxyXG4gIGlmIChmaWVsZEluamVjdGlvbkVudHJ5ICYmIGZpZWxkSW5qZWN0aW9uRW50cnkubGVuZ3RoID4gMCkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGZpZWxkSW5qZWN0aW9uRW50cnkpO1xyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBsaXN0ZW5lciA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vTGlzdGVuZXInKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGxpc3RlbmVyRW50cnkgPSBsaXN0ZW5lcihlbGVtZW50LCBicG1uRmFjdG9yeSwge30sIHRyYW5zbGF0ZSk7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChsaXN0ZW5lckVudHJ5LmVudHJpZXMpO1xyXG5cclxuICByZXR1cm4ge1xyXG4gICAgZ2V0U2VsZWN0ZWRMaXN0ZW5lcjogbGlzdGVuZXJFbnRyeS5nZXRTZWxlY3RlZExpc3RlbmVyXHJcbiAgfTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgbXVsdGlJbnN0YW5jZUxvb3BDaGFyYWN0ZXJpc3RpY3MgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL011bHRpSW5zdGFuY2VMb29wQ2hhcmFjdGVyaXN0aWNzJyk7XHJcblxyXG52YXIgam9iUmV0cnlUaW1lQ3ljbGUgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0pvYlJldHJ5VGltZUN5Y2xlJyksXHJcbiAgICBhc3luY0NvbnRpbnVhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQXN5bmNDb250aW51YXRpb24nKTtcclxuXHJcblxyXG5mdW5jdGlvbiBnZXRMb29wQ2hhcmFjdGVyaXN0aWNzKGVsZW1lbnQpIHtcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICByZXR1cm4gYm8ubG9vcENoYXJhY3RlcmlzdGljcztcclxufVxyXG5cclxuXHJcbmZ1bmN0aW9uIGVuc3VyZU11bHRpSW5zdGFuY2VTdXBwb3J0ZWQoZWxlbWVudCkge1xyXG4gIHZhciBsb29wQ2hhcmFjdGVyaXN0aWNzID0gZ2V0TG9vcENoYXJhY3RlcmlzdGljcyhlbGVtZW50KTtcclxuICByZXR1cm4gISFsb29wQ2hhcmFjdGVyaXN0aWNzICYmIGlzKGxvb3BDaGFyYWN0ZXJpc3RpY3MsICdhY3Rpdml0aTpDb2xsZWN0YWJsZScpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlmICghZW5zdXJlTXVsdGlJbnN0YW5jZVN1cHBvcnRlZChlbGVtZW50KSkge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgLy8gbXVsdGkgaW5zdGFuY2UgcHJvcGVydGllc1xyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChtdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljcyhlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSk7XHJcblxyXG4gIC8vIGFzeW5jIGNvbnRpbnVhdGlvbiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGFzeW5jQ29udGludWF0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBnZXRCdXNpbmVzc09iamVjdDogZ2V0TG9vcENoYXJhY3RlcmlzdGljcyxcclxuICAgIGlkUHJlZml4OiAnbXVsdGlJbnN0YW5jZS0nLFxyXG4gICAgbGFiZWxQcmVmaXg6IHRyYW5zbGF0ZSgnTXVsdGkgSW5zdGFuY2UgJylcclxuICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcblxyXG4gIC8vIHJldHJ5IHRpbWUgY3ljbGUgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChqb2JSZXRyeVRpbWVDeWNsZShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGdldExvb3BDaGFyYWN0ZXJpc3RpY3MsXHJcbiAgICBpZFByZWZpeDogJ211bHRpSW5zdGFuY2UtJyxcclxuICAgIGxhYmVsUHJlZml4OiB0cmFuc2xhdGUoJ011bHRpIEluc3RhbmNlICcpXHJcbiAgfSwgdHJhbnNsYXRlKSk7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBwcm9wZXJ0aWVzID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9Qcm9wZXJ0aWVzJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBwcm9wZXJ0aWVzRW50cnkgPSBwcm9wZXJ0aWVzKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ3Byb3BlcnRpZXMnLFxyXG4gICAgbW9kZWxQcm9wZXJ0aWVzOiBbICduYW1lJywgJ3ZhbHVlJyBdLFxyXG4gICAgbGFiZWxzOiBbIHRyYW5zbGF0ZSgnTmFtZScpLCB0cmFuc2xhdGUoJ1ZhbHVlJykgXSxcclxuXHJcbiAgICBnZXRQYXJlbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGJvKSB7XHJcbiAgICAgIHJldHVybiBiby5leHRlbnNpb25FbGVtZW50cztcclxuICAgIH0sXHJcblxyXG4gICAgY3JlYXRlUGFyZW50OiBmdW5jdGlvbihlbGVtZW50LCBibykge1xyXG4gICAgICB2YXIgcGFyZW50ID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkV4dGVuc2lvbkVsZW1lbnRzJywgeyB2YWx1ZXM6IFtdIH0sIGJvLCBicG1uRmFjdG9yeSk7XHJcbiAgICAgIHZhciBjbWQgPSBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgZXh0ZW5zaW9uRWxlbWVudHM6IHBhcmVudCB9KTtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBjbWQ6IGNtZCxcclxuICAgICAgICBwYXJlbnQ6IHBhcmVudFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH0sIHRyYW5zbGF0ZSk7XHJcblxyXG4gIGlmIChwcm9wZXJ0aWVzRW50cnkpIHtcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChwcm9wZXJ0aWVzRW50cnkpO1xyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgc2NyaXB0SW1wbGVtZW50YXRpb24gPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL1NjcmlwdCcpO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuICB2YXIgYm87XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpTY3JpcHRUYXNrJykpIHtcclxuICAgIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICBpZiAoIWJvKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgc2NyaXB0ID0gc2NyaXB0SW1wbGVtZW50YXRpb24oJ3NjcmlwdEZvcm1hdCcsICdzY3JpcHQnLCBmYWxzZSwgdHJhbnNsYXRlKTtcclxuICBncm91cC5lbnRyaWVzLnB1c2goe1xyXG4gICAgaWQ6ICdzY3JpcHQtaW1wbGVtZW50YXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnU2NyaXB0JyksXHJcbiAgICBodG1sOiBzY3JpcHQudGVtcGxhdGUsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBzY3JpcHQuZ2V0KGVsZW1lbnQsIGJvKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIGNvbnRhaW5lckVsZW1lbnQpIHtcclxuICAgICAgdmFyIHByb3BlcnRpZXMgPSBzY3JpcHQuc2V0KGVsZW1lbnQsIHZhbHVlcywgY29udGFpbmVyRWxlbWVudCk7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcHJvcGVydGllcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgcmV0dXJuIHNjcmlwdC52YWxpZGF0ZShlbGVtZW50LCB2YWx1ZXMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzY3JpcHQgOiBzY3JpcHQsXHJcblxyXG4gICAgY3NzQ2xhc3NlczogWydicHAtdGV4dGZpZWxkJ11cclxuXHJcbiAgfSk7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkIDogJ3NjcmlwdFJlc3VsdFZhcmlhYmxlJyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdSZXN1bHQgVmFyaWFibGUnKSxcclxuICAgIG1vZGVsUHJvcGVydHkgOiAnc2NyaXB0UmVzdWx0VmFyaWFibGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydHlOYW1lKSB7XHJcbiAgICAgIHZhciBib1Jlc3VsdFZhcmlhYmxlID0gYm8uZ2V0KCdhY3Rpdml0aTpyZXN1bHRWYXJpYWJsZScpO1xyXG5cclxuICAgICAgcmV0dXJuIHsgc2NyaXB0UmVzdWx0VmFyaWFibGUgOiBib1Jlc3VsdFZhcmlhYmxlIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBjb250YWluZXJFbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOnJlc3VsdFZhcmlhYmxlJzogdmFsdWVzLnNjcmlwdFJlc3VsdFZhcmlhYmxlLmxlbmd0aFxyXG4gICAgICAgICAgPyB2YWx1ZXMuc2NyaXB0UmVzdWx0VmFyaWFibGVcclxuICAgICAgICAgIDogdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgSW1wbGVtZW50YXRpb25UeXBlSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0ltcGxlbWVudGF0aW9uVHlwZUhlbHBlcicpLFxyXG4gICAgSW5wdXRPdXRwdXRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvSW5wdXRPdXRwdXRIZWxwZXInKTtcclxuXHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uL1V0aWxzJyksXHJcbiAgICBlc2NhcGVIVE1MID0gdXRpbHMuZXNjYXBlSFRNTCxcclxuICAgIHRyaWdnZXJDbGlja0V2ZW50ID0gdXRpbHMudHJpZ2dlckNsaWNrRXZlbnQ7XHJcblxyXG52YXIgaW1wbGVtZW50YXRpb25UeXBlID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9JbXBsZW1lbnRhdGlvblR5cGUnKSxcclxuICAgIGRlbGVnYXRlID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9EZWxlZ2F0ZScpLFxyXG4gICAgZXh0ZXJuYWwgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0V4dGVybmFsJyksXHJcbiAgICBjYWxsYWJsZSA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQ2FsbGFibGUnKSxcclxuICAgIHJlc3VsdFZhcmlhYmxlID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9SZXN1bHRWYXJpYWJsZScpO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnksXHJcbiAgICBkb21DbG9zZXN0ID0gcmVxdWlyZSgnbWluLWRvbScpLmNsb3Nlc3QsXHJcbiAgICBkb21DbGFzc2VzID0gcmVxdWlyZSgnbWluLWRvbScpLmNsYXNzZXM7XHJcblxyXG5mdW5jdGlvbiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkge1xyXG4gIHJldHVybiBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuZ2V0SW1wbGVtZW50YXRpb25UeXBlKGVsZW1lbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSB7XHJcbiAgcmV0dXJuIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRTZXJ2aWNlVGFza0xpa2VCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNEbW5DYXBhYmxlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzRG1uQ2FwYWJsZShlbGVtZW50KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNFeHRlcm5hbENhcGFibGUoZWxlbWVudCkge1xyXG4gIHJldHVybiBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuaXNFeHRlcm5hbENhcGFibGUoZWxlbWVudCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzU2VydmljZVRhc2tMaWtlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gSW1wbGVtZW50YXRpb25UeXBlSGVscGVyLmlzU2VydmljZVRhc2tMaWtlKGVsZW1lbnQpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGlmICghaXNTZXJ2aWNlVGFza0xpa2UoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgaGFzRG1uU3VwcG9ydCA9IGlzRG1uQ2FwYWJsZShlbGVtZW50KTtcclxuICB2YXIgaGFzRXh0ZXJuYWxTdXBwb3J0ID0gaXNFeHRlcm5hbENhcGFibGUoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkpO1xyXG5cclxuICAvLyBpbXBsZW1lbnRhdGlvbiB0eXBlIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoaW1wbGVtZW50YXRpb25UeXBlKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBnZXRCdXNpbmVzc09iamVjdDogZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBnZXRJbXBsZW1lbnRhdGlvblR5cGU6IGdldEltcGxlbWVudGF0aW9uVHlwZSxcclxuICAgIGhhc0RtblN1cHBvcnQ6IGhhc0RtblN1cHBvcnQsXHJcbiAgICBoYXNFeHRlcm5hbFN1cHBvcnQ6IGhhc0V4dGVybmFsU3VwcG9ydCxcclxuICAgIGhhc1NlcnZpY2VUYXNrTGlrZVN1cHBvcnQ6IHRydWVcclxuICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcblxyXG4gIC8vIGRlbGVnYXRlIChjbGFzcywgZXhwcmVzc2lvbiwgZGVsZWdhdGVFeHByZXNzaW9uKSAvLy8vLy8vLy8vXHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChkZWxlZ2F0ZShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgZ2V0SW1wbGVtZW50YXRpb25UeXBlOiBnZXRJbXBsZW1lbnRhdGlvblR5cGVcclxuICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcblxyXG4gIC8vIHJlc3VsdCB2YXJpYWJsZSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQocmVzdWx0VmFyaWFibGUoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0OiBnZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGdldEltcGxlbWVudGF0aW9uVHlwZTogZ2V0SW1wbGVtZW50YXRpb25UeXBlLFxyXG4gICAgaGlkZVJlc3VsdFZhcmlhYmxlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkgIT09ICdleHByZXNzaW9uJztcclxuICAgIH1cclxuICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgLy8gZXh0ZXJuYWwgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgaWYgKGhhc0V4dGVybmFsU3VwcG9ydCkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGV4dGVybmFsKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGdldEJ1c2luZXNzT2JqZWN0OiBnZXRCdXNpbmVzc09iamVjdCxcclxuICAgICAgZ2V0SW1wbGVtZW50YXRpb25UeXBlOiBnZXRJbXBsZW1lbnRhdGlvblR5cGVcclxuICAgIH0sIHRyYW5zbGF0ZSkpO1xyXG4gIH1cclxuXHJcblxyXG4gIC8vIGRtbiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBpZiAoaGFzRG1uU3VwcG9ydCkge1xyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGNhbGxhYmxlKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGdldENhbGxhYmxlVHlwZTogZ2V0SW1wbGVtZW50YXRpb25UeXBlXHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuICB9XHJcblxyXG5cclxuICAvLyBjb25uZWN0b3IgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIHZhciBpc0Nvbm5lY3RvciA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkgPT09ICdjb25uZWN0b3InO1xyXG4gIH07XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkubGluayh7XHJcbiAgICBpZDogJ2NvbmZpZ3VyZUNvbm5lY3RvckxpbmsnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ29uZmlndXJlIENvbm5lY3RvcicpLFxyXG4gICAgaGFuZGxlQ2xpY2s6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50KSB7XHJcblxyXG4gICAgICB2YXIgY29ubmVjdG9yVGFiRWwgPSBnZXRUYWJOb2RlKG5vZGUsICdjb25uZWN0b3InKTtcclxuXHJcbiAgICAgIGlmIChjb25uZWN0b3JUYWJFbCkge1xyXG4gICAgICAgIHRyaWdnZXJDbGlja0V2ZW50KGNvbm5lY3RvclRhYkVsKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gc3VwcHJlc3MgYWN0dWFsIGxpbmsgY2xpY2tcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfSxcclxuICAgIHNob3dMaW5rOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBsaW5rID0gZG9tUXVlcnkoJ2EnLCBub2RlKTtcclxuICAgICAgbGluay50ZXh0Q29udGVudCA9ICcnO1xyXG5cclxuICAgICAgZG9tQ2xhc3NlcyhsaW5rKS5yZW1vdmUoJ2JwcC1lcnJvci1tZXNzYWdlJyk7XHJcblxyXG4gICAgICBpZiAoaXNDb25uZWN0b3IoZWxlbWVudCkpIHtcclxuICAgICAgICB2YXIgY29ubmVjdG9ySWQgPSBJbnB1dE91dHB1dEhlbHBlci5nZXRDb25uZWN0b3IoZWxlbWVudCkuZ2V0KCdjb25uZWN0b3JJZCcpO1xyXG4gICAgICAgIGlmIChjb25uZWN0b3JJZCkge1xyXG4gICAgICAgICAgbGluay50ZXh0Q29udGVudCA9IHRyYW5zbGF0ZSgnQ29uZmlndXJlIENvbm5lY3RvcicpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBsaW5rLmlubmVySFRNTCA9ICc8c3BhbiBjbGFzcz1cImJwcC1pY29uLXdhcm5pbmdcIj48L3NwYW4+ICcgKyBlc2NhcGVIVE1MKHRyYW5zbGF0ZSgnTXVzdCBjb25maWd1cmUgQ29ubmVjdG9yJykpO1xyXG4gICAgICAgICAgZG9tQ2xhc3NlcyhsaW5rKS5hZGQoJ2JwcC1lcnJvci1tZXNzYWdlJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbn07XHJcblxyXG5cclxuXHJcbi8vIGhlbHBlcnMgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG5mdW5jdGlvbiBnZXRUYWJOb2RlKGVsLCBpZCkge1xyXG4gIHZhciBjb250YWluZXJFbCA9IGRvbUNsb3Nlc3QoZWwsICcuYnBwLXByb3BlcnRpZXMtcGFuZWwnKTtcclxuXHJcbiAgcmV0dXJuIGRvbVF1ZXJ5KCdhW2RhdGEtdGFiLXRhcmdldD1cIicgKyBpZCArICdcIl0nLCBjb250YWluZXJFbCk7XHJcbn0iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6SW5pdGlhdG9yJykgJiYgIWlzKGVsZW1lbnQucGFyZW50LCAnYnBtbjpTdWJQcm9jZXNzJykpIHtcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQ6ICdpbml0aWF0b3InLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdJbml0aWF0b3InKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eTogJ2luaXRpYXRvcidcclxuICAgIH0pKTtcclxuICB9XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgdGFza2xpc3QgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL1Rhc2tsaXN0Jyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIGJ1c2luZXNzT2JqZWN0ID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYWN0aXZpdGk6UHJvY2VzcycpIHx8XHJcbiAgICAgIGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdwcm9jZXNzUmVmJykpIHtcclxuXHJcbiAgICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQodGFza2xpc3QoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3Q6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKCFpcyhibywgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICAgICAgcmV0dXJuIGJvO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGJvLmdldCgncHJvY2Vzc1JlZicpO1xyXG4gICAgICB9XHJcbiAgICB9LCB0cmFuc2xhdGUpKTtcclxuXHJcbiAgfVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzLFxyXG4gICAgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpIHtcclxuICBpZiAoaXMoZWxlbWVudCwgJ2FjdGl2aXRpOkFzc2lnbmFibGUnKSkge1xyXG5cclxuICAgIC8vIEFzc2lnbmVlXHJcbiAgICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICAgIGlkIDogJ2Fzc2lnbmVlJyxcclxuICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0Fzc2lnbmVlJyksXHJcbiAgICAgIG1vZGVsUHJvcGVydHkgOiAnYXNzaWduZWUnXHJcbiAgICB9KSk7XHJcblxyXG4gICAgLy8gQ2FuZGlkYXRlIFVzZXJzXHJcbiAgICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICAgIGlkIDogJ2NhbmRpZGF0ZVVzZXJzJyxcclxuICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0NhbmRpZGF0ZSBVc2VycycpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5IDogJ2NhbmRpZGF0ZVVzZXJzJ1xyXG4gICAgfSkpO1xyXG5cclxuICAgIC8vIENhbmRpZGF0ZSBHcm91cHNcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQgOiAnY2FuZGlkYXRlR3JvdXBzJyxcclxuICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0NhbmRpZGF0ZSBHcm91cHMnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA6ICdjYW5kaWRhdGVHcm91cHMnXHJcbiAgICB9KSk7XHJcblxyXG4gICAgLy8gRHVlIERhdGVcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQgOiAnZHVlRGF0ZScsXHJcbiAgICAgIGRlc2NyaXB0aW9uIDogdHJhbnNsYXRlKCdUaGUgZHVlIGRhdGUgYXMgYW4gRUwgZXhwcmVzc2lvbiAoZS5nLiAke3NvbWVEYXRlfSBvciBhbiBJU08gZGF0ZSAoZS5nLiAyMDE1LTA2LTI2VDA5OjU0OjAwKScpLFxyXG4gICAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnRHVlIERhdGUnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA6ICdkdWVEYXRlJ1xyXG4gICAgfSkpO1xyXG5cclxuICAgIC8vIEZvbGxvd1VwIERhdGVcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQgOiAnZm9sbG93VXBEYXRlJyxcclxuICAgICAgZGVzY3JpcHRpb24gOiB0cmFuc2xhdGUoJ1RoZSBmb2xsb3cgdXAgZGF0ZSBhcyBhbiBFTCBleHByZXNzaW9uIChlLmcuICR7c29tZURhdGV9IG9yIGFuICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICdJU08gZGF0ZSAoZS5nLiAyMDE1LTA2LTI2VDA5OjU0OjAwKScpLFxyXG4gICAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnRm9sbG93IFVwIERhdGUnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA6ICdmb2xsb3dVcERhdGUnXHJcbiAgICB9KSk7XHJcblxyXG4gICAgLy8gcHJpb3JpdHlcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQgOiAncHJpb3JpdHknLFxyXG4gICAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnUHJpb3JpdHknKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA6ICdwcmlvcml0eSdcclxuICAgIH0pKTtcclxuICB9XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBpc0FueSA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJykuaXNBbnksXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgZmlsdGVyID0gcmVxdWlyZSgnbG9kYXNoL2ZpbHRlcicpO1xyXG5cclxudmFyIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKSxcclxuICAgIGV2ZW50RGVmaW5pdGlvbkhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uL2hlbHBlci9FdmVudERlZmluaXRpb25IZWxwZXInKTtcclxuXHJcbnZhciBleHRlbnNpb25FbGVtZW50c0VudHJ5ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9FeHRlbnNpb25FbGVtZW50cycpO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG4vKipcclxuICAqIHJldHVybiBkZXBlbmQgb24gcGFyYW1ldGVyICd0eXBlJyBhY3Rpdml0aTppbiBvciBhY3Rpdml0aTpvdXQgZXh0ZW5zaW9uIGVsZW1lbnRzXHJcbiAgKi9cclxuZnVuY3Rpb24gZ2V0QWN0aXZpdGlJbk91dE1hcHBpbmdzKGVsZW1lbnQsIHR5cGUpIHtcclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgdmFyIHNpZ25hbEV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRTaWduYWxFdmVudERlZmluaXRpb24oYm8pO1xyXG5cclxuICByZXR1cm4gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoc2lnbmFsRXZlbnREZWZpbml0aW9uIHx8IGJvLCB0eXBlKSB8fCBbXTtcclxufVxyXG5cclxuLyoqXHJcbiAgKiByZXR1cm4gZGVwZW5kIG9uIHBhcmFtZXRlciAndHlwZScgYWN0aXZpdGk6aW4gb3IgYWN0aXZpdGk6b3V0IGV4dGVuc2lvbiBlbGVtZW50c1xyXG4gICogd2l0aCBzb3VyY2Ugb3Igc291cmNlRXhwcmVzc2lvbiBhdHRyaWJ1dGVcclxuICAqL1xyXG5mdW5jdGlvbiBnZXRWYXJpYWJsZU1hcHBpbmdzKGVsZW1lbnQsIHR5cGUpIHtcclxuICB2YXIgYWN0aXZpdGlNYXBwaW5ncyA9IGdldEFjdGl2aXRpSW5PdXRNYXBwaW5ncyhlbGVtZW50LCB0eXBlKTtcclxuXHJcbiAgcmV0dXJuIGZpbHRlcihhY3Rpdml0aU1hcHBpbmdzLCBmdW5jdGlvbihtYXBwaW5nKSB7XHJcbiAgICByZXR1cm4gIW1hcHBpbmcuYnVzaW5lc3NLZXk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEluT3V0VHlwZShtYXBwaW5nKSB7XHJcbiAgdmFyIGluT3V0VHlwZSA9ICdzb3VyY2UnO1xyXG5cclxuICBpZiAobWFwcGluZy52YXJpYWJsZXMgPT09ICdhbGwnKSB7XHJcbiAgICBpbk91dFR5cGUgPSAndmFyaWFibGVzJztcclxuICB9XHJcbiAgZWxzZSBpZiAodHlwZW9mIG1hcHBpbmcuc291cmNlICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgaW5PdXRUeXBlID0gJ3NvdXJjZSc7XHJcbiAgfVxyXG4gIGVsc2UgaWYgKHR5cGVvZiBtYXBwaW5nLnNvdXJjZUV4cHJlc3Npb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICBpbk91dFR5cGUgPSAnc291cmNlRXhwcmVzc2lvbic7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gaW5PdXRUeXBlO1xyXG59XHJcblxyXG52YXIgQUNUSVZJVElfSU5fRVhURU5TSU9OX0VMRU1FTlQgPSAnYWN0aXZpdGk6SW4nLFxyXG4gICAgQUNUSVZJVElfT1VUX0VYVEVOU0lPTl9FTEVNRU5UID0gJ2FjdGl2aXRpOk91dCc7XHJcblxyXG52YXIgV0hJVEVTUEFDRV9SRUdFWCA9IC9cXHMvO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGluT3V0VHlwZU9wdGlvbnMgPSBbXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6IHRyYW5zbGF0ZSgnU291cmNlJyksXHJcbiAgICAgIHZhbHVlOiAnc291cmNlJ1xyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogdHJhbnNsYXRlKCdTb3VyY2UgRXhwcmVzc2lvbicpLFxyXG4gICAgICB2YWx1ZTogJ3NvdXJjZUV4cHJlc3Npb24nXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiB0cmFuc2xhdGUoJ0FsbCcpLFxyXG4gICAgICB2YWx1ZTogJ3ZhcmlhYmxlcydcclxuICAgIH1cclxuICBdO1xyXG5cclxuICB2YXIgc2lnbmFsRXZlbnREZWZpbml0aW9uID0gZXZlbnREZWZpbml0aW9uSGVscGVyLmdldFNpZ25hbEV2ZW50RGVmaW5pdGlvbihlbGVtZW50KTtcclxuXHJcbiAgaWYgKCFpcyhlbGVtZW50LCAnYWN0aXZpdGk6Q2FsbEFjdGl2aXR5JykgJiYgIXNpZ25hbEV2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgcmV0dXJuO1xyXG4gIH1cclxuXHJcbiAgaWYgKHNpZ25hbEV2ZW50RGVmaW5pdGlvbiAmJiAhKGlzQW55KGVsZW1lbnQsIFtcclxuICAgICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnLFxyXG4gICAgJ2JwbW46RW5kRXZlbnQnXHJcbiAgXSkpKSB7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICB2YXIgaXNTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHJldHVybiAhIWdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gIH07XHJcblxyXG4gIHZhciBnZXRTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciBwYXJlbnROb2RlID0gbm9kZS5wYXJlbnROb2RlO1xyXG4gICAgdmFyIHNlbGVjdGlvbiA9IGluRW50cnkuZ2V0U2VsZWN0ZWQoZWxlbWVudCwgcGFyZW50Tm9kZSk7XHJcblxyXG4gICAgdmFyIHBhcmFtZXRlciA9IGdldFZhcmlhYmxlTWFwcGluZ3MoZWxlbWVudCwgQUNUSVZJVElfSU5fRVhURU5TSU9OX0VMRU1FTlQpW3NlbGVjdGlvbi5pZHhdO1xyXG5cclxuICAgIGlmICghcGFyYW1ldGVyICYmIG91dEVudHJ5KSB7XHJcbiAgICAgIHNlbGVjdGlvbiA9IG91dEVudHJ5LmdldFNlbGVjdGVkKGVsZW1lbnQsIHBhcmVudE5vZGUpO1xyXG4gICAgICBwYXJhbWV0ZXIgPSBnZXRWYXJpYWJsZU1hcHBpbmdzKGVsZW1lbnQsIEFDVElWSVRJX09VVF9FWFRFTlNJT05fRUxFTUVOVClbc2VsZWN0aW9uLmlkeF07XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBhcmFtZXRlcjtcclxuICB9O1xyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBvcHRpb24sIHByb3BlcnR5LCB2YWx1ZSwgaWR4KSB7XHJcbiAgICAgIHZhciB2YXJpYWJsZU1hcHBpbmdzID0gZ2V0VmFyaWFibGVNYXBwaW5ncyhlbGVtZW50LCB0eXBlKTtcclxuICAgICAgdmFyIG1hcHBpbmdWYWx1ZSA9IHZhcmlhYmxlTWFwcGluZ3NbaWR4XTtcclxuICAgICAgdmFyIGxhYmVsID0gKG1hcHBpbmdWYWx1ZS50YXJnZXQgfHwgJzx1bmRlZmluZWQ+JykgKyAnIDo9ICc7XHJcbiAgICAgIHZhciBtYXBwaW5nVHlwZSA9IGdldEluT3V0VHlwZShtYXBwaW5nVmFsdWUpO1xyXG5cclxuICAgICAgaWYgKG1hcHBpbmdUeXBlID09PSAndmFyaWFibGVzJykge1xyXG4gICAgICAgIGxhYmVsID0gJ2FsbCc7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAobWFwcGluZ1R5cGUgPT09ICdzb3VyY2UnKSB7XHJcbiAgICAgICAgbGFiZWwgPSBsYWJlbCArIChtYXBwaW5nVmFsdWUuc291cmNlIHx8ICc8ZW1wdHk+Jyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAobWFwcGluZ1R5cGUgPT09ICdzb3VyY2VFeHByZXNzaW9uJykge1xyXG4gICAgICAgIGxhYmVsID0gbGFiZWwgKyAobWFwcGluZ1ZhbHVlLnNvdXJjZUV4cHJlc3Npb24gfHwgJzxlbXB0eT4nKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBsYWJlbCA9IGxhYmVsICsgJzxlbXB0eT4nO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBvcHRpb24udGV4dCA9IGxhYmVsO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgbmV3RWxlbWVudCA9IGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgdmFsdWUpIHtcclxuICAgICAgdmFyIG5ld0VsZW0gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQodHlwZSwgeyBzb3VyY2U6ICcnIH0sIGV4dGVuc2lvbkVsZW1lbnRzLCBicG1uRmFjdG9yeSk7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLmFkZEVsZW1lbnRzVG9saXN0KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCAndmFsdWVzJywgWyBuZXdFbGVtIF0pO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgcmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgdmFsdWUsIGlkeCkge1xyXG4gICAgICB2YXIgdmFyaWFibGVzTWFwcGluZ3M9IGdldFZhcmlhYmxlTWFwcGluZ3MoZWxlbWVudCwgdHlwZSk7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gdmFyaWFibGVzTWFwcGluZ3NbaWR4XTtcclxuXHJcbiAgICAgIGlmIChtYXBwaW5nKSB7XHJcbiAgICAgICAgcmV0dXJuIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyXHJcbiAgICAgICAgICAucmVtb3ZlRW50cnkoc2lnbmFsRXZlbnREZWZpbml0aW9uIHx8IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLCBlbGVtZW50LCBtYXBwaW5nKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICAvLyBpbiBtYXBwaW5nIGZvciBzb3VyY2UgYW5kIHNvdXJjZUV4cHJlc3Npb24gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIHZhciBpbkVudHJ5ID0gZXh0ZW5zaW9uRWxlbWVudHNFbnRyeShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgaWQ6ICd2YXJpYWJsZU1hcHBpbmctaW4nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSW4gTWFwcGluZycpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3NvdXJjZScsXHJcbiAgICBwcmVmaXg6ICdJbicsXHJcbiAgICBpZEdlbmVyYXRpb246IGZhbHNlLFxyXG4gICAgcmVzaXphYmxlOiB0cnVlLFxyXG4gICAgYnVzaW5lc3NPYmplY3Q6IHNpZ25hbEV2ZW50RGVmaW5pdGlvbiB8fCBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuXHJcbiAgICBjcmVhdGVFeHRlbnNpb25FbGVtZW50OiBuZXdFbGVtZW50KEFDVElWSVRJX0lOX0VYVEVOU0lPTl9FTEVNRU5UKSxcclxuICAgIHJlbW92ZUV4dGVuc2lvbkVsZW1lbnQ6IHJlbW92ZUVsZW1lbnQoQUNUSVZJVElfSU5fRVhURU5TSU9OX0VMRU1FTlQpLFxyXG5cclxuICAgIGdldEV4dGVuc2lvbkVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBnZXRWYXJpYWJsZU1hcHBpbmdzKGVsZW1lbnQsIEFDVElWSVRJX0lOX0VYVEVOU0lPTl9FTEVNRU5UKTtcclxuICAgIH0sXHJcblxyXG4gICAgb25TZWxlY3Rpb25DaGFuZ2U6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50LCBzY29wZSkge1xyXG4gICAgICBvdXRFbnRyeSAmJiBvdXRFbnRyeS5kZXNlbGVjdChlbGVtZW50LCBub2RlLnBhcmVudE5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKEFDVElWSVRJX0lOX0VYVEVOU0lPTl9FTEVNRU5UKVxyXG4gIH0pO1xyXG4gIGdyb3VwLmVudHJpZXMucHVzaChpbkVudHJ5KTtcclxuXHJcbiAgLy8gb3V0IG1hcHBpbmcgZm9yIHNvdXJjZSBhbmQgc291cmNlRXhwcmVzc2lvbiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIGlmICghc2lnbmFsRXZlbnREZWZpbml0aW9uKSB7XHJcbiAgICB2YXIgb3V0RW50cnkgPSBleHRlbnNpb25FbGVtZW50c0VudHJ5KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGlkOiAndmFyaWFibGVNYXBwaW5nLW91dCcsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ091dCBNYXBwaW5nJyksXHJcbiAgICAgIG1vZGVsUHJvcGVydHk6ICdzb3VyY2UnLFxyXG4gICAgICBwcmVmaXg6ICdPdXQnLFxyXG4gICAgICBpZEdlbmVyYXRpb246IGZhbHNlLFxyXG4gICAgICByZXNpemFibGU6IHRydWUsXHJcblxyXG4gICAgICBjcmVhdGVFeHRlbnNpb25FbGVtZW50OiBuZXdFbGVtZW50KEFDVElWSVRJX09VVF9FWFRFTlNJT05fRUxFTUVOVCksXHJcbiAgICAgIHJlbW92ZUV4dGVuc2lvbkVsZW1lbnQ6IHJlbW92ZUVsZW1lbnQoQUNUSVZJVElfT1VUX0VYVEVOU0lPTl9FTEVNRU5UKSxcclxuXHJcbiAgICAgIGdldEV4dGVuc2lvbkVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGdldFZhcmlhYmxlTWFwcGluZ3MoZWxlbWVudCwgQUNUSVZJVElfT1VUX0VYVEVOU0lPTl9FTEVNRU5UKTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIG9uU2VsZWN0aW9uQ2hhbmdlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBldmVudCwgc2NvcGUpIHtcclxuICAgICAgICBpbkVudHJ5LmRlc2VsZWN0KGVsZW1lbnQsIG5vZGUucGFyZW50Tm9kZSk7XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKEFDVElWSVRJX09VVF9FWFRFTlNJT05fRUxFTUVOVClcclxuICAgIH0pO1xyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKG91dEVudHJ5KTtcclxuICB9XHJcblxyXG4gIC8vIGxhYmVsIGZvciBzZWxlY3RlZCBtYXBwaW5nIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5sYWJlbCh7XHJcbiAgICBpZDogJ3ZhcmlhYmxlTWFwcGluZy10eXBlTGFiZWwnLFxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICB2YXIgdmFsdWUgPSAnJztcclxuICAgICAgaWYgKGlzKG1hcHBpbmcsIEFDVElWSVRJX0lOX0VYVEVOU0lPTl9FTEVNRU5UKSkge1xyXG4gICAgICAgIHZhbHVlID0gdHJhbnNsYXRlKCdJbiBNYXBwaW5nJyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAoaXMobWFwcGluZywgQUNUSVZJVElfT1VUX0VYVEVOU0lPTl9FTEVNRU5UKSkge1xyXG4gICAgICAgIHZhbHVlID0gdHJhbnNsYXRlKCdPdXQgTWFwcGluZycpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxhYmVsOiB2YWx1ZVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzaG93TGFiZWw6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6ICd2YXJpYWJsZU1hcHBpbmctaW5PdXRUeXBlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1R5cGUnKSxcclxuICAgIHNlbGVjdE9wdGlvbnM6IGluT3V0VHlwZU9wdGlvbnMsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnaW5PdXRUeXBlJyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgbWFwcGluZyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpIHx8IHt9O1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGluT3V0VHlwZTogZ2V0SW5PdXRUeXBlKG1hcHBpbmcpXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGluT3V0VHlwZSA9IHZhbHVlcy5pbk91dFR5cGU7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgJ3NvdXJjZScgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgJ3NvdXJjZUV4cHJlc3Npb24nIDogdW5kZWZpbmVkLFxyXG4gICAgICAgICd2YXJpYWJsZXMnIDogdW5kZWZpbmVkXHJcbiAgICAgIH07XHJcblxyXG4gICAgICBpZiAoaW5PdXRUeXBlID09PSAnc291cmNlJykge1xyXG4gICAgICAgIHByb3BzLnNvdXJjZSA9ICcnO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKGluT3V0VHlwZSA9PT0gJ3NvdXJjZUV4cHJlc3Npb24nKSB7XHJcbiAgICAgICAgcHJvcHMuc291cmNlRXhwcmVzc2lvbiA9ICcnO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKGluT3V0VHlwZSA9PT0gJ3ZhcmlhYmxlcycpIHtcclxuICAgICAgICBwcm9wcy52YXJpYWJsZXMgPSAnYWxsJztcclxuICAgICAgICBwcm9wcy50YXJnZXQgPSB1bmRlZmluZWQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgbWFwcGluZywgcHJvcHMpO1xyXG4gICAgfSxcclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAndmFyaWFibGVNYXBwaW5nLXNvdXJjZScsXHJcbiAgICBkYXRhVmFsdWVMYWJlbDogJ3NvdXJjZUxhYmVsJyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdzb3VyY2UnLFxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSkgfHwge307XHJcblxyXG4gICAgICB2YXIgbGFiZWwgPSAnJztcclxuICAgICAgdmFyIGluT3V0VHlwZSA9IGdldEluT3V0VHlwZShtYXBwaW5nKTtcclxuICAgICAgaWYgKGluT3V0VHlwZSA9PT0gJ3NvdXJjZScpIHtcclxuICAgICAgICBsYWJlbCA9IHRyYW5zbGF0ZSgnU291cmNlJyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAoaW5PdXRUeXBlID09PSAnc291cmNlRXhwcmVzc2lvbicpIHtcclxuICAgICAgICBsYWJlbCA9IHRyYW5zbGF0ZSgnU291cmNlIEV4cHJlc3Npb24nKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBzb3VyY2U6IG1hcHBpbmdbaW5PdXRUeXBlXSxcclxuICAgICAgICBzb3VyY2VMYWJlbDogbGFiZWxcclxuICAgICAgfTtcclxuICAgIH0sXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YWx1ZXMuc291cmNlID0gdmFsdWVzLnNvdXJjZSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICB2YXIgbWFwcGluZyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB2YXIgaW5PdXRUeXBlID0gZ2V0SW5PdXRUeXBlKG1hcHBpbmcpO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW2luT3V0VHlwZV0gPSB2YWx1ZXMuc291cmNlIHx8ICcnO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBtYXBwaW5nLCBwcm9wcyk7XHJcbiAgICB9LFxyXG4gICAgLy8gb25lIG9mIGJvdGggKHNvdXJjZSBvciBzb3VyY2VFeHByZXNzaW9uKSBtdXN0IGhhdmUgYSB2YWx1ZSB0byBtYWtlXHJcbiAgICAvLyB0aGUgY29uZmlndXJhdGlvbiBlYXNpZXIgYW5kIG1vcmUgdW5kZXJzdGFuZGFibGVcclxuICAgIC8vIGl0IGlzIG5vdCBlbmdpbmUgY29uZm9ybVxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgbWFwcGluZyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIHZhbGlkYXRpb24gPSB7fTtcclxuICAgICAgaWYgKG1hcHBpbmcpIHtcclxuICAgICAgICBpZiAoIXZhbHVlcy5zb3VyY2UpIHtcclxuICAgICAgICAgIHZhbGlkYXRpb24uc291cmNlID1cclxuICAgICAgICAgIHZhbGlkYXRpb24uc291cmNlID0gdmFsdWVzLnNvdXJjZUxhYmVsID9cclxuICAgICAgICAgICAgdHJhbnNsYXRlKCdNYXBwaW5nIG11c3QgaGF2ZSBhIHt2YWx1ZX0nLCB7IHZhbHVlOiB2YWx1ZXMuc291cmNlTGFiZWwudG9Mb3dlckNhc2UoKSB9KSA6XHJcbiAgICAgICAgICAgIHRyYW5zbGF0ZSgnTWFwcGluZyBtdXN0IGhhdmUgYSB2YWx1ZScpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGluT3V0VHlwZSA9IGdldEluT3V0VHlwZShtYXBwaW5nKTtcclxuXHJcbiAgICAgICAgaWYgKFdISVRFU1BBQ0VfUkVHRVgudGVzdCh2YWx1ZXMuc291cmNlKSAmJiBpbk91dFR5cGUgIT09ICdzb3VyY2VFeHByZXNzaW9uJykge1xyXG4gICAgICAgICAgdmFsaWRhdGlvbi5zb3VyY2UgPSB0cmFuc2xhdGUoJ3tsYWJlbH0gbXVzdCBub3QgY29udGFpbiB3aGl0ZXNwYWNlJywgeyBsYWJlbDogdmFsdWVzLnNvdXJjZUxhYmVsIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbGlkYXRpb247XHJcbiAgICB9LFxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZE1hcHBpbmcgPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuICFzZWxlY3RlZE1hcHBpbmcgfHwgKHNlbGVjdGVkTWFwcGluZyAmJiBzZWxlY3RlZE1hcHBpbmcudmFyaWFibGVzKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ3ZhcmlhYmxlTWFwcGluZy10YXJnZXQnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGFyZ2V0JyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAndGFyZ2V0JyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHRhcmdldDogKGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpIHx8IHt9KS50YXJnZXRcclxuICAgICAgfTtcclxuICAgIH0sXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YWx1ZXMudGFyZ2V0ID0gdmFsdWVzLnRhcmdldCB8fCB1bmRlZmluZWQ7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgbWFwcGluZywgdmFsdWVzKTtcclxuICAgIH0sXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBtYXBwaW5nID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICB2YXIgdmFsaWRhdGlvbiA9IHt9O1xyXG4gICAgICBpZiAobWFwcGluZykge1xyXG4gICAgICAgIHZhciBtYXBwaW5nVHlwZSA9IGdldEluT3V0VHlwZShtYXBwaW5nKTtcclxuXHJcbiAgICAgICAgaWYgKCF2YWx1ZXMudGFyZ2V0ICYmIG1hcHBpbmdUeXBlICE9PSAndmFyaWFibGVzJykge1xyXG4gICAgICAgICAgdmFsaWRhdGlvbi50YXJnZXQgPSB0cmFuc2xhdGUoJ01hcHBpbmcgbXVzdCBoYXZlIGEgdGFyZ2V0Jyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodmFsdWVzLnRhcmdldFxyXG4gICAgICAgICAgJiYgV0hJVEVTUEFDRV9SRUdFWC50ZXN0KHZhbHVlcy50YXJnZXQpXHJcbiAgICAgICAgICAmJiBtYXBwaW5nVHlwZSAhPT0gJ3ZhcmlhYmxlcycpIHtcclxuICAgICAgICAgIHZhbGlkYXRpb24udGFyZ2V0ID0gdHJhbnNsYXRlKCdUYXJnZXQgbXVzdCBub3QgY29udGFpbiB3aGl0ZXNwYWNlJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdmFsaWRhdGlvbjtcclxuICAgIH0sXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIHNlbGVjdGVkTWFwcGluZyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gIXNlbGVjdGVkTWFwcGluZyB8fCAoc2VsZWN0ZWRNYXBwaW5nICYmIHNlbGVjdGVkTWFwcGluZy52YXJpYWJsZXMpO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkuY2hlY2tib3goe1xyXG4gICAgaWQ6ICd2YXJpYWJsZU1hcHBpbmctbG9jYWwnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnTG9jYWwnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdsb2NhbCcsXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBsb2NhbDogKGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpIHx8IHt9KS5sb2NhbFxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhbHVlcy5sb2NhbCA9IHZhbHVlcy5sb2NhbCB8fCBmYWxzZTtcclxuICAgICAgdmFyIG1hcHBpbmcgPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBtYXBwaW5nLCB2YWx1ZXMpO1xyXG4gICAgfSxcclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSAmJiBiby5nZXQoJ3Byb2Nlc3NSZWYnKSkge1xyXG4gICAgdmFyIHZlcnNpb25UYWdFbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgICBpZDogJ3ZlcnNpb25UYWcnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdWZXJzaW9uIFRhZycpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5OiAndmVyc2lvblRhZydcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIGluIHBhcnRpY2lwYW50cyB3ZSBoYXZlIHRvIGNoYW5nZSB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiBzZXQgYW5kIGdldFxyXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuICAgICAgdmVyc2lvblRhZ0VudHJ5LmdldCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgcHJvY2Vzc0JvID0gYm8uZ2V0KCdwcm9jZXNzUmVmJyk7XHJcblxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICB2ZXJzaW9uVGFnOiBwcm9jZXNzQm8uZ2V0KCdhY3Rpdml0aTp2ZXJzaW9uVGFnJylcclxuICAgICAgICB9O1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmVyc2lvblRhZ0VudHJ5LnNldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICAgIHZhciBwcm9jZXNzQm8gPSBiby5nZXQoJ3Byb2Nlc3NSZWYnKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBwcm9jZXNzQm8sIHtcclxuICAgICAgICAgICdhY3Rpdml0aTp2ZXJzaW9uVGFnJzogdmFsdWVzLnZlcnNpb25UYWcgfHwgdW5kZWZpbmVkXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKHZlcnNpb25UYWdFbnRyeSk7XHJcblxyXG4gIH1cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGFzc2lnbiA9IHJlcXVpcmUoJ2xvZGFzaC9hc3NpZ24nKTtcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGFzeW5jQ2FwYWJsZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9Bc3luY0NhcGFibGVIZWxwZXInKSxcclxuICAgIGV2ZW50RGVmaW5pdGlvbkhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FdmVudERlZmluaXRpb25IZWxwZXInKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbmZ1bmN0aW9uIGlzQXN5bmNCZWZvcmUoYm8pIHtcclxuICByZXR1cm4gYXN5bmNDYXBhYmxlSGVscGVyLmlzQXN5bmNCZWZvcmUoYm8pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBpc0FzeW5jQWZ0ZXIoYm8pIHtcclxuICByZXR1cm4gYXN5bmNDYXBhYmxlSGVscGVyLmlzQXN5bmNBZnRlcihibyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzRXhjbHVzaXZlKGJvKSB7XHJcbiAgcmV0dXJuIGFzeW5jQ2FwYWJsZUhlbHBlci5pc0V4Y2x1c2l2ZShibyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGJvLCBlbGVtZW50KSB7XHJcbiAgcmV0dXJuIGFzeW5jQ2FwYWJsZUhlbHBlci5yZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibywgZWxlbWVudCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNhblJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gIWV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRUaW1lckV2ZW50RGVmaW5pdGlvbihlbGVtZW50KTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBnZXRCdXNpbmVzc09iamVjdCA9IG9wdGlvbnMuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG4gIHZhciBpZFByZWZpeCA9IG9wdGlvbnMuaWRQcmVmaXggfHwgJycsXHJcbiAgICAgIGxhYmVsUHJlZml4ID0gb3B0aW9ucy5sYWJlbFByZWZpeCB8fCAnJztcclxuXHJcblxyXG4gIHZhciBhc3luY0JlZm9yZUVudHJ5ID0gZW50cnlGYWN0b3J5LmNoZWNrYm94KHtcclxuICAgIGlkOiBpZFByZWZpeCArICdhc3luY0JlZm9yZScsXHJcbiAgICBsYWJlbDogbGFiZWxQcmVmaXggKyB0cmFuc2xhdGUoJ0FzeW5jaHJvbm91cyBCZWZvcmUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdhc3luY0JlZm9yZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGFzeW5jQmVmb3JlOiBpc0FzeW5jQmVmb3JlKGJvKVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIGFzeW5jQmVmb3JlID0gISF2YWx1ZXMuYXN5bmNCZWZvcmU7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOmFzeW5jQmVmb3JlJzogYXN5bmNCZWZvcmUsXHJcbiAgICAgICAgJ2FjdGl2aXRpOmFzeW5jJzogZmFsc2VcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdO1xyXG4gICAgICBpZiAoIWlzQXN5bmNBZnRlcihibykgJiYgIWFzeW5jQmVmb3JlKSB7XHJcbiAgICAgICAgcHJvcHMgPSBhc3NpZ24oeyAnYWN0aXZpdGk6ZXhjbHVzaXZlJyA6IHRydWUgfSwgcHJvcHMpO1xyXG4gICAgICAgIGlmIChjYW5SZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShlbGVtZW50KSkge1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChyZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibywgZWxlbWVudCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHByb3BzKSk7XHJcbiAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgIH1cclxuICB9KTtcclxuXHJcblxyXG4gIHZhciBhc3luY0FmdGVyRW50cnkgPSBlbnRyeUZhY3RvcnkuY2hlY2tib3goe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ2FzeW5jQWZ0ZXInLFxyXG4gICAgbGFiZWw6IGxhYmVsUHJlZml4ICsgdHJhbnNsYXRlKCdBc3luY2hyb25vdXMgQWZ0ZXInKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdhc3luY0FmdGVyJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgYXN5bmNBZnRlcjogaXNBc3luY0FmdGVyKGJvKVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIGFzeW5jQWZ0ZXIgPSAhIXZhbHVlcy5hc3luY0FmdGVyO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge1xyXG4gICAgICAgICdhY3Rpdml0aTphc3luY0FmdGVyJzogYXN5bmNBZnRlclxyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcbiAgICAgIGlmICghaXNBc3luY0JlZm9yZShibykgJiYgIWFzeW5jQWZ0ZXIpIHtcclxuICAgICAgICBwcm9wcyA9IGFzc2lnbih7ICdhY3Rpdml0aTpleGNsdXNpdmUnIDogdHJ1ZSB9LCBwcm9wcyk7XHJcbiAgICAgICAgaWYgKGNhblJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGVsZW1lbnQpKSB7XHJcbiAgICAgICAgICBjb21tYW5kcy5wdXNoKHJlbW92ZUZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGJvLCBlbGVtZW50KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBibywgcHJvcHMpKTtcclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuXHJcbiAgdmFyIGV4Y2x1c2l2ZUVudHJ5ID0gZW50cnlGYWN0b3J5LmNoZWNrYm94KHtcclxuICAgIGlkOiBpZFByZWZpeCArICdleGNsdXNpdmUnLFxyXG4gICAgbGFiZWw6IGxhYmVsUHJlZml4ICsgdHJhbnNsYXRlKCdFeGNsdXNpdmUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdleGNsdXNpdmUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgcmV0dXJuIHsgZXhjbHVzaXZlOiBpc0V4Y2x1c2l2ZShibykgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgJ2FjdGl2aXRpOmV4Y2x1c2l2ZSc6ICEhdmFsdWVzLmV4Y2x1c2l2ZSB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gYm8gJiYgIWlzQXN5bmNBZnRlcihibykgJiYgIWlzQXN5bmNCZWZvcmUoYm8pO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gWyBhc3luY0JlZm9yZUVudHJ5LCBhc3luY0FmdGVyRW50cnksIGV4Y2x1c2l2ZUVudHJ5IF07XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyksXHJcbiAgICBleHRlbnNpb25FbGVtZW50c0hlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpO1xyXG5cclxuXHJcbnZhciByZXN1bHRWYXJpYWJsZSA9IHJlcXVpcmUoJy4vUmVzdWx0VmFyaWFibGUnKTtcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XHJcblxyXG52YXIgYXR0cmlidXRlSW5mbyA9IHtcclxuICBicG1uOiB7XHJcbiAgICBlbGVtZW50OiAnY2FsbGVkRWxlbWVudCcsXHJcbiAgICBiaW5kaW5nOiAnYWN0aXZpdGk6Y2FsbGVkRWxlbWVudEJpbmRpbmcnLFxyXG4gICAgdmVyc2lvbjogJ2FjdGl2aXRpOmNhbGxlZEVsZW1lbnRWZXJzaW9uJyxcclxuICAgIHZlcnNpb25UYWc6ICdhY3Rpdml0aTpjYWxsZWRFbGVtZW50VmVyc2lvblRhZycsXHJcbiAgICB0ZW5hbnRJZDogJ2FjdGl2aXRpOmNhbGxlZEVsZW1lbnRUZW5hbnRJZCdcclxuICB9LFxyXG5cclxuICBjbW1uOiB7XHJcbiAgICBlbGVtZW50OiAnYWN0aXZpdGk6Y2FzZVJlZicsXHJcbiAgICBiaW5kaW5nOiAnYWN0aXZpdGk6Y2FzZUJpbmRpbmcnLFxyXG4gICAgdmVyc2lvbjogJ2FjdGl2aXRpOmNhc2VWZXJzaW9uJyxcclxuICAgIHRlbmFudElkOiAnYWN0aXZpdGk6Y2FzZVRlbmFudElkJ1xyXG4gIH0sXHJcblxyXG4gIGRtbjoge1xyXG4gICAgZWxlbWVudDogJ2FjdGl2aXRpOmRlY2lzaW9uUmVmJyxcclxuICAgIGJpbmRpbmc6ICdhY3Rpdml0aTpkZWNpc2lvblJlZkJpbmRpbmcnLFxyXG4gICAgdmVyc2lvbjogJ2FjdGl2aXRpOmRlY2lzaW9uUmVmVmVyc2lvbicsXHJcbiAgICB2ZXJzaW9uVGFnOiAnYWN0aXZpdGk6ZGVjaXNpb25SZWZWZXJzaW9uVGFnJyxcclxuICAgIHRlbmFudElkOiAnYWN0aXZpdGk6ZGVjaXNpb25SZWZUZW5hbnRJZCdcclxuICB9XHJcbn07XHJcblxyXG52YXIgbWFwRGVjaXNpb25SZXN1bHRPcHRpb25zID0gW1xyXG4gIHtcclxuICAgIG5hbWU6ICdzaW5nbGVFbnRyeSAoVHlwZWRWYWx1ZSknLFxyXG4gICAgdmFsdWU6ICdzaW5nbGVFbnRyeSdcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6J3NpbmdsZVJlc3VsdCAoTWFwPFN0cmluZywgT2JqZWN0PiknLFxyXG4gICAgdmFsdWU6J3NpbmdsZVJlc3VsdCdcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6J2NvbGxlY3RFbnRyaWVzIChMaXN0PE9iamVjdD4pJyxcclxuICAgIHZhbHVlOidjb2xsZWN0RW50cmllcydcclxuICB9LFxyXG4gIHtcclxuICAgIG5hbWU6J3Jlc3VsdExpc3QgKExpc3Q8TWFwPFN0cmluZywgT2JqZWN0Pj4pJyxcclxuICAgIHZhbHVlOidyZXN1bHRMaXN0J1xyXG4gIH1cclxuXTtcclxuXHJcbnZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ09wdGlvbnMgPSBbXHJcbiAge1xyXG4gICAgbmFtZTogJ3ZhcmlhYmxlTWFwcGluZ0NsYXNzJyxcclxuICAgIHZhbHVlOiAndmFyaWFibGVNYXBwaW5nQ2xhc3MnXHJcbiAgfSxcclxuICB7XHJcbiAgICBuYW1lOiAndmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJyxcclxuICAgIHZhbHVlOiAndmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJ1xyXG4gIH1cclxuXTtcclxuXHJcbmZ1bmN0aW9uIGdldEFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkoZWxlbWVudCkge1xyXG4gIHZhciBhY3Rpdml0aUluID0gW10sXHJcbiAgICAgIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBhY3Rpdml0aUluUGFyYW1zID0gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sICdhY3Rpdml0aTpJbicpO1xyXG4gIGlmIChhY3Rpdml0aUluUGFyYW1zKSB7XHJcbiAgICBmb3JFYWNoKGFjdGl2aXRpSW5QYXJhbXMsIGZ1bmN0aW9uKHBhcmFtKSB7XHJcbiAgICAgIGlmIChwYXJhbS5idXNpbmVzc0tleSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgYWN0aXZpdGlJbi5wdXNoKHBhcmFtKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIHJldHVybiBhY3Rpdml0aUluO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRCdXNpbmVzc0tleShlbGVtZW50LCB0ZXh0LCBicG1uRmFjdG9yeSkge1xyXG4gIHZhciBjb21tYW5kcyA9IFtdO1xyXG5cclxuICB2YXIgYWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleSA9IGdldEFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkoZWxlbWVudCk7XHJcblxyXG4gIGlmIChhY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5Lmxlbmd0aCkge1xyXG4gICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleVswXSwge1xyXG4gICAgICBidXNpbmVzc0tleTogdGV4dFxyXG4gICAgfSkpO1xyXG4gIH0gZWxzZSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICBleHRlbnNpb25FbGVtZW50cyA9IGJvLmV4dGVuc2lvbkVsZW1lbnRzO1xyXG5cclxuICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnLCB7IHZhbHVlczogW10gfSwgYm8sIGJwbW5GYWN0b3J5KTtcclxuICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCB7IGV4dGVuc2lvbkVsZW1lbnRzOiBleHRlbnNpb25FbGVtZW50cyB9KSk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGFjdGl2aXRpSW4gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoXHJcbiAgICAgICdhY3Rpdml0aTpJbicsXHJcbiAgICAgIHsgJ2J1c2luZXNzS2V5JzogdGV4dCB9LFxyXG4gICAgICBleHRlbnNpb25FbGVtZW50cyxcclxuICAgICAgYnBtbkZhY3RvcnlcclxuICAgICk7XHJcblxyXG4gICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgZWxlbWVudCxcclxuICAgICAgZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICBbIGFjdGl2aXRpSW4gXSxbXVxyXG4gICAgKSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gY29tbWFuZHM7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRlbGV0ZUJ1c2luZXNzS2V5KGVsZW1lbnQpIHtcclxuICB2YXIgYWN0aXZpdGlJbkV4dGVuc2lvbnMgPSBnZXRBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5KGVsZW1lbnQpO1xyXG4gIHZhciBjb21tYW5kcyA9IFtdO1xyXG4gIGZvckVhY2goYWN0aXZpdGlJbkV4dGVuc2lvbnMsIGZ1bmN0aW9uKGVsZW0pIHtcclxuICAgIGNvbW1hbmRzLnB1c2goZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksIGVsZW1lbnQsIGVsZW0pKTtcclxuICB9KTtcclxuICByZXR1cm4gY29tbWFuZHM7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKHR5cGUpIHtcclxuICByZXR1cm4gWyAnYnBtbicsICdjbW1uJywgJ2RtbicgXS5pbmRleE9mKHR5cGUpICE9PSAtMTtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBiaW5kaW5nT3B0aW9ucyA9IFtcclxuICAgIHtcclxuICAgICAgbmFtZTogdHJhbnNsYXRlKCdsYXRlc3QnKSxcclxuICAgICAgdmFsdWU6ICdsYXRlc3QnXHJcbiAgICB9LFxyXG4gICAge1xyXG4gICAgICBuYW1lOiB0cmFuc2xhdGUoJ2RlcGxveW1lbnQnKSxcclxuICAgICAgdmFsdWU6ICdkZXBsb3ltZW50J1xyXG4gICAgfSxcclxuICAgIHtcclxuICAgICAgbmFtZTogdHJhbnNsYXRlKCd2ZXJzaW9uJyksXHJcbiAgICAgIHZhbHVlOiAndmVyc2lvbidcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6IHRyYW5zbGF0ZSgndmVyc2lvblRhZycpLFxyXG4gICAgICB2YWx1ZTogJ3ZlcnNpb25UYWcnXHJcbiAgICB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIGdldENhbGxhYmxlVHlwZSA9IG9wdGlvbnMuZ2V0Q2FsbGFibGVUeXBlO1xyXG5cclxuICB2YXIgZW50cmllcyA9IFtdO1xyXG5cclxuICBmdW5jdGlvbiBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgcHJvcCkge1xyXG4gICAgdmFyIHR5cGUgPSBnZXRDYWxsYWJsZVR5cGUoZWxlbWVudCk7XHJcbiAgICByZXR1cm4gKGF0dHJpYnV0ZUluZm9bdHlwZV0gfHwge30pW3Byb3BdO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0Q2FsbEFjdGl2aXR5QmluZGluZ1ZhbHVlKGVsZW1lbnQpIHtcclxuICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICB2YXIgYXR0ciA9IChhdHRyaWJ1dGVJbmZvW3R5cGVdIHx8IHt9KS5iaW5kaW5nO1xyXG4gICAgcmV0dXJuIGJvLmdldChhdHRyKTtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIGdldERlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZShlbGVtZW50KSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICB2YXIgYm9WYXJpYWJsZU1hcHBpbmdDbGFzcyA9IGJvLmdldCgnYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nQ2xhc3MnKSxcclxuICAgICAgICBib1ZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbiA9IGJvLmdldCgnYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJyk7XHJcblxyXG4gICAgdmFyIGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZSA9ICcnO1xyXG4gICAgaWYgKHR5cGVvZiBib1ZhcmlhYmxlTWFwcGluZ0NsYXNzICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUgPSAndmFyaWFibGVNYXBwaW5nQ2xhc3MnO1xyXG4gICAgfSBlbHNlXHJcblxyXG4gICAgaWYgKHR5cGVvZiBib1ZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlID0gJ3ZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbic7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZTtcclxuICB9XHJcblxyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ2NhbGxhYmxlLWVsZW1lbnQtcmVmJyxcclxuICAgIGRhdGFWYWx1ZUxhYmVsOiAnY2FsbGFibGVFbGVtZW50TGFiZWwnLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2NhbGxhYmxlRWxlbWVudFJlZicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBjYWxsYWJsZUVsZW1lbnRSZWY7XHJcblxyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAnZWxlbWVudCcpO1xyXG4gICAgICBpZiAoYXR0cikge1xyXG4gICAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICAgIGNhbGxhYmxlRWxlbWVudFJlZiA9IGJvLmdldChhdHRyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGxhYmVsID0gJyc7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgICBpZiAodHlwZSA9PT0gJ2JwbW4nKSB7XHJcbiAgICAgICAgbGFiZWwgPSB0cmFuc2xhdGUoJ0NhbGxlZCBFbGVtZW50Jyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ2NtbW4nKSB7XHJcbiAgICAgICAgbGFiZWwgPSB0cmFuc2xhdGUoJ0Nhc2UgUmVmJyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAodHlwZSA9PT0gJ2RtbicpIHtcclxuICAgICAgICBsYWJlbCA9IHRyYW5zbGF0ZSgnRGVjaXNpb24gUmVmJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgY2FsbGFibGVFbGVtZW50UmVmOiBjYWxsYWJsZUVsZW1lbnRSZWYsXHJcbiAgICAgICAgY2FsbGFibGVFbGVtZW50TGFiZWw6IGxhYmVsXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBuZXdDYWxsYWJsZUVsZW1lbnRSZWYgPSB2YWx1ZXMuY2FsbGFibGVFbGVtZW50UmVmO1xyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAnZWxlbWVudCcpO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW2F0dHJdID0gbmV3Q2FsbGFibGVFbGVtZW50UmVmIHx8ICcnO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgZWxlbWVudFJlZiA9IHZhbHVlcy5jYWxsYWJsZUVsZW1lbnRSZWY7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gaXNTdXBwb3J0ZWRDYWxsYWJsZVR5cGUodHlwZSkgJiYgIWVsZW1lbnRSZWYgPyB7IGNhbGxhYmxlRWxlbWVudFJlZjogdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpIH0gOiB7fTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhaXNTdXBwb3J0ZWRDYWxsYWJsZVR5cGUoZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpKTtcclxuICAgIH1cclxuXHJcbiAgfSkpO1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnNlbGVjdEJveCh7XHJcbiAgICBpZDogJ2NhbGxhYmxlLWJpbmRpbmcnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQmluZGluZycpLFxyXG4gICAgc2VsZWN0T3B0aW9uczogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICB2YXIgdHlwZSA9IGdldENhbGxhYmxlVHlwZShlbGVtZW50KTtcclxuICAgICAgdmFyIG9wdGlvbnM7XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ2NtbW4nKSB7XHJcbiAgICAgICAgb3B0aW9ucyA9IGJpbmRpbmdPcHRpb25zLmZpbHRlcihmdW5jdGlvbihiaW5kaW5nT3B0aW9uKSB7XHJcbiAgICAgICAgICByZXR1cm4gYmluZGluZ09wdGlvbi52YWx1ZSAhPT0gJ3ZlcnNpb25UYWcnO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIG9wdGlvbnMgPSBiaW5kaW5nT3B0aW9ucztcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gb3B0aW9ucztcclxuICAgIH0sXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY2FsbGFibGVCaW5kaW5nJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGNhbGxhYmxlQmluZGluZztcclxuXHJcbiAgICAgIHZhciBhdHRyID0gZ2V0QXR0cmlidXRlKGVsZW1lbnQsICdiaW5kaW5nJyk7XHJcbiAgICAgIGlmIChhdHRyKSB7XHJcbiAgICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgICAgY2FsbGFibGVCaW5kaW5nID0gYm8uZ2V0KGF0dHIpIHx8ICdsYXRlc3QnO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGNhbGxhYmxlQmluZGluZzogY2FsbGFibGVCaW5kaW5nXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBiaW5kaW5nID0gdmFsdWVzLmNhbGxhYmxlQmluZGluZztcclxuICAgICAgdmFyIGF0dHIgPSBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgJ2JpbmRpbmcnKSxcclxuICAgICAgICAgIGF0dHJWZXIgPSBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgJ3ZlcnNpb24nKSxcclxuICAgICAgICAgIGF0dHJWZXJUYWcgPSBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgJ3ZlcnNpb25UYWcnKTtcclxuXHJcbiAgICAgIHZhciBwcm9wcyA9IHt9O1xyXG4gICAgICBwcm9wc1thdHRyXSA9IGJpbmRpbmc7XHJcblxyXG4gICAgICAvLyBzZXQgdmVyc2lvbiBhbmQgdmVyc2lvblRhZyB2YWx1ZXMgYWx3YXlzIHRvIHVuZGVmaW5lZCB0byBkZWxldGUgdGhlIGV4aXN0aW5nIHZhbHVlXHJcbiAgICAgIHByb3BzW2F0dHJWZXJdID0gdW5kZWZpbmVkO1xyXG4gICAgICBwcm9wc1thdHRyVmVyVGFnXSA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBwcm9wcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKGdldENhbGxhYmxlVHlwZShlbGVtZW50KSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdjYWxsYWJsZS12ZXJzaW9uJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1ZlcnNpb24nKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdjYWxsYWJsZVZlcnNpb24nLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgY2FsbGFibGVWZXJzaW9uO1xyXG5cclxuICAgICAgdmFyIGF0dHIgPSBnZXRBdHRyaWJ1dGUoZWxlbWVudCwgJ3ZlcnNpb24nKTtcclxuICAgICAgaWYgKGF0dHIpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgICBjYWxsYWJsZVZlcnNpb24gPSBiby5nZXQoYXR0cik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgY2FsbGFibGVWZXJzaW9uOiBjYWxsYWJsZVZlcnNpb25cclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIHZlcnNpb24gPSB2YWx1ZXMuY2FsbGFibGVWZXJzaW9uO1xyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndmVyc2lvbicpO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW2F0dHJdID0gdmVyc2lvbiB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcHJvcHMpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciB2ZXJzaW9uID0gdmFsdWVzLmNhbGxhYmxlVmVyc2lvbjtcclxuXHJcbiAgICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIGlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKHR5cGUpICYmXHJcbiAgICAgICAgZ2V0Q2FsbEFjdGl2aXR5QmluZGluZ1ZhbHVlKGVsZW1lbnQpID09PSAndmVyc2lvbicgJiYgKFxyXG4gICAgICAgICAgIXZlcnNpb24gPyB7IGNhbGxhYmxlVmVyc2lvbjogdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpIH0gOiB7fVxyXG4gICAgICAgIClcclxuICAgICAgKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gIWlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKHR5cGUpIHx8IGdldENhbGxBY3Rpdml0eUJpbmRpbmdWYWx1ZShlbGVtZW50KSAhPT0gJ3ZlcnNpb24nO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnY2FsbGFibGUtdmVyc2lvbi10YWcnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVmVyc2lvbiBUYWcnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICd2ZXJzaW9uVGFnJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIHZlcnNpb25UYWc7XHJcblxyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndmVyc2lvblRhZycpO1xyXG5cclxuICAgICAgaWYgKGF0dHIpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgICAgdmVyc2lvblRhZyA9IGJvLmdldChhdHRyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB2ZXJzaW9uVGFnOiB2ZXJzaW9uVGFnXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciB2ZXJzaW9uVGFnID0gdmFsdWVzLnZlcnNpb25UYWc7XHJcblxyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndmVyc2lvblRhZycpO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcblxyXG4gICAgICBwcm9wc1thdHRyXSA9IHZlcnNpb25UYWcgfHwgdW5kZWZpbmVkO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgdmVyc2lvblRhZyA9IHZhbHVlcy52ZXJzaW9uVGFnO1xyXG5cclxuICAgICAgdmFyIHR5cGUgPSBnZXRDYWxsYWJsZVR5cGUoZWxlbWVudCk7XHJcblxyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIGlzU3VwcG9ydGVkQ2FsbGFibGVUeXBlKHR5cGUpICYmXHJcbiAgICAgICAgZ2V0Q2FsbEFjdGl2aXR5QmluZGluZ1ZhbHVlKGVsZW1lbnQpID09PSAndmVyc2lvblRhZycgJiYgKFxyXG4gICAgICAgICAgIXZlcnNpb25UYWcgPyB7IHZlcnNpb25UYWc6IHRyYW5zbGF0ZSgnTXVzdCBwcm92aWRlIGEgdmFsdWUnKSB9IDoge31cclxuICAgICAgICApXHJcbiAgICAgICk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgdHlwZSA9IGdldENhbGxhYmxlVHlwZShlbGVtZW50KTtcclxuXHJcbiAgICAgIHJldHVybiAhaXNTdXBwb3J0ZWRDYWxsYWJsZVR5cGUodHlwZSkgfHwgZ2V0Q2FsbEFjdGl2aXR5QmluZGluZ1ZhbHVlKGVsZW1lbnQpICE9PSAndmVyc2lvblRhZyc7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICd0ZW5hbnQtaWQnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGVuYW50IElkJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAndGVuYW50SWQnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgdGVuYW50SWQ7XHJcblxyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndGVuYW50SWQnKTtcclxuICAgICAgaWYgKGF0dHIpIHtcclxuICAgICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgICB0ZW5hbnRJZCA9IGJvLmdldChhdHRyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB0ZW5hbnRJZDogdGVuYW50SWRcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIHRlbmFudElkID0gdmFsdWVzLnRlbmFudElkO1xyXG4gICAgICB2YXIgYXR0ciA9IGdldEF0dHJpYnV0ZShlbGVtZW50LCAndGVuYW50SWQnKTtcclxuXHJcbiAgICAgIHZhciBwcm9wcyA9IHt9O1xyXG4gICAgICBwcm9wc1thdHRyXSA9IHRlbmFudElkIHx8IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBwcm9wcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgdHlwZSA9IGdldENhbGxhYmxlVHlwZShlbGVtZW50KTtcclxuICAgICAgcmV0dXJuICFpc1N1cHBvcnRlZENhbGxhYmxlVHlwZSh0eXBlKTtcclxuICAgIH1cclxuXHJcbiAgfSkpO1xyXG5cclxuICBpZiAoaXMoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksICdicG1uOkNhbGxBY3Rpdml0eScpKSB7XHJcbiAgICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmNoZWNrYm94KHtcclxuICAgICAgaWQ6ICdjYWxsYWJsZS1idXNpbmVzcy1rZXknLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdCdXNpbmVzcyBLZXknKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eTogJ2NhbGxhYmxlQnVzaW5lc3NLZXknLFxyXG5cclxuICAgICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgICAgdmFyIGFjdGl2aXRpSW4gPSBnZXRBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5KGVsZW1lbnQpO1xyXG5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgY2FsbGFibGVCdXNpbmVzc0tleTogISEoYWN0aXZpdGlJbiAmJiBhY3Rpdml0aUluLmxlbmd0aCA+IDApXHJcbiAgICAgICAgfTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlcy5jYWxsYWJsZUJ1c2luZXNzS2V5KSB7XHJcbiAgICAgICAgICByZXR1cm4gc2V0QnVzaW5lc3NLZXkoZWxlbWVudCwgJyN7ZXhlY3V0aW9uLnByb2Nlc3NCdXNpbmVzc0tleX0nLCBicG1uRmFjdG9yeSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHJldHVybiBkZWxldGVCdXNpbmVzc0tleShlbGVtZW50KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pKTtcclxuICB9XHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnYnVzaW5lc3Mta2V5LWV4cHJlc3Npb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQnVzaW5lc3MgS2V5IEV4cHJlc3Npb24nKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdidXNpbmVzc0tleScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBhY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5ID0gZ2V0QWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleShlbGVtZW50KTtcclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgYnVzaW5lc3NLZXk6IChcclxuICAgICAgICAgIGFjdGl2aXRpSW5XaXRoQnVzaW5lc3NLZXkubGVuZ3RoID9cclxuICAgICAgICAgICAgYWN0aXZpdGlJbldpdGhCdXNpbmVzc0tleVswXS5nZXQoJ2FjdGl2aXRpOmJ1c2luZXNzS2V5JykgOlxyXG4gICAgICAgICAgICB1bmRlZmluZWRcclxuICAgICAgICApXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBidXNpbmVzc0tleSA9IHZhbHVlcy5idXNpbmVzc0tleTtcclxuXHJcbiAgICAgIHJldHVybiBzZXRCdXNpbmVzc0tleShlbGVtZW50LCBidXNpbmVzc0tleSwgYnBtbkZhY3RvcnkpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBidXNpbmVzc0tleSA9IHZhbHVlcy5idXNpbmVzc0tleTtcclxuXHJcbiAgICAgIHJldHVybiBidXNpbmVzc0tleSA9PT0gJycgPyB7IGJ1c2luZXNzS2V5OiB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJykgfSA6IHt9O1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICFnZXRBY3Rpdml0aUluV2l0aEJ1c2luZXNzS2V5KGVsZW1lbnQpLmxlbmd0aDtcclxuICAgIH1cclxuXHJcbiAgfSkpO1xyXG5cclxuICBlbnRyaWVzID0gZW50cmllcy5jb25jYXQocmVzdWx0VmFyaWFibGUoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkOiAnZG1uLXJlc3VsdFZhcmlhYmxlJyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0OiBnZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGdldEltcGxlbWVudGF0aW9uVHlwZTogZ2V0Q2FsbGFibGVUeXBlLFxyXG4gICAgaGlkZVJlc3VsdFZhcmlhYmxlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBnZXRDYWxsYWJsZVR5cGUoZWxlbWVudCkgIT09ICdkbW4nO1xyXG4gICAgfVxyXG4gIH0sIHRyYW5zbGF0ZSkpO1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnNlbGVjdEJveCh7XHJcbiAgICBpZDogJ2Rtbi1tYXAtZGVjaXNpb24tcmVzdWx0JyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ01hcCBEZWNpc2lvbiBSZXN1bHQnKSxcclxuICAgIHNlbGVjdE9wdGlvbnM6IG1hcERlY2lzaW9uUmVzdWx0T3B0aW9ucyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdtYXBEZWNpc2lvblJlc3VsdCcsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIG1hcERlY2lzaW9uUmVzdWx0OiBiby5nZXQoJ2FjdGl2aXRpOm1hcERlY2lzaW9uUmVzdWx0JykgfHwgJ3Jlc3VsdExpc3QnXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOm1hcERlY2lzaW9uUmVzdWx0JzogdmFsdWVzLm1hcERlY2lzaW9uUmVzdWx0IHx8ICdyZXN1bHRMaXN0J1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICB2YXIgcmVzdWx0VmFyaWFibGUgPSBiby5nZXQoJ2FjdGl2aXRpOnJlc3VsdFZhcmlhYmxlJyk7XHJcbiAgICAgIHJldHVybiAhKGdldENhbGxhYmxlVHlwZShlbGVtZW50KSA9PT0gJ2RtbicgJiYgdHlwZW9mIHJlc3VsdFZhcmlhYmxlICE9PSAndW5kZWZpbmVkJyk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3Rvcnkuc2VsZWN0Qm94KHtcclxuICAgIGlkOiAnZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0RlbGVnYXRlIFZhcmlhYmxlIE1hcHBpbmcnKSxcclxuICAgIHNlbGVjdE9wdGlvbnM6IGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nT3B0aW9ucyxcclxuICAgIGVtcHR5UGFyYW1ldGVyOiB0cnVlLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2RlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlIDogZ2V0RGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlKGVsZW1lbnQpXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUgPSB2YWx1ZXMuZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlO1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge1xyXG4gICAgICAgICdhY3Rpdml0aTp2YXJpYWJsZU1hcHBpbmdDbGFzcycgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgJ2FjdGl2aXRpOnZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbicgOiB1bmRlZmluZWRcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlmIChkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUgPT09ICd2YXJpYWJsZU1hcHBpbmdDbGFzcycpIHtcclxuICAgICAgICBwcm9wc1snYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nQ2xhc3MnXSA9ICcnO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nVHlwZSA9PT0gJ3ZhcmlhYmxlTWFwcGluZ0RlbGVnYXRlRXhwcmVzc2lvbicpIHtcclxuICAgICAgICBwcm9wc1snYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJ10gPSAnJztcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVQcm9wZXJ0aWVzKGVsZW1lbnQsIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAoZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpICE9PSAnYnBtbicpO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmcnLFxyXG4gICAgZGF0YVZhbHVlTGFiZWw6ICdkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ0xhYmVsJyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZycsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgdmFyIGxhYmVsID0gJyc7XHJcbiAgICAgIHZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyA9IHVuZGVmaW5lZDtcclxuICAgICAgdmFyIHR5cGUgPSBnZXREZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUoZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAodHlwZSA9PT0gJ3ZhcmlhYmxlTWFwcGluZ0NsYXNzJykge1xyXG4gICAgICAgIGxhYmVsID0gdHJhbnNsYXRlKCdDbGFzcycpO1xyXG4gICAgICAgIGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nID0gYm8uZ2V0KCdhY3Rpdml0aTp2YXJpYWJsZU1hcHBpbmdDbGFzcycpO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKHR5cGUgPT09ICd2YXJpYWJsZU1hcHBpbmdEZWxlZ2F0ZUV4cHJlc3Npb24nKSB7XHJcbiAgICAgICAgbGFiZWwgPSB0cmFuc2xhdGUoJ0RlbGVnYXRlIEV4cHJlc3Npb24nKTtcclxuICAgICAgICBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyA9IGJvLmdldCgnYWN0aXZpdGk6dmFyaWFibGVNYXBwaW5nRGVsZWdhdGVFeHByZXNzaW9uJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmc6IGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nLFxyXG4gICAgICAgIGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nTGFiZWw6IGxhYmVsXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyA9IHZhbHVlcy5kZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZztcclxuXHJcbiAgICAgIHZhciBhdHRyID0gJ2FjdGl2aXRpOicgKyBnZXREZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZ1R5cGUoZWxlbWVudCk7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSB7fTtcclxuICAgICAgcHJvcHNbYXR0cl0gPSBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZVByb3BlcnRpZXMoZWxlbWVudCwgcHJvcHMpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBkZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZyA9IHZhbHVlcy5kZWxlZ2F0ZVZhcmlhYmxlTWFwcGluZztcclxuICAgICAgcmV0dXJuIChcclxuICAgICAgICBnZXRDYWxsYWJsZVR5cGUoZWxlbWVudCkgPT09ICdicG1uJyAmJiAoXHJcbiAgICAgICAgICAhZGVsZWdhdGVWYXJpYWJsZU1hcHBpbmcgPyB7IGRlbGVnYXRlVmFyaWFibGVNYXBwaW5nOiB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJykgfSA6IHt9XHJcbiAgICAgICAgKVxyXG4gICAgICApO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICEoZ2V0Q2FsbGFibGVUeXBlKGVsZW1lbnQpID09PSAnYnBtbicgJiYgZ2V0RGVsZWdhdGVWYXJpYWJsZU1hcHBpbmdUeXBlKGVsZW1lbnQpICE9PSAnJyk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICB2YXIgY2FuZGlkYXRlU3RhcnRlckdyb3Vwc0VudHJ5ID0gZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ2NhbmRpZGF0ZVN0YXJ0ZXJHcm91cHMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ2FuZGlkYXRlIFN0YXJ0ZXIgR3JvdXBzJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY2FuZGlkYXRlU3RhcnRlckdyb3VwcycsXHJcbiAgICBkZXNjcmlwdGlvbjogdHJhbnNsYXRlKCdTcGVjaWZ5IG1vcmUgdGhhbiBvbmUgZ3JvdXAgYXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdC4nKSxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHZhciBjYW5kaWRhdGVTdGFydGVyR3JvdXBzID0gYm8uZ2V0KCdhY3Rpdml0aTpjYW5kaWRhdGVTdGFydGVyR3JvdXBzJyk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGNhbmRpZGF0ZVN0YXJ0ZXJHcm91cHM6IGNhbmRpZGF0ZVN0YXJ0ZXJHcm91cHMgPyBjYW5kaWRhdGVTdGFydGVyR3JvdXBzIDogJydcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHtcclxuICAgICAgICAnYWN0aXZpdGk6Y2FuZGlkYXRlU3RhcnRlckdyb3Vwcyc6IHZhbHVlcy5jYW5kaWRhdGVTdGFydGVyR3JvdXBzIHx8IHVuZGVmaW5lZFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHZhciBjYW5kaWRhdGVTdGFydGVyVXNlcnNFbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdjYW5kaWRhdGVTdGFydGVyVXNlcnMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ2FuZGlkYXRlIFN0YXJ0ZXIgVXNlcnMnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdjYW5kaWRhdGVTdGFydGVyVXNlcnMnLFxyXG4gICAgZGVzY3JpcHRpb246IHRyYW5zbGF0ZSgnU3BlY2lmeSBtb3JlIHRoYW4gb25lIHVzZXIgYXMgYSBjb21tYSBzZXBhcmF0ZWQgbGlzdC4nKSxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHZhciBjYW5kaWRhdGVTdGFydGVyVXNlcnMgPSBiby5nZXQoJ2FjdGl2aXRpOmNhbmRpZGF0ZVN0YXJ0ZXJVc2VycycpO1xyXG5cclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBjYW5kaWRhdGVTdGFydGVyVXNlcnM6IGNhbmRpZGF0ZVN0YXJ0ZXJVc2VycyA/IGNhbmRpZGF0ZVN0YXJ0ZXJVc2VycyA6ICcnXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGJvLCB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOmNhbmRpZGF0ZVN0YXJ0ZXJVc2Vycyc6IHZhbHVlcy5jYW5kaWRhdGVTdGFydGVyVXNlcnMgfHwgdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIGNhbmRpZGF0ZVN0YXJ0ZXJHcm91cHNFbnRyeSxcclxuICAgIGNhbmRpZGF0ZVN0YXJ0ZXJVc2Vyc0VudHJ5XHJcbiAgXTtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgREVMRUdBVEVfVFlQRVMgPSBbXHJcbiAgJ2NsYXNzJyxcclxuICAnZXhwcmVzc2lvbicsXHJcbiAgJ2RlbGVnYXRlRXhwcmVzc2lvbidcclxuXTtcclxuXHJcbnZhciBQUk9QRVJUSUVTID0ge1xyXG4gIGNsYXNzOiAnYWN0aXZpdGk6Y2xhc3MnLFxyXG4gIGV4cHJlc3Npb246ICdhY3Rpdml0aTpleHByZXNzaW9uJyxcclxuICBkZWxlZ2F0ZUV4cHJlc3Npb246ICdhY3Rpdml0aTpkZWxlZ2F0ZUV4cHJlc3Npb24nXHJcbn07XHJcblxyXG5mdW5jdGlvbiBpc0RlbGVnYXRlKHR5cGUpIHtcclxuICByZXR1cm4gREVMRUdBVEVfVFlQRVMuaW5kZXhPZih0eXBlKSAhPT0gLTE7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEF0dHJpYnV0ZSh0eXBlKSB7XHJcbiAgcmV0dXJuIFBST1BFUlRJRVNbdHlwZV07XHJcbn1cclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldEltcGxlbWVudGF0aW9uVHlwZSA9IG9wdGlvbnMuZ2V0SW1wbGVtZW50YXRpb25UeXBlLFxyXG4gICAgICBnZXRCdXNpbmVzc09iamVjdCA9IG9wdGlvbnMuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG4gIGZ1bmN0aW9uIGdldERlbGVnYXRpb25MYWJlbCh0eXBlKSB7XHJcbiAgICBzd2l0Y2ggKHR5cGUpIHtcclxuICAgIGNhc2UgJ2NsYXNzJzpcclxuICAgICAgcmV0dXJuIHRyYW5zbGF0ZSgnSmF2YSBDbGFzcycpO1xyXG4gICAgY2FzZSAnZXhwcmVzc2lvbic6XHJcbiAgICAgIHJldHVybiB0cmFuc2xhdGUoJ0V4cHJlc3Npb24nKTtcclxuICAgIGNhc2UgJ2RlbGVnYXRlRXhwcmVzc2lvbic6XHJcbiAgICAgIHJldHVybiB0cmFuc2xhdGUoJ0RlbGVnYXRlIEV4cHJlc3Npb24nKTtcclxuICAgIGRlZmF1bHQ6XHJcbiAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHZhciBkZWxlZ2F0ZUVudHJ5ID0gZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ2RlbGVnYXRlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1ZhbHVlJyksXHJcbiAgICBkYXRhVmFsdWVMYWJlbDogJ2RlbGVnYXRpb25MYWJlbCcsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZGVsZWdhdGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIHR5cGUgPSBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCk7XHJcbiAgICAgIHZhciBhdHRyID0gZ2V0QXR0cmlidXRlKHR5cGUpO1xyXG4gICAgICB2YXIgbGFiZWwgPSBnZXREZWxlZ2F0aW9uTGFiZWwodHlwZSk7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZGVsZWdhdGU6IGJvLmdldChhdHRyKSxcclxuICAgICAgICBkZWxlZ2F0aW9uTGFiZWw6IGxhYmVsXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICB2YXIgdHlwZSA9IGdldEltcGxlbWVudGF0aW9uVHlwZShlbGVtZW50KTtcclxuICAgICAgdmFyIGF0dHIgPSBnZXRBdHRyaWJ1dGUodHlwZSk7XHJcbiAgICAgIHZhciBwcm9wID0ge307XHJcbiAgICAgIHByb3BbYXR0cl0gPSB2YWx1ZXMuZGVsZWdhdGUgfHwgJyc7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHByb3ApO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHJldHVybiBpc0RlbGVnYXRlKGdldEltcGxlbWVudGF0aW9uVHlwZShlbGVtZW50KSkgJiYgIXZhbHVlcy5kZWxlZ2F0ZSA/IHsgZGVsZWdhdGU6IHRyYW5zbGF0ZSgnTXVzdCBwcm92aWRlIGEgdmFsdWUnKSB9IDoge307XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzRGVsZWdhdGUoZ2V0SW1wbGVtZW50YXRpb25UeXBlKGVsZW1lbnQpKTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBbIGRlbGVnYXRlRW50cnkgXTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgZWxlbWVudFJlZmVyZW5jZVByb3BlcnR5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vcHJvdmlkZXIvYnBtbi9wYXJ0cy9pbXBsZW1lbnRhdGlvbi9FbGVtZW50UmVmZXJlbmNlUHJvcGVydHknKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oXHJcbiAgICBncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIGVycm9yRXZlbnREZWZpbml0aW9uLFxyXG4gICAgc2hvd0Vycm9yQ29kZVZhcmlhYmxlLCBzaG93RXJyb3JNZXNzYWdlVmFyaWFibGUsIHRyYW5zbGF0ZVxyXG4pIHtcclxuXHJcblxyXG4gIHZhciBnZXRWYWx1ZSA9IGZ1bmN0aW9uKG1vZGVsUHJvcGVydHkpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHZhciBtb2RlbFByb3BlcnR5VmFsdWUgPSBlcnJvckV2ZW50RGVmaW5pdGlvbi5nZXQoJ2FjdGl2aXRpOicgKyBtb2RlbFByb3BlcnR5KTtcclxuICAgICAgdmFyIHZhbHVlID0ge307XHJcblxyXG4gICAgICB2YWx1ZVttb2RlbFByb3BlcnR5XSA9IG1vZGVsUHJvcGVydHlWYWx1ZTtcclxuICAgICAgcmV0dXJuIHZhbHVlO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgc2V0VmFsdWUgPSBmdW5jdGlvbihtb2RlbFByb3BlcnR5KSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBwcm9wcyA9IHt9O1xyXG5cclxuICAgICAgcHJvcHNbJ2FjdGl2aXRpOicgKyBtb2RlbFByb3BlcnR5XSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGVycm9yRXZlbnREZWZpbml0aW9uLCBwcm9wcyk7XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoXHJcbiAgICBlbGVtZW50UmVmZXJlbmNlUHJvcGVydHkoZWxlbWVudCwgZXJyb3JFdmVudERlZmluaXRpb24sIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGlkOiAnZXJyb3ItZWxlbWVudC1tZXNzYWdlJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXJyb3IgTWVzc2FnZScpLFxyXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eTogJ2Vycm9yUmVmJyxcclxuICAgICAgbW9kZWxQcm9wZXJ0eTogJ2Vycm9yTWVzc2FnZSdcclxuICAgIH0pXHJcbiAgKTtcclxuXHJcbiAgaWYgKHNob3dFcnJvckNvZGVWYXJpYWJsZSkge1xyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgICBpZDogJ2Vycm9yQ29kZVZhcmlhYmxlJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXJyb3IgQ29kZSBWYXJpYWJsZScpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5IDogJ2Vycm9yQ29kZVZhcmlhYmxlJyxcclxuXHJcbiAgICAgIGdldDogZ2V0VmFsdWUoJ2Vycm9yQ29kZVZhcmlhYmxlJyksXHJcbiAgICAgIHNldDogc2V0VmFsdWUoJ2Vycm9yQ29kZVZhcmlhYmxlJylcclxuICAgIH0pKTtcclxuICB9XHJcblxyXG4gIGlmIChzaG93RXJyb3JNZXNzYWdlVmFyaWFibGUpIHtcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQ6ICdlcnJvck1lc3NhZ2VWYXJpYWJsZScsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0Vycm9yIE1lc3NhZ2UgVmFyaWFibGUnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eTogJ2Vycm9yTWVzc2FnZVZhcmlhYmxlJyxcclxuXHJcbiAgICAgIGdldDogZ2V0VmFsdWUoJ2Vycm9yTWVzc2FnZVZhcmlhYmxlJyksXHJcbiAgICAgIHNldDogc2V0VmFsdWUoJ2Vycm9yTWVzc2FnZVZhcmlhYmxlJylcclxuICAgIH0pKTtcclxuICB9XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIGRvbVF1ZXJ5ID0gcmVxdWlyZSgnbWluLWRvbScpLnF1ZXJ5LFxyXG4gICAgZG9tQ2xvc2VzdCA9IHJlcXVpcmUoJ21pbi1kb20nKS5jbG9zZXN0LFxyXG4gICAgZG9taWZ5ID0gcmVxdWlyZSgnbWluLWRvbScpLmRvbWlmeSxcclxuICAgIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpO1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpLFxyXG4gICAgdXRpbHMgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9VdGlscycpLFxyXG4gICAgZXNjYXBlSFRNTCA9IHV0aWxzLmVzY2FwZUhUTUw7XHJcblxyXG5mdW5jdGlvbiBnZXRTZWxlY3RCb3gobm9kZSwgaWQpIHtcclxuICB2YXIgY3VycmVudFRhYiA9IGRvbUNsb3Nlc3Qobm9kZSwgJ2Rpdi5icHAtcHJvcGVydGllcy10YWInKTtcclxuICB2YXIgcXVlcnkgPSAnc2VsZWN0W25hbWU9c2VsZWN0ZWRFeHRlbnNpb25FbGVtZW50XScgKyAoaWQgPyAnW2lkPWNhbS1leHRlbnNpb25FbGVtZW50cy0nICsgaWQgKyAnXScgOiAnJyk7XHJcbiAgcmV0dXJuIGRvbVF1ZXJ5KHF1ZXJ5LCBjdXJyZW50VGFiKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0U2VsZWN0ZWQobm9kZSwgaWQpIHtcclxuICB2YXIgc2VsZWN0Qm94ID0gZ2V0U2VsZWN0Qm94KG5vZGUsIGlkKTtcclxuICByZXR1cm4ge1xyXG4gICAgdmFsdWU6IChzZWxlY3RCb3ggfHwge30pLnZhbHVlLFxyXG4gICAgaWR4OiAoc2VsZWN0Qm94IHx8IHt9KS5zZWxlY3RlZEluZGV4XHJcbiAgfTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVFbGVtZW50SWQocHJlZml4KSB7XHJcbiAgcHJlZml4ID0gcHJlZml4ICsgJ18nO1xyXG4gIHJldHVybiB1dGlscy5uZXh0SWQocHJlZml4KTtcclxufVxyXG5cclxudmFyIENSRUFURV9FWFRFTlNJT05fRUxFTUVOVF9BQ1RJT04gPSAnY3JlYXRlLWV4dGVuc2lvbi1lbGVtZW50JyxcclxuICAgIFJFTU9WRV9FWFRFTlNJT05fRUxFTUVOVF9BQ1RJT04gPSAncmVtb3ZlLWV4dGVuc2lvbi1lbGVtZW50JztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgaWQgPSBvcHRpb25zLmlkLFxyXG4gICAgICBwcmVmaXggPSBvcHRpb25zLnByZWZpeCB8fCAnZWxlbScsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCB8fCBpZCxcclxuICAgICAgaWRHZW5lcmF0aW9uID0gKG9wdGlvbnMuaWRHZW5lcmF0aW9uID09PSBmYWxzZSkgPyBvcHRpb25zLmlkR2VuZXJhdGlvbiA6IHRydWUsXHJcbiAgICAgIGJ1c2luZXNzT2JqZWN0ID0gb3B0aW9ucy5idXNpbmVzc09iamVjdCB8fCBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgdmFyIG1vZGVsUHJvcGVydHkgPSBvcHRpb25zLm1vZGVsUHJvcGVydHkgfHwgJ2lkJztcclxuXHJcbiAgdmFyIGdldEVsZW1lbnRzID0gb3B0aW9ucy5nZXRFeHRlbnNpb25FbGVtZW50cztcclxuXHJcbiAgdmFyIGNyZWF0ZUVsZW1lbnQgPSBvcHRpb25zLmNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQsXHJcbiAgICAgIGNhbkNyZWF0ZSA9IHR5cGVvZiBjcmVhdGVFbGVtZW50ID09PSAnZnVuY3Rpb24nO1xyXG5cclxuICB2YXIgcmVtb3ZlRWxlbWVudCA9IG9wdGlvbnMucmVtb3ZlRXh0ZW5zaW9uRWxlbWVudCxcclxuICAgICAgY2FuUmVtb3ZlID0gdHlwZW9mIHJlbW92ZUVsZW1lbnQgPT09ICdmdW5jdGlvbic7XHJcblxyXG4gIHZhciBvblNlbGVjdGlvbkNoYW5nZSA9IG9wdGlvbnMub25TZWxlY3Rpb25DaGFuZ2U7XHJcblxyXG4gIHZhciBoaWRlRWxlbWVudHMgPSBvcHRpb25zLmhpZGVFeHRlbnNpb25FbGVtZW50cyxcclxuICAgICAgY2FuQmVIaWRkZW4gPSB0eXBlb2YgaGlkZUVsZW1lbnRzID09PSAnZnVuY3Rpb24nO1xyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IG9wdGlvbnMuc2V0T3B0aW9uTGFiZWxWYWx1ZTtcclxuXHJcbiAgdmFyIGRlZmF1bHRTaXplID0gb3B0aW9ucy5zaXplIHx8IDUsXHJcbiAgICAgIHJlc2l6YWJsZSA9IG9wdGlvbnMucmVzaXphYmxlO1xyXG5cclxuICB2YXIgcmVmZXJlbmNlID0gb3B0aW9ucy5yZWZlcmVuY2UgfHwgdW5kZWZpbmVkO1xyXG5cclxuICB2YXIgc2VsZWN0aW9uQ2hhbmdlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50LCBzY29wZSkge1xyXG4gICAgaWYgKHR5cGVvZiBvblNlbGVjdGlvbkNoYW5nZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICByZXR1cm4gb25TZWxlY3Rpb25DaGFuZ2UoZWxlbWVudCwgbm9kZSwgZXZlbnQsIHNjb3BlKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICB2YXIgY3JlYXRlT3B0aW9uID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgIHJldHVybiAnPG9wdGlvbiB2YWx1ZT1cIicgKyBlc2NhcGVIVE1MKHZhbHVlKSArICdcIiBkYXRhLXZhbHVlIGRhdGEtbmFtZT1cImV4dGVuc2lvbkVsZW1lbnRWYWx1ZVwiPicgKyBlc2NhcGVIVE1MKHZhbHVlKSArICc8L29wdGlvbj4nO1xyXG4gIH07XHJcblxyXG4gIHZhciBpbml0U2VsZWN0aW9uU2l6ZSA9IGZ1bmN0aW9uKHNlbGVjdEJveCwgb3B0aW9uc0xlbmd0aCkge1xyXG4gICAgaWYgKHJlc2l6YWJsZSkge1xyXG4gICAgICBzZWxlY3RCb3guc2l6ZSA9IG9wdGlvbnNMZW5ndGggPiBkZWZhdWx0U2l6ZSA/IG9wdGlvbnNMZW5ndGggOiBkZWZhdWx0U2l6ZTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICByZXR1cm4ge1xyXG4gICAgaWQ6IGlkLFxyXG4gICAgaHRtbDogJzxkaXYgY2xhc3M9XCJicHAtcm93IGJwcC1lbGVtZW50LWxpc3RcIiAnICtcclxuICAgICAgICAgICAgKGNhbkJlSGlkZGVuID8gJ2RhdGEtc2hvdz1cImhpZGVFbGVtZW50c1wiJyA6ICcnKSArICc+JyArXHJcbiAgICAgICAgICAgICc8bGFiZWwgZm9yPVwiY2FtLWV4dGVuc2lvbkVsZW1lbnRzLScgKyBlc2NhcGVIVE1MKGlkKSArICdcIj4nICsgZXNjYXBlSFRNTChsYWJlbCkgKyAnPC9sYWJlbD4nICtcclxuICAgICAgICAgICAgJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlclwiPicgK1xyXG4gICAgICAgICAgICAgICc8c2VsZWN0IGlkPVwiY2FtLWV4dGVuc2lvbkVsZW1lbnRzLScgKyBlc2NhcGVIVE1MKGlkKSArICdcIicgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgJ25hbWU9XCJzZWxlY3RlZEV4dGVuc2lvbkVsZW1lbnRcIiAnICtcclxuICAgICAgICAgICAgICAgICAgICAgICdzaXplPVwiJyArIGVzY2FwZUhUTUwoZGVmYXVsdFNpemUpICsgJ1wiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgJ2RhdGEtbGlzdC1lbnRyeS1jb250YWluZXIgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAnZGF0YS1vbi1jaGFuZ2U9XCJzZWxlY3RFbGVtZW50XCI+JyArXHJcbiAgICAgICAgICAgICAgJzwvc2VsZWN0PicgK1xyXG4gICAgICAgICAgICAgIChjYW5DcmVhdGUgPyAnPGJ1dHRvbiBjbGFzcz1cImFkZFwiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdpZD1cImNhbS1leHRlbnNpb25FbGVtZW50cy1jcmVhdGUtJyArIGVzY2FwZUhUTUwoaWQpICsgJ1wiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkYXRhLWFjdGlvbj1cImNyZWF0ZUVsZW1lbnRcIj4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnPHNwYW4+Kzwvc3Bhbj4nICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgJzwvYnV0dG9uPicgOiAnJykgK1xyXG4gICAgICAgICAgICAgIChjYW5SZW1vdmUgPyAnPGJ1dHRvbiBjbGFzcz1cImNsZWFyXCIgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2lkPVwiY2FtLWV4dGVuc2lvbkVsZW1lbnRzLXJlbW92ZS0nICsgZXNjYXBlSFRNTChpZCkgKyAnXCIgJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2RhdGEtYWN0aW9uPVwicmVtb3ZlRWxlbWVudFwiICcgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdkYXRhLWRpc2FibGU9XCJkaXNhYmxlUmVtb3ZlXCI+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJzxzcGFuPi08L3NwYW4+JyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICc8L2J1dHRvbj4nIDogJycpICtcclxuICAgICAgICAgICAgJzwvZGl2PicgK1xyXG4gICAgICAgICAgJzwvZGl2PicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBlbGVtZW50cyA9IGdldEVsZW1lbnRzKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgICBmb3JFYWNoKGVsZW1lbnRzLCBmdW5jdGlvbihlbGVtKSB7XHJcbiAgICAgICAgcmVzdWx0LnB1c2goe1xyXG4gICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudFZhbHVlOiBlbGVtLmdldChtb2RlbFByb3BlcnR5KVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHZhciBzZWxlY3RCb3ggPSBnZXRTZWxlY3RCb3gobm9kZS5wYXJlbnROb2RlLCBpZCk7XHJcbiAgICAgIGluaXRTZWxlY3Rpb25TaXplKHNlbGVjdEJveCwgcmVzdWx0Lmxlbmd0aCk7XHJcblxyXG4gICAgICByZXR1cm4gcmVzdWx0O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYWN0aW9uID0gdGhpcy5fX2FjdGlvbjtcclxuICAgICAgZGVsZXRlIHRoaXMuX19hY3Rpb247XHJcblxyXG4gICAgICBidXNpbmVzc09iamVjdCA9IGJ1c2luZXNzT2JqZWN0IHx8IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgdmFyIGJvID1cclxuICAgICAgICAocmVmZXJlbmNlICYmIGJ1c2luZXNzT2JqZWN0LmdldChyZWZlcmVuY2UpKVxyXG4gICAgICAgICAgPyBidXNpbmVzc09iamVjdC5nZXQocmVmZXJlbmNlKVxyXG4gICAgICAgICAgOiBidXNpbmVzc09iamVjdDtcclxuXHJcbiAgICAgIHZhciBleHRlbnNpb25FbGVtZW50cyA9IGJvLmdldCgnZXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuXHJcbiAgICAgIGlmIChhY3Rpb24uaWQgPT09IENSRUFURV9FWFRFTlNJT05fRUxFTUVOVF9BQ1RJT04pIHtcclxuICAgICAgICB2YXIgY29tbWFuZHMgPSBbXTtcclxuICAgICAgICBpZiAoIWV4dGVuc2lvbkVsZW1lbnRzKSB7XHJcbiAgICAgICAgICBleHRlbnNpb25FbGVtZW50cyA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYnBtbjpFeHRlbnNpb25FbGVtZW50cycsIHsgdmFsdWVzOiBbXSB9LCBibywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgZXh0ZW5zaW9uRWxlbWVudHM6IGV4dGVuc2lvbkVsZW1lbnRzIH0pKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChjcmVhdGVFbGVtZW50KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCBhY3Rpb24udmFsdWUsIG5vZGUpKTtcclxuICAgICAgICByZXR1cm4gY29tbWFuZHM7XHJcblxyXG4gICAgICB9XHJcbiAgICAgIGVsc2UgaWYgKGFjdGlvbi5pZCA9PT0gUkVNT1ZFX0VYVEVOU0lPTl9FTEVNRU5UX0FDVElPTikge1xyXG4gICAgICAgIHJldHVybiByZW1vdmVFbGVtZW50KGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCBhY3Rpb24udmFsdWUsIGFjdGlvbi5pZHgsIG5vZGUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgfSxcclxuXHJcbiAgICBjcmVhdGVMaXN0RW50cnlUZW1wbGF0ZTogZnVuY3Rpb24odmFsdWUsIGluZGV4LCBzZWxlY3RCb3gpIHtcclxuICAgICAgaW5pdFNlbGVjdGlvblNpemUoc2VsZWN0Qm94LCBzZWxlY3RCb3gub3B0aW9ucy5sZW5ndGggKyAxKTtcclxuICAgICAgcmV0dXJuIGNyZWF0ZU9wdGlvbih2YWx1ZS5leHRlbnNpb25FbGVtZW50VmFsdWUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBkZXNlbGVjdDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgc2VsZWN0Qm94ID0gZ2V0U2VsZWN0Qm94KG5vZGUsIGlkKTtcclxuICAgICAgc2VsZWN0Qm94LnNlbGVjdGVkSW5kZXggPSAtMTtcclxuICAgIH0sXHJcblxyXG4gICAgZ2V0U2VsZWN0ZWQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGdldFNlbGVjdGVkKG5vZGUsIGlkKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0Q29udHJvbFZhbHVlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBvcHRpb24sIHByb3BlcnR5LCB2YWx1ZSwgaWR4KSB7XHJcbiAgICAgIG5vZGUudmFsdWUgPSB2YWx1ZTtcclxuXHJcbiAgICAgIGlmICghc2V0T3B0aW9uTGFiZWxWYWx1ZSkge1xyXG4gICAgICAgIG5vZGUudGV4dCA9IHZhbHVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNldE9wdGlvbkxhYmVsVmFsdWUoZWxlbWVudCwgbm9kZSwgb3B0aW9uLCBwcm9wZXJ0eSwgdmFsdWUsIGlkeCk7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgY3JlYXRlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICAvLyBjcmVhdGUgb3B0aW9uIHRlbXBsYXRlXHJcbiAgICAgIHZhciBnZW5lcmF0ZWRJZDtcclxuICAgICAgaWYgKGlkR2VuZXJhdGlvbikge1xyXG4gICAgICAgIGdlbmVyYXRlZElkID0gZ2VuZXJhdGVFbGVtZW50SWQocHJlZml4KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHNlbGVjdEJveCA9IGdldFNlbGVjdEJveChub2RlLCBpZCk7XHJcbiAgICAgIHZhciB0ZW1wbGF0ZSA9IGRvbWlmeShjcmVhdGVPcHRpb24oZ2VuZXJhdGVkSWQpKTtcclxuXHJcbiAgICAgIC8vIGFkZCBuZXcgZW1wdHkgb3B0aW9uIGFzIGxhc3QgY2hpbGQgZWxlbWVudFxyXG4gICAgICBzZWxlY3RCb3guYXBwZW5kQ2hpbGQodGVtcGxhdGUpO1xyXG5cclxuICAgICAgLy8gc2VsZWN0IGxhc3QgY2hpbGQgZWxlbWVudFxyXG4gICAgICBzZWxlY3RCb3gubGFzdENoaWxkLnNlbGVjdGVkID0gJ3NlbGVjdGVkJztcclxuICAgICAgc2VsZWN0aW9uQ2hhbmdlZChlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBzZWxlY3QgYm94IHNpemVcclxuICAgICAgaW5pdFNlbGVjdGlvblNpemUoc2VsZWN0Qm94LCBzZWxlY3RCb3gub3B0aW9ucy5sZW5ndGgpO1xyXG5cclxuICAgICAgdGhpcy5fX2FjdGlvbiA9IHtcclxuICAgICAgICBpZDogQ1JFQVRFX0VYVEVOU0lPTl9FTEVNRU5UX0FDVElPTixcclxuICAgICAgICB2YWx1ZTogZ2VuZXJhdGVkSWRcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICByZW1vdmVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3Rpb24gPSBnZXRTZWxlY3RlZChub2RlLCBpZCk7XHJcblxyXG4gICAgICB2YXIgc2VsZWN0Qm94ID0gZ2V0U2VsZWN0Qm94KG5vZGUsIGlkKTtcclxuICAgICAgc2VsZWN0Qm94LnJlbW92ZUNoaWxkKHNlbGVjdEJveC5vcHRpb25zW3NlbGVjdGlvbi5pZHhdKTtcclxuXHJcbiAgICAgIC8vIHVwZGF0ZSBzZWxlY3QgYm94IHNpemVcclxuICAgICAgaW5pdFNlbGVjdGlvblNpemUoc2VsZWN0Qm94LCBzZWxlY3RCb3gub3B0aW9ucy5sZW5ndGgpO1xyXG5cclxuICAgICAgdGhpcy5fX2FjdGlvbiA9IHtcclxuICAgICAgICBpZDogUkVNT1ZFX0VYVEVOU0lPTl9FTEVNRU5UX0FDVElPTixcclxuICAgICAgICB2YWx1ZTogc2VsZWN0aW9uLnZhbHVlLFxyXG4gICAgICAgIGlkeDogc2VsZWN0aW9uLmlkeFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGVFbGVtZW50czogZnVuY3Rpb24oZWxlbWVudCwgZW50cnlOb2RlLCBub2RlLCBzY29wZU5vZGUpIHtcclxuICAgICAgcmV0dXJuICFoaWRlRWxlbWVudHMoZWxlbWVudCwgZW50cnlOb2RlLCBub2RlLCBzY29wZU5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBkaXNhYmxlUmVtb3ZlOiBmdW5jdGlvbihlbGVtZW50LCBlbnRyeU5vZGUsIG5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICByZXR1cm4gKGdldFNlbGVjdGVkKGVudHJ5Tm9kZSwgaWQpIHx8IHt9KS5pZHggPCAwO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZWxlY3RFbGVtZW50OiBzZWxlY3Rpb25DaGFuZ2VkXHJcbiAgfTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBnZXRJbXBsZW1lbnRhdGlvblR5cGUgPSBvcHRpb25zLmdldEltcGxlbWVudGF0aW9uVHlwZSxcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICBmdW5jdGlvbiBpc0V4dGVybmFsKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBnZXRJbXBsZW1lbnRhdGlvblR5cGUoZWxlbWVudCkgPT09ICdleHRlcm5hbCc7XHJcbiAgfVxyXG5cclxuICB2YXIgdG9waWNFbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdleHRlcm5hbFRvcGljJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1RvcGljJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZXh0ZXJuYWxUb3BpYycsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4geyBleHRlcm5hbFRvcGljOiBiby5nZXQoJ2FjdGl2aXRpOnRvcGljJykgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHtcclxuICAgICAgICAnYWN0aXZpdGk6dG9waWMnOiB2YWx1ZXMuZXh0ZXJuYWxUb3BpY1xyXG4gICAgICB9KTtcclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICByZXR1cm4gaXNFeHRlcm5hbChlbGVtZW50KSAmJiAhdmFsdWVzLmV4dGVybmFsVG9waWMgPyB7IGV4dGVybmFsVG9waWM6IHRyYW5zbGF0ZSgnTXVzdCBwcm92aWRlIGEgdmFsdWUnKSB9IDoge307XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gIWlzRXh0ZXJuYWwoZWxlbWVudCk7XHJcbiAgICB9XHJcblxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gWyB0b3BpY0VudHJ5IF07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gb3B0aW9ucy5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbiAgdmFyIGV4dGVybmFsVGFza1ByaW9yaXR5RW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnZXh0ZXJuYWxUYXNrUHJpb3JpdHknLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGFzayBQcmlvcml0eScpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3Rhc2tQcmlvcml0eScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHRhc2tQcmlvcml0eTogYm8uZ2V0KCdhY3Rpdml0aTp0YXNrUHJpb3JpdHknKVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBibywge1xyXG4gICAgICAgICdhY3Rpdml0aTp0YXNrUHJpb3JpdHknOiB2YWx1ZXMudGFza1ByaW9yaXR5IHx8IHVuZGVmaW5lZFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBbIGV4dGVybmFsVGFza1ByaW9yaXR5RW50cnkgXTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBleHRlbnNpb25FbGVtZW50c0hlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FeHRlbnNpb25FbGVtZW50c0hlbHBlcicpLFxyXG4gICAgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgdXRpbHMgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9VdGlscycpO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgZXh0ZW5zaW9uRWxlbWVudHNFbnRyeSA9IHJlcXVpcmUoJy4vRXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuXHJcbnZhciBNb2RlbFV0aWwgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBNb2RlbFV0aWwuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgYXNzaWduID0gcmVxdWlyZSgnbG9kYXNoL2Fzc2lnbicpO1xyXG5cclxuXHJcbnZhciBERUZBVUxUX1BST1BTID0ge1xyXG4gICdzdHJpbmdWYWx1ZSc6IHVuZGVmaW5lZCxcclxuICAnc3RyaW5nJzogdW5kZWZpbmVkLFxyXG4gICdleHByZXNzaW9uJzogdW5kZWZpbmVkXHJcbn07XHJcblxyXG52YXIgQUNUSVZJVElfRklFTERfRVhURU5TSU9OX0VMRU1FTlQgPSAnYWN0aXZpdGk6RmllbGQnO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgdHJhbnNsYXRlLCBvcHRpb25zKSB7XHJcblxyXG4gIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xyXG5cclxuICB2YXIgaW5zaWRlTGlzdGVuZXIgPSAhIW9wdGlvbnMuaW5zaWRlTGlzdGVuZXIsXHJcbiAgICAgIGlkUHJlZml4ID0gb3B0aW9ucy5pZFByZWZpeCB8fCAnJyxcclxuICAgICAgZ2V0U2VsZWN0ZWRMaXN0ZW5lciA9IG9wdGlvbnMuZ2V0U2VsZWN0ZWRMaXN0ZW5lcixcclxuICAgICAgYnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmJ1c2luZXNzT2JqZWN0IHx8IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICB2YXIgZW50cmllcyA9IFtdO1xyXG5cclxuICB2YXIgaXNTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHJldHVybiBnZXRTZWxlY3RlZEZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG4gIH07XHJcblxyXG4gIGZ1bmN0aW9uIGdldFNlbGVjdGVkRmllbGQoZWxlbWVudCwgbm9kZSkge1xyXG4gICAgdmFyIHNlbGVjdGVkID0gZmllbGRFbnRyeS5nZXRTZWxlY3RlZChlbGVtZW50LCBub2RlLnBhcmVudE5vZGUpO1xyXG5cclxuICAgIGlmIChzZWxlY3RlZC5pZHggPT09IC0xKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZmllbGRzID0gZ2V0QWN0aXZpdGlGaWVsZHMoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgcmV0dXJuIGZpZWxkc1tzZWxlY3RlZC5pZHhdO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0QWN0aXZpdGlGaWVsZHMoZWxlbWVudCwgbm9kZSkge1xyXG4gICAgaWYgKCFpbnNpZGVMaXN0ZW5lcikge1xyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIGJ1c2luZXNzT2JqZWN0ICYmXHJcbiAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYnVzaW5lc3NPYmplY3QsIEFDVElWSVRJX0ZJRUxEX0VYVEVOU0lPTl9FTEVNRU5UKVxyXG4gICAgICApIHx8IFtdO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGdldEFjdGl2aXRpTGlzdGVuZXJGaWVsZHMoZWxlbWVudCwgbm9kZSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBnZXRBY3Rpdml0aUxpc3RlbmVyRmllbGRzKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciBzZWxlY3RlZExpc3RlbmVyID0gZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKTtcclxuICAgIHJldHVybiBzZWxlY3RlZExpc3RlbmVyICYmIHNlbGVjdGVkTGlzdGVuZXIuZmllbGRzIHx8IFtdO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0RmllbGRUeXBlKGJvKSB7XHJcbiAgICB2YXIgZmllbGRUeXBlID0gJ3N0cmluZyc7XHJcblxyXG4gICAgdmFyIGV4cHJlc3Npb25WYWx1ZSA9IGJvICYmIGJvLmV4cHJlc3Npb247XHJcbiAgICB2YXIgc3RyaW5nVmFsdWUgPSBibyAmJiAoYm8uc3RyaW5nIHx8IGJvLnN0cmluZ1ZhbHVlKTtcclxuXHJcbiAgICBpZiAodHlwZW9mIHN0cmluZ1ZhbHVlICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICBmaWVsZFR5cGUgPSAnc3RyaW5nJztcclxuICAgIH0gZWxzZSBpZiAodHlwZW9mIGV4cHJlc3Npb25WYWx1ZSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgZmllbGRUeXBlID0gJ2V4cHJlc3Npb24nO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmaWVsZFR5cGU7XHJcbiAgfVxyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIG9wdGlvbiwgcHJvcGVydHksIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGFjdGl2aXRpRmllbGRzID0gZ2V0QWN0aXZpdGlGaWVsZHMoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBmaWVsZCA9IGFjdGl2aXRpRmllbGRzW2lkeF07XHJcblxyXG4gICAgICB2YWx1ZSA9IChmaWVsZC5uYW1lKSA/IGZpZWxkLm5hbWUgOiAnPGVtcHR5Pic7XHJcblxyXG4gICAgICB2YXIgbGFiZWwgPSBpZHggKyAnIDogJyArIHZhbHVlO1xyXG5cclxuICAgICAgb3B0aW9uLnRleHQgPSBsYWJlbDtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgdmFyIG5ld0VsZW1lbnQgPSBmdW5jdGlvbigpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgdmFsdWUsIG5vZGUpIHtcclxuXHJcbiAgICAgIHZhciBwcm9wcyA9IHtcclxuICAgICAgICBuYW1lOiAnJyxcclxuICAgICAgICBzdHJpbmc6ICcnXHJcbiAgICAgIH07XHJcblxyXG4gICAgICB2YXIgbmV3RmllbGRFbGVtO1xyXG5cclxuICAgICAgaWYgKCFpbnNpZGVMaXN0ZW5lcikge1xyXG5cclxuICAgICAgICBuZXdGaWVsZEVsZW0gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoQUNUSVZJVElfRklFTERfRVhURU5TSU9OX0VMRU1FTlQsIHByb3BzLCBleHRlbnNpb25FbGVtZW50cywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgIHJldHVybiBjbWRIZWxwZXIuYWRkRWxlbWVudHNUb2xpc3QoZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsICd2YWx1ZXMnLCBbIG5ld0ZpZWxkRWxlbSBdKTtcclxuXHJcbiAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgIHZhciBzZWxlY3RlZExpc3RlbmVyID0gZ2V0U2VsZWN0ZWRMaXN0ZW5lcihlbGVtZW50LCBub2RlKTtcclxuICAgICAgICBuZXdGaWVsZEVsZW0gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoQUNUSVZJVElfRklFTERfRVhURU5TSU9OX0VMRU1FTlQsIHByb3BzLCBzZWxlY3RlZExpc3RlbmVyLCBicG1uRmFjdG9yeSk7XHJcbiAgICAgICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBzZWxlY3RlZExpc3RlbmVyLCAnZmllbGRzJywgWyBuZXdGaWVsZEVsZW0gXSk7XHJcblxyXG4gICAgICB9XHJcblxyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgcmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCB2YWx1ZSwgaWR4LCBub2RlKSB7XHJcbiAgICAgIHZhciBhY3Rpdml0aUZpZWxkcz0gZ2V0QWN0aXZpdGlGaWVsZHMoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBmaWVsZCA9IGFjdGl2aXRpRmllbGRzW2lkeF07XHJcbiAgICAgIGlmIChmaWVsZCkge1xyXG4gICAgICAgIGlmICghaW5zaWRlTGlzdGVuZXIpIHtcclxuICAgICAgICAgIHJldHVybiBleHRlbnNpb25FbGVtZW50c0hlbHBlci5yZW1vdmVFbnRyeShidXNpbmVzc09iamVjdCwgZWxlbWVudCwgZmllbGQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc2VsZWN0ZWRMaXN0ZW5lciA9IGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgICAgcmV0dXJuIGNtZEhlbHBlci5yZW1vdmVFbGVtZW50c0Zyb21MaXN0KGVsZW1lbnQsIHNlbGVjdGVkTGlzdGVuZXIsICdmaWVsZHMnLCBudWxsLCBbIGZpZWxkIF0pO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG5cclxuICB2YXIgZmllbGRFbnRyeSA9IGV4dGVuc2lvbkVsZW1lbnRzRW50cnkoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkIDogaWRQcmVmaXggKyAnZmllbGRzJyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdGaWVsZHMnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdmaWVsZE5hbWUnLFxyXG4gICAgaWRHZW5lcmF0aW9uOiAnZmFsc2UnLFxyXG5cclxuICAgIGJ1c2luZXNzT2JqZWN0OiBidXNpbmVzc09iamVjdCxcclxuXHJcbiAgICBjcmVhdGVFeHRlbnNpb25FbGVtZW50OiBuZXdFbGVtZW50KCksXHJcbiAgICByZW1vdmVFeHRlbnNpb25FbGVtZW50OiByZW1vdmVFbGVtZW50KCksXHJcblxyXG4gICAgZ2V0RXh0ZW5zaW9uRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGdldEFjdGl2aXRpRmllbGRzKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKClcclxuXHJcbiAgfSk7XHJcbiAgZW50cmllcy5wdXNoKGZpZWxkRW50cnkpO1xyXG5cclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS52YWxpZGF0aW9uQXdhcmVUZXh0RmllbGQoe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ2ZpZWxkLW5hbWUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnTmFtZScpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2ZpZWxkTmFtZScsXHJcblxyXG4gICAgZ2V0UHJvcGVydHk6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIChnZXRTZWxlY3RlZEZpZWxkKGVsZW1lbnQsIG5vZGUpIHx8IHt9KS5uYW1lO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBzZWxlY3RlZEZpZWxkID0gZ2V0U2VsZWN0ZWRGaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBzZWxlY3RlZEZpZWxkLCB7IG5hbWUgOiB2YWx1ZXMuZmllbGROYW1lIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICB2YXIgdmFsaWRhdGlvbiA9IHt9O1xyXG4gICAgICBpZiAoYm8pIHtcclxuICAgICAgICB2YXIgbmFtZVZhbHVlID0gdmFsdWVzLmZpZWxkTmFtZTtcclxuXHJcbiAgICAgICAgaWYgKG5hbWVWYWx1ZSkge1xyXG4gICAgICAgICAgaWYgKHV0aWxzLmNvbnRhaW5zU3BhY2UobmFtZVZhbHVlKSkge1xyXG4gICAgICAgICAgICB2YWxpZGF0aW9uLmZpZWxkTmFtZSA9IHRyYW5zbGF0ZSgnTmFtZSBtdXN0IG5vdCBjb250YWluIHNwYWNlcycpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB2YWxpZGF0aW9uLmZpZWxkTmFtZSA9IHRyYW5zbGF0ZSgnUGFyYW1ldGVyIG11c3QgaGF2ZSBhIG5hbWUnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB2YWxpZGF0aW9uO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICFpc1NlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG4gIHZhciBmaWVsZFR5cGVPcHRpb25zID0gW1xyXG4gICAge1xyXG4gICAgICBuYW1lOiB0cmFuc2xhdGUoJ1N0cmluZycpLFxyXG4gICAgICB2YWx1ZTogJ3N0cmluZydcclxuICAgIH0sXHJcbiAgICB7XHJcbiAgICAgIG5hbWU6IHRyYW5zbGF0ZSgnRXhwcmVzc2lvbicpLFxyXG4gICAgICB2YWx1ZTogJ2V4cHJlc3Npb24nXHJcbiAgICB9XHJcbiAgXTtcclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ2ZpZWxkLXR5cGUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVHlwZScpLFxyXG4gICAgc2VsZWN0T3B0aW9uczogZmllbGRUeXBlT3B0aW9ucyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdmaWVsZFR5cGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZEZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIGZpZWxkVHlwZSA9IGdldEZpZWxkVHlwZShibyk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGZpZWxkVHlwZTogZmllbGRUeXBlXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBwcm9wcyA9IGFzc2lnbih7fSwgREVGQVVMVF9QUk9QUyk7XHJcblxyXG4gICAgICB2YXIgZmllbGRUeXBlID0gdmFsdWVzLmZpZWxkVHlwZTtcclxuXHJcbiAgICAgIGlmIChmaWVsZFR5cGUgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgcHJvcHMuc3RyaW5nID0gJyc7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAoZmllbGRUeXBlID09PSAnZXhwcmVzc2lvbicpIHtcclxuICAgICAgICBwcm9wcy5leHByZXNzaW9uID0gJyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgZ2V0U2VsZWN0ZWRGaWVsZChlbGVtZW50LCBub2RlKSwgcHJvcHMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuICFpc1NlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRCb3goe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ2ZpZWxkLXZhbHVlJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1ZhbHVlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZmllbGRWYWx1ZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkRmllbGQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBmaWVsZFR5cGUgPSBnZXRGaWVsZFR5cGUoYm8pO1xyXG5cclxuICAgICAgdmFyIGZpZWxkVmFsdWU7XHJcblxyXG4gICAgICBpZiAoZmllbGRUeXBlID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIGZpZWxkVmFsdWUgPSBibyAmJiAoYm8uc3RyaW5nIHx8IGJvLnN0cmluZ1ZhbHVlKTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmIChmaWVsZFR5cGUgPT09ICdleHByZXNzaW9uJykge1xyXG4gICAgICAgIGZpZWxkVmFsdWUgPSBibyAmJiBiby5leHByZXNzaW9uO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGZpZWxkVmFsdWU6IGZpZWxkVmFsdWVcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWRGaWVsZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGZpZWxkVHlwZSA9IGdldEZpZWxkVHlwZShibyk7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIERFRkFVTFRfUFJPUFMpO1xyXG5cclxuICAgICAgdmFyIGZpZWxkVmFsdWUgPSB2YWx1ZXMuZmllbGRWYWx1ZSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICBpZiAoZmllbGRUeXBlID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgIHByb3BzLnN0cmluZyA9IGZpZWxkVmFsdWU7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAoZmllbGRUeXBlID09PSAnZXhwcmVzc2lvbicpIHtcclxuICAgICAgICBwcm9wcy5leHByZXNzaW9uID0gZmllbGRWYWx1ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBibywgcHJvcHMpO1xyXG5cclxuICAgIH0sXHJcblxyXG4gICAgdmFsaWRhdGU6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZEZpZWxkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIHZhbGlkYXRpb24gPSB7fTtcclxuICAgICAgaWYgKGJvKSB7XHJcbiAgICAgICAgaWYgKCF2YWx1ZXMuZmllbGRWYWx1ZSkge1xyXG4gICAgICAgICAgdmFsaWRhdGlvbi5maWVsZFZhbHVlID0gdHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgYSB2YWx1ZScpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbGlkYXRpb247XHJcbiAgICB9LFxyXG5cclxuICAgIHNob3c6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gb3B0aW9ucy5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbiAgdmFyIGhpc3RvcnlUaW1lVG9MaXZlRW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnaGlzdG9yeVRpbWVUb0xpdmUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSGlzdG9yeSBUaW1lIFRvIExpdmUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdoaXN0b3J5VGltZVRvTGl2ZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICB2YXIgaGlzdG9yeVRpbWVUb0xpdmUgPSBiby5nZXQoJ2FjdGl2aXRpOmhpc3RvcnlUaW1lVG9MaXZlJyk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGhpc3RvcnlUaW1lVG9MaXZlOiBoaXN0b3J5VGltZVRvTGl2ZSA/IGhpc3RvcnlUaW1lVG9MaXZlIDogJydcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHtcclxuICAgICAgICAnYWN0aXZpdGk6aGlzdG9yeVRpbWVUb0xpdmUnOiB2YWx1ZXMuaGlzdG9yeVRpbWVUb0xpdmUgfHwgdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIFsgaGlzdG9yeVRpbWVUb0xpdmVFbnRyeSBdO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKSxcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKTtcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyk7XHJcbnZhciBtYXAgPSByZXF1aXJlKCdsb2Rhc2gvbWFwJyk7XHJcblxyXG52YXIgREVGQVVMVF9ERUxFR0FURV9QUk9QUyA9IFsgJ2NsYXNzJywgJ2V4cHJlc3Npb24nLCAnZGVsZWdhdGVFeHByZXNzaW9uJyBdO1xyXG5cclxudmFyIERFTEVHQVRFX1BST1BTID0ge1xyXG4gICdhY3Rpdml0aTpjbGFzcyc6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6ZXhwcmVzc2lvbic6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6ZGVsZWdhdGVFeHByZXNzaW9uJzogdW5kZWZpbmVkLFxyXG4gICdhY3Rpdml0aTpyZXN1bHRWYXJpYWJsZSc6IHVuZGVmaW5lZFxyXG59O1xyXG5cclxudmFyIERNTl9DQVBBQkxFX1BST1BTID0ge1xyXG4gICdhY3Rpdml0aTpkZWNpc2lvblJlZic6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6ZGVjaXNpb25SZWZCaW5kaW5nJzogJ2xhdGVzdCcsXHJcbiAgJ2FjdGl2aXRpOmRlY2lzaW9uUmVmVmVyc2lvbic6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6bWFwRGVjaXNpb25SZXN1bHQnOiAncmVzdWx0TGlzdCcsXHJcbiAgJ2FjdGl2aXRpOmRlY2lzaW9uUmVmVGVuYW50SWQnOiB1bmRlZmluZWRcclxufTtcclxuXHJcblxyXG52YXIgRVhURVJOQUxfQ0FQQUJMRV9QUk9QUyA9IHtcclxuICAnYWN0aXZpdGk6dHlwZSc6IHVuZGVmaW5lZCxcclxuICAnYWN0aXZpdGk6dG9waWMnOiB1bmRlZmluZWRcclxufTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgREVGQVVMVF9PUFRJT05TID0gW1xyXG4gICAgeyB2YWx1ZTogJ2NsYXNzJywgbmFtZTogdHJhbnNsYXRlKCdKYXZhIENsYXNzJykgfSxcclxuICAgIHsgdmFsdWU6ICdleHByZXNzaW9uJywgbmFtZTogdHJhbnNsYXRlKCdFeHByZXNzaW9uJykgfSxcclxuICAgIHsgdmFsdWU6ICdkZWxlZ2F0ZUV4cHJlc3Npb24nLCBuYW1lOiB0cmFuc2xhdGUoJ0RlbGVnYXRlIEV4cHJlc3Npb24nKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIERNTl9PUFRJT04gPSBbXHJcbiAgICB7IHZhbHVlOiAnZG1uJywgbmFtZTogdHJhbnNsYXRlKCdETU4nKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIEVYVEVSTkFMX09QVElPTiA9IFtcclxuICAgIHsgdmFsdWU6ICdleHRlcm5hbCcsIG5hbWU6IHRyYW5zbGF0ZSgnRXh0ZXJuYWwnKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIENPTk5FQ1RPUl9PUFRJT04gPSBbXHJcbiAgICB7IHZhbHVlOiAnY29ubmVjdG9yJywgbmFtZTogdHJhbnNsYXRlKCdDb25uZWN0b3InKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIFNDUklQVF9PUFRJT04gPSBbXHJcbiAgICB7IHZhbHVlOiAnc2NyaXB0JywgbmFtZTogdHJhbnNsYXRlKCdTY3JpcHQnKSB9XHJcbiAgXTtcclxuXHJcbiAgdmFyIGdldFR5cGUgPSBvcHRpb25zLmdldEltcGxlbWVudGF0aW9uVHlwZSxcclxuICAgICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICB2YXIgaGFzRG1uU3VwcG9ydCA9IG9wdGlvbnMuaGFzRG1uU3VwcG9ydCxcclxuICAgICAgaGFzRXh0ZXJuYWxTdXBwb3J0ID0gb3B0aW9ucy5oYXNFeHRlcm5hbFN1cHBvcnQsXHJcbiAgICAgIGhhc1NlcnZpY2VUYXNrTGlrZVN1cHBvcnQgPSBvcHRpb25zLmhhc1NlcnZpY2VUYXNrTGlrZVN1cHBvcnQsXHJcbiAgICAgIGhhc1NjcmlwdFN1cHBvcnQgPSBvcHRpb25zLmhhc1NjcmlwdFN1cHBvcnQ7XHJcblxyXG4gIHZhciBlbnRyaWVzID0gW107XHJcblxyXG4gIHZhciBzZWxlY3RPcHRpb25zID0gREVGQVVMVF9PUFRJT05TLmNvbmNhdChbXSk7XHJcblxyXG4gIGlmIChoYXNEbW5TdXBwb3J0KSB7XHJcbiAgICBzZWxlY3RPcHRpb25zID0gc2VsZWN0T3B0aW9ucy5jb25jYXQoRE1OX09QVElPTik7XHJcbiAgfVxyXG5cclxuICBpZiAoaGFzRXh0ZXJuYWxTdXBwb3J0KSB7XHJcbiAgICBzZWxlY3RPcHRpb25zID0gc2VsZWN0T3B0aW9ucy5jb25jYXQoRVhURVJOQUxfT1BUSU9OKTtcclxuICB9XHJcblxyXG4gIGlmIChoYXNTZXJ2aWNlVGFza0xpa2VTdXBwb3J0KSB7XHJcbiAgICBzZWxlY3RPcHRpb25zID0gc2VsZWN0T3B0aW9ucy5jb25jYXQoQ09OTkVDVE9SX09QVElPTik7XHJcbiAgfVxyXG5cclxuICBpZiAoaGFzU2NyaXB0U3VwcG9ydCkge1xyXG4gICAgc2VsZWN0T3B0aW9ucyA9IHNlbGVjdE9wdGlvbnMuY29uY2F0KFNDUklQVF9PUFRJT04pO1xyXG4gIH1cclxuXHJcbiAgc2VsZWN0T3B0aW9ucy5wdXNoKHsgdmFsdWU6ICcnIH0pO1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnNlbGVjdEJveCh7XHJcbiAgICBpZCA6ICdpbXBsZW1lbnRhdGlvbicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdJbXBsZW1lbnRhdGlvbicpLFxyXG4gICAgc2VsZWN0T3B0aW9uczogc2VsZWN0T3B0aW9ucyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdpbXBsVHlwZScsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgaW1wbFR5cGU6IGdldFR5cGUoZWxlbWVudCkgfHwgJydcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHZhciBvbGRUeXBlID0gZ2V0VHlwZShlbGVtZW50KTtcclxuICAgICAgdmFyIG5ld1R5cGUgPSB2YWx1ZXMuaW1wbFR5cGU7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSBhc3NpZ24oe30sIERFTEVHQVRFX1BST1BTKTtcclxuXHJcbiAgICAgIGlmIChERUZBVUxUX0RFTEVHQVRFX1BST1BTLmluZGV4T2YobmV3VHlwZSkgIT09IC0xKSB7XHJcblxyXG4gICAgICAgIHZhciBuZXdWYWx1ZSA9ICcnO1xyXG4gICAgICAgIGlmIChERUZBVUxUX0RFTEVHQVRFX1BST1BTLmluZGV4T2Yob2xkVHlwZSkgIT09IC0xKSB7XHJcbiAgICAgICAgICBuZXdWYWx1ZSA9IGJvLmdldCgnYWN0aXZpdGk6JyArIG9sZFR5cGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwcm9wc1snYWN0aXZpdGk6JyArIG5ld1R5cGVdID0gbmV3VmFsdWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChoYXNEbW5TdXBwb3J0KSB7XHJcbiAgICAgICAgcHJvcHMgPSBhc3NpZ24ocHJvcHMsIERNTl9DQVBBQkxFX1BST1BTKTtcclxuICAgICAgICBpZiAobmV3VHlwZSA9PT0gJ2RtbicpIHtcclxuICAgICAgICAgIHByb3BzWydhY3Rpdml0aTpkZWNpc2lvblJlZiddID0gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaGFzRXh0ZXJuYWxTdXBwb3J0KSB7XHJcbiAgICAgICAgcHJvcHMgPSBhc3NpZ24ocHJvcHMsIEVYVEVSTkFMX0NBUEFCTEVfUFJPUFMpO1xyXG4gICAgICAgIGlmIChuZXdUeXBlID09PSAnZXh0ZXJuYWwnKSB7XHJcbiAgICAgICAgICBwcm9wc1snYWN0aXZpdGk6dHlwZSddID0gJ2V4dGVybmFsJztcclxuICAgICAgICAgIHByb3BzWydhY3Rpdml0aTp0b3BpYyddID0gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaGFzU2NyaXB0U3VwcG9ydCkge1xyXG4gICAgICAgIHByb3BzWydhY3Rpdml0aTpzY3JpcHQnXSA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAgICAgaWYgKG5ld1R5cGUgPT09ICdzY3JpcHQnKSB7XHJcbiAgICAgICAgICBwcm9wc1snYWN0aXZpdGk6c2NyaXB0J10gPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2FjdGl2aXRpOlNjcmlwdCcsIHt9LCBibywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGJvLCBwcm9wcykpO1xyXG5cclxuICAgICAgaWYgKGhhc1NlcnZpY2VUYXNrTGlrZVN1cHBvcnQpIHtcclxuICAgICAgICB2YXIgY29ubmVjdG9ycyA9IGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyLmdldEV4dGVuc2lvbkVsZW1lbnRzKGJvLCAnYWN0aXZpdGk6Q29ubmVjdG9yJyk7XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChtYXAoY29ubmVjdG9ycywgZnVuY3Rpb24oY29ubmVjdG9yKSB7XHJcbiAgICAgICAgICByZXR1cm4gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoYm8sIGVsZW1lbnQsIGNvbm5lY3Rvcik7XHJcbiAgICAgICAgfSkpO1xyXG5cclxuICAgICAgICBpZiAobmV3VHlwZSA9PT0gJ2Nvbm5lY3RvcicpIHtcclxuICAgICAgICAgIHZhciBleHRlbnNpb25FbGVtZW50cyA9IGJvLmdldCgnZXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuICAgICAgICAgIGlmICghZXh0ZW5zaW9uRWxlbWVudHMpIHtcclxuICAgICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnLCB7IHZhbHVlczogW10gfSwgYm8sIGJwbW5GYWN0b3J5KTtcclxuICAgICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgZXh0ZW5zaW9uRWxlbWVudHM6IGV4dGVuc2lvbkVsZW1lbnRzIH0pKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHZhciBjb25uZWN0b3IgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoJ2FjdGl2aXRpOkNvbm5lY3RvcicsIHt9LCBleHRlbnNpb25FbGVtZW50cywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgICAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAgICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICAgICAgICBbIGNvbm5lY3RvciBdLFxyXG4gICAgICAgICAgICBbXVxyXG4gICAgICAgICAgKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcblxyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXInKSxcclxuICAgIGlucHV0T3V0cHV0SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0lucHV0T3V0cHV0SGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgZXh0ZW5zaW9uRWxlbWVudHNFbnRyeSA9IHJlcXVpcmUoJy4vRXh0ZW5zaW9uRWxlbWVudHMnKTtcclxuXHJcblxyXG5mdW5jdGlvbiBnZXRJbnB1dE91dHB1dChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICByZXR1cm4gaW5wdXRPdXRwdXRIZWxwZXIuZ2V0SW5wdXRPdXRwdXQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0Q29ubmVjdG9yKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaW5wdXRPdXRwdXRIZWxwZXIuZ2V0Q29ubmVjdG9yKGVsZW1lbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRJbnB1dFBhcmFtZXRlcnMoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSB7XHJcbiAgcmV0dXJuIGlucHV0T3V0cHV0SGVscGVyLmdldElucHV0UGFyYW1ldGVycyhlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRPdXRwdXRQYXJhbWV0ZXJzKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcikge1xyXG4gIHJldHVybiBpbnB1dE91dHB1dEhlbHBlci5nZXRPdXRwdXRQYXJhbWV0ZXJzKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcik7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldElucHV0UGFyYW1ldGVyKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KSB7XHJcbiAgcmV0dXJuIGlucHV0T3V0cHV0SGVscGVyLmdldElucHV0UGFyYW1ldGVyKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KTtcclxufVxyXG5cclxuZnVuY3Rpb24gZ2V0T3V0cHV0UGFyYW1ldGVyKGVsZW1lbnQsIGluc2lkZUNvbm5lY3RvciwgaWR4KSB7XHJcbiAgcmV0dXJuIGlucHV0T3V0cHV0SGVscGVyLmdldE91dHB1dFBhcmFtZXRlcihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IsIGlkeCk7XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHR5cGUsIHBhcmVudCwgZmFjdG9yeSwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQodHlwZSwgcHJvcGVydGllcywgcGFyZW50LCBmYWN0b3J5KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlSW5wdXRPdXRwdXQocGFyZW50LCBicG1uRmFjdG9yeSwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiBjcmVhdGVFbGVtZW50KCdhY3Rpdml0aTpJbnB1dE91dHB1dCcsIHBhcmVudCwgYnBtbkZhY3RvcnksIHByb3BlcnRpZXMpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVQYXJhbWV0ZXIodHlwZSwgcGFyZW50LCBicG1uRmFjdG9yeSwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiBjcmVhdGVFbGVtZW50KHR5cGUsIHBhcmVudCwgYnBtbkZhY3RvcnksIHByb3BlcnRpZXMpO1xyXG59XHJcblxyXG5cclxuZnVuY3Rpb24gZW5zdXJlSW5wdXRPdXRwdXRTdXBwb3J0ZWQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSB7XHJcbiAgcmV0dXJuIGlucHV0T3V0cHV0SGVscGVyLmlzSW5wdXRPdXRwdXRTdXBwb3J0ZWQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKTtcclxufVxyXG5cclxuZnVuY3Rpb24gZW5zdXJlT3V0cGFyYW1ldGVyU3VwcG9ydGVkKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcikge1xyXG4gIHJldHVybiBpbnB1dE91dHB1dEhlbHBlci5hcmVPdXRwdXRQYXJhbWV0ZXJzU3VwcG9ydGVkKGVsZW1lbnQsIGluc2lkZUNvbm5lY3Rvcik7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgVFlQRV9MQUJFTCA9IHtcclxuICAgICdhY3Rpdml0aTpNYXAnOiB0cmFuc2xhdGUoJ01hcCcpLFxyXG4gICAgJ2FjdGl2aXRpOkxpc3QnOiB0cmFuc2xhdGUoJ0xpc3QnKSxcclxuICAgICdhY3Rpdml0aTpTY3JpcHQnOiB0cmFuc2xhdGUoJ1NjcmlwdCcpXHJcbiAgfTtcclxuXHJcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG4gIHZhciBpbnNpZGVDb25uZWN0b3IgPSAhIW9wdGlvbnMuaW5zaWRlQ29ubmVjdG9yLFxyXG4gICAgICBpZFByZWZpeCA9IG9wdGlvbnMuaWRQcmVmaXggfHwgJyc7XHJcblxyXG4gIHZhciBnZXRTZWxlY3RlZCA9IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgIHZhciBzZWxlY3Rpb24gPSAoaW5wdXRFbnRyeSAmJiBpbnB1dEVudHJ5LmdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpKSB8fCB7IGlkeDogLTEgfTtcclxuXHJcbiAgICB2YXIgcGFyYW1ldGVyID0gZ2V0SW5wdXRQYXJhbWV0ZXIoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yLCBzZWxlY3Rpb24uaWR4KTtcclxuICAgIGlmICghcGFyYW1ldGVyICYmIG91dHB1dEVudHJ5KSB7XHJcbiAgICAgIHNlbGVjdGlvbiA9IG91dHB1dEVudHJ5LmdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICBwYXJhbWV0ZXIgPSBnZXRPdXRwdXRQYXJhbWV0ZXIoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yLCBzZWxlY3Rpb24uaWR4KTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXJhbWV0ZXI7XHJcbiAgfTtcclxuXHJcbiAgdmFyIHJlc3VsdCA9IHtcclxuICAgIGdldFNlbGVjdGVkUGFyYW1ldGVyOiBnZXRTZWxlY3RlZFxyXG4gIH07XHJcblxyXG4gIHZhciBlbnRyaWVzID0gcmVzdWx0LmVudHJpZXMgPSBbXTtcclxuXHJcbiAgaWYgKCFlbnN1cmVJbnB1dE91dHB1dFN1cHBvcnRlZChlbGVtZW50KSkge1xyXG4gICAgcmV0dXJuIHJlc3VsdDtcclxuICB9XHJcblxyXG4gIHZhciBuZXdFbGVtZW50ID0gZnVuY3Rpb24odHlwZSwgcHJvcCwgZmFjdG9yeSkge1xyXG5cclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgdmFsdWUpIHtcclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcblxyXG4gICAgICB2YXIgaW5wdXRPdXRwdXQgPSBnZXRJbnB1dE91dHB1dChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG4gICAgICBpZiAoIWlucHV0T3V0cHV0KSB7XHJcbiAgICAgICAgdmFyIHBhcmVudCA9ICFpbnNpZGVDb25uZWN0b3IgPyBleHRlbnNpb25FbGVtZW50cyA6IGdldENvbm5lY3RvcihlbGVtZW50KTtcclxuICAgICAgICBpbnB1dE91dHB1dCA9IGNyZWF0ZUlucHV0T3V0cHV0KHBhcmVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgICAgICAgIGlucHV0UGFyYW1ldGVyczogW10sXHJcbiAgICAgICAgICBvdXRwdXRQYXJhbWV0ZXJzOiBbXVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBpZiAoIWluc2lkZUNvbm5lY3Rvcikge1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgICAgICAgZWxlbWVudCxcclxuICAgICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHMsXHJcbiAgICAgICAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAgICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICAgICAgICBbIGlucHV0T3V0cHV0IF0sXHJcbiAgICAgICAgICAgIFtdXHJcbiAgICAgICAgICApKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgcGFyZW50LCB7IGlucHV0T3V0cHV0OiBpbnB1dE91dHB1dCB9KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgbmV3RWxlbSA9IGNyZWF0ZVBhcmFtZXRlcih0eXBlLCBpbnB1dE91dHB1dCwgYnBtbkZhY3RvcnksIHsgbmFtZTogdmFsdWUgfSk7XHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLmFkZEVsZW1lbnRzVG9saXN0KGVsZW1lbnQsIGlucHV0T3V0cHV0LCBwcm9wLCBbIG5ld0VsZW0gXSkpO1xyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgcmVtb3ZlRWxlbWVudCA9IGZ1bmN0aW9uKGdldHRlciwgcHJvcCwgb3RoZXJQcm9wKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24oZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGlucHV0T3V0cHV0ID0gZ2V0SW5wdXRPdXRwdXQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKTtcclxuICAgICAgdmFyIHBhcmFtZXRlciA9IGdldHRlcihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IsIGlkeCk7XHJcblxyXG4gICAgICB2YXIgY29tbWFuZHMgPSBbXTtcclxuICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIucmVtb3ZlRWxlbWVudHNGcm9tTGlzdChlbGVtZW50LCBpbnB1dE91dHB1dCwgcHJvcCwgbnVsbCwgWyBwYXJhbWV0ZXIgXSkpO1xyXG5cclxuICAgICAgdmFyIGZpcnN0TGVuZ3RoID0gaW5wdXRPdXRwdXQuZ2V0KHByb3ApLmxlbmd0aC0xO1xyXG4gICAgICB2YXIgc2Vjb25kTGVuZ3RoID0gKGlucHV0T3V0cHV0LmdldChvdGhlclByb3ApIHx8IFtdKS5sZW5ndGg7XHJcblxyXG4gICAgICBpZiAoIWZpcnN0TGVuZ3RoICYmICFzZWNvbmRMZW5ndGgpIHtcclxuXHJcbiAgICAgICAgaWYgKCFpbnNpZGVDb25uZWN0b3IpIHtcclxuICAgICAgICAgIGNvbW1hbmRzLnB1c2goZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksIGVsZW1lbnQsIGlucHV0T3V0cHV0KSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHZhciBjb25uZWN0b3IgPSBnZXRDb25uZWN0b3IoZWxlbWVudCk7XHJcbiAgICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBjb25uZWN0b3IsIHsgaW5wdXRPdXRwdXQ6IHVuZGVmaW5lZCB9KSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IGZ1bmN0aW9uKGdldHRlcikge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIG9wdGlvbiwgcHJvcGVydHksIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIHBhcmFtZXRlciA9IGdldHRlcihlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IsIGlkeCk7XHJcblxyXG4gICAgICB2YXIgc3VmZml4ID0gJ1RleHQnO1xyXG5cclxuICAgICAgdmFyIGRlZmluaXRpb24gPSBwYXJhbWV0ZXIuZ2V0KCdkZWZpbml0aW9uJyk7XHJcbiAgICAgIGlmICh0eXBlb2YgZGVmaW5pdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICB2YXIgdHlwZSA9IGRlZmluaXRpb24uJHR5cGU7XHJcbiAgICAgICAgc3VmZml4ID0gVFlQRV9MQUJFTFt0eXBlXTtcclxuICAgICAgfVxyXG5cclxuICAgICAgb3B0aW9uLnRleHQgPSAodmFsdWUgfHwgJycpICsgJyA6ICcgKyBzdWZmaXg7XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG5cclxuICAvLyBpbnB1dCBwYXJhbWV0ZXJzIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICB2YXIgaW5wdXRFbnRyeSA9IGV4dGVuc2lvbkVsZW1lbnRzRW50cnkoZWxlbWVudCwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkOiBpZFByZWZpeCArICdpbnB1dHMnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSW5wdXQgUGFyYW1ldGVycycpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ25hbWUnLFxyXG4gICAgcHJlZml4OiAnSW5wdXQnLFxyXG4gICAgcmVzaXphYmxlOiB0cnVlLFxyXG5cclxuICAgIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQ6IG5ld0VsZW1lbnQoJ2FjdGl2aXRpOklucHV0UGFyYW1ldGVyJywgJ2lucHV0UGFyYW1ldGVycycpLFxyXG4gICAgcmVtb3ZlRXh0ZW5zaW9uRWxlbWVudDogcmVtb3ZlRWxlbWVudChnZXRJbnB1dFBhcmFtZXRlciwgJ2lucHV0UGFyYW1ldGVycycsICdvdXRwdXRQYXJhbWV0ZXJzJyksXHJcblxyXG4gICAgZ2V0RXh0ZW5zaW9uRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgcmV0dXJuIGdldElucHV0UGFyYW1ldGVycyhlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG4gICAgfSxcclxuXHJcbiAgICBvblNlbGVjdGlvbkNoYW5nZTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgZXZlbnQsIHNjb3BlKSB7XHJcbiAgICAgIG91dHB1dEVudHJ5ICYmIG91dHB1dEVudHJ5LmRlc2VsZWN0KGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKGdldElucHV0UGFyYW1ldGVyKVxyXG5cclxuICB9KTtcclxuICBlbnRyaWVzLnB1c2goaW5wdXRFbnRyeSk7XHJcblxyXG5cclxuICAvLyBvdXRwdXQgcGFyYW1ldGVycyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIGlmIChlbnN1cmVPdXRwYXJhbWV0ZXJTdXBwb3J0ZWQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSkge1xyXG4gICAgdmFyIG91dHB1dEVudHJ5ID0gZXh0ZW5zaW9uRWxlbWVudHNFbnRyeShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgICBpZDogaWRQcmVmaXggKyAnb3V0cHV0cycsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ091dHB1dCBQYXJhbWV0ZXJzJyksXHJcbiAgICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuICAgICAgcHJlZml4OiAnT3V0cHV0JyxcclxuICAgICAgcmVzaXphYmxlOiB0cnVlLFxyXG5cclxuICAgICAgY3JlYXRlRXh0ZW5zaW9uRWxlbWVudDogbmV3RWxlbWVudCgnYWN0aXZpdGk6T3V0cHV0UGFyYW1ldGVyJywgJ291dHB1dFBhcmFtZXRlcnMnKSxcclxuICAgICAgcmVtb3ZlRXh0ZW5zaW9uRWxlbWVudDogcmVtb3ZlRWxlbWVudChnZXRPdXRwdXRQYXJhbWV0ZXIsICdvdXRwdXRQYXJhbWV0ZXJzJywgJ2lucHV0UGFyYW1ldGVycycpLFxyXG5cclxuICAgICAgZ2V0RXh0ZW5zaW9uRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICByZXR1cm4gZ2V0T3V0cHV0UGFyYW1ldGVycyhlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgb25TZWxlY3Rpb25DaGFuZ2U6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGV2ZW50LCBzY29wZSkge1xyXG4gICAgICAgIGlucHV0RW50cnkuZGVzZWxlY3QoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIH0sXHJcblxyXG4gICAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKGdldE91dHB1dFBhcmFtZXRlcilcclxuXHJcbiAgICB9KTtcclxuICAgIGVudHJpZXMucHVzaChvdXRwdXRFbnRyeSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gcmVzdWx0O1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcztcclxuXHJcbnZhciBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKSxcclxuICAgIGlucHV0T3V0cHV0SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0lucHV0T3V0cHV0SGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL1V0aWxzJyk7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIHNjcmlwdEltcGxlbWVudGF0aW9uID0gcmVxdWlyZSgnLi9TY3JpcHQnKTtcclxuXHJcblxyXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50KHR5cGUsIHBhcmVudCwgZmFjdG9yeSwgcHJvcGVydGllcykge1xyXG4gIHJldHVybiBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQodHlwZSwgcHJvcGVydGllcywgcGFyZW50LCBmYWN0b3J5KTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNTY3JpcHQoZWxlbSkge1xyXG4gIHJldHVybiBpcyhlbGVtLCAnYWN0aXZpdGk6U2NyaXB0Jyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTGlzdChlbGVtKSB7XHJcbiAgcmV0dXJuIGlzKGVsZW0sICdhY3Rpdml0aTpMaXN0Jyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGlzTWFwKGVsZW0pIHtcclxuICByZXR1cm4gaXMoZWxlbSwgJ2FjdGl2aXRpOk1hcCcpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBlbnN1cmVJbnB1dE91dHB1dFN1cHBvcnRlZChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpIHtcclxuICByZXR1cm4gaW5wdXRPdXRwdXRIZWxwZXIuaXNJbnB1dE91dHB1dFN1cHBvcnRlZChlbGVtZW50LCBpbnNpZGVDb25uZWN0b3IpO1xyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIHR5cGVJbmZvID0ge1xyXG4gICAgJ2FjdGl2aXRpOk1hcCc6IHtcclxuICAgICAgdmFsdWU6ICdtYXAnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdNYXAnKVxyXG4gICAgfSxcclxuICAgICdhY3Rpdml0aTpMaXN0Jzoge1xyXG4gICAgICB2YWx1ZTogJ2xpc3QnLFxyXG4gICAgICBsYWJlbDogdHJhbnNsYXRlKCdMaXN0JylcclxuICAgIH0sXHJcbiAgICAnYWN0aXZpdGk6U2NyaXB0Jzoge1xyXG4gICAgICB2YWx1ZTogJ3NjcmlwdCcsXHJcbiAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1NjcmlwdCcpXHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcblxyXG4gIHZhciBpbnNpZGVDb25uZWN0b3IgPSAhIW9wdGlvbnMuaW5zaWRlQ29ubmVjdG9yLFxyXG4gICAgICBpZFByZWZpeCA9IG9wdGlvbnMuaWRQcmVmaXggfHwgJyc7XHJcblxyXG4gIHZhciBnZXRTZWxlY3RlZCA9IG9wdGlvbnMuZ2V0U2VsZWN0ZWRQYXJhbWV0ZXI7XHJcblxyXG4gIGlmICghZW5zdXJlSW5wdXRPdXRwdXRTdXBwb3J0ZWQoZWxlbWVudCwgaW5zaWRlQ29ubmVjdG9yKSkge1xyXG4gICAgcmV0dXJuIFtdO1xyXG4gIH1cclxuXHJcbiAgdmFyIGVudHJpZXMgPSBbXTtcclxuXHJcbiAgdmFyIGlzU2VsZWN0ZWQgPSBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICByZXR1cm4gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgfTtcclxuXHJcblxyXG4gIC8vIHBhcmFtZXRlciBuYW1lIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudmFsaWRhdGlvbkF3YXJlVGV4dEZpZWxkKHtcclxuICAgIGlkOiBpZFByZWZpeCArICdwYXJhbWV0ZXJOYW1lJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ05hbWUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuXHJcbiAgICBnZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4gKGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpIHx8IHt9KS5uYW1lO1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBwYXJhbSA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHBhcmFtLCB2YWx1ZXMpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgdmFyIHZhbGlkYXRpb24gPSB7fTtcclxuICAgICAgaWYgKGJvKSB7XHJcbiAgICAgICAgdmFyIG5hbWVWYWx1ZSA9IHZhbHVlcy5uYW1lO1xyXG5cclxuICAgICAgICBpZiAobmFtZVZhbHVlKSB7XHJcbiAgICAgICAgICBpZiAodXRpbHMuY29udGFpbnNTcGFjZShuYW1lVmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHZhbGlkYXRpb24ubmFtZSA9IHRyYW5zbGF0ZSgnTmFtZSBtdXN0IG5vdCBjb250YWluIHNwYWNlcycpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB2YWxpZGF0aW9uLm5hbWUgPSB0cmFuc2xhdGUoJ1BhcmFtZXRlciBtdXN0IGhhdmUgYSBuYW1lJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdmFsaWRhdGlvbjtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhaXNTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG5cclxuICAvLyBwYXJhbWV0ZXIgdHlwZSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgdmFyIHNlbGVjdE9wdGlvbnMgPSBbXHJcbiAgICB7IHZhbHVlOiAndGV4dCcsIG5hbWU6IHRyYW5zbGF0ZSgnVGV4dCcpIH0sXHJcbiAgICB7IHZhbHVlOiAnc2NyaXB0JywgbmFtZTogdHJhbnNsYXRlKCdTY3JpcHQnKSB9LFxyXG4gICAgeyB2YWx1ZTogJ2xpc3QnLCBuYW1lOiB0cmFuc2xhdGUoJ0xpc3QnKSB9LFxyXG4gICAgeyB2YWx1ZTogJ21hcCcsIG5hbWU6IHRyYW5zbGF0ZSgnTWFwJykgfVxyXG4gIF07XHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3Rvcnkuc2VsZWN0Qm94KHtcclxuICAgIGlkIDogaWRQcmVmaXggKyAncGFyYW1ldGVyVHlwZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdUeXBlJyksXHJcbiAgICBzZWxlY3RPcHRpb25zOiBzZWxlY3RPcHRpb25zLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3BhcmFtZXRlclR5cGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICAgIHZhciBwYXJhbWV0ZXJUeXBlID0gJ3RleHQnO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiBibyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICB2YXIgZGVmaW5pdGlvbiA9IGJvLmdldCgnZGVmaW5pdGlvbicpO1xyXG4gICAgICAgIGlmICh0eXBlb2YgZGVmaW5pdGlvbiAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgIHZhciB0eXBlID0gZGVmaW5pdGlvbi4kdHlwZTtcclxuICAgICAgICAgIHBhcmFtZXRlclR5cGUgPSB0eXBlSW5mb1t0eXBlXS52YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgcGFyYW1ldGVyVHlwZTogcGFyYW1ldGVyVHlwZVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuXHJcbiAgICAgIHZhciBwcm9wZXJ0aWVzID0ge1xyXG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXHJcbiAgICAgICAgZGVmaW5pdGlvbjogdW5kZWZpbmVkXHJcbiAgICAgIH07XHJcblxyXG4gICAgICB2YXIgY3JlYXRlUGFyYW1ldGVyVHlwZUVsZW0gPSBmdW5jdGlvbih0eXBlKSB7XHJcbiAgICAgICAgcmV0dXJuIGNyZWF0ZUVsZW1lbnQodHlwZSwgYm8sIGJwbW5GYWN0b3J5KTtcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBwYXJhbWV0ZXJUeXBlID0gdmFsdWVzLnBhcmFtZXRlclR5cGU7XHJcblxyXG4gICAgICBpZiAocGFyYW1ldGVyVHlwZSA9PT0gJ3NjcmlwdCcpIHtcclxuICAgICAgICBwcm9wZXJ0aWVzLmRlZmluaXRpb24gPSBjcmVhdGVQYXJhbWV0ZXJUeXBlRWxlbSgnYWN0aXZpdGk6U2NyaXB0Jyk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSBpZiAocGFyYW1ldGVyVHlwZSA9PT0gJ2xpc3QnKSB7XHJcbiAgICAgICAgcHJvcGVydGllcy5kZWZpbml0aW9uID0gY3JlYXRlUGFyYW1ldGVyVHlwZUVsZW0oJ2FjdGl2aXRpOkxpc3QnKTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIGlmIChwYXJhbWV0ZXJUeXBlID09PSAnbWFwJykge1xyXG4gICAgICAgIHByb3BlcnRpZXMuZGVmaW5pdGlvbiA9IGNyZWF0ZVBhcmFtZXRlclR5cGVFbGVtKCdhY3Rpdml0aTpNYXAnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBibywgcHJvcGVydGllcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNob3c6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIGlzU2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIC8vIHBhcmFtZXRlciB2YWx1ZSAodHlwZSA9IHRleHQpIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0Qm94KHtcclxuICAgIGlkIDogaWRQcmVmaXggKyAncGFyYW1ldGVyVHlwZS10ZXh0JyxcclxuICAgIGxhYmVsIDogdHJhbnNsYXRlKCdWYWx1ZScpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3ZhbHVlJyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHZhbHVlOiAoZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSkgfHwge30pLnZhbHVlXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBwYXJhbSA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB2YWx1ZXMudmFsdWUgPSB2YWx1ZXMudmFsdWUgfHwgdW5kZWZpbmVkO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHBhcmFtLCB2YWx1ZXMpO1xyXG4gICAgfSxcclxuXHJcbiAgICBzaG93OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gYm8gJiYgIWJvLmRlZmluaXRpb247XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIC8vIHBhcmFtZXRlciB2YWx1ZSAodHlwZSA9IHNjcmlwdCkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG4gIHZhciBzY3JpcHQgPSBzY3JpcHRJbXBsZW1lbnRhdGlvbignc2NyaXB0Rm9ybWF0JywgJ3ZhbHVlJywgdHJ1ZSwgdHJhbnNsYXRlKTtcclxuICBlbnRyaWVzLnB1c2goe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ3BhcmFtZXRlclR5cGUtc2NyaXB0JyxcclxuICAgIGh0bWw6ICc8ZGl2IGRhdGEtc2hvdz1cImlzU2NyaXB0XCI+JyArXHJcbiAgICAgICAgICAgIHNjcmlwdC50ZW1wbGF0ZSArXHJcbiAgICAgICAgICAnPC9kaXY+JyxcclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGJvICYmIGlzU2NyaXB0KGJvLmRlZmluaXRpb24pID8gc2NyaXB0LmdldChlbGVtZW50LCBiby5kZWZpbml0aW9uKSA6IHt9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIHVwZGF0ZSA9IHNjcmlwdC5zZXQoZWxlbWVudCwgdmFsdWVzKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBiby5kZWZpbml0aW9uLCB1cGRhdGUpO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gYm8gJiYgaXNTY3JpcHQoYm8uZGVmaW5pdGlvbikgPyBzY3JpcHQudmFsaWRhdGUoZWxlbWVudCwgYm8uZGVmaW5pdGlvbikgOiB7fTtcclxuICAgIH0sXHJcblxyXG4gICAgaXNTY3JpcHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiBibyAmJiBpc1NjcmlwdChiby5kZWZpbml0aW9uKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2NyaXB0OiBzY3JpcHRcclxuXHJcbiAgfSk7XHJcblxyXG5cclxuICAvLyBwYXJhbWV0ZXIgdmFsdWUgKHR5cGUgPSBsaXN0KSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXHJcblxyXG4gIGVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGFibGUoe1xyXG4gICAgaWQ6IGlkUHJlZml4ICsgJ3BhcmFtZXRlclR5cGUtbGlzdCcsXHJcbiAgICBtb2RlbFByb3BlcnRpZXM6IFsgJ3ZhbHVlJyBdLFxyXG4gICAgbGFiZWxzOiBbIHRyYW5zbGF0ZSgnVmFsdWUnKSBdLFxyXG4gICAgYWRkTGFiZWw6IHRyYW5zbGF0ZSgnQWRkIFZhbHVlJyksXHJcblxyXG4gICAgZ2V0RWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcblxyXG4gICAgICBpZiAoYm8gJiYgaXNMaXN0KGJvLmRlZmluaXRpb24pKSB7XHJcbiAgICAgICAgcmV0dXJuIGJvLmRlZmluaXRpb24uaXRlbXM7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBbXTtcclxuICAgIH0sXHJcblxyXG4gICAgdXBkYXRlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlLCBpZHgpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBpdGVtID0gYm8uZGVmaW5pdGlvbi5pdGVtc1tpZHhdO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGl0ZW0sIHZhbHVlcyk7XHJcbiAgICB9LFxyXG5cclxuICAgIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBuZXdWYWx1ZSA9IGNyZWF0ZUVsZW1lbnQoJ2FjdGl2aXRpOlZhbHVlJywgYm8uZGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIHsgdmFsdWU6IHVuZGVmaW5lZCB9KTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBiby5kZWZpbml0aW9uLCAnaXRlbXMnLCBbIG5ld1ZhbHVlIF0pO1xyXG4gICAgfSxcclxuXHJcbiAgICByZW1vdmVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBpZHgpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIucmVtb3ZlRWxlbWVudHNGcm9tTGlzdChlbGVtZW50LCBiby5kZWZpbml0aW9uLCAnaXRlbXMnLCBudWxsLCBbIGJvLmRlZmluaXRpb24uaXRlbXNbaWR4XSBdKTtcclxuICAgIH0sXHJcblxyXG4gICAgZWRpdGFibGU6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIHByb3AsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGl0ZW0gPSBiby5kZWZpbml0aW9uLml0ZW1zW2lkeF07XHJcbiAgICAgIHJldHVybiAhaXNNYXAoaXRlbSkgJiYgIWlzTGlzdChpdGVtKSAmJiAhaXNTY3JpcHQoaXRlbSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHNldENvbnRyb2xWYWx1ZTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgaW5wdXQsIHByb3AsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSk7XHJcbiAgICAgIHZhciBpdGVtID0gYm8uZGVmaW5pdGlvbi5pdGVtc1tpZHhdO1xyXG5cclxuICAgICAgaWYgKCFpc01hcChpdGVtKSAmJiAhaXNMaXN0KGl0ZW0pICYmICFpc1NjcmlwdChpdGVtKSkge1xyXG4gICAgICAgIGlucHV0LnZhbHVlID0gdmFsdWU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaW5wdXQudmFsdWUgPSB0eXBlSW5mb1tpdGVtLiR0eXBlXS5sYWJlbDtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICBzaG93OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICByZXR1cm4gYm8gJiYgYm8uZGVmaW5pdGlvbiAmJiBpc0xpc3QoYm8uZGVmaW5pdGlvbik7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcblxyXG4gIC8vIHBhcmFtZXRlciB2YWx1ZSAodHlwZSA9IG1hcCkgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRhYmxlKHtcclxuICAgIGlkOiBpZFByZWZpeCArICdwYXJhbWV0ZXJUeXBlLW1hcCcsXHJcbiAgICBtb2RlbFByb3BlcnRpZXM6IFsgJ2tleScsICd2YWx1ZScgXSxcclxuICAgIGxhYmVsczogWyB0cmFuc2xhdGUoJ0tleScpLCB0cmFuc2xhdGUoJ1ZhbHVlJykgXSxcclxuICAgIGFkZExhYmVsOiB0cmFuc2xhdGUoJ0FkZCBFbnRyeScpLFxyXG5cclxuICAgIGdldEVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBibyA9IGdldFNlbGVjdGVkKGVsZW1lbnQsIG5vZGUpO1xyXG5cclxuICAgICAgaWYgKGJvICYmIGlzTWFwKGJvLmRlZmluaXRpb24pKSB7XHJcbiAgICAgICAgcmV0dXJuIGJvLmRlZmluaXRpb24uZW50cmllcztcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIFtdO1xyXG4gICAgfSxcclxuXHJcbiAgICB1cGRhdGVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGVudHJ5ID0gYm8uZGVmaW5pdGlvbi5lbnRyaWVzW2lkeF07XHJcblxyXG4gICAgICBpZiAoaXNNYXAoZW50cnkuZGVmaW5pdGlvbikgfHwgaXNMaXN0KGVudHJ5LmRlZmluaXRpb24pIHx8IGlzU2NyaXB0KGVudHJ5LmRlZmluaXRpb24pKSB7XHJcbiAgICAgICAgdmFsdWVzID0ge1xyXG4gICAgICAgICAga2V5OiB2YWx1ZXMua2V5XHJcbiAgICAgICAgfTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBlbnRyeSwgdmFsdWVzKTtcclxuICAgIH0sXHJcblxyXG4gICAgYWRkRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIG5ld0VudHJ5ID0gY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6RW50cnknLCBiby5kZWZpbml0aW9uLCBicG1uRmFjdG9yeSwgeyBrZXk6IHVuZGVmaW5lZCwgdmFsdWU6IHVuZGVmaW5lZCB9KTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBiby5kZWZpbml0aW9uLCAnZW50cmllcycsIFsgbmV3RW50cnkgXSk7XHJcbiAgICB9LFxyXG5cclxuICAgIHJlbW92ZUVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci5yZW1vdmVFbGVtZW50c0Zyb21MaXN0KGVsZW1lbnQsIGJvLmRlZmluaXRpb24sICdlbnRyaWVzJywgbnVsbCwgWyBiby5kZWZpbml0aW9uLmVudHJpZXNbaWR4XSBdKTtcclxuICAgIH0sXHJcblxyXG4gICAgZWRpdGFibGU6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUsIHByb3AsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGVudHJ5ID0gYm8uZGVmaW5pdGlvbi5lbnRyaWVzW2lkeF07XHJcbiAgICAgIHJldHVybiBwcm9wID09PSAna2V5JyB8fCAoIWlzTWFwKGVudHJ5LmRlZmluaXRpb24pICYmICFpc0xpc3QoZW50cnkuZGVmaW5pdGlvbikgJiYgIWlzU2NyaXB0KGVudHJ5LmRlZmluaXRpb24pKTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0Q29udHJvbFZhbHVlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBpbnB1dCwgcHJvcCwgdmFsdWUsIGlkeCkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgdmFyIGVudHJ5ID0gYm8uZGVmaW5pdGlvbi5lbnRyaWVzW2lkeF07XHJcblxyXG4gICAgICBpZiAocHJvcCA9PT0gJ2tleScgfHwgKCFpc01hcChlbnRyeS5kZWZpbml0aW9uKSAmJiAhaXNMaXN0KGVudHJ5LmRlZmluaXRpb24pICYmICFpc1NjcmlwdChlbnRyeS5kZWZpbml0aW9uKSkpIHtcclxuICAgICAgICBpbnB1dC52YWx1ZSA9IHZhbHVlO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlucHV0LnZhbHVlID0gdHlwZUluZm9bZW50cnkuZGVmaW5pdGlvbi4kdHlwZV0ubGFiZWw7XHJcbiAgICAgIH1cclxuICAgIH0sXHJcblxyXG4gICAgc2hvdzogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgcmV0dXJuIGJvICYmIGJvLmRlZmluaXRpb24gJiYgaXNNYXAoYm8uZGVmaW5pdGlvbik7XHJcbiAgICB9XHJcblxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldEJ1c2luZXNzT2JqZWN0ID0gb3B0aW9ucy5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbiAgdmFyIGpvYlByaW9yaXR5RW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAnam9iUHJpb3JpdHknLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSm9iIFByaW9yaXR5JyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnam9iUHJpb3JpdHknLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBqb2JQcmlvcml0eTogYm8uZ2V0KCdhY3Rpdml0aTpqb2JQcmlvcml0eScpXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGJvLCB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOmpvYlByaW9yaXR5JzogdmFsdWVzLmpvYlByaW9yaXR5IHx8IHVuZGVmaW5lZFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBbIGpvYlByaW9yaXR5RW50cnkgXTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXM7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBhc3luY0NhcGFibGVIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQXN5bmNDYXBhYmxlSGVscGVyJyk7XHJcblxyXG52YXIgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyksXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5mdW5jdGlvbiBpc0FzeW5jQmVmb3JlKGJvKSB7XHJcbiAgcmV0dXJuIGFzeW5jQ2FwYWJsZUhlbHBlci5pc0FzeW5jQmVmb3JlKGJvKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNBc3luY0FmdGVyKGJvKSB7XHJcbiAgcmV0dXJuIGFzeW5jQ2FwYWJsZUhlbHBlci5pc0FzeW5jQWZ0ZXIoYm8pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibykge1xyXG4gIHJldHVybiBhc3luY0NhcGFibGVIZWxwZXIuZ2V0RmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUoYm8pO1xyXG59XHJcblxyXG5mdW5jdGlvbiByZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibywgZWxlbWVudCkge1xyXG4gIHJldHVybiBhc3luY0NhcGFibGVIZWxwZXIucmVtb3ZlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUoYm8sIGVsZW1lbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVFeHRlbnNpb25FbGVtZW50cyhwYXJlbnQsIGJwbW5GYWN0b3J5KSB7XHJcbiAgcmV0dXJuIGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYnBtbjpFeHRlbnNpb25FbGVtZW50cycsIHsgdmFsdWVzOiBbXSB9LCBwYXJlbnQsIGJwbW5GYWN0b3J5KTtcclxufVxyXG5cclxuZnVuY3Rpb24gY3JlYXRlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUocGFyZW50LCBicG1uRmFjdG9yeSwgY3ljbGUpIHtcclxuICByZXR1cm4gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdhY3Rpdml0aTpGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZScsIHsgYm9keTogY3ljbGUgfSwgcGFyZW50LCBicG1uRmFjdG9yeSk7XHJcbn1cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0O1xyXG5cclxuICB2YXIgaWRQcmVmaXggPSBvcHRpb25zLmlkUHJlZml4IHx8ICcnLFxyXG4gICAgICBsYWJlbFByZWZpeCA9IG9wdGlvbnMubGFiZWxQcmVmaXggfHwgJyc7XHJcblxyXG4gIHZhciByZXRyeVRpbWVDeWNsZUVudHJ5ID0gZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogaWRQcmVmaXggKyAncmV0cnlUaW1lQ3ljbGUnLFxyXG4gICAgbGFiZWw6IGxhYmVsUHJlZml4ICsgdHJhbnNsYXRlKCdSZXRyeSBUaW1lIEN5Y2xlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY3ljbGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgcmV0cnlUaW1lQ3ljbGUgPSBnZXRGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSk7XHJcbiAgICAgIHZhciB2YWx1ZSA9IHJldHJ5VGltZUN5Y2xlICYmIHJldHJ5VGltZUN5Y2xlLmdldCgnYm9keScpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGN5Y2xlOiB2YWx1ZVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgbmV3Q3ljbGUgPSB2YWx1ZXMuY3ljbGU7XHJcbiAgICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICAgICAgaWYgKG5ld0N5Y2xlID09PSAnJyB8fCB0eXBlb2YgbmV3Q3ljbGUgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgLy8gcmVtb3ZlIHJldHJ5IHRpbWUgY3ljbGUgZWxlbWVudChzKVxyXG4gICAgICAgIHJldHVybiByZW1vdmVGYWlsZWRKb2JSZXRyeVRpbWVDeWNsZShibywgZWxlbWVudCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciByZXRyeVRpbWVDeWNsZSA9IGdldEZhaWxlZEpvYlJldHJ5VGltZUN5Y2xlKGJvKTtcclxuXHJcbiAgICAgIGlmICghcmV0cnlUaW1lQ3ljbGUpIHtcclxuICAgICAgICAvLyBhZGQgbmV3IHJldHJ5IHRpbWUgY3ljbGUgZWxlbWVudFxyXG4gICAgICAgIHZhciBjb21tYW5kcyA9IFtdO1xyXG5cclxuICAgICAgICB2YXIgZXh0ZW5zaW9uRWxlbWVudHMgPSBiby5nZXQoJ2V4dGVuc2lvbkVsZW1lbnRzJyk7XHJcbiAgICAgICAgaWYgKCFleHRlbnNpb25FbGVtZW50cykge1xyXG4gICAgICAgICAgZXh0ZW5zaW9uRWxlbWVudHMgPSBjcmVhdGVFeHRlbnNpb25FbGVtZW50cyhibywgYnBtbkZhY3RvcnkpO1xyXG4gICAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHsgZXh0ZW5zaW9uRWxlbWVudHM6IGV4dGVuc2lvbkVsZW1lbnRzIH0pKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHJ5VGltZUN5Y2xlID0gY3JlYXRlRmFpbGVkSm9iUmV0cnlUaW1lQ3ljbGUoZXh0ZW5zaW9uRWxlbWVudHMsIGJwbW5GYWN0b3J5LCBuZXdDeWNsZSk7XHJcbiAgICAgICAgY29tbWFuZHMucHVzaChjbWRIZWxwZXIuYWRkQW5kUmVtb3ZlRWxlbWVudHNGcm9tTGlzdChcclxuICAgICAgICAgIGVsZW1lbnQsXHJcbiAgICAgICAgICBleHRlbnNpb25FbGVtZW50cyxcclxuICAgICAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAgICAgJ2V4dGVuc2lvbkVsZW1lbnRzJyxcclxuICAgICAgICAgIFsgcmV0cnlUaW1lQ3ljbGUgXSxcclxuICAgICAgICAgIFtdXHJcbiAgICAgICAgKSk7XHJcblxyXG4gICAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gdXBkYXRlIGV4aXN0aW5nIHJldHJ5IHRpbWUgY3ljbGUgZWxlbWVudFxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHJldHJ5VGltZUN5Y2xlLCB7IGJvZHk6IG5ld0N5Y2xlIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICBoaWRkZW46IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAoYm8gJiYgKGlzQXN5bmNCZWZvcmUoYm8pIHx8IGlzQXN5bmNBZnRlcihibykpKSB7XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46RXZlbnQnKSkge1xyXG4gICAgICAgIHJldHVybiAhZXZlbnREZWZpbml0aW9uSGVscGVyLmdldFRpbWVyRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBbIHJldHJ5VGltZUN5Y2xlRW50cnkgXTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG52YXIgZXh0ZW5zaW9uRWxlbWVudHNFbnRyeSA9IHJlcXVpcmUoJy4vRXh0ZW5zaW9uRWxlbWVudHMnKSxcclxuICAgIGV4dGVuc2lvbkVsZW1lbnRzSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0V4dGVuc2lvbkVsZW1lbnRzSGVscGVyJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBlbGVtZW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0VsZW1lbnRIZWxwZXInKSxcclxuICAgIEltcGxlbWVudGF0aW9uVHlwZUhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9JbXBsZW1lbnRhdGlvblR5cGVIZWxwZXInKTtcclxuXHJcblxyXG5mdW5jdGlvbiBnZXRMaXN0ZW5lcnMoYm8sIHR5cGUpIHtcclxuICByZXR1cm4gYm8gJiYgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIuZ2V0RXh0ZW5zaW9uRWxlbWVudHMoYm8sIHR5cGUpIHx8IFtdO1xyXG59XHJcblxyXG52YXIgQUNUSVZJVElfRVhFQ1VUSU9OX0xJU1RFTkVSX0VMRU1FTlQgPSAnYWN0aXZpdGk6RXhlY3V0aW9uTGlzdGVuZXInO1xyXG52YXIgQUNUSVZJVElfVEFTS19MSVNURU5FUl9FTEVNRU5UID0gJ2FjdGl2aXRpOlRhc2tMaXN0ZW5lcic7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIExJU1RFTkVSX1RZUEVfTEFCRUwgPSB7XHJcbiAgICBjbGFzczogdHJhbnNsYXRlKCdKYXZhIENsYXNzJyksXHJcbiAgICBleHByZXNzaW9uOiB0cmFuc2xhdGUoJ0V4cHJlc3Npb24nKSxcclxuICAgIGRlbGVnYXRlRXhwcmVzc2lvbjogdHJhbnNsYXRlKCdEZWxlZ2F0ZSBFeHByZXNzaW9uJyksXHJcbiAgICBzY3JpcHQ6IHRyYW5zbGF0ZSgnU2NyaXB0JylcclxuICB9O1xyXG5cclxuICB2YXIgYm87XHJcblxyXG4gIHZhciByZXN1bHQgPSB7XHJcbiAgICBnZXRTZWxlY3RlZExpc3RlbmVyOiBnZXRTZWxlY3RlZExpc3RlbmVyXHJcbiAgfTtcclxuXHJcbiAgdmFyIGVudHJpZXMgPSByZXN1bHQuZW50cmllcyA9IFtdO1xyXG5cclxuICB2YXIgaXNTZXF1ZW5jZUZsb3cgPSBJbXBsZW1lbnRhdGlvblR5cGVIZWxwZXIuaXNTZXF1ZW5jZUZsb3coZWxlbWVudCk7XHJcblxyXG4gIGZ1bmN0aW9uIGdldFNlbGVjdGVkTGlzdGVuZXIoZWxlbWVudCwgbm9kZSkge1xyXG4gICAgdmFyIHNlbGVjdGlvbiA9IChleGVjdXRpb25MaXN0ZW5lckVudHJ5ICYmIGV4ZWN1dGlvbkxpc3RlbmVyRW50cnkuZ2V0U2VsZWN0ZWQoZWxlbWVudCwgbm9kZSkpIHx8IHsgaWR4OiAtMSB9O1xyXG5cclxuICAgIHZhciBsaXN0ZW5lciA9IGdldExpc3RlbmVycyhibywgQUNUSVZJVElfRVhFQ1VUSU9OX0xJU1RFTkVSX0VMRU1FTlQpW3NlbGVjdGlvbi5pZHhdO1xyXG4gICAgaWYgKCFsaXN0ZW5lciAmJiB0YXNrTGlzdGVuZXJFbnRyeSkge1xyXG4gICAgICBzZWxlY3Rpb24gPSB0YXNrTGlzdGVuZXJFbnRyeS5nZXRTZWxlY3RlZChlbGVtZW50LCBub2RlKTtcclxuICAgICAgbGlzdGVuZXIgPSBnZXRMaXN0ZW5lcnMoYm8sIEFDVElWSVRJX1RBU0tfTElTVEVORVJfRUxFTUVOVClbc2VsZWN0aW9uLmlkeF07XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbGlzdGVuZXI7XHJcbiAgfVxyXG5cclxuICB2YXIgc2V0T3B0aW9uTGFiZWxWYWx1ZSA9IGZ1bmN0aW9uKHR5cGUpIHtcclxuICAgIHJldHVybiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBvcHRpb24sIHByb3BlcnR5LCB2YWx1ZSwgaWR4KSB7XHJcbiAgICAgIHZhciBsaXN0ZW5lcnMgPSBnZXRMaXN0ZW5lcnMoYm8sIHR5cGUpO1xyXG4gICAgICB2YXIgbGlzdGVuZXIgPSBsaXN0ZW5lcnNbaWR4XTtcclxuICAgICAgdmFyIGxpc3RlbmVyVHlwZSA9IEltcGxlbWVudGF0aW9uVHlwZUhlbHBlci5nZXRJbXBsZW1lbnRhdGlvblR5cGUobGlzdGVuZXIpO1xyXG5cclxuICAgICAgdmFyIGV2ZW50ID0gKGxpc3RlbmVyLmdldCgnZXZlbnQnKSkgPyBsaXN0ZW5lci5nZXQoJ2V2ZW50JykgOiAnPGVtcHR5Pic7XHJcblxyXG4gICAgICB2YXIgbGFiZWwgPSAoZXZlbnQgfHwgJyonKSArICcgOiAnICsgKExJU1RFTkVSX1RZUEVfTEFCRUxbbGlzdGVuZXJUeXBlXSB8fCAnJyk7XHJcblxyXG4gICAgICBvcHRpb24udGV4dCA9IGxhYmVsO1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgbmV3RWxlbWVudCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHR5cGUsIGluaXRpYWxFdmVudCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIGV4dGVuc2lvbkVsZW1lbnRzLCB2YWx1ZSkge1xyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgZXZlbnQ6IGluaXRpYWxFdmVudCxcclxuICAgICAgICBjbGFzczogJydcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHZhciBuZXdFbGVtID0gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KHR5cGUsIHByb3BzLCBleHRlbnNpb25FbGVtZW50cywgYnBtbkZhY3RvcnkpO1xyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci5hZGRFbGVtZW50c1RvbGlzdChlbGVtZW50LCBleHRlbnNpb25FbGVtZW50cywgJ3ZhbHVlcycsIFsgbmV3RWxlbSBdKTtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgdmFyIHJlbW92ZUVsZW1lbnQgPSBmdW5jdGlvbihlbGVtZW50LCB0eXBlKSB7XHJcbiAgICByZXR1cm4gZnVuY3Rpb24oZWxlbWVudCwgZXh0ZW5zaW9uRWxlbWVudHMsIHZhbHVlLCBpZHgpIHtcclxuICAgICAgdmFyIGxpc3RlbmVycyA9IGdldExpc3RlbmVycyhibywgdHlwZSk7XHJcbiAgICAgIHZhciBsaXN0ZW5lciA9IGxpc3RlbmVyc1tpZHhdO1xyXG4gICAgICBpZiAobGlzdGVuZXIpIHtcclxuICAgICAgICByZXR1cm4gZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoYm8sIGVsZW1lbnQsIGxpc3RlbmVyKTtcclxuICAgICAgfVxyXG4gICAgfTtcclxuICB9O1xyXG5cclxuXHJcbiAgLy8gRXhlY3V0aW9uIExpc3RlbmVyXHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpGbG93RWxlbWVudCcpIHx8IGlzKGVsZW1lbnQsICdicG1uOlByb2Nlc3MnKSB8fCBpcyhlbGVtZW50LCAnYnBtbjpQYXJ0aWNpcGFudCcpKSB7XHJcbiAgICBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuICAgICAgZWxlbWVudCA9IGVsZW1lbnQucHJvY2Vzc1JlZjtcclxuICAgICAgYm8gPSBiby5nZXQoJ3Byb2Nlc3NSZWYnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoYm8pIHtcclxuXHJcbiAgICAgIHZhciBleGVjdXRpb25MaXN0ZW5lckVudHJ5ID0gZXh0ZW5zaW9uRWxlbWVudHNFbnRyeShlbGVtZW50LCBicG1uRmFjdG9yeSwge1xyXG4gICAgICAgIGlkIDogJ2V4ZWN1dGlvbkxpc3RlbmVycycsXHJcbiAgICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0V4ZWN1dGlvbiBMaXN0ZW5lcicpLFxyXG4gICAgICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuICAgICAgICBpZEdlbmVyYXRpb246ICdmYWxzZScsXHJcbiAgICAgICAgcmVmZXJlbmNlOiAncHJvY2Vzc1JlZicsXHJcblxyXG4gICAgICAgIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQ6IG5ld0VsZW1lbnQoZWxlbWVudCwgQUNUSVZJVElfRVhFQ1VUSU9OX0xJU1RFTkVSX0VMRU1FTlQsIChpc1NlcXVlbmNlRmxvdykgPyAndGFrZScgOiAnc3RhcnQnKSxcclxuICAgICAgICByZW1vdmVFeHRlbnNpb25FbGVtZW50OiByZW1vdmVFbGVtZW50KGVsZW1lbnQsIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUl9FTEVNRU5UKSxcclxuXHJcbiAgICAgICAgZ2V0RXh0ZW5zaW9uRWxlbWVudHM6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICAgIHJldHVybiBnZXRMaXN0ZW5lcnMoYm8sIEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUl9FTEVNRU5UKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBvblNlbGVjdGlvbkNoYW5nZTogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgZXZlbnQsIHNjb3BlKSB7XHJcbiAgICAgICAgICB0YXNrTGlzdGVuZXJFbnRyeSAmJiB0YXNrTGlzdGVuZXJFbnRyeS5kZXNlbGVjdChlbGVtZW50LCBub2RlKTtcclxuICAgICAgICB9LFxyXG5cclxuICAgICAgICBzZXRPcHRpb25MYWJlbFZhbHVlOiBzZXRPcHRpb25MYWJlbFZhbHVlKEFDVElWSVRJX0VYRUNVVElPTl9MSVNURU5FUl9FTEVNRU5UKVxyXG5cclxuICAgICAgfSk7XHJcbiAgICAgIGVudHJpZXMucHVzaChleGVjdXRpb25MaXN0ZW5lckVudHJ5KTtcclxuXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuXHJcbiAgLy8gVGFzayBMaXN0ZW5lclxyXG5cclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46VXNlclRhc2snKSkge1xyXG4gICAgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICB2YXIgdGFza0xpc3RlbmVyRW50cnkgPSBleHRlbnNpb25FbGVtZW50c0VudHJ5KGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB7XHJcbiAgICAgIGlkIDogJ3Rhc2tMaXN0ZW5lcnMnLFxyXG4gICAgICBsYWJlbCA6IHRyYW5zbGF0ZSgnVGFzayBMaXN0ZW5lcicpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5OiAnbmFtZScsXHJcbiAgICAgIGlkR2VuZXJhdGlvbjogJ2ZhbHNlJyxcclxuXHJcbiAgICAgIGNyZWF0ZUV4dGVuc2lvbkVsZW1lbnQ6IG5ld0VsZW1lbnQoZWxlbWVudCwgQUNUSVZJVElfVEFTS19MSVNURU5FUl9FTEVNRU5ULCAnY3JlYXRlJyksXHJcbiAgICAgIHJlbW92ZUV4dGVuc2lvbkVsZW1lbnQ6IHJlbW92ZUVsZW1lbnQoZWxlbWVudCwgQUNUSVZJVElfVEFTS19MSVNURU5FUl9FTEVNRU5UKSxcclxuXHJcbiAgICAgIGdldEV4dGVuc2lvbkVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGdldExpc3RlbmVycyhibywgQUNUSVZJVElfVEFTS19MSVNURU5FUl9FTEVNRU5UKTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIG9uU2VsZWN0aW9uQ2hhbmdlOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBldmVudCwgc2NvcGUpIHtcclxuICAgICAgICBleGVjdXRpb25MaXN0ZW5lckVudHJ5LmRlc2VsZWN0KGVsZW1lbnQsIG5vZGUpO1xyXG4gICAgICB9LFxyXG5cclxuICAgICAgc2V0T3B0aW9uTGFiZWxWYWx1ZTogc2V0T3B0aW9uTGFiZWxWYWx1ZShBQ1RJVklUSV9UQVNLX0xJU1RFTkVSX0VMRU1FTlQpXHJcblxyXG4gICAgfSk7XHJcbiAgICBlbnRyaWVzLnB1c2godGFza0xpc3RlbmVyRW50cnkpO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHJlc3VsdDtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBlc2NhcGVIVE1MID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vVXRpbHMnKS5lc2NhcGVIVE1MO1xyXG5cclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxudmFyIGRvbUNsYXNzZXMgPSByZXF1aXJlKCdtaW4tZG9tJykuY2xhc3NlcztcclxuXHJcbi8qKlxyXG4gKiBHZXQgYSBwcm9wZXJ0eSB2YWx1ZSBvZiB0aGUgbG9vcCBjaGFyYWN0ZXJpc3RpY3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtIHtzdHJpbmd9IHByb3BlcnR5TmFtZVxyXG4gKlxyXG4gKiBAcmV0dXJuIHthbnl9IHRoZSBwcm9wZXJ0eSB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UHJvcGVydHkoZWxlbWVudCwgcHJvcGVydHlOYW1lKSB7XHJcbiAgdmFyIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSBnZXRMb29wQ2hhcmFjdGVyaXN0aWNzKGVsZW1lbnQpO1xyXG4gIHJldHVybiBsb29wQ2hhcmFjdGVyaXN0aWNzICYmIGxvb3BDaGFyYWN0ZXJpc3RpY3MuZ2V0KHByb3BlcnR5TmFtZSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIGJvZHkgb2YgYSBnaXZlbiBleHByZXNzaW9uLlxyXG4gKlxyXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnQ8YnBtbjpGb3JtYWxFeHByZXNzaW9uPn0gZXhwcmVzc2lvblxyXG4gKlxyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSBib2R5ICh2YWx1ZSkgb2YgdGhlIGV4cHJlc3Npb25cclxuICovXHJcbmZ1bmN0aW9uIGdldEJvZHkoZXhwcmVzc2lvbikge1xyXG4gIHJldHVybiBleHByZXNzaW9uICYmIGV4cHJlc3Npb24uZ2V0KCdib2R5Jyk7XHJcbn1cclxuXHJcblxyXG4vKipcclxuICogR2V0IHRoZSBsb29wIGNoYXJhY3RlcmlzdGljcyBvZiBhbiBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnQ8YnBtbjpNdWx0aUluc3RhbmNlTG9vcENoYXJhY3RlcmlzdGljcz59IHRoZSBsb29wIGNoYXJhY3RlcmlzdGljc1xyXG4gKi9cclxuZnVuY3Rpb24gZ2V0TG9vcENoYXJhY3RlcmlzdGljcyhlbGVtZW50KSB7XHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgcmV0dXJuIGJvLmxvb3BDaGFyYWN0ZXJpc3RpY3M7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIGxvb3AgY2FyZGluYWxpdHkgb2YgdGhlIGxvb3AgY2hhcmFjdGVyaXN0aWNzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnQ8YnBtbjpGb3JtYWxFeHByZXNzaW9uPn0gYW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGxvb3AgY2FyZGluYWxpdHlcclxuICovXHJcbmZ1bmN0aW9uIGdldExvb3BDYXJkaW5hbGl0eShlbGVtZW50KSB7XHJcbiAgcmV0dXJuIGdldFByb3BlcnR5KGVsZW1lbnQsICdsb29wQ2FyZGluYWxpdHknKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgbG9vcCBjYXJkaW5hbGl0eSB2YWx1ZSBvZiB0aGUgbG9vcCBjaGFyYWN0ZXJpc3RpY3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgbG9vcCBjYXJkaW5hbGl0eSB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0TG9vcENhcmRpbmFsaXR5VmFsdWUoZWxlbWVudCkge1xyXG4gIHZhciBsb29wQ2FyZGluYWxpdHkgPSBnZXRMb29wQ2FyZGluYWxpdHkoZWxlbWVudCk7XHJcbiAgcmV0dXJuIGdldEJvZHkobG9vcENhcmRpbmFsaXR5KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgY29tcGxldGlvbiBjb25kaXRpb24gb2YgdGhlIGxvb3AgY2hhcmFjdGVyaXN0aWNzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge01vZGRsZUVsZW1lbnQ8YnBtbjpGb3JtYWxFeHByZXNzaW9uPn0gYW4gZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbXBsZXRpb24gY29uZGl0aW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRDb21wbGV0aW9uQ29uZGl0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gZ2V0UHJvcGVydHkoZWxlbWVudCwgJ2NvbXBsZXRpb25Db25kaXRpb24nKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgY29tcGxldGlvbiBjb25kaXRpb24gdmFsdWUgb2YgdGhlIGxvb3AgY2hhcmFjdGVyaXN0aWNzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqXHJcbiAqIEByZXR1cm4ge3N0cmluZ30gdGhlIGNvbXBsZXRpb24gY29uZGl0aW9uIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRDb21wbGV0aW9uQ29uZGl0aW9uVmFsdWUoZWxlbWVudCkge1xyXG4gIHZhciBjb21wbGV0aW9uQ29uZGl0aW9uID0gZ2V0Q29tcGxldGlvbkNvbmRpdGlvbihlbGVtZW50KTtcclxuICByZXR1cm4gZ2V0Qm9keShjb21wbGV0aW9uQ29uZGl0aW9uKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgJ2FjdGl2aXRpOmNvbGxlY3Rpb24nIGF0dHJpYnV0ZSB2YWx1ZSBvZiB0aGUgbG9vcCBjaGFyYWN0ZXJpc3RpY3MuXHJcbiAqXHJcbiAqIEBwYXJhbSB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7c3RyaW5nfSB0aGUgJ2FjdGl2aXRpOmNvbGxlY3Rpb24nIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRDb2xsZWN0aW9uKGVsZW1lbnQpIHtcclxuICByZXR1cm4gZ2V0UHJvcGVydHkoZWxlbWVudCwgJ2FjdGl2aXRpOmNvbGxlY3Rpb24nKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCB0aGUgJ2FjdGl2aXRpOmVsZW1lbnRWYXJpYWJsZScgYXR0cmlidXRlIHZhbHVlIG9mIHRoZSBsb29wIGNoYXJhY3RlcmlzdGljcy5cclxuICpcclxuICogQHBhcmFtIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IHRoZSAnYWN0aXZpdGk6ZWxlbWVudFZhcmlhYmxlJyB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0RWxlbWVudFZhcmlhYmxlKGVsZW1lbnQpIHtcclxuICByZXR1cm4gZ2V0UHJvcGVydHkoZWxlbWVudCwgJ2FjdGl2aXRpOmVsZW1lbnRWYXJpYWJsZScpO1xyXG59XHJcblxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZXMgJ2JwbW46Rm9ybWFsRXhwcmVzc2lvbicgZWxlbWVudC5cclxuICpcclxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBwYXJlbnRcclxuICogQHBhcmFtIHtzdHJpbmd9IGJvZHlcclxuICogQHBhcmFtIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICpcclxuICogQHJlc3VsdCB7TW9kZGxlRWxlbWVudDxicG1uOkZvcm1hbEV4cHJlc3Npb24+fSBhIGZvcm1hbCBleHByZXNzaW9uXHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVGb3JtYWxFeHByZXNzaW9uKHBhcmVudCwgYm9keSwgYnBtbkZhY3RvcnkpIHtcclxuICByZXR1cm4gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkZvcm1hbEV4cHJlc3Npb24nLCB7IGJvZHk6IGJvZHkgfSwgcGFyZW50LCBicG1uRmFjdG9yeSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBVcGRhdGVzIGEgc3BlY2lmaWMgZm9ybWFsIGV4cHJlc3Npb24gb2YgdGhlIGxvb3AgY2hhcmFjdGVyaXN0aWNzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wZXJ0eU5hbWVcclxuICogQHBhcmFtIHtzdHJpbmd9IG5ld1ZhbHVlXHJcbiAqIEBwYXJhbSB7QnBtbkZhY3Rvcnl9IGJwbW5GYWN0b3J5XHJcbiAqL1xyXG5mdW5jdGlvbiB1cGRhdGVGb3JtYWxFeHByZXNzaW9uKGVsZW1lbnQsIHByb3BlcnR5TmFtZSwgbmV3VmFsdWUsIGJwbW5GYWN0b3J5KSB7XHJcbiAgdmFyIGxvb3BDaGFyYWN0ZXJpc3RpY3MgPSBnZXRMb29wQ2hhcmFjdGVyaXN0aWNzKGVsZW1lbnQpO1xyXG5cclxuICB2YXIgZXhwcmVzc2lvblByb3BzID0ge307XHJcblxyXG4gIGlmICghbmV3VmFsdWUpIHtcclxuICAgIC8vIHJlbW92ZSBmb3JtYWwgZXhwcmVzc2lvblxyXG4gICAgZXhwcmVzc2lvblByb3BzW3Byb3BlcnR5TmFtZV0gPSB1bmRlZmluZWQ7XHJcbiAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGxvb3BDaGFyYWN0ZXJpc3RpY3MsIGV4cHJlc3Npb25Qcm9wcyk7XHJcbiAgfVxyXG5cclxuICB2YXIgZXhpc3RpbmdFeHByZXNzaW9uID0gbG9vcENoYXJhY3RlcmlzdGljcy5nZXQocHJvcGVydHlOYW1lKTtcclxuXHJcbiAgaWYgKCFleGlzdGluZ0V4cHJlc3Npb24pIHtcclxuICAgIC8vIGFkZCBmb3JtYWwgZXhwcmVzc2lvblxyXG4gICAgZXhwcmVzc2lvblByb3BzW3Byb3BlcnR5TmFtZV0gPSBjcmVhdGVGb3JtYWxFeHByZXNzaW9uKGxvb3BDaGFyYWN0ZXJpc3RpY3MsIG5ld1ZhbHVlLCBicG1uRmFjdG9yeSk7XHJcbiAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGxvb3BDaGFyYWN0ZXJpc3RpY3MsIGV4cHJlc3Npb25Qcm9wcyk7XHJcbiAgfVxyXG5cclxuICAvLyBlZGl0IGV4aXN0aW5nIGZvcm1hbCBleHByZXNzaW9uXHJcbiAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBleGlzdGluZ0V4cHJlc3Npb24sIHtcclxuICAgIGJvZHk6IG5ld1ZhbHVlXHJcbiAgfSk7XHJcbn1cclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGVudHJpZXMgPSBbXTtcclxuXHJcbiAgLy8gZXJyb3IgbWVzc2FnZSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBlbnRyaWVzLnB1c2goe1xyXG4gICAgaWQ6ICdtdWx0aUluc3RhbmNlLWVycm9yTWVzc2FnZScsXHJcbiAgICBodG1sOiAnPGRpdiBkYXRhLXNob3c9XCJpc1ZhbGlkXCI+JyArXHJcbiAgICAgICAgICAgICAnPHNwYW4gY2xhc3M9XCJicHAtaWNvbi13YXJuaW5nXCI+PC9zcGFuPiAnICtcclxuICAgICAgICAgICAgIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdNdXN0IHByb3ZpZGUgZWl0aGVyIGxvb3AgY2FyZGluYWxpdHkgb3IgY29sbGVjdGlvbicpKSArXHJcbiAgICAgICAgICAnPC9kaXY+JyxcclxuXHJcbiAgICBpc1ZhbGlkOiBmdW5jdGlvbihlbGVtZW50LCBub2RlLCBub3RpZmljYXRpb24sIHNjb3BlKSB7XHJcbiAgICAgIHZhciBsb29wQ2hhcmFjdGVyaXN0aWNzID0gZ2V0TG9vcENoYXJhY3RlcmlzdGljcyhlbGVtZW50KTtcclxuXHJcbiAgICAgIHZhciBpc1ZhbGlkID0gdHJ1ZTtcclxuICAgICAgaWYgKGxvb3BDaGFyYWN0ZXJpc3RpY3MpIHtcclxuICAgICAgICB2YXIgbG9vcENhcmRpbmFsaXR5ID0gZ2V0TG9vcENhcmRpbmFsaXR5VmFsdWUoZWxlbWVudCk7XHJcbiAgICAgICAgdmFyIGNvbGxlY3Rpb24gPSBnZXRDb2xsZWN0aW9uKGVsZW1lbnQpO1xyXG5cclxuICAgICAgICBpc1ZhbGlkID0gIWxvb3BDYXJkaW5hbGl0eSAmJiAhY29sbGVjdGlvbjtcclxuICAgICAgfVxyXG5cclxuICAgICAgZG9tQ2xhc3Nlcyhub2RlKS50b2dnbGUoJ2JwcC1oaWRkZW4nLCAhaXNWYWxpZCk7XHJcbiAgICAgIGRvbUNsYXNzZXMobm90aWZpY2F0aW9uKS50b2dnbGUoJ2JwcC1lcnJvci1tZXNzYWdlJywgaXNWYWxpZCk7XHJcblxyXG4gICAgICByZXR1cm4gaXNWYWxpZDtcclxuICAgIH1cclxuICB9KTtcclxuXHJcbiAgLy8gbG9vcCBjYXJkaW5hbGl0eSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ211bHRpSW5zdGFuY2UtbG9vcENhcmRpbmFsaXR5JyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0xvb3AgQ2FyZGluYWxpdHknKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdsb29wQ2FyZGluYWxpdHknLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxvb3BDYXJkaW5hbGl0eTogZ2V0TG9vcENhcmRpbmFsaXR5VmFsdWUoZWxlbWVudClcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgcmV0dXJuIHVwZGF0ZUZvcm1hbEV4cHJlc3Npb24oZWxlbWVudCwgJ2xvb3BDYXJkaW5hbGl0eScsIHZhbHVlcy5sb29wQ2FyZGluYWxpdHksIGJwbW5GYWN0b3J5KTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG5cclxuICAvLyBjb2xsZWN0aW9uIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xyXG5cclxuICBlbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ211bHRpSW5zdGFuY2UtY29sbGVjdGlvbicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdDb2xsZWN0aW9uJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnY29sbGVjdGlvbicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgY29sbGVjdGlvbjogZ2V0Q29sbGVjdGlvbihlbGVtZW50KVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgbG9vcENoYXJhY3RlcmlzdGljcyA9IGdldExvb3BDaGFyYWN0ZXJpc3RpY3MoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgbG9vcENoYXJhY3RlcmlzdGljcywge1xyXG4gICAgICAgICdhY3Rpdml0aTpjb2xsZWN0aW9uJzogdmFsdWVzLmNvbGxlY3Rpb24gfHwgdW5kZWZpbmVkXHJcbiAgICAgIH0pO1xyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciBjb2xsZWN0aW9uID0gZ2V0Q29sbGVjdGlvbihlbGVtZW50KTtcclxuICAgICAgdmFyIGVsZW1lbnRWYXJpYWJsZSA9IGdldEVsZW1lbnRWYXJpYWJsZShlbGVtZW50KTtcclxuXHJcbiAgICAgIGlmICghY29sbGVjdGlvbiAmJiBlbGVtZW50VmFyaWFibGUpIHtcclxuICAgICAgICByZXR1cm4geyBjb2xsZWN0aW9uIDogJ011c3QgcHJvdmlkZSBhIHZhbHVlJyB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgLy8gZWxlbWVudCB2YXJpYWJsZSAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdtdWx0aUluc3RhbmNlLWVsZW1lbnRWYXJpYWJsZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdFbGVtZW50IFZhcmlhYmxlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZWxlbWVudFZhcmlhYmxlJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBlbGVtZW50VmFyaWFibGU6IGdldEVsZW1lbnRWYXJpYWJsZShlbGVtZW50KVxyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgbG9vcENoYXJhY3RlcmlzdGljcyA9IGdldExvb3BDaGFyYWN0ZXJpc3RpY3MoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgbG9vcENoYXJhY3RlcmlzdGljcywge1xyXG4gICAgICAgICdhY3Rpdml0aTplbGVtZW50VmFyaWFibGUnOiB2YWx1ZXMuZWxlbWVudFZhcmlhYmxlIHx8IHVuZGVmaW5lZFxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9KSk7XHJcblxyXG5cclxuICAvLyBDb21wbGV0aW9uIENvbmRpdGlvbiAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cclxuXHJcbiAgZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6ICdtdWx0aUluc3RhbmNlLWNvbXBsZXRpb25Db25kaXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQ29tcGxldGlvbiBDb25kaXRpb24nKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdjb21wbGV0aW9uQ29uZGl0aW9uJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBjb21wbGV0aW9uQ29uZGl0aW9uOiBnZXRDb21wbGV0aW9uQ29uZGl0aW9uVmFsdWUoZWxlbWVudClcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgcmV0dXJuIHVwZGF0ZUZvcm1hbEV4cHJlc3Npb24oZWxlbWVudCwgJ2NvbXBsZXRpb25Db25kaXRpb24nLCB2YWx1ZXMuY29tcGxldGlvbkNvbmRpdGlvbiwgYnBtbkZhY3RvcnkpO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbiAgcmV0dXJuIGVudHJpZXM7XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzO1xyXG5cclxudmFyIGZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRXh0ZW5zaW9uRWxlbWVudHNIZWxwZXInKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKSxcclxuICAgIHV0aWxzID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vVXRpbHMnKTtcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyksXHJcbiAgICBmb3JFYWNoID0gcmVxdWlyZSgnbG9kYXNoL2ZvckVhY2gnKSxcclxuICAgIGZpbmQgPSByZXF1aXJlKCdsb2Rhc2gvZmluZCcpO1xyXG5cclxuZnVuY3Rpb24gZ2VuZXJhdGVQcm9wZXJ0eUlkKCkge1xyXG4gIHJldHVybiB1dGlscy5uZXh0SWQoJ1Byb3BlcnR5XycpO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0IGFsbCBhY3Rpdml0aTpwcm9wZXJ0eSBvYmplY3RzIGZvciBhIHNwZWNpZmljIGJ1c2luZXNzIG9iamVjdFxyXG4gKlxyXG4gKiBAcGFyYW0gIHtNb2RkbGVFbGVtZW50fSBwYXJlbnRcclxuICpcclxuICogQHJldHVybiB7QXJyYXk8TW9kZGxlRWxlbWVudD59IGEgbGlzdCBvZiBhY3Rpdml0aTpwcm9wZXJ0eSBvYmplY3RzXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRQcm9wZXJ0eVZhbHVlcyhwYXJlbnQpIHtcclxuICB2YXIgcHJvcGVydGllcyA9IHBhcmVudCAmJiBnZXRQcm9wZXJ0aWVzRWxlbWVudChwYXJlbnQpO1xyXG4gIGlmIChwcm9wZXJ0aWVzICYmIHByb3BlcnRpZXMudmFsdWVzKSB7XHJcbiAgICByZXR1cm4gcHJvcGVydGllcy52YWx1ZXM7XHJcbiAgfVxyXG4gIHJldHVybiBbXTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldCBhbGwgYWN0aXZpdGk6UHJvcGVydGllcyBvYmplY3QgZm9yIGEgc3BlY2lmaWMgYnVzaW5lc3Mgb2JqZWN0XHJcbiAqXHJcbiAqIEBwYXJhbSAge01vZGRsZUVsZW1lbnR9IHBhcmVudFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50fSBhIGFjdGl2aXRpOlByb3BlcnRpZXMgb2JqZWN0XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRQcm9wZXJ0aWVzRWxlbWVudChlbGVtZW50KSB7XHJcbiAgaWYgKCFpc0V4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQpKSB7XHJcbiAgICByZXR1cm4gZWxlbWVudC5wcm9wZXJ0aWVzO1xyXG4gIH0gZWxzZSB7XHJcbiAgICByZXR1cm4gZ2V0UHJvcGVydGllc0VsZW1lbnRJbnNpZGVFeHRlbnNpb25FbGVtZW50cyhlbGVtZW50KTtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgZmlyc3QgYWN0aXZpdGk6UHJvcGVydGllcyBvYmplY3QgZm9yIGEgc3BlY2lmaWMgYnBtbjpFeHRlbnNpb25FbGVtZW50c1xyXG4gKiBidXNpbmVzcyBvYmplY3QuXHJcbiAqXHJcbiAqIEBwYXJhbSB7TW9kZGxlRWxlbWVudH0gZXh0ZW5zaW9uRWxlbWVudHNcclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gYSBhY3Rpdml0aTpQcm9wZXJ0aWVzIG9iamVjdFxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0UHJvcGVydGllc0VsZW1lbnRJbnNpZGVFeHRlbnNpb25FbGVtZW50cyhleHRlbnNpb25FbGVtZW50cykge1xyXG4gIHJldHVybiBmaW5kKGV4dGVuc2lvbkVsZW1lbnRzLnZhbHVlcywgZnVuY3Rpb24oZWxlbSkge1xyXG4gICAgcmV0dXJuIGlzKGVsZW0sICdhY3Rpdml0aTpQcm9wZXJ0aWVzJyk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRydWUsIGlmIHRoZSBnaXZlbiBidXNpbmVzcyBvYmplY3QgaXMgYSBicG1uOkV4dGVuc2lvbkVsZW1lbnRzLlxyXG4gKlxyXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7Ym9vbGVhbn0gYSBib29sZWFuIHZhbHVlXHJcbiAqL1xyXG5mdW5jdGlvbiBpc0V4dGVuc2lvbkVsZW1lbnRzKGVsZW1lbnQpIHtcclxuICByZXR1cm4gaXMoZWxlbWVudCwgJ2JwbW46RXh0ZW5zaW9uRWxlbWVudHMnKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhIGFjdGl2aXRpOnByb3BlcnR5IGVudHJ5IHVzaW5nIHRhYmxlRW50cnlGYWN0b3J5XHJcbiAqXHJcbiAqIEBwYXJhbSAge2Rqcy5tb2RlbC5CYXNlfSBlbGVtZW50XHJcbiAqIEBwYXJhbSAge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmlkXHJcbiAqIEBwYXJhbSAge0FycmF5PHN0cmluZz59IG9wdGlvbnMubW9kZWxQcm9wZXJ0aWVzXHJcbiAqIEBwYXJhbSAge0FycmF5PHN0cmluZz59IG9wdGlvbnMubGFiZWxzXHJcbiAqIEBwYXJhbSAge2Z1bmN0aW9ufSBvcHRpb25zLmdldFBhcmVudCBHZXRzIHRoZSBwYXJlbnQgYnVzaW5lc3Mgb2JqZWN0XHJcbiAqIEBwYXJhbSAge2Z1bmN0aW9ufSBvcHRpb25zLnNob3cgSW5kaWNhdGUgd2hlbiB0aGUgZW50cnkgd2lsbCBiZSBzaG93biwgc2hvdWxkIHJldHVybiBib29sZWFuXHJcbiAqL1xyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldFBhcmVudCA9IG9wdGlvbnMuZ2V0UGFyZW50O1xyXG5cclxuICB2YXIgbW9kZWxQcm9wZXJ0aWVzID0gb3B0aW9ucy5tb2RlbFByb3BlcnRpZXMsXHJcbiAgICAgIGNyZWF0ZVBhcmVudCA9IG9wdGlvbnMuY3JlYXRlUGFyZW50O1xyXG5cclxuICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgYm8gPSBiby5nZXQoJ3Byb2Nlc3NSZWYnKTtcclxuICB9XHJcblxyXG4gIC8vIGJ1aWxkIHByb3BlcnRpZXMgZ3JvdXAgb25seSB3aGVuIHRoZSBwYXJ0aWNpcGFudCBoYXZlIGEgcHJvY2Vzc1JlZlxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGFzc2lnbihvcHRpb25zLCB7XHJcbiAgICBhZGRMYWJlbDogdHJhbnNsYXRlKCdBZGQgUHJvcGVydHknKSxcclxuICAgIGdldEVsZW1lbnRzOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBwYXJlbnQgPSBnZXRQYXJlbnQoZWxlbWVudCwgbm9kZSwgYm8pO1xyXG4gICAgICByZXR1cm4gZ2V0UHJvcGVydHlWYWx1ZXMocGFyZW50KTtcclxuICAgIH0sXHJcbiAgICBhZGRFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdLFxyXG4gICAgICAgICAgcGFyZW50ID0gZ2V0UGFyZW50KGVsZW1lbnQsIG5vZGUsIGJvKTtcclxuXHJcbiAgICAgIGlmICghcGFyZW50ICYmIHR5cGVvZiBjcmVhdGVQYXJlbnQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gY3JlYXRlUGFyZW50KGVsZW1lbnQsIGJvKTtcclxuICAgICAgICBwYXJlbnQgPSByZXN1bHQucGFyZW50O1xyXG4gICAgICAgIGNvbW1hbmRzLnB1c2gocmVzdWx0LmNtZCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBwcm9wZXJ0aWVzID0gZ2V0UHJvcGVydGllc0VsZW1lbnQocGFyZW50KTtcclxuICAgICAgaWYgKCFwcm9wZXJ0aWVzKSB7XHJcbiAgICAgICAgcHJvcGVydGllcyA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6UHJvcGVydGllcycsIHt9LCBwYXJlbnQsIGJwbW5GYWN0b3J5KTtcclxuXHJcbiAgICAgICAgaWYgKCFpc0V4dGVuc2lvbkVsZW1lbnRzKHBhcmVudCkpIHtcclxuICAgICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHBhcmVudCwgeyAncHJvcGVydGllcyc6IHByb3BlcnRpZXMgfSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5hZGRBbmRSZW1vdmVFbGVtZW50c0Zyb21MaXN0KFxyXG4gICAgICAgICAgICBlbGVtZW50LFxyXG4gICAgICAgICAgICBwYXJlbnQsXHJcbiAgICAgICAgICAgICd2YWx1ZXMnLFxyXG4gICAgICAgICAgICAnZXh0ZW5zaW9uRWxlbWVudHMnLFxyXG4gICAgICAgICAgICBbIHByb3BlcnRpZXMgXSxcclxuICAgICAgICAgICAgW11cclxuICAgICAgICAgICkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHByb3BlcnR5UHJvcHMgPSB7fTtcclxuICAgICAgZm9yRWFjaChtb2RlbFByb3BlcnRpZXMsIGZ1bmN0aW9uKHByb3ApIHtcclxuICAgICAgICBwcm9wZXJ0eVByb3BzW3Byb3BdID0gdW5kZWZpbmVkO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIGNyZWF0ZSBpZCBpZiBuZWNlc3NhcnlcclxuICAgICAgaWYgKG1vZGVsUHJvcGVydGllcy5pbmRleE9mKCdpZCcpID49IDApIHtcclxuICAgICAgICBwcm9wZXJ0eVByb3BzLmlkID0gZ2VuZXJhdGVQcm9wZXJ0eUlkKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHZhciBwcm9wZXJ0eSA9IGVsZW1lbnRIZWxwZXIuY3JlYXRlRWxlbWVudCgnYWN0aXZpdGk6UHJvcGVydHknLCBwcm9wZXJ0eVByb3BzLCBwcm9wZXJ0aWVzLCBicG1uRmFjdG9yeSk7XHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLmFkZEVsZW1lbnRzVG9saXN0KGVsZW1lbnQsIHByb3BlcnRpZXMsICd2YWx1ZXMnLCBbIHByb3BlcnR5IF0pKTtcclxuXHJcbiAgICAgIHJldHVybiBjb21tYW5kcztcclxuICAgIH0sXHJcbiAgICB1cGRhdGVFbGVtZW50OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZSwgbm9kZSwgaWR4KSB7XHJcbiAgICAgIHZhciBwYXJlbnQgPSBnZXRQYXJlbnQoZWxlbWVudCwgbm9kZSwgYm8pLFxyXG4gICAgICAgICAgcHJvcGVydHkgPSBnZXRQcm9wZXJ0eVZhbHVlcyhwYXJlbnQpW2lkeF07XHJcblxyXG4gICAgICBmb3JFYWNoKG1vZGVsUHJvcGVydGllcywgZnVuY3Rpb24ocHJvcCkge1xyXG4gICAgICAgIHZhbHVlW3Byb3BdID0gdmFsdWVbcHJvcF0gfHwgdW5kZWZpbmVkO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgcHJvcGVydHksIHZhbHVlKTtcclxuICAgIH0sXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWUsIG5vZGUsIGlkeCkge1xyXG4gICAgICAvLyB2YWxpZGF0ZSBpZCBpZiBuZWNlc3NhcnlcclxuICAgICAgaWYgKG1vZGVsUHJvcGVydGllcy5pbmRleE9mKCdpZCcpID49IDApIHtcclxuXHJcbiAgICAgICAgdmFyIHBhcmVudCA9IGdldFBhcmVudChlbGVtZW50LCBub2RlLCBibyksXHJcbiAgICAgICAgICAgIHByb3BlcnRpZXMgPSBnZXRQcm9wZXJ0eVZhbHVlcyhwYXJlbnQpLFxyXG4gICAgICAgICAgICBwcm9wZXJ0eSA9IHByb3BlcnRpZXNbaWR4XTtcclxuXHJcbiAgICAgICAgaWYgKHByb3BlcnR5KSB7XHJcbiAgICAgICAgICAvLyBjaGVjayBpZiBpZCBpcyB2YWxpZFxyXG4gICAgICAgICAgdmFyIHZhbGlkYXRpb25FcnJvciA9IHV0aWxzLmlzSWRWYWxpZChwcm9wZXJ0eSwgdmFsdWUuaWQsIHRyYW5zbGF0ZSk7XHJcblxyXG4gICAgICAgICAgaWYgKHZhbGlkYXRpb25FcnJvcikge1xyXG4gICAgICAgICAgICByZXR1cm4geyBpZDogdmFsaWRhdGlvbkVycm9yIH07XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAgcmVtb3ZlRWxlbWVudDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSwgaWR4KSB7XHJcbiAgICAgIHZhciBjb21tYW5kcyA9IFtdLFxyXG4gICAgICAgICAgcGFyZW50ID0gZ2V0UGFyZW50KGVsZW1lbnQsIG5vZGUsIGJvKSxcclxuICAgICAgICAgIHByb3BlcnRpZXMgPSBnZXRQcm9wZXJ0aWVzRWxlbWVudChwYXJlbnQpLFxyXG4gICAgICAgICAgcHJvcGVydHlWYWx1ZXMgPSBnZXRQcm9wZXJ0eVZhbHVlcyhwYXJlbnQpLFxyXG4gICAgICAgICAgY3VycmVudFByb3BlcnR5ID0gcHJvcGVydHlWYWx1ZXNbaWR4XTtcclxuXHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnJlbW92ZUVsZW1lbnRzRnJvbUxpc3QoZWxlbWVudCwgcHJvcGVydGllcywgJ3ZhbHVlcycsIG51bGwsIFsgY3VycmVudFByb3BlcnR5IF0pKTtcclxuXHJcbiAgICAgIGlmIChwcm9wZXJ0eVZhbHVlcy5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICAvLyByZW1vdmUgYWN0aXZpdGk6cHJvcGVydGllcyBpZiB0aGUgbGFzdCBleGlzdGluZyBwcm9wZXJ0eSBoYXMgYmVlbiByZW1vdmVkXHJcbiAgICAgICAgaWYgKCFpc0V4dGVuc2lvbkVsZW1lbnRzKHBhcmVudCkpIHtcclxuICAgICAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIHBhcmVudCwgeyBwcm9wZXJ0aWVzOiB1bmRlZmluZWQgfSkpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBmb3JFYWNoKHBhcmVudC52YWx1ZXMsIGZ1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIGlmIChpcyh2YWx1ZSwgJ2FjdGl2aXRpOlByb3BlcnRpZXMnKSkge1xyXG4gICAgICAgICAgICAgIGNvbW1hbmRzLnB1c2goZXh0ZW5zaW9uRWxlbWVudHNIZWxwZXIucmVtb3ZlRW50cnkoYm8sIGVsZW1lbnQsIHZhbHVlKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNvbW1hbmRzO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gZmFjdG9yeS50YWJsZShvcHRpb25zKTtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcztcclxuXHJcbnZhciBhc3NpZ24gPSByZXF1aXJlKCdsb2Rhc2gvYXNzaWduJyk7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKSxcclxuICAgIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgYnBtbkZhY3RvcnksIG9wdGlvbnMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSBvcHRpb25zLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgICBoaWRlUmVzdWx0VmFyaWFibGUgPSBvcHRpb25zLmhpZGVSZXN1bHRWYXJpYWJsZSxcclxuICAgICAgaWQgPSBvcHRpb25zLmlkIHx8ICdyZXN1bHRWYXJpYWJsZSc7XHJcblxyXG5cclxuICB2YXIgcmVzdWx0VmFyaWFibGVFbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6IGlkLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnUmVzdWx0IFZhcmlhYmxlJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAncmVzdWx0VmFyaWFibGUnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgcmV0dXJuIHsgcmVzdWx0VmFyaWFibGU6IGJvLmdldCgnYWN0aXZpdGk6cmVzdWx0VmFyaWFibGUnKSB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcywgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuXHJcbiAgICAgIHZhciByZXN1bHRWYXJpYWJsZSA9IHZhbHVlcy5yZXN1bHRWYXJpYWJsZSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOnJlc3VsdFZhcmlhYmxlJzogcmVzdWx0VmFyaWFibGVcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlmIChpcyhibywgJ2FjdGl2aXRpOkRtbkNhcGFibGUnKSAmJiAhcmVzdWx0VmFyaWFibGUpIHtcclxuICAgICAgICBwcm9wcyA9IGFzc2lnbih7ICdhY3Rpdml0aTptYXBEZWNpc2lvblJlc3VsdCc6ICdyZXN1bHRMaXN0JyB9LCBwcm9wcyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIGlmICh0eXBlb2YgaGlkZVJlc3VsdFZhcmlhYmxlID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgcmV0dXJuIGhpZGVSZXN1bHRWYXJpYWJsZS5hcHBseShyZXN1bHRWYXJpYWJsZUVudHJ5LCBhcmd1bWVudHMpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gWyByZXN1bHRWYXJpYWJsZUVudHJ5IF07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnksXHJcbiAgICBlc2NhcGVIVE1MID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vVXRpbHMnKS5lc2NhcGVIVE1MLFxyXG4gICAgdXRpbHMgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9VdGlscycpO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGdldFNjcmlwdFR5cGUobm9kZSkge1xyXG4gIHJldHVybiB1dGlscy5zZWxlY3RlZFR5cGUoJ3NlbGVjdFtuYW1lPXNjcmlwdFR5cGVdJywgbm9kZS5wYXJlbnRFbGVtZW50KTtcclxufVxyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc2NyaXB0TGFuZ3VhZ2VQcm9wTmFtZSwgc2NyaXB0VmFsdWVQcm9wTmFtZSwgaXNGb3JtYXRSZXF1aXJlZCwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHJldHVybiB7XHJcbiAgICB0ZW1wbGF0ZTpcclxuICAgICc8ZGl2IGNsYXNzPVwiYnBwLXJvdyBicHAtdGV4dGZpZWxkXCI+JyArXHJcbiAgICAgICc8bGFiZWwgZm9yPVwiY2FtLXNjcmlwdC1mb3JtYXRcIj4nICsgZXNjYXBlSFRNTCh0cmFuc2xhdGUoJ1NjcmlwdCBGb3JtYXQnKSkgKyAnPC9sYWJlbD4nICtcclxuICAgICAgJzxkaXYgY2xhc3M9XCJicHAtZmllbGQtd3JhcHBlclwiPicgK1xyXG4gICAgICAgICc8aW5wdXQgaWQ9XCJjYW0tc2NyaXB0LWZvcm1hdFwiIHR5cGU9XCJ0ZXh0XCIgbmFtZT1cInNjcmlwdEZvcm1hdFwiIC8+JyArXHJcbiAgICAgICAgJzxidXR0b24gY2xhc3M9XCJjbGVhclwiIGRhdGEtYWN0aW9uPVwic2NyaXB0LmNsZWFyU2NyaXB0Rm9ybWF0XCIgZGF0YS1zaG93PVwic2NyaXB0LmNhbkNsZWFyU2NyaXB0Rm9ybWF0XCI+JyArXHJcbiAgICAgICAgICAnPHNwYW4+WDwvc3Bhbj4nICtcclxuICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICc8L2Rpdj4nICtcclxuICAgICc8L2Rpdj4nICtcclxuXHJcbiAgICAnPGRpdiBjbGFzcz1cImJwcC1yb3dcIj4nICtcclxuICAgICAgJzxsYWJlbCBmb3I9XCJjYW0tc2NyaXB0LXR5cGVcIj4nICsgZXNjYXBlSFRNTCh0cmFuc2xhdGUoJ1NjcmlwdCBUeXBlJykpICsgJzwvbGFiZWw+JyArXHJcbiAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXJcIj4nICtcclxuICAgICAgICAnPHNlbGVjdCBpZD1cImNhbS1zY3JpcHQtdHlwZVwiIG5hbWU9XCJzY3JpcHRUeXBlXCIgZGF0YS12YWx1ZT4nICtcclxuICAgICAgICAgICc8b3B0aW9uIHZhbHVlPVwic2NyaXB0XCIgc2VsZWN0ZWQ+JyArIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdJbmxpbmUgU2NyaXB0JykpICsgJzwvb3B0aW9uPicgK1xyXG4gICAgICAgICAgJzxvcHRpb24gdmFsdWU9XCJzY3JpcHRSZXNvdXJjZVwiPicgKyBlc2NhcGVIVE1MKHRyYW5zbGF0ZSgnRXh0ZXJuYWwgUmVzb3VyY2UnKSkgKyAnPC9vcHRpb24+JyArXHJcbiAgICAgICAgJzwvc2VsZWN0PicgK1xyXG4gICAgICAnPC9kaXY+JyArXHJcbiAgICAnPC9kaXY+JyArXHJcblxyXG4gICAgJzxkaXYgY2xhc3M9XCJicHAtcm93IGJwcC10ZXh0ZmllbGRcIj4nICtcclxuICAgICAgJzxsYWJlbCBmb3I9XCJjYW0tc2NyaXB0LXJlc291cmNlLXZhbFwiIGRhdGEtc2hvdz1cInNjcmlwdC5pc1NjcmlwdFJlc291cmNlXCI+JyArIGVzY2FwZUhUTUwodHJhbnNsYXRlKCdSZXNvdXJjZScpKSArICc8L2xhYmVsPicgK1xyXG4gICAgICAnPGRpdiBjbGFzcz1cImJwcC1maWVsZC13cmFwcGVyXCIgZGF0YS1zaG93PVwic2NyaXB0LmlzU2NyaXB0UmVzb3VyY2VcIj4nICtcclxuICAgICAgICAnPGlucHV0IGlkPVwiY2FtLXNjcmlwdC1yZXNvdXJjZS12YWxcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJzY3JpcHRSZXNvdXJjZVZhbHVlXCIgLz4nICtcclxuICAgICAgICAnPGJ1dHRvbiBjbGFzcz1cImNsZWFyXCIgZGF0YS1hY3Rpb249XCJzY3JpcHQuY2xlYXJTY3JpcHRSZXNvdXJjZVwiIGRhdGEtc2hvdz1cInNjcmlwdC5jYW5DbGVhclNjcmlwdFJlc291cmNlXCI+JyArXHJcbiAgICAgICAgICAnPHNwYW4+WDwvc3Bhbj4nICtcclxuICAgICAgICAnPC9idXR0b24+JyArXHJcbiAgICAgICc8L2Rpdj4nICtcclxuICAgICc8L2Rpdj4nICtcclxuXHJcbiAgICAnPGRpdiBjbGFzcz1cImJwcC1yb3dcIj4nICtcclxuICAgICAgJzxsYWJlbCBmb3I9XCJjYW0tc2NyaXB0LXZhbFwiIGRhdGEtc2hvdz1cInNjcmlwdC5pc1NjcmlwdFwiPicgKyBlc2NhcGVIVE1MKHRyYW5zbGF0ZSgnU2NyaXB0JykpICsgJzwvbGFiZWw+JyArXHJcbiAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXJcIiBkYXRhLXNob3c9XCJzY3JpcHQuaXNTY3JpcHRcIj4nICtcclxuICAgICAgICAnPHRleHRhcmVhIGlkPVwiY2FtLXNjcmlwdC12YWxcIiB0eXBlPVwidGV4dFwiIG5hbWU9XCJzY3JpcHRWYWx1ZVwiPjwvdGV4dGFyZWE+JyArXHJcbiAgICAgICc8L2Rpdj4nK1xyXG4gICAgJzwvZGl2PicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBibykge1xyXG4gICAgICB2YXIgdmFsdWVzID0ge307XHJcblxyXG4gICAgICAvLyByZWFkIHZhbHVlcyBmcm9tIHhtbDpcclxuICAgICAgdmFyIGJvU2NyaXB0UmVzb3VyY2UgPSBiby5nZXQoJ2FjdGl2aXRpOnJlc291cmNlJyksXHJcbiAgICAgICAgICBib1NjcmlwdCA9IGJvLmdldChzY3JpcHRWYWx1ZVByb3BOYW1lKSxcclxuICAgICAgICAgIGJvU2NyaXB0Rm9ybWF0ID0gYm8uZ2V0KHNjcmlwdExhbmd1YWdlUHJvcE5hbWUpO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiBib1NjcmlwdFJlc291cmNlICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHZhbHVlcy5zY3JpcHRSZXNvdXJjZVZhbHVlID0gYm9TY3JpcHRSZXNvdXJjZTtcclxuICAgICAgICB2YWx1ZXMuc2NyaXB0VHlwZSA9ICdzY3JpcHRSZXNvdXJjZSc7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFsdWVzLnNjcmlwdFZhbHVlID0gYm9TY3JpcHQ7XHJcbiAgICAgICAgdmFsdWVzLnNjcmlwdFR5cGUgPSAnc2NyaXB0JztcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFsdWVzLnNjcmlwdEZvcm1hdCA9IGJvU2NyaXB0Rm9ybWF0O1xyXG5cclxuICAgICAgcmV0dXJuIHZhbHVlcztcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIGNvbnRhaW5lckVsZW1lbnQpIHtcclxuICAgICAgdmFyIHNjcmlwdEZvcm1hdCA9IHZhbHVlcy5zY3JpcHRGb3JtYXQsXHJcbiAgICAgICAgICBzY3JpcHRUeXBlID0gdmFsdWVzLnNjcmlwdFR5cGUsXHJcbiAgICAgICAgICBzY3JpcHRSZXNvdXJjZVZhbHVlID0gdmFsdWVzLnNjcmlwdFJlc291cmNlVmFsdWUsXHJcbiAgICAgICAgICBzY3JpcHRWYWx1ZSA9IHZhbHVlcy5zY3JpcHRWYWx1ZTtcclxuXHJcbiAgICAgIC8vIGluaXQgdXBkYXRlXHJcbiAgICAgIHZhciB1cGRhdGUgPSB7XHJcbiAgICAgICAgJ2FjdGl2aXRpOnJlc291cmNlJzogdW5kZWZpbmVkXHJcbiAgICAgIH07XHJcbiAgICAgIHVwZGF0ZVtzY3JpcHRWYWx1ZVByb3BOYW1lXSA9IHVuZGVmaW5lZDtcclxuICAgICAgdXBkYXRlW3NjcmlwdExhbmd1YWdlUHJvcE5hbWVdID0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgaWYgKGlzRm9ybWF0UmVxdWlyZWQpIHtcclxuICAgICAgICAvLyBhbHdheXMgc2V0IGxhbmd1YWdlXHJcbiAgICAgICAgdXBkYXRlW3NjcmlwdExhbmd1YWdlUHJvcE5hbWVdID0gc2NyaXB0Rm9ybWF0IHx8ICcnO1xyXG4gICAgICB9IGVsc2VcclxuICAgICAgLy8gc2V0IGxhbmd1YWdlIG9ubHkgd2hlbiBzY3JpcHRGb3JtYXQgaGFzIGEgdmFsdWVcclxuICAgICAgaWYgKHNjcmlwdEZvcm1hdCAhPT0gJycpIHtcclxuICAgICAgICB1cGRhdGVbc2NyaXB0TGFuZ3VhZ2VQcm9wTmFtZV0gPSBzY3JpcHRGb3JtYXQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHNldCBlaXRoZXIgaW5saW5lIHNjcmlwdCBvciByZXNvdXJjZVxyXG4gICAgICBpZiAoJ3NjcmlwdFJlc291cmNlJyA9PT0gc2NyaXB0VHlwZSkge1xyXG4gICAgICAgIHVwZGF0ZVsnYWN0aXZpdGk6cmVzb3VyY2UnXSA9IHNjcmlwdFJlc291cmNlVmFsdWUgfHwgJyc7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdXBkYXRlW3NjcmlwdFZhbHVlUHJvcE5hbWVdID0gc2NyaXB0VmFsdWUgfHwgJyc7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiB1cGRhdGU7XHJcbiAgICB9LFxyXG5cclxuICAgIHZhbGlkYXRlOiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIHZhbGlkYXRpb25SZXN1bHQgPSB7fTtcclxuXHJcbiAgICAgIGlmICh2YWx1ZXMuc2NyaXB0VHlwZSA9PT0gJ3NjcmlwdCcgJiYgIXZhbHVlcy5zY3JpcHRWYWx1ZSkge1xyXG4gICAgICAgIHZhbGlkYXRpb25SZXN1bHQuc2NyaXB0VmFsdWUgPSB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh2YWx1ZXMuc2NyaXB0VHlwZSA9PT0gJ3NjcmlwdFJlc291cmNlJyAmJiAhdmFsdWVzLnNjcmlwdFJlc291cmNlVmFsdWUpIHtcclxuICAgICAgICB2YWxpZGF0aW9uUmVzdWx0LnNjcmlwdFJlc291cmNlVmFsdWUgPSB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChpc0Zvcm1hdFJlcXVpcmVkICYmICghdmFsdWVzLnNjcmlwdEZvcm1hdCB8fCB2YWx1ZXMuc2NyaXB0Rm9ybWF0Lmxlbmd0aCA9PT0gMCkpIHtcclxuICAgICAgICB2YWxpZGF0aW9uUmVzdWx0LnNjcmlwdEZvcm1hdCA9IHRyYW5zbGF0ZSgnTXVzdCBwcm92aWRlIGEgdmFsdWUnKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHZhbGlkYXRpb25SZXN1bHQ7XHJcbiAgICB9LFxyXG5cclxuICAgIGNsZWFyU2NyaXB0Rm9ybWF0OiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUsIGJ0bk5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICBkb21RdWVyeSgnaW5wdXRbbmFtZT1zY3JpcHRGb3JtYXRdJywgc2NvcGVOb2RlKS52YWx1ZT0nJztcclxuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuXHJcbiAgICBjYW5DbGVhclNjcmlwdEZvcm1hdDogZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlLCBidG5Ob2RlLCBzY29wZU5vZGUpIHtcclxuICAgICAgdmFyIGlucHV0ID0gZG9tUXVlcnkoJ2lucHV0W25hbWU9c2NyaXB0Rm9ybWF0XScsIHNjb3BlTm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gaW5wdXQudmFsdWUgIT09ICcnO1xyXG4gICAgfSxcclxuXHJcbiAgICBjbGVhclNjcmlwdFJlc291cmNlOiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUsIGJ0bk5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICBkb21RdWVyeSgnaW5wdXRbbmFtZT1zY3JpcHRSZXNvdXJjZVZhbHVlXScsIHNjb3BlTm9kZSkudmFsdWU9Jyc7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgY2FuQ2xlYXJTY3JpcHRSZXNvdXJjZTogZnVuY3Rpb24oZWxlbWVudCwgaW5wdXROb2RlLCBidG5Ob2RlLCBzY29wZU5vZGUpIHtcclxuICAgICAgdmFyIGlucHV0ID0gZG9tUXVlcnkoJ2lucHV0W25hbWU9c2NyaXB0UmVzb3VyY2VWYWx1ZV0nLCBzY29wZU5vZGUpO1xyXG5cclxuICAgICAgcmV0dXJuIGlucHV0LnZhbHVlICE9PSAnJztcclxuICAgIH0sXHJcblxyXG4gICAgY2xlYXJTY3JpcHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSwgYnRuTm9kZSwgc2NvcGVOb2RlKSB7XHJcbiAgICAgIGRvbVF1ZXJ5KCd0ZXh0YXJlYVtuYW1lPXNjcmlwdFZhbHVlXScsIHNjb3BlTm9kZSkudmFsdWU9Jyc7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH0sXHJcblxyXG4gICAgY2FuQ2xlYXJTY3JpcHQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSwgYnRuTm9kZSwgc2NvcGVOb2RlKSB7XHJcbiAgICAgIHZhciBpbnB1dCA9IGRvbVF1ZXJ5KCd0ZXh0YXJlYVtuYW1lPXNjcmlwdFZhbHVlXScsIHNjb3BlTm9kZSk7XHJcblxyXG4gICAgICByZXR1cm4gaW5wdXQudmFsdWUgIT09ICcnO1xyXG4gICAgfSxcclxuXHJcbiAgICBpc1NjcmlwdFJlc291cmNlOiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUsIGJ0bk5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICB2YXIgc2NyaXB0VHlwZSA9IGdldFNjcmlwdFR5cGUoc2NvcGVOb2RlKTtcclxuICAgICAgcmV0dXJuIHNjcmlwdFR5cGUgPT09ICdzY3JpcHRSZXNvdXJjZSc7XHJcbiAgICB9LFxyXG5cclxuICAgIGlzU2NyaXB0OiBmdW5jdGlvbihlbGVtZW50LCBpbnB1dE5vZGUsIGJ0bk5vZGUsIHNjb3BlTm9kZSkge1xyXG4gICAgICB2YXIgc2NyaXB0VHlwZSA9IGdldFNjcmlwdFR5cGUoc2NvcGVOb2RlKTtcclxuICAgICAgcmV0dXJuIHNjcmlwdFR5cGUgPT09ICdzY3JpcHQnO1xyXG4gICAgfVxyXG5cclxuICB9O1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG52YXIgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBicG1uRmFjdG9yeSwgb3B0aW9ucywgdHJhbnNsYXRlKSB7XHJcblxyXG4gIHZhciBnZXRCdXNpbmVzc09iamVjdCA9IG9wdGlvbnMuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG4gIHZhciBpc1N0YXJ0YWJsZUluVGFza2xpc3RFbnRyeSA9IGVudHJ5RmFjdG9yeS5jaGVja2JveCh7XHJcbiAgICBpZDogJ2lzU3RhcnRhYmxlSW5UYXNrbGlzdCcsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdTdGFydGFibGUnKSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICdpc1N0YXJ0YWJsZUluVGFza2xpc3QnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KTtcclxuICAgICAgdmFyIGlzU3RhcnRhYmxlSW5UYXNrbGlzdCA9IGJvLmdldCgnYWN0aXZpdGk6aXNTdGFydGFibGVJblRhc2tsaXN0Jyk7XHJcblxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGlzU3RhcnRhYmxlSW5UYXNrbGlzdDogaXNTdGFydGFibGVJblRhc2tsaXN0ID8gaXNTdGFydGFibGVJblRhc2tsaXN0IDogJydcclxuICAgICAgfTtcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMpIHtcclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgYm8sIHtcclxuICAgICAgICAnYWN0aXZpdGk6aXNTdGFydGFibGVJblRhc2tsaXN0JzogISF2YWx1ZXMuaXNTdGFydGFibGVJblRhc2tsaXN0XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIFtcclxuICAgIGlzU3RhcnRhYmxlSW5UYXNrbGlzdEVudHJ5XHJcbiAgXTtcclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgTW9kZWxVdGlsID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKSxcclxuICAgIGlzID0gTW9kZWxVdGlsLmlzLFxyXG4gICAgZ2V0QnVzaW5lc3NPYmplY3QgPSBNb2RlbFV0aWwuZ2V0QnVzaW5lc3NPYmplY3Q7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgZ2V0VmFsdWUgPSBmdW5jdGlvbihidXNpbmVzc09iamVjdCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgdmFyIGRvY3VtZW50YXRpb25zID0gYnVzaW5lc3NPYmplY3QgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdkb2N1bWVudGF0aW9uJyksXHJcbiAgICAgICAgICB0ZXh0ID0gKGRvY3VtZW50YXRpb25zICYmIGRvY3VtZW50YXRpb25zLmxlbmd0aCA+IDApID8gZG9jdW1lbnRhdGlvbnNbMF0udGV4dCA6ICcnO1xyXG5cclxuICAgICAgcmV0dXJuIHsgZG9jdW1lbnRhdGlvbjogdGV4dCB9O1xyXG4gICAgfTtcclxuICB9O1xyXG5cclxuICB2YXIgc2V0VmFsdWUgPSBmdW5jdGlvbihidXNpbmVzc09iamVjdCkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgbmV3T2JqZWN0TGlzdCA9IFtdO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZXMuZG9jdW1lbnRhdGlvbiAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWVzLmRvY3VtZW50YXRpb24gIT09ICcnKSB7XHJcbiAgICAgICAgbmV3T2JqZWN0TGlzdC5wdXNoKGJwbW5GYWN0b3J5LmNyZWF0ZSgnYnBtbjpEb2N1bWVudGF0aW9uJywge1xyXG4gICAgICAgICAgdGV4dDogdmFsdWVzLmRvY3VtZW50YXRpb25cclxuICAgICAgICB9KSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIuc2V0TGlzdChlbGVtZW50LCBidXNpbmVzc09iamVjdCwgJ2RvY3VtZW50YXRpb24nLCBuZXdPYmplY3RMaXN0KTtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgLy8gRWxlbWVudCBEb2N1bWVudGF0aW9uXHJcbiAgdmFyIGVsZW1lbnREb2N1RW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEJveCh7XHJcbiAgICBpZDogJ2RvY3VtZW50YXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnRWxlbWVudCBEb2N1bWVudGF0aW9uJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZG9jdW1lbnRhdGlvbidcclxuICB9KTtcclxuXHJcbiAgZWxlbWVudERvY3VFbnRyeS5zZXQgPSBzZXRWYWx1ZShnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSk7XHJcblxyXG4gIGVsZW1lbnREb2N1RW50cnkuZ2V0ID0gZ2V0VmFsdWUoZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkpO1xyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZWxlbWVudERvY3VFbnRyeSk7XHJcblxyXG5cclxuICB2YXIgcHJvY2Vzc1JlZjtcclxuXHJcbiAgLy8gUHJvY2VzcyBEb2N1bWVudGF0aW9uIHdoZW4gaGF2aW5nIGEgQ29sbGFib3JhdGlvbiBEaWFncmFtXHJcbiAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuXHJcbiAgICBwcm9jZXNzUmVmID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCkucHJvY2Vzc1JlZjtcclxuXHJcbiAgICAvLyBkbyBub3Qgc2hvdyBmb3IgY29sbGFwc2VkIFBvb2xzL1BhcnRpY2lwYW50c1xyXG4gICAgaWYgKHByb2Nlc3NSZWYpIHtcclxuICAgICAgdmFyIHByb2Nlc3NEb2N1RW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEJveCh7XHJcbiAgICAgICAgaWQ6ICdwcm9jZXNzLWRvY3VtZW50YXRpb24nLFxyXG4gICAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1Byb2Nlc3MgRG9jdW1lbnRhdGlvbicpLFxyXG4gICAgICAgIG1vZGVsUHJvcGVydHk6ICdkb2N1bWVudGF0aW9uJ1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHByb2Nlc3NEb2N1RW50cnkuc2V0ID0gc2V0VmFsdWUocHJvY2Vzc1JlZik7XHJcblxyXG4gICAgICBwcm9jZXNzRG9jdUVudHJ5LmdldCA9IGdldFZhbHVlKHByb2Nlc3NSZWYpO1xyXG5cclxuICAgICAgZ3JvdXAuZW50cmllcy5wdXNoKHByb2Nlc3NEb2N1RW50cnkpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBpc0FueSA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL2ZlYXR1cmVzL21vZGVsaW5nL3V0aWwvTW9kZWxpbmdVdGlsJykuaXNBbnksXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyk7XHJcblxyXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XHJcblxyXG52YXIgbWVzc2FnZSA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vTWVzc2FnZUV2ZW50RGVmaW5pdGlvbicpLFxyXG4gICAgc2lnbmFsID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9TaWduYWxFdmVudERlZmluaXRpb24nKSxcclxuICAgIGVycm9yID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9FcnJvckV2ZW50RGVmaW5pdGlvbicpLFxyXG4gICAgZXNjYWxhdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vRXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbicpLFxyXG4gICAgdGltZXIgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL1RpbWVyRXZlbnREZWZpbml0aW9uJyksXHJcbiAgICBjb21wZW5zYXRpb24gPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL0NvbXBlbnNhdGVFdmVudERlZmluaXRpb24nKSxcclxuICAgIGNvbmRpdGlvbiA9IHJlcXVpcmUoJy4vaW1wbGVtZW50YXRpb24vQ29uZGl0aW9uYWxFdmVudERlZmluaXRpb24nKTtcclxuXHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpIHtcclxuICB2YXIgZXZlbnRzID0gW1xyXG4gICAgJ2JwbW46U3RhcnRFdmVudCcsXHJcbiAgICAnYnBtbjpFbmRFdmVudCcsXHJcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcclxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxyXG4gICAgJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCdcclxuICBdO1xyXG5cclxuICAvLyBNZXNzYWdlIGFuZCBTaWduYWwgRXZlbnQgRGVmaW5pdGlvblxyXG4gIGZvckVhY2goZXZlbnRzLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsIGV2ZW50KSkge1xyXG5cclxuICAgICAgdmFyIG1lc3NhZ2VFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0TWVzc2FnZUV2ZW50RGVmaW5pdGlvbihlbGVtZW50KSxcclxuICAgICAgICAgIHNpZ25hbEV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRTaWduYWxFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAobWVzc2FnZUV2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgICAgIG1lc3NhZ2UoZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBtZXNzYWdlRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoc2lnbmFsRXZlbnREZWZpbml0aW9uKSB7XHJcbiAgICAgICAgc2lnbmFsKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgc2lnbmFsRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICAvLyBTcGVjaWFsIENhc2U6IFJlY2VpdmUgVGFza1xyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpSZWNlaXZlVGFzaycpKSB7XHJcbiAgICBtZXNzYWdlKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCksIHRyYW5zbGF0ZSk7XHJcbiAgfVxyXG5cclxuICAvLyBFcnJvciBFdmVudCBEZWZpbml0aW9uXHJcbiAgdmFyIGVycm9yRXZlbnRzID0gW1xyXG4gICAgJ2JwbW46U3RhcnRFdmVudCcsXHJcbiAgICAnYnBtbjpCb3VuZGFyeUV2ZW50JyxcclxuICAgICdicG1uOkVuZEV2ZW50J1xyXG4gIF07XHJcblxyXG4gIGZvckVhY2goZXJyb3JFdmVudHMsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICBpZiAoaXMoZWxlbWVudCwgZXZlbnQpKSB7XHJcblxyXG4gICAgICB2YXIgZXJyb3JFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0RXJyb3JFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAoZXJyb3JFdmVudERlZmluaXRpb24pIHtcclxuXHJcbiAgICAgICAgZXJyb3IoZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlcnJvckV2ZW50RGVmaW5pdGlvbiwgdHJhbnNsYXRlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICAvLyBFc2NhbGF0aW9uIEV2ZW50IERlZmluaXRpb25cclxuICB2YXIgZXNjYWxhdGlvbkV2ZW50cyA9IFtcclxuICAgICdicG1uOlN0YXJ0RXZlbnQnLFxyXG4gICAgJ2JwbW46Qm91bmRhcnlFdmVudCcsXHJcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50JyxcclxuICAgICdicG1uOkVuZEV2ZW50J1xyXG4gIF07XHJcblxyXG4gIGZvckVhY2goZXNjYWxhdGlvbkV2ZW50cywgZnVuY3Rpb24oZXZlbnQpIHtcclxuICAgIGlmIChpcyhlbGVtZW50LCBldmVudCkpIHtcclxuXHJcbiAgICAgIHZhciBzaG93RXNjYWxhdGlvbkNvZGVWYXJpYWJsZSA9IGlzKGVsZW1lbnQsICdicG1uOlN0YXJ0RXZlbnQnKSB8fCBpcyhlbGVtZW50LCAnYnBtbjpCb3VuZGFyeUV2ZW50Jyk7XHJcblxyXG4gICAgICAvLyBnZXQgYnVzaW5lc3Mgb2JqZWN0XHJcbiAgICAgIHZhciBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uID0gZXZlbnREZWZpbml0aW9uSGVscGVyLmdldEVzY2FsYXRpb25FdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAoZXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgICAgIGVzY2FsYXRpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uLCBzaG93RXNjYWxhdGlvbkNvZGVWYXJpYWJsZSxcclxuICAgICAgICAgIHRyYW5zbGF0ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIC8vIFRpbWVyIEV2ZW50IERlZmluaXRpb25cclxuICB2YXIgdGltZXJFdmVudHMgPSBbXHJcbiAgICAnYnBtbjpTdGFydEV2ZW50JyxcclxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxyXG4gICAgJ2JwbW46SW50ZXJtZWRpYXRlQ2F0Y2hFdmVudCdcclxuICBdO1xyXG5cclxuICBmb3JFYWNoKHRpbWVyRXZlbnRzLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsIGV2ZW50KSkge1xyXG5cclxuICAgICAgLy8gZ2V0IGJ1c2luZXNzIG9iamVjdFxyXG4gICAgICB2YXIgdGltZXJFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0VGltZXJFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAodGltZXJFdmVudERlZmluaXRpb24pIHtcclxuICAgICAgICB0aW1lcihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHRpbWVyRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIC8vIENvbXBlbnNhdGUgRXZlbnQgRGVmaW5pdGlvblxyXG4gIHZhciBjb21wZW5zYXRpb25FdmVudHMgPSBbXHJcbiAgICAnYnBtbjpFbmRFdmVudCcsXHJcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVUaHJvd0V2ZW50J1xyXG4gIF07XHJcblxyXG4gIGZvckVhY2goY29tcGVuc2F0aW9uRXZlbnRzLCBmdW5jdGlvbihldmVudCkge1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsIGV2ZW50KSkge1xyXG5cclxuICAgICAgLy8gZ2V0IGJ1c2luZXNzIG9iamVjdFxyXG4gICAgICB2YXIgY29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbkhlbHBlci5nZXRDb21wZW5zYXRlRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpO1xyXG5cclxuICAgICAgaWYgKGNvbXBlbnNhdGVFdmVudERlZmluaXRpb24pIHtcclxuICAgICAgICBjb21wZW5zYXRpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxuXHJcblxyXG4gIC8vIENvbmRpdGlvbmFsIEV2ZW50IERlZmluaXRpb25cclxuICB2YXIgY29uZGl0aW9uYWxFdmVudHMgPSBbXHJcbiAgICAnYnBtbjpTdGFydEV2ZW50JyxcclxuICAgICdicG1uOkJvdW5kYXJ5RXZlbnQnLFxyXG4gICAgJ2JwbW46SW50ZXJtZWRpYXRlVGhyb3dFdmVudCcsXHJcbiAgICAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50J1xyXG4gIF07XHJcblxyXG4gIGlmIChpc0FueShlbGVtZW50LCBjb25kaXRpb25hbEV2ZW50cykpIHtcclxuXHJcbiAgICAvLyBnZXQgYnVzaW5lc3Mgb2JqZWN0XHJcbiAgICB2YXIgY29uZGl0aW9uYWxFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0Q29uZGl0aW9uYWxFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgaWYgKGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uKSB7XHJcbiAgICAgIGNvbmRpdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uLCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIHBhcnRpY2lwYW50SGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL1BhcnRpY2lwYW50SGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIGlmICghYm8pIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYm8uZ2V0KCdwcm9jZXNzUmVmJykpKSB7XHJcblxyXG4gICAgdmFyIGV4ZWN1dGFibGVFbnRyeSA9IGVudHJ5RmFjdG9yeS5jaGVja2JveCh7XHJcbiAgICAgIGlkOiAncHJvY2Vzcy1pcy1leGVjdXRhYmxlJyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXhlY3V0YWJsZScpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5OiAnaXNFeGVjdXRhYmxlJ1xyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gaW4gcGFydGljaXBhbnRzIHdlIGhhdmUgdG8gY2hhbmdlIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHNldCBhbmQgZ2V0XHJcbiAgICBpZiAoaXMoZWxlbWVudCwgJ2JwbW46UGFydGljaXBhbnQnKSkge1xyXG4gICAgICBleGVjdXRhYmxlRW50cnkuZ2V0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiBwYXJ0aWNpcGFudEhlbHBlci5nZXRQcm9jZXNzQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgJ2lzRXhlY3V0YWJsZScpO1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgZXhlY3V0YWJsZUVudHJ5LnNldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICAgIHJldHVybiBwYXJ0aWNpcGFudEhlbHBlci5tb2RpZnlQcm9jZXNzQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgJ2lzRXhlY3V0YWJsZScsIHZhbHVlcyk7XHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKGV4ZWN1dGFibGVFbnRyeSk7XHJcbiAgfVxyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBnZXRCdXNpbmVzc09iamVjdCA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuZ2V0QnVzaW5lc3NPYmplY3QsXHJcbiAgICB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uL1V0aWxzJyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKGdyb3VwLCBlbGVtZW50LCB0cmFuc2xhdGUsIG9wdGlvbnMpIHtcclxuXHJcbiAgdmFyIGRlc2NyaXB0aW9uID0gb3B0aW9ucyAmJiBvcHRpb25zLmRlc2NyaXB0aW9uO1xyXG5cclxuICAvLyBJZFxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudmFsaWRhdGlvbkF3YXJlVGV4dEZpZWxkKHtcclxuICAgIGlkOiAnaWQnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnSWQnKSxcclxuICAgIGRlc2NyaXB0aW9uOiBkZXNjcmlwdGlvbiAmJiB0cmFuc2xhdGUoZGVzY3JpcHRpb24pLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2lkJyxcclxuICAgIGdldFByb3BlcnR5OiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgIHJldHVybiBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KS5pZDtcclxuICAgIH0sXHJcbiAgICBzZXRQcm9wZXJ0eTogZnVuY3Rpb24oZWxlbWVudCwgcHJvcGVydGllcykge1xyXG5cclxuICAgICAgZWxlbWVudCA9IGVsZW1lbnQubGFiZWxUYXJnZXQgfHwgZWxlbWVudDtcclxuXHJcbiAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlUHJvcGVydGllcyhlbGVtZW50LCBwcm9wZXJ0aWVzKTtcclxuICAgIH0sXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBpZFZhbHVlID0gdmFsdWVzLmlkO1xyXG5cclxuICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gICAgICB2YXIgaWRFcnJvciA9IHV0aWxzLmlzSWRWYWxpZChibywgaWRWYWx1ZSwgdHJhbnNsYXRlKTtcclxuXHJcbiAgICAgIHJldHVybiBpZEVycm9yID8geyBpZDogaWRFcnJvciB9IDoge307XHJcbiAgICB9XHJcbiAgfSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdCxcclxuICAgIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5JyksXHJcbiAgICBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgZm9yRWFjaCA9IHJlcXVpcmUoJ2xvZGFzaC9mb3JFYWNoJyk7XHJcblxyXG5mdW5jdGlvbiBnZXRMaW5rRXZlbnREZWZpbml0aW9uKGVsZW1lbnQpIHtcclxuXHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gIHZhciBsaW5rRXZlbnREZWZpbml0aW9uID0gbnVsbDtcclxuICBpZiAoYm8uZXZlbnREZWZpbml0aW9ucykge1xyXG4gICAgZm9yRWFjaChiby5ldmVudERlZmluaXRpb25zLCBmdW5jdGlvbihldmVudERlZmluaXRpb24pIHtcclxuICAgICAgaWYgKGlzKGV2ZW50RGVmaW5pdGlvbiwgJ2JwbW46TGlua0V2ZW50RGVmaW5pdGlvbicpKSB7XHJcbiAgICAgICAgbGlua0V2ZW50RGVmaW5pdGlvbiA9IGV2ZW50RGVmaW5pdGlvbjtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gbGlua0V2ZW50RGVmaW5pdGlvbjtcclxufVxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgdHJhbnNsYXRlKSB7XHJcbiAgdmFyIGxpbmtFdmVudHMgPSBbICdicG1uOkludGVybWVkaWF0ZVRocm93RXZlbnQnLCAnYnBtbjpJbnRlcm1lZGlhdGVDYXRjaEV2ZW50JyBdO1xyXG5cclxuICBmb3JFYWNoKGxpbmtFdmVudHMsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcbiAgICBpZiAoaXMoZWxlbWVudCwgZXZlbnQpKSB7XHJcblxyXG4gICAgICB2YXIgbGlua0V2ZW50RGVmaW5pdGlvbiA9IGdldExpbmtFdmVudERlZmluaXRpb24oZWxlbWVudCk7XHJcblxyXG4gICAgICBpZiAobGlua0V2ZW50RGVmaW5pdGlvbikge1xyXG4gICAgICAgIHZhciBlbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgICAgICAgaWQ6ICdsaW5rLWV2ZW50JyxcclxuICAgICAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0xpbmsgTmFtZScpLFxyXG4gICAgICAgICAgbW9kZWxQcm9wZXJ0eTogJ2xpbmstbmFtZSdcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgZW50cnkuZ2V0ID0gZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICByZXR1cm4geyAnbGluay1uYW1lJzogbGlua0V2ZW50RGVmaW5pdGlvbi5nZXQoJ25hbWUnKSB9O1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGVudHJ5LnNldCA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICAgICAgdmFyIG5ld1Byb3BlcnRpZXMgPSB7XHJcbiAgICAgICAgICAgIG5hbWU6IHZhbHVlc1snbGluay1uYW1lJ11cclxuICAgICAgICAgIH07XHJcbiAgICAgICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGxpbmtFdmVudERlZmluaXRpb24sIG5ld1Byb3BlcnRpZXMpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9KTtcclxufTtcclxuXHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBuYW1lRW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi9pbXBsZW1lbnRhdGlvbi9OYW1lJyksXHJcbiAgICBjcmVhdGVDYXRlZ29yeVZhbHVlID0gcmVxdWlyZSgnLi4vLi4vLi4vaGVscGVyL0NhdGVnb3J5SGVscGVyJykuY3JlYXRlQ2F0ZWdvcnlWYWx1ZSxcclxuICAgIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdDtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjYW52YXMsIHRyYW5zbGF0ZSkge1xyXG5cclxuICBmdW5jdGlvbiBpbml0aWFsaXplQ2F0ZWdvcnkoc2VtYW50aWMpIHtcclxuICAgIHZhciByb290RWxlbWVudCA9IGNhbnZhcy5nZXRSb290RWxlbWVudCgpLFxyXG4gICAgICAgIGRlZmluaXRpb25zID0gZ2V0QnVzaW5lc3NPYmplY3Qocm9vdEVsZW1lbnQpLiRwYXJlbnQsXHJcbiAgICAgICAgY2F0ZWdvcnlWYWx1ZSA9IGNyZWF0ZUNhdGVnb3J5VmFsdWUoZGVmaW5pdGlvbnMsIGJwbW5GYWN0b3J5KTtcclxuXHJcbiAgICBzZW1hbnRpYy5jYXRlZ29yeVZhbHVlUmVmID0gY2F0ZWdvcnlWYWx1ZTtcclxuXHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBzZXRHcm91cE5hbWUoZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICB2YXIgYm8gPSBnZXRCdXNpbmVzc09iamVjdChlbGVtZW50KSxcclxuICAgICAgICBjYXRlZ29yeVZhbHVlUmVmID0gYm8uY2F0ZWdvcnlWYWx1ZVJlZjtcclxuXHJcbiAgICBpZiAoIWNhdGVnb3J5VmFsdWVSZWYpIHtcclxuICAgICAgaW5pdGlhbGl6ZUNhdGVnb3J5KGJvKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBuZWVkcyBkaXJlY3QgY2FsbCB0byB1cGRhdGUgY2F0ZWdvcnlWYWx1ZSBwcm9wZXJseVxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgY21kOiAnZWxlbWVudC51cGRhdGVMYWJlbCcsXHJcbiAgICAgIGNvbnRleHQ6IHtcclxuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxyXG4gICAgICAgIG5ld0xhYmVsOiB2YWx1ZXMuY2F0ZWdvcnlWYWx1ZVxyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gZ2V0R3JvdXBOYW1lKGVsZW1lbnQpIHtcclxuICAgIHZhciBibyA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpLFxyXG4gICAgICAgIHZhbHVlID0gKGJvLmNhdGVnb3J5VmFsdWVSZWYgfHwge30pLnZhbHVlO1xyXG5cclxuICAgIHJldHVybiB7IGNhdGVnb3J5VmFsdWU6IHZhbHVlIH07XHJcbiAgfVxyXG5cclxuICBpZiAoIWlzKGVsZW1lbnQsICdicG1uOkNvbGxhYm9yYXRpb24nKSkge1xyXG5cclxuICAgIHZhciBvcHRpb25zO1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlRleHRBbm5vdGF0aW9uJykpIHtcclxuICAgICAgb3B0aW9ucyA9IHsgbW9kZWxQcm9wZXJ0eTogJ3RleHQnLCBsYWJlbDogdHJhbnNsYXRlKCdUZXh0JykgfTtcclxuICAgIH0gZWxzZSBpZiAoaXMoZWxlbWVudCwgJ2JwbW46R3JvdXAnKSkge1xyXG4gICAgICBvcHRpb25zID0ge1xyXG4gICAgICAgIG1vZGVsUHJvcGVydHk6ICdjYXRlZ29yeVZhbHVlJyxcclxuICAgICAgICBsYWJlbDogdHJhbnNsYXRlKCdDYXRlZ29yeSBWYWx1ZScpLFxyXG4gICAgICAgIGdldDogZ2V0R3JvdXBOYW1lLFxyXG4gICAgICAgIHNldDogc2V0R3JvdXBOYW1lXHJcbiAgICAgIH07XHJcbiAgICB9XHJcblxyXG4gICAgLy8gbmFtZVxyXG4gICAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KG5hbWVFbnRyeUZhY3RvcnkoZWxlbWVudCwgb3B0aW9ucywgdHJhbnNsYXRlKSk7XHJcblxyXG4gIH1cclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBpcyA9IHJlcXVpcmUoJ2JwbW4tanMvbGliL3V0aWwvTW9kZWxVdGlsJykuaXMsXHJcbiAgICBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgcGFydGljaXBhbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi9oZWxwZXIvUGFydGljaXBhbnRIZWxwZXInKSxcclxuICAgIGdldEJ1c2luZXNzT2JqZWN0ID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5nZXRCdXNpbmVzc09iamVjdCxcclxuICAgIG5hbWVFbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuL2ltcGxlbWVudGF0aW9uL05hbWUnKSxcclxuICAgIHV0aWxzID0gcmVxdWlyZSgnLi4vLi4vLi4vVXRpbHMnKTtcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIHRyYW5zbGF0ZSwgb3B0aW9ucykge1xyXG4gIHZhciBidXNpbmVzc09iamVjdCA9IGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnQpO1xyXG5cclxuICB2YXIgcHJvY2Vzc0lkRGVzY3JpcHRpb24gPSBvcHRpb25zICYmIG9wdGlvbnMucHJvY2Vzc0lkRGVzY3JpcHRpb247XHJcblxyXG4gIGlmIChpcyhlbGVtZW50LCAnYnBtbjpQcm9jZXNzJykgfHwgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykgJiYgYnVzaW5lc3NPYmplY3QuZ2V0KCdwcm9jZXNzUmVmJykpKSB7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBwcm9jZXNzSWRcclxuICAgICAqL1xyXG4gICAgaWYgKGlzKGVsZW1lbnQsICdicG1uOlBhcnRpY2lwYW50JykpIHtcclxuICAgICAgdmFyIGlkRW50cnkgPSBlbnRyeUZhY3RvcnkudmFsaWRhdGlvbkF3YXJlVGV4dEZpZWxkKHtcclxuICAgICAgICBpZDogJ3Byb2Nlc3MtaWQnLFxyXG4gICAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1Byb2Nlc3MgSWQnKSxcclxuICAgICAgICBkZXNjcmlwdGlvbjogcHJvY2Vzc0lkRGVzY3JpcHRpb24gJiYgdHJhbnNsYXRlKHByb2Nlc3NJZERlc2NyaXB0aW9uKSxcclxuICAgICAgICBtb2RlbFByb3BlcnR5OiAncHJvY2Vzc0lkJ1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIGluIHBhcnRpY2lwYW50cyB3ZSBoYXZlIHRvIGNoYW5nZSB0aGUgZGVmYXVsdCBiZWhhdmlvciBvZiBzZXQgYW5kIGdldFxyXG4gICAgICBpZEVudHJ5LmdldCA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgICB2YXIgcHJvcGVydGllcyA9IHBhcnRpY2lwYW50SGVscGVyLmdldFByb2Nlc3NCdXNpbmVzc09iamVjdChlbGVtZW50LCAnaWQnKTtcclxuICAgICAgICByZXR1cm4geyBwcm9jZXNzSWQ6IHByb3BlcnRpZXMuaWQgfTtcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlkRW50cnkuc2V0ID0gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnRpY2lwYW50SGVscGVyLm1vZGlmeVByb2Nlc3NCdXNpbmVzc09iamVjdChlbGVtZW50LCAnaWQnLCB7IGlkOiB2YWx1ZXMucHJvY2Vzc0lkIH0pO1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgaWRFbnRyeS52YWxpZGF0ZSA9IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICAgIHZhciBpZFZhbHVlID0gdmFsdWVzLnByb2Nlc3NJZDtcclxuXHJcbiAgICAgICAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcblxyXG4gICAgICAgIHZhciBwcm9jZXNzSWRFcnJvciA9IHV0aWxzLmlzSWRWYWxpZChiby5wcm9jZXNzUmVmLCBpZFZhbHVlLCB0cmFuc2xhdGUpO1xyXG5cclxuICAgICAgICByZXR1cm4gcHJvY2Vzc0lkRXJyb3IgPyB7IHByb2Nlc3NJZDogcHJvY2Vzc0lkRXJyb3IgfSA6IHt9O1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgZ3JvdXAuZW50cmllcy5wdXNoKGlkRW50cnkpO1xyXG5cclxuXHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBwcm9jZXNzIG5hbWVcclxuICAgICAgICovXHJcbiAgICAgIHZhciBwcm9jZXNzTmFtZUVudHJ5ID0gbmFtZUVudHJ5RmFjdG9yeShlbGVtZW50LCB7XHJcbiAgICAgICAgaWQ6ICdwcm9jZXNzLW5hbWUnLFxyXG4gICAgICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1Byb2Nlc3MgTmFtZScpXHJcbiAgICAgIH0pWzBdO1xyXG5cclxuICAgICAgLy8gaW4gcGFydGljaXBhbnRzIHdlIGhhdmUgdG8gY2hhbmdlIHRoZSBkZWZhdWx0IGJlaGF2aW9yIG9mIHNldCBhbmQgZ2V0XHJcbiAgICAgIHByb2Nlc3NOYW1lRW50cnkuZ2V0ID0gZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICAgIHJldHVybiBwYXJ0aWNpcGFudEhlbHBlci5nZXRQcm9jZXNzQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgJ25hbWUnKTtcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHByb2Nlc3NOYW1lRW50cnkuc2V0ID0gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgICAgcmV0dXJuIHBhcnRpY2lwYW50SGVscGVyLm1vZGlmeVByb2Nlc3NCdXNpbmVzc09iamVjdChlbGVtZW50LCAnbmFtZScsIHZhbHVlcyk7XHJcbiAgICAgIH07XHJcblxyXG4gICAgICBncm91cC5lbnRyaWVzLnB1c2gocHJvY2Vzc05hbWVFbnRyeSk7XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZW50cnlGYWN0b3J5ID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vZmFjdG9yeS9FbnRyeUZhY3RvcnknKTtcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyksXHJcbiAgICBldmVudERlZmluaXRpb25IZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRXZlbnREZWZpbml0aW9uSGVscGVyJyksXHJcbiAgICB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL1V0aWxzJyk7XHJcblxyXG52YXIgZ2V0QnVzaW5lc3NPYmplY3QgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmdldEJ1c2luZXNzT2JqZWN0LFxyXG4gICAgaXMgPSByZXF1aXJlKCdicG1uLWpzL2xpYi91dGlsL01vZGVsVXRpbCcpLmlzO1xyXG5cclxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpLFxyXG4gICAgZmluZCA9IHJlcXVpcmUoJ2xvZGFzaC9maW5kJyksXHJcbiAgICBmaWx0ZXIgPSByZXF1aXJlKCdsb2Rhc2gvZmlsdGVyJyk7XHJcblxyXG5cclxuZnVuY3Rpb24gZ2V0Q29udGFpbmVkQWN0aXZpdGllcyhlbGVtZW50KSB7XHJcbiAgcmV0dXJuIGdldEZsb3dFbGVtZW50cyhlbGVtZW50LCAnYnBtbjpBY3Rpdml0eScpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRDb250YWluZWRCb3VuZGFyeUV2ZW50cyhlbGVtZW50KSB7XHJcbiAgcmV0dXJuIGdldEZsb3dFbGVtZW50cyhlbGVtZW50LCAnYnBtbjpCb3VuZGFyeUV2ZW50Jyk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEZsb3dFbGVtZW50cyhlbGVtZW50LCB0eXBlKSB7XHJcbiAgcmV0dXJuIHV0aWxzLmZpbHRlckVsZW1lbnRzQnlUeXBlKGVsZW1lbnQuZmxvd0VsZW1lbnRzLCB0eXBlKTtcclxufVxyXG5cclxuZnVuY3Rpb24gaXNDb21wZW5zYXRpb25FdmVudEF0dGFjaGVkVG9BY3Rpdml0eShhY3Rpdml0eSwgYm91bmRhcnlFdmVudHMpIHtcclxuICB2YXIgYWN0aXZpdHlJZCA9IGFjdGl2aXR5LmlkO1xyXG4gIHZhciBib3VuZGFyeUV2ZW50ID0gZmluZChib3VuZGFyeUV2ZW50cywgZnVuY3Rpb24oYm91bmRhcnlFdmVudCkge1xyXG4gICAgdmFyIGNvbXBlbnNhdGVFdmVudERlZmluaXRpb24gPSBldmVudERlZmluaXRpb25IZWxwZXIuZ2V0Q29tcGVuc2F0ZUV2ZW50RGVmaW5pdGlvbihib3VuZGFyeUV2ZW50KTtcclxuICAgIHZhciBhdHRhY2hlZFRvUmVmID0gYm91bmRhcnlFdmVudC5hdHRhY2hlZFRvUmVmO1xyXG4gICAgcmV0dXJuIGNvbXBlbnNhdGVFdmVudERlZmluaXRpb24gJiYgYXR0YWNoZWRUb1JlZiAmJiBhdHRhY2hlZFRvUmVmLmlkID09PSBhY3Rpdml0eUlkO1xyXG4gIH0pO1xyXG4gIHJldHVybiAhIWJvdW5kYXJ5RXZlbnQ7XHJcbn1cclxuXHJcbi8vIHN1YnByb2Nlc3M6IG9ubHkgd2hlbiBpdCBpcyBub3QgdHJpZ2dlcmVkQnlFdmVudFxyXG4vLyBhY3Rpdml0eTogb25seSB3aGVuIGl0IGF0dGFjaCBhIGNvbXBlbnNhdGlvbiBib3VuZGFyeSBldmVudFxyXG4vLyBjYWxsQWN0aXZpdHk6IG5vIGxpbWl0YXRpb25cclxuZnVuY3Rpb24gY2FuQWN0aXZpdHlCZUNvbXBlbnNhdGVkKGFjdGl2aXR5LCBib3VuZGFyeUV2ZW50cykge1xyXG4gIHJldHVybiAoaXMoYWN0aXZpdHksICdicG1uOlN1YlByb2Nlc3MnKSAmJiAhYWN0aXZpdHkudHJpZ2dlcmVkQnlFdmVudCkgfHxcclxuICAgICAgICAgIGlzKGFjdGl2aXR5LCAnYnBtbjpDYWxsQWN0aXZpdHknKSB8fFxyXG4gICAgICAgICAgaXNDb21wZW5zYXRpb25FdmVudEF0dGFjaGVkVG9BY3Rpdml0eShhY3Rpdml0eSwgYm91bmRhcnlFdmVudHMpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRBY3Rpdml0aWVzRm9yQ29tcGVuc2F0aW9uKGVsZW1lbnQpIHtcclxuICB2YXIgYm91bmRhcnlFdmVudHMgPSBnZXRDb250YWluZWRCb3VuZGFyeUV2ZW50cyhlbGVtZW50KTtcclxuICByZXR1cm4gZmlsdGVyKGdldENvbnRhaW5lZEFjdGl2aXRpZXMoZWxlbWVudCksIGZ1bmN0aW9uKGFjdGl2aXR5KSB7XHJcbiAgICByZXR1cm4gY2FuQWN0aXZpdHlCZUNvbXBlbnNhdGVkKGFjdGl2aXR5LCBib3VuZGFyeUV2ZW50cyk7XHJcbiAgfSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGdldEFjdGl2aXRpZXNGb3JBY3Rpdml0eVJlZihlbGVtZW50KSB7XHJcbiAgdmFyIGJvID0gZ2V0QnVzaW5lc3NPYmplY3QoZWxlbWVudCk7XHJcbiAgdmFyIHBhcmVudCA9IGJvLiRwYXJlbnQ7XHJcblxyXG4gIHZhciBhY3Rpdml0aWVzRm9yQWN0aXZpdHlSZWYgPSBnZXRBY3Rpdml0aWVzRm9yQ29tcGVuc2F0aW9uKHBhcmVudCk7XHJcblxyXG4gIC8vIGlmIHRocm93aW5nIGNvbXBlbnNhdGlvbiBldmVudCBpcyBpbiBhbiBldmVudCBzdWIgcHJvY2VzczpcclxuICAvLyBnZXQgYWxzbyBhbGwgYWN0aXZpdGllcyBvdXRzaWRlIG9mIHRoZSBldmVudCBzdWIgcHJvY2Vzc1xyXG4gIGlmIChpcyhwYXJlbnQsICdicG1uOlN1YlByb2Nlc3MnKSAmJiBwYXJlbnQudHJpZ2dlcmVkQnlFdmVudCkge1xyXG4gICAgcGFyZW50ID0gcGFyZW50LiRwYXJlbnQ7XHJcbiAgICBpZiAocGFyZW50KSB7XHJcbiAgICAgIGFjdGl2aXRpZXNGb3JBY3Rpdml0eVJlZiA9IGFjdGl2aXRpZXNGb3JBY3Rpdml0eVJlZi5jb25jYXQoZ2V0QWN0aXZpdGllc0ZvckNvbXBlbnNhdGlvbihwYXJlbnQpKTtcclxuICAgIH1cclxuXHJcbiAgfVxyXG5cclxuICByZXR1cm4gYWN0aXZpdGllc0ZvckFjdGl2aXR5UmVmO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjcmVhdGVBY3Rpdml0eVJlZk9wdGlvbnMoZWxlbWVudCkge1xyXG4gIHZhciBvcHRpb25zID0gWyB7IHZhbHVlOiAnJyB9IF07XHJcblxyXG4gIHZhciBhY3Rpdml0aWVzID0gZ2V0QWN0aXZpdGllc0ZvckFjdGl2aXR5UmVmKGVsZW1lbnQpO1xyXG4gIGZvckVhY2goYWN0aXZpdGllcywgZnVuY3Rpb24oYWN0aXZpdHkpIHtcclxuICAgIHZhciBhY3Rpdml0eUlkID0gYWN0aXZpdHkuaWQ7XHJcbiAgICB2YXIgbmFtZSA9IChhY3Rpdml0eS5uYW1lID8gKGFjdGl2aXR5Lm5hbWUgKyAnICcpIDogJycpICsgJyhpZD0nICsgYWN0aXZpdHlJZCArICcpJztcclxuICAgIG9wdGlvbnMucHVzaCh7IHZhbHVlOiBhY3Rpdml0eUlkLCBuYW1lOiBuYW1lIH0pO1xyXG4gIH0pO1xyXG5cclxuICByZXR1cm4gb3B0aW9ucztcclxufVxyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLCBlbGVtZW50UmVnaXN0cnksIHRyYW5zbGF0ZSkge1xyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LmNoZWNrYm94KHtcclxuICAgIGlkOiAnd2FpdC1mb3ItY29tcGxldGlvbicsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdXYWl0IGZvciBDb21wbGV0aW9uJyksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnd2FpdEZvckNvbXBsZXRpb24nLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHdhaXRGb3JDb21wbGV0aW9uOiBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLndhaXRGb3JDb21wbGV0aW9uXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhbHVlcy53YWl0Rm9yQ29tcGxldGlvbiA9IHZhbHVlcy53YWl0Rm9yQ29tcGxldGlvbiB8fCBmYWxzZTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLCB2YWx1ZXMpO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbiAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS5zZWxlY3RCb3goe1xyXG4gICAgaWQ6ICdhY3Rpdml0eS1yZWYnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnQWN0aXZpdHkgUmVmJyksXHJcbiAgICBzZWxlY3RPcHRpb25zOiBjcmVhdGVBY3Rpdml0eVJlZk9wdGlvbnMoZWxlbWVudCksXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnYWN0aXZpdHlSZWYnLFxyXG5cclxuICAgIGdldDogZnVuY3Rpb24oZWxlbWVudCwgbm9kZSkge1xyXG4gICAgICB2YXIgYWN0aXZpdHlSZWYgPSBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLmFjdGl2aXR5UmVmO1xyXG4gICAgICBhY3Rpdml0eVJlZiA9IGFjdGl2aXR5UmVmICYmIGFjdGl2aXR5UmVmLmlkO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGFjdGl2aXR5UmVmOiBhY3Rpdml0eVJlZiB8fCAnJ1xyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgYWN0aXZpdHlSZWYgPSB2YWx1ZXMuYWN0aXZpdHlSZWYgfHwgdW5kZWZpbmVkO1xyXG4gICAgICBhY3Rpdml0eVJlZiA9IGFjdGl2aXR5UmVmICYmIGdldEJ1c2luZXNzT2JqZWN0KGVsZW1lbnRSZWdpc3RyeS5nZXQoYWN0aXZpdHlSZWYpKTtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBjb21wZW5zYXRlRXZlbnREZWZpbml0aW9uLCB7XHJcbiAgICAgICAgYWN0aXZpdHlSZWY6IGFjdGl2aXR5UmVmXHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH0pKTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxudmFyIGlzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9Nb2RlbFV0aWwnKS5pcyxcclxuICAgIGlzRXZlbnRTdWJQcm9jZXNzID0gcmVxdWlyZSgnYnBtbi1qcy9saWIvdXRpbC9EaVV0aWwnKS5pc0V2ZW50U3ViUHJvY2VzcztcclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBjb25kaXRpb25hbEV2ZW50RGVmaW5pdGlvbiwgZWxlbWVudFJlZ2lzdHJ5LCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgdmFyIGdldFZhbHVlID0gZnVuY3Rpb24obW9kZWxQcm9wZXJ0eSkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgICAgdmFyIG1vZGVsUHJvcGVydHlWYWx1ZSA9IGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uLmdldCgnY2FtdW5kYTonICsgbW9kZWxQcm9wZXJ0eSk7XHJcbiAgICAgIHZhciB2YWx1ZSA9IHt9O1xyXG5cclxuICAgICAgdmFsdWVbbW9kZWxQcm9wZXJ0eV0gPSBtb2RlbFByb3BlcnR5VmFsdWU7XHJcbiAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH07XHJcbiAgfTtcclxuXHJcbiAgdmFyIHNldFZhbHVlID0gZnVuY3Rpb24obW9kZWxQcm9wZXJ0eSkge1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgcHJvcHMgPSB7fTtcclxuXHJcbiAgICAgIHByb3BzWydjYW11bmRhOicgKyBtb2RlbFByb3BlcnR5XSA9IHZhbHVlc1ttb2RlbFByb3BlcnR5XSB8fCB1bmRlZmluZWQ7XHJcblxyXG4gICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGNvbmRpdGlvbmFsRXZlbnREZWZpbml0aW9uLCBwcm9wcyk7XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG4gIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgIGlkOiAndmFyaWFibGVOYW1lJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ1ZhcmlhYmxlIE5hbWUnKSxcclxuICAgIG1vZGVsUHJvcGVydHkgOiAndmFyaWFibGVOYW1lJyxcclxuXHJcbiAgICBnZXQ6IGdldFZhbHVlKCd2YXJpYWJsZU5hbWUnKSxcclxuICAgIHNldDogc2V0VmFsdWUoJ3ZhcmlhYmxlTmFtZScpXHJcbiAgfSkpO1xyXG5cclxuICB2YXIgaXNDb25kaXRpb25hbFN0YXJ0RXZlbnQgPVxyXG4gICAgaXMoZWxlbWVudCwgJ2JwbW46U3RhcnRFdmVudCcpICYmICFpc0V2ZW50U3ViUHJvY2VzcyhlbGVtZW50LnBhcmVudCk7XHJcblxyXG4gIGlmICghaXNDb25kaXRpb25hbFN0YXJ0RXZlbnQpIHtcclxuICAgIGdyb3VwLmVudHJpZXMucHVzaChlbnRyeUZhY3RvcnkudGV4dEZpZWxkKHtcclxuICAgICAgaWQ6ICd2YXJpYWJsZUV2ZW50JyxcclxuICAgICAgbGFiZWw6IHRyYW5zbGF0ZSgnVmFyaWFibGUgRXZlbnQnKSxcclxuICAgICAgZGVzY3JpcHRpb246IHRyYW5zbGF0ZSgnU3BlY2lmeSBtb3JlIHRoYW4gb25lIHZhcmlhYmxlIGNoYW5nZSBldmVudCBhcyBhIGNvbW1hIHNlcGFyYXRlZCBsaXN0LicpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5IDogJ3ZhcmlhYmxlRXZlbnQnLFxyXG5cclxuICAgICAgZ2V0OiBnZXRWYWx1ZSgndmFyaWFibGVFdmVudCcpLFxyXG4gICAgICBzZXQ6IHNldFZhbHVlKCd2YXJpYWJsZUV2ZW50JylcclxuICAgIH0pKTtcclxuICB9XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpO1xyXG5cclxudmFyIGNtZEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9DbWRIZWxwZXInKTtcclxuXHJcbi8qKlxyXG4gKiBDcmVhdGUgYW4gZW50cnkgdG8gbW9kaWZ5IGEgcHJvcGVydHkgb2YgYW4gZWxlbWVudCB3aGljaFxyXG4gKiBpcyByZWZlcmVuY2VkIGJ5IGEgZXZlbnQgZGVmaW5pdGlvbi5cclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gZGVmaW5pdGlvblxyXG4gKiBAcGFyYW0gIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5pZCB0aGUgaWQgb2YgdGhlIGVudHJ5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5sYWJlbCB0aGUgbGFiZWwgb2YgdGhlIGVudHJ5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5yZWZlcmVuY2VQcm9wZXJ0eSB0aGUgbmFtZSBvZiByZWZlcmVuY2luZyBwcm9wZXJ0eVxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eSB0aGUgbmFtZSBvZiBwcm9wZXJ0eSB0byBtb2RpZnlcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLnNob3VsZFZhbGlkYXRlIGEgZmxhZyBpbmRpY2F0ZSB3aGV0aGVyIHRvIHZhbGlkYXRlIG9yIG5vdFxyXG4gKlxyXG4gKiBAcmV0dXJuIHtBcnJheTxPYmplY3Q+fSByZXR1cm4gYW4gYXJyYXkgY29udGFpbmluZyB0aGUgZW50cmllc1xyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBkZWZpbml0aW9uLCBicG1uRmFjdG9yeSwgb3B0aW9ucykge1xyXG5cclxuICB2YXIgaWQgPSBvcHRpb25zLmlkIHx8ICdlbGVtZW50LXByb3BlcnR5JztcclxuICB2YXIgbGFiZWwgPSBvcHRpb25zLmxhYmVsO1xyXG4gIHZhciByZWZlcmVuY2VQcm9wZXJ0eSA9IG9wdGlvbnMucmVmZXJlbmNlUHJvcGVydHk7XHJcbiAgdmFyIG1vZGVsUHJvcGVydHkgPSBvcHRpb25zLm1vZGVsUHJvcGVydHkgfHwgJ25hbWUnO1xyXG4gIHZhciBzaG91bGRWYWxpZGF0ZSA9IG9wdGlvbnMuc2hvdWxkVmFsaWRhdGUgfHwgZmFsc2U7XHJcblxyXG4gIHZhciBlbnRyeSA9IGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgaWQ6IGlkLFxyXG4gICAgbGFiZWw6IGxhYmVsLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogbW9kZWxQcm9wZXJ0eSxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgdmFyIHJlZmVyZW5jZSA9IGRlZmluaXRpb24uZ2V0KHJlZmVyZW5jZVByb3BlcnR5KTtcclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW21vZGVsUHJvcGVydHldID0gcmVmZXJlbmNlICYmIHJlZmVyZW5jZS5nZXQobW9kZWxQcm9wZXJ0eSk7XHJcbiAgICAgIHJldHVybiBwcm9wcztcclxuICAgIH0sXHJcblxyXG4gICAgc2V0OiBmdW5jdGlvbihlbGVtZW50LCB2YWx1ZXMsIG5vZGUpIHtcclxuICAgICAgdmFyIHJlZmVyZW5jZSA9IGRlZmluaXRpb24uZ2V0KHJlZmVyZW5jZVByb3BlcnR5KTtcclxuICAgICAgdmFyIHByb3BzID0ge307XHJcbiAgICAgIHByb3BzW21vZGVsUHJvcGVydHldID0gdmFsdWVzW21vZGVsUHJvcGVydHldIHx8IHVuZGVmaW5lZDtcclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCByZWZlcmVuY2UsIHByb3BzKTtcclxuICAgIH0sXHJcblxyXG4gICAgaGlkZGVuOiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHJldHVybiAhZGVmaW5pdGlvbi5nZXQocmVmZXJlbmNlUHJvcGVydHkpO1xyXG4gICAgfVxyXG4gIH0pO1xyXG5cclxuICBpZiAoc2hvdWxkVmFsaWRhdGUpIHtcclxuICAgIGVudHJ5LnZhbGlkYXRlID0gZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzLCBub2RlKSB7XHJcbiAgICAgIHZhciByZWZlcmVuY2UgPSBkZWZpbml0aW9uLmdldChyZWZlcmVuY2VQcm9wZXJ0eSk7XHJcbiAgICAgIGlmIChyZWZlcmVuY2UgJiYgIXZhbHVlc1ttb2RlbFByb3BlcnR5XSkge1xyXG4gICAgICAgIHZhciB2YWxpZGF0aW9uRXJyb3JzID0ge307XHJcbiAgICAgICAgdmFsaWRhdGlvbkVycm9yc1ttb2RlbFByb3BlcnR5XSA9ICdNdXN0IHByb3ZpZGUgYSB2YWx1ZSc7XHJcbiAgICAgICAgcmV0dXJuIHZhbGlkYXRpb25FcnJvcnM7XHJcbiAgICAgIH1cclxuICAgIH07XHJcbiAgfVxyXG5cclxuICByZXR1cm4gWyBlbnRyeSBdO1xyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXZlbnREZWZpbml0aW9uUmVmZXJlbmNlID0gcmVxdWlyZSgnLi9FdmVudERlZmluaXRpb25SZWZlcmVuY2UnKSxcclxuICAgIGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vRWxlbWVudFJlZmVyZW5jZVByb3BlcnR5Jyk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIGVycm9yRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpIHtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChldmVudERlZmluaXRpb25SZWZlcmVuY2UoZWxlbWVudCwgZXJyb3JFdmVudERlZmluaXRpb24sIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdFcnJvcicpLFxyXG4gICAgZWxlbWVudE5hbWU6ICdlcnJvcicsXHJcbiAgICBlbGVtZW50VHlwZTogJ2JwbW46RXJyb3InLFxyXG4gICAgcmVmZXJlbmNlUHJvcGVydHk6ICdlcnJvclJlZicsXHJcbiAgICBuZXdFbGVtZW50SWRQcmVmaXg6ICdFcnJvcl8nXHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eShlbGVtZW50LCBlcnJvckV2ZW50RGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkOiAnZXJyb3ItZWxlbWVudC1uYW1lJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0Vycm9yIE5hbWUnKSxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnZXJyb3JSZWYnLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ25hbWUnLFxyXG4gICAgc2hvdWxkVmFsaWRhdGU6IHRydWVcclxuICB9KSk7XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoZWxlbWVudFJlZmVyZW5jZVByb3BlcnR5KGVsZW1lbnQsIGVycm9yRXZlbnREZWZpbml0aW9uLCBicG1uRmFjdG9yeSwge1xyXG4gICAgaWQ6ICdlcnJvci1lbGVtZW50LWNvZGUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXJyb3IgQ29kZScpLFxyXG4gICAgcmVmZXJlbmNlUHJvcGVydHk6ICdlcnJvclJlZicsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnZXJyb3JDb2RlJ1xyXG4gIH0pKTtcclxuXHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBlbnRyeUZhY3RvcnkgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9mYWN0b3J5L0VudHJ5RmFjdG9yeScpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxudmFyIGV2ZW50RGVmaW5pdGlvblJlZmVyZW5jZSA9IHJlcXVpcmUoJy4vRXZlbnREZWZpbml0aW9uUmVmZXJlbmNlJyksXHJcbiAgICBlbGVtZW50UmVmZXJlbmNlUHJvcGVydHkgPSByZXF1aXJlKCcuL0VsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eScpO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uLCBzaG93RXNjYWxhdGlvbkNvZGVWYXJpYWJsZSwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChldmVudERlZmluaXRpb25SZWZlcmVuY2UoZWxlbWVudCwgZXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIHtcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ0VzY2FsYXRpb24nKSxcclxuICAgIGVsZW1lbnROYW1lOiAnZXNjYWxhdGlvbicsXHJcbiAgICBlbGVtZW50VHlwZTogJ2JwbW46RXNjYWxhdGlvbicsXHJcbiAgICByZWZlcmVuY2VQcm9wZXJ0eTogJ2VzY2FsYXRpb25SZWYnLFxyXG4gICAgbmV3RWxlbWVudElkUHJlZml4OiAnRXNjYWxhdGlvbl8nXHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eShlbGVtZW50LCBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uLCBicG1uRmFjdG9yeSwge1xyXG4gICAgaWQ6ICdlc2NhbGF0aW9uLWVsZW1lbnQtbmFtZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdFc2NhbGF0aW9uIE5hbWUnKSxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnZXNjYWxhdGlvblJlZicsXHJcbiAgICBtb2RlbFByb3BlcnR5OiAnbmFtZScsXHJcbiAgICBzaG91bGRWYWxpZGF0ZTogdHJ1ZVxyXG4gIH0pKTtcclxuXHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChlbGVtZW50UmVmZXJlbmNlUHJvcGVydHkoZWxlbWVudCwgZXNjYWxhdGlvbkV2ZW50RGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIHtcclxuICAgIGlkOiAnZXNjYWxhdGlvbi1lbGVtZW50LWNvZGUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnRXNjYWxhdGlvbiBDb2RlJyksXHJcbiAgICByZWZlcmVuY2VQcm9wZXJ0eTogJ2VzY2FsYXRpb25SZWYnLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ2VzY2FsYXRpb25Db2RlJ1xyXG4gIH0pKTtcclxuXHJcblxyXG4gIGlmIChzaG93RXNjYWxhdGlvbkNvZGVWYXJpYWJsZSkge1xyXG4gICAgZ3JvdXAuZW50cmllcy5wdXNoKGVudHJ5RmFjdG9yeS50ZXh0RmllbGQoe1xyXG4gICAgICBpZCA6ICdlc2NhbGF0aW9uQ29kZVZhcmlhYmxlJyxcclxuICAgICAgbGFiZWwgOiB0cmFuc2xhdGUoJ0VzY2FsYXRpb24gQ29kZSBWYXJpYWJsZScpLFxyXG4gICAgICBtb2RlbFByb3BlcnR5IDogJ2VzY2FsYXRpb25Db2RlVmFyaWFibGUnLFxyXG5cclxuICAgICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50KSB7XHJcbiAgICAgICAgdmFyIGNvZGVWYXJpYWJsZSA9IGVzY2FsYXRpb25FdmVudERlZmluaXRpb24uZ2V0KCdjYW11bmRhOmVzY2FsYXRpb25Db2RlVmFyaWFibGUnKTtcclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgZXNjYWxhdGlvbkNvZGVWYXJpYWJsZTogY29kZVZhcmlhYmxlXHJcbiAgICAgICAgfTtcclxuICAgICAgfSxcclxuXHJcbiAgICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCBlc2NhbGF0aW9uRXZlbnREZWZpbml0aW9uLCB7XHJcbiAgICAgICAgICAnY2FtdW5kYTplc2NhbGF0aW9uQ29kZVZhcmlhYmxlJzogdmFsdWVzLmVzY2FsYXRpb25Db2RlVmFyaWFibGUgfHwgdW5kZWZpbmVkXHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pKTtcclxuICB9XHJcbn07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbnZhciBjbWRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvQ21kSGVscGVyJyk7XHJcblxyXG52YXIgZG9tUXVlcnkgPSByZXF1aXJlKCdtaW4tZG9tJykucXVlcnksXHJcbiAgICBkb21pZnkgPSByZXF1aXJlKCdtaW4tZG9tJykuZG9taWZ5LFxyXG4gICAgZG9tQXR0ciA9IHJlcXVpcmUoJ21pbi1kb20nKS5hdHRyO1xyXG5cclxudmFyIGZvckVhY2ggPSByZXF1aXJlKCdsb2Rhc2gvZm9yRWFjaCcpLFxyXG4gICAgZmluZCA9IHJlcXVpcmUoJ2xvZGFzaC9maW5kJyk7XHJcblxyXG52YXIgZWxlbWVudEhlbHBlciA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2hlbHBlci9FbGVtZW50SGVscGVyJyk7XHJcbnZhciB1dGlscyA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL1V0aWxzJyksXHJcbiAgICBlc2NhcGVIVE1MID0gdXRpbHMuZXNjYXBlSFRNTDtcclxuXHJcbnZhciBzZWxlY3RvciA9ICdzZWxlY3RbbmFtZT1zZWxlY3RlZEVsZW1lbnRdJztcclxuXHJcbi8qKlxyXG4gKiBHZXQgc2VsZWN0IGJveCBjb250YWluaW5nIGFsbCBlbGVtZW50cy5cclxuICpcclxuICogQHBhcmFtIHtET01FbGVtZW50fSBub2RlXHJcbiAqXHJcbiAqIEByZXR1cm4ge0RPTUVsZW1lbnR9IHRoZSBzZWxlY3QgYm94XHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRTZWxlY3RCb3gobm9kZSkge1xyXG4gIHJldHVybiBkb21RdWVyeShzZWxlY3Rvciwgbm9kZS5wYXJlbnRFbGVtZW50KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEZpbmQgZWxlbWVudCBieSBnaXZlbiBpZC5cclxuICpcclxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50fSBldmVudERlZmluaXRpb25cclxuICpcclxuICogQHJldHVybiB7TW9kZGxlRWxlbWVudH0gYW4gZWxlbWVudFxyXG4gKi9cclxuZnVuY3Rpb24gZmluZEVsZW1lbnRCeUlkKGV2ZW50RGVmaW5pdGlvbiwgdHlwZSwgaWQpIHtcclxuICB2YXIgZWxlbWVudHMgPSB1dGlscy5maW5kUm9vdEVsZW1lbnRzQnlUeXBlKGV2ZW50RGVmaW5pdGlvbiwgdHlwZSk7XHJcbiAgcmV0dXJuIGZpbmQoZWxlbWVudHMsIGZ1bmN0aW9uKGVsZW1lbnQpIHtcclxuICAgIHJldHVybiBlbGVtZW50LmlkID09PSBpZDtcclxuICB9KTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBhbiBlbnRyeSB0byBtb2RpZnkgdGhlIHJlZmVyZW5jZSB0byBhbiBlbGVtZW50IGZyb20gYW5cclxuICogZXZlbnQgZGVmaW5pdGlvbi5cclxuICpcclxuICogQHBhcmFtICB7ZGpzLm1vZGVsLkJhc2V9IGVsZW1lbnRcclxuICogQHBhcmFtICB7TW9kZGxlRWxlbWVudH0gZGVmaW5pdGlvblxyXG4gKiBAcGFyYW0gIHtCcG1uRmFjdG9yeX0gYnBtbkZhY3RvcnlcclxuICogQHBhcmFtICB7T2JqZWN0fSBvcHRpb25zXHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5sYWJlbCB0aGUgbGFiZWwgb2YgdGhlIGVudHJ5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5kZXNjcmlwdGlvbiB0aGUgZGVzY3JpcHRpb24gb2YgdGhlIGVudHJ5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5lbGVtZW50TmFtZSB0aGUgbmFtZSBvZiB0aGUgZWxlbWVudFxyXG4gKiBAcGFyYW0gIHtzdHJpbmd9IG9wdGlvbnMuZWxlbWVudFR5cGUgdGhlIHR5cGUgb2YgdGhlIGVsZW1lbnRcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLnJlZmVyZW5jZVByb3BlcnR5IHRoZSBuYW1lIG9mIHJlZmVyZW5jaW5nIHByb3BlcnR5XHJcbiAqIEBwYXJhbSAge3N0cmluZ30gb3B0aW9ucy5uZXdFbGVtZW50SWRQcmVmaXggdGhlIHByZWZpeCBvZiBhIG5ldyBjcmVhdGVkIGVsZW1lbnRcclxuICpcclxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn0gcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIGVudHJpZXNcclxuICovXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZWxlbWVudCwgZGVmaW5pdGlvbiwgYnBtbkZhY3RvcnksIG9wdGlvbnMpIHtcclxuXHJcbiAgdmFyIGVsZW1lbnROYW1lID0gb3B0aW9ucy5lbGVtZW50TmFtZSB8fCAnJyxcclxuICAgICAgZWxlbWVudFR5cGUgPSBvcHRpb25zLmVsZW1lbnRUeXBlLFxyXG4gICAgICByZWZlcmVuY2VQcm9wZXJ0eSA9IG9wdGlvbnMucmVmZXJlbmNlUHJvcGVydHk7XHJcblxyXG4gIHZhciBuZXdFbGVtZW50SWRQcmVmaXggPSBvcHRpb25zLm5ld0VsZW1lbnRJZFByZWZpeCB8fCAnZWxlbV8nO1xyXG5cclxuICB2YXIgbGFiZWwgPSBvcHRpb25zLmxhYmVsIHx8ICcnLFxyXG4gICAgICBkZXNjcmlwdGlvbiA9IG9wdGlvbnMuZGVzY3JpcHRpb24gfHwgJyc7XHJcblxyXG4gIHZhciBlbnRyaWVzID0gW107XHJcblxyXG4gIGVudHJpZXMucHVzaCh7XHJcblxyXG4gICAgaWQ6ICdldmVudC1kZWZpbml0aW9ucy0nICsgZWxlbWVudE5hbWUsXHJcbiAgICBkZXNjcmlwdGlvbjogZGVzY3JpcHRpb24sXHJcbiAgICBodG1sOiAnPGRpdiBjbGFzcz1cImJwcC1yb3cgYnBwLXNlbGVjdFwiPicgK1xyXG4gICAgICAgICAgICAgJzxsYWJlbCBmb3I9XCJjYW11bmRhLScgKyBlc2NhcGVIVE1MKGVsZW1lbnROYW1lKSArICdcIj4nICsgZXNjYXBlSFRNTChsYWJlbCkgKyAnPC9sYWJlbD4nICtcclxuICAgICAgICAgICAgICc8ZGl2IGNsYXNzPVwiYnBwLWZpZWxkLXdyYXBwZXJcIj4nICtcclxuICAgICAgICAgICAgICAgJzxzZWxlY3QgaWQ9XCJjYW11bmRhLScgKyBlc2NhcGVIVE1MKGVsZW1lbnROYW1lKSArICdcIiBuYW1lPVwic2VsZWN0ZWRFbGVtZW50XCIgZGF0YS12YWx1ZT4nICtcclxuICAgICAgICAgICAgICAgJzwvc2VsZWN0PicgK1xyXG4gICAgICAgICAgICAgICAnPGJ1dHRvbiBjbGFzcz1cImFkZFwiIGlkPVwiYWRkRWxlbWVudFwiIGRhdGEtYWN0aW9uPVwiYWRkRWxlbWVudFwiPjxzcGFuPis8L3NwYW4+PC9idXR0b24+JyArXHJcbiAgICAgICAgICAgICAnPC9kaXY+JyArXHJcbiAgICAgICAgICAnPC9kaXY+JyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGVudHJ5Tm9kZSkge1xyXG4gICAgICB1dGlscy51cGRhdGVPcHRpb25zRHJvcERvd24oc2VsZWN0b3IsIGRlZmluaXRpb24sIGVsZW1lbnRUeXBlLCBlbnRyeU5vZGUpO1xyXG4gICAgICB2YXIgcmVmZXJlbmNlID0gZGVmaW5pdGlvbi5nZXQocmVmZXJlbmNlUHJvcGVydHkpO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHNlbGVjdGVkRWxlbWVudDogKHJlZmVyZW5jZSAmJiByZWZlcmVuY2UuaWQpIHx8ICcnXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciBzZWxlY3Rpb24gPSB2YWx1ZXMuc2VsZWN0ZWRFbGVtZW50O1xyXG5cclxuICAgICAgdmFyIHByb3BzID0ge307XHJcblxyXG4gICAgICBpZiAoIXNlbGVjdGlvbiB8fCB0eXBlb2Ygc2VsZWN0aW9uID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIC8vIHJlbW92ZSByZWZlcmVuY2UgdG8gZWxlbWVudFxyXG4gICAgICAgIHByb3BzW3JlZmVyZW5jZVByb3BlcnR5XSA9IHVuZGVmaW5lZDtcclxuICAgICAgICByZXR1cm4gY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGRlZmluaXRpb24sIHByb3BzKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGNvbW1hbmRzID0gW107XHJcblxyXG4gICAgICB2YXIgc2VsZWN0ZWRFbGVtZW50ID0gZmluZEVsZW1lbnRCeUlkKGRlZmluaXRpb24sIGVsZW1lbnRUeXBlLCBzZWxlY3Rpb24pO1xyXG4gICAgICBpZiAoIXNlbGVjdGVkRWxlbWVudCkge1xyXG4gICAgICAgIHZhciByb290ID0gdXRpbHMuZ2V0Um9vdChkZWZpbml0aW9uKTtcclxuXHJcbiAgICAgICAgLy8gY3JlYXRlIGEgbmV3IGVsZW1lbnRcclxuICAgICAgICBzZWxlY3RlZEVsZW1lbnQgPSBlbGVtZW50SGVscGVyLmNyZWF0ZUVsZW1lbnQoZWxlbWVudFR5cGUsIHsgbmFtZTogc2VsZWN0aW9uIH0sIHJvb3QsIGJwbW5GYWN0b3J5KTtcclxuICAgICAgICBjb21tYW5kcy5wdXNoKGNtZEhlbHBlci5hZGRBbmRSZW1vdmVFbGVtZW50c0Zyb21MaXN0KGVsZW1lbnQsIHJvb3QsICdyb290RWxlbWVudHMnLCBudWxsLCBbIHNlbGVjdGVkRWxlbWVudCBdKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHVwZGF0ZSByZWZlcmVuY2UgdG8gZWxlbWVudFxyXG4gICAgICBwcm9wc1tyZWZlcmVuY2VQcm9wZXJ0eV0gPSBzZWxlY3RlZEVsZW1lbnQ7XHJcbiAgICAgIGNvbW1hbmRzLnB1c2goY21kSGVscGVyLnVwZGF0ZUJ1c2luZXNzT2JqZWN0KGVsZW1lbnQsIGRlZmluaXRpb24sIHByb3BzKSk7XHJcblxyXG4gICAgICByZXR1cm4gY29tbWFuZHM7XHJcbiAgICB9LFxyXG5cclxuICAgIGFkZEVsZW1lbnQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGlucHV0Tm9kZSkge1xyXG4gICAgICAvLyBub3RlOiB0aGlzIGdlbmVyYXRlZCBpZCB3aWxsIGJlIHVzZWQgYXMgbmFtZVxyXG4gICAgICAvLyBvZiB0aGUgZWxlbWVudCBhbmQgbm90IGFzIGlkXHJcbiAgICAgIHZhciBpZCA9IHV0aWxzLm5leHRJZChuZXdFbGVtZW50SWRQcmVmaXgpO1xyXG5cclxuICAgICAgdmFyIG9wdGlvblRlbXBsYXRlID0gZG9taWZ5KCc8b3B0aW9uIHZhbHVlPVwiJyArIGVzY2FwZUhUTUwoaWQpICsgJ1wiPiAoaWQ9Jytlc2NhcGVIVE1MKGlkKSsnKScgKyAnPC9vcHRpb24+Jyk7XHJcblxyXG4gICAgICAvLyBhZGQgbmV3IG9wdGlvblxyXG4gICAgICB2YXIgc2VsZWN0Qm94ID0gZ2V0U2VsZWN0Qm94KGlucHV0Tm9kZSk7XHJcbiAgICAgIHNlbGVjdEJveC5pbnNlcnRCZWZvcmUob3B0aW9uVGVtcGxhdGUsIHNlbGVjdEJveC5maXJzdENoaWxkKTtcclxuXHJcbiAgICAgIC8vIHNlbGVjdCBuZXcgZWxlbWVudCBpbiB0aGUgc2VsZWN0IGJveFxyXG4gICAgICBmb3JFYWNoKHNlbGVjdEJveCwgZnVuY3Rpb24ob3B0aW9uKSB7XHJcbiAgICAgICAgaWYgKG9wdGlvbi52YWx1ZSA9PT0gaWQpIHtcclxuICAgICAgICAgIGRvbUF0dHIob3B0aW9uLCAnc2VsZWN0ZWQnLCAnc2VsZWN0ZWQnKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgZG9tQXR0cihvcHRpb24sICdzZWxlY3RlZCcsIG51bGwpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBlbnRyaWVzO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGV2ZW50RGVmaW5pdGlvblJlZmVyZW5jZSA9IHJlcXVpcmUoJy4vRXZlbnREZWZpbml0aW9uUmVmZXJlbmNlJyksXHJcbiAgICBlbGVtZW50UmVmZXJlbmNlUHJvcGVydHkgPSByZXF1aXJlKCcuL0VsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eScpO1xyXG5cclxuXHJcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oZ3JvdXAsIGVsZW1lbnQsIGJwbW5GYWN0b3J5LCBtZXNzYWdlRXZlbnREZWZpbml0aW9uLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGV2ZW50RGVmaW5pdGlvblJlZmVyZW5jZShlbGVtZW50LCBtZXNzYWdlRXZlbnREZWZpbml0aW9uLCBicG1uRmFjdG9yeSwge1xyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnTWVzc2FnZScpLFxyXG4gICAgZWxlbWVudE5hbWU6ICdtZXNzYWdlJyxcclxuICAgIGVsZW1lbnRUeXBlOiAnYnBtbjpNZXNzYWdlJyxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnbWVzc2FnZVJlZicsXHJcbiAgICBuZXdFbGVtZW50SWRQcmVmaXg6ICdNZXNzYWdlXydcclxuICB9KSk7XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzID0gZ3JvdXAuZW50cmllcy5jb25jYXQoZWxlbWVudFJlZmVyZW5jZVByb3BlcnR5KGVsZW1lbnQsIG1lc3NhZ2VFdmVudERlZmluaXRpb24sIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ21lc3NhZ2UtZWxlbWVudC1uYW1lJyxcclxuICAgIGxhYmVsOiB0cmFuc2xhdGUoJ01lc3NhZ2UgTmFtZScpLFxyXG4gICAgcmVmZXJlbmNlUHJvcGVydHk6ICdtZXNzYWdlUmVmJyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuICAgIHNob3VsZFZhbGlkYXRlOiB0cnVlXHJcbiAgfSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG4vKipcclxuICogQ3JlYXRlIGFuIGVudHJ5IHRvIG1vZGlmeSB0aGUgbmFtZSBvZiBhbiBhbiBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0gIHtkanMubW9kZWwuQmFzZX0gZWxlbWVudFxyXG4gKiBAcGFyYW0gIHtPYmplY3R9IG9wdGlvbnNcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmlkIHRoZSBpZCBvZiB0aGUgZW50cnlcclxuICogQHBhcmFtICB7c3RyaW5nfSBvcHRpb25zLmxhYmVsIHRoZSBsYWJlbCBvZiB0aGUgZW50cnlcclxuICpcclxuICogQHJldHVybiB7QXJyYXk8T2JqZWN0Pn0gcmV0dXJuIGFuIGFycmF5IGNvbnRhaW5pbmdcclxuICogICAgICAgICAgICAgICAgICAgICAgICAgdGhlIGVudHJ5IHRvIG1vZGlmeSB0aGUgbmFtZVxyXG4gKi9cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihlbGVtZW50LCBvcHRpb25zLCB0cmFuc2xhdGUpIHtcclxuXHJcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XHJcbiAgdmFyIGlkID0gb3B0aW9ucy5pZCB8fCAnbmFtZScsXHJcbiAgICAgIGxhYmVsID0gb3B0aW9ucy5sYWJlbCB8fCB0cmFuc2xhdGUoJ05hbWUnKSxcclxuICAgICAgbW9kZWxQcm9wZXJ0eSA9IG9wdGlvbnMubW9kZWxQcm9wZXJ0eSB8fCAnbmFtZSc7XHJcblxyXG4gIHZhciBuYW1lRW50cnkgPSBlbnRyeUZhY3RvcnkudGV4dEJveCh7XHJcbiAgICBpZDogaWQsXHJcbiAgICBsYWJlbDogbGFiZWwsXHJcbiAgICBtb2RlbFByb3BlcnR5OiBtb2RlbFByb3BlcnR5LFxyXG4gICAgZ2V0OiBvcHRpb25zLmdldCxcclxuICAgIHNldDogb3B0aW9ucy5zZXRcclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIFsgbmFtZUVudHJ5IF07XHJcblxyXG59O1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG52YXIgZXZlbnREZWZpbml0aW9uUmVmZXJlbmNlID0gcmVxdWlyZSgnLi9FdmVudERlZmluaXRpb25SZWZlcmVuY2UnKSxcclxuICAgIGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eSA9IHJlcXVpcmUoJy4vRWxlbWVudFJlZmVyZW5jZVByb3BlcnR5Jyk7XHJcblxyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihncm91cCwgZWxlbWVudCwgYnBtbkZhY3RvcnksIHNpZ25hbEV2ZW50RGVmaW5pdGlvbiwgdHJhbnNsYXRlKSB7XHJcblxyXG4gIGdyb3VwLmVudHJpZXMgPSBncm91cC5lbnRyaWVzLmNvbmNhdChldmVudERlZmluaXRpb25SZWZlcmVuY2UoZWxlbWVudCwgc2lnbmFsRXZlbnREZWZpbml0aW9uLCBicG1uRmFjdG9yeSwge1xyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnU2lnbmFsJyksXHJcbiAgICBlbGVtZW50TmFtZTogJ3NpZ25hbCcsXHJcbiAgICBlbGVtZW50VHlwZTogJ2JwbW46U2lnbmFsJyxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnc2lnbmFsUmVmJyxcclxuICAgIG5ld0VsZW1lbnRJZFByZWZpeDogJ1NpZ25hbF8nXHJcbiAgfSkpO1xyXG5cclxuXHJcbiAgZ3JvdXAuZW50cmllcyA9IGdyb3VwLmVudHJpZXMuY29uY2F0KGVsZW1lbnRSZWZlcmVuY2VQcm9wZXJ0eShlbGVtZW50LCBzaWduYWxFdmVudERlZmluaXRpb24sIGJwbW5GYWN0b3J5LCB7XHJcbiAgICBpZDogJ3NpZ25hbC1lbGVtZW50LW5hbWUnLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnU2lnbmFsIE5hbWUnKSxcclxuICAgIHJlZmVyZW5jZVByb3BlcnR5OiAnc2lnbmFsUmVmJyxcclxuICAgIG1vZGVsUHJvcGVydHk6ICduYW1lJyxcclxuICAgIHNob3VsZFZhbGlkYXRlOiB0cnVlXHJcbiAgfSkpO1xyXG5cclxufTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxudmFyIGVsZW1lbnRIZWxwZXIgPSByZXF1aXJlKCcuLi8uLi8uLi8uLi9oZWxwZXIvRWxlbWVudEhlbHBlcicpLFxyXG4gICAgY21kSGVscGVyID0gcmVxdWlyZSgnLi4vLi4vLi4vLi4vaGVscGVyL0NtZEhlbHBlcicpO1xyXG5cclxudmFyIGVudHJ5RmFjdG9yeSA9IHJlcXVpcmUoJy4uLy4uLy4uLy4uL2ZhY3RvcnkvRW50cnlGYWN0b3J5Jyk7XHJcblxyXG4vKipcclxuICogR2V0IHRoZSB0aW1lciBkZWZpbml0aW9uIHR5cGUgZm9yIGEgZ2l2ZW4gdGltZXIgZXZlbnQgZGVmaW5pdGlvbi5cclxuICpcclxuICogQHBhcmFtIHtNb2RkbGVFbGVtZW50PGJwbW46VGltZXJFdmVudERlZmluaXRpb24+fSB0aW1lclxyXG4gKlxyXG4gKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSB0aGUgdGltZXIgZGVmaW5pdGlvbiB0eXBlXHJcbiAqL1xyXG5mdW5jdGlvbiBnZXRUaW1lckRlZmluaXRpb25UeXBlKHRpbWVyKSB7XHJcbiAgdmFyIHRpbWVEYXRlID0gdGltZXIuZ2V0KCd0aW1lRGF0ZScpO1xyXG4gIGlmICh0eXBlb2YgdGltZURhdGUgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXR1cm4gJ3RpbWVEYXRlJztcclxuICB9XHJcblxyXG4gIHZhciB0aW1lQ3ljbGUgPSB0aW1lci5nZXQoJ3RpbWVDeWNsZScpO1xyXG4gIGlmICh0eXBlb2YgdGltZUN5Y2xlICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgcmV0dXJuICd0aW1lQ3ljbGUnO1xyXG4gIH1cclxuXHJcbiAgdmFyIHRpbWVEdXJhdGlvbiA9IHRpbWVyLmdldCgndGltZUR1cmF0aW9uJyk7XHJcbiAgaWYgKHR5cGVvZiB0aW1lRHVyYXRpb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICByZXR1cm4gJ3RpbWVEdXJhdGlvbic7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogQ3JlYXRlcyAnYnBtbjpGb3JtYWxFeHByZXNzaW9uJyBlbGVtZW50LlxyXG4gKlxyXG4gKiBAcGFyYW0ge01vZGRsZUVsZW1lbnR9IHBhcmVudFxyXG4gKiBAcGFyYW0ge3N0cmluZ30gYm9keVxyXG4gKiBAcGFyYW0ge0JwbW5GYWN0b3J5fSBicG1uRmFjdG9yeVxyXG4gKlxyXG4gKiBAcmV0dXJuIHtNb2RkbGVFbGVtZW50PGJwbW46Rm9ybWFsRXhwcmVzc2lvbj59IGEgZm9ybWFsIGV4cHJlc3Npb25cclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUZvcm1hbEV4cHJlc3Npb24ocGFyZW50LCBib2R5LCBicG1uRmFjdG9yeSkge1xyXG4gIGJvZHkgPSBib2R5IHx8IHVuZGVmaW5lZDtcclxuICByZXR1cm4gZWxlbWVudEhlbHBlci5jcmVhdGVFbGVtZW50KCdicG1uOkZvcm1hbEV4cHJlc3Npb24nLCB7IGJvZHk6IGJvZHkgfSwgcGFyZW50LCBicG1uRmFjdG9yeSk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIFRpbWVyRXZlbnREZWZpbml0aW9uKGdyb3VwLCBlbGVtZW50LCBicG1uRmFjdG9yeSwgdGltZXJFdmVudERlZmluaXRpb24sIHRyYW5zbGF0ZSkge1xyXG5cclxuICB2YXIgc2VsZWN0T3B0aW9ucyA9IFtcclxuICAgIHsgdmFsdWU6ICd0aW1lRGF0ZScsIG5hbWU6IHRyYW5zbGF0ZSgnRGF0ZScpIH0sXHJcbiAgICB7IHZhbHVlOiAndGltZUR1cmF0aW9uJywgbmFtZTogdHJhbnNsYXRlKCdEdXJhdGlvbicpIH0sXHJcbiAgICB7IHZhbHVlOiAndGltZUN5Y2xlJywgbmFtZTogdHJhbnNsYXRlKCdDeWNsZScpIH1cclxuICBdO1xyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnNlbGVjdEJveCh7XHJcbiAgICBpZDogJ3RpbWVyLWV2ZW50LWRlZmluaXRpb24tdHlwZScsXHJcbiAgICBsYWJlbDogdHJhbnNsYXRlKCdUaW1lciBEZWZpbml0aW9uIFR5cGUnKSxcclxuICAgIHNlbGVjdE9wdGlvbnM6IHNlbGVjdE9wdGlvbnMsXHJcbiAgICBlbXB0eVBhcmFtZXRlcjogdHJ1ZSxcclxuICAgIG1vZGVsUHJvcGVydHk6ICd0aW1lckRlZmluaXRpb25UeXBlJyxcclxuXHJcbiAgICBnZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIG5vZGUpIHtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB0aW1lckRlZmluaXRpb25UeXBlOiBnZXRUaW1lckRlZmluaXRpb25UeXBlKHRpbWVyRXZlbnREZWZpbml0aW9uKSB8fCAnJ1xyXG4gICAgICB9O1xyXG4gICAgfSxcclxuXHJcbiAgICBzZXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIHZhbHVlcykge1xyXG4gICAgICB2YXIgcHJvcHMgPSB7XHJcbiAgICAgICAgdGltZUR1cmF0aW9uOiB1bmRlZmluZWQsXHJcbiAgICAgICAgdGltZURhdGU6IHVuZGVmaW5lZCxcclxuICAgICAgICB0aW1lQ3ljbGU6IHVuZGVmaW5lZFxyXG4gICAgICB9O1xyXG5cclxuICAgICAgdmFyIG5ld1R5cGUgPSB2YWx1ZXMudGltZXJEZWZpbml0aW9uVHlwZTtcclxuICAgICAgaWYgKHZhbHVlcy50aW1lckRlZmluaXRpb25UeXBlKSB7XHJcbiAgICAgICAgdmFyIG9sZFR5cGUgPSBnZXRUaW1lckRlZmluaXRpb25UeXBlKHRpbWVyRXZlbnREZWZpbml0aW9uKTtcclxuXHJcbiAgICAgICAgdmFyIHZhbHVlO1xyXG4gICAgICAgIGlmIChvbGRUeXBlKSB7XHJcbiAgICAgICAgICB2YXIgZGVmaW5pdGlvbiA9IHRpbWVyRXZlbnREZWZpbml0aW9uLmdldChvbGRUeXBlKTtcclxuICAgICAgICAgIHZhbHVlID0gZGVmaW5pdGlvbi5nZXQoJ2JvZHknKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHByb3BzW25ld1R5cGVdID0gY3JlYXRlRm9ybWFsRXhwcmVzc2lvbih0aW1lckV2ZW50RGVmaW5pdGlvbiwgdmFsdWUsIGJwbW5GYWN0b3J5KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGNtZEhlbHBlci51cGRhdGVCdXNpbmVzc09iamVjdChlbGVtZW50LCB0aW1lckV2ZW50RGVmaW5pdGlvbiwgcHJvcHMpO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG5cclxuICBncm91cC5lbnRyaWVzLnB1c2goZW50cnlGYWN0b3J5LnRleHRGaWVsZCh7XHJcbiAgICBpZDogJ3RpbWVyLWV2ZW50LWRlZmluaXRpb24nLFxyXG4gICAgbGFiZWw6IHRyYW5zbGF0ZSgnVGltZXIgRGVmaW5pdGlvbicpLFxyXG4gICAgbW9kZWxQcm9wZXJ0eTogJ3RpbWVyRGVmaW5pdGlvbicsXHJcblxyXG4gICAgZ2V0OiBmdW5jdGlvbihlbGVtZW50LCBub2RlKSB7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0VGltZXJEZWZpbml0aW9uVHlwZSh0aW1lckV2ZW50RGVmaW5pdGlvbik7XHJcbiAgICAgIHZhciBkZWZpbml0aW9uID0gdHlwZSAmJiB0aW1lckV2ZW50RGVmaW5pdGlvbi5nZXQodHlwZSk7XHJcbiAgICAgIHZhciB2YWx1ZSA9IGRlZmluaXRpb24gJiYgZGVmaW5pdGlvbi5nZXQoJ2JvZHknKTtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICB0aW1lckRlZmluaXRpb246IHZhbHVlXHJcbiAgICAgIH07XHJcbiAgICB9LFxyXG5cclxuICAgIHNldDogZnVuY3Rpb24oZWxlbWVudCwgdmFsdWVzKSB7XHJcbiAgICAgIHZhciB0eXBlID0gZ2V0VGltZXJEZWZpbml0aW9uVHlwZSh0aW1lckV2ZW50RGVmaW5pdGlvbik7XHJcbiAgICAgIHZhciBkZWZpbml0aW9uID0gdHlwZSAmJiB0aW1lckV2ZW50RGVmaW5pdGlvbi5nZXQodHlwZSk7XHJcblxyXG4gICAgICBpZiAoZGVmaW5pdGlvbikge1xyXG4gICAgICAgIHJldHVybiBjbWRIZWxwZXIudXBkYXRlQnVzaW5lc3NPYmplY3QoZWxlbWVudCwgZGVmaW5pdGlvbiwge1xyXG4gICAgICAgICAgYm9keTogdmFsdWVzLnRpbWVyRGVmaW5pdGlvbiB8fCB1bmRlZmluZWRcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSxcclxuXHJcbiAgICB2YWxpZGF0ZTogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICB2YXIgdHlwZSA9IGdldFRpbWVyRGVmaW5pdGlvblR5cGUodGltZXJFdmVudERlZmluaXRpb24pO1xyXG4gICAgICB2YXIgZGVmaW5pdGlvbiA9IHR5cGUgJiYgdGltZXJFdmVudERlZmluaXRpb24uZ2V0KHR5cGUpO1xyXG4gICAgICBpZiAoZGVmaW5pdGlvbikge1xyXG4gICAgICAgIHZhciB2YWx1ZSA9IGRlZmluaXRpb24uZ2V0KCdib2R5Jyk7XHJcbiAgICAgICAgaWYgKCF2YWx1ZSkge1xyXG4gICAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgdGltZXJEZWZpbml0aW9uOiB0cmFuc2xhdGUoJ011c3QgcHJvdmlkZSBhIHZhbHVlJylcclxuICAgICAgICAgIH07XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9LFxyXG5cclxuICAgIGhpZGRlbjogZnVuY3Rpb24oZWxlbWVudCkge1xyXG4gICAgICByZXR1cm4gIWdldFRpbWVyRGVmaW5pdGlvblR5cGUodGltZXJFdmVudERlZmluaXRpb24pO1xyXG4gICAgfVxyXG5cclxuICB9KSk7XHJcblxyXG59XHJcblxyXG5tb2R1bGUuZXhwb3J0cyA9IFRpbWVyRXZlbnREZWZpbml0aW9uO1xyXG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiDlhajlsYDlip/og73lsIHoo4VcbiAqIEBhdXRob3IgenJcbiAqIEB0eXBlIHt7cmVnaXN0ZXJGaWxlRHJvcCgqLCAqKTogdm9pZCwgc2F2ZUJwbW4oT2JqZWN0KTogdm9pZCwgaGFuZGxlRHJhZ092ZXIoKik6IHZvaWQsIHNldENvbG9yKE9iamVjdCk6IHZvaWQsIGRvd25Mb2FkKE9iamVjdCk6IHZvaWQsIHVwbG9hZChPYmplY3QsIE9iamVjdCwgT2JqZWN0KTogdm9pZCwgaGFuZGxlRmlsZVNlbGVjdCgqKTogdm9pZCwgc2V0RW5jb2RlZChPYmplY3QsIHN0cmluZywgc3RyaW5nKTogdm9pZCwgb3BlbkZyb21VcmwoT2JqZWN0LCBPYmplY3QsIE9iamVjdCwgc3RyaW5nKTogdm9pZCwgY3JlYXRlRGlhZ3JhbShzdHJpbmcsIE9iamVjdCwgT2JqZWN0KTogUHJvbWlzZTx2b2lkPiwgZ2V0VXJsUGFyYW06IHRvb2xzLmdldFVybFBhcmFtfX1cbiAqL1xuXG5pbXBvcnQgJCBmcm9tICdqcXVlcnknO1xuY29uc3QgcHJvSG9zdCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0O1xuY29uc3QgaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNwbGl0KFwiYnBtbmpzXCIpWzBdO1xuY29uc3Qga2V5ID0gaHJlZi5zcGxpdCh3aW5kb3cubG9jYXRpb24uaG9zdClbMV07XG5jb25zdCBwdWJsaWN1cmwgPSBwcm9Ib3N0ICsga2V5O1xuY29uc3QgdG9vbHMgPSB7XG4gICAgcmVnaXN0ZXJGaWxlRHJvcChjb250YWluZXIsIGNhbGxiYWNrKSB7XG4gICAgICAgIGNvbnRhaW5lci5nZXQoMCkuYWRkRXZlbnRMaXN0ZW5lcignZHJhZ292ZXInLCB0b29scy5oYW5kbGVEcmFnT3ZlciwgZmFsc2UpO1xuICAgICAgICBjb250YWluZXIuZ2V0KDApLmFkZEV2ZW50TGlzdGVuZXIoJ2Ryb3AnLCB0b29scy5oYW5kbGVGaWxlU2VsZWN0LCBmYWxzZSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDojrflj5blnLDlnYDmoI/lj4LmlbBcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAgICAgKi9cbiAgICBnZXRVcmxQYXJhbTogZnVuY3Rpb24gKHVybCkge1xuICAgICAgICB2YXIgb2JqZWN0ID0ge307XG4gICAgICAgIGlmICh1cmwuaW5kZXhPZihcIj9cIikgIT0gLTEpIHtcbiAgICAgICAgICAgIHZhciBzdHIgPSB1cmwuc3BsaXQoXCI/XCIpWzFdO1xuICAgICAgICAgICAgdmFyIHN0cnMgPSBzdHIuc3BsaXQoXCImXCIpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgb2JqZWN0W3N0cnNbaV0uc3BsaXQoXCI9XCIpWzBdXSA9IHN0cnNbaV0uc3BsaXQoXCI9XCIpWzFdXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gb2JqZWN0XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG9iamVjdFt1cmxdO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog6YCa6L+HeG1s5Yib5bu6YnBtblxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB4bWwg5Yib5bu6YnBtcyB4bWxcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gYnBtbk1vZGVsZXIgYnBtbuWvueixoVxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBjb250YWluZXIg5a655Zmo5a+56LGhXG4gICAgICovXG4gICAgYXN5bmMgY3JlYXRlRGlhZ3JhbSh4bWwsIGJwbW5Nb2RlbGVyLCBjb250YWluZXIpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGF3YWl0IGJwbW5Nb2RlbGVyLmltcG9ydFhNTCh4bWwpO1xuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKCd3aXRoLWVycm9yJykuYWRkQ2xhc3MoJ3dpdGgtZGlhZ3JhbScpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcygnd2l0aC1kaWFncmFtJykuYWRkQ2xhc3MoJ3dpdGgtZXJyb3InKTtcbiAgICAgICAgICAgIGNvbnRhaW5lci5maW5kKCcuZXJyb3IgcHJlJykudGV4dChlcnIubWVzc2FnZSk7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOmAmui/h0pzb27orr7nva7popzoibJcbiAgICAgKiBAcGFyYW0ge29iamVjdH0ganNvbiBqc29uIOWtl+espuS4slxuICAgICAqL1xuICAgIHNldENvbG9yKGpzb24sYnBtbk1vZGVsZXIpIHtcbiAgICAgICAgdmFyIG1vZGVsaW5nID0gYnBtbk1vZGVsZXIuZ2V0KCdtb2RlbGluZycpO1xuICAgICAgICB2YXIgZWxlbWVudFJlZ2lzdHJ5ID0gYnBtbk1vZGVsZXIuZ2V0KCdlbGVtZW50UmVnaXN0cnknKVxuICAgICAgICB2YXIgZWxlbWVudFRvQ29sb3IgPSBlbGVtZW50UmVnaXN0cnkuZ2V0KGpzb24ubmFtZSk7XG4gICAgICAgIGlmKGVsZW1lbnRUb0NvbG9yKXtcbiAgICAgICAgICAgIG1vZGVsaW5nLnNldENvbG9yKFtlbGVtZW50VG9Db2xvcl0sIHtcbiAgICAgICAgICAgICAgICBzdHJva2U6IGpzb24uc3Ryb2tlLFxuICAgICAgICAgICAgICAgIGZpbGw6IGpzb24uZmlsbFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOS/neWtmGJwbW7lr7nosaFcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gYnBtbk1vZGVsZXIgYnBtbuWvueixoVxuICAgICAqL1xuICAgIHNhdmVCcG1uKGJwbW5Nb2RlbGVyKSB7XG4gICAgICAgIGJwbW5Nb2RlbGVyLnNhdmVYTUwoeyBmb3JtYXQ6IHRydWUgfSwgZnVuY3Rpb24gKGVyciwgeG1sKSB7XG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvbnNvbGUuZXJyb3IoJ+S/neWtmOWksei0pe+8jOivt+mHjeivlScsIGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh4bWwpXG4gICAgICAgICAgICB2YXIgcGFyYW09e1xuICAgICAgICAgICAgICAgICAgICBcInN0cmluZ0JQTU5cIjp4bWxcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgICAgIHVybDogbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJWVUVfQVBQX0JBU0VfQVBJXCIpKycvcHJvY2Vzc0RlZmluaXRpb24vYWRkRGVwbG95bWVudEJ5U3RyaW5nJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICAgICAgZGF0YVR5cGU6XCJqc29uXCIsXG4gICAgICAgICAgICAgICAgZGF0YTogcGFyYW0sXG4gICAgICAgICAgICAgICAgLy9oZWFkZXJzOnsnQ29udGVudC1UeXBlJzonYXBwbGljYXRpb24vanNvbjtjaGFyc2V0PXV0ZjgnfSxcbiAgICAgICAgICAgICAgICBzdWNjZXNzOiBmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICAgICAgICAgICAgICAgIGlmKHJlc3VsdC5jb2RlPT09MjAwKXtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRvb2xzLnN5aGlkZSgnYWxlcnQnKVxuICAgICAgICAgICAgICAgICAgICB9ZWxzZXtcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsZXJ0KHJlc3VsdC5tc2cpXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycilcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDkuIvovb1icG1uXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGJwbW5Nb2RlbGVyIGJwbW7lr7nosaFcbiAgICAgKi9cbiAgICBkb3duTG9hZChicG1uTW9kZWxlcikge1xuICAgICAgICB2YXIgZG93bmxvYWRMaW5rID0gJChcIiNkb3dubG9hZEJwbW5cIilcbiAgICAgICAgYnBtbk1vZGVsZXIuc2F2ZVhNTCh7IGZvcm1hdDogdHJ1ZSB9LCBmdW5jdGlvbiAoZXJyLCB4bWwpIHtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29uc29sZS5lcnJvcignY291bGQgbm90IHNhdmUgQlBNTiAyLjAgZGlhZ3JhbScsIGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0b29scy5zZXRFbmNvZGVkKGRvd25sb2FkTGluaywgJ2RpYWdyYW0uYnBtbicsIGVyciA/IG51bGwgOiB4bWwpO1xuICAgICAgICB9KTtcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOi9rOeggXhtbOW5tuS4i+i9vVxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBsaW5rIOaMiemSrlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIOS4i+i9veWQjeensFxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBkYXRhIGJhc2U2NFhNTFxuICAgICAqL1xuICAgIHNldEVuY29kZWQobGluaywgbmFtZSwgZGF0YSkge1xuICAgICAgICB2YXIgZW5jb2RlZERhdGEgPSBlbmNvZGVVUklDb21wb25lbnQoZGF0YSk7XG4gICAgICAgIGlmIChkYXRhKSB7XG4gICAgICAgICAgICBsaW5rLmFkZENsYXNzKCdhY3RpdmUnKS5hdHRyKHtcbiAgICAgICAgICAgICAgICAnaHJlZic6ICdkYXRhOmFwcGxpY2F0aW9uL2JwbW4yMC14bWw7Y2hhcnNldD1VVEYtOCwnICsgZW5jb2RlZERhdGEsXG4gICAgICAgICAgICAgICAgJ2Rvd25sb2FkJzogbmFtZVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsaW5rLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICog5LiK5LygYnBtblxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBicG1uTW9kZWxlciBicG1u5a+56LGhXG4gICAgICogQHBhcmFtIHtvYmplY3R9IGNvbnRhaW5lciDlrrnlmajlr7nosaFcbiAgICAgKi9cbiAgICB1cGxvYWQoYnBtbk1vZGVsZXIsIGNvbnRhaW5lcikge1xuICAgICAgICB2YXIgRmlsZVVwbG9hZCA9IGRvY3VtZW50Lm15Rm9ybS51cGxvYWRGaWxlLmZpbGVzWzBdO1xuICAgICAgICB2YXIgZm0gPSBuZXcgRm9ybURhdGEoKTtcbiAgICAgICAgZm0uYXBwZW5kKCdwcm9jZXNzRmlsZScsIEZpbGVVcGxvYWQpO1xuICAgICAgICAkLmFqYXgoe1xuICAgICAgICAgICAgdXJsOiBsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcIlZVRV9BUFBfQkFTRV9BUElcIikrJy9wcm9jZXNzRGVmaW5pdGlvbi91cGxvYWQnLFxuICAgICAgICAgICAgLy8gdXJsOiAnaHR0cDovL2xvY2FsaG9zdDo4MDgwL3Byb2Nlc3NEZWZpbml0aW9uL3VwbG9hZCcsXG4gICAgICAgICAgICB0eXBlOiAnUE9TVCcsXG4gICAgICAgICAgICBkYXRhOiBmbSxcbiAgICAgICAgICAgIGFzeW5jOiBmYWxzZSxcbiAgICAgICAgICAgIGNvbnRlbnRUeXBlOiBmYWxzZSwgLy/npoHmraLorr7nva7or7fmsYLnsbvlnotcbiAgICAgICAgICAgIHByb2Nlc3NEYXRhOiBmYWxzZSwgLy/npoHmraJqcXVlcnnlr7lEQXRh5pWw5o2u55qE5aSE55CGLOm7mOiupOS8muWkhOeQhlxuICAgICAgICAgICAgc3VjY2VzczogZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHZhciB1cmwgPSByZXN1bHQuZGF0YS5zdWJzdHIoMCw0KT09XCJodHRwXCI/cmVzdWx0LmRhdGE6bG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJWVUVfQVBQX0JBU0VfQVBJXCIpKyByZXN1bHQuZGF0YVxuICAgICAgICAgICAgICAgIHRvb2xzLm9wZW5Gcm9tVXJsKGJwbW5Nb2RlbGVyLCBjb250YWluZXIsIHVybClcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGVycilcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDmiZPlvIB4bWwgIFVybCDlnLDlnYBcbiAgICAgKiBAcGFyYW0ge29iamVjdH0gYnBtbk1vZGVsZXIgYnBtbuWvueixoVxuICAgICAqIEBwYXJhbSB7b2JqZWN0fSBjb250YWluZXIg5a655Zmo5a+56LGhXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHVybCB1cmzlnLDlnYBcbiAgICAgKi9cbiAgICBvcGVuRnJvbVVybChicG1uTW9kZWxlciwgY29udGFpbmVyLCB1cmwpIHtcbiAgICAgICAgJC5hamF4KHVybCwgeyBkYXRhVHlwZTogJ3RleHQnIH0pLmRvbmUoYXN5bmMgZnVuY3Rpb24gKHhtbCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBhd2FpdCBicG1uTW9kZWxlci5pbXBvcnRYTUwoeG1sKTtcbiAgICAgICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3MoJ3dpdGgtZXJyb3InKS5hZGRDbGFzcygnd2l0aC1kaWFncmFtJyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH0sXG4gICAgLyoqXG4gICAgICog5omT5byA5by55Ye65qGGXG4gICAgICogQHBhcmFtIGlkXG4gICAgICovXG4gICAgc3lvcGVuKGlkKSB7XG4gICAgICAgIHZhciBkb20gPSAkKFwiI1wiICsgaWQpO1xuICAgICAgICB0aGlzLnN5Y2VudGVyKGRvbSk7XG4gICAgICAgIGRvbS5hZGRDbGFzcyhuYW1lKTtcbiAgICAgICAgZG9tLnNob3coKTtcbiAgICAgICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgICAgICAkKFwiLnN5LW1hc2tcIikuZmFkZUluKDMwMClcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGRvbS5yZW1vdmVDbGFzcyhuYW1lKVxuICAgICAgICB9LCAzMDApO1xuXG4gICAgfSxcbiAgICAvKipcbiAgICAgKiDpmpDol4/lvLnlh7rmoYZcbiAgICAgKiBAcGFyYW0gaWRcbiAgICAgKi9cbiAgICBzeWhpZGUoaWQpIHtcbiAgICAgICAgaWYgKHR5cGVvZiBpZCA9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgICAgICB2YXIgZG9tID0gJChcIi5zeS1hbGVydFwiKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGRvbSA9ICQoXCIjXCIgKyBpZClcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmFtZSA9IGRvbS5hdHRyKFwic3ktbGVhdmVcIik7XG4gICAgICAgIGRvbS5hZGRDbGFzcyhuYW1lKTtcbiAgICAgICAgJChcIi5zeS1tYXNrXCIpLmZhZGVPdXQoMzAwKTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGRvbS5oaWRlKCk7XG4gICAgICAgICAgICBkb20ucmVtb3ZlQ2xhc3MobmFtZSk7XG4gICAgICAgIH0sIDMwMClcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOW8ueWHuuahhuWxheS4rVxuICAgICAqIEBwYXJhbSBkb21cbiAgICAgKi9cbiAgICBzeWNlbnRlcihkb20pIHtcbiAgICAgICAgdmFyIG1ndG9wID0gcGFyc2VGbG9hdChkb20uaGVpZ2h0KCkgLyAyKTtcbiAgICAgICAgZG9tLmNzcyh7XG4gICAgICAgICAgICBcInRvcFwiOiBcIjUwJVwiLFxuICAgICAgICAgICAgXCJtYXJnaW4tdG9wXCI6IFwiLVwiICsgbWd0b3AgKyBcInB4XCJcbiAgICAgICAgfSlcbiAgICB9LFxuICAgIC8qKlxuICAgICAqIOWIpOaWreaYr+WQpuaYr+aVsOe7hFxuICAgICAqIEBwYXJhbSB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHthcmcgaXMgQXJyYXk8YW55Pnxib29sZWFufVxuICAgICAqL1xuICAgIGlzQXJyYXlGbih2YWx1ZSl7XG4gICAgICAgIGlmICh0eXBlb2YgQXJyYXkuaXNBcnJheSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSk7XG4gICAgICAgIH1lbHNle1xuICAgICAgICAgICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT09IFwiW29iamVjdCBBcnJheV1cIjtcbiAgICAgICAgfVxuICAgIH0sXG4gICAgLyoqXG4gICAgICog5qC55o2u5pWw5o2u6K6+572u6aKc6ImyXG4gICAgICogQHBhcmFtIGRhdGFcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9XG4gICAgICovXG4gICAgZ2V0QnlDb2xvcihkYXRhKXtcblxuICAgICAgICB2YXIgQ29sb3JKc29uPVtdXG4gICAgICAgIGZvcih2YXIgayBpbiBkYXRhWydoaWdoTGluZSddKXtcbiAgICAgICAgICAgIHZhciBwYXI9e1xuICAgICAgICAgICAgICAgIFwibmFtZVwiOiBkYXRhWydoaWdoTGluZSddW2tdLFxuICAgICAgICAgICAgICAgIFwic3Ryb2tlXCI6XCJncmVlblwiLFxuICAgICAgICAgICAgICAgIFwiZmlsbFwiOlwiZ3JlZW5cIlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQ29sb3JKc29uLnB1c2gocGFyKVxuICAgICAgICB9XG4gICAgICAgIGZvcih2YXIgayBpbiBkYXRhWydoaWdoUG9pbnQnXSl7XG4gICAgICAgICAgICB2YXIgcGFyPXtcbiAgICAgICAgICAgICAgICBcIm5hbWVcIjogZGF0YVsnaGlnaFBvaW50J11ba10sXG4gICAgICAgICAgICAgICAgXCJzdHJva2VcIjpcImdyYXlcIixcbiAgICAgICAgICAgICAgICBcImZpbGxcIjpcIiNlYWU5ZTlcIlxuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBDb2xvckpzb24ucHVzaChwYXIpXG4gICAgICAgIH1cbiAgICAgICAgZm9yKHZhciBrIGluIGRhdGFbJ2lEbyddKXtcbiAgICAgICAgICAgIHZhciBwYXI9e1xuICAgICAgICAgICAgICAgIFwibmFtZVwiOiBkYXRhWydpRG8nXVtrXSxcbiAgICAgICAgICAgICAgICBcInN0cm9rZVwiOlwiZ3JlZW5cIixcbiAgICAgICAgICAgICAgICBcImZpbGxcIjpcIiNhM2Q2OGVcIlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQ29sb3JKc29uLnB1c2gocGFyKVxuICAgICAgICB9XG4gICAgICAgIGZvcih2YXIgayBpbiBkYXRhWyd3YWl0aW5nVG9EbyddKXtcbiAgICAgICAgICAgIHZhciBwYXI9e1xuICAgICAgICAgICAgICAgIFwibmFtZVwiOiBkYXRhWyd3YWl0aW5nVG9EbyddW2tdLFxuICAgICAgICAgICAgICAgIFwic3Ryb2tlXCI6XCJncmVlblwiLFxuICAgICAgICAgICAgICAgIFwiZmlsbFwiOlwieWVsbG93XCJcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIENvbG9ySnNvbi5wdXNoKHBhcilcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gQ29sb3JKc29uXG4gICAgfVxufVxuXG5cblxuXG5leHBvcnQgZGVmYXVsdCB0b29sc1xuIl19